From 3f66b6f4e4453f09df487213f3dca791212e1f73 Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Tue, 17 Mar 2020 16:20:41 +0100 Subject: [PATCH 001/300] Fix vesting benchmark (#5269) * Fix vesting bench starting block. * Set subs s+1 to hit worst path. * Remove unused origin. * Apply review suggestions. --- frame/identity/src/benchmarking.rs | 20 ++++++++++++----- frame/vesting/src/benchmarking.rs | 35 ++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/frame/identity/src/benchmarking.rs b/frame/identity/src/benchmarking.rs index 87d577c4d8..1ca10707c9 100644 --- a/frame/identity/src/benchmarking.rs +++ b/frame/identity/src/benchmarking.rs @@ -53,7 +53,7 @@ fn add_registrars(r: u32) -> Result<(), &'static str> { // Adds `s` sub-accounts to the identity of `who`. Each wil have 32 bytes of raw data added to it. // This additionally returns the vector of sub-accounts to it can be modified if needed. -fn add_sub_accounts(who: T::AccountId, s: u32) -> Result, &'static str> { +fn add_sub_accounts(who: &T::AccountId, s: u32) -> Result, &'static str> { let mut subs = Vec::new(); let who_origin = RawOrigin::Signed(who.clone()); let data = Data::Raw(vec![0; 32]); @@ -100,7 +100,7 @@ benchmarks! { let s in 1 .. T::MaxSubAccounts::get() => { // Give them s many sub accounts let caller = account::("caller", 0); - let _ = add_sub_accounts::(caller, s)?; + let _ = add_sub_accounts::(&caller, s)?; }; let x in 1 .. T::MaxAdditionalFields::get() => { // Create their main identity with x additional fields @@ -149,11 +149,19 @@ benchmarks! { ) set_subs { - let s in ...; - let caller = account::("caller", 0); - let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); - let subs = Module::::subs(&caller); + + // Give them s many sub accounts. + let s in 1 .. T::MaxSubAccounts::get() - 1 => { + let _ = add_sub_accounts::(&caller, s)?; + }; + + let mut subs = Module::::subs(&caller); + + // Create an s + 1 sub account. + let data = Data::Raw(vec![0; 32]); + subs.push((account::("sub", s + 1), data)); + }: _(RawOrigin::Signed(caller), subs) clear_identity { diff --git a/frame/vesting/src/benchmarking.rs b/frame/vesting/src/benchmarking.rs index 79ab0cb6e3..8d0f0214eb 100644 --- a/frame/vesting/src/benchmarking.rs +++ b/frame/vesting/src/benchmarking.rs @@ -44,6 +44,7 @@ fn setup(b: u32) -> T::AccountId { let starting_block = 0; let caller = account("caller", 0, SEED); + System::::set_block_number(0.into()); // Add schedule to avoid `NotVesting` error. let _ = Vesting::::add_vesting_schedule( @@ -63,32 +64,44 @@ fn setup(b: u32) -> T::AccountId { benchmarks! { _ { - // Current block. It allows to hit different paths of `update_lock`. - // It doesn't seems to influence the timings which branch is taken. - let b in 0 .. 1 => (); // Number of previous locks. // It doesn't seems to influence the timings for lower values. let l in 0 .. MAX_LOCKS => add_locks::(l); } - vest { - let b in ...; + vest_locked { let l in ...; - let caller = setup::(b); + let caller = setup::(0u32); - }: _(RawOrigin::Signed(caller)) + }: vest(RawOrigin::Signed(caller)) - vest_other { - let b in ...; + vest_not_locked { let l in ...; - let other: T::AccountId = setup::(b); + let caller = setup::(1u32); + + }: vest(RawOrigin::Signed(caller)) + + vest_other_locked { + let l in ...; + + let other: T::AccountId = setup::(0u32); + let other_lookup: ::Source = T::Lookup::unlookup(other.clone()); + + let caller = account("caller", 0, SEED); + + }: vest_other(RawOrigin::Signed(caller), other_lookup) + + vest_other_not_locked { + let l in ...; + + let other: T::AccountId = setup::(1u32); let other_lookup: ::Source = T::Lookup::unlookup(other.clone()); let caller = account("caller", 0, SEED); - }: _(RawOrigin::Signed(caller), other_lookup) + }: vest_other(RawOrigin::Signed(caller), other_lookup) vested_transfer { let u in 0 .. 1000; -- GitLab From abd00b1251982efcb1d1ec3e5535bb6a2d870fde Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Tue, 17 Mar 2020 08:24:04 -0700 Subject: [PATCH 002/300] Produce block always on updated transaction pool state (#5227) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * make sure return ready iterator once state is updated * update sc_basic_authorship tests * update node tests * fix manual seal * actually fix service test * add tests * Update client/basic-authorship/src/basic_authorship.rs Co-Authored-By: Tomasz Drwięga * helper function * review suggestions * warning and continue * add debug log * use futures::chennel::oneshot * use declaration bound * no option for updated_at * no allocation * ready_at / ready * Update client/transaction-pool/src/lib.rs Co-Authored-By: Bastian Köcher * Update client/transaction-pool/src/lib.rs Co-Authored-By: Bastian Köcher * Update client/transaction-pool/src/lib.rs Co-Authored-By: Bastian Köcher * Update client/transaction-pool/src/lib.rs Co-Authored-By: Bastian Köcher * Update client/transaction-pool/src/lib.rs Co-Authored-By: Bastian Köcher * Update client/transaction-pool/src/lib.rs Co-Authored-By: Bastian Köcher Co-authored-by: Tomasz Drwięga Co-authored-by: Bastian Köcher --- Cargo.lock | 2 + bin/node/cli/src/service.rs | 31 ++++++- client/basic-authorship/Cargo.toml | 1 + .../basic-authorship/src/basic_authorship.rs | 71 ++++++++++++++-- client/consensus/manual-seal/Cargo.toml | 1 + client/consensus/manual-seal/src/lib.rs | 16 +++- client/service/test/src/lib.rs | 6 +- .../graph/src/validated_pool.rs | 2 +- client/transaction-pool/src/lib.rs | 83 +++++++++++++++++-- client/transaction-pool/src/testing/pool.rs | 52 ++++++++++++ primitives/blockchain/src/error.rs | 2 + primitives/transaction-pool/src/pool.rs | 13 ++- 12 files changed, 256 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f929a3dcbf..6fc90c3c23 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5642,6 +5642,7 @@ name = "sc-basic-authorship" version = "0.8.0-alpha.3" dependencies = [ "futures 0.3.4", + "futures-timer 3.0.2", "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", @@ -5970,6 +5971,7 @@ dependencies = [ name = "sc-consensus-manual-seal" version = "0.8.0-alpha.3" dependencies = [ + "assert_matches", "derive_more", "env_logger 0.7.1", "futures 0.3.4", diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 6d9989b274..d81ec5f031 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -397,6 +397,7 @@ mod tests { use sc_service::AbstractService; use crate::service::{new_full, new_light}; use sp_runtime::traits::IdentifyAccount; + use sp_transaction_pool::{MaintainedTransactionPool, ChainEvent}; type AccountPublic = ::Signer; @@ -414,7 +415,21 @@ mod tests { let dummy_runtime = ::tokio::runtime::Runtime::new().unwrap(); let block_factory = |service: &::FullService| { let block_id = BlockId::number(service.client().chain_info().best_number); - let parent_header = service.client().header(&block_id).unwrap().unwrap(); + let parent_header = service.client().best_header(&block_id) + .expect("db error") + .expect("best block should exist"); + + futures::executor::block_on( + service.transaction_pool().maintain( + ChainEvent::NewBlock { + is_new_best: true, + id: block_id.clone(), + retracted: vec![], + header: parent_header, + }, + ) + ); + let consensus_net = ConsensusNetwork::new(service.network(), service.client().clone()); let proposer_factory = consensus::ProposerFactory { client: service.client().clone(), @@ -464,6 +479,8 @@ mod tests { } #[test] + // It is "ignored", but the node-cli ignored tests are running on the CI. + // This can be run locally with `cargo test --release -p node-cli test_sync -- --ignored`. #[ignore] fn test_sync() { let keystore_path = tempfile::tempdir().expect("Creates keystore path"); @@ -504,6 +521,18 @@ mod tests { let parent_header = service.client().header(&parent_id).unwrap().unwrap(); let parent_hash = parent_header.hash(); let parent_number = *parent_header.number(); + + futures::executor::block_on( + service.transaction_pool().maintain( + ChainEvent::NewBlock { + is_new_best: true, + id: parent_id.clone(), + retracted: vec![], + header: parent_header.clone(), + }, + ) + ); + let mut proposer_factory = sc_basic_authorship::ProposerFactory::new( service.client(), service.transaction_pool() diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index 7503221f65..ee2ff971bc 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -23,6 +23,7 @@ sc-telemetry = { version = "2.0.0-alpha.2", path = "../telemetry" } sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../primitives/transaction-pool" } sc-block-builder = { version = "0.8.0-alpha.2", path = "../block-builder" } tokio-executor = { version = "0.2.0-alpha.6", features = ["blocking"] } +futures-timer = "3.0.1" [dev-dependencies] sc-transaction-pool = { version = "2.0.0-alpha.2", path = "../../client/transaction-pool" } diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index fc9a5dec06..986d797ca7 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -33,7 +33,7 @@ use sp_transaction_pool::{TransactionPool, InPoolTransaction}; use sc_telemetry::{telemetry, CONSENSUS_INFO}; use sc_block_builder::{BlockBuilderApi, BlockBuilderProvider}; use sp_api::{ProvideRuntimeApi, ApiExt}; -use futures::prelude::*; +use futures::{executor, future, future::Either}; use sp_blockchain::{HeaderBackend, ApplyExtrinsicFailed}; use std::marker::PhantomData; @@ -210,7 +210,18 @@ impl ProposerInner let mut is_first = true; let mut skipped = 0; let mut unqueue_invalid = Vec::new(); - let pending_iterator = self.transaction_pool.ready(); + let pending_iterator = match executor::block_on(future::select( + self.transaction_pool.ready_at(self.parent_number), + futures_timer::Delay::new((deadline - (self.now)()) / 8), + )) { + Either::Left((iterator, _)) => iterator, + Either::Right(_) => { + log::warn!( + "Timeout fired waiting for transaction pool to be ready. Proceeding to block production anyway.", + ); + self.transaction_pool.ready() + } + }; debug!("Attempting to push transactions from the pool."); debug!("Pool status: {:?}", self.transaction_pool.status()); @@ -304,10 +315,12 @@ mod tests { prelude::*, runtime::{Extrinsic, Transfer}, }; + use sp_transaction_pool::{ChainEvent, MaintainedTransactionPool}; use sc_transaction_pool::{BasicPool, FullChainApi}; use sp_api::Core; use backend::Backend; use sp_blockchain::HeaderBackend; + use sp_runtime::traits::NumberFor; fn extrinsic(nonce: u64) -> Extrinsic { Transfer { @@ -318,6 +331,17 @@ mod tests { }.into_signed_tx() } + fn chain_event(block_number: u64, header: B::Header) -> ChainEvent + where NumberFor: From + { + ChainEvent::NewBlock { + id: BlockId::Number(block_number.into()), + retracted: vec![], + is_new_best: true, + header: header, + } + } + #[test] fn should_cease_building_block_when_deadline_is_reached() { // given @@ -330,16 +354,27 @@ mod tests { txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)]) ).unwrap(); + futures::executor::block_on( + txpool.maintain(chain_event( + 0, + client.header(&BlockId::Number(0u64)).expect("header get error").expect("there should be header") + )) + ); + let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone()); - let cell = Mutex::new(time::Instant::now()); + let cell = Mutex::new((false, time::Instant::now())); let mut proposer = proposer_factory.init_with_now( &client.header(&BlockId::number(0)).unwrap().unwrap(), Box::new(move || { let mut value = cell.lock(); - let old = *value; + if !value.0 { + value.0 = true; + return value.1; + } + let old = value.1; let new = old + time::Duration::from_secs(2); - *value = new; + *value = (true, new); old }) ); @@ -371,6 +406,13 @@ mod tests { txpool.submit_at(&BlockId::number(0), vec![extrinsic(0)]), ).unwrap(); + futures::executor::block_on( + txpool.maintain(chain_event( + 0, + client.header(&BlockId::Number(0u64)).expect("header get error").expect("there should be header") + )) + ); + let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone()); let mut proposer = proposer_factory.init_with_now( @@ -459,15 +501,26 @@ mod tests { block }; + futures::executor::block_on( + txpool.maintain(chain_event( + 0, + client.header(&BlockId::Number(0u64)).expect("header get error").expect("there should be header") + )) + ); + // let's create one block and import it let block = propose_block(&client, 0, 2, 7); client.import(BlockOrigin::Own, block).unwrap(); - // now let's make sure that we can still make some progress + futures::executor::block_on( + txpool.maintain(chain_event( + 1, + client.header(&BlockId::Number(1)).expect("header get error").expect("there should be header") + )) + ); - // This is most likely incorrect, and caused by #5139 - let tx_remaining = 0; - let block = propose_block(&client, 1, 2, tx_remaining); + // now let's make sure that we can still make some progress + let block = propose_block(&client, 1, 2, 5); client.import(BlockOrigin::Own, block).unwrap(); } } diff --git a/client/consensus/manual-seal/Cargo.toml b/client/consensus/manual-seal/Cargo.toml index 11fee0e3f9..f0925df089 100644 --- a/client/consensus/manual-seal/Cargo.toml +++ b/client/consensus/manual-seal/Cargo.toml @@ -17,6 +17,7 @@ jsonrpc-derive = "14.0.5" log = "0.4.8" parking_lot = "0.10.0" serde = { version = "1.0", features=["derive"] } +assert_matches = "1.3.0" sc-client = { path = "../../../client" , version = "0.8.0-alpha.2"} sc-client-api = { path = "../../../client/api" , version = "2.0.0-alpha.2"} diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs index 18dc91ad34..36d12a0046 100644 --- a/client/consensus/manual-seal/src/lib.rs +++ b/client/consensus/manual-seal/src/lib.rs @@ -224,7 +224,7 @@ mod tests { txpool::Options, }; use substrate_test_runtime_transaction_pool::{TestApi, uxt}; - use sp_transaction_pool::TransactionPool; + use sp_transaction_pool::{TransactionPool, MaintainedTransactionPool}; use sp_runtime::generic::BlockId; use sp_blockchain::HeaderBackend; use sp_consensus::ImportedAux; @@ -432,14 +432,24 @@ mod tests { assert!(backend.blockchain().header(BlockId::Number(0)).unwrap().is_some()); assert!(pool.submit_one(&BlockId::Number(1), uxt(Alice, 1)).await.is_ok()); + pool.maintain(sp_transaction_pool::ChainEvent::NewBlock { + id: BlockId::Number(1), + header: backend.blockchain().header(BlockId::Number(1)).expect("db error").expect("imported above"), + is_new_best: true, + retracted: vec![], + }).await; + let (tx1, rx1) = futures::channel::oneshot::channel(); assert!(sink.send(EngineCommand::SealNewBlock { - parent_hash: Some(created_block.hash.clone()), + parent_hash: Some(created_block.hash), sender: Some(tx1), create_empty: false, finalize: false, }).await.is_ok()); - assert!(rx1.await.unwrap().is_ok()); + assert_matches::assert_matches!( + rx1.await.expect("should be no error receiving"), + Ok(_) + ); assert!(backend.blockchain().header(BlockId::Number(1)).unwrap().is_some()); pool_api.increment_nonce(Alice.into()); diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 259c25ee4d..0a29bc7bf2 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -482,7 +482,11 @@ pub fn sync( let first_user_data = &network.full_nodes[0].2; let best_block = BlockId::number(first_service.get().client().chain_info().best_number); let extrinsic = extrinsic_factory(&first_service.get(), first_user_data); - futures::executor::block_on(first_service.get().transaction_pool().submit_one(&best_block, extrinsic)).unwrap(); + + futures::executor::block_on( + first_service.get().transaction_pool().submit_one(&best_block, extrinsic) + ).expect("failed to submit extrinsic"); + network.run_until_all_full( |_index, service| service.get().transaction_pool().ready().count() == 1, |_index, _service| true, diff --git a/client/transaction-pool/graph/src/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index a62822a918..3a6573d9bd 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -545,7 +545,7 @@ impl ValidatedPool { } /// Get an iterator for ready transactions ordered by priority - pub fn ready(&self) -> impl Iterator> { + pub fn ready(&self) -> impl Iterator> + Send { self.pool.read().ready() } diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index 7ee73b862a..3c240611f0 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -31,12 +31,12 @@ pub use sc_transaction_graph as txpool; pub use crate::api::{FullChainApi, LightChainApi}; use std::{collections::HashMap, sync::Arc, pin::Pin}; -use futures::{Future, FutureExt, future::ready}; +use futures::{Future, FutureExt, future::ready, channel::oneshot}; use parking_lot::Mutex; use sp_runtime::{ generic::BlockId, - traits::{Block as BlockT, NumberFor, AtLeast32Bit, Extrinsic}, + traits::{Block as BlockT, NumberFor, AtLeast32Bit, Extrinsic, Zero}, }; use sp_transaction_pool::{ TransactionPool, PoolStatus, ImportNotificationStream, TxHash, TransactionFor, @@ -44,6 +44,12 @@ use sp_transaction_pool::{ }; use wasm_timer::Instant; +type BoxedReadyIterator = Box>> + Send>; + +type ReadyIteratorFor = BoxedReadyIterator, sc_transaction_graph::ExtrinsicFor>; + +type PolledIterator = Pin> + Send>>; + /// Basic implementation of transaction pool that can be customized by providing PoolApi. pub struct BasicPool where @@ -54,6 +60,48 @@ pub struct BasicPool api: Arc, revalidation_strategy: Arc>>>, revalidation_queue: Arc>, + ready_poll: Arc, Block>>>, +} + +struct ReadyPoll { + updated_at: NumberFor, + pollers: Vec<(NumberFor, oneshot::Sender)>, +} + +impl Default for ReadyPoll { + fn default() -> Self { + Self { + updated_at: NumberFor::::zero(), + pollers: Default::default(), + } + } +} + +impl ReadyPoll { + fn trigger(&mut self, number: NumberFor, iterator_factory: impl Fn() -> T) { + self.updated_at = number; + + let mut idx = 0; + while idx < self.pollers.len() { + if self.pollers[idx].0 <= number { + let poller_sender = self.pollers.swap_remove(idx); + log::debug!(target: "txpool", "Sending ready signal at block {}", number); + let _ = poller_sender.1.send(iterator_factory()); + } else { + idx += 1; + } + } + } + + fn add(&mut self, number: NumberFor) -> oneshot::Receiver { + let (sender, receiver) = oneshot::channel(); + self.pollers.push((number, sender)); + receiver + } + + fn updated_at(&self) -> NumberFor { + self.updated_at + } } #[cfg(not(target_os = "unknown"))] @@ -128,6 +176,7 @@ impl BasicPool RevalidationType::Full => RevalidationStrategy::Always, } )), + ready_poll: Default::default(), }, background_task, ) @@ -196,10 +245,6 @@ impl TransactionPool for BasicPool self.pool.validated_pool().status() } - fn ready(&self) -> Box>> { - Box::new(self.pool.validated_pool().ready()) - } - fn import_notification_stream(&self) -> ImportNotificationStream> { self.pool.validated_pool().import_notification_stream() } @@ -215,6 +260,27 @@ impl TransactionPool for BasicPool fn ready_transaction(&self, hash: &TxHash) -> Option> { self.pool.validated_pool().ready_by_hash(hash) } + + fn ready_at(&self, at: NumberFor) -> PolledIterator { + if self.ready_poll.lock().updated_at() >= at { + let iterator: ReadyIteratorFor = Box::new(self.pool.validated_pool().ready()); + return Box::pin(futures::future::ready(iterator)); + } + + Box::pin( + self.ready_poll + .lock() + .add(at) + .map(|received| received.unwrap_or_else(|e| { + log::warn!("Error receiving pending set: {:?}", e); + Box::new(vec![].into_iter()) + })) + ) + } + + fn ready(&self) -> ReadyIteratorFor { + Box::new(self.pool.validated_pool().ready()) + } } #[cfg_attr(test, derive(Debug))] @@ -329,6 +395,7 @@ impl MaintainedTransactionPool for BasicPool let revalidation_strategy = self.revalidation_strategy.clone(); let retracted = retracted.clone(); let revalidation_queue = self.revalidation_queue.clone(); + let ready_poll = self.ready_poll.clone(); async move { // We don't query block if we won't prune anything @@ -348,6 +415,10 @@ impl MaintainedTransactionPool for BasicPool } } + let extra_pool = pool.clone(); + // After #5200 lands, this arguably might be moved to the handler of "all blocks notification". + ready_poll.lock().trigger(block_number, move || Box::new(extra_pool.validated_pool().ready())); + if next_action.resubmit { let mut resubmit_transactions = Vec::new(); diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index 7494ba2684..27cb6c62a5 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -28,6 +28,7 @@ use substrate_test_runtime_client::{ }; use substrate_test_runtime_transaction_pool::{TestApi, uxt}; use crate::revalidation::BACKGROUND_REVALIDATION_INTERVAL; +use futures::task::Poll; fn pool() -> Pool { Pool::new(Default::default(), TestApi::with_alice_nonce(209).into()) @@ -600,5 +601,56 @@ fn fork_aware_finalization() { assert_eq!(stream.next(), Some(TransactionStatus::Finalized(e1.clone()))); assert_eq!(stream.next(), None); } +} + +#[test] +fn ready_set_should_not_resolve_before_block_update() { + let (pool, _guard) = maintained_pool(); + let xt1 = uxt(Alice, 209); + block_on(pool.submit_one(&BlockId::number(1), xt1.clone())).expect("1. Imported"); + + assert!(pool.ready_at(1).now_or_never().is_none()); +} + +#[test] +fn ready_set_should_resolve_after_block_update() { + let (pool, _guard) = maintained_pool(); + pool.api.push_block(1, vec![]); + + let xt1 = uxt(Alice, 209); + + block_on(pool.submit_one(&BlockId::number(1), xt1.clone())).expect("1. Imported"); + block_on(pool.maintain(block_event(1))); + assert!(pool.ready_at(1).now_or_never().is_some()); } + +#[test] +fn ready_set_should_eventually_resolve_when_block_update_arrives() { + let (pool, _guard) = maintained_pool(); + pool.api.push_block(1, vec![]); + + let xt1 = uxt(Alice, 209); + + block_on(pool.submit_one(&BlockId::number(1), xt1.clone())).expect("1. Imported"); + + let noop_waker = futures::task::noop_waker(); + let mut context = futures::task::Context::from_waker(&noop_waker); + + let mut ready_set_future = pool.ready_at(1); + if let Poll::Ready(_) = ready_set_future.poll_unpin(&mut context) { + panic!("Ready set should not be ready before block update!"); + } + + block_on(pool.maintain(block_event(1))); + + match ready_set_future.poll_unpin(&mut context) { + Poll::Pending => { + panic!("Ready set should become ready after block update!"); + }, + Poll::Ready(iterator) => { + let data = iterator.collect::>(); + assert_eq!(data.len(), 1); + } + } +} \ No newline at end of file diff --git a/primitives/blockchain/src/error.rs b/primitives/blockchain/src/error.rs index a4ec9c2995..e479b8abe9 100644 --- a/primitives/blockchain/src/error.rs +++ b/primitives/blockchain/src/error.rs @@ -127,6 +127,8 @@ pub enum Error { /// Incomplete block import pipeline. #[display(fmt = "Incomplete block import pipeline.")] IncompletePipeline, + #[display(fmt = "Transaction pool not ready for block production.")] + TransactionPoolNotReady, /// A convenience variant for String #[display(fmt = "{}", _0)] Msg(String), diff --git a/primitives/transaction-pool/src/pool.rs b/primitives/transaction-pool/src/pool.rs index 89f327a523..cad0667964 100644 --- a/primitives/transaction-pool/src/pool.rs +++ b/primitives/transaction-pool/src/pool.rs @@ -29,7 +29,7 @@ use futures::{ use serde::{Deserialize, Serialize}; use sp_runtime::{ generic::BlockId, - traits::{Block as BlockT, Member}, + traits::{Block as BlockT, Member, NumberFor}, transaction_validity::{ TransactionLongevity, TransactionPriority, TransactionTag, }, @@ -210,8 +210,15 @@ pub trait TransactionPool: Send + Sync { ) -> PoolFuture>, Self::Error>; // *** Block production / Networking - /// Get an iterator for ready transactions ordered by priority - fn ready(&self) -> Box>>; + /// Get an iterator for ready transactions ordered by priority. + /// + /// Guarantees to return only when transaction pool got updated at `at` block. + /// Guarantees to return immediately when `None` is passed. + fn ready_at(&self, at: NumberFor) + -> Pin> + Send>> + Send>>; + + /// Get an iterator for ready transactions ordered by priority. + fn ready(&self) -> Box> + Send>; // *** Block production /// Remove transactions identified by given hashes (and dependent transactions) from the pool. -- GitLab From a22d57f9c371efb10b015afcc132a95f083cd326 Mon Sep 17 00:00:00 2001 From: nahuseyoum <39748285+nahuseyoum@users.noreply.github.com> Date: Tue, 17 Mar 2020 17:52:00 +0000 Subject: [PATCH 003/300] bug fix - if statement logic (#5283) if statement logic for recently sent block was inverted. --- frame/example-offchain-worker/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/example-offchain-worker/src/lib.rs b/frame/example-offchain-worker/src/lib.rs index d4905d26b0..b05d7c38da 100644 --- a/frame/example-offchain-worker/src/lib.rs +++ b/frame/example-offchain-worker/src/lib.rs @@ -276,7 +276,7 @@ impl Module { match last_send { // If we already have a value in storage and the block number is recent enough // we avoid sending another transaction at this time. - Some(Some(block)) if block + T::GracePeriod::get() < block_number => { + Some(Some(block)) if block_number < block + T::GracePeriod::get() => { Err(RECENTLY_SENT) }, // In every other case we attempt to acquire the lock and send a transaction. -- GitLab From 1b8b62b1c64503b4293ee263f715225a837836b0 Mon Sep 17 00:00:00 2001 From: derfredy Date: Wed, 18 Mar 2020 10:31:50 +0100 Subject: [PATCH 004/300] Substrate Dashboard example (#5284) --- .../grafana-dashboards/substrate-dabsboard.md | 7 + .../substrate-dashboard.json | 1621 +++++++++++++++++ 2 files changed, 1628 insertions(+) create mode 100644 .maintain/monitoring/grafana-dashboards/substrate-dabsboard.md create mode 100644 .maintain/monitoring/grafana-dashboards/substrate-dashboard.json diff --git a/.maintain/monitoring/grafana-dashboards/substrate-dabsboard.md b/.maintain/monitoring/grafana-dashboards/substrate-dabsboard.md new file mode 100644 index 0000000000..957c5de8d3 --- /dev/null +++ b/.maintain/monitoring/grafana-dashboards/substrate-dabsboard.md @@ -0,0 +1,7 @@ +## Substrate Dashboard + +### Usage + +### Prometheus job template + +### Grafana variables setup diff --git a/.maintain/monitoring/grafana-dashboards/substrate-dashboard.json b/.maintain/monitoring/grafana-dashboards/substrate-dashboard.json new file mode 100644 index 0000000000..4ed0d9c863 --- /dev/null +++ b/.maintain/monitoring/grafana-dashboards/substrate-dashboard.json @@ -0,0 +1,1621 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 24, + "iteration": 1584461546653, + "links": [ + { + "icon": "external link", + "tags": [], + "targetBlank": true, + "title": "With love from ColmenaLabs", + "tooltip": "", + "type": "link", + "url": "https://colmenalabs.org" + }, + { + "icon": "external link", + "tags": [], + "targetBlank": true, + "title": "Polkastats.io", + "tooltip": "", + "type": "link", + "url": "https://polkastats.io" + } + ], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(polkadot_block_height_number{status=\"finalized\",hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}[10m])/rate(polkadot_block_height_number{status=\"finalized\",hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}[1m])", + "intervalFactor": 1, + "legendFormat": "rate[10m] / rate[1m]", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Relative Block Production Speed", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 0 + }, + "hiddenSeries": false, + "id": 15, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "polkadot_sub_libp2p_peers_count{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "legendFormat": "{{hostname}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Peers count", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 0 + }, + "hiddenSeries": false, + "id": 17, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pluginVersion": "6.4.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "scalar(polkadot_block_height_number{status=\"best\",hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"})-scalar(polkadot_block_height_number{status=\"finalized\",hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"})", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Diff -> ( Best Block - Finalized )", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 0 + }, + "hiddenSeries": false, + "id": 18, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(polkadot_block_height_number{status=\"finalized\",hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}[10m])*60", + "intervalFactor": 10, + "legendFormat": "{{hostname}} Blocks / minute", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Block rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 6 + }, + "hiddenSeries": false, + "id": 10, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "increase(polkadot_block_height_number{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",status=~\"finalized|sync_target\"}[1m])", + "intervalFactor": 5, + "legendFormat": "{{status}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Blocks Av per min", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 6 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "polkadot_block_height_number{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",status=~\"finalized|sync_target\"}", + "legendFormat": "{{hostname}} {{status}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Block Finalized", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 6 + }, + "hiddenSeries": false, + "id": 13, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "polkadot_block_height_number{status=\"best\",hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "legendFormat": "{{hostname}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Block height", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "DS_PROMETHEUS", + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 6 + }, + "hiddenSeries": false, + "id": 20, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "data": "", + "expr": "polkadot_ready_transactions_number{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "hide": false, + "legendFormat": "{{hostname}}", + "refId": "A", + "target": "txcount", + "type": "timeseries" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "TXs Count", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 12 + }, + "hiddenSeries": false, + "id": 23, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "polkadot_sync_extra_finality_proofs_active{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "legendFormat": "{{hostname}} active", + "refId": "A" + }, + { + "expr": "polkadot_sync_extra_finality_proofs_failed{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "legendFormat": "{{hostname}} failed", + "refId": "B" + }, + { + "expr": "polkadot_sync_extra_finality_proofs_importing{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "legendFormat": "{{hostname}} importing", + "refId": "C" + }, + { + "expr": "polkadot_sync_extra_finality_proofs_pending{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "legendFormat": "{{hostname}} pending", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Sync Proof", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 12 + }, + "hiddenSeries": false, + "id": 22, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "polkadot_sync_extra_justifications_active{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "legendFormat": "{{hostname}} active", + "refId": "A" + }, + { + "expr": "polkadot_sync_extra_justifications_failed{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "legendFormat": "{{hostname}} failed", + "refId": "B" + }, + { + "expr": "polkadot_sync_extra_justifications_importing{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "legendFormat": "{{hostname}} importing", + "refId": "C" + }, + { + "expr": "polkadot_sync_extra_justifications_pending{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "legendFormat": "{{hostname}} pending", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Sync justifications", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 12 + }, + "hiddenSeries": false, + "id": 24, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "polkadot_sub_libp2p_connections{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "hide": false, + "legendFormat": "{{hostname}} connections", + "refId": "A" + }, + { + "expr": "polkadot_sub_libp2p_is_major_syncing{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "hide": false, + "legendFormat": "{{hostname}} syncing", + "refId": "B" + }, + { + "expr": "polkadot_sub_libp2p_kbuckets_num_nodes{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "hide": false, + "legendFormat": "{{hostname}} num_nodes", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "sub_libp2p", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 12 + }, + "hiddenSeries": false, + "id": 26, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "polkadot_sub_libp2p_notifications_total{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",protocol=\"FRNK\",direction=\"in\"}", + "hide": false, + "legendFormat": "{{hostname}} FRNK in", + "refId": "A" + }, + { + "expr": "polkadot_sub_libp2p_notifications_total{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",protocol=\"FRNK\",direction=\"out\"}", + "hide": false, + "legendFormat": "{{hostname}} FRNK out", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "libp2p_notifications", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 18 + }, + "hiddenSeries": false, + "id": 28, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "polkadot_cpu_usage_percentage{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "legendFormat": "{{hostname}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU usage %", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 18 + }, + "hiddenSeries": false, + "id": 27, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "polkadot_memory_usage_bytes{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", + "legendFormat": "{{hostname}} Mem bytes", + "refId": "A" + }, + { + "expr": "node_memory_MemFree_bytes{hostname=\"[[hostname]]\",job=\"node_[[hostname]]\",network=\"[[network]]\"}", + "hide": true, + "legendFormat": "{{hostname}} Mem Free", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 2, + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 18 + }, + "hiddenSeries": false, + "id": 25, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "polkadot_sub_libp2p_network_per_sec_bytes", + "hide": false, + "legendFormat": "{{hostname}}", + "refId": "A" + }, + { + "expr": "polkadot_sub_libp2p_notifications_total", + "hide": true, + "legendFormat": "{{hostname}}", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "libp2p_network_per_sec_bytes", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 18 + }, + "hiddenSeries": false, + "id": 29, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pluginVersion": "6.5.2", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "polkadot_sub_libp2p_notifications_total{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",protocol=\"dot1\",direction=\"in\"}", + "hide": false, + "legendFormat": "{{hostname}} dot1 in", + "refId": "B" + }, + { + "expr": "polkadot_sub_libp2p_notifications_total{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",protocol=\"dot2\",direction=\"in\"}", + "hide": false, + "legendFormat": "{{hostname}} dot2 in", + "refId": "C" + }, + { + "expr": "polkadot_sub_libp2p_notifications_total{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",protocol=\"dot2\",direction=\"out\"}", + "hide": false, + "legendFormat": "{{hostname}} dot2 out", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "libp2p_notifications", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "30s", + "schemaVersion": 21, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": null, + "current": { + "text": "kusama", + "value": "kusama" + }, + "datasource": "DS_PROMETHEUS", + "definition": "label_values(network)", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "network", + "options": [], + "query": "label_values(network)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "kusama-public-4", + "value": "kusama-public-4" + }, + "datasource": "DS_PROMETHEUS", + "definition": "label_values(hostname)", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "hostname", + "options": [], + "query": "label_values(hostname)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Substrate Dashboard", + "uid": "ColmenaLabs", + "version": 10 +} -- GitLab From 32a7295241e1518f09974a5402f0f27588ee51ce Mon Sep 17 00:00:00 2001 From: lwshang Date: Wed, 18 Mar 2020 05:32:03 -0400 Subject: [PATCH 005/300] Print non-output messages to stderr in subkey (#5286) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Print non-output messages to stderr in subkey * Update bin/utils/subkey/src/main.rs Co-authored-by: Bastian Köcher --- bin/utils/subkey/src/main.rs | 5 ++--- bin/utils/subkey/src/rpc.rs | 2 +- bin/utils/subkey/src/vanity.rs | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/bin/utils/subkey/src/main.rs b/bin/utils/subkey/src/main.rs index 33209692ca..ae020a062f 100644 --- a/bin/utils/subkey/src/main.rs +++ b/bin/utils/subkey/src/main.rs @@ -81,7 +81,7 @@ trait Crypto: Sized { { if let Ok((pair, seed)) = Self::Pair::from_phrase(uri, password) { let public_key = Self::public_from_pair(&pair); - + match output { OutputType::Json => { let json = json!({ @@ -135,7 +135,6 @@ trait Crypto: Sized { ); }, } - } else if let Ok((public_key, v)) = ::Public::from_string_with_version(uri) { @@ -167,7 +166,7 @@ trait Crypto: Sized { }, } } else { - println!("Invalid phrase/URI given"); + eprintln!("Invalid phrase/URI given"); } } } diff --git a/bin/utils/subkey/src/rpc.rs b/bin/utils/subkey/src/rpc.rs index 7b3cde5958..e08ccc19a2 100644 --- a/bin/utils/subkey/src/rpc.rs +++ b/bin/utils/subkey/src/rpc.rs @@ -42,7 +42,7 @@ impl RpcClient { client.insert_key(key_type, suri, public).map(|_| ()) }) .map_err(|e| { - println!("Error inserting key: {:?}", e); + eprintln!("Error inserting key: {:?}", e); }) ); } diff --git a/bin/utils/subkey/src/vanity.rs b/bin/utils/subkey/src/vanity.rs index ff8703a990..8a167cd062 100644 --- a/bin/utils/subkey/src/vanity.rs +++ b/bin/utils/subkey/src/vanity.rs @@ -69,7 +69,7 @@ pub(super) fn generate_key(desired: &str) -> Result, &'sta return Err("Pattern must not be empty"); } - println!("Generating key containing pattern '{}'", desired); + eprintln!("Generating key containing pattern '{}'", desired); let top = 45 + (desired.len() * 48); let mut best = 0; @@ -94,14 +94,14 @@ pub(super) fn generate_key(desired: &str) -> Result, &'sta score: score, }; if best >= top { - println!("best: {} == top: {}", best, top); + eprintln!("best: {} == top: {}", best, top); return Ok(keypair); } } done += 1; if done % good_waypoint(done) == 0 { - println!("{} keys searched; best is {}/{} complete", done, best, top); + eprintln!("{} keys searched; best is {}/{} complete", done, best, top); } } } -- GitLab From 69d9aa0ba1ae3ffdf467eda3a7864b52a28b2618 Mon Sep 17 00:00:00 2001 From: gabriel klawitter Date: Wed, 18 Mar 2020 15:38:29 +0530 Subject: [PATCH 006/300] ci: check_runtime: fetch release tag iii (#5292) --- .maintain/gitlab/check_runtime.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.maintain/gitlab/check_runtime.sh b/.maintain/gitlab/check_runtime.sh index 1eec8311ef..5b7e25e3af 100755 --- a/.maintain/gitlab/check_runtime.sh +++ b/.maintain/gitlab/check_runtime.sh @@ -33,7 +33,7 @@ git log --graph --oneline --decorate=short -n 10 boldprint "make sure the master branch and release tag are available in shallow clones" git fetch --depth=${GIT_DEPTH:-100} origin master git fetch --depth=${GIT_DEPTH:-100} origin release -git tag release FETCH_HEAD +git tag -f release FETCH_HEAD git log -n1 release -- GitLab From 07da0f586bbc72e40bd890d89dab6cebbb27247a Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 18 Mar 2020 11:13:58 +0100 Subject: [PATCH 007/300] Revert "Substrate Dashboard example (#5284)" (#5293) This reverts commit 1b8b62b1c64503b4293ee263f715225a837836b0. --- .../grafana-dashboards/substrate-dabsboard.md | 7 - .../substrate-dashboard.json | 1621 ----------------- 2 files changed, 1628 deletions(-) delete mode 100644 .maintain/monitoring/grafana-dashboards/substrate-dabsboard.md delete mode 100644 .maintain/monitoring/grafana-dashboards/substrate-dashboard.json diff --git a/.maintain/monitoring/grafana-dashboards/substrate-dabsboard.md b/.maintain/monitoring/grafana-dashboards/substrate-dabsboard.md deleted file mode 100644 index 957c5de8d3..0000000000 --- a/.maintain/monitoring/grafana-dashboards/substrate-dabsboard.md +++ /dev/null @@ -1,7 +0,0 @@ -## Substrate Dashboard - -### Usage - -### Prometheus job template - -### Grafana variables setup diff --git a/.maintain/monitoring/grafana-dashboards/substrate-dashboard.json b/.maintain/monitoring/grafana-dashboards/substrate-dashboard.json deleted file mode 100644 index 4ed0d9c863..0000000000 --- a/.maintain/monitoring/grafana-dashboards/substrate-dashboard.json +++ /dev/null @@ -1,1621 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 24, - "iteration": 1584461546653, - "links": [ - { - "icon": "external link", - "tags": [], - "targetBlank": true, - "title": "With love from ColmenaLabs", - "tooltip": "", - "type": "link", - "url": "https://colmenalabs.org" - }, - { - "icon": "external link", - "tags": [], - "targetBlank": true, - "title": "Polkastats.io", - "tooltip": "", - "type": "link", - "url": "https://polkastats.io" - } - ], - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 8, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(polkadot_block_height_number{status=\"finalized\",hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}[10m])/rate(polkadot_block_height_number{status=\"finalized\",hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}[1m])", - "intervalFactor": 1, - "legendFormat": "rate[10m] / rate[1m]", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Relative Block Production Speed", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 6, - "y": 0 - }, - "hiddenSeries": false, - "id": 15, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "polkadot_sub_libp2p_peers_count{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "legendFormat": "{{hostname}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Peers count", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "cacheTimeout": null, - "dashLength": 10, - "dashes": false, - "datasource": null, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 12, - "y": 0 - }, - "hiddenSeries": false, - "id": 17, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pluginVersion": "6.4.1", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "scalar(polkadot_block_height_number{status=\"best\",hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"})-scalar(polkadot_block_height_number{status=\"finalized\",hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"})", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Diff -> ( Best Block - Finalized )", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "cacheTimeout": null, - "dashLength": 10, - "dashes": false, - "datasource": null, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 18, - "y": 0 - }, - "hiddenSeries": false, - "id": 18, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(polkadot_block_height_number{status=\"finalized\",hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}[10m])*60", - "intervalFactor": 10, - "legendFormat": "{{hostname}} Blocks / minute", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Block rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 0, - "y": 6 - }, - "hiddenSeries": false, - "id": 10, - "interval": "", - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "increase(polkadot_block_height_number{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",status=~\"finalized|sync_target\"}[1m])", - "intervalFactor": 5, - "legendFormat": "{{status}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Blocks Av per min", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 6, - "y": 6 - }, - "hiddenSeries": false, - "id": 14, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "polkadot_block_height_number{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",status=~\"finalized|sync_target\"}", - "legendFormat": "{{hostname}} {{status}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Block Finalized", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 12, - "y": 6 - }, - "hiddenSeries": false, - "id": 13, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "polkadot_block_height_number{status=\"best\",hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "legendFormat": "{{hostname}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Block height", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "DS_PROMETHEUS", - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 18, - "y": 6 - }, - "hiddenSeries": false, - "id": 20, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "data": "", - "expr": "polkadot_ready_transactions_number{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "hide": false, - "legendFormat": "{{hostname}}", - "refId": "A", - "target": "txcount", - "type": "timeseries" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "TXs Count", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 0, - "y": 12 - }, - "hiddenSeries": false, - "id": 23, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "polkadot_sync_extra_finality_proofs_active{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "legendFormat": "{{hostname}} active", - "refId": "A" - }, - { - "expr": "polkadot_sync_extra_finality_proofs_failed{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "legendFormat": "{{hostname}} failed", - "refId": "B" - }, - { - "expr": "polkadot_sync_extra_finality_proofs_importing{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "legendFormat": "{{hostname}} importing", - "refId": "C" - }, - { - "expr": "polkadot_sync_extra_finality_proofs_pending{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "legendFormat": "{{hostname}} pending", - "refId": "D" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Sync Proof", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 6, - "y": 12 - }, - "hiddenSeries": false, - "id": 22, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "polkadot_sync_extra_justifications_active{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "legendFormat": "{{hostname}} active", - "refId": "A" - }, - { - "expr": "polkadot_sync_extra_justifications_failed{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "legendFormat": "{{hostname}} failed", - "refId": "B" - }, - { - "expr": "polkadot_sync_extra_justifications_importing{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "legendFormat": "{{hostname}} importing", - "refId": "C" - }, - { - "expr": "polkadot_sync_extra_justifications_pending{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "legendFormat": "{{hostname}} pending", - "refId": "D" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Sync justifications", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 12, - "y": 12 - }, - "hiddenSeries": false, - "id": 24, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "polkadot_sub_libp2p_connections{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "hide": false, - "legendFormat": "{{hostname}} connections", - "refId": "A" - }, - { - "expr": "polkadot_sub_libp2p_is_major_syncing{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "hide": false, - "legendFormat": "{{hostname}} syncing", - "refId": "B" - }, - { - "expr": "polkadot_sub_libp2p_kbuckets_num_nodes{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "hide": false, - "legendFormat": "{{hostname}} num_nodes", - "refId": "C" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "sub_libp2p", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 18, - "y": 12 - }, - "hiddenSeries": false, - "id": 26, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "polkadot_sub_libp2p_notifications_total{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",protocol=\"FRNK\",direction=\"in\"}", - "hide": false, - "legendFormat": "{{hostname}} FRNK in", - "refId": "A" - }, - { - "expr": "polkadot_sub_libp2p_notifications_total{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",protocol=\"FRNK\",direction=\"out\"}", - "hide": false, - "legendFormat": "{{hostname}} FRNK out", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "libp2p_notifications", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 0, - "y": 18 - }, - "hiddenSeries": false, - "id": 28, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "polkadot_cpu_usage_percentage{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "legendFormat": "{{hostname}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "CPU usage %", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 6, - "y": 18 - }, - "hiddenSeries": false, - "id": 27, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "polkadot_memory_usage_bytes{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\"}", - "legendFormat": "{{hostname}} Mem bytes", - "refId": "A" - }, - { - "expr": "node_memory_MemFree_bytes{hostname=\"[[hostname]]\",job=\"node_[[hostname]]\",network=\"[[network]]\"}", - "hide": true, - "legendFormat": "{{hostname}} Mem Free", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Memory", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 2, - "format": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": false - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 12, - "y": 18 - }, - "hiddenSeries": false, - "id": 25, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "polkadot_sub_libp2p_network_per_sec_bytes", - "hide": false, - "legendFormat": "{{hostname}}", - "refId": "A" - }, - { - "expr": "polkadot_sub_libp2p_notifications_total", - "hide": true, - "legendFormat": "{{hostname}}", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "libp2p_network_per_sec_bytes", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "cacheTimeout": null, - "dashLength": 10, - "dashes": false, - "datasource": null, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 18, - "y": 18 - }, - "hiddenSeries": false, - "id": 29, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pluginVersion": "6.5.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "polkadot_sub_libp2p_notifications_total{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",protocol=\"dot1\",direction=\"in\"}", - "hide": false, - "legendFormat": "{{hostname}} dot1 in", - "refId": "B" - }, - { - "expr": "polkadot_sub_libp2p_notifications_total{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",protocol=\"dot2\",direction=\"in\"}", - "hide": false, - "legendFormat": "{{hostname}} dot2 in", - "refId": "C" - }, - { - "expr": "polkadot_sub_libp2p_notifications_total{hostname=\"[[hostname]]\",job=\"polkadot_[[hostname]]\",network=\"[[network]]\",protocol=\"dot2\",direction=\"out\"}", - "hide": false, - "legendFormat": "{{hostname}} dot2 out", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "libp2p_notifications", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "refresh": "30s", - "schemaVersion": 21, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "allValue": null, - "current": { - "text": "kusama", - "value": "kusama" - }, - "datasource": "DS_PROMETHEUS", - "definition": "label_values(network)", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "network", - "options": [], - "query": "label_values(network)", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - "text": "kusama-public-4", - "value": "kusama-public-4" - }, - "datasource": "DS_PROMETHEUS", - "definition": "label_values(hostname)", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "hostname", - "options": [], - "query": "label_values(hostname)", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Substrate Dashboard", - "uid": "ColmenaLabs", - "version": 10 -} -- GitLab From c6f1ba9e66c2f17afea1b17b69ae261faa68979d Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Wed, 18 Mar 2020 12:21:10 +0100 Subject: [PATCH 008/300] sc-network: Return on Poll::Pending. (#5295) If polling encounters a `Poll::Pending` we need to return it instead of continuing the loop which may turn it into a blocking operation, causing problems with executors. --- .../protocol/generic_proto/upgrade/notifications.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/client/network/src/protocol/generic_proto/upgrade/notifications.rs b/client/network/src/protocol/generic_proto/upgrade/notifications.rs index ddc07b5d6f..68898a08fe 100644 --- a/client/network/src/protocol/generic_proto/upgrade/notifications.rs +++ b/client/network/src/protocol/generic_proto/upgrade/notifications.rs @@ -200,15 +200,19 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin, Err(err) => return Poll::Ready(Some(Err(err))), } }, - Poll::Pending => - *this.handshake = NotificationsInSubstreamHandshake::PendingSend(msg), + Poll::Pending => { + *this.handshake = NotificationsInSubstreamHandshake::PendingSend(msg); + return Poll::Pending + } }, NotificationsInSubstreamHandshake::Close => match Sink::poll_close(this.socket.as_mut(), cx)? { Poll::Ready(()) => *this.handshake = NotificationsInSubstreamHandshake::Sent, - Poll::Pending => - *this.handshake = NotificationsInSubstreamHandshake::Close, + Poll::Pending => { + *this.handshake = NotificationsInSubstreamHandshake::Close; + return Poll::Pending + } }, } } -- GitLab From 79bef233db338da372619d2db585d9cc53b0052d Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Wed, 18 Mar 2020 06:04:27 -0700 Subject: [PATCH 009/300] add myself to couple of places in codebase (#5300) --- docs/CODEOWNERS | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 701df299a3..b4f1b64c4b 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -20,15 +20,22 @@ # Wasm execution and the wasm side of Substrate Runtime Interface /client/executor/ @pepyakin -/primitives/io/ @pepyakin +/primitives/io/ @pepyakin @NikVolf + +# Crypto, execution extensions, etc. +/primitives/core/ @NikVolf + +# Block production +/primitives/authorship/ @NikVolf +/client/basic-authorship/ @NikVolf # Sandboxing capability of Substrate Runtime /primitives/sr-sandbox/ @pepyakin /primitives/core/src/sandbox.rs @pepyakin # Transaction pool -/client/transaction-pool/ @tomusdrw -/primitives/transaction-pool/ @tomusdrw +/client/transaction-pool/ @tomusdrw @NikVolf +/primitives/transaction-pool/ @tomusdrw @NikVolf # Offchain /client/offchain/ @tomusdrw -- GitLab From 8516190a8855f60e9bf6f6d948ab88e65149b8aa Mon Sep 17 00:00:00 2001 From: ddorgan Date: Wed, 18 Mar 2020 13:05:10 +0000 Subject: [PATCH 010/300] Fork flaming fir 6 (#5251) --- bin/node/cli/res/flaming-fir.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/node/cli/res/flaming-fir.json b/bin/node/cli/res/flaming-fir.json index 573a9e3aa5..7ed98239b5 100644 --- a/bin/node/cli/res/flaming-fir.json +++ b/bin/node/cli/res/flaming-fir.json @@ -23,7 +23,9 @@ "tokenSymbol": "FIR" }, "forkBlocks": null, - "badBlocks": null, + "badBlocks": [ + "0xf3b02820f81988282e1da41fd479ef2aa00d63d622863639ea15d48ab6533fdc" + ], "consensusEngine": null, "genesis": { "raw": { -- GitLab From 6a38fdc0a61ff2c81f1b06b51eaf1d994000e9c3 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Wed, 18 Mar 2020 14:37:21 +0100 Subject: [PATCH 011/300] Releasing 2.0.0-alpha.4 (#5279) * Version bump * Split generate_changelog.sh into separate script Can be run in the format `generate_changelog.sh $previous_version $version`. * remove early exit from publish_draft_release.sh * adding changelog * ci: change last_github_release to also find pre-releases Co-authored-by: Martin Pugh --- .maintain/gitlab/generate_changelog.sh | 73 +++++ .maintain/gitlab/lib.sh | 16 +- .maintain/gitlab/publish_draft_release.sh | 34 +- Cargo.lock | 290 +++++++++--------- bin/node-template/node/Cargo.toml | 40 +-- bin/node-template/pallets/template/Cargo.toml | 12 +- bin/node-template/runtime/Cargo.toml | 48 +-- bin/node/cli/Cargo.toml | 108 +++---- bin/node/executor/Cargo.toml | 48 +-- bin/node/inspect/Cargo.toml | 14 +- bin/node/primitives/Cargo.toml | 8 +- bin/node/rpc-client/Cargo.toml | 6 +- bin/node/rpc/Cargo.toml | 34 +- bin/node/runtime/Cargo.toml | 106 +++---- bin/node/testing/Cargo.toml | 68 ++-- bin/node/transaction-factory/Cargo.toml | 24 +- bin/utils/chain-spec-builder/Cargo.toml | 8 +- bin/utils/subkey/Cargo.toml | 18 +- client/Cargo.toml | 38 +-- client/api/Cargo.toml | 34 +- client/authority-discovery/Cargo.toml | 22 +- client/basic-authorship/Cargo.toml | 24 +- client/block-builder/Cargo.toml | 20 +- client/chain-spec/Cargo.toml | 12 +- client/chain-spec/derive/Cargo.toml | 2 +- client/cli/Cargo.toml | 28 +- client/consensus/aura/Cargo.toml | 46 +-- client/consensus/babe/Cargo.toml | 52 ++-- client/consensus/babe/rpc/Cargo.toml | 24 +- client/consensus/epochs/Cargo.toml | 10 +- client/consensus/manual-seal/Cargo.toml | 20 +- client/consensus/pow/Cargo.toml | 22 +- client/consensus/slots/Cargo.toml | 20 +- client/consensus/uncles/Cargo.toml | 14 +- client/db/Cargo.toml | 26 +- client/executor/Cargo.toml | 24 +- client/executor/common/Cargo.toml | 10 +- client/executor/runtime-test/Cargo.toml | 12 +- client/executor/wasmi/Cargo.toml | 8 +- client/executor/wasmtime/Cargo.toml | 8 +- client/finality-grandpa/Cargo.toml | 48 +-- client/informant/Cargo.toml | 12 +- client/keystore/Cargo.toml | 6 +- client/network-gossip/Cargo.toml | 6 +- client/network/Cargo.toml | 28 +- client/network/test/Cargo.toml | 18 +- client/offchain/Cargo.toml | 22 +- client/peerset/Cargo.toml | 2 +- client/rpc-api/Cargo.toml | 12 +- client/rpc-servers/Cargo.toml | 4 +- client/rpc/Cargo.toml | 40 +-- client/service/Cargo.toml | 54 ++-- client/service/test/Cargo.toml | 14 +- client/state-db/Cargo.toml | 6 +- client/telemetry/Cargo.toml | 2 +- client/tracing/Cargo.toml | 4 +- client/transaction-pool/Cargo.toml | 18 +- client/transaction-pool/graph/Cargo.toml | 10 +- docs/CHANGELOG.md | 46 +++ frame/assets/Cargo.toml | 14 +- frame/aura/Cargo.toml | 26 +- frame/authority-discovery/Cargo.toml | 22 +- frame/authorship/Cargo.toml | 18 +- frame/babe/Cargo.toml | 28 +- frame/balances/Cargo.toml | 18 +- frame/benchmark/Cargo.toml | 14 +- frame/benchmarking/Cargo.toml | 16 +- frame/collective/Cargo.toml | 16 +- frame/contracts/Cargo.toml | 24 +- frame/contracts/common/Cargo.toml | 6 +- frame/contracts/rpc/Cargo.toml | 16 +- frame/contracts/rpc/runtime-api/Cargo.toml | 10 +- frame/democracy/Cargo.toml | 18 +- frame/elections-phragmen/Cargo.toml | 18 +- frame/elections/Cargo.toml | 16 +- frame/evm/Cargo.toml | 18 +- frame/example-offchain-worker/Cargo.toml | 12 +- frame/example/Cargo.toml | 16 +- frame/executive/Cargo.toml | 22 +- frame/finality-tracker/Cargo.toml | 18 +- frame/generic-asset/Cargo.toml | 14 +- frame/grandpa/Cargo.toml | 22 +- frame/identity/Cargo.toml | 18 +- frame/im-online/Cargo.toml | 22 +- frame/indices/Cargo.toml | 18 +- frame/membership/Cargo.toml | 14 +- frame/metadata/Cargo.toml | 6 +- frame/nicks/Cargo.toml | 16 +- frame/offences/Cargo.toml | 18 +- frame/randomness-collective-flip/Cargo.toml | 14 +- frame/recovery/Cargo.toml | 16 +- frame/scored-pool/Cargo.toml | 16 +- frame/session/Cargo.toml | 22 +- frame/session/benchmarking/Cargo.toml | 14 +- frame/society/Cargo.toml | 16 +- frame/staking/Cargo.toml | 34 +- frame/staking/reward-curve/Cargo.toml | 4 +- frame/sudo/Cargo.toml | 14 +- frame/support/Cargo.toml | 22 +- frame/support/procedural/Cargo.toml | 4 +- frame/support/procedural/tools/Cargo.toml | 4 +- .../procedural/tools/derive/Cargo.toml | 2 +- frame/support/test/Cargo.toml | 12 +- frame/system/Cargo.toml | 16 +- frame/system/rpc/runtime-api/Cargo.toml | 4 +- frame/timestamp/Cargo.toml | 22 +- frame/transaction-payment/Cargo.toml | 18 +- frame/transaction-payment/rpc/Cargo.toml | 14 +- .../rpc/runtime-api/Cargo.toml | 10 +- frame/treasury/Cargo.toml | 16 +- frame/utility/Cargo.toml | 18 +- frame/vesting/Cargo.toml | 20 +- primitives/allocator/Cargo.toml | 6 +- primitives/api/Cargo.toml | 14 +- primitives/api/proc-macro/Cargo.toml | 2 +- primitives/api/test/Cargo.toml | 16 +- primitives/application-crypto/Cargo.toml | 8 +- primitives/application-crypto/test/Cargo.toml | 8 +- primitives/arithmetic/Cargo.toml | 6 +- primitives/authority-discovery/Cargo.toml | 10 +- primitives/authorship/Cargo.toml | 8 +- primitives/block-builder/Cargo.toml | 10 +- primitives/blockchain/Cargo.toml | 10 +- primitives/consensus/aura/Cargo.toml | 14 +- primitives/consensus/babe/Cargo.toml | 16 +- primitives/consensus/common/Cargo.toml | 14 +- primitives/consensus/pow/Cargo.toml | 10 +- primitives/core/Cargo.toml | 14 +- primitives/debug-derive/Cargo.toml | 2 +- primitives/externalities/Cargo.toml | 8 +- primitives/finality-grandpa/Cargo.toml | 10 +- primitives/finality-tracker/Cargo.toml | 6 +- primitives/inherents/Cargo.toml | 6 +- primitives/io/Cargo.toml | 14 +- primitives/keyring/Cargo.toml | 6 +- primitives/offchain/Cargo.toml | 6 +- primitives/panic-handler/Cargo.toml | 2 +- primitives/phragmen/Cargo.toml | 8 +- primitives/rpc/Cargo.toml | 4 +- primitives/runtime-interface/Cargo.toml | 14 +- .../runtime-interface/proc-macro/Cargo.toml | 2 +- .../runtime-interface/test-wasm/Cargo.toml | 8 +- primitives/runtime-interface/test/Cargo.toml | 10 +- primitives/runtime/Cargo.toml | 14 +- primitives/sandbox/Cargo.toml | 8 +- primitives/serializer/Cargo.toml | 2 +- primitives/session/Cargo.toml | 10 +- primitives/staking/Cargo.toml | 6 +- primitives/state-machine/Cargo.toml | 12 +- primitives/std/Cargo.toml | 2 +- primitives/storage/Cargo.toml | 6 +- primitives/test-primitives/Cargo.toml | 6 +- primitives/timestamp/Cargo.toml | 10 +- primitives/transaction-pool/Cargo.toml | 6 +- primitives/trie/Cargo.toml | 8 +- primitives/version/Cargo.toml | 6 +- primitives/wasm-interface/Cargo.toml | 2 +- test-utils/client/Cargo.toml | 20 +- test-utils/runtime/Cargo.toml | 54 ++-- test-utils/runtime/client/Cargo.toml | 14 +- .../runtime/transaction-pool/Cargo.toml | 8 +- utils/browser/Cargo.toml | 10 +- utils/build-script-utils/Cargo.toml | 2 +- utils/fork-tree/Cargo.toml | 2 +- utils/frame/benchmarking-cli/Cargo.toml | 20 +- utils/frame/rpc/support/Cargo.toml | 10 +- utils/frame/rpc/system/Cargo.toml | 18 +- utils/prometheus/Cargo.toml | 2 +- 168 files changed, 1629 insertions(+), 1530 deletions(-) create mode 100755 .maintain/gitlab/generate_changelog.sh create mode 100644 docs/CHANGELOG.md diff --git a/.maintain/gitlab/generate_changelog.sh b/.maintain/gitlab/generate_changelog.sh new file mode 100755 index 0000000000..ba2a507e4c --- /dev/null +++ b/.maintain/gitlab/generate_changelog.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +# shellcheck source=lib.sh +source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/lib.sh" + +version="$2" +last_version="$1" + +all_changes="$(sanitised_git_logs "$last_version" "$version")" +runtime_changes="" +api_changes="" +client_changes="" +changes="" + +while IFS= read -r line; do + pr_id=$(echo "$line" | sed -E 's/.*#([0-9]+)\)$/\1/') + + # Skip if the PR has the silent label - this allows us to skip a few requests + if has_label 'paritytech/substrate' "$pr_id" 'B0-silent'; then + continue + fi + if has_label 'paritytech/substrate' "$pr_id" 'B1-runtimenoteworthy'; then + runtime_changes="$runtime_changes +$line" + fi + if has_label 'paritytech/substrate' "$pr_id" 'B1-clientnoteworthy'; then + client_changes="$client_changes +$line" + fi + if has_label 'paritytech/substrate' "$pr_id" 'B1-apinoteworthy' ; then + api_changes="$api_changes +$line" + continue + fi +done <<< "$all_changes" + +# Make the substrate section if there are any substrate changes +if [ -n "$runtime_changes" ] || + [ -n "$api_changes" ] || + [ -n "$client_changes" ]; then + changes=$(cat << EOF +Substrate changes +----------------- + +EOF +) + if [ -n "$runtime_changes" ]; then + changes="$changes + +Runtime +------- +$runtime_changes" + fi + if [ -n "$client_changes" ]; then + changes="$changes + +Client +------ +$client_changes" + fi + if [ -n "$api_changes" ]; then + changes="$changes + +API +--- +$api_changes" + fi + release_text="$release_text + +$changes" +fi + +echo "$changes" diff --git a/.maintain/gitlab/lib.sh b/.maintain/gitlab/lib.sh index c8b2d73e60..ecc9a5f542 100755 --- a/.maintain/gitlab/lib.sh +++ b/.maintain/gitlab/lib.sh @@ -15,11 +15,23 @@ sanitised_git_logs(){ } # Returns the last published release on github +# Note: we can't just use /latest because that ignores prereleases # repo: 'organization/repo' # Usage: last_github_release "$repo" last_github_release(){ - curl -H "Authorization: token $GITHUB_RELEASE_TOKEN" \ - -s "$api_base/$1/releases/latest" | jq '.tag_name' + i=0 + # Iterate over releases until we find the last release that's not just a draft + while [ $i -lt 29 ]; do + out=$(curl -H "Authorization: token $GITHUB_RELEASE_TOKEN" -s "$api_base/$1/releases" | jq ".[$i]") + echo "$out" + # Ugh when echoing to jq, we need to translate newlines into spaces :/ + if [ "$(echo "$out" | tr '\r\n' ' ' | jq '.draft')" = "false" ]; then + echo "$out" | tr '\r\n' ' ' | jq '.tag_name' + return + else + i=$((i + 1)) + fi + done } # Checks whether a tag on github has been verified diff --git a/.maintain/gitlab/publish_draft_release.sh b/.maintain/gitlab/publish_draft_release.sh index 4f73575f5b..c5813718a6 100755 --- a/.maintain/gitlab/publish_draft_release.sh +++ b/.maintain/gitlab/publish_draft_release.sh @@ -3,44 +3,12 @@ # shellcheck source=lib.sh source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/lib.sh" -# Substrate labels for PRs we want to include in the release notes -labels=( - 'B1-runtimenoteworthy' - 'B1-clientnoteworthy' - 'B1-apinoteworthy' -) - version="$CI_COMMIT_TAG" # Note that this is not the last *tagged* version, but the last *published* version last_version=$(last_github_release 'paritytech/substrate') -echo "[+] Version: $version; Previous version: $last_version" - -all_changes="$(sanitised_git_logs "$last_version" "$version")" -labelled_changes="" -echo "[+] Iterating through $(wc -l <<< "$all_changes") changes to find labelled PRs" -while IFS= read -r line; do - pr_id=$(echo "$line" | sed -E 's/.*#([0-9]+)\)$/\1/') - - # Skip if the PR has the silent label - this allows us to skip a few requests - if has_label 'paritytech/substrate' "$pr_id" 'B0-silent'; then - continue - fi - for label in "${labels[@]}"; do - if has_label 'paritytech/substrate' "$pr_id" "$label"; then - labelled_changes="$labelled_changes -$line" - fi - done -done <<< "$all_changes" - - -release_text="Substrate $version ------------------ -$labelled_changes" -echo "[+] Release text generated: " -echo "$release_text" +release_text="$(./generate_release_text.sh "$last_version" "$version")" echo "[+] Pushing release to github" # Create release on github diff --git a/Cargo.lock b/Cargo.lock index 6fc90c3c23..aa0212c0b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -567,7 +567,7 @@ dependencies = [ [[package]] name = "chain-spec-builder" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "ansi_term 0.12.1", "node-cli", @@ -1449,14 +1449,14 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "parity-scale-codec", ] [[package]] name = "frame-benchmarking" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -1470,7 +1470,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-benchmarking", "parity-scale-codec", @@ -1487,7 +1487,7 @@ dependencies = [ [[package]] name = "frame-executive" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -1506,7 +1506,7 @@ dependencies = [ [[package]] name = "frame-metadata" -version = "11.0.0-alpha.3" +version = "11.0.0-alpha.4" dependencies = [ "parity-scale-codec", "serde", @@ -1516,7 +1516,7 @@ dependencies = [ [[package]] name = "frame-support" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "bitmask", "frame-metadata", @@ -1541,7 +1541,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support-procedural-tools", "proc-macro2", @@ -1551,7 +1551,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -1562,7 +1562,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "proc-macro2", "quote", @@ -1587,7 +1587,7 @@ dependencies = [ [[package]] name = "frame-system" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "criterion 0.2.11", "frame-support", @@ -1605,7 +1605,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "parity-scale-codec", "sp-api", @@ -3347,7 +3347,7 @@ dependencies = [ [[package]] name = "node-cli" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "assert_cmd", "frame-benchmarking-cli", @@ -3418,7 +3418,7 @@ dependencies = [ [[package]] name = "node-executor" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "criterion 0.3.1", "frame-benchmarking", @@ -3452,7 +3452,7 @@ dependencies = [ [[package]] name = "node-inspect" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "derive_more", "log 0.4.8", @@ -3468,7 +3468,7 @@ dependencies = [ [[package]] name = "node-primitives" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "pretty_assertions", "sp-core", @@ -3478,7 +3478,7 @@ dependencies = [ [[package]] name = "node-rpc" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "jsonrpc-core", "node-primitives", @@ -3501,7 +3501,7 @@ dependencies = [ [[package]] name = "node-rpc-client" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "env_logger 0.7.1", "futures 0.1.29", @@ -3514,7 +3514,7 @@ dependencies = [ [[package]] name = "node-runtime" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-benchmarking", "frame-executive", @@ -3577,7 +3577,7 @@ dependencies = [ [[package]] name = "node-template" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "futures 0.3.4", "log 0.4.8", @@ -3606,7 +3606,7 @@ dependencies = [ [[package]] name = "node-template-runtime" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-executive", "frame-support", @@ -3638,7 +3638,7 @@ dependencies = [ [[package]] name = "node-testing" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "criterion 0.3.1", "frame-support", @@ -3684,7 +3684,7 @@ dependencies = [ [[package]] name = "node-transaction-factory" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "log 0.4.8", "parity-scale-codec", @@ -3882,7 +3882,7 @@ dependencies = [ [[package]] name = "pallet-assets" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -3896,7 +3896,7 @@ dependencies = [ [[package]] name = "pallet-aura" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -3918,7 +3918,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -3936,7 +3936,7 @@ dependencies = [ [[package]] name = "pallet-authorship" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -3952,7 +3952,7 @@ dependencies = [ [[package]] name = "pallet-babe" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -3977,7 +3977,7 @@ dependencies = [ [[package]] name = "pallet-balances" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-benchmarking", "frame-support", @@ -3993,7 +3993,7 @@ dependencies = [ [[package]] name = "pallet-benchmark" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-benchmarking", "frame-support", @@ -4007,7 +4007,7 @@ dependencies = [ [[package]] name = "pallet-collective" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4023,7 +4023,7 @@ dependencies = [ [[package]] name = "pallet-contracts" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "assert_matches", "frame-support", @@ -4048,7 +4048,7 @@ dependencies = [ [[package]] name = "pallet-contracts-primitives" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -4057,7 +4057,7 @@ dependencies = [ [[package]] name = "pallet-contracts-rpc" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4076,7 +4076,7 @@ dependencies = [ [[package]] name = "pallet-contracts-rpc-runtime-api" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "pallet-contracts-primitives", "parity-scale-codec", @@ -4087,7 +4087,7 @@ dependencies = [ [[package]] name = "pallet-democracy" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4104,7 +4104,7 @@ dependencies = [ [[package]] name = "pallet-elections" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4120,7 +4120,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4138,7 +4138,7 @@ dependencies = [ [[package]] name = "pallet-evm" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "evm", "frame-support", @@ -4189,7 +4189,7 @@ dependencies = [ [[package]] name = "pallet-finality-tracker" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4206,7 +4206,7 @@ dependencies = [ [[package]] name = "pallet-generic-asset" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4220,7 +4220,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4238,7 +4238,7 @@ dependencies = [ [[package]] name = "pallet-identity" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "enumflags2", "frame-benchmarking", @@ -4255,7 +4255,7 @@ dependencies = [ [[package]] name = "pallet-im-online" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4273,7 +4273,7 @@ dependencies = [ [[package]] name = "pallet-indices" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4289,7 +4289,7 @@ dependencies = [ [[package]] name = "pallet-membership" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4303,7 +4303,7 @@ dependencies = [ [[package]] name = "pallet-nicks" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4318,7 +4318,7 @@ dependencies = [ [[package]] name = "pallet-offences" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4334,7 +4334,7 @@ dependencies = [ [[package]] name = "pallet-randomness-collective-flip" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4348,7 +4348,7 @@ dependencies = [ [[package]] name = "pallet-recovery" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "enumflags2", "frame-support", @@ -4364,7 +4364,7 @@ dependencies = [ [[package]] name = "pallet-scored-pool" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4379,7 +4379,7 @@ dependencies = [ [[package]] name = "pallet-session" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4399,7 +4399,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-benchmarking", "frame-system", @@ -4411,7 +4411,7 @@ dependencies = [ [[package]] name = "pallet-society" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4427,7 +4427,7 @@ dependencies = [ [[package]] name = "pallet-staking" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-benchmarking", "frame-support", @@ -4452,7 +4452,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -4463,7 +4463,7 @@ dependencies = [ [[package]] name = "pallet-sudo" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4477,7 +4477,7 @@ dependencies = [ [[package]] name = "pallet-template" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4490,7 +4490,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-benchmarking", "frame-support", @@ -4508,7 +4508,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4523,7 +4523,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4540,7 +4540,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "parity-scale-codec", @@ -4553,7 +4553,7 @@ dependencies = [ [[package]] name = "pallet-treasury" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4568,7 +4568,7 @@ dependencies = [ [[package]] name = "pallet-utility" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -4583,7 +4583,7 @@ dependencies = [ [[package]] name = "pallet-vesting" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "enumflags2", "frame-benchmarking", @@ -5609,7 +5609,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "bytes 0.5.4", "derive_more", @@ -5639,7 +5639,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", @@ -5663,7 +5663,7 @@ dependencies = [ [[package]] name = "sc-block-builder" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -5680,7 +5680,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "impl-trait-for-tuples", "sc-chain-spec-derive", @@ -5694,7 +5694,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5704,7 +5704,7 @@ dependencies = [ [[package]] name = "sc-cli" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "ansi_term 0.12.1", "app_dirs", @@ -5743,7 +5743,7 @@ dependencies = [ [[package]] name = "sc-client" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "derive_more", "env_logger 0.7.1", @@ -5781,7 +5781,7 @@ dependencies = [ [[package]] name = "sc-client-api" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "derive_more", "fnv", @@ -5813,7 +5813,7 @@ dependencies = [ [[package]] name = "sc-client-db" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "env_logger 0.7.1", "hash-db", @@ -5845,7 +5845,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "derive_more", "env_logger 0.7.1", @@ -5883,7 +5883,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "derive_more", "env_logger 0.7.1", @@ -5932,7 +5932,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "derive_more", "futures 0.3.4", @@ -5957,7 +5957,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "fork-tree", "parity-scale-codec", @@ -5969,7 +5969,7 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "assert_matches", "derive_more", @@ -5998,7 +5998,7 @@ dependencies = [ [[package]] name = "sc-consensus-pow" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "derive_more", "futures 0.3.4", @@ -6018,7 +6018,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", @@ -6039,7 +6039,7 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "log 0.4.8", "sc-client-api", @@ -6052,7 +6052,7 @@ dependencies = [ [[package]] name = "sc-executor" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "assert_matches", "derive_more", @@ -6086,7 +6086,7 @@ dependencies = [ [[package]] name = "sc-executor-common" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "derive_more", "log 0.4.8", @@ -6133,7 +6133,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "assert_matches", "env_logger 0.7.1", @@ -6175,7 +6175,7 @@ dependencies = [ [[package]] name = "sc-informant" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "ansi_term 0.12.1", "futures 0.3.4", @@ -6191,7 +6191,7 @@ dependencies = [ [[package]] name = "sc-keystore" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "derive_more", "hex", @@ -6206,7 +6206,7 @@ dependencies = [ [[package]] name = "sc-network" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "assert_matches", "async-std", @@ -6265,7 +6265,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", @@ -6304,7 +6304,7 @@ dependencies = [ [[package]] name = "sc-offchain" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "bytes 0.5.4", "env_logger 0.7.1", @@ -6336,7 +6336,7 @@ dependencies = [ [[package]] name = "sc-peerset" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "futures 0.3.4", "libp2p", @@ -6348,7 +6348,7 @@ dependencies = [ [[package]] name = "sc-rpc" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "assert_matches", "futures 0.1.29", @@ -6386,7 +6386,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "derive_more", "futures 0.3.4", @@ -6408,7 +6408,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "jsonrpc-core", "jsonrpc-http-server", @@ -6435,7 +6435,7 @@ dependencies = [ [[package]] name = "sc-service" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "derive_more", "exit-future", @@ -6507,7 +6507,7 @@ dependencies = [ [[package]] name = "sc-state-db" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "env_logger 0.7.1", "log 0.4.8", @@ -6521,7 +6521,7 @@ dependencies = [ [[package]] name = "sc-telemetry" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "bytes 0.5.4", "futures 0.3.4", @@ -6542,7 +6542,7 @@ dependencies = [ [[package]] name = "sc-tracing" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "erased-serde", "log 0.4.8", @@ -6557,7 +6557,7 @@ dependencies = [ [[package]] name = "sc-transaction-graph" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "assert_matches", "criterion 0.3.1", @@ -6579,7 +6579,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "derive_more", "futures 0.3.4", @@ -6968,7 +6968,7 @@ checksum = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" [[package]] name = "sp-allocator" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "derive_more", "log 0.4.8", @@ -6979,7 +6979,7 @@ dependencies = [ [[package]] name = "sp-api" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "hash-db", "parity-scale-codec", @@ -6994,7 +6994,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "blake2-rfc", "proc-macro-crate", @@ -7024,7 +7024,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "parity-scale-codec", "serde", @@ -7046,7 +7046,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "criterion 0.3.1", "integer-sqrt", @@ -7061,7 +7061,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "parity-scale-codec", "sp-api", @@ -7072,7 +7072,7 @@ dependencies = [ [[package]] name = "sp-authorship" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -7082,7 +7082,7 @@ dependencies = [ [[package]] name = "sp-block-builder" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "parity-scale-codec", "sp-api", @@ -7093,7 +7093,7 @@ dependencies = [ [[package]] name = "sp-blockchain" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "derive_more", "log 0.4.8", @@ -7108,7 +7108,7 @@ dependencies = [ [[package]] name = "sp-consensus" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "derive_more", "futures 0.3.4", @@ -7130,7 +7130,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "parity-scale-codec", "sp-api", @@ -7143,7 +7143,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "parity-scale-codec", "schnorrkel", @@ -7158,7 +7158,7 @@ dependencies = [ [[package]] name = "sp-consensus-pow" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "parity-scale-codec", "sp-api", @@ -7169,7 +7169,7 @@ dependencies = [ [[package]] name = "sp-core" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "base58", "blake2-rfc", @@ -7214,7 +7214,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "proc-macro2", "quote", @@ -7223,7 +7223,7 @@ dependencies = [ [[package]] name = "sp-externalities" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "environmental", "sp-std", @@ -7232,7 +7232,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "parity-scale-codec", "serde", @@ -7244,7 +7244,7 @@ dependencies = [ [[package]] name = "sp-finality-tracker" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -7253,7 +7253,7 @@ dependencies = [ [[package]] name = "sp-inherents" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "derive_more", "parity-scale-codec", @@ -7264,7 +7264,7 @@ dependencies = [ [[package]] name = "sp-io" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "hash-db", "libsecp256k1", @@ -7281,7 +7281,7 @@ dependencies = [ [[package]] name = "sp-keyring" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "lazy_static", "sp-core", @@ -7291,7 +7291,7 @@ dependencies = [ [[package]] name = "sp-offchain" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "sp-api", "sp-runtime", @@ -7299,7 +7299,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "backtrace", "log 0.4.8", @@ -7307,7 +7307,7 @@ dependencies = [ [[package]] name = "sp-phragmen" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "rand 0.7.3", "serde", @@ -7319,7 +7319,7 @@ dependencies = [ [[package]] name = "sp-rpc" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "serde", "serde_json", @@ -7328,7 +7328,7 @@ dependencies = [ [[package]] name = "sp-runtime" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "hash256-std-hasher", "impl-trait-for-tuples", @@ -7349,7 +7349,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "parity-scale-codec", "primitive-types", @@ -7368,7 +7368,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "Inflector", "proc-macro-crate", @@ -7402,7 +7402,7 @@ dependencies = [ [[package]] name = "sp-sandbox" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "assert_matches", "parity-scale-codec", @@ -7416,7 +7416,7 @@ dependencies = [ [[package]] name = "sp-serializer" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "serde", "serde_json", @@ -7424,7 +7424,7 @@ dependencies = [ [[package]] name = "sp-session" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "sp-api", "sp-core", @@ -7434,7 +7434,7 @@ dependencies = [ [[package]] name = "sp-staking" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -7443,7 +7443,7 @@ dependencies = [ [[package]] name = "sp-state-machine" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "hash-db", "hex-literal", @@ -7463,11 +7463,11 @@ dependencies = [ [[package]] name = "sp-std" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" [[package]] name = "sp-storage" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "impl-serde 0.2.3", "serde", @@ -7489,7 +7489,7 @@ dependencies = [ [[package]] name = "sp-timestamp" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -7502,7 +7502,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "derive_more", "futures 0.3.4", @@ -7515,7 +7515,7 @@ dependencies = [ [[package]] name = "sp-trie" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "criterion 0.2.11", "hash-db", @@ -7533,7 +7533,7 @@ dependencies = [ [[package]] name = "sp-version" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "impl-serde 0.2.3", "parity-scale-codec", @@ -7650,7 +7650,7 @@ dependencies = [ [[package]] name = "subkey" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "clap", "derive_more", @@ -7692,7 +7692,7 @@ dependencies = [ [[package]] name = "substrate-browser-utils" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "chrono", "clear_on_drop", @@ -7717,11 +7717,11 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" [[package]] name = "substrate-frame-rpc-support" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -7737,7 +7737,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "env_logger 0.7.1", "frame-system-rpc-runtime-api", @@ -7760,7 +7760,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "async-std", "derive_more", diff --git a/bin/node-template/node/Cargo.toml b/bin/node-template/node/Cargo.toml index 5dc0c46d99..e46e930c3f 100644 --- a/bin/node-template/node/Cargo.toml +++ b/bin/node-template/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-template" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Anonymous"] edition = "2018" license = "Unlicense" @@ -16,26 +16,26 @@ futures = "0.3.1" log = "0.4.8" structopt = "0.3.8" -sc-cli = { version = "0.8.0-alpha.2", path = "../../../client/cli" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sc-executor = { version = "0.8.0-alpha.2", path = "../../../client/executor" } -sc-service = { version = "0.8.0-alpha.2", path = "../../../client/service" } -sp-inherents = { version = "2.0.0-alpha.2", path = "../../../primitives/inherents" } -sc-transaction-pool = { version = "2.0.0-alpha.2", path = "../../../client/transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../../primitives/transaction-pool" } -sc-network = { version = "0.8.0-alpha.2", path = "../../../client/network" } -sc-consensus-aura = { version = "0.8.0-alpha.2", path = "../../../client/consensus/aura" } -sp-consensus-aura = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/aura" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/common" } -grandpa = { version = "0.8.0-alpha.2", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } -grandpa-primitives = { version = "2.0.0-alpha.2", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } -sc-client = { version = "0.8.0-alpha.2", path = "../../../client/" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../../../client/api" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sc-basic-authorship = { path = "../../../client/basic-authorship", version = "0.8.0-alpha.2"} +sc-cli = { version = "0.8.0-alpha.4", path = "../../../client/cli" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sc-executor = { version = "0.8.0-alpha.4", path = "../../../client/executor" } +sc-service = { version = "0.8.0-alpha.4", path = "../../../client/service" } +sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } +sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../primitives/transaction-pool" } +sc-network = { version = "0.8.0-alpha.4", path = "../../../client/network" } +sc-consensus-aura = { version = "0.8.0-alpha.4", path = "../../../client/consensus/aura" } +sp-consensus-aura = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/aura" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +grandpa = { version = "0.8.0-alpha.4", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } +grandpa-primitives = { version = "2.0.0-alpha.4", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } +sc-client = { version = "0.8.0-alpha.4", path = "../../../client/" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../../../client/api" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sc-basic-authorship = { path = "../../../client/basic-authorship", version = "0.8.0-alpha.4"} -node-template-runtime = { version = "2.0.0-alpha.2", path = "../runtime" } +node-template-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } [build-dependencies] vergen = "3.0.4" -build-script-utils = { version = "2.0.0-alpha.2", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } +build-script-utils = { version = "2.0.0-alpha.4", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } diff --git a/bin/node-template/pallets/template/Cargo.toml b/bin/node-template/pallets/template/Cargo.toml index b39fcc1dae..fe934b4747 100644 --- a/bin/node-template/pallets/template/Cargo.toml +++ b/bin/node-template/pallets/template/Cargo.toml @@ -2,7 +2,7 @@ authors = ['Anonymous'] edition = '2018' name = 'pallet-template' -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" license = "Unlicense" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -14,27 +14,27 @@ safe-mix = { default-features = false, version = '1.0.0' } [dependencies.frame-support] default-features = false -version = "2.0.0-alpha.2" +version = "2.0.0-alpha.4" path = "../../../../frame/support" [dependencies.system] default-features = false package = 'frame-system' -version = "2.0.0-alpha.2" +version = "2.0.0-alpha.4" path = "../../../../frame/system" [dev-dependencies.sp-core] default-features = false -version = "2.0.0-alpha.2" +version = "2.0.0-alpha.4" path = "../../../../primitives/core" [dev-dependencies.sp-io] default-features = false -version = "2.0.0-alpha.2" +version = "2.0.0-alpha.4" path = "../../../../primitives/io" [dev-dependencies.sp-runtime] default-features = false -version = "2.0.0-alpha.2" +version = "2.0.0-alpha.4" path = "../../../../primitives/runtime" diff --git a/bin/node-template/runtime/Cargo.toml b/bin/node-template/runtime/Cargo.toml index 9268dd8c05..fa4c0a9f14 100644 --- a/bin/node-template/runtime/Cargo.toml +++ b/bin/node-template/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-template-runtime" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Anonymous"] edition = "2018" license = "Unlicense" @@ -10,31 +10,31 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -aura = { version = "2.0.0-alpha.2", default-features = false, package = "pallet-aura", path = "../../../frame/aura" } -balances = { version = "2.0.0-alpha.2", default-features = false, package = "pallet-balances", path = "../../../frame/balances" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/support" } -grandpa = { version = "2.0.0-alpha.2", default-features = false, package = "pallet-grandpa", path = "../../../frame/grandpa" } -randomness-collective-flip = { version = "2.0.0-alpha.2", default-features = false, package = "pallet-randomness-collective-flip", path = "../../../frame/randomness-collective-flip" } -sudo = { version = "2.0.0-alpha.2", default-features = false, package = "pallet-sudo", path = "../../../frame/sudo" } -system = { version = "2.0.0-alpha.2", default-features = false, package = "frame-system", path = "../../../frame/system" } -timestamp = { version = "2.0.0-alpha.2", default-features = false, package = "pallet-timestamp", path = "../../../frame/timestamp" } -transaction-payment = { version = "2.0.0-alpha.2", default-features = false, package = "pallet-transaction-payment", path = "../../../frame/transaction-payment" } -frame-executive = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/executive" } +aura = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-aura", path = "../../../frame/aura" } +balances = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-balances", path = "../../../frame/balances" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/support" } +grandpa = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-grandpa", path = "../../../frame/grandpa" } +randomness-collective-flip = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-randomness-collective-flip", path = "../../../frame/randomness-collective-flip" } +sudo = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-sudo", path = "../../../frame/sudo" } +system = { version = "2.0.0-alpha.4", default-features = false, package = "frame-system", path = "../../../frame/system" } +timestamp = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-timestamp", path = "../../../frame/timestamp" } +transaction-payment = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-transaction-payment", path = "../../../frame/transaction-payment" } +frame-executive = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/executive" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/api" } -sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.2"} -sp-consensus-aura = { version = "0.8.0-alpha.2", default-features = false, path = "../../../primitives/consensus/aura" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/core" } -sp-inherents = { path = "../../../primitives/inherents", default-features = false, version = "2.0.0-alpha.2"} -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/io" } -sp-offchain = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/offchain" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/runtime" } -sp-session = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/session" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/std" } -sp-transaction-pool = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/transaction-pool" } -sp-version = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/version" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/api" } +sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.4"} +sp-consensus-aura = { version = "0.8.0-alpha.4", default-features = false, path = "../../../primitives/consensus/aura" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/core" } +sp-inherents = { path = "../../../primitives/inherents", default-features = false, version = "2.0.0-alpha.4"} +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/io" } +sp-offchain = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/offchain" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } +sp-session = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/session" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/std" } +sp-transaction-pool = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/transaction-pool" } +sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/version" } -template = { version = "2.0.0-alpha.2", default-features = false, path = "../pallets/template", package = "pallet-template" } +template = { version = "2.0.0-alpha.4", default-features = false, path = "../pallets/template", package = "pallet-template" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index e18b6b228e..f9a999763e 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-cli" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] description = "Substrate node implementation in Rust." build = "build.rs" @@ -42,68 +42,68 @@ structopt = { version = "0.3.8", optional = true } tracing = "0.1.10" # primitives -sp-authority-discovery = { version = "2.0.0-alpha.2", path = "../../../primitives/authority-discovery" } -sp-consensus-babe = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/babe" } -grandpa-primitives = { version = "2.0.0-alpha.2", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/timestamp" } -sp-finality-tracker = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/finality-tracker" } -sp-inherents = { version = "2.0.0-alpha.2", path = "../../../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.2", path = "../../../primitives/keyring" } -sp-io = { version = "2.0.0-alpha.2", path = "../../../primitives/io" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/common" } +sp-authority-discovery = { version = "2.0.0-alpha.4", path = "../../../primitives/authority-discovery" } +sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/babe" } +grandpa-primitives = { version = "2.0.0-alpha.4", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/timestamp" } +sp-finality-tracker = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/finality-tracker" } +sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } +sp-keyring = { version = "2.0.0-alpha.4", path = "../../../primitives/keyring" } +sp-io = { version = "2.0.0-alpha.4", path = "../../../primitives/io" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } # client dependencies -sc-client-api = { version = "2.0.0-alpha.2", path = "../../../client/api" } -sc-client = { version = "0.8.0-alpha.2", path = "../../../client/" } -sc-chain-spec = { version = "2.0.0-alpha.2", path = "../../../client/chain-spec" } -sc-transaction-pool = { version = "2.0.0-alpha.2", path = "../../../client/transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../../primitives/transaction-pool" } -sc-network = { version = "0.8.0-alpha.2", path = "../../../client/network" } -sc-consensus-babe = { version = "0.8.0-alpha.2", path = "../../../client/consensus/babe" } -grandpa = { version = "0.8.0-alpha.2", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } -sc-client-db = { version = "0.8.0-alpha.2", default-features = false, path = "../../../client/db" } -sc-offchain = { version = "2.0.0-alpha.2", path = "../../../client/offchain" } -sc-rpc = { version = "2.0.0-alpha.2", path = "../../../client/rpc" } -sc-basic-authorship = { version = "0.8.0-alpha.2", path = "../../../client/basic-authorship" } -sc-service = { version = "0.8.0-alpha.2", default-features = false, path = "../../../client/service" } -sc-tracing = { version = "2.0.0-alpha.2", path = "../../../client/tracing" } -sc-telemetry = { version = "2.0.0-alpha.2", path = "../../../client/telemetry" } -sc-authority-discovery = { version = "0.8.0-alpha.2", path = "../../../client/authority-discovery" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../../../client/api" } +sc-client = { version = "0.8.0-alpha.4", path = "../../../client/" } +sc-chain-spec = { version = "2.0.0-alpha.4", path = "../../../client/chain-spec" } +sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../primitives/transaction-pool" } +sc-network = { version = "0.8.0-alpha.4", path = "../../../client/network" } +sc-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../client/consensus/babe" } +grandpa = { version = "0.8.0-alpha.4", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } +sc-client-db = { version = "0.8.0-alpha.4", default-features = false, path = "../../../client/db" } +sc-offchain = { version = "2.0.0-alpha.4", path = "../../../client/offchain" } +sc-rpc = { version = "2.0.0-alpha.4", path = "../../../client/rpc" } +sc-basic-authorship = { version = "0.8.0-alpha.4", path = "../../../client/basic-authorship" } +sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../../../client/service" } +sc-tracing = { version = "2.0.0-alpha.4", path = "../../../client/tracing" } +sc-telemetry = { version = "2.0.0-alpha.4", path = "../../../client/telemetry" } +sc-authority-discovery = { version = "0.8.0-alpha.4", path = "../../../client/authority-discovery" } # frame dependencies -pallet-indices = { version = "2.0.0-alpha.2", path = "../../../frame/indices" } -pallet-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/timestamp" } -pallet-contracts = { version = "2.0.0-alpha.2", path = "../../../frame/contracts" } -frame-system = { version = "2.0.0-alpha.2", path = "../../../frame/system" } -pallet-balances = { version = "2.0.0-alpha.2", path = "../../../frame/balances" } -pallet-transaction-payment = { version = "2.0.0-alpha.2", path = "../../../frame/transaction-payment" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/support" } -pallet-im-online = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/im-online" } -pallet-authority-discovery = { version = "2.0.0-alpha.2", path = "../../../frame/authority-discovery" } +pallet-indices = { version = "2.0.0-alpha.4", path = "../../../frame/indices" } +pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/timestamp" } +pallet-contracts = { version = "2.0.0-alpha.4", path = "../../../frame/contracts" } +frame-system = { version = "2.0.0-alpha.4", path = "../../../frame/system" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../../../frame/balances" } +pallet-transaction-payment = { version = "2.0.0-alpha.4", path = "../../../frame/transaction-payment" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/support" } +pallet-im-online = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/im-online" } +pallet-authority-discovery = { version = "2.0.0-alpha.4", path = "../../../frame/authority-discovery" } # node-specific dependencies -node-runtime = { version = "2.0.0-alpha.2", path = "../runtime" } -node-rpc = { version = "2.0.0-alpha.2", path = "../rpc" } -node-primitives = { version = "2.0.0-alpha.2", path = "../primitives" } -node-executor = { version = "2.0.0-alpha.2", path = "../executor" } +node-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } +node-rpc = { version = "2.0.0-alpha.4", path = "../rpc" } +node-primitives = { version = "2.0.0-alpha.4", path = "../primitives" } +node-executor = { version = "2.0.0-alpha.4", path = "../executor" } # CLI-specific dependencies -sc-cli = { version = "0.8.0-alpha.2", optional = true, path = "../../../client/cli" } -frame-benchmarking-cli = { version = "2.0.0-alpha.2", optional = true, path = "../../../utils/frame/benchmarking-cli" } -node-transaction-factory = { version = "0.8.0-alpha.2", optional = true, path = "../transaction-factory" } -node-inspect = { version = "0.8.0-alpha.2", optional = true, path = "../inspect" } +sc-cli = { version = "0.8.0-alpha.4", optional = true, path = "../../../client/cli" } +frame-benchmarking-cli = { version = "2.0.0-alpha.4", optional = true, path = "../../../utils/frame/benchmarking-cli" } +node-transaction-factory = { version = "0.8.0-alpha.4", optional = true, path = "../transaction-factory" } +node-inspect = { version = "0.8.0-alpha.4", optional = true, path = "../inspect" } # WASM-specific dependencies wasm-bindgen = { version = "0.2.57", optional = true } wasm-bindgen-futures = { version = "0.4.7", optional = true } -browser-utils = { package = "substrate-browser-utils", path = "../../../utils/browser", optional = true, version = "0.8.0-alpha.2" } +browser-utils = { package = "substrate-browser-utils", path = "../../../utils/browser", optional = true, version = "0.8.0-alpha.4"} [dev-dependencies] -sc-keystore = { version = "2.0.0-alpha.2", path = "../../../client/keystore" } -sc-consensus-babe = { version = "0.8.0-alpha.2", features = ["test-helpers"], path = "../../../client/consensus/babe" } -sc-consensus-epochs = { version = "0.8.0-alpha.2", path = "../../../client/consensus/epochs" } +sc-keystore = { version = "2.0.0-alpha.4", path = "../../../client/keystore" } +sc-consensus-babe = { version = "0.8.0-alpha.4", features = ["test-helpers"], path = "../../../client/consensus/babe" } +sc-consensus-epochs = { version = "0.8.0-alpha.4", path = "../../../client/consensus/epochs" } sc-service-test = { version = "2.0.0-dev", path = "../../../client/service/test" } futures = "0.3.1" tempfile = "3.1.0" @@ -112,14 +112,14 @@ nix = "0.17" serde_json = "1.0" [build-dependencies] -build-script-utils = { version = "2.0.0-alpha.2", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } +build-script-utils = { version = "2.0.0-alpha.4", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } structopt = { version = "0.3.8", optional = true } -node-transaction-factory = { version = "0.8.0-alpha.2", optional = true, path = "../transaction-factory" } -node-inspect = { version = "0.8.0-alpha.2", optional = true, path = "../inspect" } -frame-benchmarking-cli = { version = "2.0.0-alpha.2", optional = true, path = "../../../utils/frame/benchmarking-cli" } +node-transaction-factory = { version = "0.8.0-alpha.4", optional = true, path = "../transaction-factory" } +node-inspect = { version = "0.8.0-alpha.4", optional = true, path = "../inspect" } +frame-benchmarking-cli = { version = "2.0.0-alpha.4", optional = true, path = "../../../utils/frame/benchmarking-cli" } [build-dependencies.sc-cli] -version = "0.8.0-alpha.2" +version = "0.8.0-alpha.4" package = "sc-cli" path = "../../../client/cli" optional = true diff --git a/bin/node/executor/Cargo.toml b/bin/node/executor/Cargo.toml index a77efcf7f8..6d02e7de80 100644 --- a/bin/node/executor/Cargo.toml +++ b/bin/node/executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-executor" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] description = "Substrate node implementation in Rust." edition = "2018" @@ -10,33 +10,33 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0" } -node-primitives = { version = "2.0.0-alpha.2", path = "../primitives" } -node-runtime = { version = "2.0.0-alpha.2", path = "../runtime" } -sc-executor = { version = "0.8.0-alpha.2", path = "../../../client/executor" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-io = { version = "2.0.0-alpha.2", path = "../../../primitives/io" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../../primitives/state-machine" } -sp-trie = { version = "2.0.0-alpha.2", path = "../../../primitives/trie" } +node-primitives = { version = "2.0.0-alpha.4", path = "../primitives" } +node-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } +sc-executor = { version = "0.8.0-alpha.4", path = "../../../client/executor" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-io = { version = "2.0.0-alpha.4", path = "../../../primitives/io" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } +sp-trie = { version = "2.0.0-alpha.4", path = "../../../primitives/trie" } trie-root = "0.16.0" -frame-benchmarking = { version = "2.0.0-alpha.2", path = "../../../frame/benchmarking" } +frame-benchmarking = { version = "2.0.0-alpha.4", path = "../../../frame/benchmarking" } [dev-dependencies] criterion = "0.3.0" -frame-support = { version = "2.0.0-alpha.2", path = "../../../frame/support" } -frame-system = { version = "2.0.0-alpha.2", path = "../../../frame/system" } -node-testing = { version = "2.0.0-alpha.2", path = "../testing" } -pallet-balances = { version = "2.0.0-alpha.2", path = "../../../frame/balances" } -pallet-contracts = { version = "2.0.0-alpha.2", path = "../../../frame/contracts" } -pallet-grandpa = { version = "2.0.0-alpha.2", path = "../../../frame/grandpa" } -pallet-im-online = { version = "2.0.0-alpha.2", path = "../../../frame/im-online" } -pallet-indices = { version = "2.0.0-alpha.2", path = "../../../frame/indices" } -pallet-session = { version = "2.0.0-alpha.2", path = "../../../frame/session" } -pallet-timestamp = { version = "2.0.0-alpha.2", path = "../../../frame/timestamp" } -pallet-transaction-payment = { version = "2.0.0-alpha.2", path = "../../../frame/transaction-payment" } -pallet-treasury = { version = "2.0.0-alpha.2", path = "../../../frame/treasury" } -sp-application-crypto = { version = "2.0.0-alpha.2", path = "../../../primitives/application-crypto" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-externalities = { version = "0.8.0-alpha.3", path = "../../../primitives/externalities" } +frame-support = { version = "2.0.0-alpha.4", path = "../../../frame/support" } +frame-system = { version = "2.0.0-alpha.4", path = "../../../frame/system" } +node-testing = { version = "2.0.0-alpha.4", path = "../testing" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../../../frame/balances" } +pallet-contracts = { version = "2.0.0-alpha.4", path = "../../../frame/contracts" } +pallet-grandpa = { version = "2.0.0-alpha.4", path = "../../../frame/grandpa" } +pallet-im-online = { version = "2.0.0-alpha.4", path = "../../../frame/im-online" } +pallet-indices = { version = "2.0.0-alpha.4", path = "../../../frame/indices" } +pallet-session = { version = "2.0.0-alpha.4", path = "../../../frame/session" } +pallet-timestamp = { version = "2.0.0-alpha.4", path = "../../../frame/timestamp" } +pallet-transaction-payment = { version = "2.0.0-alpha.4", path = "../../../frame/transaction-payment" } +pallet-treasury = { version = "2.0.0-alpha.4", path = "../../../frame/treasury" } +sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../../primitives/application-crypto" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-externalities = { version = "0.8.0-alpha.4", path = "../../../primitives/externalities" } substrate-test-client = { version = "2.0.0-dev", path = "../../../test-utils/client" } wabt = "0.9.2" diff --git a/bin/node/inspect/Cargo.toml b/bin/node/inspect/Cargo.toml index 022f4d0ca4..6eb8523f39 100644 --- a/bin/node/inspect/Cargo.toml +++ b/bin/node/inspect/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-inspect" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,10 +11,10 @@ repository = "https://github.com/paritytech/substrate/" codec = { package = "parity-scale-codec", version = "1.2.0" } derive_more = "0.99" log = "0.4.8" -sc-cli = { version = "0.8.0-alpha.2", path = "../../../client/cli" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../../../client/api" } -sc-service = { version = "0.8.0-alpha.2", default-features = false, path = "../../../client/service" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } +sc-cli = { version = "0.8.0-alpha.4", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../../../client/api" } +sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../../../client/service" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } structopt = "0.3.8" diff --git a/bin/node/primitives/Cargo.toml b/bin/node/primitives/Cargo.toml index cb271b987d..e200c04cdd 100644 --- a/bin/node/primitives/Cargo.toml +++ b/bin/node/primitives/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-primitives" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,11 +8,11 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } [dev-dependencies] -sp-serializer = { version = "2.0.0-alpha.2", path = "../../../primitives/serializer" } +sp-serializer = { version = "2.0.0-alpha.4", path = "../../../primitives/serializer" } pretty_assertions = "0.6.1" [features] diff --git a/bin/node/rpc-client/Cargo.toml b/bin/node/rpc-client/Cargo.toml index 8b37aff291..46f8411b42 100644 --- a/bin/node/rpc-client/Cargo.toml +++ b/bin/node/rpc-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-rpc-client" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,5 +13,5 @@ futures = "0.1.29" hyper = "0.12.35" jsonrpc-core-client = { version = "14.0.3", features = ["http", "ws"] } log = "0.4.8" -node-primitives = { version = "2.0.0-alpha.2", path = "../primitives" } -sc-rpc = { version = "2.0.0-alpha.2", path = "../../../client/rpc" } +node-primitives = { version = "2.0.0-alpha.4", path = "../primitives" } +sc-rpc = { version = "2.0.0-alpha.4", path = "../../../client/rpc" } diff --git a/bin/node/rpc/Cargo.toml b/bin/node/rpc/Cargo.toml index 1155eab304..dd64e3336a 100644 --- a/bin/node/rpc/Cargo.toml +++ b/bin/node/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-rpc" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,20 +8,20 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sc-client = { version = "0.8.0-alpha.2", path = "../../../client/" } +sc-client = { version = "0.8.0-alpha.4", path = "../../../client/" } jsonrpc-core = "14.0.3" -node-primitives = { version = "2.0.0-alpha.2", path = "../primitives" } -node-runtime = { version = "2.0.0-alpha.2", path = "../runtime" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.2", path = "../../../primitives/api" } -pallet-contracts-rpc = { version = "0.8.0-alpha.2", path = "../../../frame/contracts/rpc/" } -pallet-transaction-payment-rpc = { version = "2.0.0-alpha.2", path = "../../../frame/transaction-payment/rpc/" } -substrate-frame-rpc-system = { version = "2.0.0-alpha.2", path = "../../../utils/frame/rpc/system" } -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../../primitives/transaction-pool" } -sc-consensus-babe = { version = "0.8.0-alpha.2", path = "../../../client/consensus/babe" } -sc-consensus-babe-rpc = { version = "0.8.0-alpha.2", path = "../../../client/consensus/babe/rpc" } -sp-consensus-babe = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/babe" } -sc-keystore = { version = "2.0.0-alpha.2", path = "../../../client/keystore" } -sc-consensus-epochs = { version = "0.8.0-alpha.2", path = "../../../client/consensus/epochs" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } +node-primitives = { version = "2.0.0-alpha.4", path = "../primitives" } +node-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } +pallet-contracts-rpc = { version = "0.8.0-alpha.4", path = "../../../frame/contracts/rpc/" } +pallet-transaction-payment-rpc = { version = "2.0.0-alpha.4", path = "../../../frame/transaction-payment/rpc/" } +substrate-frame-rpc-system = { version = "2.0.0-alpha.4", path = "../../../utils/frame/rpc/system" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../primitives/transaction-pool" } +sc-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../client/consensus/babe" } +sc-consensus-babe-rpc = { version = "0.8.0-alpha.4", path = "../../../client/consensus/babe/rpc" } +sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/babe" } +sc-keystore = { version = "2.0.0-alpha.4", path = "../../../client/keystore" } +sc-consensus-epochs = { version = "0.8.0-alpha.4", path = "../../../client/consensus/epochs" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index c279a25b0a..90ef3833a3 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-runtime" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" @@ -17,65 +17,65 @@ rustc-hex = { version = "2.0", optional = true } serde = { version = "1.0.102", optional = true } # primitives -sp-authority-discovery = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/authority-discovery" } -sp-consensus-babe = { version = "0.8.0-alpha.2", default-features = false, path = "../../../primitives/consensus/babe" } -sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.2"} -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/inherents" } -node-primitives = { version = "2.0.0-alpha.2", default-features = false, path = "../primitives" } -sp-offchain = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/offchain" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/core" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/std" } -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/staking" } -sp-keyring = { version = "2.0.0-alpha.2", optional = true, path = "../../../primitives/keyring" } -sp-session = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/session" } -sp-transaction-pool = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/transaction-pool" } -sp-version = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/version" } +sp-authority-discovery = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/authority-discovery" } +sp-consensus-babe = { version = "0.8.0-alpha.4", default-features = false, path = "../../../primitives/consensus/babe" } +sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.4"} +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/inherents" } +node-primitives = { version = "2.0.0-alpha.4", default-features = false, path = "../primitives" } +sp-offchain = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/offchain" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/std" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/staking" } +sp-keyring = { version = "2.0.0-alpha.4", optional = true, path = "../../../primitives/keyring" } +sp-session = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/session" } +sp-transaction-pool = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/transaction-pool" } +sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/version" } # frame dependencies -frame-executive = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/executive" } -frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/system" } -frame-system-rpc-runtime-api = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } -pallet-authority-discovery = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/authority-discovery" } -pallet-authorship = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/authorship" } -pallet-babe = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/babe" } -pallet-balances = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/balances" } -pallet-collective = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/collective" } -pallet-contracts = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/contracts" } -pallet-contracts-primitives = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/contracts/common/" } -pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.2", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" } -pallet-democracy = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/democracy" } -pallet-elections-phragmen = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/elections-phragmen" } -pallet-finality-tracker = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/finality-tracker" } -pallet-grandpa = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/grandpa" } -pallet-im-online = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/im-online" } -pallet-indices = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/indices" } -pallet-identity = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/identity" } -pallet-membership = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/membership" } -pallet-offences = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/offences" } -pallet-randomness-collective-flip = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/randomness-collective-flip" } -pallet-recovery = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/recovery" } -pallet-session = { version = "2.0.0-alpha.2", features = ["historical"], path = "../../../frame/session", default-features = false } -pallet-session-benchmarking = { version = "2.0.0-alpha.2", path = "../../../frame/session/benchmarking", default-features = false, optional = true } -pallet-staking = { version = "2.0.0-alpha.2", features = ["migrate"], path = "../../../frame/staking", default-features = false } -pallet-staking-reward-curve = { version = "2.0.0-alpha.2", path = "../../../frame/staking/reward-curve" } -pallet-sudo = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/sudo" } -pallet-society = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/society" } -pallet-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/timestamp" } -pallet-treasury = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/treasury" } -pallet-utility = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/utility" } -pallet-transaction-payment = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/transaction-payment" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" } -pallet-vesting = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/vesting" } +frame-executive = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/executive" } +frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/system" } +frame-system-rpc-runtime-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } +pallet-authority-discovery = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/authority-discovery" } +pallet-authorship = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/authorship" } +pallet-babe = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/babe" } +pallet-balances = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/balances" } +pallet-collective = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/collective" } +pallet-contracts = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/contracts" } +pallet-contracts-primitives = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/contracts/common/" } +pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.4", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" } +pallet-democracy = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/democracy" } +pallet-elections-phragmen = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/elections-phragmen" } +pallet-finality-tracker = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/finality-tracker" } +pallet-grandpa = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/grandpa" } +pallet-im-online = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/im-online" } +pallet-indices = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/indices" } +pallet-identity = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/identity" } +pallet-membership = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/membership" } +pallet-offences = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/offences" } +pallet-randomness-collective-flip = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/randomness-collective-flip" } +pallet-recovery = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/recovery" } +pallet-session = { version = "2.0.0-alpha.4", features = ["historical"], path = "../../../frame/session", default-features = false } +pallet-session-benchmarking = { version = "2.0.0-alpha.4", path = "../../../frame/session/benchmarking", default-features = false, optional = true } +pallet-staking = { version = "2.0.0-alpha.4", features = ["migrate"], path = "../../../frame/staking", default-features = false } +pallet-staking-reward-curve = { version = "2.0.0-alpha.4", path = "../../../frame/staking/reward-curve" } +pallet-sudo = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/sudo" } +pallet-society = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/society" } +pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/timestamp" } +pallet-treasury = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/treasury" } +pallet-utility = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/utility" } +pallet-transaction-payment = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/transaction-payment" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" } +pallet-vesting = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/vesting" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.2", path = "../../../primitives/io" } +sp-io = { version = "2.0.0-alpha.4", path = "../../../primitives/io" } [features] default = ["std"] diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index 97d76467fe..8ef154c173 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-testing" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] description = "Test utilities for Substrate node." edition = "2018" @@ -10,48 +10,48 @@ repository = "https://github.com/paritytech/substrate/" publish = true [dependencies] -pallet-balances = { version = "2.0.0-alpha.2", path = "../../../frame/balances" } -sc-client = { version = "0.8.0-alpha.2", path = "../../../client/" } -sc-client-db = { version = "0.8.0-alpha.2", path = "../../../client/db/", features = ["kvdb-rocksdb"] } -sc-client-api = { version = "2.0.0-alpha.2", path = "../../../client/api/" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../../../frame/balances" } +sc-client = { version = "0.8.0-alpha.4", path = "../../../client/" } +sc-client-db = { version = "0.8.0-alpha.4", path = "../../../client/db/", features = ["kvdb-rocksdb"] } +sc-client-api = { version = "2.0.0-alpha.4", path = "../../../client/api/" } codec = { package = "parity-scale-codec", version = "1.2.0" } -pallet-contracts = { version = "2.0.0-alpha.2", path = "../../../frame/contracts" } -pallet-grandpa = { version = "2.0.0-alpha.2", path = "../../../frame/grandpa" } -pallet-indices = { version = "2.0.0-alpha.2", path = "../../../frame/indices" } -sp-keyring = { version = "2.0.0-alpha.2", path = "../../../primitives/keyring" } -node-executor = { version = "2.0.0-alpha.2", path = "../executor" } -node-primitives = { version = "2.0.0-alpha.2", path = "../primitives" } -node-runtime = { version = "2.0.0-alpha.2", path = "../runtime" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-io = { version = "2.0.0-alpha.2", path = "../../../primitives/io" } -frame-support = { version = "2.0.0-alpha.2", path = "../../../frame/support" } -pallet-session = { version = "2.0.0-alpha.2", path = "../../../frame/session" } -pallet-society = { version = "2.0.0-alpha.2", path = "../../../frame/society" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -pallet-staking = { version = "2.0.0-alpha.2", path = "../../../frame/staking" } -sc-executor = { version = "0.8.0-alpha.2", path = "../../../client/executor", features = ["wasmtime"] } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/common" } -frame-system = { version = "2.0.0-alpha.2", path = "../../../frame/system" } +pallet-contracts = { version = "2.0.0-alpha.4", path = "../../../frame/contracts" } +pallet-grandpa = { version = "2.0.0-alpha.4", path = "../../../frame/grandpa" } +pallet-indices = { version = "2.0.0-alpha.4", path = "../../../frame/indices" } +sp-keyring = { version = "2.0.0-alpha.4", path = "../../../primitives/keyring" } +node-executor = { version = "2.0.0-alpha.4", path = "../executor" } +node-primitives = { version = "2.0.0-alpha.4", path = "../primitives" } +node-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-io = { version = "2.0.0-alpha.4", path = "../../../primitives/io" } +frame-support = { version = "2.0.0-alpha.4", path = "../../../frame/support" } +pallet-session = { version = "2.0.0-alpha.4", path = "../../../frame/session" } +pallet-society = { version = "2.0.0-alpha.4", path = "../../../frame/society" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +pallet-staking = { version = "2.0.0-alpha.4", path = "../../../frame/staking" } +sc-executor = { version = "0.8.0-alpha.4", path = "../../../client/executor", features = ["wasmtime"] } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +frame-system = { version = "2.0.0-alpha.4", path = "../../../frame/system" } substrate-test-client = { version = "2.0.0-dev", path = "../../../test-utils/client" } -pallet-timestamp = { version = "2.0.0-alpha.2", path = "../../../frame/timestamp" } -pallet-transaction-payment = { version = "2.0.0-alpha.2", path = "../../../frame/transaction-payment" } -pallet-treasury = { version = "2.0.0-alpha.2", path = "../../../frame/treasury" } +pallet-timestamp = { version = "2.0.0-alpha.4", path = "../../../frame/timestamp" } +pallet-transaction-payment = { version = "2.0.0-alpha.4", path = "../../../frame/transaction-payment" } +pallet-treasury = { version = "2.0.0-alpha.4", path = "../../../frame/treasury" } wabt = "0.9.2" -sp-api = { version = "2.0.0-alpha.2", path = "../../../primitives/api" } -sp-finality-tracker = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/finality-tracker" } -sp-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/timestamp" } -sp-block-builder = { version = "2.0.0-alpha.2", path = "../../../primitives/block-builder" } -sc-block-builder = { version = "0.8.0-alpha.3", path = "../../../client/block-builder" } -sp-inherents = { version = "2.0.0-alpha.2", path = "../../../primitives/inherents" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } +sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } +sp-finality-tracker = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/finality-tracker" } +sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/timestamp" } +sp-block-builder = { version = "2.0.0-alpha.4", path = "../../../primitives/block-builder" } +sc-block-builder = { version = "0.8.0-alpha.4", path = "../../../client/block-builder" } +sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } log = "0.4.8" tempfile = "3.1.0" fs_extra = "1" [dev-dependencies] criterion = "0.3.0" -sc-cli = { version = "0.8.0-alpha.2", path = "../../../client/cli" } -sc-service = { version = "0.8.0-alpha.2", path = "../../../client/service", features = ["rocksdb"] } +sc-cli = { version = "0.8.0-alpha.4", path = "../../../client/cli" } +sc-service = { version = "0.8.0-alpha.4", path = "../../../client/service", features = ["rocksdb"] } [[bench]] name = "import" diff --git a/bin/node/transaction-factory/Cargo.toml b/bin/node/transaction-factory/Cargo.toml index 44f2d87f9c..6d44faca10 100644 --- a/bin/node/transaction-factory/Cargo.toml +++ b/bin/node/transaction-factory/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-transaction-factory" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,16 +8,16 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-block-builder = { version = "2.0.0-alpha.2", path = "../../../primitives/block-builder" } -sc-cli = { version = "0.8.0-alpha.2", path = "../../../client/cli" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../../../client/api" } -sc-block-builder = { version = "0.8.0-alpha.2", path = "../../../client/block-builder" } -sc-client = { version = "0.8.0-alpha.2", path = "../../../client" } +sp-block-builder = { version = "2.0.0-alpha.4", path = "../../../primitives/block-builder" } +sc-cli = { version = "0.8.0-alpha.4", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../../../client/api" } +sc-block-builder = { version = "0.8.0-alpha.4", path = "../../../client/block-builder" } +sc-client = { version = "0.8.0-alpha.4", path = "../../../client" } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } log = "0.4.8" -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-api = { version = "2.0.0-alpha.2", path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sc-service = { version = "0.8.0-alpha.2", default-features = false, path = "../../../client/service" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../../../client/service" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } diff --git a/bin/utils/chain-spec-builder/Cargo.toml b/bin/utils/chain-spec-builder/Cargo.toml index 5e51c4358e..7068ce48e0 100644 --- a/bin/utils/chain-spec-builder/Cargo.toml +++ b/bin/utils/chain-spec-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "chain-spec-builder" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" @@ -10,8 +10,8 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] ansi_term = "0.12.1" -sc-keystore = { version = "2.0.0-alpha.2", path = "../../../client/keystore" } -node-cli = { version = "2.0.0-alpha.2", path = "../../node/cli" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } +sc-keystore = { version = "2.0.0-alpha.4", path = "../../../client/keystore" } +node-cli = { version = "2.0.0-alpha.4", path = "../../node/cli" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } rand = "0.7.2" structopt = "0.3.8" diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index 252978a3a9..feb78ed7b4 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "subkey" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,10 +9,10 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] futures = "0.1.29" -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -node-runtime = { version = "2.0.0-alpha.2", path = "../../node/runtime" } -node-primitives = { version = "2.0.0-alpha.2", path = "../../node/primitives" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +node-runtime = { version = "2.0.0-alpha.4", path = "../../node/runtime" } +node-primitives = { version = "2.0.0-alpha.4", path = "../../node/primitives" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } rand = "0.7.2" clap = "2.33.0" tiny-bip39 = "0.7" @@ -21,13 +21,13 @@ substrate-bip39 = "0.3.1" hex = "0.4.0" hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.2.0" } -frame-system = { version = "2.0.0-alpha.2", path = "../../../frame/system" } -pallet-balances = { version = "2.0.0-alpha.2", path = "../../../frame/balances" } -pallet-transaction-payment = { version = "2.0.0-alpha.2", path = "../../../frame/transaction-payment" } +frame-system = { version = "2.0.0-alpha.4", path = "../../../frame/system" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../../../frame/balances" } +pallet-transaction-payment = { version = "2.0.0-alpha.4", path = "../../../frame/transaction-payment" } rpassword = "4.0.1" itertools = "0.8.2" derive_more = { version = "0.99.2" } -sc-rpc = { version = "2.0.0-alpha.2", path = "../../../client/rpc" } +sc-rpc = { version = "2.0.0-alpha.4", path = "../../../client/rpc" } jsonrpc-core-client = { version = "14.0.3", features = ["http"] } hyper = "0.12.35" libp2p = "0.16.2" diff --git a/client/Cargo.toml b/client/Cargo.toml index 61199f04da..686dbb661d 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-client" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,32 +9,32 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate Client and associated logic." [dependencies] -sc-block-builder = { version = "0.8.0-alpha.2", path = "block-builder" } -sc-client-api = { version = "2.0.0-alpha.2", path = "api" } +sc-block-builder = { version = "0.8.0-alpha.4", path = "block-builder" } +sc-client-api = { version = "2.0.0-alpha.4", path = "api" } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.2", path = "../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../primitives/consensus/common" } derive_more = { version = "0.99.2" } -sc-executor = { version = "0.8.0-alpha.2", path = "executor" } -sp-externalities = { version = "0.8.0-alpha.2", path = "../primitives/externalities" } +sc-executor = { version = "0.8.0-alpha.4", path = "executor" } +sp-externalities = { version = "0.8.0-alpha.4", path = "../primitives/externalities" } fnv = { version = "1.0.6" } futures = { version = "0.3.1", features = ["compat"] } hash-db = { version = "0.15.2" } hex-literal = { version = "0.2.1" } -sp-inherents = { version = "2.0.0-alpha.2", path = "../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.2", path = "../primitives/keyring" } +sp-inherents = { version = "2.0.0-alpha.4", path = "../primitives/inherents" } +sp-keyring = { version = "2.0.0-alpha.4", path = "../primitives/keyring" } kvdb = "0.4.0" log = { version = "0.4.8" } parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.2", path = "../primitives/core" } -sp-std = { version = "2.0.0-alpha.2", path = "../primitives/std" } -sp-version = { version = "2.0.0-alpha.2", path = "../primitives/version" } -sp-api = { version = "2.0.0-alpha.2", path = "../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../primitives/runtime" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../primitives/blockchain" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-alpha.2", path = "telemetry" } -sp-trie = { version = "2.0.0-alpha.2", path = "../primitives/trie" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.2", path = "../utils/prometheus" } +sp-core = { version = "2.0.0-alpha.4", path = "../primitives/core" } +sp-std = { version = "2.0.0-alpha.4", path = "../primitives/std" } +sp-version = { version = "2.0.0-alpha.4", path = "../primitives/version" } +sp-api = { version = "2.0.0-alpha.4", path = "../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../primitives/runtime" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../primitives/blockchain" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-alpha.4", path = "telemetry" } +sp-trie = { version = "2.0.0-alpha.4", path = "../primitives/trie" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.4", path = "../utils/prometheus" } tracing = "0.1.10" [dev-dependencies] @@ -42,4 +42,4 @@ env_logger = "0.7.0" tempfile = "3.1.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../test-utils/runtime/client" } kvdb-memorydb = "0.4.0" -sp-panic-handler = { version = "2.0.0-alpha.2", path = "../primitives/panic-handler" } +sp-panic-handler = { version = "2.0.0-alpha.4", path = "../primitives/panic-handler" } diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index 7ceb12eaf6..94234a4a92 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-client-api" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,30 +12,30 @@ documentation = "https://docs.rs/sc-client-api" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } derive_more = { version = "0.99.2" } -sc-executor = { version = "0.8.0-alpha.2", path = "../executor" } -sp-externalities = { version = "0.8.0-alpha.2", path = "../../primitives/externalities" } +sc-executor = { version = "0.8.0-alpha.4", path = "../executor" } +sp-externalities = { version = "0.8.0-alpha.4", path = "../../primitives/externalities" } fnv = { version = "1.0.6" } futures = { version = "0.3.1" } hash-db = { version = "0.15.2", default-features = false } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../primitives/blockchain" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } hex-literal = { version = "0.2.1" } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.2", path = "../../primitives/keyring" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } +sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } kvdb = "0.4.0" log = { version = "0.4.8" } parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-version = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/version" } -sp-api = { version = "2.0.0-alpha.2", path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-alpha.2", path = "../telemetry" } -sp-trie = { version = "2.0.0-alpha.2", path = "../../primitives/trie" } -sp-storage = { version = "2.0.0-alpha.2", path = "../../primitives/storage" } -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../primitives/transaction-pool" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/version" } +sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } +sp-trie = { version = "2.0.0-alpha.4", path = "../../primitives/trie" } +sp-storage = { version = "2.0.0-alpha.4", path = "../../primitives/storage" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } [dev-dependencies] sp-test-primitives = { version = "2.0.0-dev", path = "../../primitives/test-primitives" } diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index a7ea523552..c0d6804d0b 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-authority-discovery" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" @@ -20,21 +20,21 @@ futures = "0.3.1" futures-timer = "3.0.1" libp2p = { version = "0.16.2", default-features = false, features = ["secp256k1", "libp2p-websocket"] } log = "0.4.8" -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.2" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.4"} prost = "0.6.1" rand = "0.7.2" -sc-client-api = { version = "2.0.0-alpha.2", path = "../api" } -sc-keystore = { version = "2.0.0-alpha.2", path = "../keystore" } -sc-network = { version = "0.8.0-alpha.2", path = "../network" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } +sc-keystore = { version = "2.0.0-alpha.4", path = "../keystore" } +sc-network = { version = "0.8.0-alpha.4", path = "../network" } serde_json = "1.0.41" -sp-authority-discovery = { version = "2.0.0-alpha.2", path = "../../primitives/authority-discovery" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.2", path = "../../primitives/api" } +sp-authority-discovery = { version = "2.0.0-alpha.4", path = "../../primitives/authority-discovery" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } [dev-dependencies] env_logger = "0.7.0" quickcheck = "0.9.0" -sc-peerset = { version = "2.0.0-alpha.2", path = "../peerset" } +sc-peerset = { version = "2.0.0-alpha.4", path = "../peerset" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client"} diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index ee2ff971bc..f7bab74a24 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-basic-authorship" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,20 +12,20 @@ description = "Basic implementation of block-authoring logic." log = "0.4.8" futures = "0.3.1" codec = { package = "parity-scale-codec", version = "1.2.0" } -sp-api = { version = "2.0.0-alpha.2", path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../primitives/blockchain" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../api" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-alpha.2", path = "../../primitives/inherents" } -sc-telemetry = { version = "2.0.0-alpha.2", path = "../telemetry" } -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../primitives/transaction-pool" } -sc-block-builder = { version = "0.8.0-alpha.2", path = "../block-builder" } +sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-alpha.4", path = "../../primitives/inherents" } +sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } +sc-block-builder = { version = "0.8.0-alpha.4", path = "../block-builder" } tokio-executor = { version = "0.2.0-alpha.6", features = ["blocking"] } futures-timer = "3.0.1" [dev-dependencies] -sc-transaction-pool = { version = "2.0.0-alpha.2", path = "../../client/transaction-pool" } +sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../../client/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } parking_lot = "0.10.0" diff --git a/client/block-builder/Cargo.toml b/client/block-builder/Cargo.toml index dd4ebcb07f..be97b796fb 100644 --- a/client/block-builder/Cargo.toml +++ b/client/block-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-block-builder" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,16 +10,16 @@ description = "Substrate block builder" [dependencies] -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../primitives/state-machine" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.2", path = "../../primitives/api" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-block-builder = { version = "2.0.0-alpha.2", path = "../../primitives/block-builder" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../api" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-block-builder = { version = "2.0.0-alpha.4", path = "../../primitives/block-builder" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } [dev-dependencies] substrate-test-runtime-client = { path = "../../test-utils/runtime/client" } -sp-trie = { version = "2.0.0-alpha.2", path = "../../primitives/trie" } +sp-trie = { version = "2.0.0-alpha.4", path = "../../primitives/trie" } diff --git a/client/chain-spec/Cargo.toml b/client/chain-spec/Cargo.toml index 10d4fc2622..72a999bca3 100644 --- a/client/chain-spec/Cargo.toml +++ b/client/chain-spec/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-chain-spec" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,11 +9,11 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate chain configurations." [dependencies] -sc-chain-spec-derive = { version = "2.0.0-alpha.2", path = "./derive" } +sc-chain-spec-derive = { version = "2.0.0-alpha.4", path = "./derive" } impl-trait-for-tuples = "0.1.3" -sc-network = { version = "0.8.0-alpha.2", path = "../network" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +sc-network = { version = "0.8.0-alpha.4", path = "../network" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } -sc-telemetry = { version = "2.0.0-alpha.2", path = "../telemetry" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } diff --git a/client/chain-spec/derive/Cargo.toml b/client/chain-spec/derive/Cargo.toml index df0e2f92b2..236eb9ce09 100644 --- a/client/chain-spec/derive/Cargo.toml +++ b/client/chain-spec/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-chain-spec-derive" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 908cc4c10e..93103a4323 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-cli" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "Substrate CLI interface." edition = "2018" @@ -23,21 +23,21 @@ tokio = { version = "0.2.9", features = [ "signal", "rt-core", "rt-threaded" ] } futures = "0.3.1" fdlimit = "0.1.1" serde_json = "1.0.41" -sc-informant = { version = "0.8.0-alpha.2", path = "../informant" } -sp-panic-handler = { version = "2.0.0-alpha.2", path = "../../primitives/panic-handler" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../api" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../primitives/blockchain" } -sc-network = { version = "0.8.0-alpha.2", path = "../network" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sc-service = { version = "0.8.0-alpha.2", default-features = false, path = "../service" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-alpha.2", path = "../telemetry" } -substrate-prometheus-endpoint = { path = "../../utils/prometheus" , version = "0.8.0-alpha.2"} -sp-keyring = { version = "2.0.0-alpha.2", path = "../../primitives/keyring" } +sc-informant = { version = "0.8.0-alpha.4", path = "../informant" } +sp-panic-handler = { version = "2.0.0-alpha.4", path = "../../primitives/panic-handler" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } +sc-network = { version = "0.8.0-alpha.4", path = "../network" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../service" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } +substrate-prometheus-endpoint = { path = "../../utils/prometheus" , version = "0.8.0-alpha.4"} +sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } names = "0.11.0" structopt = "0.3.8" -sc-tracing = { version = "2.0.0-alpha.2", path = "../tracing" } +sc-tracing = { version = "2.0.0-alpha.4", path = "../tracing" } chrono = "0.4.10" parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } diff --git a/client/consensus/aura/Cargo.toml b/client/consensus/aura/Cargo.toml index f0b90f3819..3ba1eaab4f 100644 --- a/client/consensus/aura/Cargo.toml +++ b/client/consensus/aura/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-aura" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "Aura consensus algorithm for substrate" edition = "2018" @@ -9,37 +9,37 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.2", path = "../../../primitives/application-crypto" } -sp-consensus-aura = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/aura" } -sp-block-builder = { version = "2.0.0-alpha.2", path = "../../../primitives/block-builder" } -sc-block-builder = { version = "0.8.0-alpha.3", path = "../../../client/block-builder" } -sc-client = { version = "0.8.0-alpha.2", path = "../../" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../../api" } +sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../../primitives/application-crypto" } +sp-consensus-aura = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/aura" } +sp-block-builder = { version = "2.0.0-alpha.4", path = "../../../primitives/block-builder" } +sc-block-builder = { version = "0.8.0-alpha.4", path = "../../../client/block-builder" } +sc-client = { version = "0.8.0-alpha.4", path = "../../" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../../api" } codec = { package = "parity-scale-codec", version = "1.2.0" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } derive_more = "0.99.2" futures = "0.3.1" futures-timer = "3.0.1" -sp-inherents = { version = "2.0.0-alpha.2", path = "../../../primitives/inherents" } -sc-keystore = { version = "2.0.0-alpha.2", path = "../../keystore" } +sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } +sc-keystore = { version = "2.0.0-alpha.4", path = "../../keystore" } log = "0.4.8" parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } -sp-io = { version = "2.0.0-alpha.2", path = "../../../primitives/io" } -sp-version = { version = "2.0.0-alpha.2", path = "../../../primitives/version" } -sc-consensus-slots = { version = "0.8.0-alpha.2", path = "../slots" } -sp-api = { version = "2.0.0-alpha.2", path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-timestamp = { version = "2.0.0-alpha.2", path = "../../../primitives/timestamp" } -sc-telemetry = { version = "2.0.0-alpha.2", path = "../../telemetry" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +sp-io = { version = "2.0.0-alpha.4", path = "../../../primitives/io" } +sp-version = { version = "2.0.0-alpha.4", path = "../../../primitives/version" } +sc-consensus-slots = { version = "0.8.0-alpha.4", path = "../slots" } +sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-timestamp = { version = "2.0.0-alpha.4", path = "../../../primitives/timestamp" } +sc-telemetry = { version = "2.0.0-alpha.4", path = "../../telemetry" } [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.2", path = "../../../primitives/keyring" } -sc-executor = { version = "0.8.0-alpha.2", path = "../../executor" } -sc-network = { version = "0.8.0-alpha.2", path = "../../network" } +sp-keyring = { version = "2.0.0-alpha.4", path = "../../../primitives/keyring" } +sc-executor = { version = "0.8.0-alpha.4", path = "../../executor" } +sc-network = { version = "0.8.0-alpha.4", path = "../../network" } sc-network-test = { version = "0.8.0-dev", path = "../../network/test" } -sc-service = { version = "0.8.0-alpha.2", path = "../../service" } +sc-service = { version = "0.8.0-alpha.4", path = "../../service" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } env_logger = "0.7.0" tempfile = "3.1.0" diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index 66455adbdf..aa70fc0d40 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-babe" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "BABE consensus algorithm for substrate" edition = "2018" @@ -12,30 +12,30 @@ documentation = "https://docs.rs/sc-consensus-babe" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } -sp-consensus-babe = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/babe" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-application-crypto = { version = "2.0.0-alpha.2", path = "../../../primitives/application-crypto" } +sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/babe" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../../primitives/application-crypto" } num-bigint = "0.2.3" num-rational = "0.2.2" num-traits = "0.2.8" serde = { version = "1.0.104", features = ["derive"] } -sp-version = { version = "2.0.0-alpha.2", path = "../../../primitives/version" } -sp-io = { version = "2.0.0-alpha.2", path = "../../../primitives/io" } -sp-inherents = { version = "2.0.0-alpha.2", path = "../../../primitives/inherents" } -sp-timestamp = { version = "2.0.0-alpha.2", path = "../../../primitives/timestamp" } -sc-telemetry = { version = "2.0.0-alpha.2", path = "../../telemetry" } -sc-keystore = { version = "2.0.0-alpha.2", path = "../../keystore" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../../api" } -sc-client = { version = "0.8.0-alpha.2", path = "../../" } -sc-consensus-epochs = { version = "0.8.0-alpha.2", path = "../epochs" } -sp-api = { version = "2.0.0-alpha.2", path = "../../../primitives/api" } -sp-block-builder = { version = "2.0.0-alpha.2", path = "../../../primitives/block-builder" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/common" } -sc-consensus-uncles = { version = "0.8.0-alpha.2", path = "../uncles" } -sc-consensus-slots = { version = "0.8.0-alpha.2", path = "../slots" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -fork-tree = { version = "2.0.0-alpha.2", path = "../../../utils/fork-tree" } +sp-version = { version = "2.0.0-alpha.4", path = "../../../primitives/version" } +sp-io = { version = "2.0.0-alpha.4", path = "../../../primitives/io" } +sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } +sp-timestamp = { version = "2.0.0-alpha.4", path = "../../../primitives/timestamp" } +sc-telemetry = { version = "2.0.0-alpha.4", path = "../../telemetry" } +sc-keystore = { version = "2.0.0-alpha.4", path = "../../keystore" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../../api" } +sc-client = { version = "0.8.0-alpha.4", path = "../../" } +sc-consensus-epochs = { version = "0.8.0-alpha.4", path = "../epochs" } +sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } +sp-block-builder = { version = "2.0.0-alpha.4", path = "../../../primitives/block-builder" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +sc-consensus-uncles = { version = "0.8.0-alpha.4", path = "../uncles" } +sc-consensus-slots = { version = "0.8.0-alpha.4", path = "../slots" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +fork-tree = { version = "2.0.0-alpha.4", path = "../../../utils/fork-tree" } futures = "0.3.1" futures-timer = "3.0.1" parking_lot = "0.10.0" @@ -47,13 +47,13 @@ pdqselect = "0.1.0" derive_more = "0.99.2" [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.2", path = "../../../primitives/keyring" } -sc-executor = { version = "0.8.0-alpha.2", path = "../../executor" } -sc-network = { version = "0.8.0-alpha.2", path = "../../network" } +sp-keyring = { version = "2.0.0-alpha.4", path = "../../../primitives/keyring" } +sc-executor = { version = "0.8.0-alpha.4", path = "../../executor" } +sc-network = { version = "0.8.0-alpha.4", path = "../../network" } sc-network-test = { version = "0.8.0-dev", path = "../../network/test" } -sc-service = { version = "0.8.0-alpha.2", path = "../../service" } +sc-service = { version = "0.8.0-alpha.4", path = "../../service" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sc-block-builder = { version = "0.8.0-alpha.2", path = "../../block-builder" } +sc-block-builder = { version = "0.8.0-alpha.4", path = "../../block-builder" } env_logger = "0.7.0" tempfile = "3.1.0" diff --git a/client/consensus/babe/rpc/Cargo.toml b/client/consensus/babe/rpc/Cargo.toml index 3f2cc4f0bc..e9e7f68890 100644 --- a/client/consensus/babe/rpc/Cargo.toml +++ b/client/consensus/babe/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-babe-rpc" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "RPC extensions for the BABE consensus algorithm" edition = "2018" @@ -9,24 +9,24 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sc-consensus-babe = { version = "0.8.0-alpha.2", path = "../" } +sc-consensus-babe = { version = "0.8.0-alpha.4", path = "../" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" -sp-consensus-babe = { version = "0.8.0-alpha.2", path = "../../../../primitives/consensus/babe" } +sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../../primitives/consensus/babe" } serde = { version = "1.0.104", features=["derive"] } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../../primitives/runtime" } -sc-consensus-epochs = { version = "0.8.0-alpha.2", path = "../../epochs" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../../primitives/runtime" } +sc-consensus-epochs = { version = "0.8.0-alpha.4", path = "../../epochs" } futures = "0.3.1" derive_more = "0.99.2" -sp-api = { version = "2.0.0-alpha.2", path = "../../../../primitives/api" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../../primitives/consensus/common" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../../primitives/core" } -sc-keystore = { version = "2.0.0-alpha.2", path = "../../../keystore" } +sp-api = { version = "2.0.0-alpha.4", path = "../../../../primitives/api" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../../primitives/consensus/common" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../../primitives/core" } +sc-keystore = { version = "2.0.0-alpha.4", path = "../../../keystore" } [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../../test-utils/runtime/client" } -sp-application-crypto = { version = "2.0.0-alpha.2", path = "../../../../primitives/application-crypto" } -sp-keyring = { version = "2.0.0-alpha.2", path = "../../../../primitives/keyring" } +sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../../../primitives/application-crypto" } +sp-keyring = { version = "2.0.0-alpha.4", path = "../../../../primitives/keyring" } tempfile = "3.1.0" diff --git a/client/consensus/epochs/Cargo.toml b/client/consensus/epochs/Cargo.toml index fe23654298..28ae39a5a7 100644 --- a/client/consensus/epochs/Cargo.toml +++ b/client/consensus/epochs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-epochs" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "Generic epochs-based utilities for consensus" edition = "2018" @@ -11,7 +11,7 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } parking_lot = "0.10.0" -fork-tree = { version = "2.0.0-alpha.2", path = "../../../utils/fork-tree" } -sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.2"} -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } -sc-client-api = { path = "../../api" , version = "2.0.0-alpha.2"} +fork-tree = { version = "2.0.0-alpha.4", path = "../../../utils/fork-tree" } +sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.4"} +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +sc-client-api = { path = "../../api" , version = "2.0.0-alpha.4"} diff --git a/client/consensus/manual-seal/Cargo.toml b/client/consensus/manual-seal/Cargo.toml index f0925df089..4e412c2f02 100644 --- a/client/consensus/manual-seal/Cargo.toml +++ b/client/consensus/manual-seal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-manual-seal" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "Manual sealing engine for Substrate" edition = "2018" @@ -19,17 +19,17 @@ parking_lot = "0.10.0" serde = { version = "1.0", features=["derive"] } assert_matches = "1.3.0" -sc-client = { path = "../../../client" , version = "0.8.0-alpha.2"} -sc-client-api = { path = "../../../client/api" , version = "2.0.0-alpha.2"} -sc-transaction-pool = { path = "../../transaction-pool" , version = "2.0.0-alpha.2"} -sp-blockchain = { path = "../../../primitives/blockchain" , version = "2.0.0-alpha.2"} -sp-consensus = { package = "sp-consensus", path = "../../../primitives/consensus/common" , version = "0.8.0-alpha.2"} -sp-inherents = { path = "../../../primitives/inherents" , version = "2.0.0-alpha.2"} -sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.2"} -sp-transaction-pool = { path = "../../../primitives/transaction-pool" , version = "2.0.0-alpha.2"} +sc-client = { path = "../../../client" , version = "0.8.0-alpha.4"} +sc-client-api = { path = "../../../client/api" , version = "2.0.0-alpha.4"} +sc-transaction-pool = { path = "../../transaction-pool" , version = "2.0.0-alpha.4"} +sp-blockchain = { path = "../../../primitives/blockchain" , version = "2.0.0-alpha.4"} +sp-consensus = { package = "sp-consensus", path = "../../../primitives/consensus/common" , version = "0.8.0-alpha.4"} +sp-inherents = { path = "../../../primitives/inherents" , version = "2.0.0-alpha.4"} +sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.4"} +sp-transaction-pool = { path = "../../../primitives/transaction-pool" , version = "2.0.0-alpha.4"} [dev-dependencies] -sc-basic-authorship = { path = "../../basic-authorship" , version = "0.8.0-alpha.2"} +sc-basic-authorship = { path = "../../basic-authorship" , version = "0.8.0-alpha.4"} substrate-test-runtime-client = { path = "../../../test-utils/runtime/client" , version = "2.0.0-dev"} substrate-test-runtime-transaction-pool = { path = "../../../test-utils/runtime/transaction-pool" , version = "2.0.0-dev"} tokio = { version = "0.2", features = ["rt-core", "macros"] } diff --git a/client/consensus/pow/Cargo.toml b/client/consensus/pow/Cargo.toml index f95d196b62..f782a67fef 100644 --- a/client/consensus/pow/Cargo.toml +++ b/client/consensus/pow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-pow" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "PoW consensus algorithm for substrate" edition = "2018" @@ -10,16 +10,16 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.2", path = "../../../primitives/api" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../../api" } -sp-block-builder = { version = "2.0.0-alpha.2", path = "../../../primitives/block-builder" } -sp-inherents = { version = "2.0.0-alpha.2", path = "../../../primitives/inherents" } -sp-consensus-pow = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/pow" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/common" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../../api" } +sp-block-builder = { version = "2.0.0-alpha.4", path = "../../../primitives/block-builder" } +sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } +sp-consensus-pow = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/pow" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } log = "0.4.8" futures = { version = "0.3.1", features = ["compat"] } -sp-timestamp = { version = "2.0.0-alpha.2", path = "../../../primitives/timestamp" } +sp-timestamp = { version = "2.0.0-alpha.4", path = "../../../primitives/timestamp" } derive_more = "0.99.2" diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index fe7958b257..91498be629 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-slots" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "Generic slots-based utilities for consensus" edition = "2018" @@ -11,15 +11,15 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../../api" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../../primitives/state-machine" } -sp-api = { version = "2.0.0-alpha.2", path = "../../../primitives/api" } -sc-telemetry = { version = "2.0.0-alpha.2", path = "../../telemetry" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-alpha.2", path = "../../../primitives/inherents" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../../api" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } +sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } +sc-telemetry = { version = "2.0.0-alpha.4", path = "../../telemetry" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } futures = "0.3.1" futures-timer = "3.0.1" parking_lot = "0.10.0" diff --git a/client/consensus/uncles/Cargo.toml b/client/consensus/uncles/Cargo.toml index ad325ed79f..745d885416 100644 --- a/client/consensus/uncles/Cargo.toml +++ b/client/consensus/uncles/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-uncles" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "Generic uncle inclusion utilities for consensus" edition = "2018" @@ -9,10 +9,10 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sc-client-api = { version = "2.0.0-alpha.2", path = "../../api" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-authorship = { version = "2.0.0-alpha.2", path = "../../../primitives/authorship" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-alpha.2", path = "../../../primitives/inherents" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../../api" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-authorship = { version = "2.0.0-alpha.4", path = "../../../primitives/authorship" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } log = "0.4.8" diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index d30b6f95e4..dde3de8e89 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-client-db" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -20,20 +20,20 @@ hash-db = "0.15.2" parity-util-mem = { version = "0.5.2", default-features = false, features = ["std"] } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } -sc-client-api = { version = "2.0.0-alpha.2", path = "../api" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } -sc-client = { version = "0.8.0-alpha.2", path = "../" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../primitives/state-machine" } -sc-executor = { version = "0.8.0-alpha.2", path = "../executor" } -sc-state-db = { version = "0.8.0-alpha.2", path = "../state-db" } -sp-trie = { version = "2.0.0-alpha.2", path = "../../primitives/trie" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../primitives/blockchain" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.2", path = "../../utils/prometheus" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sc-client = { version = "0.8.0-alpha.4", path = "../" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } +sc-executor = { version = "0.8.0-alpha.4", path = "../executor" } +sc-state-db = { version = "0.8.0-alpha.4", path = "../state-db" } +sp-trie = { version = "2.0.0-alpha.4", path = "../../primitives/trie" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.4", path = "../../utils/prometheus" } [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.2", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } env_logger = "0.7.0" quickcheck = "0.9" diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index 1353bc5730..aa14c1e43e 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,19 +12,19 @@ documentation = "https://docs.rs/sc-executor" [dependencies] derive_more = "0.99.2" codec = { package = "parity-scale-codec", version = "1.2.0" } -sp-io = { version = "2.0.0-alpha.2", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-trie = { version = "2.0.0-alpha.2", path = "../../primitives/trie" } -sp-serializer = { version = "2.0.0-alpha.2", path = "../../primitives/serializer" } -sp-version = { version = "2.0.0-alpha.2", path = "../../primitives/version" } -sp-panic-handler = { version = "2.0.0-alpha.2", path = "../../primitives/panic-handler" } +sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-trie = { version = "2.0.0-alpha.4", path = "../../primitives/trie" } +sp-serializer = { version = "2.0.0-alpha.4", path = "../../primitives/serializer" } +sp-version = { version = "2.0.0-alpha.4", path = "../../primitives/version" } +sp-panic-handler = { version = "2.0.0-alpha.4", path = "../../primitives/panic-handler" } wasmi = "0.6.2" parity-wasm = "0.41.0" lazy_static = "1.4.0" sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.2", path = "../../primitives/runtime-interface" } -sp-externalities = { version = "0.8.0-alpha.2", path = "../../primitives/externalities" } -sc-executor-common = { version = "0.8.0-alpha.2", path = "common" } +sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../primitives/runtime-interface" } +sp-externalities = { version = "0.8.0-alpha.4", path = "../../primitives/externalities" } +sc-executor-common = { version = "0.8.0-alpha.4", path = "common" } sc-executor-wasmi = { version = "0.8.0-alpha.2", path = "wasmi" } sc-executor-wasmtime = { version = "0.8.0-alpha.2", path = "wasmtime", optional = true } parking_lot = "0.10.0" @@ -37,9 +37,9 @@ wabt = "0.9.2" hex-literal = "0.2.1" sc-runtime-test = { version = "2.0.0-dev", path = "runtime-test" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } test-case = "0.3.3" -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } [features] default = [ "std" ] diff --git a/client/executor/common/Cargo.toml b/client/executor/common/Cargo.toml index 04db56938a..5b54f091f6 100644 --- a/client/executor/common/Cargo.toml +++ b/client/executor/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor-common" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,11 +14,11 @@ log = "0.4.8" derive_more = "0.99.2" codec = { package = "parity-scale-codec", version = "1.2.0" } wasmi = "0.6.2" -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-alpha.2", path = "../../../primitives/allocator" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-alpha.4", path = "../../../primitives/allocator" } sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime-interface" } -sp-serializer = { version = "2.0.0-alpha.2", path = "../../../primitives/serializer" } +sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime-interface" } +sp-serializer = { version = "2.0.0-alpha.4", path = "../../../primitives/serializer" } [features] default = [] diff --git a/client/executor/runtime-test/Cargo.toml b/client/executor/runtime-test/Cargo.toml index ad7c44718d..25de14f223 100644 --- a/client/executor/runtime-test/Cargo.toml +++ b/client/executor/runtime-test/Cargo.toml @@ -10,12 +10,12 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/io" } -sp-sandbox = { version = "0.8.0-alpha.2", default-features = false, path = "../../../primitives/sandbox" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/runtime" } -sp-allocator = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/allocator" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/io" } +sp-sandbox = { version = "0.8.0-alpha.4", default-features = false, path = "../../../primitives/sandbox" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } +sp-allocator = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/allocator" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } diff --git a/client/executor/wasmi/Cargo.toml b/client/executor/wasmi/Cargo.toml index aa259e29f8..ccaf8b449b 100644 --- a/client/executor/wasmi/Cargo.toml +++ b/client/executor/wasmi/Cargo.toml @@ -14,8 +14,8 @@ log = "0.4.8" wasmi = "0.6.2" parity-wasm = "0.41.0" codec = { package = "parity-scale-codec", version = "1.2.0" } -sc-executor-common = { version = "0.8.0-alpha.2", path = "../common" } +sc-executor-common = { version = "0.8.0-alpha.4", path = "../common" } sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime-interface" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-alpha.2", path = "../../../primitives/allocator" } +sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime-interface" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-alpha.4", path = "../../../primitives/allocator" } diff --git a/client/executor/wasmtime/Cargo.toml b/client/executor/wasmtime/Cargo.toml index 9f8784cc98..a7342145b8 100644 --- a/client/executor/wasmtime/Cargo.toml +++ b/client/executor/wasmtime/Cargo.toml @@ -13,11 +13,11 @@ log = "0.4.8" scoped-tls = "1.0" parity-wasm = "0.41.0" codec = { package = "parity-scale-codec", version = "1.2.0" } -sc-executor-common = { version = "0.8.0-alpha.2", path = "../common" } +sc-executor-common = { version = "0.8.0-alpha.4", path = "../common" } sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime-interface" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-alpha.2", path = "../../../primitives/allocator" } +sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime-interface" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-alpha.4", path = "../../../primitives/allocator" } wasmtime = { git = "https://github.com/paritytech/wasmtime", branch = "a-thread-safe-api" } [dev-dependencies] diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index 6cee0cd852..e60052756a 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-finality-grandpa" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,7 +11,7 @@ documentation = "https://docs.rs/sc-finality-grandpa" [dependencies] -fork-tree = { version = "2.0.0-alpha.2", path = "../../utils/fork-tree" } +fork-tree = { version = "2.0.0-alpha.4", path = "../../utils/fork-tree" } futures = "0.3.1" futures-timer = "3.0.1" log = "0.4.8" @@ -19,36 +19,36 @@ parking_lot = "0.10.0" rand = "0.7.2" assert_matches = "1.3.0" parity-scale-codec = { version = "1.2.0", features = ["derive"] } -sp-arithmetic = { version = "2.0.0-alpha.2", path = "../../primitives/arithmetic" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } -sp-consensus = { version = "0.8.0-alpha.1", path = "../../primitives/consensus/common" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-api = { version = "2.0.0-alpha.2", path = "../../primitives/api" } -sc-telemetry = { version = "2.0.0-alpha.2", path = "../telemetry" } -sc-keystore = { version = "2.0.0-alpha.2", path = "../keystore" } +sp-arithmetic = { version = "2.0.0-alpha.4", path = "../../primitives/arithmetic" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } +sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } +sc-keystore = { version = "2.0.0-alpha.4", path = "../keystore" } serde_json = "1.0.41" -sc-client-api = { version = "2.0.0-alpha.2", path = "../api" } -sc-client = { version = "0.8.0-alpha.2", path = "../" } -sp-inherents = { version = "2.0.0-alpha.2", path = "../../primitives/inherents" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../primitives/blockchain" } -sc-network = { version = "0.8.0-alpha.2", path = "../network" } -sc-network-gossip = { version = "0.8.0-alpha.2", path = "../network-gossip" } -sp-finality-tracker = { version = "2.0.0-alpha.2", path = "../../primitives/finality-tracker" } -sp-finality-grandpa = { version = "2.0.0-alpha.2", path = "../../primitives/finality-grandpa" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.2" } -sc-block-builder = { version = "0.8.0-alpha.2", path = "../block-builder" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } +sc-client = { version = "0.8.0-alpha.4", path = "../" } +sp-inherents = { version = "2.0.0-alpha.4", path = "../../primitives/inherents" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } +sc-network = { version = "0.8.0-alpha.4", path = "../network" } +sc-network-gossip = { version = "0.8.0-alpha.4", path = "../network-gossip" } +sp-finality-tracker = { version = "2.0.0-alpha.4", path = "../../primitives/finality-tracker" } +sp-finality-grandpa = { version = "2.0.0-alpha.4", path = "../../primitives/finality-grandpa" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.4"} +sc-block-builder = { version = "0.8.0-alpha.4", path = "../block-builder" } finality-grandpa = { version = "0.11.1", features = ["derive-codec"] } pin-project = "0.4.6" [dev-dependencies] finality-grandpa = { version = "0.11.1", features = ["derive-codec", "test-helpers"] } -sc-network = { version = "0.8.0-alpha.2", path = "../network" } +sc-network = { version = "0.8.0-alpha.4", path = "../network" } sc-network-test = { version = "0.8.0-dev", path = "../network/test" } -sp-keyring = { version = "2.0.0-alpha.2", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } -sp-consensus-babe = { version = "0.8.0-alpha.2", path = "../../primitives/consensus/babe" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../primitives/state-machine" } +sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/babe" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } env_logger = "0.7.0" tokio = { version = "0.2", features = ["rt-core"] } tempfile = "3.1.0" -sp-api = { version = "2.0.0-alpha.2", path = "../../primitives/api" } +sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } diff --git a/client/informant/Cargo.toml b/client/informant/Cargo.toml index d37bfb1cc2..3a7ccaf489 100644 --- a/client/informant/Cargo.toml +++ b/client/informant/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-informant" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "Substrate informant." edition = "2018" @@ -14,8 +14,8 @@ futures = "0.3.1" log = "0.4.8" parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } wasm-timer = "0.2" -sc-client-api = { version = "2.0.0-alpha.2", path = "../api" } -sc-network = { version = "0.8.0-alpha.2", path = "../network" } -sc-service = { version = "0.8.0-alpha.2", default-features = false, path = "../service" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } +sc-network = { version = "0.8.0-alpha.4", path = "../network" } +sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../service" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } diff --git a/client/keystore/Cargo.toml b/client/keystore/Cargo.toml index 247376bc46..aafcd87ded 100644 --- a/client/keystore/Cargo.toml +++ b/client/keystore/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-keystore" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,8 +12,8 @@ documentation = "https://docs.rs/sc-keystore" [dependencies] derive_more = "0.99.2" -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-application-crypto = { version = "2.0.0-alpha.2", path = "../../primitives/application-crypto" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../primitives/application-crypto" } hex = "0.4.0" rand = "0.7.2" serde_json = "1.0.41" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index 955911f1f0..c06c7bbd71 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Gossiping for the Substrate network protocol" name = "sc-network-gossip" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -16,6 +16,6 @@ futures-timer = "3.0.1" libp2p = { version = "0.16.2", default-features = false, features = ["libp2p-websocket"] } log = "0.4.8" lru = "0.4.3" -sc-network = { version = "0.8.0-alpha.2", path = "../network" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } +sc-network = { version = "0.8.0-alpha.4", path = "../network" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } wasm-timer = "0.2" diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index d99dce2fd2..e8422cc0a3 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Substrate network protocol" name = "sc-network" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -21,7 +21,7 @@ derive_more = "0.99.2" either = "1.5.3" erased-serde = "0.3.9" fnv = "1.0.6" -fork-tree = { version = "2.0.0-alpha.2", path = "../../utils/fork-tree" } +fork-tree = { version = "2.0.0-alpha.4", path = "../../utils/fork-tree" } futures = "0.3.1" futures_codec = "0.3.3" futures-timer = "3.0.1" @@ -36,23 +36,23 @@ parking_lot = "0.10.0" prost = "0.6.1" rand = "0.7.2" rustc-hex = "2.0.1" -sc-block-builder = { version = "0.8.0-alpha.2", path = "../block-builder" } -sc-client = { version = "0.8.0-alpha.2", path = "../" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../api" } -sc-peerset = { version = "2.0.0-alpha.2", path = "../peerset" } +sc-block-builder = { version = "0.8.0-alpha.4", path = "../block-builder" } +sc-client = { version = "0.8.0-alpha.4", path = "../" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } +sc-peerset = { version = "2.0.0-alpha.4", path = "../peerset" } pin-project = "0.4.6" serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } slog_derive = "0.2.0" smallvec = "0.6.10" -sp-arithmetic = { version = "2.0.0-alpha.2", path = "../../primitives/arithmetic" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../primitives/blockchain" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../primitives/consensus/common" } -sp-consensus-babe = { version = "0.8.0-alpha.2", path = "../../primitives/consensus/babe" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.2", path = "../../utils/prometheus" } +sp-arithmetic = { version = "2.0.0-alpha.4", path = "../../primitives/arithmetic" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } +sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/babe" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.4", path = "../../utils/prometheus" } thiserror = "1" unsigned-varint = { version = "0.3.1", features = ["futures", "futures-codec"] } void = "1.0.2" @@ -64,7 +64,7 @@ assert_matches = "1.3" env_logger = "0.7.0" quickcheck = "0.9.0" rand = "0.7.2" -sp-keyring = { version = "2.0.0-alpha.2", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } sp-test-primitives = { version = "2.0.0-dev", path = "../../primitives/test-primitives" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index 7fec4f4da8..e1abc49ff4 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -10,21 +10,21 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sc-network = { version = "0.8.0-alpha.2", path = "../" } +sc-network = { version = "0.8.0-alpha.4", path = "../" } log = "0.4.8" parking_lot = "0.10.0" futures = "0.3.1" futures-timer = "3.0.1" rand = "0.7.2" libp2p = { version = "0.16.2", default-features = false, features = ["libp2p-websocket"] } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/common" } -sc-client = { version = "0.8.0-alpha.2", path = "../../" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../../api" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sc-block-builder = { version = "0.8.0-alpha.2", path = "../../block-builder" } -sp-consensus-babe = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/babe" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +sc-client = { version = "0.8.0-alpha.4", path = "../../" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../../api" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sc-block-builder = { version = "0.8.0-alpha.4", path = "../../block-builder" } +sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/babe" } env_logger = "0.7.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../../test-utils/runtime" } diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index 963663ff3e..ecc8621be3 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Substrate offchain workers" name = "sc-offchain" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -10,22 +10,22 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] bytes = "0.5" -sc-client-api = { version = "2.0.0-alpha.2", path = "../api" } -sp-api = { version = "2.0.0-alpha.2", path = "../../primitives/api" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } +sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } fnv = "1.0.6" futures = "0.3.1" futures-timer = "3.0.1" log = "0.4.8" threadpool = "1.7" num_cpus = "1.10" -sp-offchain = { version = "2.0.0-alpha.2", path = "../../primitives/offchain" } +sp-offchain = { version = "2.0.0-alpha.4", path = "../../primitives/offchain" } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } rand = "0.7.2" -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } -sc-network = { version = "0.8.0-alpha.2", path = "../network" } -sc-keystore = { version = "2.0.0-alpha.2", path = "../keystore" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sc-network = { version = "0.8.0-alpha.4", path = "../network" } +sc-keystore = { version = "2.0.0-alpha.4", path = "../keystore" } [target.'cfg(not(target_os = "unknown"))'.dependencies] hyper = "0.13.2" @@ -34,9 +34,9 @@ hyper-rustls = "0.20" [dev-dependencies] env_logger = "0.7.0" fdlimit = "0.1" -sc-client-db = { version = "0.8.0-alpha.2", default-features = true, path = "../db/" } -sc-transaction-pool = { version = "2.0.0-alpha.2", path = "../../client/transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../primitives/transaction-pool" } +sc-client-db = { version = "0.8.0-alpha.4", default-features = true, path = "../db/" } +sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } tokio = "0.2" diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 9e76b8015a..4095e79ed2 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -3,7 +3,7 @@ description = "Connectivity manager based on reputation" homepage = "http://parity.io" license = "GPL-3.0" name = "sc-peerset" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" repository = "https://github.com/paritytech/substrate/" diff --git a/client/rpc-api/Cargo.toml b/client/rpc-api/Cargo.toml index 0f3b72e519..a9a625f743 100644 --- a/client/rpc-api/Cargo.toml +++ b/client/rpc-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-rpc-api" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -18,10 +18,10 @@ jsonrpc-derive = "14.0.3" jsonrpc-pubsub = "14.0.3" log = "0.4.8" parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-version = { version = "2.0.0-alpha.2", path = "../../primitives/version" } -sp-runtime = { path = "../../primitives/runtime" , version = "2.0.0-alpha.2"} +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-version = { version = "2.0.0-alpha.4", path = "../../primitives/version" } +sp-runtime = { path = "../../primitives/runtime" , version = "2.0.0-alpha.4"} serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../primitives/transaction-pool" } -sp-rpc = { version = "2.0.0-alpha.2", path = "../../primitives/rpc" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } +sp-rpc = { version = "2.0.0-alpha.4", path = "../../primitives/rpc" } diff --git a/client/rpc-servers/Cargo.toml b/client/rpc-servers/Cargo.toml index 79d2984c22..117589fe39 100644 --- a/client/rpc-servers/Cargo.toml +++ b/client/rpc-servers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-rpc-server" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,7 +14,7 @@ pubsub = { package = "jsonrpc-pubsub", version = "14.0.3" } log = "0.4.8" serde = "1.0.101" serde_json = "1.0.41" -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } [target.'cfg(not(target_os = "unknown"))'.dependencies] http = { package = "jsonrpc-http-server", version = "14.0.3" } diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index f99e25b14e..dee2fca9f9 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-rpc" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,37 +9,37 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate Client RPC" [dependencies] -sc-rpc-api = { version = "0.8.0-alpha.2", path = "../rpc-api" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../api" } -sc-client = { version = "0.8.0-alpha.2", path = "../" } -sp-api = { version = "2.0.0-alpha.2", path = "../../primitives/api" } +sc-rpc-api = { version = "0.8.0-alpha.4", path = "../rpc-api" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } +sc-client = { version = "0.8.0-alpha.4", path = "../" } +sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.2.0" } futures = { version = "0.3.1", features = ["compat"] } jsonrpc-pubsub = "14.0.3" log = "0.4.8" -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } rpc = { package = "jsonrpc-core", version = "14.0.3" } -sp-version = { version = "2.0.0-alpha.2", path = "../../primitives/version" } +sp-version = { version = "2.0.0-alpha.4", path = "../../primitives/version" } serde_json = "1.0.41" -sp-session = { version = "2.0.0-alpha.2", path = "../../primitives/session" } -sp-offchain = { version = "2.0.0-alpha.2", path = "../../primitives/offchain" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } -sp-rpc = { version = "2.0.0-alpha.2", path = "../../primitives/rpc" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../primitives/state-machine" } -sc-executor = { version = "0.8.0-alpha.2", path = "../executor" } -sc-block-builder = { version = "0.8.0-alpha.2", path = "../../client/block-builder" } -sc-keystore = { version = "2.0.0-alpha.2", path = "../keystore" } -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../primitives/transaction-pool" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../primitives/blockchain" } +sp-session = { version = "2.0.0-alpha.4", path = "../../primitives/session" } +sp-offchain = { version = "2.0.0-alpha.4", path = "../../primitives/offchain" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sp-rpc = { version = "2.0.0-alpha.4", path = "../../primitives/rpc" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } +sc-executor = { version = "0.8.0-alpha.4", path = "../executor" } +sc-block-builder = { version = "0.8.0-alpha.4", path = "../../client/block-builder" } +sc-keystore = { version = "2.0.0-alpha.4", path = "../keystore" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } hash-db = { version = "0.15.2", default-features = false } parking_lot = "0.10.0" [dev-dependencies] assert_matches = "1.3.0" futures01 = { package = "futures", version = "0.1.29" } -sc-network = { version = "0.8.0-alpha.2", path = "../network" } +sc-network = { version = "0.8.0-alpha.4", path = "../network" } rustc-hex = "2.0.1" -sp-io = { version = "2.0.0-alpha.2", path = "../../primitives/io" } +sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } tokio = "0.1.22" -sc-transaction-pool = { version = "2.0.0-alpha.2", path = "../transaction-pool" } +sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../transaction-pool" } diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index ba376ed329..c6d49e55d1 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-service" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -33,36 +33,36 @@ serde = "1.0.101" serde_json = "1.0.41" sysinfo = "0.11.7" target_info = "0.1.0" -sc-keystore = { version = "2.0.0-alpha.2", path = "../keystore" } -sp-io = { version = "2.0.0-alpha.2", path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-session = { version = "2.0.0-alpha.2", path = "../../primitives/session" } -sp-application-crypto = { version = "2.0.0-alpha.2", path = "../../primitives/application-crypto" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../primitives/consensus/common" } -sc-network = { version = "0.8.0-alpha.2", path = "../network" } -sc-chain-spec = { version = "2.0.0-alpha.2", path = "../chain-spec" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../api" } -sc-client = { version = "0.8.0-alpha.2", path = "../" } -sp-api = { version = "2.0.0-alpha.2", path = "../../primitives/api" } -sc-client-db = { version = "0.8.0-alpha.2", path = "../db" } +sc-keystore = { version = "2.0.0-alpha.4", path = "../keystore" } +sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-session = { version = "2.0.0-alpha.4", path = "../../primitives/session" } +sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../primitives/application-crypto" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } +sc-network = { version = "0.8.0-alpha.4", path = "../network" } +sc-chain-spec = { version = "2.0.0-alpha.4", path = "../chain-spec" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } +sc-client = { version = "0.8.0-alpha.4", path = "../" } +sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } +sc-client-db = { version = "0.8.0-alpha.4", path = "../db" } codec = { package = "parity-scale-codec", version = "1.2.0" } -sc-executor = { version = "0.8.0-alpha.2", path = "../executor" } -sc-transaction-pool = { version = "2.0.0-alpha.2", path = "../transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../primitives/transaction-pool" } -sc-rpc-server = { version = "2.0.0-alpha.2", path = "../rpc-servers" } -sc-rpc = { version = "2.0.0-alpha.2", path = "../rpc" } -sc-telemetry = { version = "2.0.0-alpha.2", path = "../telemetry" } -sc-offchain = { version = "2.0.0-alpha.2", path = "../offchain" } +sc-executor = { version = "0.8.0-alpha.4", path = "../executor" } +sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../transaction-pool" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } +sc-rpc-server = { version = "2.0.0-alpha.4", path = "../rpc-servers" } +sc-rpc = { version = "2.0.0-alpha.4", path = "../rpc" } +sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } +sc-offchain = { version = "2.0.0-alpha.4", path = "../offchain" } parity-multiaddr = { package = "parity-multiaddr", version = "0.7.3" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" , version = "0.8.0-alpha.2"} -sc-tracing = { version = "2.0.0-alpha.2", path = "../tracing" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" , version = "0.8.0-alpha.4"} +sc-tracing = { version = "2.0.0-alpha.4", path = "../tracing" } tracing = "0.1.10" parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } -sp-consensus-babe = { version = "0.8.0-alpha.2", path = "../../primitives/consensus/babe" } -grandpa = { version = "0.8.0-alpha.2", package = "sc-finality-grandpa", path = "../finality-grandpa" } -grandpa-primitives = { version = "2.0.0-alpha.2", package = "sp-finality-grandpa", path = "../../primitives/finality-grandpa" } +sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/babe" } +grandpa = { version = "0.8.0-alpha.4", package = "sc-finality-grandpa", path = "../finality-grandpa" } +grandpa-primitives = { version = "2.0.0-alpha.4", package = "sp-finality-grandpa", path = "../../primitives/finality-grandpa" } diff --git a/client/service/test/Cargo.toml b/client/service/test/Cargo.toml index f27f880330..41ccd0369a 100644 --- a/client/service/test/Cargo.toml +++ b/client/service/test/Cargo.toml @@ -16,10 +16,10 @@ log = "0.4.8" env_logger = "0.7.0" fdlimit = "0.1.1" futures = { version = "0.3.1", features = ["compat"] } -sc-service = { version = "0.8.0-alpha.2", default-features = false, path = "../../service" } -sc-network = { version = "0.8.0-alpha.2", path = "../../network" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/common" } -sc-client = { version = "0.8.0-alpha.2", path = "../../" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../../primitives/transaction-pool" } +sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../../service" } +sc-network = { version = "0.8.0-alpha.4", path = "../../network" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +sc-client = { version = "0.8.0-alpha.4", path = "../../" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../primitives/transaction-pool" } diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index da62696a15..a1978b4e75 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-state-db" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,8 +11,8 @@ description = "State database maintenance. Handles canonicalization and pruning [dependencies] parking_lot = "0.10.0" log = "0.4.8" -sc-client-api = { version = "2.0.0-alpha.2", path = "../api" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } parity-util-mem = "0.5.2" parity-util-mem-derive = "0.1.0" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index 248c90ec68..e643f44d0c 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-telemetry" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] description = "Telemetry utils" edition = "2018" diff --git a/client/tracing/Cargo.toml b/client/tracing/Cargo.toml index ad988f0607..b5e75fcb03 100644 --- a/client/tracing/Cargo.toml +++ b/client/tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-tracing" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -17,7 +17,7 @@ serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } tracing-core = "0.1.7" -sc-telemetry = { version = "2.0.0-alpha.2", path = "../telemetry" } +sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } [dev-dependencies] tracing = "0.1.10" diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 233397262a..aee4564c2e 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-transaction-pool" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,17 +16,17 @@ futures-diagnose = "1.0" log = "0.4.8" parking_lot = "0.10.0" wasm-timer = "0.2" -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-api = { version = "2.0.0-alpha.2", path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } -sc-transaction-graph = { version = "2.0.0-alpha.2", path = "./graph" } -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../primitives/transaction-pool" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../api" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sc-transaction-graph = { version = "2.0.0-alpha.4", path = "./graph" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } futures-timer = "2.0" parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.2", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } substrate-test-runtime-transaction-pool = { version = "2.0.0-dev", path = "../../test-utils/runtime/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index 080061dd25..05642de9f7 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-transaction-graph" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,10 +15,10 @@ log = "0.4.8" parking_lot = "0.10.0" serde = { version = "1.0.101", features = ["derive"] } wasm-timer = "0.2" -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../../primitives/transaction-pool" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../primitives/transaction-pool" } parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } linked-hash-map = "0.5.2" diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md new file mode 100644 index 0000000000..0570f6f15d --- /dev/null +++ b/docs/CHANGELOG.md @@ -0,0 +1,46 @@ +# Changelog + +The format is based on [Keep a Changelog]. + +[Keep a Changelog]: http://keepachangelog.com/en/1.0.0/ + +## Unreleased + +## 2.0.0-alpha.3 -> 2.0.0-alpha.4 + +Runtime +------- + +* Move runtime upgrade to `frame-executive` (#5197) +* Split fees and tips between author and treasury independently (#5207) +* Refactor session away from needless double_maps (#5202) +* Remove `secp256k1` from WASM build (#5187) +* Introduce default-setting prime for collective (#5137) +* Adds `vested_transfer` to Vesting pallet (#5029) +* Change extrinsic_count to extrinsic_index in pallet-utility (#5044) + +Client +------ + +* client/finality-grandpa: Add Prometheus metrics to GossipValidator (#5237) +* removes use of sc_client::Client from node-transaction-factory (#5158) +* removes use of sc_client::Client from sc_network (#5147) +* Use CLI to configure max instances cache (#5177) +* client/service/src/builder.rs: Add build_info metric (#5192) +* Remove substrate-ui.parity.io from CORS whitelist (#5142) +* removes use of sc_client::Client from sc-rpc (#5063) +* Use 128mb for db cache default (#5134) +* Drop db-cache default from 1gig to 32mb (#5128) +* Add more metrics to prometheus (#5034) + +API +--- + +* Produce block always on updated transaction pool state (#5227) +* Add `ext_terminate` (#5234) +* Add ext_transfer call (#5169) +* ChainSpec trait (#5185) +* client/authority-discovery: Instrument code with Prometheus (#5195) +* Don't include `:code` by default in storage proofs (#5179) +* client/network-gossip: Merge GossipEngine and GossipEngineInner (#5042) +* Introduce `on_runtime_upgrade` (#5058) \ No newline at end of file diff --git a/frame/assets/Cargo.toml b/frame/assets/Cargo.toml index 5b0b5f096a..9f82331062 100644 --- a/frame/assets/Cargo.toml +++ b/frame/assets/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-assets" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,16 +12,16 @@ description = "FRAME asset management pallet" serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } # Needed for various traits. In our case, `OnFinalize`. -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } # Needed for type-safe access to storage DB. -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } # `system` module provides us with all sorts of useful stuff and macros depend on it being around. -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.2", path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.4", path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/aura/Cargo.toml b/frame/aura/Cargo.toml index 77abfe4ae1..20438c006c 100644 --- a/frame/aura/Cargo.toml +++ b/frame/aura/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-aura" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,20 +9,20 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME AURA consensus pallet" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/inherents" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -pallet-session = { version = "2.0.0-alpha.2", default-features = false, path = "../session" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.2"} -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -sp-consensus-aura = { path = "../../primitives/consensus/aura", default-features = false, version = "0.8.0-alpha.2"} -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -sp-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/timestamp" } -pallet-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../timestamp" } +pallet-session = { version = "2.0.0-alpha.4", default-features = false, path = "../session" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +sp-consensus-aura = { path = "../../primitives/consensus/aura", default-features = false, version = "0.8.0-alpha.4"} +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/timestamp" } +pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../timestamp" } [dev-dependencies] diff --git a/frame/authority-discovery/Cargo.toml b/frame/authority-discovery/Cargo.toml index c82d1eab58..9da18af6b3 100644 --- a/frame/authority-discovery/Cargo.toml +++ b/frame/authority-discovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-authority-discovery" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,20 +9,20 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for authority discovery" [dependencies] -sp-authority-discovery = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/authority-discovery" } -sp-application-crypto = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/application-crypto" } +sp-authority-discovery = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/authority-discovery" } +sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -pallet-session = { version = "2.0.0-alpha.2", features = ["historical" ], path = "../session", default-features = false } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +pallet-session = { version = "2.0.0-alpha.4", features = ["historical" ], path = "../session", default-features = false } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] -sp-staking = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/staking" } +sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } [features] default = ["std"] diff --git a/frame/authorship/Cargo.toml b/frame/authorship/Cargo.toml index 2a01cdbd8a..2ec4d9df70 100644 --- a/frame/authorship/Cargo.toml +++ b/frame/authorship/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-authorship" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" description = "Block and Uncle Author tracking for the FRAME" authors = ["Parity Technologies "] edition = "2018" @@ -9,15 +9,15 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/inherents" } -sp-authorship = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/authorship" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.2"} +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } +sp-authorship = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/authorship" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} impl-trait-for-tuples = "0.1.3" [features] diff --git a/frame/babe/Cargo.toml b/frame/babe/Cargo.toml index 7e39e5bed5..28f3d98701 100644 --- a/frame/babe/Cargo.toml +++ b/frame/babe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-babe" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,23 +12,23 @@ description = "Consensus extension module for BABE consensus. Collects on-chain hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../timestamp" } -sp-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/timestamp" } -pallet-session = { version = "2.0.0-alpha.2", default-features = false, path = "../session" } -sp-consensus-babe = { version = "0.8.0-alpha.2", default-features = false, path = "../../primitives/consensus/babe" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.2"} +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../timestamp" } +sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/timestamp" } +pallet-session = { version = "2.0.0-alpha.4", default-features = false, path = "../session" } +sp-consensus-babe = { version = "0.8.0-alpha.4", default-features = false, path = "../../primitives/consensus/babe" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} [dev-dependencies] lazy_static = "1.4.0" parking_lot = "0.10.0" -sp-version = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/version" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/version" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } [features] diff --git a/frame/balances/Cargo.toml b/frame/balances/Cargo.toml index 6bb551c9c6..f51942bbea 100644 --- a/frame/balances/Cargo.toml +++ b/frame/balances/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-balances" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "FRAME pallet to manage balances" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -pallet-transaction-payment = { version = "2.0.0-alpha.2", path = "../transaction-payment" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +pallet-transaction-payment = { version = "2.0.0-alpha.4", path = "../transaction-payment" } [features] default = ["std"] diff --git a/frame/benchmark/Cargo.toml b/frame/benchmark/Cargo.toml index ac6fdbfe52..cbdc017049 100644 --- a/frame/benchmark/Cargo.toml +++ b/frame/benchmark/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-benchmark" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,12 +8,12 @@ license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.3", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.3", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.3", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.3", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.3", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-alpha.3", default-features = false, path = "../benchmarking", optional = true } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } [features] default = ["std"] diff --git a/frame/benchmarking/Cargo.toml b/frame/benchmarking/Cargo.toml index b39031a6b7..efd15cf004 100644 --- a/frame/benchmarking/Cargo.toml +++ b/frame/benchmarking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-benchmarking" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,13 +10,13 @@ description = "Macro for benchmarking a FRAME runtime." [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-api = { version = "2.0.0-alpha.2", path = "../../primitives/api", default-features = false } -sp-runtime-interface = { version = "2.0.0-alpha.2", path = "../../primitives/runtime-interface", default-features = false } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime", default-features = false } -sp-std = { version = "2.0.0-alpha.2", path = "../../primitives/std", default-features = false } -sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.2" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api", default-features = false } +sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../primitives/runtime-interface", default-features = false } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime", default-features = false } +sp-std = { version = "2.0.0-alpha.4", path = "../../primitives/std", default-features = false } +sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.4"} +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [features] default = [ "std" ] diff --git a/frame/collective/Cargo.toml b/frame/collective/Cargo.toml index 60899feb4f..5cc0ecb381 100644 --- a/frame/collective/Cargo.toml +++ b/frame/collective/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-collective" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "Collective system: Members of a set of account IDs can make their [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } [features] default = ["std"] diff --git a/frame/contracts/Cargo.toml b/frame/contracts/Cargo.toml index 86f39f8a82..e2b0f628cd 100644 --- a/frame/contracts/Cargo.toml +++ b/frame/contracts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,22 +14,22 @@ pwasm-utils = { version = "0.12.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } parity-wasm = { version = "0.41.0", default-features = false } wasmi-validation = { version = "0.3.0", default-features = false } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-sandbox = { version = "0.8.0-alpha.2", default-features = false, path = "../../primitives/sandbox" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -pallet-contracts-primitives = { version = "2.0.0-alpha.2", default-features = false, path = "common" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-sandbox = { version = "0.8.0-alpha.4", default-features = false, path = "../../primitives/sandbox" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +pallet-contracts-primitives = { version = "2.0.0-alpha.4", default-features = false, path = "common" } [dev-dependencies] wabt = "0.9.2" assert_matches = "1.3.0" hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } -pallet-timestamp = { version = "2.0.0-alpha.2", path = "../timestamp" } -pallet-randomness-collective-flip = { version = "2.0.0-alpha.2", path = "../randomness-collective-flip" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +pallet-timestamp = { version = "2.0.0-alpha.4", path = "../timestamp" } +pallet-randomness-collective-flip = { version = "2.0.0-alpha.4", path = "../randomness-collective-flip" } [features] default = ["std"] diff --git a/frame/contracts/common/Cargo.toml b/frame/contracts/common/Cargo.toml index 0d009e7c82..dcb1763a94 100644 --- a/frame/contracts/common/Cargo.toml +++ b/frame/contracts/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts-primitives" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,8 +11,8 @@ description = "A crate that hosts a common definitions that are relevant for the [dependencies] # This crate should not rely on any of the frame primitives. codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } [features] default = ["std"] diff --git a/frame/contracts/rpc/Cargo.toml b/frame/contracts/rpc/Cargo.toml index 092d049c54..d3338a7ad4 100644 --- a/frame/contracts/rpc/Cargo.toml +++ b/frame/contracts/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts-rpc" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,14 +13,14 @@ codec = { package = "parity-scale-codec", version = "1.2.0" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-rpc = { version = "2.0.0-alpha.2", path = "../../../primitives/rpc" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-rpc = { version = "2.0.0-alpha.4", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.2", path = "../../../primitives/api" } -pallet-contracts-primitives = { version = "2.0.0-alpha.2", path = "../common" } -pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.2", path = "./runtime-api" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } +pallet-contracts-primitives = { version = "2.0.0-alpha.4", path = "../common" } +pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.4", path = "./runtime-api" } [dev-dependencies] serde_json = "1.0.41" diff --git a/frame/contracts/rpc/runtime-api/Cargo.toml b/frame/contracts/rpc/runtime-api/Cargo.toml index 8435a6c423..880c53c21a 100644 --- a/frame/contracts/rpc/runtime-api/Cargo.toml +++ b/frame/contracts/rpc/runtime-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts-rpc-runtime-api" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,11 +9,11 @@ repository = "https://github.com/paritytech/substrate/" description = "Runtime API definition required by Contracts RPC extensions." [dependencies] -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../../../../primitives/api" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../../../primitives/runtime" } -pallet-contracts-primitives = { version = "2.0.0-alpha.2", default-features = false, path = "../../common" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/runtime" } +pallet-contracts-primitives = { version = "2.0.0-alpha.4", default-features = false, path = "../../common" } [features] default = ["std"] diff --git a/frame/democracy/Cargo.toml b/frame/democracy/Cargo.toml index d2938956bd..cd9a94ae04 100644 --- a/frame/democracy/Cargo.toml +++ b/frame/democracy/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-democracy" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "FRAME pallet for democracy" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } -sp-storage = { version = "2.0.0-alpha.2", path = "../../primitives/storage" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +sp-storage = { version = "2.0.0-alpha.4", path = "../../primitives/storage" } hex-literal = "0.2.1" [features] diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index 62ae091e9a..a7514b10a3 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-elections-phragmen" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,17 +10,17 @@ description = "FRAME election pallet for PHRAGMEN" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-phragmen = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/phragmen" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-phragmen = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/phragmen" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.2", path = "../../primitives/io" } +sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } substrate-test-utils = { version = "2.0.0-alpha.2", path = "../../test-utils" } serde = { version = "1.0.101" } diff --git a/frame/elections/Cargo.toml b/frame/elections/Cargo.toml index e65f4e5d46..40b05a6d1e 100644 --- a/frame/elections/Cargo.toml +++ b/frame/elections/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-elections" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "FRAME pallet for elections" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } [features] default = ["std"] diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml index 76407d57e4..b252dac689 100644 --- a/frame/evm/Cargo.toml +++ b/frame/evm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-evm" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,14 +11,14 @@ description = "FRAME EVM contracts pallet" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../timestamp" } -pallet-balances = { version = "2.0.0-alpha.2", default-features = false, path = "../balances" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../timestamp" } +pallet-balances = { version = "2.0.0-alpha.4", default-features = false, path = "../balances" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } primitive-types = { version = "0.6.2", default-features = false, features = ["rlp"] } rlp = { version = "0.4", default-features = false } evm = { version = "0.15", default-features = false } diff --git a/frame/example-offchain-worker/Cargo.toml b/frame/example-offchain-worker/Cargo.toml index ff8d780c3c..2eafe9185d 100644 --- a/frame/example-offchain-worker/Cargo.toml +++ b/frame/example-offchain-worker/Cargo.toml @@ -10,13 +10,13 @@ description = "FRAME example pallet for offchain worker" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } serde = { version = "1.0.101", optional = true } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } serde_json = { version = "1.0.46", default-features = false, features = ["alloc"] } [features] diff --git a/frame/example/Cargo.toml b/frame/example/Cargo.toml index 515d1fd8d7..9edd365405 100644 --- a/frame/example/Cargo.toml +++ b/frame/example/Cargo.toml @@ -11,16 +11,16 @@ description = "FRAME example pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -pallet-balances = { version = "2.0.0-alpha.2", default-features = false, path = "../balances" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } +frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +pallet-balances = { version = "2.0.0-alpha.4", default-features = false, path = "../balances" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/executive/Cargo.toml b/frame/executive/Cargo.toml index 44751b0f3f..0921c0433b 100644 --- a/frame/executive/Cargo.toml +++ b/frame/executive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-executive" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,20 +10,20 @@ description = "FRAME executives engine" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } serde = { version = "1.0.101", optional = true } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } [dev-dependencies] hex-literal = "0.2.1" -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-io ={ path = "../../primitives/io", version = "2.0.0-alpha.2"} -pallet-indices = { version = "2.0.0-alpha.2", path = "../indices" } -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } -pallet-transaction-payment = { version = "2.0.0-alpha.2", path = "../transaction-payment" } -sp-version = { version = "2.0.0-alpha.2", path = "../../primitives/version" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-io ={ path = "../../primitives/io", version = "2.0.0-alpha.4"} +pallet-indices = { version = "2.0.0-alpha.4", path = "../indices" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +pallet-transaction-payment = { version = "2.0.0-alpha.4", path = "../transaction-payment" } +sp-version = { version = "2.0.0-alpha.4", path = "../../primitives/version" } [features] default = ["std"] diff --git a/frame/finality-tracker/Cargo.toml b/frame/finality-tracker/Cargo.toml index 1313080dfe..e7e109d8ef 100644 --- a/frame/finality-tracker/Cargo.toml +++ b/frame/finality-tracker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-finality-tracker" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,17 +13,17 @@ documentation = "https://docs.rs/pallet-finality-tracker" [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-finality-tracker = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/finality-tracker" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-finality-tracker = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/finality-tracker" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/generic-asset/Cargo.toml b/frame/generic-asset/Cargo.toml index a8df92e3c6..6fc69a09a6 100644 --- a/frame/generic-asset/Cargo.toml +++ b/frame/generic-asset/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-generic-asset" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Centrality Developers "] edition = "2018" license = "GPL-3.0" @@ -11,14 +11,14 @@ description = "FRAME pallet for generic asset management" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.2", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-alpha.4", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/grandpa/Cargo.toml b/frame/grandpa/Cargo.toml index f5cce65fe9..1e64f66a6a 100644 --- a/frame/grandpa/Cargo.toml +++ b/frame/grandpa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-grandpa" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,18 +11,18 @@ description = "FRAME pallet for GRANDPA finality gadget" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-finality-grandpa = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/finality-grandpa" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -pallet-session = { version = "2.0.0-alpha.2", default-features = false, path = "../session" } -pallet-finality-tracker = { version = "2.0.0-alpha.2", default-features = false, path = "../finality-tracker" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-finality-grandpa = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/finality-grandpa" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-alpha.4", default-features = false, path = "../session" } +pallet-finality-tracker = { version = "2.0.0-alpha.4", default-features = false, path = "../finality-tracker" } [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.2", path = "../../primitives/io" } +sp-io ={ version = "2.0.0-alpha.4", path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/identity/Cargo.toml b/frame/identity/Cargo.toml index 3dbffedffc..1371b2ce50 100644 --- a/frame/identity/Cargo.toml +++ b/frame/identity/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-identity" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,16 +12,16 @@ description = "FRAME identity management pallet" serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } [features] default = ["std"] diff --git a/frame/im-online/Cargo.toml b/frame/im-online/Cargo.toml index ab8c066945..2b9e80ce4e 100644 --- a/frame/im-online/Cargo.toml +++ b/frame/im-online/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-im-online" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,18 +9,18 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME's I'm online pallet" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/application-crypto" } -pallet-authorship = { version = "2.0.0-alpha.2", default-features = false, path = "../authorship" } +sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/application-crypto" } +pallet-authorship = { version = "2.0.0-alpha.4", default-features = false, path = "../authorship" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -pallet-session = { version = "2.0.0-alpha.2", default-features = false, path = "../session" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-alpha.4", default-features = false, path = "../session" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [features] default = ["std", "pallet-session/historical"] diff --git a/frame/indices/Cargo.toml b/frame/indices/Cargo.toml index d7e01765b5..6909988449 100644 --- a/frame/indices/Cargo.toml +++ b/frame/indices/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-indices" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "FRAME indices management pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-keyring = { version = "2.0.0-alpha.2", optional = true, path = "../../primitives/keyring" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-keyring = { version = "2.0.0-alpha.4", optional = true, path = "../../primitives/keyring" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } [features] default = ["std"] diff --git a/frame/membership/Cargo.toml b/frame/membership/Cargo.toml index b54109083d..ca267ae800 100644 --- a/frame/membership/Cargo.toml +++ b/frame/membership/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-membership" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,14 +11,14 @@ description = "FRAME membership management pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/metadata/Cargo.toml b/frame/metadata/Cargo.toml index b3d333f369..a01ec9bce5 100644 --- a/frame/metadata/Cargo.toml +++ b/frame/metadata/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-metadata" -version = "11.0.0-alpha.3" +version = "11.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,8 +11,8 @@ description = "Decodable variant of the RuntimeMetadata." [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/nicks/Cargo.toml b/frame/nicks/Cargo.toml index 07c84c439f..9c48a60863 100644 --- a/frame/nicks/Cargo.toml +++ b/frame/nicks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-nicks" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,15 +11,15 @@ description = "FRAME pallet for nick management" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } [features] default = ["std"] diff --git a/frame/offences/Cargo.toml b/frame/offences/Cargo.toml index 99c52e4088..2ab98265d8 100644 --- a/frame/offences/Cargo.toml +++ b/frame/offences/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-offences" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,18 +9,18 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME offences pallet" [dependencies] -pallet-balances = { version = "2.0.0-alpha.2", default-features = false, path = "../balances" } +pallet-balances = { version = "2.0.0-alpha.4", default-features = false, path = "../balances" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.2", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/randomness-collective-flip/Cargo.toml b/frame/randomness-collective-flip/Cargo.toml index 4e4ce76fee..645809bd13 100644 --- a/frame/randomness-collective-flip/Cargo.toml +++ b/frame/randomness-collective-flip/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-randomness-collective-flip" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,14 +11,14 @@ description = "FRAME randomness collective flip pallet" [dependencies] safe-mix = { version = "1.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-io = { version = "2.0.0-alpha.2", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/recovery/Cargo.toml b/frame/recovery/Cargo.toml index 80456aa375..e67cd3b340 100644 --- a/frame/recovery/Cargo.toml +++ b/frame/recovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-recovery" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,15 +12,15 @@ description = "FRAME account recovery pallet" serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } [features] default = ["std"] diff --git a/frame/scored-pool/Cargo.toml b/frame/scored-pool/Cargo.toml index a1b7b39d8c..f4f54c9498 100644 --- a/frame/scored-pool/Cargo.toml +++ b/frame/scored-pool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-scored-pool" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,15 +11,15 @@ description = "FRAME pallet for scored pools" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/session/Cargo.toml b/frame/session/Cargo.toml index 5bea3ecb9f..3211399bd6 100644 --- a/frame/session/Cargo.toml +++ b/frame/session/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-session" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,19 +11,19 @@ description = "FRAME sessions pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../timestamp" } -sp-trie = { optional = true, path = "../../primitives/trie", default-features = false, version = "2.0.0-alpha.2"} -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.2"} +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../timestamp" } +sp-trie = { optional = true, path = "../../primitives/trie", default-features = false, version = "2.0.0-alpha.4"} +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-application-crypto = { version = "2.0.0-alpha.2", path = "../../primitives/application-crypto" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../primitives/application-crypto" } lazy_static = "1.4.0" [features] diff --git a/frame/session/benchmarking/Cargo.toml b/frame/session/benchmarking/Cargo.toml index ec117e03e2..91721f05d4 100644 --- a/frame/session/benchmarking/Cargo.toml +++ b/frame/session/benchmarking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-session-benchmarking" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,12 +9,12 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME sessions pallet benchmarking" [dependencies] -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/runtime" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../../system" } -frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../../benchmarking" } -pallet-staking = { version = "2.0.0-alpha.2", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } -pallet-session = { version = "2.0.0-alpha.2", default-features = false, path = "../../session" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../../system" } +frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../../benchmarking" } +pallet-staking = { version = "2.0.0-alpha.4", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } +pallet-session = { version = "2.0.0-alpha.4", default-features = false, path = "../../session" } [features] default = ["std"] diff --git a/frame/society/Cargo.toml b/frame/society/Cargo.toml index 35b1c5c4a4..feeebfac2c 100644 --- a/frame/society/Cargo.toml +++ b/frame/society/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-society" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "FRAME society pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.2"} -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } rand_chacha = { version = "0.2", default-features = false } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } [features] default = ["std"] diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index e83f263285..e1991d4a2a 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-staking" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,27 +11,27 @@ description = "FRAME pallet staking" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-keyring = { version = "2.0.0-alpha.2", optional = true, path = "../../primitives/keyring" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-phragmen = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/phragmen" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.2"} -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -pallet-session = { version = "2.0.0-alpha.2", features = ["historical"], path = "../session", default-features = false } -pallet-authorship = { version = "2.0.0-alpha.2", default-features = false, path = "../authorship" } +sp-keyring = { version = "2.0.0-alpha.4", optional = true, path = "../../primitives/keyring" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-phragmen = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/phragmen" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-alpha.4", features = ["historical"], path = "../session", default-features = false } +pallet-authorship = { version = "2.0.0-alpha.4", default-features = false, path = "../authorship" } -frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } rand_chacha = { version = "0.2", default-features = false, optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } -pallet-timestamp = { version = "2.0.0-alpha.2", path = "../timestamp" } -pallet-staking-reward-curve = { version = "2.0.0-alpha.2", path = "../staking/reward-curve" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +pallet-timestamp = { version = "2.0.0-alpha.4", path = "../timestamp" } +pallet-staking-reward-curve = { version = "2.0.0-alpha.4", path = "../staking/reward-curve" } substrate-test-utils = { version = "2.0.0-alpha.2", path = "../../test-utils" } -frame-benchmarking = { version = "2.0.0-alpha.2", path = "../benchmarking" } +frame-benchmarking = { version = "2.0.0-alpha.4", path = "../benchmarking" } rand_chacha = { version = "0.2" } [features] diff --git a/frame/staking/reward-curve/Cargo.toml b/frame/staking/reward-curve/Cargo.toml index d55813682e..abdcf6426b 100644 --- a/frame/staking/reward-curve/Cargo.toml +++ b/frame/staking/reward-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-staking-reward-curve" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -18,4 +18,4 @@ proc-macro2 = "1.0.6" proc-macro-crate = "0.1.4" [dev-dependencies] -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } diff --git a/frame/sudo/Cargo.toml b/frame/sudo/Cargo.toml index 8d645df85c..d15349b8f7 100644 --- a/frame/sudo/Cargo.toml +++ b/frame/sudo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-sudo" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,14 +11,14 @@ description = "FRAME pallet for sudo" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index 8f0dd255ac..7bd77488b6 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,24 +12,24 @@ description = "Support code for the runtime." log = "0.4" serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -frame-metadata = { version = "11.0.0-alpha.2", default-features = false, path = "../metadata" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.2"} -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-arithmetic = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/arithmetic" } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/inherents" } -frame-support-procedural = { version = "2.0.0-alpha.2", path = "./procedural" } +frame-metadata = { version = "11.0.0-alpha.4", default-features = false, path = "../metadata" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-arithmetic = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/arithmetic" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } +frame-support-procedural = { version = "2.0.0-alpha.4", path = "./procedural" } paste = "0.1.6" once_cell = { version = "1", default-features = false, optional = true } -sp-state-machine = { version = "0.8.0-alpha.2", optional = true, path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-alpha.4", optional = true, path = "../../primitives/state-machine" } bitmask = { version = "0.5.0", default-features = false } impl-trait-for-tuples = "0.1.3" tracing = { version = "0.1.10", optional = true } [dev-dependencies] pretty_assertions = "0.6.1" -frame-system = { version = "2.0.0-alpha.2", path = "../system" } +frame-system = { version = "2.0.0-alpha.4", path = "../system" } [features] default = ["std"] diff --git a/frame/support/procedural/Cargo.toml b/frame/support/procedural/Cargo.toml index 8d8ecb18a7..9ef0ea56d5 100644 --- a/frame/support/procedural/Cargo.toml +++ b/frame/support/procedural/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support-procedural" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,7 +12,7 @@ description = "Proc macro of Support code for the runtime." proc-macro = true [dependencies] -frame-support-procedural-tools = { version = "2.0.0-alpha.2", path = "./tools" } +frame-support-procedural-tools = { version = "2.0.0-alpha.4", path = "./tools" } proc-macro2 = "1.0.6" quote = "1.0.3" syn = { version = "1.0.7", features = ["full"] } diff --git a/frame/support/procedural/tools/Cargo.toml b/frame/support/procedural/tools/Cargo.toml index 52773f6fbe..4bd008c877 100644 --- a/frame/support/procedural/tools/Cargo.toml +++ b/frame/support/procedural/tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support-procedural-tools" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "Proc macro helpers for procedural macros" [dependencies] -frame-support-procedural-tools-derive = { version = "2.0.0-alpha.2", path = "./derive" } +frame-support-procedural-tools-derive = { version = "2.0.0-alpha.4", path = "./derive" } proc-macro2 = "1.0.6" quote = "1.0.3" syn = { version = "1.0.7", features = ["full", "visit"] } diff --git a/frame/support/procedural/tools/derive/Cargo.toml b/frame/support/procedural/tools/derive/Cargo.toml index 6bed290c7d..837c5b5b40 100644 --- a/frame/support/procedural/tools/derive/Cargo.toml +++ b/frame/support/procedural/tools/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support-procedural-tools-derive" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index 0a5595914b..cd0375f066 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -11,12 +11,12 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-io ={ path = "../../../primitives/io", default-features = false , version = "2.0.0-alpha.2"} -sp-state-machine = { version = "0.8.0-alpha.2", optional = true, path = "../../../primitives/state-machine" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../" } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/inherents" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../../primitives/core" } +sp-io ={ path = "../../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} +sp-state-machine = { version = "0.8.0-alpha.4", optional = true, path = "../../../primitives/state-machine" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/inherents" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/core" } trybuild = "1.0.17" pretty_assertions = "0.6.1" diff --git a/frame/system/Cargo.toml b/frame/system/Cargo.toml index 4e350be1a9..369083f97a 100644 --- a/frame/system/Cargo.toml +++ b/frame/system/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-system" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,17 +11,17 @@ description = "FRAME system module" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.2" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-version = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/version" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.4"} +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/version" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] criterion = "0.2.11" -sp-externalities = { version = "0.8.0-alpha.2", path = "../../primitives/externalities" } +sp-externalities = { version = "0.8.0-alpha.4", path = "../../primitives/externalities" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } [features] diff --git a/frame/system/rpc/runtime-api/Cargo.toml b/frame/system/rpc/runtime-api/Cargo.toml index 3bcc34698a..861d72a748 100644 --- a/frame/system/rpc/runtime-api/Cargo.toml +++ b/frame/system/rpc/runtime-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-system-rpc-runtime-api" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "Runtime API definition required by System RPC extensions." [dependencies] -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../../../../primitives/api" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } [features] diff --git a/frame/timestamp/Cargo.toml b/frame/timestamp/Cargo.toml index ff5b72de67..2c186a97ca 100644 --- a/frame/timestamp/Cargo.toml +++ b/frame/timestamp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-timestamp" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,19 +13,19 @@ documentation = "https://docs.rs/pallet-timestamp" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io", optional = true } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/inherents" } -frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -sp-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/timestamp" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io", optional = true } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } +frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/timestamp" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.2", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-alpha.4", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/transaction-payment/Cargo.toml b/frame/transaction-payment/Cargo.toml index 3a291dc516..0b8d681d39 100644 --- a/frame/transaction-payment/Cargo.toml +++ b/frame/transaction-payment/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-payment" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,16 +10,16 @@ description = "FRAME pallet to manage transaction payments" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.2", default-features = false, path = "./rpc/runtime-api" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.4", default-features = false, path = "./rpc/runtime-api" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.2", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } +sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } [features] default = ["std"] diff --git a/frame/transaction-payment/rpc/Cargo.toml b/frame/transaction-payment/rpc/Cargo.toml index 309dfeedd5..5b1fa9bb97 100644 --- a/frame/transaction-payment/rpc/Cargo.toml +++ b/frame/transaction-payment/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-payment-rpc" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,10 +13,10 @@ codec = { package = "parity-scale-codec", version = "1.2.0" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sp-rpc = { version = "2.0.0-alpha.2", path = "../../../primitives/rpc" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-rpc = { version = "2.0.0-alpha.4", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.2", path = "../../../primitives/api" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.2", path = "./runtime-api" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.4", path = "./runtime-api" } diff --git a/frame/transaction-payment/rpc/runtime-api/Cargo.toml b/frame/transaction-payment/rpc/runtime-api/Cargo.toml index 96716769a3..ca1258c5e9 100644 --- a/frame/transaction-payment/rpc/runtime-api/Cargo.toml +++ b/frame/transaction-payment/rpc/runtime-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-payment-rpc-runtime-api" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,11 +10,11 @@ description = "RPC runtime API for transaction payment FRAME pallet" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../../../../primitives/api" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../../../support" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../../../support" } [dev-dependencies] serde_json = "1.0.41" diff --git a/frame/treasury/Cargo.toml b/frame/treasury/Cargo.toml index 99071e9276..f6429ec1c7 100644 --- a/frame/treasury/Cargo.toml +++ b/frame/treasury/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-treasury" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,15 +11,15 @@ description = "FRAME pallet to manage treasury" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -pallet-balances = { version = "2.0.0-alpha.2", default-features = false, path = "../balances" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +pallet-balances = { version = "2.0.0-alpha.4", default-features = false, path = "../balances" } [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.2", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-alpha.4", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/utility/Cargo.toml b/frame/utility/Cargo.toml index 46f59a191a..d77e5fcd69 100644 --- a/frame/utility/Cargo.toml +++ b/frame/utility/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-utility" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "FRAME utilities pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } [features] default = ["std"] diff --git a/frame/vesting/Cargo.toml b/frame/vesting/Cargo.toml index 882c062c43..1563813361 100644 --- a/frame/vesting/Cargo.toml +++ b/frame/vesting/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-vesting" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,17 +12,17 @@ description = "FRAME pallet for manage vesting" serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking", optional = true } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.2", path = "../balances" } -sp-storage = { version = "2.0.0-alpha.2", path = "../../primitives/storage" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +sp-storage = { version = "2.0.0-alpha.4", path = "../../primitives/storage" } hex-literal = "0.2.1" [features] diff --git a/primitives/allocator/Cargo.toml b/primitives/allocator/Cargo.toml index 944cfa6de1..31ce159955 100644 --- a/primitives/allocator/Cargo.toml +++ b/primitives/allocator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-allocator" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,8 +10,8 @@ description = "Collection of allocator implementations." documentation = "https://docs.rs/sp-allocator" [dependencies] -sp-std = { version = "2.0.0-alpha.2", path = "../std", default-features = false } -sp-core = { version = "2.0.0-alpha.2", path = "../core", default-features = false } +sp-std = { version = "2.0.0-alpha.4", path = "../std", default-features = false } +sp-core = { version = "2.0.0-alpha.4", path = "../core", default-features = false } sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../wasm-interface", default-features = false } log = { version = "0.4.8", optional = true } derive_more = { version = "0.99.2", optional = true } diff --git a/primitives/api/Cargo.toml b/primitives/api/Cargo.toml index a33ff0fa0d..94f8545e6d 100644 --- a/primitives/api/Cargo.toml +++ b/primitives/api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-api" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,12 +10,12 @@ description = "Substrate runtime api primitives" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-api-proc-macro = { version = "2.0.0-alpha.2", path = "proc-macro" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../runtime" } -sp-version = { version = "2.0.0-alpha.2", default-features = false, path = "../version" } -sp-state-machine = { version = "0.8.0-alpha.2", optional = true, path = "../../primitives/state-machine" } +sp-api-proc-macro = { version = "2.0.0-alpha.4", path = "proc-macro" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } +sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../version" } +sp-state-machine = { version = "0.8.0-alpha.4", optional = true, path = "../../primitives/state-machine" } hash-db = { version = "0.15.2", optional = true } [dev-dependencies] diff --git a/primitives/api/proc-macro/Cargo.toml b/primitives/api/proc-macro/Cargo.toml index 940e217596..88819c047d 100644 --- a/primitives/api/proc-macro/Cargo.toml +++ b/primitives/api/proc-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-api-proc-macro" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/api/test/Cargo.toml b/primitives/api/test/Cargo.toml index 3b41e28cf3..53405a8a5f 100644 --- a/primitives/api/test/Cargo.toml +++ b/primitives/api/test/Cargo.toml @@ -9,22 +9,22 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-api = { version = "2.0.0-alpha.2", path = "../" } +sp-api = { version = "2.0.0-alpha.4", path = "../" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-version = { version = "2.0.0-alpha.2", path = "../../version" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../runtime" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../blockchain" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensus/common" } -sc-block-builder = { version = "0.8.0-alpha.2", path = "../../../client/block-builder" } +sp-version = { version = "2.0.0-alpha.4", path = "../../version" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../runtime" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../blockchain" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +sc-block-builder = { version = "0.8.0-alpha.4", path = "../../../client/block-builder" } codec = { package = "parity-scale-codec", version = "1.2.0" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } trybuild = "1.0.17" rustversion = "1.0.0" [dev-dependencies] criterion = "0.3.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-core = { version = "2.0.0-alpha.1", path = "../../core" } +sp-core = { version = "2.0.0-alpha.4", path = "../../core" } [[bench]] name = "bench" diff --git a/primitives/application-crypto/Cargo.toml b/primitives/application-crypto/Cargo.toml index ee710b2988..d6ab604e46 100644 --- a/primitives/application-crypto/Cargo.toml +++ b/primitives/application-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-application-crypto" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" description = "Provides facilities for generating application specific crypto wrapper types." @@ -11,11 +11,11 @@ documentation = "https://docs.rs/sp-application-crypto" [dependencies] -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../core" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } [features] default = [ "std" ] diff --git a/primitives/application-crypto/test/Cargo.toml b/primitives/application-crypto/test/Cargo.toml index 0ed5355ce2..f1231a0561 100644 --- a/primitives/application-crypto/test/Cargo.toml +++ b/primitives/application-crypto/test/Cargo.toml @@ -10,8 +10,8 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../core" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../core" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../runtime" } -sp-api = { version = "2.0.0-alpha.2", path = "../../api" } -sp-application-crypto = { version = "2.0.0-alpha.2", path = "../" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../runtime" } +sp-api = { version = "2.0.0-alpha.4", path = "../../api" } +sp-application-crypto = { version = "2.0.0-alpha.4", path = "../" } diff --git a/primitives/arithmetic/Cargo.toml b/primitives/arithmetic/Cargo.toml index 617e8b8e5c..aa45e2a674 100644 --- a/primitives/arithmetic/Cargo.toml +++ b/primitives/arithmetic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-arithmetic" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,9 +14,9 @@ documentation = "https://docs.rs/sp-arithmetic" codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } integer-sqrt = "0.1.2" num-traits = { version = "0.2.8", default-features = false } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-debug-derive = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/debug-derive" } +sp-debug-derive = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/debug-derive" } [dev-dependencies] primitive-types = "0.6.2" diff --git a/primitives/authority-discovery/Cargo.toml b/primitives/authority-discovery/Cargo.toml index b4197c56d7..332d1cf938 100644 --- a/primitives/authority-discovery/Cargo.toml +++ b/primitives/authority-discovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-authority-discovery" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] description = "Authority discovery primitives" edition = "2018" @@ -9,11 +9,11 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.2", default-features = false, path = "../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../application-crypto" } codec = { package = "parity-scale-codec", default-features = false, version = "1.2.0" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/authorship/Cargo.toml b/primitives/authorship/Cargo.toml index c5215631cc..1da224be76 100644 --- a/primitives/authorship/Cargo.toml +++ b/primitives/authorship/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-authorship" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] description = "Authorship primitives" edition = "2018" @@ -9,9 +9,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../inherents" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../runtime" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../inherents" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } [features] diff --git a/primitives/block-builder/Cargo.toml b/primitives/block-builder/Cargo.toml index b5cb592d55..f14b9691e4 100644 --- a/primitives/block-builder/Cargo.toml +++ b/primitives/block-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-block-builder" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,11 +9,11 @@ repository = "https://github.com/paritytech/substrate/" description = "The block builder runtime api." [dependencies] -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../runtime" } -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../api" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../inherents" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../inherents" } [features] default = [ "std" ] diff --git a/primitives/blockchain/Cargo.toml b/primitives/blockchain/Cargo.toml index 5fb8ce3574..1425caa364 100644 --- a/primitives/blockchain/Cargo.toml +++ b/primitives/blockchain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-blockchain" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,7 +16,7 @@ lru = "0.4.0" parking_lot = "0.10.0" derive_more = "0.99.2" codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.2", path = "../consensus/common" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../runtime" } -sp-block-builder = { version = "2.0.0-alpha.2", path = "../block-builder" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../state-machine" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../consensus/common" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } +sp-block-builder = { version = "2.0.0-alpha.4", path = "../block-builder" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../state-machine" } diff --git a/primitives/consensus/aura/Cargo.toml b/primitives/consensus/aura/Cargo.toml index 04d4119399..7ffdc96fa0 100644 --- a/primitives/consensus/aura/Cargo.toml +++ b/primitives/consensus/aura/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-aura" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" @@ -9,13 +9,13 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.2", default-features = false, path = "../../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../std" } -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../../api" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../runtime" } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../inherents" } -sp-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../../timestamp" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../std" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../api" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../runtime" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../inherents" } +sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../timestamp" } [features] default = ["std"] diff --git a/primitives/consensus/babe/Cargo.toml b/primitives/consensus/babe/Cargo.toml index f910b73ed6..f4bab0080f 100644 --- a/primitives/consensus/babe/Cargo.toml +++ b/primitives/consensus/babe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-babe" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "Primitives for BABE consensus" edition = "2018" @@ -9,15 +9,15 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.2", default-features = false, path = "../../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../std" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../std" } schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"], optional = true } -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../../api" } -sp-consensus = { version = "0.8.0-alpha.2", optional = true, path = "../common" } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../inherents" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../runtime" } -sp-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../../timestamp" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../api" } +sp-consensus = { version = "0.8.0-alpha.4", optional = true, path = "../common" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../inherents" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../runtime" } +sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../timestamp" } [features] default = ["std"] diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index e8d3c0c611..a34e16af1e 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,15 +14,15 @@ documentation = "https://docs.rs/sp-consensus/" derive_more = "0.99.2" libp2p = { version = "0.16.2", default-features = false } log = "0.4.8" -sp-core = { path= "../../core" , version = "2.0.0-alpha.2"} -sp-inherents = { version = "2.0.0-alpha.2", path = "../../inherents" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../../primitives/state-machine" } +sp-core = { path= "../../core" , version = "2.0.0-alpha.4"} +sp-inherents = { version = "2.0.0-alpha.4", path = "../../inherents" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } futures = { version = "0.3.1", features = ["thread-pool"] } futures-timer = "3.0.1" futures-diagnose = "1.0" -sp-std = { version = "2.0.0-alpha.2", path = "../../std" } -sp-version = { version = "2.0.0-alpha.2", path = "../../version" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../runtime" } +sp-std = { version = "2.0.0-alpha.4", path = "../../std" } +sp-version = { version = "2.0.0-alpha.4", path = "../../version" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../runtime" } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } parking_lot = "0.10.0" serde = { version = "1.0", features = ["derive"] } diff --git a/primitives/consensus/pow/Cargo.toml b/primitives/consensus/pow/Cargo.toml index 4abead3258..fb8b774854 100644 --- a/primitives/consensus/pow/Cargo.toml +++ b/primitives/consensus/pow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-pow" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" @@ -9,10 +9,10 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../../api" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../runtime" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../core" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../api" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../runtime" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../core" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } [features] diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 2b694fea30..8b9aaaabd5 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-core" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,7 +10,7 @@ description = "Shareable Substrate types." documentation = "https://docs.rs/sp-core" [dependencies] -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } rustc-hex = { version = "2.0.1", default-features = false } log = { version = "0.4.8", default-features = false } @@ -30,9 +30,9 @@ num-traits = { version = "0.2.8", default-features = false } zeroize = { version = "1.0.0", default-features = false } lazy_static = { version = "1.4.0", default-features = false, optional = true } parking_lot = { version = "0.10.0", optional = true } -sp-debug-derive = { version = "2.0.0-alpha.2", path = "../debug-derive" } -sp-externalities = { version = "0.8.0-alpha.2", optional = true, path = "../externalities" } -sp-storage = { version = "2.0.0-alpha.2", default-features = false, path = "../storage" } +sp-debug-derive = { version = "2.0.0-alpha.4", path = "../debug-derive" } +sp-externalities = { version = "0.8.0-alpha.4", optional = true, path = "../externalities" } +sp-storage = { version = "2.0.0-alpha.4", default-features = false, path = "../storage" } parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } futures = { version = "0.3.1", optional = true } @@ -46,10 +46,10 @@ hex = { version = "0.4", default-features = false, optional = true } twox-hash = { version = "1.5.0", default-features = false, optional = true } libsecp256k1 = { version = "0.3.2", default-features = false, features = ["hmac"], optional = true } -sp-runtime-interface = { version = "2.0.0-alpha.2", default-features = false, path = "../runtime-interface" } +sp-runtime-interface = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime-interface" } [dev-dependencies] -sp-serializer = { version = "2.0.0-alpha.2", path = "../serializer" } +sp-serializer = { version = "2.0.0-alpha.4", path = "../serializer" } pretty_assertions = "0.6.1" hex-literal = "0.2.1" rand = "0.7.2" diff --git a/primitives/debug-derive/Cargo.toml b/primitives/debug-derive/Cargo.toml index 1ffa37308e..5b1dc12722 100644 --- a/primitives/debug-derive/Cargo.toml +++ b/primitives/debug-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-debug-derive" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/externalities/Cargo.toml b/primitives/externalities/Cargo.toml index dc47515dcc..18ccf50e30 100644 --- a/primitives/externalities/Cargo.toml +++ b/primitives/externalities/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-externalities" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -10,6 +10,6 @@ description = "Substrate externalities abstraction" documentation = "https://docs.rs/sp-externalities" [dependencies] -sp-storage = { version = "2.0.0-alpha.2", path = "../storage" } -sp-std = { version = "2.0.0-alpha.2", path = "../std" } -environmental = { version = "1.1.1" } \ No newline at end of file +sp-storage = { version = "2.0.0-alpha.4", path = "../storage" } +sp-std = { version = "2.0.0-alpha.4", path = "../std" } +environmental = { version = "1.1.1" } diff --git a/primitives/finality-grandpa/Cargo.toml b/primitives/finality-grandpa/Cargo.toml index d36f0e4b52..d615d5bb50 100644 --- a/primitives/finality-grandpa/Cargo.toml +++ b/primitives/finality-grandpa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-finality-grandpa" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,12 +11,12 @@ documentation = "https://docs.rs/sp-finality-grandpa" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.2", default-features = false, path = "../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/finality-tracker/Cargo.toml b/primitives/finality-tracker/Cargo.toml index f89cb24d4a..5a7c15c896 100644 --- a/primitives/finality-tracker/Cargo.toml +++ b/primitives/finality-tracker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-finality-tracker" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,8 +10,8 @@ description = "FRAME module that tracks the last finalized block, as perceived b [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } [features] default = ["std"] diff --git a/primitives/inherents/Cargo.toml b/primitives/inherents/Cargo.toml index 839edba73d..948d1b609f 100644 --- a/primitives/inherents/Cargo.toml +++ b/primitives/inherents/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-inherents" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,8 +12,8 @@ documentation = "https://docs.rs/sp-inherents" [dependencies] parking_lot = { version = "0.10.0", optional = true } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } derive_more = { version = "0.99.2", optional = true } diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index 4f74063802..8ff99349a8 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-io" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,14 +13,14 @@ documentation = "https://docs.rs/sp-io" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } hash-db = { version = "0.15.2", default-features = false } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } libsecp256k1 = { version = "0.3.4", optional = true } -sp-state-machine = { version = "0.8.0-alpha.2", optional = true, path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-alpha.4", optional = true, path = "../../primitives/state-machine" } sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../../primitives/wasm-interface", default-features = false } -sp-runtime-interface = { version = "2.0.0-alpha.2", default-features = false, path = "../runtime-interface" } -sp-trie = { version = "2.0.0-alpha.2", optional = true, path = "../../primitives/trie" } -sp-externalities = { version = "0.8.0-alpha.2", optional = true, path = "../externalities" } +sp-runtime-interface = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime-interface" } +sp-trie = { version = "2.0.0-alpha.4", optional = true, path = "../../primitives/trie" } +sp-externalities = { version = "0.8.0-alpha.4", optional = true, path = "../externalities" } log = { version = "0.4.8", optional = true } [features] diff --git a/primitives/keyring/Cargo.toml b/primitives/keyring/Cargo.toml index 1ec4ebe547..030258aad2 100644 --- a/primitives/keyring/Cargo.toml +++ b/primitives/keyring/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-keyring" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,7 +11,7 @@ documentation = "https://docs.rs/sp-keyring" [dependencies] -sp-core = { version = "2.0.0-alpha.2", path = "../core" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../runtime" } +sp-core = { version = "2.0.0-alpha.4", path = "../core" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } lazy_static = "1.4.0" strum = { version = "0.16.0", features = ["derive"] } diff --git a/primitives/offchain/Cargo.toml b/primitives/offchain/Cargo.toml index 45324d368b..22205613a3 100644 --- a/primitives/offchain/Cargo.toml +++ b/primitives/offchain/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Substrate offchain workers primitives" name = "sp-offchain" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -9,8 +9,8 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/panic-handler/Cargo.toml b/primitives/panic-handler/Cargo.toml index 592107b84f..78697a991e 100644 --- a/primitives/panic-handler/Cargo.toml +++ b/primitives/panic-handler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-panic-handler" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/phragmen/Cargo.toml b/primitives/phragmen/Cargo.toml index 6a599bdabd..6d813bb3c5 100644 --- a/primitives/phragmen/Cargo.toml +++ b/primitives/phragmen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-phragmen" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,12 +10,12 @@ description = "PHRAGMENT primitives" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } [dev-dependencies] substrate-test-utils = { version = "2.0.0-alpha.2", path = "../../test-utils" } -sp-io ={ version = "2.0.0-alpha.2", path = "../../primitives/io" } +sp-io ={ version = "2.0.0-alpha.4", path = "../../primitives/io" } rand = "0.7.2" [features] diff --git a/primitives/rpc/Cargo.toml b/primitives/rpc/Cargo.toml index 13d91e71d3..5c151a4fe4 100644 --- a/primitives/rpc/Cargo.toml +++ b/primitives/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-rpc" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,7 +10,7 @@ description = "Substrate RPC primitives and utilities." [dependencies] serde = { version = "1.0.101", features = ["derive"] } -sp-core = { version = "2.0.0-alpha.2", path = "../core" } +sp-core = { version = "2.0.0-alpha.4", path = "../core" } [dev-dependencies] serde_json = "1.0.41" diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 70092c0587..403eaf8b83 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-runtime-interface" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,18 +11,18 @@ documentation = "https://docs.rs/sp-runtime-interface/" [dependencies] sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../wasm-interface", default-features = false } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } -sp-runtime-interface-proc-macro = { version = "2.0.0-alpha.2", path = "proc-macro" } -sp-externalities = { version = "0.8.0-alpha.2", optional = true, path = "../externalities" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-runtime-interface-proc-macro = { version = "2.0.0-alpha.4", path = "proc-macro" } +sp-externalities = { version = "0.8.0-alpha.4", optional = true, path = "../externalities" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } static_assertions = "1.0.0" primitive-types = { version = "0.6.2", default-features = false } [dev-dependencies] sp-runtime-interface-test-wasm = { version = "2.0.0-dev", path = "test-wasm" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../primitives/state-machine" } -sp-core = { version = "2.0.0-alpha.2", path = "../core" } -sp-io = { version = "2.0.0-alpha.2", path = "../io" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } +sp-core = { version = "2.0.0-alpha.4", path = "../core" } +sp-io = { version = "2.0.0-alpha.4", path = "../io" } rustversion = "1.0.0" trybuild = "1.0.23" diff --git a/primitives/runtime-interface/proc-macro/Cargo.toml b/primitives/runtime-interface/proc-macro/Cargo.toml index 3743b2e09a..3d6585bf11 100644 --- a/primitives/runtime-interface/proc-macro/Cargo.toml +++ b/primitives/runtime-interface/proc-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-runtime-interface-proc-macro" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/runtime-interface/test-wasm/Cargo.toml b/primitives/runtime-interface/test-wasm/Cargo.toml index b322e529d6..65c9cc9765 100644 --- a/primitives/runtime-interface/test-wasm/Cargo.toml +++ b/primitives/runtime-interface/test-wasm/Cargo.toml @@ -10,10 +10,10 @@ repository = "https://github.com/paritytech/substrate/" publish = false [dependencies] -sp-runtime-interface = { version = "2.0.0-alpha.2", default-features = false, path = "../" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../io" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../core" } +sp-runtime-interface = { version = "2.0.0-alpha.4", default-features = false, path = "../" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../io" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../core" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } diff --git a/primitives/runtime-interface/test/Cargo.toml b/primitives/runtime-interface/test/Cargo.toml index 53c05b68b3..b8da8042ed 100644 --- a/primitives/runtime-interface/test/Cargo.toml +++ b/primitives/runtime-interface/test/Cargo.toml @@ -9,9 +9,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-runtime-interface = { version = "2.0.0-alpha.2", path = "../" } -sc-executor = { version = "0.8.0-alpha.2", path = "../../../client/executor" } +sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../" } +sc-executor = { version = "0.8.0-alpha.4", path = "../../../client/executor" } sp-runtime-interface-test-wasm = { version = "2.0.0-dev", path = "../test-wasm" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../../primitives/state-machine" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../runtime" } -sp-io = { version = "2.0.0-alpha.2", path = "../../io" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../runtime" } +sp-io = { version = "2.0.0-alpha.4", path = "../../io" } diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index fd40b9406a..af71aed703 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-runtime" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,16 +13,16 @@ documentation = "https://docs.rs/sp-runtime" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../core" } -sp-application-crypto = { version = "2.0.0-alpha.2", default-features = false, path = "../application-crypto" } -sp-arithmetic = { version = "2.0.0-alpha.2", default-features = false, path = "../arithmetic" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../io" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } +sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../application-crypto" } +sp-arithmetic = { version = "2.0.0-alpha.4", default-features = false, path = "../arithmetic" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../io" } log = { version = "0.4.8", optional = true } paste = "0.1.6" rand = { version = "0.7.2", optional = true } impl-trait-for-tuples = "0.1.3" -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../inherents" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../inherents" } parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } hash256-std-hasher = { version = "0.15.2", default-features = false } diff --git a/primitives/sandbox/Cargo.toml b/primitives/sandbox/Cargo.toml index 060801a29e..9057fea8e3 100755 --- a/primitives/sandbox/Cargo.toml +++ b/primitives/sandbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-sandbox" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,9 +10,9 @@ description = "This crate provides means to instantiate and execute wasm modules [dependencies] wasmi = { version = "0.6.2", optional = true } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../io" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../io" } sp-wasm-interface = { version = "2.0.0-alpha.2", default-features = false, path = "../wasm-interface" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } diff --git a/primitives/serializer/Cargo.toml b/primitives/serializer/Cargo.toml index 39f78c078b..58577964dd 100644 --- a/primitives/serializer/Cargo.toml +++ b/primitives/serializer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-serializer" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/session/Cargo.toml b/primitives/session/Cargo.toml index d01f7ee440..3e41d1084f 100644 --- a/primitives/session/Cargo.toml +++ b/primitives/session/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-session" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,10 +9,10 @@ repository = "https://github.com/paritytech/substrate/" description = "Primitives for sessions" [dependencies] -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../api" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../core" } -sp-runtime = { version = "2.0.0-alpha.2", optional = true, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } +sp-runtime = { version = "2.0.0-alpha.4", optional = true, path = "../runtime" } [features] default = [ "std" ] diff --git a/primitives/staking/Cargo.toml b/primitives/staking/Cargo.toml index 2f85b8251b..175f478f00 100644 --- a/primitives/staking/Cargo.toml +++ b/primitives/staking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-staking" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,8 +10,8 @@ description = "A crate which contains primitives that are useful for implementat [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../runtime" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } [features] default = ["std"] diff --git a/primitives/state-machine/Cargo.toml b/primitives/state-machine/Cargo.toml index 16f921c3ac..c9969e318a 100644 --- a/primitives/state-machine/Cargo.toml +++ b/primitives/state-machine/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-state-machine" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "Substrate State Machine" edition = "2018" @@ -15,17 +15,17 @@ parking_lot = "0.10.0" hash-db = "0.15.2" trie-db = "0.20.0" trie-root = "0.16.0" -sp-trie = { version = "2.0.0-alpha.2", path = "../trie" } -sp-core = { version = "2.0.0-alpha.2", path = "../core" } -sp-panic-handler = { version = "2.0.0-alpha.2", path = "../panic-handler" } +sp-trie = { version = "2.0.0-alpha.4", path = "../trie" } +sp-core = { version = "2.0.0-alpha.4", path = "../core" } +sp-panic-handler = { version = "2.0.0-alpha.4", path = "../panic-handler" } codec = { package = "parity-scale-codec", version = "1.2.0" } num-traits = "0.2.8" rand = "0.7.2" -sp-externalities = { version = "0.8.0-alpha.2", path = "../externalities" } +sp-externalities = { version = "0.8.0-alpha.4", path = "../externalities" } [dev-dependencies] hex-literal = "0.2.1" -sp-runtime = { version = "2.0.0-alpha.2", path = "../runtime" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } [features] default = [] diff --git a/primitives/std/Cargo.toml b/primitives/std/Cargo.toml index 38a0c713c0..86b6e037b8 100644 --- a/primitives/std/Cargo.toml +++ b/primitives/std/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-std" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/storage/Cargo.toml b/primitives/storage/Cargo.toml index 7e434cdd89..9e90b6ecc6 100644 --- a/primitives/storage/Cargo.toml +++ b/primitives/storage/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-storage" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" description = "Storage related primitives" @@ -10,10 +10,10 @@ repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sp-storage/" [dependencies] -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } impl-serde = { version = "0.2.3", optional = true } -sp-debug-derive = { version = "2.0.0-alpha.2", path = "../debug-derive" } +sp-debug-derive = { version = "2.0.0-alpha.4", path = "../debug-derive" } [features] default = [ "std" ] diff --git a/primitives/test-primitives/Cargo.toml b/primitives/test-primitives/Cargo.toml index 8788876769..41b2b52e2f 100644 --- a/primitives/test-primitives/Cargo.toml +++ b/primitives/test-primitives/Cargo.toml @@ -9,11 +9,11 @@ repository = "https://github.com/paritytech/substrate/" publish = false [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.2", default-features = false, path = "../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../core" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../runtime" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } [features] diff --git a/primitives/timestamp/Cargo.toml b/primitives/timestamp/Cargo.toml index 1fc40a113f..52cb523ca5 100644 --- a/primitives/timestamp/Cargo.toml +++ b/primitives/timestamp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-timestamp" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,11 +9,11 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate core types and inherents for timestamps." [dependencies] -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../api" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../inherents" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../inherents" } impl-trait-for-tuples = "0.1.3" wasm-timer = "0.2" diff --git a/primitives/transaction-pool/Cargo.toml b/primitives/transaction-pool/Cargo.toml index 69ec59cf5e..e17607921b 100644 --- a/primitives/transaction-pool/Cargo.toml +++ b/primitives/transaction-pool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-transaction-pool" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,8 +16,8 @@ derive_more = { version = "0.99.2", optional = true } futures = { version = "0.3.1", optional = true } log = { version = "0.4.8", optional = true } serde = { version = "1.0.101", features = ["derive"], optional = true} -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } [features] default = [ "std" ] diff --git a/primitives/trie/Cargo.toml b/primitives/trie/Cargo.toml index ff3c04b541..15d0febe9a 100644 --- a/primitives/trie/Cargo.toml +++ b/primitives/trie/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-trie" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] description = "Patricia trie stuff using a parity-scale-codec node format" repository = "https://github.com/paritytech/substrate/" @@ -15,19 +15,19 @@ harness = false [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } hash-db = { version = "0.15.2", default-features = false } trie-db = { version = "0.20.0", default-features = false } trie-root = { version = "0.16.0", default-features = false } memory-db = { version = "0.19.0", default-features = false } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../core" } +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } [dev-dependencies] trie-bench = "0.20.0" trie-standardmap = "0.15.2" criterion = "0.2.11" hex-literal = "0.2.1" -sp-runtime = { version = "2.0.0-alpha.2", path = "../runtime" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } [features] default = ["std"] diff --git a/primitives/version/Cargo.toml b/primitives/version/Cargo.toml index edaf940465..e917909266 100644 --- a/primitives/version/Cargo.toml +++ b/primitives/version/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-version" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,8 +14,8 @@ documentation = "https://docs.rs/sp-version" impl-serde = { version = "0.2.3", optional = true } serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/wasm-interface/Cargo.toml b/primitives/wasm-interface/Cargo.toml index bbe53df258..66157333e6 100644 --- a/primitives/wasm-interface/Cargo.toml +++ b/primitives/wasm-interface/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.rs/sp-wasm-interface" [dependencies] wasmi = { version = "0.6.2", optional = true } impl-trait-for-tuples = "0.1.2" -sp-std = { version = "2.0.0-alpha.2", path = "../std", default-features = false } +sp-std = { version = "2.0.0-alpha.4", path = "../std", default-features = false } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } [features] diff --git a/test-utils/client/Cargo.toml b/test-utils/client/Cargo.toml index 77a614e5fe..fcdc81a2db 100644 --- a/test-utils/client/Cargo.toml +++ b/test-utils/client/Cargo.toml @@ -9,16 +9,16 @@ repository = "https://github.com/paritytech/substrate/" publish = false [dependencies] -sc-client-api = { version = "2.0.0-alpha.2", path = "../../client/api" } -sc-client = { version = "0.8.0-alpha.2", path = "../../client/" } -sc-client-db = { version = "0.8.0-alpha.2", features = ["test-helpers"], path = "../../client/db" } -sp-consensus = { version = "0.8.0-alpha.2", path = "../../primitives/consensus/common" } -sc-executor = { version = "0.8.0-alpha.2", path = "../../client/executor" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../../client/api" } +sc-client = { version = "0.8.0-alpha.4", path = "../../client/" } +sc-client-db = { version = "0.8.0-alpha.4", features = ["test-helpers"], path = "../../client/db" } +sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } +sc-executor = { version = "0.8.0-alpha.4", path = "../../client/executor" } futures = "0.3.1" hash-db = "0.15.2" -sp-keyring = { version = "2.0.0-alpha.2", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } codec = { package = "parity-scale-codec", version = "1.2.0" } -sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../primitives/blockchain" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../primitives/state-machine" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index 629656f10f..a1601c085e 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -10,43 +10,43 @@ repository = "https://github.com/paritytech/substrate/" publish = false [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/application-crypto" } -sp-consensus-aura = { version = "0.8.0-alpha.2", default-features = false, path = "../../primitives/consensus/aura" } -sp-consensus-babe = { version = "0.8.0-alpha.2", default-features = false, path = "../../primitives/consensus/babe" } -sp-block-builder = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/block-builder" } +sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/application-crypto" } +sp-consensus-aura = { version = "0.8.0-alpha.4", default-features = false, path = "../../primitives/consensus/aura" } +sp-consensus-babe = { version = "0.8.0-alpha.4", default-features = false, path = "../../primitives/consensus/babe" } +sp-block-builder = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/block-builder" } cfg-if = "0.1.10" codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -frame-executive = { version = "2.0.0-alpha.2", default-features = false, path = "../../frame/executive" } -sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.2", optional = true, path = "../../primitives/keyring" } +frame-executive = { version = "2.0.0-alpha.4", default-features = false, path = "../../frame/executive" } +sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } +sp-keyring = { version = "2.0.0-alpha.4", optional = true, path = "../../primitives/keyring" } log = { version = "0.4.8", optional = true } memory-db = { version = "0.19.0", default-features = false } -sp-offchain = { path = "../../primitives/offchain", default-features = false, version = "2.0.0-alpha.2"} -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" } -sp-runtime-interface = { path = "../../primitives/runtime-interface", default-features = false, version = "2.0.0-alpha.2"} -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" } -frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../../frame/support" } -sp-version = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/version" } +sp-offchain = { path = "../../primitives/offchain", default-features = false, version = "2.0.0-alpha.4"} +sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-runtime-interface = { path = "../../primitives/runtime-interface", default-features = false, version = "2.0.0-alpha.4"} +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../../frame/support" } +sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/version" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-session = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/session" } -sp-api = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } -pallet-babe = { version = "2.0.0-alpha.2", default-features = false, path = "../../frame/babe" } -frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../../frame/system" } -frame-system-rpc-runtime-api = { version = "2.0.0-alpha.2", default-features = false, path = "../../frame/system/rpc/runtime-api" } -pallet-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../../frame/timestamp" } -sc-client = { version = "0.8.0-alpha.2", optional = true, path = "../../client" } -sp-trie = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/trie" } -sp-transaction-pool = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/transaction-pool" } +sp-session = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/session" } +sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +pallet-babe = { version = "2.0.0-alpha.4", default-features = false, path = "../../frame/babe" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../../frame/system" } +frame-system-rpc-runtime-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../frame/system/rpc/runtime-api" } +pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../frame/timestamp" } +sc-client = { version = "0.8.0-alpha.4", optional = true, path = "../../client" } +sp-trie = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/trie" } +sp-transaction-pool = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/transaction-pool" } trie-db = { version = "0.20.0", default-features = false } parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } [dev-dependencies] -sc-block-builder = { version = "0.8.0-alpha.2", path = "../../client/block-builder" } -sc-executor = { version = "0.8.0-alpha.2", path = "../../client/executor" } +sc-block-builder = { version = "0.8.0-alpha.4", path = "../../client/block-builder" } +sc-executor = { version = "0.8.0-alpha.4", path = "../../client/executor" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "./client" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../utils/wasm-builder-runner" } diff --git a/test-utils/runtime/client/Cargo.toml b/test-utils/runtime/client/Cargo.toml index 5f16e77860..e8e233855c 100644 --- a/test-utils/runtime/client/Cargo.toml +++ b/test-utils/runtime/client/Cargo.toml @@ -9,14 +9,14 @@ repository = "https://github.com/paritytech/substrate/" publish = false [dependencies] -sc-block-builder = { version = "0.8.0-alpha.2", path = "../../../client/block-builder" } +sc-block-builder = { version = "0.8.0-alpha.4", path = "../../../client/block-builder" } substrate-test-client = { version = "2.0.0-dev", path = "../../client" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../runtime" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.2", path = "../../../primitives/api" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } codec = { package = "parity-scale-codec", version = "1.2.0" } -sc-client-api = { version = "2.0.0-alpha.2", path = "../../../client/api" } -sc-client = { version = "0.8.0-alpha.2", path = "../../../client/" } +sc-client-api = { version = "2.0.0-alpha.4", path = "../../../client/api" } +sc-client = { version = "0.8.0-alpha.4", path = "../../../client/" } futures = "0.3.1" diff --git a/test-utils/runtime/transaction-pool/Cargo.toml b/test-utils/runtime/transaction-pool/Cargo.toml index 3e22da468f..a33f91785f 100644 --- a/test-utils/runtime/transaction-pool/Cargo.toml +++ b/test-utils/runtime/transaction-pool/Cargo.toml @@ -12,9 +12,9 @@ publish = false substrate-test-runtime-client = { version = "2.0.0-dev", path = "../client" } parking_lot = "0.10.0" codec = { package = "parity-scale-codec", version = "1.2.0" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../../primitives/transaction-pool" } -sc-transaction-graph = { version = "2.0.0-alpha.2", path = "../../../client/transaction-pool/graph" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../primitives/transaction-pool" } +sc-transaction-graph = { version = "2.0.0-alpha.4", path = "../../../client/transaction-pool/graph" } futures = { version = "0.3.1", features = ["compat"] } derive_more = "0.99.2" diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 205f42d61f..45bab46239 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-browser-utils" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] description = "Utilities for creating a browser light-client." edition = "2018" @@ -19,10 +19,10 @@ js-sys = "0.3.34" wasm-bindgen = "0.2.57" wasm-bindgen-futures = "0.4.7" kvdb-web = "0.4" -sc-informant = { version = "0.8.0-alpha.2", path = "../../client/informant" } -sc-service = { version = "0.8.0-alpha.2", path = "../../client/service", default-features = false } -sc-network = { path = "../../client/network" , version = "0.8.0-alpha.2"} -sc-chain-spec = { path = "../../client/chain-spec" , version = "2.0.0-alpha.2"} +sc-informant = { version = "0.8.0-alpha.4", path = "../../client/informant" } +sc-service = { version = "0.8.0-alpha.4", path = "../../client/service", default-features = false } +sc-network = { path = "../../client/network" , version = "0.8.0-alpha.4"} +sc-chain-spec = { path = "../../client/chain-spec" , version = "2.0.0-alpha.4"} # Imported just for the `no_cc` feature clear_on_drop = { version = "0.2.3", features = ["no_cc"] } diff --git a/utils/build-script-utils/Cargo.toml b/utils/build-script-utils/Cargo.toml index 5903d107fb..b0008f77c4 100644 --- a/utils/build-script-utils/Cargo.toml +++ b/utils/build-script-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-build-script-utils" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/utils/fork-tree/Cargo.toml b/utils/fork-tree/Cargo.toml index 8ade20cd7b..604a87bf86 100644 --- a/utils/fork-tree/Cargo.toml +++ b/utils/fork-tree/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fork-tree" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/utils/frame/benchmarking-cli/Cargo.toml b/utils/frame/benchmarking-cli/Cargo.toml index 67b217c287..3535a542d9 100644 --- a/utils/frame/benchmarking-cli/Cargo.toml +++ b/utils/frame/benchmarking-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-benchmarking-cli" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,14 +9,14 @@ repository = "https://github.com/paritytech/substrate/" description = "CLI for benchmarking FRAME" [dependencies] -frame-benchmarking = { version = "2.0.0-alpha.2", path = "../../../frame/benchmarking" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } -sc-service = { version = "0.8.0-alpha.2", default-features = false, path = "../../../client/service" } -sc-cli = { version = "0.8.0-alpha.2", path = "../../../client/cli" } -sc-client = { version = "0.8.0-alpha.2", path = "../../../client" } -sc-client-db = { version = "0.8.0-alpha.2", path = "../../../client/db" } -sc-executor = { version = "0.8.0-alpha.2", path = "../../../client/executor" } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-alpha.2", path = "../../../primitives/state-machine" } +frame-benchmarking = { version = "2.0.0-alpha.4", path = "../../../frame/benchmarking" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../../../client/service" } +sc-cli = { version = "0.8.0-alpha.4", path = "../../../client/cli" } +sc-client = { version = "0.8.0-alpha.4", path = "../../../client" } +sc-client-db = { version = "0.8.0-alpha.4", path = "../../../client/db" } +sc-executor = { version = "0.8.0-alpha.4", path = "../../../client/executor" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } structopt = "0.3.8" codec = { version = "1.2.0", package = "parity-scale-codec" } diff --git a/utils/frame/rpc/support/Cargo.toml b/utils/frame/rpc/support/Cargo.toml index 162d25cf9b..6ebc79a391 100644 --- a/utils/frame/rpc/support/Cargo.toml +++ b/utils/frame/rpc/support/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-frame-rpc-support" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies ", "Andrew Dirksen "] edition = "2018" license = "GPL-3.0" @@ -14,10 +14,10 @@ jsonrpc-client-transports = "14" jsonrpc-core = "14" codec = { package = "parity-scale-codec", version = "1" } serde = "1" -frame-support = { version = "2.0.0-alpha.2", path = "../../../../frame/support" } -sp-storage = { version = "2.0.0-alpha.2", path = "../../../../primitives/storage" } -sc-rpc-api = { version = "0.8.0-alpha.2", path = "../../../../client/rpc-api" } +frame-support = { version = "2.0.0-alpha.4", path = "../../../../frame/support" } +sp-storage = { version = "2.0.0-alpha.4", path = "../../../../primitives/storage" } +sc-rpc-api = { version = "0.8.0-alpha.4", path = "../../../../client/rpc-api" } [dev-dependencies] -frame-system = { version = "2.0.0-alpha.2", path = "../../../../frame/system" } +frame-system = { version = "2.0.0-alpha.4", path = "../../../../frame/system" } tokio = "0.2" diff --git a/utils/frame/rpc/system/Cargo.toml b/utils/frame/rpc/system/Cargo.toml index 8b1c62ccd7..aaec43b451 100644 --- a/utils/frame/rpc/system/Cargo.toml +++ b/utils/frame/rpc/system/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-frame-rpc-system" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME's system exposed over Substrate RPC" [dependencies] -sc-client = { version = "0.8.0-alpha.2", path = "../../../../client/" } +sc-client = { version = "0.8.0-alpha.4", path = "../../../../client/" } codec = { package = "parity-scale-codec", version = "1.2.0" } futures = "0.3.1" jsonrpc-core = "14.0.3" @@ -17,14 +17,14 @@ jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" log = "0.4.8" serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.2", path = "../../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.2", path = "../../../../primitives/api" } -frame-system-rpc-runtime-api = { version = "2.0.0-alpha.2", path = "../../../../frame/system/rpc/runtime-api" } -sp-core = { version = "2.0.0-alpha.2", path = "../../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.2", path = "../../../../primitives/blockchain" } -sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../../../primitives/transaction-pool" } +sp-runtime = { version = "2.0.0-alpha.4", path = "../../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.4", path = "../../../../primitives/api" } +frame-system-rpc-runtime-api = { version = "2.0.0-alpha.4", path = "../../../../frame/system/rpc/runtime-api" } +sp-core = { version = "2.0.0-alpha.4", path = "../../../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../../primitives/blockchain" } +sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../../primitives/transaction-pool" } [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../../test-utils/runtime/client" } env_logger = "0.7.0" -sc-transaction-pool = { version = "2.0.0-alpha.2", path = "../../../../client/transaction-pool" } +sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../../client/transaction-pool" } diff --git a/utils/prometheus/Cargo.toml b/utils/prometheus/Cargo.toml index bc7750a720..8448283e74 100644 --- a/utils/prometheus/Cargo.toml +++ b/utils/prometheus/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Endpoint to expose Prometheus metrics" name = "substrate-prometheus-endpoint" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" -- GitLab From 9fa8589d9b8cfe8716e9e4c48f9e3f238c1e502f Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Wed, 18 Mar 2020 15:47:34 +0100 Subject: [PATCH 012/300] alpha.4 release fixes (#5303) * Adding missing metadata for benchmark-pallet * Missed to bump a few * release on roling tag * Wasm executors were missed --- .gitlab-ci.yml | 2 +- Cargo.lock | 12 ++++++------ client/executor/Cargo.toml | 6 +++--- client/executor/common/Cargo.toml | 2 +- client/executor/wasmi/Cargo.toml | 6 +++--- client/executor/wasmtime/Cargo.toml | 4 ++-- frame/benchmark/Cargo.toml | 3 +++ frame/elections-phragmen/Cargo.toml | 2 +- frame/example-offchain-worker/Cargo.toml | 2 +- frame/example/Cargo.toml | 2 +- frame/staking/Cargo.toml | 2 +- primitives/allocator/Cargo.toml | 2 +- primitives/io/Cargo.toml | 2 +- primitives/phragmen/Cargo.toml | 2 +- primitives/runtime-interface/Cargo.toml | 2 +- primitives/sandbox/Cargo.toml | 2 +- primitives/wasm-interface/Cargo.toml | 2 +- test-utils/Cargo.toml | 2 +- 18 files changed, 30 insertions(+), 27 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 98cf4dd1d8..8791690d89 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -578,7 +578,7 @@ publish-to-crates-io: <<: *docker-env only: - tags - - /^v[0-9]+\.[0-9]+\.[0-9]+.*$/ + - ci-release script: - cargo install cargo-unleash ${CARGO_UNLEASH_INSTALL_PARAMS} - cargo unleash em-dragons --no-check ${CARGO_UNLEASH_PKG_DEF} diff --git a/Cargo.lock b/Cargo.lock index aa0212c0b2..70610b770b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4158,7 +4158,7 @@ dependencies = [ [[package]] name = "pallet-example" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-benchmarking", "frame-support", @@ -4174,7 +4174,7 @@ dependencies = [ [[package]] name = "pallet-example-offchain-worker" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", @@ -6101,7 +6101,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "log 0.4.8", "parity-scale-codec", @@ -6116,7 +6116,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" dependencies = [ "assert_matches", "log 0.4.8", @@ -7544,7 +7544,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -7866,7 +7866,7 @@ dependencies = [ [[package]] name = "substrate-test-utils" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" [[package]] name = "substrate-wasm-builder" diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index aa14c1e43e..be4730b2a2 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -21,12 +21,12 @@ sp-panic-handler = { version = "2.0.0-alpha.4", path = "../../primitives/panic-h wasmi = "0.6.2" parity-wasm = "0.41.0" lazy_static = "1.4.0" -sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../../primitives/wasm-interface" } +sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../../primitives/wasm-interface" } sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../primitives/runtime-interface" } sp-externalities = { version = "0.8.0-alpha.4", path = "../../primitives/externalities" } sc-executor-common = { version = "0.8.0-alpha.4", path = "common" } -sc-executor-wasmi = { version = "0.8.0-alpha.2", path = "wasmi" } -sc-executor-wasmtime = { version = "0.8.0-alpha.2", path = "wasmtime", optional = true } +sc-executor-wasmi = { version = "0.8.0-alpha.4", path = "wasmi" } +sc-executor-wasmtime = { version = "0.8.0-alpha.4", path = "wasmtime", optional = true } parking_lot = "0.10.0" log = "0.4.8" libsecp256k1 = "0.3.4" diff --git a/client/executor/common/Cargo.toml b/client/executor/common/Cargo.toml index 5b54f091f6..c1a92a8ba4 100644 --- a/client/executor/common/Cargo.toml +++ b/client/executor/common/Cargo.toml @@ -16,7 +16,7 @@ codec = { package = "parity-scale-codec", version = "1.2.0" } wasmi = "0.6.2" sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } sp-allocator = { version = "2.0.0-alpha.4", path = "../../../primitives/allocator" } -sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../../../primitives/wasm-interface" } +sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/wasm-interface" } sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime-interface" } sp-serializer = { version = "2.0.0-alpha.4", path = "../../../primitives/serializer" } diff --git a/client/executor/wasmi/Cargo.toml b/client/executor/wasmi/Cargo.toml index ccaf8b449b..8655561d43 100644 --- a/client/executor/wasmi/Cargo.toml +++ b/client/executor/wasmi/Cargo.toml @@ -1,13 +1,13 @@ [package] name = "sc-executor-wasmi" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "This crate provides an implementation of `WasmRuntime` that is baked by wasmi." -documentation = "https://docs.rs/sc-execturo-wasmi" +documentation = "https://docs.rs/sc-executor-wasmi" [dependencies] log = "0.4.8" @@ -15,7 +15,7 @@ wasmi = "0.6.2" parity-wasm = "0.41.0" codec = { package = "parity-scale-codec", version = "1.2.0" } sc-executor-common = { version = "0.8.0-alpha.4", path = "../common" } -sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../../../primitives/wasm-interface" } +sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/wasm-interface" } sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime-interface" } sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } sp-allocator = { version = "2.0.0-alpha.4", path = "../../../primitives/allocator" } diff --git a/client/executor/wasmtime/Cargo.toml b/client/executor/wasmtime/Cargo.toml index a7342145b8..fb9d054f09 100644 --- a/client/executor/wasmtime/Cargo.toml +++ b/client/executor/wasmtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor-wasmtime" -version = "0.8.0-alpha.3" +version = "0.8.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,7 +14,7 @@ scoped-tls = "1.0" parity-wasm = "0.41.0" codec = { package = "parity-scale-codec", version = "1.2.0" } sc-executor-common = { version = "0.8.0-alpha.4", path = "../common" } -sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../../../primitives/wasm-interface" } +sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/wasm-interface" } sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime-interface" } sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } sp-allocator = { version = "2.0.0-alpha.4", path = "../../../primitives/allocator" } diff --git a/frame/benchmark/Cargo.toml b/frame/benchmark/Cargo.toml index cbdc017049..2501e6090a 100644 --- a/frame/benchmark/Cargo.toml +++ b/frame/benchmark/Cargo.toml @@ -4,6 +4,9 @@ version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "Patterns to benchmark in a FRAME runtime." [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index a7514b10a3..bef7b7dfd8 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -21,7 +21,7 @@ sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } hex-literal = "0.2.1" pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -substrate-test-utils = { version = "2.0.0-alpha.2", path = "../../test-utils" } +substrate-test-utils = { version = "2.0.0-alpha.4", path = "../../test-utils" } serde = { version = "1.0.101" } [features] diff --git a/frame/example-offchain-worker/Cargo.toml b/frame/example-offchain-worker/Cargo.toml index 2eafe9185d..3c705138f4 100644 --- a/frame/example-offchain-worker/Cargo.toml +++ b/frame/example-offchain-worker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-example-offchain-worker" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "Unlicense" diff --git a/frame/example/Cargo.toml b/frame/example/Cargo.toml index 9edd365405..ee1b870e03 100644 --- a/frame/example/Cargo.toml +++ b/frame/example/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-example" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "Unlicense" diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index e1991d4a2a..0bb6c3fd4c 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -30,7 +30,7 @@ sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } pallet-timestamp = { version = "2.0.0-alpha.4", path = "../timestamp" } pallet-staking-reward-curve = { version = "2.0.0-alpha.4", path = "../staking/reward-curve" } -substrate-test-utils = { version = "2.0.0-alpha.2", path = "../../test-utils" } +substrate-test-utils = { version = "2.0.0-alpha.4", path = "../../test-utils" } frame-benchmarking = { version = "2.0.0-alpha.4", path = "../benchmarking" } rand_chacha = { version = "0.2" } diff --git a/primitives/allocator/Cargo.toml b/primitives/allocator/Cargo.toml index 31ce159955..358d74b79e 100644 --- a/primitives/allocator/Cargo.toml +++ b/primitives/allocator/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.rs/sp-allocator" [dependencies] sp-std = { version = "2.0.0-alpha.4", path = "../std", default-features = false } sp-core = { version = "2.0.0-alpha.4", path = "../core", default-features = false } -sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../wasm-interface", default-features = false } +sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../wasm-interface", default-features = false } log = { version = "0.4.8", optional = true } derive_more = { version = "0.99.2", optional = true } diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index 8ff99349a8..2b445be657 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -17,7 +17,7 @@ sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } libsecp256k1 = { version = "0.3.4", optional = true } sp-state-machine = { version = "0.8.0-alpha.4", optional = true, path = "../../primitives/state-machine" } -sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../../primitives/wasm-interface", default-features = false } +sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../../primitives/wasm-interface", default-features = false } sp-runtime-interface = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime-interface" } sp-trie = { version = "2.0.0-alpha.4", optional = true, path = "../../primitives/trie" } sp-externalities = { version = "0.8.0-alpha.4", optional = true, path = "../externalities" } diff --git a/primitives/phragmen/Cargo.toml b/primitives/phragmen/Cargo.toml index 6d813bb3c5..53429480bb 100644 --- a/primitives/phragmen/Cargo.toml +++ b/primitives/phragmen/Cargo.toml @@ -14,7 +14,7 @@ sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } [dev-dependencies] -substrate-test-utils = { version = "2.0.0-alpha.2", path = "../../test-utils" } +substrate-test-utils = { version = "2.0.0-alpha.4", path = "../../test-utils" } sp-io ={ version = "2.0.0-alpha.4", path = "../../primitives/io" } rand = "0.7.2" diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 403eaf8b83..06f25c45dd 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -10,7 +10,7 @@ description = "Substrate runtime interface" documentation = "https://docs.rs/sp-runtime-interface/" [dependencies] -sp-wasm-interface = { version = "2.0.0-alpha.2", path = "../wasm-interface", default-features = false } +sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../wasm-interface", default-features = false } sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } sp-runtime-interface-proc-macro = { version = "2.0.0-alpha.4", path = "proc-macro" } sp-externalities = { version = "0.8.0-alpha.4", optional = true, path = "../externalities" } diff --git a/primitives/sandbox/Cargo.toml b/primitives/sandbox/Cargo.toml index 9057fea8e3..fb01e32acd 100755 --- a/primitives/sandbox/Cargo.toml +++ b/primitives/sandbox/Cargo.toml @@ -13,7 +13,7 @@ wasmi = { version = "0.6.2", optional = true } sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../io" } -sp-wasm-interface = { version = "2.0.0-alpha.2", default-features = false, path = "../wasm-interface" } +sp-wasm-interface = { version = "2.0.0-alpha.4", default-features = false, path = "../wasm-interface" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } [dev-dependencies] diff --git a/primitives/wasm-interface/Cargo.toml b/primitives/wasm-interface/Cargo.toml index 66157333e6..e8bbbc3ebe 100644 --- a/primitives/wasm-interface/Cargo.toml +++ b/primitives/wasm-interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-wasm-interface" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml index d3477b94a6..9ebfa16dac 100644 --- a/test-utils/Cargo.toml +++ b/test-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-test-utils" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" -- GitLab From 48701053e02b4b40c3e58429b0ed60a5f82f1d93 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 18 Mar 2020 20:15:57 +0100 Subject: [PATCH 013/300] client/network-gossip/src/bridge: Finish when network event stream closes (#5282) * client/network-gossip/src/bridge: Finish when network even stream closes Previously within `::poll` one would poll the `network_event_stream` ignoring all messages other than `Poll::Ready(Some())`. Ignoring `Poll::Ready(None)` leads to a panic on the next poll of the stream, gien that it is not fused. By design `network_event_stream` does not close unless an unbounded send into it fails, or the `NetworkWorker` gets shut down. > The stream never ends (unless the `NetworkWorker` gets shut down). > (client/network/src/service.rs) An `unbounded_send` to fail on an unbounded channel is unlikely. The `NetworkWorker` shutting down is not unlikely. In such case the `GossipEngine` should shut down as well. With this patch a `` finishes on `Poll::Ready(None)` returned from `network_event_stream`. * client/finality-grandpa/communication: Error on gossip engine finished Have `::poll` return `Poll::Ready(Err)` instead of `Poll::Ready(Ok)` to be consistent with the handling of the neighbor packet worker stream and the gossip validator report stream. Both `Err` as well as `Ok` shut down the `NetworkBridge` as well as the `VoterWorker`. * client/network-gossip/src/bridge: Add regression test * client/network-gossip: Move substrate test client to dev dependencies * client/network-gossip: Remove TODO Addressed in a follow up pull request. * client/network-gossip/bridge: Put match on newline after loop * client/finality-grandpa/src/observer: Fix regression test Make sure the event stream sender side is not dropped till the end. --- Cargo.lock | 1 + .../finality-grandpa/src/communication/mod.rs | 5 +- client/finality-grandpa/src/observer.rs | 13 +- client/network-gossip/Cargo.toml | 3 + client/network-gossip/src/bridge.rs | 131 ++++++++++++++---- 5 files changed, 117 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 70610b770b..47ac61f036 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6274,6 +6274,7 @@ dependencies = [ "lru", "sc-network", "sp-runtime", + "substrate-test-runtime-client", "wasm-timer", ] diff --git a/client/finality-grandpa/src/communication/mod.rs b/client/finality-grandpa/src/communication/mod.rs index 3c6a8d7648..52bfdbc818 100644 --- a/client/finality-grandpa/src/communication/mod.rs +++ b/client/finality-grandpa/src/communication/mod.rs @@ -451,8 +451,9 @@ impl> Future for NetworkBridge { } match self.gossip_engine.lock().poll_unpin(cx) { - // The gossip engine future finished. We should do the same. - Poll::Ready(()) => return Poll::Ready(Ok(())), + Poll::Ready(()) => return Poll::Ready( + Err(Error::Network("Gossip engine future finished.".into())) + ), Poll::Pending => {}, } diff --git a/client/finality-grandpa/src/observer.rs b/client/finality-grandpa/src/observer.rs index 971c213290..07eaf1db9f 100644 --- a/client/finality-grandpa/src/observer.rs +++ b/client/finality-grandpa/src/observer.rs @@ -425,21 +425,16 @@ mod tests { tester.trigger_gossip_validator_reputation_change(&peer_id); executor::block_on(async move { + // Poll the observer once and have it forward the reputation change from the gossip + // validator to the test network. + assert!(observer.now_or_never().is_none()); + // Ignore initial event stream request by gossip engine. match tester.events.next().now_or_never() { Some(Some(Event::EventStream(_))) => {}, _ => panic!("expected event stream request"), }; - assert!( - tester.events.next().now_or_never().is_none(), - "expect no further network events", - ); - - // Poll the observer once and have it forward the reputation change from the gossip - // validator to the test network. - assert!(observer.now_or_never().is_none()); - assert_matches!(tester.events.next().now_or_never(), Some(Some(Event::Report(_, _)))); }); } diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index c06c7bbd71..57e18124ae 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -19,3 +19,6 @@ lru = "0.4.3" sc-network = { version = "0.8.0-alpha.4", path = "../network" } sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } wasm-timer = "0.2" + +[dev-dependencies] +substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } diff --git a/client/network-gossip/src/bridge.rs b/client/network-gossip/src/bridge.rs index c06cb6268c..85e06a1d6f 100644 --- a/client/network-gossip/src/bridge.rs +++ b/client/network-gossip/src/bridge.rs @@ -148,33 +148,40 @@ impl Future for GossipEngine { fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { let this = &mut *self; - while let Poll::Ready(Some(event)) = this.network_event_stream.poll_next_unpin(cx) { - match event { - Event::NotificationStreamOpened { remote, engine_id: msg_engine_id, roles } => { - if msg_engine_id != this.engine_id { - continue; + loop { + match this.network_event_stream.poll_next_unpin(cx) { + Poll::Ready(Some(event)) => match event { + Event::NotificationStreamOpened { remote, engine_id: msg_engine_id, roles } => { + if msg_engine_id != this.engine_id { + continue; + } + this.state_machine.new_peer(&mut *this.network, remote, roles); } - this.state_machine.new_peer(&mut *this.network, remote, roles); + Event::NotificationStreamClosed { remote, engine_id: msg_engine_id } => { + if msg_engine_id != this.engine_id { + continue; + } + this.state_machine.peer_disconnected(&mut *this.network, remote); + }, + Event::NotificationsReceived { remote, messages } => { + let engine_id = this.engine_id.clone(); + this.state_machine.on_incoming( + &mut *this.network, + remote, + messages.into_iter() + .filter_map(|(engine, data)| if engine == engine_id { + Some(ConsensusMessage { + engine_id: engine, data: data.to_vec(), + }) + } else { None }) + .collect() + ); + }, + Event::Dht(_) => {} } - Event::NotificationStreamClosed { remote, engine_id: msg_engine_id } => { - if msg_engine_id != this.engine_id { - continue; - } - this.state_machine.peer_disconnected(&mut *this.network, remote); - }, - Event::NotificationsReceived { remote, messages } => { - let engine_id = this.engine_id.clone(); - this.state_machine.on_incoming( - &mut *this.network, - remote, - messages.into_iter() - .filter_map(|(engine, data)| if engine == engine_id { - Some(ConsensusMessage { engine_id: engine, data: data.to_vec() }) - } else { None }) - .collect() - ); - }, - Event::Dht(_) => {} + // The network event stream closed. Do the same for [`GossipValidator`]. + Poll::Ready(None) => return Poll::Ready(()), + Poll::Pending => break, } } @@ -186,3 +193,77 @@ impl Future for GossipEngine { Poll::Pending } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ValidationResult, ValidatorContext}; + use substrate_test_runtime_client::runtime::Block; + + struct TestNetwork {} + + impl Network for Arc { + fn event_stream(&self) -> Pin + Send>> { + let (_tx, rx) = futures::channel::mpsc::channel(0); + + // Return rx and drop tx. Thus the given channel will yield `Poll::Ready(None)` on first + // poll. + Box::pin(rx) + } + + fn report_peer(&self, _: PeerId, _: ReputationChange) { + unimplemented!(); + } + + fn disconnect_peer(&self, _: PeerId) { + unimplemented!(); + } + + fn write_notification(&self, _: PeerId, _: ConsensusEngineId, _: Vec) { + unimplemented!(); + } + + fn register_notifications_protocol(&self, _: ConsensusEngineId, _: Cow<'static, [u8]>) {} + + fn announce(&self, _: B::Hash, _: Vec) { + unimplemented!(); + } + } + + struct TestValidator {} + + impl Validator for TestValidator { + fn validate( + &self, + _: &mut dyn ValidatorContext, + _: &PeerId, + _: &[u8] + ) -> ValidationResult { + unimplemented!(); + } + } + + /// Regression test for the case where the `GossipEngine.network_event_stream` closes. One + /// should not ignore a `Poll::Ready(None)` as `poll_next_unpin` will panic on subsequent calls. + /// + /// See https://github.com/paritytech/substrate/issues/5000 for details. + #[test] + fn returns_when_network_event_stream_closes() { + let mut gossip_engine = GossipEngine::::new( + Arc::new(TestNetwork{}), + [1, 2, 3, 4], + "my_protocol".as_bytes(), + Arc::new(TestValidator{}), + ); + + futures::executor::block_on(futures::future::poll_fn(move |ctx| { + if let Poll::Pending = gossip_engine.poll_unpin(ctx) { + panic!( + "Expected gossip engine to finish on first poll, given that \ + `GossipEngine.network_event_stream` closes right away." + ) + } + Poll::Ready(()) + })) + } +} -- GitLab From 0b30207969fdde85e0dad785750757399cd0e3e4 Mon Sep 17 00:00:00 2001 From: Chevdor Date: Wed, 18 Mar 2020 23:04:32 +0100 Subject: [PATCH 014/300] Add more generated utils to the image (#5305) --- .maintain/Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.maintain/Dockerfile b/.maintain/Dockerfile index 2fc1532aa2..21a41720f7 100644 --- a/.maintain/Dockerfile +++ b/.maintain/Dockerfile @@ -39,6 +39,10 @@ RUN mv /usr/share/ca* /tmp && \ ln -s /substrate/.local/share/substrate /data COPY --from=builder /substrate/target/$PROFILE/substrate /usr/local/bin +COPY --from=builder /substrate/target/$PROFILE/subkey /usr/local/bin +COPY --from=builder /substrate/target/$PROFILE/node-rpc-client /usr/local/bin +COPY --from=builder /substrate/target/$PROFILE/node-template /usr/local/bin +COPY --from=builder /substrate/target/$PROFILE/chain-spec-builder /usr/local/bin # checks RUN ldd /usr/local/bin/substrate && \ -- GitLab From 1ea615c0a422fdbc7ecdbc7357bdf7f5bbdc421b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Thu, 19 Mar 2020 10:37:29 +0000 Subject: [PATCH 015/300] grandpa: support for hard forking any pending standard changes (#5306) * grandpa: support for hard forking any pending standard changes * grandpa: expose authority_set_hard_forks in block import constructor * grandpa: don't break the public api --- client/finality-grandpa/src/import.rs | 54 ++++++++++++++++++++++++-- client/finality-grandpa/src/lib.rs | 56 ++++++++++++++++++++++++++- 2 files changed, 104 insertions(+), 6 deletions(-) diff --git a/client/finality-grandpa/src/import.rs b/client/finality-grandpa/src/import.rs index ea1deccdaf..ef5cc739de 100644 --- a/client/finality-grandpa/src/import.rs +++ b/client/finality-grandpa/src/import.rs @@ -30,7 +30,7 @@ use sp_consensus::{ BlockCheckParams, BlockImportParams, ImportResult, JustificationImport, SelectChain, }; -use sp_finality_grandpa::{GRANDPA_ENGINE_ID, ScheduledChange, ConsensusLog}; +use sp_finality_grandpa::{ConsensusLog, ScheduledChange, SetId, GRANDPA_ENGINE_ID}; use sp_runtime::Justification; use sp_runtime::generic::{BlockId, OpaqueDigestItemId}; use sp_runtime::traits::{ @@ -59,6 +59,7 @@ pub struct GrandpaBlockImport { authority_set: SharedAuthoritySet>, send_voter_commands: mpsc::UnboundedSender>>, consensus_changes: SharedConsensusChanges>, + authority_set_hard_forks: HashMap>>, _phantom: PhantomData, } @@ -72,6 +73,7 @@ impl Clone for authority_set: self.authority_set.clone(), send_voter_commands: self.send_voter_commands.clone(), consensus_changes: self.consensus_changes.clone(), + authority_set_hard_forks: self.authority_set_hard_forks.clone(), _phantom: PhantomData, } } @@ -212,9 +214,16 @@ where Client: crate::ClientForGrandpa, { // check for a new authority set change. - fn check_new_change(&self, header: &Block::Header, hash: Block::Hash) - -> Option>> - { + fn check_new_change( + &self, + header: &Block::Header, + hash: Block::Hash, + ) -> Option>> { + // check for forced authority set hard forks + if let Some(change) = self.authority_set_hard_forks.get(&hash) { + return Some(change.clone()); + } + // check for forced change. if let Some((median_last_finalized, change)) = find_forced_change::(header) { return Some(PendingChange { @@ -529,13 +538,50 @@ impl GrandpaBlockImport>, send_voter_commands: mpsc::UnboundedSender>>, consensus_changes: SharedConsensusChanges>, + authority_set_hard_forks: Vec<(SetId, PendingChange>)>, ) -> GrandpaBlockImport { + // check for and apply any forced authority set hard fork that applies + // to the *current* authority set. + if let Some((_, change)) = authority_set_hard_forks + .iter() + .find(|(set_id, _)| *set_id == authority_set.set_id()) + { + let mut authority_set = authority_set.inner().write(); + authority_set.current_authorities = change.next_authorities.clone(); + } + + // index authority set hard forks by block hash so that they can be used + // by any node syncing the chain and importing a block hard fork + // authority set changes. + let authority_set_hard_forks = authority_set_hard_forks + .into_iter() + .map(|(_, change)| (change.canon_hash, change)) + .collect::>(); + + // check for and apply any forced authority set hard fork that apply to + // any *pending* standard changes, checking by the block hash at which + // they were announced. + { + let mut authority_set = authority_set.inner().write(); + + authority_set.pending_standard_changes = authority_set + .pending_standard_changes + .clone() + .map(&mut |hash, _, original| { + authority_set_hard_forks + .get(&hash) + .cloned() + .unwrap_or(original) + }); + } + GrandpaBlockImport { inner, select_chain, authority_set, send_voter_commands, consensus_changes, + authority_set_hard_forks, _phantom: PhantomData, } } diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index 91da62848c..967584fa9b 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -417,10 +417,43 @@ pub fn block_import( client: Arc, genesis_authorities_provider: &dyn GenesisAuthoritySetProvider, select_chain: SC, -) -> Result<( +) -> Result< + ( GrandpaBlockImport, LinkHalf, - ), ClientError> + ), + ClientError, +> +where + SC: SelectChain, + BE: Backend + 'static, + Client: ClientForGrandpa + 'static, +{ + block_import_with_authority_set_hard_forks( + client, + genesis_authorities_provider, + select_chain, + Default::default(), + ) +} + +/// Make block importer and link half necessary to tie the background voter to +/// it. A vector of authority set hard forks can be passed, any authority set +/// change signaled at the given block (either already signalled or in a further +/// block when importing it) will be replaced by a standard change with the +/// given static authorities. +pub fn block_import_with_authority_set_hard_forks( + client: Arc, + genesis_authorities_provider: &dyn GenesisAuthoritySetProvider, + select_chain: SC, + authority_set_hard_forks: Vec<(SetId, (Block::Hash, NumberFor), AuthorityList)>, +) -> Result< + ( + GrandpaBlockImport, + LinkHalf, + ), + ClientError, +> where SC: SelectChain, BE: Backend + 'static, @@ -444,6 +477,24 @@ where let (voter_commands_tx, voter_commands_rx) = mpsc::unbounded(); + // create pending change objects with 0 delay and enacted on finality + // (i.e. standard changes) for each authority set hard fork. + let authority_set_hard_forks = authority_set_hard_forks + .into_iter() + .map(|(set_id, (hash, number), authorities)| { + ( + set_id, + authorities::PendingChange { + next_authorities: authorities, + delay: Zero::zero(), + canon_hash: hash, + canon_height: number, + delay_kind: authorities::DelayKind::Finalized, + }, + ) + }) + .collect(); + Ok(( GrandpaBlockImport::new( client.clone(), @@ -451,6 +502,7 @@ where persistent_data.authority_set.clone(), voter_commands_tx, persistent_data.consensus_changes.clone(), + authority_set_hard_forks, ), LinkHalf { client, -- GitLab From 79d75af4d11891a47ace0fe6bc909392b14343cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Thu, 19 Mar 2020 11:44:18 +0000 Subject: [PATCH 016/300] grandpa: bump dependency version to 0.11.2 (#5312) --- Cargo.lock | 4 ++-- client/finality-grandpa/Cargo.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 47ac61f036..9d4eaeac8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1381,9 +1381,9 @@ dependencies = [ [[package]] name = "finality-grandpa" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cbb25bef9fcad97fb31e817da280b1c9174435b8769c770ee190a330dd181ea" +checksum = "024517816630be5204eba201e8d1d405042b1255a5e0e3f298b054fc24d59e1d" dependencies = [ "futures 0.3.4", "futures-timer 2.0.2", diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index e60052756a..15c65ce5df 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -37,11 +37,11 @@ sp-finality-tracker = { version = "2.0.0-alpha.4", path = "../../primitives/fina sp-finality-grandpa = { version = "2.0.0-alpha.4", path = "../../primitives/finality-grandpa" } prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.4"} sc-block-builder = { version = "0.8.0-alpha.4", path = "../block-builder" } -finality-grandpa = { version = "0.11.1", features = ["derive-codec"] } +finality-grandpa = { version = "0.11.2", features = ["derive-codec"] } pin-project = "0.4.6" [dev-dependencies] -finality-grandpa = { version = "0.11.1", features = ["derive-codec", "test-helpers"] } +finality-grandpa = { version = "0.11.2", features = ["derive-codec", "test-helpers"] } sc-network = { version = "0.8.0-alpha.4", path = "../network" } sc-network-test = { version = "0.8.0-dev", path = "../network/test" } sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } -- GitLab From 974fb6687698ab342113751611a6d4155c34548e Mon Sep 17 00:00:00 2001 From: Roman Borschel Date: Thu, 19 Mar 2020 13:53:16 +0100 Subject: [PATCH 017/300] Safe logger initialisation in test. (#5311) env_logger::init() can lead to panics on concurrent test execution. See: https://gitlab.parity.io/parity/substrate/-/jobs/422283 --- client/finality-grandpa/src/communication/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/finality-grandpa/src/communication/tests.rs b/client/finality-grandpa/src/communication/tests.rs index f964cea469..7c9170a48e 100644 --- a/client/finality-grandpa/src/communication/tests.rs +++ b/client/finality-grandpa/src/communication/tests.rs @@ -357,7 +357,7 @@ fn good_commit_leads_to_relay() { #[test] fn bad_commit_leads_to_report() { - env_logger::init(); + let _ = env_logger::try_init(); let private = [Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let public = make_ids(&private[..]); let voter_set = Arc::new(public.iter().cloned().collect::>()); -- GitLab From 68e51d6e24862d499b5f042321cc87b172579e74 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Thu, 19 Mar 2020 14:02:07 +0100 Subject: [PATCH 018/300] Fixed a couple of syncing issues (#5277) * Don't queue duplicate blocks * Keep queue_blocks on restart --- client/network/src/protocol.rs | 5 +++ client/network/src/protocol/sync.rs | 52 ++++++++++++++++++----------- client/network/src/service.rs | 5 +++ client/network/test/src/lib.rs | 5 +++ client/network/test/src/sync.rs | 37 ++++++++++++++++++++ 5 files changed, 84 insertions(+), 20 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 29e5137a3d..846440ac39 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -556,6 +556,11 @@ impl Protocol { self.sync.status().queued_blocks } + /// Number of processed blocks. + pub fn num_processed_blocks(&self) -> usize { + self.sync.num_processed_blocks() + } + /// Number of active sync requests. pub fn num_sync_requests(&self) -> usize { self.sync.num_sync_requests() diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index ffbe6a096a..683f3c3139 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -85,7 +85,7 @@ mod rep { pub const INCOMPLETE_HEADER: Rep = Rep::new(-(1 << 20), "Incomplete header"); /// Reputation change for peers which send us a block which we fail to verify. - pub const VERIFICATION_FAIL: Rep = Rep::new(-(1 << 20), "Block verification failed"); + pub const VERIFICATION_FAIL: Rep = Rep::new(-(1 << 29), "Block verification failed"); /// Reputation change for peers which send us a known bad block. pub const BAD_BLOCK: Rep = Rep::new(-(1 << 29), "Bad block"); @@ -138,6 +138,8 @@ pub struct ChainSync { block_announce_validator: Box + Send>, /// Maximum number of peers to ask the same blocks in parallel. max_parallel_downloads: u32, + /// Total number of processed blocks (imported or failed). + processed_blocks: usize, } /// All the data we have about a Peer that we are trying to sync with @@ -318,6 +320,7 @@ impl ChainSync { is_idle: false, block_announce_validator, max_parallel_downloads, + processed_blocks: 0, } } @@ -357,6 +360,11 @@ impl ChainSync { self.fork_targets.len() } + /// Number of processed blocks. + pub fn num_processed_blocks(&self) -> usize { + self.processed_blocks + } + /// Handle a new connected peer. /// /// Call this method whenever we connect to a new peer. @@ -649,7 +657,7 @@ impl ChainSync { pub fn on_block_data (&mut self, who: PeerId, request: Option>, response: BlockResponse) -> Result, BadPeer> { - let new_blocks: Vec> = + let mut new_blocks: Vec> = if let Some(peer) = self.peers.get_mut(&who) { let mut blocks = response.blocks; if request.as_ref().map_or(false, |r| r.direction == message::Direction::Descending) { @@ -768,6 +776,12 @@ impl ChainSync { Vec::new() }; + let orig_len = new_blocks.len(); + new_blocks.retain(|b| !self.queue_blocks.contains(&b.hash)); + if new_blocks.len() != orig_len { + debug!(target: "sync", "Ignoring {} blocks that are already queued", orig_len - new_blocks.len()); + } + let is_recent = new_blocks.first() .map(|block| { self.peers.iter().any(|(_, peer)| peer.recently_announced.contains(&block.hash)) @@ -895,10 +909,12 @@ impl ChainSync { let mut output = Vec::new(); let mut has_error = false; - let mut hashes = vec![]; - for (result, hash) in results { - hashes.push(hash); + for (_, hash) in &results { + self.queue_blocks.remove(&hash); + } + self.processed_blocks += results.len(); + for (result, hash) in results { if has_error { continue; } @@ -943,43 +959,39 @@ impl ChainSync { }, Err(BlockImportError::IncompleteHeader(who)) => { if let Some(peer) = who { - info!("Peer sent block with incomplete header to import"); + warn!("Peer sent block with incomplete header to import"); output.push(Err(BadPeer(peer, rep::INCOMPLETE_HEADER))); output.extend(self.restart()); } }, Err(BlockImportError::VerificationFailed(who, e)) => { if let Some(peer) = who { - info!("Verification failed from peer: {}", e); + warn!("Verification failed for block {:?} received from peer: {}, {:?}", hash, peer, e); output.push(Err(BadPeer(peer, rep::VERIFICATION_FAIL))); output.extend(self.restart()); } }, Err(BlockImportError::BadBlock(who)) => { if let Some(peer) = who { - info!("Block received from peer has been blacklisted"); + info!("Block {:?} received from peer {} has been blacklisted", hash, peer); output.push(Err(BadPeer(peer, rep::BAD_BLOCK))); - output.extend(self.restart()); } }, Err(BlockImportError::MissingState) => { // This may happen if the chain we were requesting upon has been discarded // in the meantime because other chain has been finalized. // Don't mark it as bad as it still may be synced if explicitly requested. - trace!(target: "sync", "Obsolete block"); + trace!(target: "sync", "Obsolete block {:?}", hash); }, - Err(BlockImportError::UnknownParent) | - Err(BlockImportError::Cancelled) | - Err(BlockImportError::Other(_)) => { + e @ Err(BlockImportError::UnknownParent) | + e @ Err(BlockImportError::Other(_)) => { + warn!(target: "sync", "Error importing block {:?}: {:?}", hash, e); output.extend(self.restart()); }, + Err(BlockImportError::Cancelled) => {} }; } - for hash in hashes { - self.queue_blocks.remove(&hash); - } - self.is_idle = false; output.into_iter() } @@ -1094,9 +1106,9 @@ impl ChainSync { if let PeerSyncState::AncestorSearch(_, _) = peer.state { return OnBlockAnnounce::Nothing } - // If the announced block is the best they have seen, our common number + // If the announced block is the best they have and is not ahead of us, our common number // is either one further ahead or it's the one they just announced, if we know about it. - if is_best { + if is_best && self.best_queued_number >= number { if known { peer.common_number = number } else if header.parent_hash() == &self.best_queued_hash || known_parent { @@ -1168,7 +1180,7 @@ impl ChainSync { /// Restart the sync process. fn restart<'a>(&'a mut self) -> impl Iterator), BadPeer>> + 'a { - self.queue_blocks.clear(); + self.processed_blocks = 0; self.blocks.clear(); let info = self.client.info(); self.best_queued_hash = info.best_hash; diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 811690f433..81bea868b4 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -375,6 +375,11 @@ impl NetworkWorker { self.network_service.user_protocol().num_queued_blocks() } + /// Returns the number of processed blocks. + pub fn num_processed_blocks(&self) -> usize { + self.network_service.user_protocol().num_processed_blocks() + } + /// Number of active sync requests. pub fn num_sync_requests(&self) -> usize { self.network_service.user_protocol().num_sync_requests() diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index e98cf8bada..8ff06fc5ac 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -207,6 +207,11 @@ impl Peer { self.network.num_connected_peers() } + /// Returns the number of processed blocks. + pub fn num_processed_blocks(&self) -> usize { + self.network.num_processed_blocks() + } + /// Returns true if we have no peer. pub fn is_offline(&self) -> bool { self.num_peers() == 0 diff --git a/client/network/test/src/sync.rs b/client/network/test/src/sync.rs index 3882575168..5453747220 100644 --- a/client/network/test/src/sync.rs +++ b/client/network/test/src/sync.rs @@ -657,3 +657,40 @@ fn full_sync_requires_block_body() { net.block_until_idle(); assert_eq!(net.peer(1).client.info().best_number, 0); } + +#[test] +fn imports_stale_once() { + let _ = ::env_logger::try_init(); + + fn import_with_announce(net: &mut TestNet, hash: H256) { + // Announce twice + net.peer(0).announce_block(hash, Vec::new()); + net.peer(0).announce_block(hash, Vec::new()); + + block_on(futures::future::poll_fn::<(), _>(|cx| { + net.poll(cx); + if net.peer(1).client().header(&BlockId::Hash(hash)).unwrap().is_some() { + Poll::Ready(()) + } else { + Poll::Pending + } + })); + } + + // given the network with 2 full nodes + let mut net = TestNet::new(2); + + // let them connect to each other + net.block_until_sync(); + + // check that NEW block is imported from announce message + let new_hash = net.peer(0).push_blocks(1, false); + import_with_announce(&mut net, new_hash); + assert_eq!(net.peer(1).num_processed_blocks(), 1); + + // check that KNOWN STALE block is imported from announce message + let known_stale_hash = net.peer(0).push_blocks_at(BlockId::Number(0), 1, true); + import_with_announce(&mut net, known_stale_hash); + assert_eq!(net.peer(1).num_processed_blocks(), 2); +} + -- GitLab From c50faf2395218e644859611d703d9fe3a4876f5b Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Thu, 19 Mar 2020 16:03:26 +0100 Subject: [PATCH 019/300] Update dependencies (#5316) * switching to released wasmtime * update depdencies in general * Update fdlimit * Update parity common deps * Also update schnorrkel * update kvdb-rocksdb * update further dependents * also update primitive types * update cargo.lock * update merlin * Bumping evm version --- Cargo.lock | 639 ++++++++++------------- bin/utils/subkey/Cargo.toml | 2 +- client/Cargo.toml | 4 +- client/api/Cargo.toml | 2 +- client/cli/Cargo.toml | 4 +- client/consensus/babe/Cargo.toml | 4 +- client/db/Cargo.toml | 10 +- client/executor/wasmtime/Cargo.toml | 2 +- client/informant/Cargo.toml | 2 +- client/offchain/Cargo.toml | 2 +- client/service/Cargo.toml | 2 +- client/service/test/Cargo.toml | 2 +- client/state-db/Cargo.toml | 2 +- client/transaction-pool/Cargo.toml | 2 +- client/transaction-pool/graph/Cargo.toml | 2 +- frame/evm/Cargo.toml | 4 +- primitives/arithmetic/Cargo.toml | 2 +- primitives/arithmetic/fuzzer/Cargo.toml | 2 +- primitives/consensus/babe/Cargo.toml | 2 +- primitives/core/Cargo.toml | 9 +- primitives/runtime-interface/Cargo.toml | 2 +- primitives/runtime/Cargo.toml | 2 +- primitives/test-primitives/Cargo.toml | 2 +- test-utils/runtime/Cargo.toml | 2 +- utils/browser/Cargo.toml | 6 +- 25 files changed, 317 insertions(+), 397 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d4eaeac8f..189f85013c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5e63fd144e18ba274ae7095c0197a870a7b9468abc801dd62f190d80817d2ec" +checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" dependencies = [ "memchr", ] @@ -242,9 +242,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.44" +version = "0.3.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4036b9bf40f3cf16aba72a3d65e8a520fc4bafcdc7079aea8f848c58c5b5536" +checksum = "ad235dabf00f36301792cfe82499880ba54c6486be094d1047b02bacb67c14e8" dependencies = [ "backtrace-sys", "cfg-if", @@ -254,9 +254,9 @@ dependencies = [ [[package]] name = "backtrace-sys" -version = "0.1.32" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" +checksum = "ca797db0057bae1a7aa2eef3283a874695455cecf08a43bfb8507ee0ebc1ed69" dependencies = [ "cc", "libc", @@ -305,9 +305,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.53.1" +version = "0.53.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99de13bb6361e01e493b3db7928085dcc474b7ba4f5481818e53a89d76b8393f" +checksum = "6bb26d6a69a335b8cb0e7c7e9775cd5666611dc50a37177c3f2cedcfc040e8c8" dependencies = [ "bitflags", "cexpr", @@ -496,15 +496,6 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" -[[package]] -name = "c2-chacha" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" -dependencies = [ - "ppv-lite86", -] - [[package]] name = "c_linked_list" version = "1.1.1" @@ -543,9 +534,9 @@ dependencies = [ [[package]] name = "cexpr" -version = "0.3.6" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d" +checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" dependencies = [ "nom", ] @@ -579,9 +570,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" +checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" dependencies = [ "js-sys", "num-integer", @@ -592,9 +583,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "0.28.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853" +checksum = "f92986241798376849e1a007827041fed9bb36195822c2049d18e174420e0534" dependencies = [ "glob 0.3.0", "libc", @@ -689,32 +680,16 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -[[package]] -name = "core-foundation" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" -dependencies = [ - "core-foundation-sys 0.6.2", - "libc", -] - [[package]] name = "core-foundation" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" dependencies = [ - "core-foundation-sys 0.7.0", + "core-foundation-sys", "libc", ] -[[package]] -name = "core-foundation-sys" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" - [[package]] name = "core-foundation-sys" version = "0.7.0" @@ -724,7 +699,8 @@ checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" [[package]] name = "cranelift-bforest" version = "0.59.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a9c21f8042b9857bda93f6c1910b9f9f24100187a3d3d52f214a34e3dc5818" dependencies = [ "cranelift-entity", ] @@ -732,7 +708,8 @@ dependencies = [ [[package]] name = "cranelift-codegen" version = "0.59.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7853f77a6e4a33c67a69c40f5e1bb982bd2dc5c4a22e17e67b65bbccf9b33b2e" dependencies = [ "byteorder 1.3.4", "cranelift-bforest", @@ -750,7 +727,8 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" version = "0.59.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "084cd6d5fb0d1da28acd72c199471bfb09acc703ec8f3bf07b1699584272a3b9" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -759,12 +737,14 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" version = "0.59.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "701b599783305a58c25027a4d73f2d6b599b2d8ef3f26677275f480b4d51e05d" [[package]] name = "cranelift-entity" version = "0.59.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b88e792b28e1ebbc0187b72ba5ba880dad083abe9231a99d19604d10c9e73f38" dependencies = [ "serde", ] @@ -772,7 +752,8 @@ dependencies = [ [[package]] name = "cranelift-frontend" version = "0.59.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "518344698fa6c976d853319218415fdfb4f1bc6b42d0b2e2df652e55dff1f778" dependencies = [ "cranelift-codegen", "log 0.4.8", @@ -783,7 +764,8 @@ dependencies = [ [[package]] name = "cranelift-native" version = "0.59.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32daf082da21c0c05d93394ff4842c2ab7c4991b1f3186a1d952f8ac660edd0b" dependencies = [ "cranelift-codegen", "raw-cpuid", @@ -793,7 +775,8 @@ dependencies = [ [[package]] name = "cranelift-wasm" version = "0.59.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2aa816f554a3ef739a5d17ca3081a1f8983f04c944ea8ff60fb8d9dd8cd2d7b" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -1020,19 +1003,6 @@ dependencies = [ "rand 0.3.23", ] -[[package]] -name = "curve25519-dalek" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d" -dependencies = [ - "byteorder 1.3.4", - "clear_on_drop", - "digest", - "rand_core 0.3.1", - "subtle 2.2.2", -] - [[package]] name = "curve25519-dalek" version = "2.0.0" @@ -1043,7 +1013,7 @@ dependencies = [ "digest", "rand_core 0.5.1", "subtle 2.2.2", - "zeroize 1.1.0", + "zeroize", ] [[package]] @@ -1112,9 +1082,9 @@ dependencies = [ [[package]] name = "doc-comment" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97" +checksum = "807e5847c39ad6a11eac66de492ed1406f76a260eb8656e8740cad9eabc69c27" [[package]] name = "ed25519-dalek" @@ -1123,7 +1093,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978710b352437433c97b2bff193f2fb1dfd58a093f863dd95e225a19baa599a2" dependencies = [ "clear_on_drop", - "curve25519-dalek 2.0.0", + "curve25519-dalek", "rand 0.7.3", "sha2", ] @@ -1230,36 +1200,36 @@ dependencies = [ [[package]] name = "ethbloom" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cfe1c169414b709cf28aa30c74060bdb830a03a8ba473314d079ac79d80a5f" +checksum = "9e7abcddbdd5db30aeed4deb586adc4824e6c247e2f7238d1187f752893f096b" dependencies = [ "crunchy", "fixed-hash", "impl-rlp", - "impl-serde 0.2.3", - "tiny-keccak 1.5.0", + "impl-serde 0.3.0", + "tiny-keccak 2.0.1", ] [[package]] name = "ethereum-types" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba744248e3553a393143d5ebb68939fc3a4ec0c22a269682535f5ffe7fed728c" +checksum = "964c23cdee0ca07d5be2a628b46d5c11a2134ce554a8c16d8dbc2db647e4fd4d" dependencies = [ "ethbloom", "fixed-hash", "impl-rlp", - "impl-serde 0.2.3", + "impl-serde 0.3.0", "primitive-types", "uint", ] [[package]] name = "evm" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "272f65e18a2b6449b682bfcdf6c3ccc63db0b93898d89c0fb237548bbfc764a5" +checksum = "e3fd803d8dd69ee382f5d2010b6da5442bf41f94e46606357e8ebb994021cc7a" dependencies = [ "evm-core", "evm-gasometer", @@ -1272,18 +1242,18 @@ dependencies = [ [[package]] name = "evm-core" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66534d42e13d50f9101bed87cb568fd5aa929c600c3c13f8dadbbf39f5635945" +checksum = "06f59a5b6832f6826a0d222f354ac4a83747b6b7cadc6b539056daafea948536" dependencies = [ "primitive-types", ] [[package]] name = "evm-gasometer" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39bc5b592803ca644781fe2290b7305ea5182f7c9516d615ddfb2308c2cab639" +checksum = "66330d03fbd117156b3c54a7d41d22b40ba8bf2a07b80f23f95359e22eada4da" dependencies = [ "evm-core", "evm-runtime", @@ -1292,9 +1262,9 @@ dependencies = [ [[package]] name = "evm-runtime" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389e4b447fb26971a9c76c8aa49c0ab435f8e46e8fc46e1bc4ebf01f3c2b428f" +checksum = "ca05dc5b906d3c93b8e679a6dc0973c9d072e9962f8b4483530eb9a0ffc14ea5" dependencies = [ "evm-core", "primitive-types", @@ -1362,9 +1332,9 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fdlimit" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9084c55bb76efb1496328976db88320fe7d9ee86e649e83c4ecce3ba7a9a35d1" +checksum = "0da54a593b34c71b889ee45f5b5bb900c74148c5f7f8c6a9479ee7899f69603c" dependencies = [ "libc", ] @@ -1396,12 +1366,11 @@ dependencies = [ [[package]] name = "fixed-hash" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" +checksum = "32529fc42e86ec06e5047092082aab9ad459b070c5d2a76b14f4f5ce70bf2e84" dependencies = [ "byteorder 1.3.4", - "libc", "rand 0.7.3", "rustc-hex", "static_assertions", @@ -1932,9 +1901,9 @@ dependencies = [ [[package]] name = "gloo-timers" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2d17dbd803c2fc86cb1b613adf63192046a7176f383a8302594654752c4c4a" +checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f" dependencies = [ "futures-channel", "futures-core", @@ -1974,9 +1943,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" +checksum = "9d5c295d1c0c68e4e42003d75f908f5e16a1edd1cbe0b0d02e4dc2006a384f47" dependencies = [ "bytes 0.5.4", "fnv", @@ -1987,7 +1956,7 @@ dependencies = [ "indexmap", "log 0.4.8", "slab", - "tokio 0.2.12", + "tokio 0.2.13", "tokio-util", ] @@ -2190,15 +2159,15 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1c527bbc634be72aa7ba31e4e4def9bbb020f5416916279b7c705cd838893e" +checksum = "e7b15203263d1faa615f9337d79c1d37959439dc46c2b4faab33286fadc2a1c5" dependencies = [ "bytes 0.5.4", "futures-channel", "futures-core", "futures-util", - "h2 0.2.1", + "h2 0.2.2", "http 0.2.0", "http-body 0.3.1", "httparse", @@ -2207,7 +2176,7 @@ dependencies = [ "net2", "pin-project", "time", - "tokio 0.2.12", + "tokio 0.2.13", "tower-service", "want 0.3.0", ] @@ -2221,11 +2190,11 @@ dependencies = [ "bytes 0.5.4", "ct-logs", "futures-util", - "hyper 0.13.2", + "hyper 0.13.3", "log 0.4.8", "rustls 0.17.0", "rustls-native-certs", - "tokio 0.2.12", + "tokio 0.2.13", "tokio-rustls", "webpki", ] @@ -2374,9 +2343,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.35" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" +checksum = "1cb931d43e71f560c81badb0191596562bafad2be06a3f9025b845c847c60df5" dependencies = [ "wasm-bindgen", ] @@ -2530,31 +2499,30 @@ dependencies = [ [[package]] name = "kvdb" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03080afe6f42cd996da9f568d6add5d7fb5ee2ea7fb7802d2d2cbd836958fd87" +checksum = "cad096c6849b2ef027fabe35c4aed356d0e3d3f586d0a8361e5e17f1e50a7ce5" dependencies = [ - "parity-bytes", - "parity-util-mem", + "parity-util-mem 0.6.0", "smallvec 1.2.0", ] [[package]] name = "kvdb-memorydb" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9355274e5a9e0a7e8ef43916950eae3949024de2a8dffe4d5a6c13974a37c8e" +checksum = "4aa954d12cfac958822dfd77aab34f3eec71f103b918c4ab79ab59a36ee594ea" dependencies = [ "kvdb", - "parity-util-mem", + "parity-util-mem 0.6.0", "parking_lot 0.10.0", ] [[package]] name = "kvdb-rocksdb" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fecd50b14a534125228d7039951f92aaff742aff151c04546347aba4d3b4fbc" +checksum = "b3f14c3a10c8894d26175e57e9e26032e6d6c49c30cbe2468c5bf5f6b64bb0be" dependencies = [ "fs-swap", "interleaved-ordered", @@ -2562,7 +2530,7 @@ dependencies = [ "log 0.4.8", "num_cpus", "owning_ref", - "parity-util-mem", + "parity-util-mem 0.6.0", "parking_lot 0.10.0", "regex", "rocksdb", @@ -2571,16 +2539,16 @@ dependencies = [ [[package]] name = "kvdb-web" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a985c47b4c46429e96033ebf6eaed784a81ceccb4e5df13d63f3b9078a4df81" +checksum = "26f96eec962af83cdf7c83036b3dbb0ae6a1249ddab746820618e2567ca8ebcd" dependencies = [ "futures 0.3.4", "js-sys", "kvdb", "kvdb-memorydb", "log 0.4.8", - "parity-util-mem", + "parity-util-mem 0.6.0", "send_wrapper 0.3.0", "wasm-bindgen", "web-sys", @@ -2694,7 +2662,7 @@ dependencies = [ "thiserror", "unsigned-varint", "void", - "zeroize 1.1.0", + "zeroize", ] [[package]] @@ -2858,7 +2826,7 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15a8a3d71f898beb6f854c8aae27aa1d198e0d1f2e49412261c2d90ef39675a" dependencies = [ - "curve25519-dalek 2.0.0", + "curve25519-dalek", "futures 0.3.4", "lazy_static", "libp2p-core", @@ -2870,7 +2838,7 @@ dependencies = [ "snow", "static_assertions", "x25519-dalek", - "zeroize 1.1.0", + "zeroize", ] [[package]] @@ -3175,7 +3143,7 @@ dependencies = [ "ahash", "hash-db", "hashbrown", - "parity-util-mem", + "parity-util-mem 0.5.2", ] [[package]] @@ -3186,14 +3154,14 @@ checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" [[package]] name = "merlin" -version = "1.3.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b0942b357c1b4d0dc43ba724674ec89c3218e6ca2b3e8269e7cb53bcecd2f6e" +checksum = "c6feca46f4fa3443a01769d768727f10c10a20fdb65e52dc16a81f0c8269bb78" dependencies = [ "byteorder 1.3.4", "keccak", - "rand_core 0.4.2", - "zeroize 1.1.0", + "rand_core 0.5.1", + "zeroize", ] [[package]] @@ -3305,9 +3273,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" +checksum = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d" dependencies = [ "lazy_static", "libc", @@ -3316,8 +3284,8 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework 0.3.4", - "security-framework-sys 0.3.3", + "security-framework", + "security-framework-sys", "tempfile", ] @@ -3715,12 +3683,12 @@ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" [[package]] name = "nom" -version = "4.2.3" +version = "5.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" +checksum = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6" dependencies = [ "memchr", - "version_check 0.1.5", + "version_check 0.9.1", ] [[package]] @@ -4417,7 +4385,7 @@ dependencies = [ "frame-system", "pallet-balances", "parity-scale-codec", - "rand_chacha 0.2.1", + "rand_chacha 0.2.2", "serde", "sp-core", "sp-io", @@ -4438,7 +4406,7 @@ dependencies = [ "pallet-staking-reward-curve", "pallet-timestamp", "parity-scale-codec", - "rand_chacha 0.2.1", + "rand_chacha 0.2.2", "serde", "sp-core", "sp-io", @@ -4600,12 +4568,6 @@ dependencies = [ "sp-storage", ] -[[package]] -name = "parity-bytes" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c276d76c5333b8c2579e02d49a06733a55b8282d2d9b13e8d53b6406bd7e30a" - [[package]] name = "parity-multiaddr" version = "0.7.3" @@ -4675,6 +4637,19 @@ name = "parity-util-mem" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9344bc978467339b9ae688f9dcf279d1aaa0ccfc88e9a780c729b765a82d57d5" +dependencies = [ + "cfg-if", + "impl-trait-for-tuples", + "parity-util-mem-derive", + "parking_lot 0.10.0", + "winapi 0.3.8", +] + +[[package]] +name = "parity-util-mem" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e42755f26e5ea21a6a819d9e63cbd70713e9867a2b767ec2cc65ca7659532c5" dependencies = [ "cfg-if", "ethereum-types", @@ -4894,9 +4869,9 @@ checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" [[package]] name = "predicates" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1188bf092c81c18228c383b190c069a8a613c18a046ffa9fdfc0f5fc8fb2da8a" +checksum = "347a1b6f0b21e636bc9872fb60b83b8e185f6f5516298b8238699f7f9a531030" dependencies = [ "difference", "predicates-core", @@ -4932,9 +4907,9 @@ dependencies = [ [[package]] name = "primitive-types" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" +checksum = "e5e4b9943a2da369aec5e96f7c10ebc74fcf434d39590d974b0a3460e6f67fbb" dependencies = [ "fixed-hash", "impl-codec", @@ -4954,28 +4929,28 @@ dependencies = [ [[package]] name = "proc-macro-error" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052b3c9af39c7e5e94245f820530487d19eb285faedcb40e0c3275132293f242" +checksum = "e7959c6467d962050d639361f7703b2051c43036d03493c36f01d440fdd3138a" dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "rustversion", "syn", + "version_check 0.9.1", ] [[package]] name = "proc-macro-error-attr" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d175bef481c7902e63e3165627123fff3502f06ac043d3ef42d08c1246da9253" +checksum = "e4002d9f55991d5e019fb940a90e1a95eb80c24e77cb2462dd4dc869604d543a" dependencies = [ "proc-macro2", "quote", - "rustversion", "syn", "syn-mid", + "version_check 0.9.1", ] [[package]] @@ -5071,9 +5046,9 @@ dependencies = [ [[package]] name = "protobuf" -version = "2.10.1" +version = "2.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6686ddd96a8dbe2687b5f2a687b2cfb520854010ec480f2d74c32e7c9873d3c5" +checksum = "37a5325d019a4d837d3abde0a836920f959e33d350f77b5f1e289e061e774942" [[package]] name = "pwasm-utils" @@ -5174,7 +5149,7 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom", "libc", - "rand_chacha 0.2.1", + "rand_chacha 0.2.2", "rand_core 0.5.1", "rand_hc 0.2.0", ] @@ -5191,11 +5166,11 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ - "c2-chacha", + "ppv-lite86", "rand_core 0.5.1", ] @@ -5380,18 +5355,18 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" +checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" dependencies = [ "byteorder 1.3.4", ] [[package]] name = "regex-syntax" -version = "0.6.14" +version = "0.6.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" +checksum = "1132f845907680735a84409c3bebc64d1364a5683ffbce899550cd09d5eaefc1" [[package]] name = "region" @@ -5532,7 +5507,7 @@ dependencies = [ "openssl-probe", "rustls 0.17.0", "schannel", - "security-framework 0.4.1", + "security-framework", ] [[package]] @@ -5718,7 +5693,7 @@ dependencies = [ "lazy_static", "log 0.4.8", "names", - "parity-util-mem", + "parity-util-mem 0.6.0", "regex", "rpassword", "sc-client-api", @@ -5738,7 +5713,7 @@ dependencies = [ "substrate-prometheus-endpoint", "tempfile", "time", - "tokio 0.2.12", + "tokio 0.2.13", ] [[package]] @@ -5823,7 +5798,7 @@ dependencies = [ "linked-hash-map", "log 0.4.8", "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.6.0", "parking_lot 0.10.0", "quickcheck", "rand 0.7.3", @@ -5993,7 +5968,7 @@ dependencies = [ "substrate-test-runtime-client", "substrate-test-runtime-transaction-pool", "tempfile", - "tokio 0.2.12", + "tokio 0.2.13", ] [[package]] @@ -6128,7 +6103,7 @@ dependencies = [ "sp-core", "sp-runtime-interface", "sp-wasm-interface", - "wasmtime", + "substrate-wasmtime", ] [[package]] @@ -6170,7 +6145,7 @@ dependencies = [ "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", - "tokio 0.2.12", + "tokio 0.2.13", ] [[package]] @@ -6180,7 +6155,7 @@ dependencies = [ "ansi_term 0.12.1", "futures 0.3.4", "log 0.4.8", - "parity-util-mem", + "parity-util-mem 0.6.0", "sc-client-api", "sc-network", "sc-service", @@ -6260,7 +6235,7 @@ dependencies = [ "unsigned-varint", "void", "wasm-timer", - "zeroize 1.1.0", + "zeroize", ] [[package]] @@ -6313,7 +6288,7 @@ dependencies = [ "fnv", "futures 0.3.4", "futures-timer 3.0.2", - "hyper 0.13.2", + "hyper 0.13.3", "hyper-rustls", "log 0.4.8", "num_cpus", @@ -6332,7 +6307,7 @@ dependencies = [ "sp-transaction-pool", "substrate-test-runtime-client", "threadpool", - "tokio 0.2.12", + "tokio 0.2.13", ] [[package]] @@ -6448,7 +6423,7 @@ dependencies = [ "log 0.4.8", "parity-multiaddr", "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.6.0", "parking_lot 0.10.0", "sc-chain-spec", "sc-client", @@ -6513,7 +6488,7 @@ dependencies = [ "env_logger 0.7.1", "log 0.4.8", "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.6.0", "parity-util-mem-derive", "parking_lot 0.10.0", "sc-client-api", @@ -6567,7 +6542,7 @@ dependencies = [ "linked-hash-map", "log 0.4.8", "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.6.0", "parking_lot 0.10.0", "serde", "sp-blockchain", @@ -6588,7 +6563,7 @@ dependencies = [ "futures-timer 2.0.2", "log 0.4.8", "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.6.0", "parking_lot 0.10.0", "sc-client-api", "sc-transaction-graph", @@ -6615,19 +6590,20 @@ dependencies = [ [[package]] name = "schnorrkel" -version = "0.8.5" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" +checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" dependencies = [ - "curve25519-dalek 1.2.3", - "failure", + "arrayref", + "arrayvec 0.5.1", + "curve25519-dalek", + "getrandom", "merlin", - "rand 0.6.5", - "rand_core 0.4.2", - "rand_os", + "rand 0.7.3", + "rand_core 0.5.1", "sha2", "subtle 2.2.2", - "zeroize 0.9.3", + "zeroize", ] [[package]] @@ -6672,18 +6648,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "security-framework" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ef2429d7cefe5fd28bd1d2ed41c944547d4ff84776f5935b456da44593a16df" -dependencies = [ - "core-foundation 0.6.4", - "core-foundation-sys 0.6.2", - "libc", - "security-framework-sys 0.3.3", -] - [[package]] name = "security-framework" version = "0.4.1" @@ -6691,18 +6655,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97bbedbe81904398b6ebb054b3e912f99d55807125790f3198ac990d98def5b0" dependencies = [ "bitflags", - "core-foundation 0.7.0", - "core-foundation-sys 0.7.0", - "security-framework-sys 0.4.1", -] - -[[package]] -name = "security-framework-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31493fc37615debb8c5090a7aeb4a9730bc61e77ab10b9af59f1a202284f895" -dependencies = [ - "core-foundation-sys 0.6.2", + "core-foundation", + "core-foundation-sys", + "security-framework-sys", ] [[package]] @@ -6711,7 +6666,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06fd2f23e31ef68dd2328cc383bd493142e46107a3a0e24f7d734e3f3b80fe4c" dependencies = [ - "core-foundation-sys 0.7.0", + "core-foundation-sys", "libc", ] @@ -6961,12 +6916,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "sourcefile" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" - [[package]] name = "sp-allocator" version = "2.0.0-alpha.4" @@ -7188,7 +7137,7 @@ dependencies = [ "log 0.4.8", "num-traits", "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.6.0", "parking_lot 0.10.0", "pretty_assertions", "primitive-types", @@ -7210,7 +7159,7 @@ dependencies = [ "tiny-keccak 2.0.1", "twox-hash", "wasmi", - "zeroize 1.1.0", + "zeroize", ] [[package]] @@ -7335,7 +7284,7 @@ dependencies = [ "impl-trait-for-tuples", "log 0.4.8", "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.6.0", "paste", "rand 0.7.3", "serde", @@ -7481,7 +7430,7 @@ name = "sp-test-primitives" version = "2.0.0-dev" dependencies = [ "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.6.0", "serde", "sp-application-crypto", "sp-core", @@ -7606,9 +7555,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1bcbed7d48956fcbb5d80c6b95aedb553513de0a1b451ea92679d999c010e98" +checksum = "3fe43617218c0805c6eb37160119dc3c548110a67786da7218d1c6555212f073" dependencies = [ "clap", "lazy_static", @@ -7617,9 +7566,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "095064aa1f5b94d14e635d0a5684cf140c43ae40a0fd990708d38f5d669e5f64" +checksum = "c6e79c80e0f4efd86ca960218d4e056249be189ff1c42824dcd9a7f51a56f0bd" dependencies = [ "heck", "proc-macro-error", @@ -7681,9 +7630,9 @@ dependencies = [ [[package]] name = "substrate-bip39" -version = "0.3.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" +checksum = "c004e8166d6e0aa3a9d5fa673e5b7098ff25f930de1013a21341988151e681bb" dependencies = [ "hmac", "pbkdf2", @@ -7733,7 +7682,7 @@ dependencies = [ "sc-rpc-api", "serde", "sp-storage", - "tokio 0.2.12", + "tokio 0.2.13", ] [[package]] @@ -7766,10 +7715,10 @@ dependencies = [ "async-std", "derive_more", "futures-util", - "hyper 0.13.2", + "hyper 0.13.3", "log 0.4.8", "prometheus", - "tokio 0.2.12", + "tokio 0.2.13", ] [[package]] @@ -7805,7 +7754,7 @@ dependencies = [ "pallet-babe", "pallet-timestamp", "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.6.0", "sc-block-builder", "sc-client", "sc-executor", @@ -7888,6 +7837,75 @@ dependencies = [ name = "substrate-wasm-builder-runner" version = "1.0.5" +[[package]] +name = "substrate-wasmtime" +version = "0.13.0-threadsafe.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e512629525ecfe43bffe1f3d9e6bb0f08bf01155288ef27fcaae4ea086e4a9d" +dependencies = [ + "anyhow", + "backtrace", + "cfg-if", + "lazy_static", + "libc", + "region", + "rustc-demangle", + "substrate-wasmtime-jit", + "substrate-wasmtime-runtime", + "target-lexicon", + "wasmparser", + "wasmtime-environ", + "wasmtime-profiling", + "wat", + "winapi 0.3.8", +] + +[[package]] +name = "substrate-wasmtime-jit" +version = "0.13.0-threadsafe.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a20de5564886d2bcffdd351c9cd114ceb50758aa58eac3cedb14faabf7f93b91" +dependencies = [ + "anyhow", + "cfg-if", + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "cranelift-native", + "cranelift-wasm", + "more-asserts", + "region", + "substrate-wasmtime-runtime", + "target-lexicon", + "thiserror", + "wasmparser", + "wasmtime-debug", + "wasmtime-environ", + "wasmtime-profiling", + "winapi 0.3.8", +] + +[[package]] +name = "substrate-wasmtime-runtime" +version = "0.13.0-threadsafe.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d08846f04293a7fc27eeb30f06262ca2e1b4ee20f5192cec1f3ce201e08ceb8" +dependencies = [ + "backtrace", + "cc", + "cfg-if", + "indexmap", + "lazy_static", + "libc", + "memoffset", + "more-asserts", + "region", + "thiserror", + "wasmtime-environ", + "wasmtime-profiling", + "winapi 0.3.8", +] + [[package]] name = "subtle" version = "1.0.0" @@ -8131,9 +8149,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b34bee1facdc352fba10c9c58b654e6ecb6a2250167772bf86071f7c5f2f5061" +checksum = "0fa5e81d6bc4e67fe889d5783bd2a128ab2e0cfa487e0be16b6a8d177b101616" dependencies = [ "bytes 0.5.4", "fnv", @@ -8264,7 +8282,7 @@ checksum = "4adb8b3e5f86b707f1b54e7c15b6de52617a823608ccda98a15d3a24222f265a" dependencies = [ "futures-core", "rustls 0.17.0", - "tokio 0.2.12", + "tokio 0.2.13", "webpki", ] @@ -8387,7 +8405,7 @@ dependencies = [ "futures-sink", "log 0.4.8", "pin-project-lite", - "tokio 0.2.12", + "tokio 0.2.13", ] [[package]] @@ -8503,9 +8521,9 @@ checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" [[package]] name = "trybuild" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26ff1b18659a2218332848d76ad1c867ce4c6ee37b085e6bc8de9a6d11401220" +checksum = "24b4e093c5ed1a60b22557090120aa14f90ca801549c0949d775ea07c1407720" dependencies = [ "glob 0.3.0", "lazy_static", @@ -8615,12 +8633,13 @@ checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" [[package]] name = "unsigned-varint" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7ffb36714206d2f5f05d61a2bc350415c642f2c54433f0ebf829afbe41d570" +checksum = "f38e01ad4b98f042e166c1bf9a13f9873a99d79eaa171ce7ca81e6dd0f895d8a" dependencies = [ "bytes 0.5.4", - "futures 0.3.4", + "futures-io", + "futures-util", "futures_codec", ] @@ -8672,13 +8691,12 @@ checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" [[package]] name = "vergen" -version = "3.0.4" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba" +checksum = "4ce50d8996df1f85af15f2cd8d33daae6e479575123ef4314a51a70a230739cb" dependencies = [ "bitflags", "chrono", - "failure", ] [[package]] @@ -8762,9 +8780,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" -version = "0.2.58" +version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" +checksum = "3557c397ab5a8e347d434782bcd31fc1483d927a6826804cec05cc792ee2519d" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -8772,9 +8790,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.58" +version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" +checksum = "e0da9c9a19850d3af6df1cb9574970b566d617ecfaf36eb0b706b6f3ef9bd2f8" dependencies = [ "bumpalo", "lazy_static", @@ -8787,9 +8805,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbdd49e3e28b40dec6a9ba8d17798245ce32b019513a845369c641b275135d9" +checksum = "457414a91863c0ec00090dba537f88ab955d93ca6555862c29b6d860990b8a8a" dependencies = [ "cfg-if", "js-sys", @@ -8799,9 +8817,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.58" +version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" +checksum = "0f6fde1d36e75a714b5fe0cffbb78978f222ea6baebb726af13c78869fdb4205" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -8809,9 +8827,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.58" +version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" +checksum = "25bda4168030a6412ea8a047e27238cadf56f0e53516e1e83fec0a8b7c786f6d" dependencies = [ "proc-macro2", "quote", @@ -8822,25 +8840,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601" - -[[package]] -name = "wasm-bindgen-webidl" -version = "0.2.58" +version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef012a0d93fc0432df126a8eaf547b2dce25a8ce9212e1d3cbeef5c11157975d" -dependencies = [ - "anyhow", - "heck", - "log 0.4.8", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "weedle", -] +checksum = "fc9f36ad51f25b0219a3d4d13b90eb44cd075dff8b6280cca015775d7acaddd8" [[package]] name = "wasm-gc-api" @@ -8899,32 +8901,11 @@ version = "0.51.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aeb1956b19469d1c5e63e459d29e7b5aa0f558d9f16fcef09736f8a265e6c10a" -[[package]] -name = "wasmtime" -version = "0.12.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" -dependencies = [ - "anyhow", - "backtrace", - "cfg-if", - "lazy_static", - "libc", - "region", - "rustc-demangle", - "target-lexicon", - "wasmparser", - "wasmtime-environ", - "wasmtime-jit", - "wasmtime-profiling", - "wasmtime-runtime", - "wat", - "winapi 0.3.8", -] - [[package]] name = "wasmtime-debug" version = "0.12.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d3d007436043bf55ec252d2f4dc1d35834157b5e2f148da839ca502e611cfe1" dependencies = [ "anyhow", "faerie", @@ -8939,7 +8920,8 @@ dependencies = [ [[package]] name = "wasmtime-environ" version = "0.12.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80f3dea0e60c076dd0da27fa10c821323903c9554c617ed32eaab8e7a7e36c89" dependencies = [ "anyhow", "base64 0.11.0", @@ -8964,34 +8946,11 @@ dependencies = [ "zstd", ] -[[package]] -name = "wasmtime-jit" -version = "0.12.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" -dependencies = [ - "anyhow", - "cfg-if", - "cranelift-codegen", - "cranelift-entity", - "cranelift-frontend", - "cranelift-native", - "cranelift-wasm", - "more-asserts", - "region", - "target-lexicon", - "thiserror", - "wasmparser", - "wasmtime-debug", - "wasmtime-environ", - "wasmtime-profiling", - "wasmtime-runtime", - "winapi 0.3.8", -] - [[package]] name = "wasmtime-profiling" version = "0.12.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "984d29c8add3381e60d649f4e3e2a501da900fc2d2586e139502eec32fe0ebc8" dependencies = [ "gimli", "goblin", @@ -9003,55 +8962,32 @@ dependencies = [ "target-lexicon", ] -[[package]] -name = "wasmtime-runtime" -version = "0.12.0" -source = "git+https://github.com/paritytech/wasmtime?branch=a-thread-safe-api#851887d84d03543f931f6312448d0dd5d8a9324e" -dependencies = [ - "backtrace", - "cc", - "cfg-if", - "indexmap", - "lazy_static", - "libc", - "memoffset", - "more-asserts", - "region", - "thiserror", - "wasmtime-environ", - "wasmtime-profiling", - "winapi 0.3.8", -] - [[package]] name = "wast" -version = "9.0.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee7b16105405ca2aa2376ba522d8d4b1a11604941dd3bb7df9fd2ece60f8d16a" +checksum = "4efb62ecebf5cc9dbf2954309a20d816289c6550c0597a138b9e811cefc05007" dependencies = [ "leb128", ] [[package]] name = "wat" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56173f7f4fb59aebe35a7e71423845e1c6c7144bfb56362d497931b6b3bed0f6" +checksum = "ffdea5e25273cc3a62f3ae3a1a4c7d7996625875b50c0b4475fee6698c2b069c" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.35" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b" +checksum = "721c6263e2c66fd44501cc5efbfa2b7dfa775d13e4ea38c46299646ed1f9c70a" dependencies = [ - "anyhow", "js-sys", - "sourcefile", "wasm-bindgen", - "wasm-bindgen-webidl", ] [[package]] @@ -9123,20 +9059,11 @@ dependencies = [ "tokio-tls", ] -[[package]] -name = "weedle" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" -dependencies = [ - "nom", -] - [[package]] name = "which" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5475d47078209a02e60614f7ba5e645ef3ed60f771920ac1906d7c1cc65024c8" +checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" dependencies = [ "libc", ] @@ -9218,9 +9145,9 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "637ff90c9540fa3073bb577e65033069e4bae7c79d49d74aa3ffdf5342a53217" dependencies = [ - "curve25519-dalek 2.0.0", + "curve25519-dalek", "rand_core 0.5.1", - "zeroize 1.1.0", + "zeroize", ] [[package]] @@ -9244,12 +9171,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "zeroize" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" - [[package]] name = "zeroize" version = "1.1.0" diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index feb78ed7b4..06e91cf591 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -17,7 +17,7 @@ rand = "0.7.2" clap = "2.33.0" tiny-bip39 = "0.7" rustc-hex = "2.0.1" -substrate-bip39 = "0.3.1" +substrate-bip39 = "0.4.1" hex = "0.4.0" hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.2.0" } diff --git a/client/Cargo.toml b/client/Cargo.toml index 686dbb661d..bca4ab60f3 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -22,7 +22,7 @@ hash-db = { version = "0.15.2" } hex-literal = { version = "0.2.1" } sp-inherents = { version = "2.0.0-alpha.4", path = "../primitives/inherents" } sp-keyring = { version = "2.0.0-alpha.4", path = "../primitives/keyring" } -kvdb = "0.4.0" +kvdb = "0.5.0" log = { version = "0.4.8" } parking_lot = "0.10.0" sp-core = { version = "2.0.0-alpha.4", path = "../primitives/core" } @@ -41,5 +41,5 @@ tracing = "0.1.10" env_logger = "0.7.0" tempfile = "3.1.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../test-utils/runtime/client" } -kvdb-memorydb = "0.4.0" +kvdb-memorydb = "0.5.0" sp-panic-handler = { version = "2.0.0-alpha.4", path = "../primitives/panic-handler" } diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index 94234a4a92..1006d92b74 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -23,7 +23,7 @@ sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain hex-literal = { version = "0.2.1" } sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } -kvdb = "0.4.0" +kvdb = "0.5.0" log = { version = "0.4.8" } parking_lot = "0.10.0" sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 93103a4323..30a53c81ca 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -21,7 +21,7 @@ lazy_static = "1.4.0" app_dirs = "1.2.1" tokio = { version = "0.2.9", features = [ "signal", "rt-core", "rt-threaded" ] } futures = "0.3.1" -fdlimit = "0.1.1" +fdlimit = "0.1.4" serde_json = "1.0.41" sc-informant = { version = "0.8.0-alpha.4", path = "../informant" } sp-panic-handler = { version = "2.0.0-alpha.4", path = "../../primitives/panic-handler" } @@ -39,7 +39,7 @@ names = "0.11.0" structopt = "0.3.8" sc-tracing = { version = "2.0.0-alpha.4", path = "../tracing" } chrono = "0.4.10" -parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [target.'cfg(not(target_os = "unknown"))'.dependencies] rpassword = "4.0.1" diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index aa70fc0d40..8a5d70e755 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -40,9 +40,9 @@ futures = "0.3.1" futures-timer = "3.0.1" parking_lot = "0.10.0" log = "0.4.8" -schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"] } +schnorrkel = { version = "0.9", features = ["preaudit_deprecated"] } rand = "0.7.2" -merlin = "1.2.1" +merlin = "2.0" pdqselect = "0.1.0" derive_more = "0.99.2" diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index dde3de8e89..955f71d34e 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -12,12 +12,12 @@ description = "Client backend that uses RocksDB database as storage." parking_lot = "0.10.0" log = "0.4.8" rand = "0.7" -kvdb = "0.4.0" -kvdb-rocksdb = { version = "0.6", optional = true } -kvdb-memorydb = "0.4.0" +kvdb = "0.5.0" +kvdb-rocksdb = { version = "0.7", optional = true } +kvdb-memorydb = "0.5.0" linked-hash-map = "0.5.2" hash-db = "0.15.2" -parity-util-mem = { version = "0.5.2", default-features = false, features = ["std"] } +parity-util-mem = { version = "0.6.0", default-features = false, features = ["std"] } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } @@ -37,7 +37,7 @@ sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } env_logger = "0.7.0" quickcheck = "0.9" -kvdb-rocksdb = "0.6" +kvdb-rocksdb = "0.7" tempfile = "3" [features] diff --git a/client/executor/wasmtime/Cargo.toml b/client/executor/wasmtime/Cargo.toml index fb9d054f09..9181d76d5c 100644 --- a/client/executor/wasmtime/Cargo.toml +++ b/client/executor/wasmtime/Cargo.toml @@ -18,7 +18,7 @@ sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/was sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime-interface" } sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } sp-allocator = { version = "2.0.0-alpha.4", path = "../../../primitives/allocator" } -wasmtime = { git = "https://github.com/paritytech/wasmtime", branch = "a-thread-safe-api" } +wasmtime = { package = "substrate-wasmtime", version = "0.13.0-threadsafe.1" } [dev-dependencies] assert_matches = "1.3.0" diff --git a/client/informant/Cargo.toml b/client/informant/Cargo.toml index 3a7ccaf489..9a9610bf16 100644 --- a/client/informant/Cargo.toml +++ b/client/informant/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/paritytech/substrate/" ansi_term = "0.12.1" futures = "0.3.1" log = "0.4.8" -parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } wasm-timer = "0.2" sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } sc-network = { version = "0.8.0-alpha.4", path = "../network" } diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index ecc8621be3..f736a85990 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -33,7 +33,7 @@ hyper-rustls = "0.20" [dev-dependencies] env_logger = "0.7.0" -fdlimit = "0.1" +fdlimit = "0.1.4" sc-client-db = { version = "0.8.0-alpha.4", default-features = true, path = "../db/" } sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../../client/transaction-pool" } sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index c6d49e55d1..4bc4d1fd78 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -59,7 +59,7 @@ parity-multiaddr = { package = "parity-multiaddr", version = "0.7.3" } prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" , version = "0.8.0-alpha.4"} sc-tracing = { version = "2.0.0-alpha.4", path = "../tracing" } tracing = "0.1.10" -parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } diff --git a/client/service/test/Cargo.toml b/client/service/test/Cargo.toml index 41ccd0369a..fc2ffeae59 100644 --- a/client/service/test/Cargo.toml +++ b/client/service/test/Cargo.toml @@ -14,7 +14,7 @@ tokio = "0.1.22" futures01 = { package = "futures", version = "0.1.29" } log = "0.4.8" env_logger = "0.7.0" -fdlimit = "0.1.1" +fdlimit = "0.1.4" futures = { version = "0.3.1", features = ["compat"] } sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../../service" } sc-network = { version = "0.8.0-alpha.4", path = "../../network" } diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index a1978b4e75..58ef699884 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -14,7 +14,7 @@ log = "0.4.8" sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } -parity-util-mem = "0.5.2" +parity-util-mem = "0.6" parity-util-mem-derive = "0.1.0" [dev-dependencies] diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index aee4564c2e..42dc9d9968 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -24,7 +24,7 @@ sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/tran sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } futures-timer = "2.0" -parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index 05642de9f7..4445df6234 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -19,7 +19,7 @@ sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockch sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../primitives/transaction-pool" } -parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } linked-hash-map = "0.5.2" [dev-dependencies] diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml index b252dac689..87b776c118 100644 --- a/frame/evm/Cargo.toml +++ b/frame/evm/Cargo.toml @@ -19,9 +19,9 @@ sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../p sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -primitive-types = { version = "0.6.2", default-features = false, features = ["rlp"] } +primitive-types = { version = "0.7.0", default-features = false, features = ["rlp"] } rlp = { version = "0.4", default-features = false } -evm = { version = "0.15", default-features = false } +evm = { version = "0.16", default-features = false } sha3 = { version = "0.8", default-features = false } [features] diff --git a/primitives/arithmetic/Cargo.toml b/primitives/arithmetic/Cargo.toml index aa45e2a674..96402567cd 100644 --- a/primitives/arithmetic/Cargo.toml +++ b/primitives/arithmetic/Cargo.toml @@ -19,7 +19,7 @@ serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-debug-derive = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/debug-derive" } [dev-dependencies] -primitive-types = "0.6.2" +primitive-types = "0.7.0" rand = "0.7.2" criterion = "0.3" diff --git a/primitives/arithmetic/fuzzer/Cargo.toml b/primitives/arithmetic/fuzzer/Cargo.toml index 19d677f744..ea129906ea 100644 --- a/primitives/arithmetic/fuzzer/Cargo.toml +++ b/primitives/arithmetic/fuzzer/Cargo.toml @@ -8,7 +8,7 @@ license = "GPL-3.0" [dependencies] sp-arithmetic = { version = "2.0.0", path = ".." } honggfuzz = "0.5" -primitive-types = "0.6.2" +primitive-types = "0.7.0" num-bigint = "0.2" num-traits = "0.2" diff --git a/primitives/consensus/babe/Cargo.toml b/primitives/consensus/babe/Cargo.toml index f4bab0080f..2457bdac20 100644 --- a/primitives/consensus/babe/Cargo.toml +++ b/primitives/consensus/babe/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/paritytech/substrate/" sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../std" } -schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"], optional = true } +schnorrkel = { version = "0.9", features = ["preaudit_deprecated"], optional = true } sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../api" } sp-consensus = { version = "0.8.0-alpha.4", optional = true, path = "../common" } sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../inherents" } diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 8b9aaaabd5..78e4f49a39 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -16,14 +16,14 @@ rustc-hex = { version = "2.0.1", default-features = false } log = { version = "0.4.8", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } byteorder = { version = "1.3.2", default-features = false } -primitive-types = { version = "0.6.2", default-features = false, features = ["codec"] } +primitive-types = { version = "0.7.0", default-features = false, features = ["codec"] } impl-serde = { version = "0.3.0", optional = true } wasmi = { version = "0.6.2", optional = true } hash-db = { version = "0.15.2", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } base58 = { version = "0.1.0", optional = true } rand = { version = "0.7.2", optional = true } -substrate-bip39 = { version = "0.3.1", optional = true } +substrate-bip39 = { version = "0.4.1", optional = true } tiny-bip39 = { version = "0.7", optional = true } regex = { version = "1.3.1", optional = true } num-traits = { version = "0.2.8", default-features = false } @@ -33,14 +33,14 @@ parking_lot = { version = "0.10.0", optional = true } sp-debug-derive = { version = "2.0.0-alpha.4", path = "../debug-derive" } sp-externalities = { version = "0.8.0-alpha.4", optional = true, path = "../externalities" } sp-storage = { version = "2.0.0-alpha.4", default-features = false, path = "../storage" } -parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } futures = { version = "0.3.1", optional = true } # full crypto ed25519-dalek = { version = "1.0.0-pre.3", default-features = false, features = ["u64_backend", "alloc"], optional = true } blake2-rfc = { version = "0.2.18", default-features = false, optional = true } tiny-keccak = { version = "2.0.1", features = ["keccak"], optional = true } -schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated", "u64_backend"], default-features = false, optional = true } +schnorrkel = { version = "0.9", features = ["preaudit_deprecated", "u64_backend"], default-features = false, optional = true } sha2 = { version = "0.8.0", default-features = false, optional = true } hex = { version = "0.4", default-features = false, optional = true } twox-hash = { version = "1.5.0", default-features = false, optional = true } @@ -75,7 +75,6 @@ std = [ "primitive-types/serde", "primitive-types/byteorder", "primitive-types/rustc-hex", - "primitive-types/libc", "impl-serde", "codec/std", "hash256-std-hasher/std", diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 06f25c45dd..880306380e 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -16,7 +16,7 @@ sp-runtime-interface-proc-macro = { version = "2.0.0-alpha.4", path = "proc-macr sp-externalities = { version = "0.8.0-alpha.4", optional = true, path = "../externalities" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } static_assertions = "1.0.0" -primitive-types = { version = "0.6.2", default-features = false } +primitive-types = { version = "0.7.0", default-features = false } [dev-dependencies] sp-runtime-interface-test-wasm = { version = "2.0.0-dev", path = "test-wasm" } diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index af71aed703..09a031b39d 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -23,7 +23,7 @@ paste = "0.1.6" rand = { version = "0.7.2", optional = true } impl-trait-for-tuples = "0.1.3" sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../inherents" } -parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } hash256-std-hasher = { version = "0.15.2", default-features = false } [dev-dependencies] diff --git a/primitives/test-primitives/Cargo.toml b/primitives/test-primitives/Cargo.toml index 41b2b52e2f..fa48bd85ac 100644 --- a/primitives/test-primitives/Cargo.toml +++ b/primitives/test-primitives/Cargo.toml @@ -14,7 +14,7 @@ codec = { package = "parity-scale-codec", version = "1.2.0", default-features = sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } -parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [features] default = [ diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index a1601c085e..33470a20e2 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -40,7 +40,7 @@ sc-client = { version = "0.8.0-alpha.4", optional = true, path = "../../client" sp-trie = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/trie" } sp-transaction-pool = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/transaction-pool" } trie-db = { version = "0.20.0", default-features = false } -parity-util-mem = { version = "0.5.2", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] sc-block-builder = { version = "0.8.0-alpha.4", path = "../../client/block-builder" } diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 45bab46239..10aa17a875 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -18,11 +18,11 @@ console_log = "0.1.2" js-sys = "0.3.34" wasm-bindgen = "0.2.57" wasm-bindgen-futures = "0.4.7" -kvdb-web = "0.4" +kvdb-web = "0.5" sc-informant = { version = "0.8.0-alpha.4", path = "../../client/informant" } sc-service = { version = "0.8.0-alpha.4", path = "../../client/service", default-features = false } -sc-network = { path = "../../client/network" , version = "0.8.0-alpha.4"} -sc-chain-spec = { path = "../../client/chain-spec" , version = "2.0.0-alpha.4"} +sc-network = { path = "../../client/network", version = "0.8.0-alpha.4"} +sc-chain-spec = { path = "../../client/chain-spec", version = "2.0.0-alpha.4"} # Imported just for the `no_cc` feature clear_on_drop = { version = "0.2.3", features = ["no_cc"] } -- GitLab From 9af109df21520ca852825206f35280d2dfd35aac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 19 Mar 2020 17:24:31 +0100 Subject: [PATCH 020/300] Make `ChainSpec` implement `Send` (#5315) --- client/chain-spec/src/chain_spec.rs | 2 +- client/chain-spec/src/lib.rs | 2 +- client/service/test/src/lib.rs | 10 +++++----- utils/browser/src/lib.rs | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/client/chain-spec/src/chain_spec.rs b/client/chain-spec/src/chain_spec.rs index 008af6f7e0..33f217cb4e 100644 --- a/client/chain-spec/src/chain_spec.rs +++ b/client/chain-spec/src/chain_spec.rs @@ -318,7 +318,7 @@ impl ChainSpec { impl crate::ChainSpec for ChainSpec where G: RuntimeGenesis, - E: GetExtension + serde::Serialize + Clone, + E: GetExtension + serde::Serialize + Clone + Send, { fn boot_nodes(&self) -> &[String] { ChainSpec::boot_nodes(self) diff --git a/client/chain-spec/src/lib.rs b/client/chain-spec/src/lib.rs index 509524fd0a..353c386f36 100644 --- a/client/chain-spec/src/lib.rs +++ b/client/chain-spec/src/lib.rs @@ -125,7 +125,7 @@ pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {} impl RuntimeGenesis for T {} /// Common interface to `GenericChainSpec` -pub trait ChainSpec: BuildStorage { +pub trait ChainSpec: BuildStorage + Send { /// Spec name. fn name(&self) -> &str; /// Spec id. diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 0a29bc7bf2..537d446477 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -131,7 +131,7 @@ where F: Send + 'static, L: Send +'static, U: Clone + Send + 'static } } -fn node_config ( +fn node_config ( index: usize, spec: &GenericChainSpec, role: Roles, @@ -219,7 +219,7 @@ fn node_config TestNet where F: AbstractService, L: AbstractService, - E: ChainSpecExtension + Clone + 'static, + E: ChainSpecExtension + Clone + 'static + Send, G: RuntimeGenesis + 'static, { fn new( @@ -324,7 +324,7 @@ pub fn connectivity( full_builder: Fb, light_builder: Lb, ) where - E: ChainSpecExtension + Clone + 'static, + E: ChainSpecExtension + Clone + 'static + Send, G: RuntimeGenesis + 'static, Fb: Fn(Configuration) -> Result, F: AbstractService, @@ -432,7 +432,7 @@ pub fn sync( B: FnMut(&F, &mut U), ExF: FnMut(&F, &U) -> ::Extrinsic, U: Clone + Send + 'static, - E: ChainSpecExtension + Clone + 'static, + E: ChainSpecExtension + Clone + 'static + Send, G: RuntimeGenesis + 'static, { const NUM_FULL_NODES: usize = 10; @@ -503,7 +503,7 @@ pub fn consensus( F: AbstractService, Lb: Fn(Configuration) -> Result, L: AbstractService, - E: ChainSpecExtension + Clone + 'static, + E: ChainSpecExtension + Clone + 'static + Send, G: RuntimeGenesis + 'static, { const NUM_FULL_NODES: usize = 10; diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index c9c159efe3..3a0162bd90 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -38,7 +38,7 @@ pub async fn browser_configuration(chain_spec: GenericChainSpec) -> Result> where G: RuntimeGenesis + 'static, - E: Extension + 'static, + E: Extension + 'static + Send, { let name = chain_spec.name().to_string(); -- GitLab From 63cf6bd01d20e06009c6c96814d9ef1984418cb1 Mon Sep 17 00:00:00 2001 From: cheme Date: Thu, 19 Mar 2020 20:06:23 +0100 Subject: [PATCH 021/300] remove old rpc --- client/rpc-api/src/state/mod.rs | 48 --------------- client/rpc/src/state/mod.rs | 93 ----------------------------- client/rpc/src/state/state_full.rs | 60 +------------------ client/rpc/src/state/state_light.rs | 52 +--------------- 4 files changed, 2 insertions(+), 251 deletions(-) diff --git a/client/rpc-api/src/state/mod.rs b/client/rpc-api/src/state/mod.rs index e94df46736..fd709788e5 100644 --- a/client/rpc-api/src/state/mod.rs +++ b/client/rpc-api/src/state/mod.rs @@ -72,54 +72,6 @@ pub trait StateApi { #[rpc(name = "state_getStorageSize", alias("state_getStorageSizeAt"))] fn storage_size(&self, key: StorageKey, hash: Option) -> FutureResult>; - /// Returns the keys with prefix from a child storage, leave empty to get all the keys - /// This method is deprecated in favor of `childstate_getChildKeys`. - #[rpc(name = "state_getChildKeys")] - fn child_storage_keys( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - prefix: StorageKey, - hash: Option - ) -> FutureResult>; - - /// Returns a child storage entry at a specific block's state. - /// This method is deprecated in favor of `childstate_getChildStorage`. - #[rpc(name = "state_getChildStorage")] - fn child_storage( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - hash: Option - ) -> FutureResult>; - - /// Returns the hash of a child storage entry at a block's state. - /// This method is deprecated in favor of `childstate_getChildStorageHash`. - #[rpc(name = "state_getChildStorageHash")] - fn child_storage_hash( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - hash: Option - ) -> FutureResult>; - - /// Returns the size of a child storage entry at a block's state. - /// This method is deprecated in favor of `childstate_getChildStorageSize`. - #[rpc(name = "state_getChildStorageSize")] - fn child_storage_size( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - hash: Option - ) -> FutureResult>; - /// Returns the runtime metadata as an opaque blob. #[rpc(name = "state_getMetadata")] fn metadata(&self, hash: Option) -> FutureResult; diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index 29ad2f7538..1805ac5351 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -104,49 +104,6 @@ pub trait StateBackend: Send + Sync + 'static .map(|x| x.map(|x| x.0.len() as u64))) } - /// Returns the keys with prefix from a child storage, leave empty to get all the keys - fn child_storage_keys( - &self, - block: Option, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - prefix: StorageKey, - ) -> FutureResult>; - - /// Returns a child storage entry at a specific block's state. - fn child_storage( - &self, - block: Option, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult>; - - /// Returns the hash of a child storage entry at a block's state. - fn child_storage_hash( - &self, - block: Option, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult>; - - /// Returns the size of a child storage entry at a block's state. - fn child_storage_size( - &self, - block: Option, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult> { - Box::new(self.child_storage(block, child_storage_key, child_info, child_type, key) - .map(|x| x.map(|x| x.0.len() as u64))) - } - /// Returns the runtime metadata as an opaque blob. fn metadata(&self, block: Option) -> FutureResult; @@ -309,50 +266,6 @@ impl StateApi for State self.backend.storage_size(block, key) } - fn child_storage( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - block: Option - ) -> FutureResult> { - self.backend.child_storage(block, child_storage_key, child_info, child_type, key) - } - - fn child_storage_keys( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key_prefix: StorageKey, - block: Option - ) -> FutureResult> { - self.backend.child_storage_keys(block, child_storage_key, child_info, child_type, key_prefix) - } - - fn child_storage_hash( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - block: Option - ) -> FutureResult> { - self.backend.child_storage_hash(block, child_storage_key, child_info, child_type, key) - } - - fn child_storage_size( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - block: Option - ) -> FutureResult> { - self.backend.child_storage_size(block, child_storage_key, child_info, child_type, key) - } - fn metadata(&self, block: Option) -> FutureResult { self.backend.metadata(block) } @@ -488,12 +401,6 @@ impl ChildStateApi for ChildState } } -const CHILD_RESOLUTION_ERROR: &str = "Unexpected child info and type"; - -fn child_resolution_error() -> Error { - client_err(sp_blockchain::Error::Msg(CHILD_RESOLUTION_ERROR.to_string())) -} - fn client_err(err: sp_blockchain::Error) -> Error { Error::Client(Box::new(err)) } diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index d27086a02c..599b8af349 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -39,8 +39,7 @@ use sp_runtime::{ use sp_api::{Metadata, ProvideRuntimeApi, CallApiAt}; -use super::{StateBackend, ChildStateBackend, error::{FutureResult, Error, Result}, - client_err, child_resolution_error}; +use super::{StateBackend, ChildStateBackend, error::{FutureResult, Error, Result}, client_err}; use std::marker::PhantomData; use sc_client_api::{CallExecutor, StorageProvider, ExecutorProvider}; @@ -307,63 +306,6 @@ impl StateBackend for FullState, - child_storage_key: StorageKey, - _child_info: StorageKey, - child_type: u32, - prefix: StorageKey, - ) -> FutureResult> { - if child_type != 1 { - return Box::new(result(Err(child_resolution_error()))); - } - ChildStateBackend::storage_keys( - self, - block, - child_storage_key, - prefix, - ) - } - - fn child_storage( - &self, - block: Option, - child_storage_key: StorageKey, - _child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult> { - if child_type != 1 { - return Box::new(result(Err(child_resolution_error()))); - } - ChildStateBackend::storage( - self, - block, - child_storage_key, - key, - ) - } - - fn child_storage_hash( - &self, - block: Option, - child_storage_key: StorageKey, - _child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult> { - if child_type != 1 { - return Box::new(result(Err(child_resolution_error()))); - } - ChildStateBackend::storage_hash( - self, - block, - child_storage_key, - key, - ) - } - fn metadata(&self, block: Option) -> FutureResult { Box::new(result( self.block_or_best(block) diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index 6e1aa6bc1f..22bee62950 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -53,8 +53,7 @@ use sp_core::{ use sp_version::RuntimeVersion; use sp_runtime::{generic::BlockId, traits::{Block as BlockT, HashFor}}; -use super::{StateBackend, ChildStateBackend, error::{FutureResult, Error}, client_err, - child_resolution_error}; +use super::{StateBackend, ChildStateBackend, error::{FutureResult, Error}, client_err}; /// Storage data map of storage keys => (optional) storage value. type StorageMap = HashMap>; @@ -242,55 +241,6 @@ impl StateBackend for LightState, - _child_storage_key: StorageKey, - _child_info: StorageKey, - _child_type: u32, - _prefix: StorageKey, - ) -> FutureResult> { - Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) - } - - fn child_storage( - &self, - block: Option, - child_storage_key: StorageKey, - _child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult> { - if child_type != 1 { - return Box::new(result(Err(child_resolution_error()))); - } - ChildStateBackend::storage( - self, - block, - child_storage_key, - key, - ) - } - - fn child_storage_hash( - &self, - block: Option, - child_storage_key: StorageKey, - _child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult> { - if child_type != 1 { - return Box::new(result(Err(child_resolution_error()))); - } - ChildStateBackend::storage_hash( - self, - block, - child_storage_key, - key, - ) - } - fn metadata(&self, block: Option) -> FutureResult { let metadata = self.call(block, "Metadata_metadata".into(), Bytes(Vec::new())) .and_then(|metadata| OpaqueMetadata::decode(&mut &metadata.0[..]) -- GitLab From c98ce9712934331bebe367c4b73ee256ef4f7830 Mon Sep 17 00:00:00 2001 From: lwshang Date: Thu, 19 Mar 2020 17:05:49 -0400 Subject: [PATCH 022/300] Prompt error if vanity pattern is not valid base58 (#5308) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Prompt error if vanity pattern is not valid base58 * Update bin/utils/subkey/src/vanity.rs * Add tests for validating pattern of subkey vanity Co-authored-by: Bastian Köcher --- bin/utils/subkey/src/vanity.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/bin/utils/subkey/src/vanity.rs b/bin/utils/subkey/src/vanity.rs index 8a167cd062..f921470946 100644 --- a/bin/utils/subkey/src/vanity.rs +++ b/bin/utils/subkey/src/vanity.rs @@ -62,6 +62,12 @@ fn calculate_score(_desired: &str, key: &str) -> usize { 0 } +/// Validate whether the char is allowed to be used in base58. +/// num 0, lower l, upper I and O are not allowed. +fn validate_base58(c :char) -> bool { + c.is_alphanumeric() && !"0lIO".contains(c) +} + pub(super) fn generate_key(desired: &str) -> Result, &'static str> where PublicOf: PublicT, { @@ -69,6 +75,11 @@ pub(super) fn generate_key(desired: &str) -> Result, &'sta return Err("Pattern must not be empty"); } + if !desired.chars().all(validate_base58) { + return Err("Pattern can only contains valid characters in base58 \ + (all alphanumeric except for 0, l, I and O)"); + } + eprintln!("Generating key containing pattern '{}'", desired); let top = 45 + (desired.len() * 48); @@ -162,6 +173,22 @@ mod tests { ); } + #[test] + fn test_invalid_pattern() { + assert!(generate_key::("").is_err()); + assert!(generate_key::("0").is_err()); + assert!(generate_key::("l").is_err()); + assert!(generate_key::("I").is_err()); + assert!(generate_key::("O").is_err()); + assert!(generate_key::("!").is_err()); + } + + #[test] + fn test_valid_pattern() { + assert!(generate_key::("o").is_ok()); + assert!(generate_key::("L").is_ok()); + } + #[cfg(feature = "bench")] #[bench] fn bench_paranoiac(b: &mut Bencher) { -- GitLab From 653c89f6bb4e069bdf2af8be97b7c6b01bc62921 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Thu, 19 Mar 2020 23:01:13 +0100 Subject: [PATCH 023/300] Remove migration code. (#5291) * Remove migration code. * Fix cargo * Bump spec version --- .../pallets/template/src/mock.rs | 2 +- bin/node-template/runtime/src/lib.rs | 2 +- bin/node/runtime/Cargo.toml | 10 +-- bin/node/runtime/src/lib.rs | 3 +- client/consensus/babe/src/aux_schema.rs | 77 +------------------ client/consensus/epochs/src/lib.rs | 2 - client/consensus/epochs/src/migration.rs | 55 ------------- frame/assets/src/lib.rs | 2 +- frame/aura/src/mock.rs | 2 +- frame/authority-discovery/src/lib.rs | 2 +- frame/authorship/src/lib.rs | 2 +- frame/babe/src/lib.rs | 6 -- frame/babe/src/mock.rs | 2 +- frame/balances/src/lib.rs | 10 +-- frame/balances/src/tests_composite.rs | 2 +- frame/balances/src/tests_local.rs | 2 +- frame/benchmarking/src/tests.rs | 2 +- frame/collective/src/lib.rs | 17 +--- frame/contracts/src/tests.rs | 2 +- frame/democracy/src/lib.rs | 34 +------- frame/elections-phragmen/src/lib.rs | 11 +-- frame/elections/src/mock.rs | 2 +- frame/example-offchain-worker/src/tests.rs | 2 +- frame/example/src/lib.rs | 2 +- frame/executive/src/lib.rs | 2 +- frame/finality-tracker/src/lib.rs | 2 +- frame/generic-asset/src/lib.rs | 2 +- frame/generic-asset/src/mock.rs | 2 +- frame/grandpa/Cargo.toml | 1 - frame/grandpa/src/lib.rs | 32 -------- frame/grandpa/src/mock.rs | 2 +- frame/grandpa/src/tests.rs | 18 ----- frame/identity/src/lib.rs | 15 +--- frame/im-online/src/lib.rs | 27 ------- frame/im-online/src/mock.rs | 2 +- frame/indices/src/mock.rs | 2 +- frame/membership/src/lib.rs | 2 +- frame/nicks/src/lib.rs | 2 +- frame/offences/src/mock.rs | 2 +- frame/randomness-collective-flip/src/lib.rs | 2 +- frame/recovery/src/lib.rs | 8 -- frame/recovery/src/mock.rs | 2 +- frame/scored-pool/src/mock.rs | 2 +- frame/session/src/historical.rs | 20 +---- frame/session/src/lib.rs | 13 ---- frame/session/src/mock.rs | 2 +- frame/society/src/lib.rs | 11 +-- frame/society/src/mock.rs | 2 +- frame/staking/Cargo.toml | 1 - frame/staking/src/lib.rs | 29 ------- frame/staking/src/mock.rs | 2 +- frame/support/src/traits.rs | 7 -- frame/system/benches/bench.rs | 2 +- frame/system/src/lib.rs | 32 +------- frame/system/src/migration.rs | 37 --------- frame/timestamp/src/lib.rs | 2 +- frame/transaction-payment/src/lib.rs | 2 +- frame/treasury/src/lib.rs | 16 +--- frame/utility/src/lib.rs | 2 +- frame/vesting/src/lib.rs | 13 ++-- test-utils/runtime/src/lib.rs | 2 +- 61 files changed, 61 insertions(+), 514 deletions(-) delete mode 100644 client/consensus/epochs/src/migration.rs delete mode 100644 frame/system/src/migration.rs diff --git a/bin/node-template/pallets/template/src/mock.rs b/bin/node-template/pallets/template/src/mock.rs index 3179b56b22..2ea81ffb45 100644 --- a/bin/node-template/pallets/template/src/mock.rs +++ b/bin/node-template/pallets/template/src/mock.rs @@ -40,7 +40,7 @@ impl system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } impl Trait for Test { diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 707799eab4..0414759a5a 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -162,7 +162,7 @@ impl system::Trait for Runtime { /// This type is being generated by `construct_runtime!`. type ModuleToIndex = ModuleToIndex; /// What to do if a new account is created. - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); /// What to do if an account is fully reaped from the system. type OnKilledAccount = (); /// The data to be stored in an account. diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 90ef3833a3..a5fad30837 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -60,8 +60,8 @@ pallet-randomness-collective-flip = { version = "2.0.0-alpha.4", default-feature pallet-recovery = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/recovery" } pallet-session = { version = "2.0.0-alpha.4", features = ["historical"], path = "../../../frame/session", default-features = false } pallet-session-benchmarking = { version = "2.0.0-alpha.4", path = "../../../frame/session/benchmarking", default-features = false, optional = true } -pallet-staking = { version = "2.0.0-alpha.4", features = ["migrate"], path = "../../../frame/staking", default-features = false } -pallet-staking-reward-curve = { version = "2.0.0-alpha.4", path = "../../../frame/staking/reward-curve" } +pallet-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/staking" } +pallet-staking-reward-curve = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/staking/reward-curve" } pallet-sudo = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/sudo" } pallet-society = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/society" } pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/timestamp" } @@ -135,10 +135,8 @@ std = [ ] runtime-benchmarks = [ "frame-benchmarking", - "pallet-balances/runtime-benchmarks", - "pallet-identity/runtime-benchmarks", - "pallet-session-benchmarking", "pallet-timestamp/runtime-benchmarks", + "pallet-identity/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", - "pallet-staking/runtime-benchmarks", ] diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 5468ee0fb3..b27ba6c9ac 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -82,7 +82,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 237, + spec_version: 238, impl_version: 0, apis: RUNTIME_API_VERSIONS, }; @@ -140,7 +140,6 @@ impl frame_system::Trait for Runtime { type Version = Version; type ModuleToIndex = ModuleToIndex; type AccountData = pallet_balances::AccountData; - type MigrateAccount = (Balances, Identity, Democracy, Elections, ImOnline, Recovery, Session, Society, Staking, Vesting); type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/client/consensus/babe/src/aux_schema.rs b/client/consensus/babe/src/aux_schema.rs index 6f69e65940..3ca2f560d4 100644 --- a/client/consensus/babe/src/aux_schema.rs +++ b/client/consensus/babe/src/aux_schema.rs @@ -25,7 +25,7 @@ use sc_client_api::backend::AuxStore; use sp_blockchain::{Result as ClientResult, Error as ClientError}; use sp_runtime::traits::Block as BlockT; use sp_consensus_babe::BabeBlockWeight; -use sc_consensus_epochs::{EpochChangesFor, SharedEpochChanges, migration::EpochChangesForV0}; +use sc_consensus_epochs::{EpochChangesFor, SharedEpochChanges}; use crate::Epoch; const BABE_EPOCH_CHANGES_VERSION: &[u8] = b"babe_epoch_changes_version"; @@ -57,11 +57,7 @@ pub(crate) fn load_epoch_changes( let version = load_decode::<_, u32>(backend, BABE_EPOCH_CHANGES_VERSION)?; let maybe_epoch_changes = match version { - None => load_decode::<_, EpochChangesForV0>( - backend, - BABE_EPOCH_CHANGES_KEY, - )?.map(|v0| v0.migrate()), - Some(BABE_EPOCH_CHANGES_CURRENT_VERSION) => load_decode::<_, EpochChangesFor>( + None | Some(BABE_EPOCH_CHANGES_CURRENT_VERSION) => load_decode::<_, EpochChangesFor>( backend, BABE_EPOCH_CHANGES_KEY, )?, @@ -127,72 +123,3 @@ pub(crate) fn load_block_weight( ) -> ClientResult> { load_decode(backend, block_weight_key(block_hash).as_slice()) } - -#[cfg(test)] -mod test { - use super::*; - use crate::Epoch; - use fork_tree::ForkTree; - use substrate_test_runtime_client; - use sp_core::H256; - use sp_runtime::traits::NumberFor; - use sc_consensus_epochs::{PersistedEpoch, PersistedEpochHeader, EpochHeader}; - use sp_consensus::Error as ConsensusError; - use sc_network_test::Block as TestBlock; - - #[test] - fn load_decode_from_v0_epoch_changes() { - let epoch = Epoch { - start_slot: 0, - authorities: vec![], - randomness: [0; 32], - epoch_index: 1, - duration: 100, - }; - let client = substrate_test_runtime_client::new(); - let mut v0_tree = ForkTree::, _>::new(); - v0_tree.import::<_, ConsensusError>( - Default::default(), - Default::default(), - PersistedEpoch::Regular(epoch), - &|_, _| Ok(false), // Test is single item only so this can be set to false. - ).unwrap(); - - client.insert_aux( - &[(BABE_EPOCH_CHANGES_KEY, - &EpochChangesForV0::::from_raw(v0_tree).encode()[..])], - &[], - ).unwrap(); - - assert_eq!( - load_decode::<_, u32>(&client, BABE_EPOCH_CHANGES_VERSION).unwrap(), - None, - ); - - let epoch_changes = load_epoch_changes::(&client).unwrap(); - - assert!( - epoch_changes.lock() - .tree() - .iter() - .map(|(_, _, epoch)| epoch.clone()) - .collect::>() == - vec![PersistedEpochHeader::Regular(EpochHeader { - start_slot: 0, - end_slot: 100, - })], - ); // PersistedEpochHeader does not implement Debug, so we use assert! directly. - - write_epoch_changes::( - &epoch_changes.lock(), - |values| { - client.insert_aux(values, &[]).unwrap(); - }, - ); - - assert_eq!( - load_decode::<_, u32>(&client, BABE_EPOCH_CHANGES_VERSION).unwrap(), - Some(1), - ); - } -} diff --git a/client/consensus/epochs/src/lib.rs b/client/consensus/epochs/src/lib.rs index 001c172b34..d5816d960c 100644 --- a/client/consensus/epochs/src/lib.rs +++ b/client/consensus/epochs/src/lib.rs @@ -16,8 +16,6 @@ //! Generic utilities for epoch-based consensus engines. -pub mod migration; - use std::{sync::Arc, ops::Add, collections::BTreeMap, borrow::{Borrow, BorrowMut}}; use parking_lot::Mutex; use codec::{Encode, Decode}; diff --git a/client/consensus/epochs/src/migration.rs b/client/consensus/epochs/src/migration.rs deleted file mode 100644 index e4717b5584..0000000000 --- a/client/consensus/epochs/src/migration.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Migration types for epoch changes. - -use std::collections::BTreeMap; -use codec::{Encode, Decode}; -use fork_tree::ForkTree; -use sp_runtime::traits::{Block as BlockT, NumberFor}; -use crate::{Epoch, EpochChanges, PersistedEpoch, PersistedEpochHeader}; - -/// Legacy definition of epoch changes. -#[derive(Clone, Encode, Decode)] -pub struct EpochChangesV0 { - inner: ForkTree>, -} - -/// Type alias for legacy definition of epoch changes. -pub type EpochChangesForV0 = EpochChangesV0<::Hash, NumberFor, Epoch>; - -impl EpochChangesV0 where - Hash: PartialEq + Ord + Copy, - Number: Ord + Copy, -{ - /// Create a new value of this type from raw. - pub fn from_raw(inner: ForkTree>) -> Self { - Self { inner } - } - - /// Migrate the type into current epoch changes definition. - pub fn migrate(self) -> EpochChanges { - let mut epochs = BTreeMap::new(); - - let inner = self.inner.map(&mut |hash, number, data| { - let header = PersistedEpochHeader::from(&data); - epochs.insert((*hash, *number), data); - header - }); - - EpochChanges { inner, epochs } - } -} diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index af74f90461..838d21a462 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -294,7 +294,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } impl Trait for Test { diff --git a/frame/aura/src/mock.rs b/frame/aura/src/mock.rs index b191e1d05d..05a161ee49 100644 --- a/frame/aura/src/mock.rs +++ b/frame/aura/src/mock.rs @@ -62,7 +62,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index 0479e710c5..8ee4931e48 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -158,7 +158,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 1869d408ca..d3c1bf752a 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -432,7 +432,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 8013e0cd45..29e8625419 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -188,12 +188,6 @@ decl_module! { Self::deposit_vrf_output(&vrf_output); } } - - fn on_runtime_upgrade() { - for i in 0..=SegmentIndex::get() { - UnderConstruction::migrate_key_from_blake(i); - } - } } } diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index 63943593b8..2ec083728e 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -65,7 +65,7 @@ impl frame_system::Trait for Test { type MaximumBlockLength = MaximumBlockLength; type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 6e707caaa1..b83530d635 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -167,7 +167,7 @@ use frame_support::{ Currency, OnKilledAccount, OnUnbalanced, TryDrop, StoredMap, WithdrawReason, WithdrawReasons, LockIdentifier, LockableCurrency, ExistenceRequirement, Imbalance, SignedImbalance, ReservableCurrency, Get, ExistenceRequirement::KeepAlive, - ExistenceRequirement::AllowDeath, IsDeadAccount, BalanceStatus as Status, MigrateAccount, + ExistenceRequirement::AllowDeath, IsDeadAccount, BalanceStatus as Status, } }; use sp_runtime::{ @@ -531,12 +531,6 @@ decl_module! { } } -impl, I: Instance> MigrateAccount for Module { - fn migrate_account(account: &T::AccountId) { - Locks::::migrate_key_from_blake(account); - } -} - impl, I: Instance> Module { // PRIVATE MUTABLES @@ -856,7 +850,7 @@ impl, I: Instance> frame_system::Trait for ElevatedTrait { type AvailableBlockRatio = T::AvailableBlockRatio; type Version = T::Version; type ModuleToIndex = T::ModuleToIndex; - type MigrateAccount = (); type OnNewAccount = T::OnNewAccount; + type OnNewAccount = T::OnNewAccount; type OnKilledAccount = T::OnKilledAccount; type AccountData = T::AccountData; } diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index 8bf31ec36c..3a5c2178f8 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -66,7 +66,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = super::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } parameter_types! { diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index c6beec0782..861c197212 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -66,7 +66,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = super::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = Module; } parameter_types! { diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index 6e837ec241..4327476c4a 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -71,7 +71,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 30b1b19974..8b46856cbb 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -168,17 +168,6 @@ decl_error! { } } -mod migration { - use super::*; - - pub fn migrate, I: Instance>() { - for p in Proposals::::get().into_iter() { - ProposalOf::::migrate_key_from_blake(&p); - Voting::::migrate_key_from_blake(&p); - } - } -} - // Note: this module is not benchmarked. The weights are obtained based on the similarity of the // executed logic with other democracy function. Note that councillor operations are assigned to the // operational class. @@ -188,10 +177,6 @@ decl_module! { fn deposit_event() = default; - fn on_runtime_upgrade() { - migration::migrate::(); - } - /// Set the collective's membership. /// /// - `new_members`: The new member list. Be nice to the chain and @@ -550,7 +535,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } impl Trait for Test { diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index d05d251b23..165e23e8b8 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -116,7 +116,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = Contracts; } impl pallet_balances::Trait for Test { diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index cbc766499f..04aef6fe41 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -170,7 +170,6 @@ use frame_system::{self as system, ensure_signed, ensure_root}; mod vote_threshold; pub use vote_threshold::{Approved, VoteThreshold}; -use frame_support::traits::MigrateAccount; const DEMOCRACY_ID: LockIdentifier = *b"democrac"; @@ -584,41 +583,10 @@ decl_error! { } } -impl MigrateAccount for Module { - fn migrate_account(a: &T::AccountId) { - Proxy::::migrate_key_from_blake(a); - Locks::::migrate_key_from_blake(a); - Delegations::::migrate_key_from_blake(a); - for i in LowestUnbaked::get()..ReferendumCount::get() { - VoteOf::::migrate_key_from_blake((i, a)); - } - } -} - -mod migration { - use super::*; - pub fn migrate() { - Blacklist::::remove_all(); - Cancellations::::remove_all(); - for i in LowestUnbaked::get()..ReferendumCount::get() { - VotersFor::::migrate_key_from_blake(i); - ReferendumInfoOf::::migrate_key_from_blake(i); - } - for (p, h, _) in PublicProps::::get().into_iter() { - DepositOf::::migrate_key_from_blake(p); - Preimages::::migrate_key_from_blake(h); - } - } -} - decl_module! { pub struct Module for enum Call where origin: T::Origin { type Error = Error; - fn on_runtime_upgrade() { - migration::migrate::(); - } - /// The minimum period of locking and the period between a proposal being approved and enacted. /// /// It should generally be a little more than the unstake period to ensure that @@ -1639,7 +1607,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } parameter_types! { diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index ac85b3047d..54bf801bbd 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -95,7 +95,6 @@ use frame_support::{ }; use sp_phragmen::ExtendedBalance; use frame_system::{self as system, ensure_signed, ensure_root}; -use frame_support::traits::MigrateAccount; const MODULE_ID: LockIdentifier = *b"phrelect"; @@ -474,14 +473,6 @@ decl_event!( } ); -impl MigrateAccount for Module { - fn migrate_account(a: &T::AccountId) { - if StakeOf::::migrate_key_from_blake(a).is_some() { - VotesOf::::migrate_key_from_blake(a); - } - } -} - impl Module { /// Attempts to remove a member `who`. If a runner up exists, it is used as the replacement. /// Otherwise, `Ok(false)` is returned to signal the caller. @@ -825,7 +816,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index 2a5e5fefbd..b82e73d512 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -55,7 +55,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/example-offchain-worker/src/tests.rs b/frame/example-offchain-worker/src/tests.rs index 5e086aa3a6..9b6a567a17 100644 --- a/frame/example-offchain-worker/src/tests.rs +++ b/frame/example-offchain-worker/src/tests.rs @@ -66,7 +66,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 62e46e9cb2..d6036b3af8 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -731,7 +731,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } parameter_types! { diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 8fbcb3bc60..117607d9b6 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -481,7 +481,7 @@ mod tests { type Version = RuntimeVersion; type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } parameter_types! { diff --git a/frame/finality-tracker/src/lib.rs b/frame/finality-tracker/src/lib.rs index 953861dede..c7d5ad30d9 100644 --- a/frame/finality-tracker/src/lib.rs +++ b/frame/finality-tracker/src/lib.rs @@ -262,7 +262,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } parameter_types! { diff --git a/frame/generic-asset/src/lib.rs b/frame/generic-asset/src/lib.rs index 29dbe3e781..3cb48ad18a 100644 --- a/frame/generic-asset/src/lib.rs +++ b/frame/generic-asset/src/lib.rs @@ -1123,7 +1123,7 @@ impl frame_system::Trait for ElevatedTrait { type Version = T::Version; type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } impl Trait for ElevatedTrait { diff --git a/frame/generic-asset/src/mock.rs b/frame/generic-asset/src/mock.rs index 8daca2da38..8db140d90c 100644 --- a/frame/generic-asset/src/mock.rs +++ b/frame/generic-asset/src/mock.rs @@ -63,7 +63,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/grandpa/Cargo.toml b/frame/grandpa/Cargo.toml index 1e64f66a6a..cca1fee0a5 100644 --- a/frame/grandpa/Cargo.toml +++ b/frame/grandpa/Cargo.toml @@ -39,4 +39,3 @@ std = [ "pallet-session/std", "pallet-finality-tracker/std", ] -migrate-authorities = [] diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index ab8c384dfb..dd0101e5f6 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -151,13 +151,6 @@ decl_error! { decl_storage! { trait Store for Module as GrandpaFinality { - /// DEPRECATED - /// - /// This used to store the current authority set, which has been migrated to the well-known - /// GRANDPA_AUTHORITIES_KEY unhashed key. - #[cfg(feature = "migrate-authorities")] - pub(crate) Authorities get(fn authorities): AuthorityList; - /// State of the current authority set. State get(fn state): StoredState = StoredState::Live; @@ -184,15 +177,6 @@ decl_storage! { } } -mod migration { - use super::*; - pub fn migrate() { - for i in 0..=CurrentSetId::get() { - SetIdSession::migrate_key_from_blake(i); - } - } -} - decl_module! { pub struct Module for enum Call where origin: T::Origin { type Error = Error; @@ -205,15 +189,6 @@ decl_module! { // FIXME: https://github.com/paritytech/substrate/issues/1112 } - fn on_runtime_upgrade() { - migration::migrate::(); - } - - fn on_initialize() { - #[cfg(feature = "migrate-authorities")] - Self::migrate_authorities(); - } - fn on_finalize(block_number: T::BlockNumber) { // check for scheduled pending authority set changes if let Some(pending_change) = >::get() { @@ -384,13 +359,6 @@ impl Module { Self::set_grandpa_authorities(authorities); } } - - #[cfg(feature = "migrate-authorities")] - fn migrate_authorities() { - if Authorities::exists() { - Self::set_grandpa_authorities(&Authorities::take()); - } - } } impl Module { diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index 24d7feab49..8b94becd5a 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -66,7 +66,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/grandpa/src/tests.rs b/frame/grandpa/src/tests.rs index ff3841b8d4..19e42a301f 100644 --- a/frame/grandpa/src/tests.rs +++ b/frame/grandpa/src/tests.rs @@ -318,21 +318,3 @@ fn time_slot_have_sane_ord() { ]; assert!(FIXTURE.windows(2).all(|f| f[0] < f[1])); } - -#[test] -#[cfg(feature = "migrate-authorities")] -fn authorities_migration() { - use sp_runtime::traits::OnInitialize; - - with_externalities(&mut new_test_ext(vec![]), || { - let authorities = to_authorities(vec![(1, 1), (2, 1), (3, 1)]); - - Authorities::put(authorities.clone()); - assert!(Grandpa::grandpa_authorities().is_empty()); - - Grandpa::on_initialize(1); - - assert!(!Authorities::exists()); - assert_eq!(Grandpa::grandpa_authorities(), authorities); - }); -} diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index d3098dcde2..4cbd8c7a2b 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -77,7 +77,6 @@ use frame_support::{ weights::SimpleDispatchInfo, }; use frame_system::{self as system, ensure_signed, ensure_root}; -use frame_support::traits::MigrateAccount; #[cfg(feature = "runtime-benchmarks")] pub mod benchmarking; @@ -887,18 +886,6 @@ impl Module { } } -impl MigrateAccount for Module { - fn migrate_account(a: &T::AccountId) { - if IdentityOf::::migrate_key_from_blake(a).is_some() { - if let Some((_, subs)) = SubsOf::::migrate_key_from_blake(a) { - for sub in subs.into_iter() { - SuperOf::::migrate_key_from_blake(sub); - } - } - } - } -} - #[cfg(test)] mod tests { use super::*; @@ -949,7 +936,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } parameter_types! { diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 4d40decdfc..a0a16c46f3 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -95,7 +95,6 @@ use frame_support::{ }; use frame_system::{self as system, ensure_none}; use frame_system::offchain::SubmitUnsignedTransaction; -use frame_support::traits::MigrateAccount; pub mod sr25519 { mod app_sr25519 { @@ -303,38 +302,12 @@ decl_error! { } } -mod migration { - use super::*; - use frame_support::Blake2_256; - pub fn migrate() { - let current_index = >::current_index(); - let key_count = Keys::::get().len() as AuthIndex; - for i in 0..key_count { - ReceivedHeartbeats::migrate_keys::(current_index, i); - } - } -} - -impl MigrateAccount for Module { - fn migrate_account(a: &T::AccountId) { - use frame_support::Blake2_256; - let current_index = >::current_index(); - if let Ok(v) = a.using_encoded(|mut d| T::ValidatorId::decode(&mut d)) { - AuthoredBlocks::::migrate_keys::(current_index, v); - } - } -} - decl_module! { pub struct Module for enum Call where origin: T::Origin { type Error = Error; fn deposit_event() = default; - fn on_runtime_upgrade() { - migration::migrate::(); - } - fn heartbeat( origin, heartbeat: Heartbeat, diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index e0ee2547bf..78b6409d54 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -119,7 +119,7 @@ impl frame_system::Trait for Runtime { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/indices/src/mock.rs b/frame/indices/src/mock.rs index f5cd1009e6..355b3cc792 100644 --- a/frame/indices/src/mock.rs +++ b/frame/indices/src/mock.rs @@ -66,7 +66,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index e9fa5a0630..129f3c4003 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -321,7 +321,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } ord_parameter_types! { diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index ddfd71107f..2ab1789d39 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -286,7 +286,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } parameter_types! { diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index c617224716..a003ad6915 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -90,7 +90,7 @@ impl frame_system::Trait for Runtime { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index 525bbedb40..0ded7dd6b0 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -192,7 +192,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index d995606e52..d7f5127ee3 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -163,7 +163,6 @@ use frame_support::{ traits::{Currency, ReservableCurrency, Get, BalanceStatus}, }; use frame_system::{self as system, ensure_signed, ensure_root}; -use frame_support::traits::MigrateAccount; #[cfg(test)] mod mock; @@ -258,13 +257,6 @@ decl_storage! { } } -impl MigrateAccount for Module { - fn migrate_account(a: &T::AccountId) { - Recoverable::::migrate_key_from_blake(a); - Proxy::::migrate_key_from_blake(a); - } -} - decl_event! { /// Events type. pub enum Event where diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index 3eaba0d6c1..a5b7731c22 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -79,7 +79,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index f50e918ee6..a28b789137 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -71,7 +71,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/session/src/historical.rs b/frame/session/src/historical.rs index 848f6d5599..12b88b347c 100644 --- a/frame/session/src/historical.rs +++ b/frame/session/src/historical.rs @@ -67,25 +67,7 @@ decl_storage! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { - fn on_initialize(_n: T::BlockNumber) { - CachedObsolete::::remove_all(); - } - fn on_runtime_upgrade() { - migration::migrate::(); - } - } -} - -mod migration { - use super::*; - pub fn migrate() { - if let Some((begin, end)) = StoredRange::get() { - for i in begin..end { - HistoricalSessions::::migrate_key_from_blake(i); - } - } - } + pub struct Module for enum Call where origin: T::Origin {} } impl Module { diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 82cacdb516..f4490e50a0 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -109,7 +109,6 @@ use frame_support::{ensure, decl_module, decl_event, decl_storage, decl_error, C use frame_support::{traits::{Get, FindAuthor, ValidatorRegistration}, Parameter}; use frame_support::dispatch::{self, DispatchResult, DispatchError}; use frame_system::{self as system, ensure_signed}; -use frame_support::traits::MigrateAccount; #[cfg(test)] mod mock; @@ -504,18 +503,6 @@ decl_module! { } } -impl MigrateAccount for Module { - fn migrate_account(a: &T::AccountId) { - if let Some(v) = T::ValidatorIdOf::convert(a.clone()) { - if let Some(keys) = NextKeys::::migrate_key_from_blake(v) { - for id in T::Keys::key_ids() { - KeyOwner::::migrate_key_from_blake((*id, keys.get_raw(*id))); - } - } - } - } -} - impl Module { /// Move on to next session. Register new validator set and session keys. Changes /// to the validator set have a session of delay to take effect. This allows for diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index 6a60233222..9d64285b90 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -179,7 +179,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index eafd5ec519..03c61ba532 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -261,7 +261,10 @@ use sp_runtime::{Percent, ModuleId, RuntimeDebug, }; use frame_support::{decl_error, decl_module, decl_storage, decl_event, ensure, dispatch::DispatchResult}; use frame_support::weights::SimpleDispatchInfo; -use frame_support::traits::{Currency, ReservableCurrency, Randomness, Get, ChangeMembers, BalanceStatus, ExistenceRequirement::AllowDeath, MigrateAccount}; +use frame_support::traits::{ + Currency, ReservableCurrency, Randomness, Get, ChangeMembers, BalanceStatus, + ExistenceRequirement::AllowDeath +}; use frame_system::{self as system, ensure_signed, ensure_root}; type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; @@ -1130,12 +1133,6 @@ decl_event! { } } -impl MigrateAccount for Module { - fn migrate_account(a: &T::AccountId) { - Payouts::::migrate_key_from_blake(a); - } -} - /// Simple ensure origin struct to filter for the founder account. pub struct EnsureFounder(sp_std::marker::PhantomData); impl EnsureOrigin for EnsureFounder { diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index b80e0cd2bf..158f139df5 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -77,7 +77,7 @@ impl frame_system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); type AccountData = pallet_balances::AccountData; } diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index 0bb6c3fd4c..ca21317e5c 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -35,7 +35,6 @@ frame-benchmarking = { version = "2.0.0-alpha.4", path = "../benchmarking" } rand_chacha = { version = "0.2" } [features] -migrate = [] default = ["std"] std = [ "serde", diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 312e70963e..4851768074 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -286,7 +286,6 @@ use sp_runtime::{Serialize, Deserialize}; use frame_system::{self as system, ensure_signed, ensure_root}; use sp_phragmen::ExtendedBalance; -use frame_support::traits::MigrateAccount; const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4; pub const MAX_NOMINATIONS: usize = 16; @@ -956,10 +955,6 @@ decl_module! { fn deposit_event() = default; - fn on_runtime_upgrade() { - migrate::(); - } - fn on_finalize() { // Set the start of the first era. if let Some(mut active_era) = Self::active_era() { @@ -1480,30 +1475,6 @@ decl_module! { } } -impl MigrateAccount for Module { - fn migrate_account(a: &T::AccountId) { - if let Some(controller) = Bonded::::migrate_key_from_blake(a) { - Ledger::::migrate_key_from_blake(controller); - Payee::::migrate_key_from_blake(a); - Validators::::migrate_key_from_blake(a); - Nominators::::migrate_key_from_blake(a); - SlashingSpans::::migrate_key_from_blake(a); - } - } -} - -fn migrate() { - if let Some(current_era) = CurrentEra::get() { - let history_depth = HistoryDepth::get(); - for era in current_era.saturating_sub(history_depth)..=current_era { - ErasStartSessionIndex::migrate_key_from_blake(era); - ErasValidatorReward::::migrate_key_from_blake(era); - ErasRewardPoints::::migrate_key_from_blake(era); - ErasTotalStake::::migrate_key_from_blake(era); - } - } -} - impl Module { // PUBLIC IMMUTABLES diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 381ddf6fa9..8754751629 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -138,7 +138,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } impl pallet_balances::Trait for Test { diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index d36656a740..b25489dbe1 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -29,13 +29,6 @@ use sp_runtime::{ use crate::dispatch::Parameter; use crate::storage::StorageMap; -/// Migrate a given account. -#[impl_trait_for_tuples::impl_for_tuples(30)] -pub trait MigrateAccount { - /// Migrate the `account`. - fn migrate_account(account: &A); -} - /// An abstraction of a value stored within storage, but possibly as part of a larger composite /// item. pub trait StoredMap { diff --git a/frame/system/benches/bench.rs b/frame/system/benches/bench.rs index 03243bbfc4..90a4ad1d34 100644 --- a/frame/system/benches/bench.rs +++ b/frame/system/benches/bench.rs @@ -77,7 +77,7 @@ impl system::Trait for Runtime { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 29167d5b7e..6c30fbd755 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -116,7 +116,7 @@ use frame_support::{ decl_module, decl_event, decl_storage, decl_error, storage, Parameter, ensure, debug, traits::{ Contains, Get, ModuleToIndex, OnNewAccount, OnKilledAccount, IsDeadAccount, Happened, - StoredMap, MigrateAccount, + StoredMap, }, weights::{Weight, DispatchInfo, DispatchClass, SimpleDispatchInfo, FunctionOf}, }; @@ -126,7 +126,6 @@ use codec::{Encode, Decode, FullCodec, EncodeLike}; use sp_io::TestExternalities; pub mod offchain; -mod migration; /// Compute the trie root of a list of extrinsics. pub fn extrinsics_root(extrinsics: &[E]) -> H::Output { @@ -222,9 +221,6 @@ pub trait Trait: 'static + Eq + Clone { /// /// All resources should be cleaned up associated with the given account. type OnKilledAccount: OnKilledAccount; - - /// Migrate an account. - type MigrateAccount: MigrateAccount; } pub type DigestOf = generic::Digest<::Hash>; @@ -460,15 +456,6 @@ decl_module! { pub struct Module for enum Call where origin: T::Origin { type Error = Error; - fn on_runtime_upgrade() { - migration::migrate::(); - - // Remove the old `RuntimeUpgraded` storage entry. - let mut runtime_upgraded_key = sp_io::hashing::twox_128(b"System").to_vec(); - runtime_upgraded_key.extend(&sp_io::hashing::twox_128(b"RuntimeUpgraded")); - sp_io::storage::clear(&runtime_upgraded_key); - } - /// A dispatch that will fill the block weight up to the given ratio. // TODO: This should only be available for testing, rather than in general usage, but // that's not possible at present (since it's within the decl_module macro). @@ -577,21 +564,6 @@ decl_module! { ensure!(account.data == T::AccountData::default(), Error::::NonDefaultComposite); Account::::remove(who); } - - #[weight = FunctionOf( - |(accounts,): (&Vec,)| accounts.len() as u32 * 10_000, - DispatchClass::Normal, - true, - )] - fn migrate_accounts(origin, accounts: Vec) { - let _ = ensure_signed(origin)?; - for a in &accounts { - if Account::::migrate_key_from_blake(a).is_some() { - // Inform other modules about the account. - T::MigrateAccount::migrate_account(a); - } - } - } } } @@ -1570,7 +1542,7 @@ mod tests { type Version = Version; type ModuleToIndex = (); type AccountData = u32; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = RecordKilled; } diff --git a/frame/system/src/migration.rs b/frame/system/src/migration.rs deleted file mode 100644 index ece389f4f8..0000000000 --- a/frame/system/src/migration.rs +++ /dev/null @@ -1,37 +0,0 @@ -use super::*; -use sp_runtime::traits::SaturatedConversion; - -pub fn migrate() { - // Number is current block - we obviously don't know that hash. - // Number - 1 is the parent block, who hash we record in this block, but then that's already - // with the new storage so we don't migrate it. - // Number - 2 is therefore the most recent block's hash that needs migrating. - if Number::::get() > One::one() { - sp_runtime::print("Migrating BlockHash..."); - BlockHash::::migrate_key_from_blake(T::BlockNumber::zero()); - let mut n = Number::::get() - One::one() - One::one(); - while !n.is_zero() { - sp_runtime::print(n.saturated_into::()); - if BlockHash::::migrate_key_from_blake(n).is_none() { - break; - } - n -= One::one(); - } - } - - sp_runtime::print("Migrating Accounts..."); - let mut count = 0u32; - if let Ok(accounts) = Vec::::decode(&mut &include_bytes!("accounts.scale")[..]) { - for a in &accounts { - if Account::::migrate_key_from_blake(a).is_some() { - // Inform other modules about the account. - T::MigrateAccount::migrate_account(a); - count += 1; - if count % 1000 == 0 { - sp_runtime::print(count); - } - } - } - } - sp_runtime::print(count); -} diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 18e3be877b..2a37dfdddb 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -278,7 +278,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } parameter_types! { diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 0306e74edb..a9da383061 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -310,7 +310,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 72f9c508ca..ad3bb419af 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -283,22 +283,8 @@ decl_error! { } } -mod migration { - use super::*; - pub fn migrate() { - for i in 0..ProposalCount::get() { - Proposals::::migrate_key_from_blake(i); - } - Reasons::::remove_all(); - } -} - decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn on_runtime_upgrade() { - migration::migrate::(); - } - /// Fraction of a proposal's value that should be bonded in order to place the proposal. /// An accepted proposal gets these back. A rejected proposal does not. const ProposalBond: Permill = T::ProposalBond::get(); @@ -776,7 +762,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } parameter_types! { diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 6ecaadab37..0b60532c3d 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -623,7 +623,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } parameter_types! { diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index 0b670de3b4..94a70b7ef1 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -53,7 +53,10 @@ use sp_runtime::{DispatchResult, RuntimeDebug, traits::{ StaticLookup, Zero, AtLeast32Bit, MaybeSerializeDeserialize, Convert }}; use frame_support::{decl_module, decl_event, decl_storage, decl_error, ensure}; -use frame_support::traits::{Currency, LockableCurrency, VestingSchedule, WithdrawReason, LockIdentifier, ExistenceRequirement, Get, MigrateAccount}; +use frame_support::traits::{ + Currency, LockableCurrency, VestingSchedule, WithdrawReason, LockIdentifier, + ExistenceRequirement, Get +}; use frame_support::weights::SimpleDispatchInfo; use frame_system::{self as system, ensure_signed}; @@ -254,12 +257,6 @@ decl_module! { } } -impl MigrateAccount for Module { - fn migrate_account(a: &T::AccountId) { - Vesting::::migrate_key_from_blake(a); - } -} - impl Module { /// (Re)set or remove the module's currency lock on `who`'s account in accordance with their /// current unvested amount. @@ -388,7 +385,7 @@ mod tests { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } impl pallet_balances::Trait for Test { diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index bc5e0070eb..59955cce48 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -391,7 +391,7 @@ impl frame_system::Trait for Runtime { type Version = (); type ModuleToIndex = (); type AccountData = (); - type MigrateAccount = (); type OnNewAccount = (); + type OnNewAccount = (); type OnKilledAccount = (); } -- GitLab From 659f8d90bb848986b9256700288d1198c6eb466a Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 20 Mar 2020 12:42:00 +0100 Subject: [PATCH 024/300] Benchmark Im Online Pallet (#5318) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial benchmarking setup * Add keystore * validate unsigned * Update frame/im-online/src/benchmarking.rs Co-Authored-By: Marcio Diaz * Fix verify_unsigned benchmark * add variable for teting the external addresss length * Update frame/im-online/src/benchmarking.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update utils/frame/benchmarking-cli/src/lib.rs Co-Authored-By: Bastian Köcher Co-authored-by: Marcio Diaz Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Benjamin Kampmann Co-authored-by: Bastian Köcher --- Cargo.lock | 2 + bin/node/runtime/Cargo.toml | 3 + bin/node/runtime/src/lib.rs | 7 ++ frame/im-online/Cargo.toml | 3 + frame/im-online/src/benchmarking.rs | 123 ++++++++++++++++++++++++ frame/im-online/src/lib.rs | 1 + primitives/runtime/src/traits.rs | 10 ++ utils/frame/benchmarking-cli/Cargo.toml | 1 + utils/frame/benchmarking-cli/src/lib.rs | 12 ++- 9 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 frame/im-online/src/benchmarking.rs diff --git a/Cargo.lock b/Cargo.lock index 189f85013c..046712c0af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1449,6 +1449,7 @@ dependencies = [ "sc-executor", "sc-service", "sp-core", + "sp-externalities", "sp-runtime", "sp-state-machine", "structopt", @@ -4225,6 +4226,7 @@ dependencies = [ name = "pallet-im-online" version = "2.0.0-alpha.4" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", "pallet-authorship", diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index a5fad30837..bdbf4cce50 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -139,4 +139,7 @@ runtime-benchmarks = [ "pallet-identity/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", + "pallet-session-benchmarking", + "pallet-staking/runtime-benchmarks", + "pallet-im-online/runtime-benchmarks", ] diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index b27ba6c9ac..48913b7771 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -864,6 +864,13 @@ impl_runtime_apis! { steps, repeat, ), + b"pallet-im-online" | b"im-online" => ImOnline::run_benchmark( + extrinsic, + lowest_range_values, + highest_range_values, + steps, + repeat, + ), b"pallet-identity" | b"identity" => Identity::run_benchmark( extrinsic, lowest_range_values, diff --git a/frame/im-online/Cargo.toml b/frame/im-online/Cargo.toml index 2b9e80ce4e..d8df22a0f5 100644 --- a/frame/im-online/Cargo.toml +++ b/frame/im-online/Cargo.toml @@ -22,6 +22,8 @@ sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../. frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } + [features] default = ["std", "pallet-session/historical"] std = [ @@ -38,3 +40,4 @@ std = [ "frame-support/std", "frame-system/std", ] +runtime-benchmarks = ["frame-benchmarking"] diff --git a/frame/im-online/src/benchmarking.rs b/frame/im-online/src/benchmarking.rs new file mode 100644 index 0000000000..1269328634 --- /dev/null +++ b/frame/im-online/src/benchmarking.rs @@ -0,0 +1,123 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! I'm Online pallet benchmarking. + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +use frame_system::RawOrigin; +use frame_benchmarking::benchmarks; +use sp_core::offchain::{OpaquePeerId, OpaqueMultiaddr}; +use sp_runtime::traits::{ValidateUnsigned, Zero}; + +use crate::Module as ImOnline; + +const MAX_KEYS: u32 = 1000; +const MAX_EXTERNAL_ADDRESSES: u32 = 100; + +pub fn create_heartbeat(k: u32, e: u32) -> + Result<(crate::Heartbeat, ::Signature), &'static str> +{ + let mut keys = Vec::new(); + for _ in 0..k { + keys.push(T::AuthorityId::generate_pair(None)); + } + Keys::::put(keys.clone()); + + let network_state = OpaqueNetworkState { + peer_id: OpaquePeerId::default(), + external_addresses: vec![OpaqueMultiaddr::new(vec![0; 32]); e as usize], + }; + let input_heartbeat = Heartbeat { + block_number: T::BlockNumber::zero(), + network_state, + session_index: 0, + authority_index: k-1, + }; + + let encoded_heartbeat = input_heartbeat.encode(); + let authority_id = keys.get((k-1) as usize).ok_or("out of range")?; + let signature = authority_id.sign(&encoded_heartbeat).ok_or("couldn't make signature")?; + + Ok((input_heartbeat, signature)) +} + +benchmarks! { + _{ } + + heartbeat { + let k in 1 .. MAX_KEYS; + let e in 1 .. MAX_EXTERNAL_ADDRESSES; + let (input_heartbeat, signature) = create_heartbeat::(k, e)?; + }: _(RawOrigin::None, input_heartbeat, signature) + + validate_unsigned { + let k in 1 .. MAX_KEYS; + let e in 1 .. MAX_EXTERNAL_ADDRESSES; + let (input_heartbeat, signature) = create_heartbeat::(k, e)?; + let call = Call::heartbeat(input_heartbeat, signature); + }: { + ImOnline::::validate_unsigned(&call)?; + } +} + +#[cfg(test)] +mod tests { + use crate::*; + use super::SelectedBenchmark; + use crate::mock::*; + use frame_support::assert_ok; + + #[test] + fn test_heartbeat_benchmark() { + new_test_ext().execute_with(|| { + let k = 10; + + assert_eq!(ReceivedHeartbeats::iter_prefix(0).count(), 0); + + let selected_benchmark = SelectedBenchmark::heartbeat; + let c = vec![(frame_benchmarking::BenchmarkParameter::k, k)]; + let closure_to_benchmark = + >::instance( + &selected_benchmark, + &c + ).unwrap(); + + assert_ok!(closure_to_benchmark()); + + assert_eq!(ReceivedHeartbeats::iter_prefix(0).count(), 1); + }); + } + + #[test] + fn test_validate_unsigned_benchmark() { + new_test_ext().execute_with(|| { + let k = 10; + + let selected_benchmark = SelectedBenchmark::validate_unsigned; + let c = vec![(frame_benchmarking::BenchmarkParameter::k, k)]; + let closure_to_benchmark = + >::instance( + &selected_benchmark, + &c + ).unwrap(); + + assert_ok!(closure_to_benchmark()); + }); + } +} diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index a0a16c46f3..861c57e5b6 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -69,6 +69,7 @@ mod mock; mod tests; +mod benchmarking; use sp_application_crypto::RuntimeAppPublic; use codec::{Encode, Decode}; diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 39e015505b..81b7733319 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -1293,6 +1293,16 @@ impl Printable for &str { } } +impl Printable for bool { + fn print(&self) { + if *self { + "true".print() + } else { + "false".print() + } + } +} + #[impl_for_tuples(1, 12)] impl Printable for Tuple { fn print(&self) { diff --git a/utils/frame/benchmarking-cli/Cargo.toml b/utils/frame/benchmarking-cli/Cargo.toml index 3535a542d9..3ba1b16481 100644 --- a/utils/frame/benchmarking-cli/Cargo.toml +++ b/utils/frame/benchmarking-cli/Cargo.toml @@ -16,6 +16,7 @@ sc-cli = { version = "0.8.0-alpha.4", path = "../../../client/cli" } sc-client = { version = "0.8.0-alpha.4", path = "../../../client" } sc-client-db = { version = "0.8.0-alpha.4", path = "../../../client/db" } sc-executor = { version = "0.8.0-alpha.4", path = "../../../client/executor" } +sp-externalities = { version = "0.8.0-alpha.4", path = "../../../primitives/externalities" } sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } structopt = "0.3.8" diff --git a/utils/frame/benchmarking-cli/src/lib.rs b/utils/frame/benchmarking-cli/src/lib.rs index 79e7e689a6..b2aa4bd6a2 100644 --- a/utils/frame/benchmarking-cli/src/lib.rs +++ b/utils/frame/benchmarking-cli/src/lib.rs @@ -23,7 +23,12 @@ use sc_service::{Configuration, ChainSpec}; use sc_executor::{NativeExecutor, NativeExecutionDispatch}; use codec::{Encode, Decode}; use frame_benchmarking::BenchmarkResults; -use sp_core::tasks; +use sp_core::{ + tasks, + traits::KeystoreExt, + testing::KeyStore, +}; +use sp_externalities::Extensions; /// The `benchmark` command used to benchmark FRAME Pallets. #[derive(Debug, structopt::StructOpt, Clone)] @@ -106,6 +111,9 @@ impl BenchmarkCmd { 2, // The runtime instances cache size. ); + let mut extensions = Extensions::default(); + extensions.register(KeystoreExt(KeyStore::new())); + let result = StateMachine::<_, _, NumberFor, _>::new( &state, None, @@ -120,7 +128,7 @@ impl BenchmarkCmd { self.steps.clone(), self.repeat, ).encode(), - Default::default(), + extensions, &sp_state_machine::backend::BackendRuntimeCode::new(&state).runtime_code()?, tasks::executor(), ) -- GitLab From eff82f4371133ac6d5bc4b2b4c20370d487d57b0 Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Fri, 20 Mar 2020 14:15:02 +0100 Subject: [PATCH 025/300] fix lone txqueue log target (#5331) --- client/transaction-pool/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index 3c240611f0..29d9a4fc1d 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -382,7 +382,7 @@ impl MaintainedTransactionPool for BasicPool let block_number = match api.block_id_to_number(&id) { Ok(Some(number)) => number, _ => { - log::trace!(target: "txqueue", "Skipping chain event - no number for that block {:?}", id); + log::trace!(target: "txpool", "Skipping chain event - no number for that block {:?}", id); return Box::pin(ready(())); } }; -- GitLab From f21606f0b0a949cefcb95922a81d3cc747c111f0 Mon Sep 17 00:00:00 2001 From: cheme Date: Fri, 20 Mar 2020 14:39:14 +0100 Subject: [PATCH 026/300] review change. --- .../network/src/protocol/light_client_handler.rs | 2 +- frame/contracts/src/account_db.rs | 12 ++++++------ frame/contracts/src/lib.rs | 16 ++++++++-------- frame/contracts/src/rent.rs | 6 +++--- .../state-machine/src/overlayed_changes.rs | 2 +- test-utils/client/src/lib.rs | 2 ++ 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/client/network/src/protocol/light_client_handler.rs b/client/network/src/protocol/light_client_handler.rs index f6588ea198..ecbd62e431 100644 --- a/client/network/src/protocol/light_client_handler.rs +++ b/client/network/src/protocol/light_client_handler.rs @@ -514,7 +514,7 @@ where Some((ChildType::ParentKeyId, storage_key)) => Ok(ChildInfo::new_default(storage_key)), None => Err("Invalid child storage key".into()), }; - let proof = match child_info.and_then(|child_info| self.chain.read_child_proof( + let proof = match child_info.and_then(|child_info| self.chain.read_child_proof( &BlockId::Hash(block), &child_info, &mut request.keys.iter().map(AsRef::as_ref) diff --git a/frame/contracts/src/account_db.rs b/frame/contracts/src/account_db.rs index f65ecb0d8c..fb1ec52b3d 100644 --- a/frame/contracts/src/account_db.rs +++ b/frame/contracts/src/account_db.rs @@ -128,7 +128,7 @@ impl AccountDb for DirectAccountDb { trie_id: Option<&TrieId>, location: &StorageKey ) -> Option> { - trie_id.and_then(|id| child::get_raw(&crate::trie_unique_id(&id[..]), &blake2_256(location))) + trie_id.and_then(|id| child::get_raw(&crate::child_trie_info(&id[..]), &blake2_256(location))) } fn get_code_hash(&self, account: &T::AccountId) -> Option> { >::get(account).and_then(|i| i.as_alive().map(|i| i.code_hash)) @@ -175,13 +175,13 @@ impl AccountDb for DirectAccountDb { (false, Some(info), _) => info, // Existing contract is being removed. (true, Some(info), None) => { - child::kill_storage(&info.child_trie_unique_id()); + child::kill_storage(&info.child_trie_info()); >::remove(&address); continue; } // Existing contract is being replaced by a new one. (true, Some(info), Some(code_hash)) => { - child::kill_storage(&info.child_trie_unique_id()); + child::kill_storage(&info.child_trie_info()); AliveContractInfo:: { code_hash, storage_size: T::StorageSizeOffset::get(), @@ -220,16 +220,16 @@ impl AccountDb for DirectAccountDb { for (k, v) in changed.storage.into_iter() { if let Some(value) = child::get_raw( - &new_info.child_trie_unique_id(), + &new_info.child_trie_info(), &blake2_256(&k), ) { new_info.storage_size -= value.len() as u32; } if let Some(value) = v { new_info.storage_size += value.len() as u32; - child::put_raw(&new_info.child_trie_unique_id(), &blake2_256(&k), &value[..]); + child::put_raw(&new_info.child_trie_info(), &blake2_256(&k), &value[..]); } else { - child::kill(&new_info.child_trie_unique_id(), &blake2_256(&k)); + child::kill(&new_info.child_trie_info(), &blake2_256(&k)); } } diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 8da776ae6b..a2d194714d 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -225,13 +225,13 @@ pub struct RawAliveContractInfo { impl RawAliveContractInfo { /// Associated child trie unique id is built from the hash part of the trie id. - pub fn child_trie_unique_id(&self) -> ChildInfo { - trie_unique_id(&self.trie_id[..]) + pub fn child_trie_info(&self) -> ChildInfo { + child_trie_info(&self.trie_id[..]) } } /// Associated child trie unique id is built from the hash part of the trie id. -pub(crate) fn trie_unique_id(trie_id: &[u8]) -> ChildInfo { +pub(crate) fn child_trie_info(trie_id: &[u8]) -> ChildInfo { ChildInfo::new_default(trie_id) } @@ -804,11 +804,11 @@ impl Module { let key_values_taken = delta.iter() .filter_map(|key| { child::get_raw( - &origin_contract.child_trie_unique_id(), + &origin_contract.child_trie_info(), &blake2_256(key), ).map(|value| { child::kill( - &origin_contract.child_trie_unique_id(), + &origin_contract.child_trie_info(), &blake2_256(key), ); @@ -821,7 +821,7 @@ impl Module { // This operation is cheap enough because last_write (delta not included) // is not this block as it has been checked earlier. &child::root( - &origin_contract.child_trie_unique_id(), + &origin_contract.child_trie_info(), )[..], code_hash, ); @@ -829,7 +829,7 @@ impl Module { if tombstone != dest_tombstone { for (key, value) in key_values_taken { child::put_raw( - &origin_contract.child_trie_unique_id(), + &origin_contract.child_trie_info(), &blake2_256(key), &value, ); @@ -933,7 +933,7 @@ decl_storage! { impl OnKilledAccount for Module { fn on_killed_account(who: &T::AccountId) { if let Some(ContractInfo::Alive(info)) = >::take(who) { - child::kill_storage(&info.child_trie_unique_id()); + child::kill_storage(&info.child_trie_info()); } } } diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index dfcbc997c5..1aa52fff31 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -223,7 +223,7 @@ fn enact_verdict( Verdict::Kill => { >::remove(account); child::kill_storage( - &alive_contract_info.child_trie_unique_id(), + &alive_contract_info.child_trie_info(), ); >::deposit_event(RawEvent::Evicted(account.clone(), false)); None @@ -235,7 +235,7 @@ fn enact_verdict( // Note: this operation is heavy. let child_storage_root = child::root( - &alive_contract_info.child_trie_unique_id(), + &alive_contract_info.child_trie_info(), ); let tombstone = >::new( @@ -246,7 +246,7 @@ fn enact_verdict( >::insert(account, &tombstone_info); child::kill_storage( - &alive_contract_info.child_trie_unique_id(), + &alive_contract_info.child_trie_info(), ); >::deposit_event(RawEvent::Evicted(account.clone(), true)); diff --git a/primitives/state-machine/src/overlayed_changes.rs b/primitives/state-machine/src/overlayed_changes.rs index 2dc56bc772..c72cfc5c1c 100644 --- a/primitives/state-machine/src/overlayed_changes.rs +++ b/primitives/state-machine/src/overlayed_changes.rs @@ -76,7 +76,7 @@ pub struct OverlayedValue { pub struct OverlayedChangeSet { /// Top level storage changes. pub top: BTreeMap, - /// Child storage changes. + /// Child storage changes. The map key is the child storage key without the common prefix. pub children_default: HashMap, ChildInfo)>, } diff --git a/test-utils/client/src/lib.rs b/test-utils/client/src/lib.rs index fad08c8238..4880b296c7 100644 --- a/test-utils/client/src/lib.rs +++ b/test-utils/client/src/lib.rs @@ -66,6 +66,8 @@ impl GenesisInit for () { pub struct TestClientBuilder { execution_strategies: ExecutionStrategies, genesis_init: G, + /// The key is an unprefixed storage key, this only contains + /// default child trie content. child_storage_extension: HashMap, StorageChild>, backend: Arc, _executor: std::marker::PhantomData, -- GitLab From f546ddb4c4760b0d7b17fea5cfe72adb69d02139 Mon Sep 17 00:00:00 2001 From: Peter Goodspeed-Niklaus Date: Fri, 20 Mar 2020 15:00:01 +0100 Subject: [PATCH 027/300] Factor out can_set_code (#5317) * Factor out can_set_code The motivation for this feature is parachain runtime upgrades, which happen in two different moments: the initial call, when the checks should be performed, and at the actual upgrade block. It's much better and more maintainable to just call `can_set_code` in the function than to manually copy those checks. I'm not entirely thrilled with the interface, which requires cloning the entire code vector in `set_code`. However, it looks like something in `decl_module!` does not play nicely with references in its function arguments. If `code` has a lifetime, it _must_ be named, which gives us this signature. ```rust pub fn can_set_code<'a>(origin, code: &'a [u8]) { ``` Unfortunately, attempting to compile with that signature generates a very large and baffling collection of build errors, so I decided to abandon that path for now. * make can_set_code non-dispatchable per PR revew Not only can we now borrow the `code` slice, but we also no longer need to worry about people sending a `can_set_code` transaction because of some misunderstanding. * move into existing impl block --- frame/system/src/lib.rs | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 6c30fbd755..e59788c600 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -484,20 +484,7 @@ decl_module! { /// Set the new runtime code. #[weight = SimpleDispatchInfo::FixedOperational(200_000)] pub fn set_code(origin, code: Vec) { - ensure_root(origin)?; - - let current_version = T::Version::get(); - let new_version = sp_io::misc::runtime_version(&code) - .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok()) - .ok_or_else(|| Error::::FailedToExtractRuntimeVersion)?; - - if new_version.spec_name != current_version.spec_name { - Err(Error::::InvalidSpecName)? - } - - if new_version.spec_version <= current_version.spec_version { - Err(Error::::SpecVersionNeedsToIncrease)? - } + Self::can_set_code(origin, &code)?; storage::unhashed::put_raw(well_known_keys::CODE, &code); Self::deposit_event(RawEvent::CodeUpdated); @@ -1009,6 +996,32 @@ impl Module { Module::::on_killed_account(who.clone()); } } + + /// Determine whether or not it is possible to update the code. + /// + /// This function has no side effects and is idempotent, but is fairly + /// heavy. It is automatically called by `set_code`; in most cases, + /// a direct call to `set_code` is preferable. It is useful to call + /// `can_set_code` when it is desirable to perform the appropriate + /// runtime checks without actually changing the code yet. + pub fn can_set_code(origin: T::Origin, code: &[u8]) -> Result<(), sp_runtime::DispatchError> { + ensure_root(origin)?; + + let current_version = T::Version::get(); + let new_version = sp_io::misc::runtime_version(&code) + .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok()) + .ok_or_else(|| Error::::FailedToExtractRuntimeVersion)?; + + if new_version.spec_name != current_version.spec_name { + Err(Error::::InvalidSpecName)? + } + + if new_version.spec_version <= current_version.spec_version { + Err(Error::::SpecVersionNeedsToIncrease)? + } + + Ok(()) + } } /// Event handler which calls on_created_account when it happens. -- GitLab From aebb228807371ade4535c895a43da68f45691828 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 20 Mar 2020 15:08:16 +0100 Subject: [PATCH 028/300] Benchmark Treasury Pallet (#5287) * Start benchmarks * try_origin or root * More benches * stuck * Custom trait functions for benchmarks * finish benchmarks * Bump impl * More comments * Bump spec * Remove import * Update frame/elections-phragmen/src/lib.rs Co-Authored-By: thiolliere * Update frame/support/src/traits.rs Co-Authored-By: thiolliere * Fix merge Co-authored-by: thiolliere --- Cargo.lock | 1 + bin/node/runtime/Cargo.toml | 9 +- bin/node/runtime/src/lib.rs | 7 + frame/elections-phragmen/Cargo.toml | 1 + frame/elections-phragmen/src/lib.rs | 12 + frame/support/Cargo.toml | 1 + frame/support/src/traits.rs | 7 + frame/treasury/Cargo.toml | 6 + frame/treasury/src/benchmarking.rs | 211 +++++++++++++ frame/treasury/src/lib.rs | 471 +--------------------------- frame/treasury/src/tests.rs | 449 ++++++++++++++++++++++++++ 11 files changed, 715 insertions(+), 460 deletions(-) create mode 100644 frame/treasury/src/benchmarking.rs create mode 100644 frame/treasury/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 046712c0af..dc3530103a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4525,6 +4525,7 @@ dependencies = [ name = "pallet-treasury" version = "2.0.0-alpha.4" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", "pallet-balances", diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index bdbf4cce50..dffde93eb4 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -135,9 +135,14 @@ std = [ ] runtime-benchmarks = [ "frame-benchmarking", - "pallet-timestamp/runtime-benchmarks", - "pallet-identity/runtime-benchmarks", + "frame-support/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-elections-phragmen/runtime-benchmarks", + "pallet-identity/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "pallet-treasury/runtime-benchmarks", + "pallet-session-benchmarking", + "pallet-staking/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", "pallet-session-benchmarking", "pallet-staking/runtime-benchmarks", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 48913b7771..98194af924 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -899,6 +899,13 @@ impl_runtime_apis! { steps, repeat, ), + b"pallet-treasury" | b"treasury" => Treasury::run_benchmark( + extrinsic, + lowest_range_values, + highest_range_values, + steps, + repeat, + ), b"pallet-vesting" | b"vesting" => Vesting::run_benchmark( extrinsic, lowest_range_values, diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index bef7b7dfd8..1b372ba565 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -34,3 +34,4 @@ std = [ "frame-system/std", "sp-std/std", ] +runtime-benchmarks = ["frame-support/runtime-benchmarks"] diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 54bf801bbd..d1a3c6af5f 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -775,6 +775,18 @@ impl Contains for Module { Self::is_member(who) } fn sorted_members() -> Vec { Self::members_ids() } + + // A special function to populate members in this pallet for passing Origin + // checks in runtime benchmarking. + #[cfg(feature = "runtime-benchmarks")] + fn add(who: &T::AccountId) { + Members::::mutate(|members| { + match members.binary_search_by(|(a, _b)| a.cmp(who)) { + Ok(_) => (), + Err(pos) => members.insert(pos, (who.clone(), BalanceOf::::default())), + } + }) + } } #[cfg(test)] diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index 7bd77488b6..ae906ef2c0 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -49,3 +49,4 @@ std = [ ] nightly = [] strict = [] +runtime-benchmarks = [] diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index b25489dbe1..585e17d80d 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -171,6 +171,13 @@ pub trait Contains { /// Get the number of items in the set. fn count() -> usize { Self::sorted_members().len() } + + /// Add an item that would satisfy `contains`. It does not make sure any other + /// state is correctly maintained or generated. + /// + /// **Should be used for benchmarking only!!!** + #[cfg(feature = "runtime-benchmarks")] + fn add(t: &T); } /// Determiner to say whether a given account is unused. diff --git a/frame/treasury/Cargo.toml b/frame/treasury/Cargo.toml index f6429ec1c7..9c1589e322 100644 --- a/frame/treasury/Cargo.toml +++ b/frame/treasury/Cargo.toml @@ -17,6 +17,8 @@ frame-support = { version = "2.0.0-alpha.4", default-features = false, path = ". frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } pallet-balances = { version = "2.0.0-alpha.4", default-features = false, path = "../balances" } +frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking", optional = true } + [dev-dependencies] sp-io ={ version = "2.0.0-alpha.4", path = "../../primitives/io" } sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } @@ -32,3 +34,7 @@ std = [ "frame-system/std", "pallet-balances/std", ] +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", +] diff --git a/frame/treasury/src/benchmarking.rs b/frame/treasury/src/benchmarking.rs new file mode 100644 index 0000000000..08318bdd6c --- /dev/null +++ b/frame/treasury/src/benchmarking.rs @@ -0,0 +1,211 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Treasury pallet benchmarking. + +use super::*; + +use frame_system::RawOrigin; +use frame_benchmarking::{benchmarks, account}; +use sp_runtime::traits::OnFinalize; + +use crate::Module as Treasury; + +const SEED: u32 = 0; + +// Create the pre-requisite information needed to create a treasury `propose_spend`. +fn setup_proposal(u: u32) -> ( + T::AccountId, + BalanceOf, + ::Source, +) { + let caller = account("caller", u, SEED); + let value: BalanceOf = T::ProposalBondMinimum::get().saturating_mul(100.into()); + let _ = T::Currency::make_free_balance_be(&caller, value); + let beneficiary = account("beneficiary", u, SEED); + let beneficiary_lookup = T::Lookup::unlookup(beneficiary); + (caller, value, beneficiary_lookup) +} + +// Create the pre-requisite information needed to create a `report_awesome`. +fn setup_awesome(length: u32) -> (T::AccountId, Vec, T::AccountId) { + let caller = account("caller", 0, SEED); + let value = T::TipReportDepositBase::get() + + T::TipReportDepositPerByte::get() * length.into() + + T::Currency::minimum_balance(); + let _ = T::Currency::make_free_balance_be(&caller, value); + let reason = vec![0; length as usize]; + let awesome_person = account("awesome", 0, SEED); + (caller, reason, awesome_person) +} + +// Create the pre-requisite information needed to call `tip_new`. +fn setup_tip(r: u32, t: u32) -> + Result<(T::AccountId, Vec, T::AccountId, BalanceOf), &'static str> +{ + for i in 0 .. t { + let member = account("member", i, SEED); + T::Tippers::add(&member); + } + + ensure!(T::Tippers::count() == t as usize, "problem creating tippers"); + let caller = account("member", t - 1, SEED); + let reason = vec![0; r as usize]; + let beneficiary = account("beneficiary", t, SEED); + let value = T::Currency::minimum_balance().saturating_mul(100.into()); + Ok((caller, reason, beneficiary, value)) +} + +// Create `t` new types for the tip proposal with `hash`. +// This function automatically moves forward the block number to a time which +// would resolve the tipping process. +fn create_tips(t: u32, hash: T::Hash, value: BalanceOf) -> Result<(), &'static str> { + for i in 0 .. t { + let caller = account("member", i, SEED); + ensure!(T::Tippers::contains(&caller), "caller is not a tipper"); + Treasury::::tip(RawOrigin::Signed(caller).into(), hash, value)?; + } + frame_system::Module::::set_block_number(T::TipCountdown::get() * 10.into()); + Ok(()) +} + +// Create proposals that are approved for use in `on_finalize`. +fn create_approved_proposals(n: u32) -> Result<(), &'static str> { + for i in 0 .. n { + let (caller, value, lookup) = setup_proposal::(i); + Treasury::::propose_spend( + RawOrigin::Signed(caller).into(), + value, + lookup + )?; + let proposal_id = ProposalCount::get() - 1; + Treasury::::approve_proposal(RawOrigin::Root.into(), proposal_id)?; + } + ensure!(Approvals::get().len() == n as usize, "Not all approved"); + Ok(()) +} + +const MAX_BYTES: u32 = 16384; +const MAX_TIPPERS: u32 = 100; + +benchmarks! { + _ { } + + propose_spend { + let u in 0 .. 1000; + let (caller, value, beneficiary_lookup) = setup_proposal::(u); + }: _(RawOrigin::Signed(caller), value, beneficiary_lookup) + + reject_proposal { + let u in 0 .. 1000; + let (caller, value, beneficiary_lookup) = setup_proposal::(u); + Treasury::::propose_spend( + RawOrigin::Signed(caller).into(), + value, + beneficiary_lookup + )?; + let proposal_id = ProposalCount::get() - 1; + }: _(RawOrigin::Root, proposal_id) + + approve_proposal { + let u in 0 .. 1000; + let (caller, value, beneficiary_lookup) = setup_proposal::(u); + Treasury::::propose_spend( + RawOrigin::Signed(caller).into(), + value, + beneficiary_lookup + )?; + let proposal_id = ProposalCount::get() - 1; + }: _(RawOrigin::Root, proposal_id) + + report_awesome { + let r in 0 .. MAX_BYTES; + let (caller, reason, awesome_person) = setup_awesome::(r); + }: _(RawOrigin::Signed(caller), reason, awesome_person) + + retract_tip { + let r in 0 .. MAX_BYTES; + let (caller, reason, awesome_person) = setup_awesome::(r); + Treasury::::report_awesome( + RawOrigin::Signed(caller.clone()).into(), + reason.clone(), + awesome_person.clone() + )?; + let reason_hash = T::Hashing::hash(&reason[..]); + let hash = T::Hashing::hash_of(&(&reason_hash, &awesome_person)); + }: _(RawOrigin::Signed(caller), hash) + + tip_new { + let r in 0 .. MAX_BYTES; + let t in 1 .. MAX_TIPPERS; + + let (caller, reason, beneficiary, value) = setup_tip::(r, t)?; + }: _(RawOrigin::Signed(caller), reason, beneficiary, value) + + tip { + let t in 1 .. MAX_TIPPERS; + let (member, reason, beneficiary, value) = setup_tip::(0, t)?; + let value = T::Currency::minimum_balance().saturating_mul(100.into()); + Treasury::::tip_new( + RawOrigin::Signed(member).into(), + reason.clone(), + beneficiary.clone(), + value + )?; + let reason_hash = T::Hashing::hash(&reason[..]); + let hash = T::Hashing::hash_of(&(&reason_hash, &beneficiary)); + ensure!(Tips::::contains_key(hash), "tip does not exist"); + create_tips::(t - 1, hash.clone(), value)?; + let caller = account("member", t - 1, SEED); + }: _(RawOrigin::Signed(caller), hash, value) + + close_tip { + let t in 1 .. MAX_TIPPERS; + + // Make sure pot is funded + let pot_account = Treasury::::account_id(); + let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000.into()); + let _ = T::Currency::make_free_balance_be(&pot_account, value); + + // Set up a new tip proposal + let (member, reason, beneficiary, value) = setup_tip::(0, t)?; + let value = T::Currency::minimum_balance().saturating_mul(100.into()); + Treasury::::tip_new( + RawOrigin::Signed(member).into(), + reason.clone(), + beneficiary.clone(), + value + )?; + + // Create a bunch of tips + let reason_hash = T::Hashing::hash(&reason[..]); + let hash = T::Hashing::hash_of(&(&reason_hash, &beneficiary)); + ensure!(Tips::::contains_key(hash), "tip does not exist"); + create_tips::(t, hash.clone(), value)?; + + let caller = account("caller", t, SEED); + }: _(RawOrigin::Signed(caller), hash) + + on_finalize { + let p in 0 .. 100; + let pot_account = Treasury::::account_id(); + let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000.into()); + let _ = T::Currency::make_free_balance_be(&pot_account, value); + create_approved_proposals::(p)?; + }: { + Treasury::::on_finalize(T::BlockNumber::zero()); + } +} diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index ad3bb419af..d7562d0767 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -100,7 +100,12 @@ use sp_runtime::{Permill, ModuleId, Percent, RuntimeDebug, traits::{ }}; use frame_support::{weights::SimpleDispatchInfo, traits::Contains}; use codec::{Encode, Decode}; -use frame_system::{self as system, ensure_signed}; +use frame_system::{self as system, ensure_signed, ensure_root}; + +#[cfg(test)] +mod tests; +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type PositiveImbalanceOf = <::Currency as Currency<::AccountId>>::PositiveImbalance; @@ -352,9 +357,11 @@ decl_module! { /// # #[weight = SimpleDispatchInfo::FixedOperational(100_000)] fn reject_proposal(origin, #[compact] proposal_id: ProposalIndex) { - T::RejectOrigin::ensure_origin(origin)?; - let proposal = >::take(&proposal_id).ok_or(Error::::InvalidProposalIndex)?; + T::RejectOrigin::try_origin(origin) + .map(|_| ()) + .or_else(ensure_root)?; + let proposal = >::take(&proposal_id).ok_or(Error::::InvalidProposalIndex)?; let value = proposal.bond; let imbalance = T::Currency::slash_reserved(&proposal.proposer, value).0; T::ProposalRejection::on_unbalanced(imbalance); @@ -372,10 +379,11 @@ decl_module! { /// # #[weight = SimpleDispatchInfo::FixedOperational(100_000)] fn approve_proposal(origin, #[compact] proposal_id: ProposalIndex) { - T::ApproveOrigin::ensure_origin(origin)?; + T::ApproveOrigin::try_origin(origin) + .map(|_| ()) + .or_else(ensure_root)?; ensure!(>::contains_key(proposal_id), Error::::InvalidProposalIndex); - Approvals::mutate(|v| v.push(proposal_id)); } @@ -718,456 +726,3 @@ impl OnUnbalanced> for Module { Self::deposit_event(RawEvent::Deposit(numeric_amount)); } } - -#[cfg(test)] -mod tests { - use super::*; - - use frame_support::{assert_noop, assert_ok, impl_outer_origin, parameter_types, weights::Weight}; - use frame_support::traits::Contains; - use sp_core::H256; - use sp_runtime::{ - Perbill, - testing::Header, - traits::{BlakeTwo256, OnFinalize, IdentityLookup, BadOrigin}, - }; - - impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} - } - - #[derive(Clone, Eq, PartialEq)] - pub struct Test; - parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - } - impl frame_system::Trait for Test { - type Origin = Origin; - type Index = u64; - type BlockNumber = u64; - type Call = (); - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = (); - type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; - type Version = (); - type ModuleToIndex = (); - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - } - parameter_types! { - pub const ExistentialDeposit: u64 = 1; -} - impl pallet_balances::Trait for Test { - type Balance = u64; - type Event = (); - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - } - pub struct TenToFourteen; - impl Contains for TenToFourteen { - fn contains(n: &u64) -> bool { - *n >= 10 && *n <= 14 - } - fn sorted_members() -> Vec { - vec![10, 11, 12, 13, 14] - } - } - parameter_types! { - pub const ProposalBond: Permill = Permill::from_percent(5); - pub const ProposalBondMinimum: u64 = 1; - pub const SpendPeriod: u64 = 2; - pub const Burn: Permill = Permill::from_percent(50); - pub const TipCountdown: u64 = 1; - pub const TipFindersFee: Percent = Percent::from_percent(20); - pub const TipReportDepositBase: u64 = 1; - pub const TipReportDepositPerByte: u64 = 1; - } - impl Trait for Test { - type Currency = pallet_balances::Module; - type ApproveOrigin = frame_system::EnsureRoot; - type RejectOrigin = frame_system::EnsureRoot; - type Tippers = TenToFourteen; - type TipCountdown = TipCountdown; - type TipFindersFee = TipFindersFee; - type TipReportDepositBase = TipReportDepositBase; - type TipReportDepositPerByte = TipReportDepositPerByte; - type Event = (); - type ProposalRejection = (); - type ProposalBond = ProposalBond; - type ProposalBondMinimum = ProposalBondMinimum; - type SpendPeriod = SpendPeriod; - type Burn = Burn; - } - type System = frame_system::Module; - type Balances = pallet_balances::Module; - type Treasury = Module; - - fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - pallet_balances::GenesisConfig::{ - // Total issuance will be 200 with treasury account initialized at ED. - balances: vec![(0, 100), (1, 98), (2, 1)], - }.assimilate_storage(&mut t).unwrap(); - GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); - t.into() - } - - #[test] - fn genesis_config_works() { - new_test_ext().execute_with(|| { - assert_eq!(Treasury::pot(), 0); - assert_eq!(Treasury::proposal_count(), 0); - }); - } - - fn tip_hash() -> H256 { - BlakeTwo256::hash_of(&(BlakeTwo256::hash(b"awesome.dot"), 3u64)) - } - - #[test] - fn tip_new_cannot_be_used_twice() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10)); - assert_noop!( - Treasury::tip_new(Origin::signed(11), b"awesome.dot".to_vec(), 3, 10), - Error::::AlreadyKnown - ); - }); - } - - #[test] - fn report_awesome_and_tip_works() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 3)); - assert_eq!(Balances::reserved_balance(0), 12); - assert_eq!(Balances::free_balance(0), 88); - - // other reports don't count. - assert_noop!( - Treasury::report_awesome(Origin::signed(1), b"awesome.dot".to_vec(), 3), - Error::::AlreadyKnown - ); - - let h = tip_hash(); - assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); - assert_noop!(Treasury::tip(Origin::signed(9), h.clone(), 10), BadOrigin); - System::set_block_number(2); - assert_ok!(Treasury::close_tip(Origin::signed(100), h.into())); - assert_eq!(Balances::reserved_balance(0), 0); - assert_eq!(Balances::free_balance(0), 102); - assert_eq!(Balances::free_balance(3), 8); - }); - } - - #[test] - fn report_awesome_from_beneficiary_and_tip_works() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 0)); - assert_eq!(Balances::reserved_balance(0), 12); - assert_eq!(Balances::free_balance(0), 88); - let h = BlakeTwo256::hash_of(&(BlakeTwo256::hash(b"awesome.dot"), 0u64)); - assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); - System::set_block_number(2); - assert_ok!(Treasury::close_tip(Origin::signed(100), h.into())); - assert_eq!(Balances::reserved_balance(0), 0); - assert_eq!(Balances::free_balance(0), 110); - }); - } - - #[test] - fn close_tip_works() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_eq!(Treasury::pot(), 100); - - assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10)); - let h = tip_hash(); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); - assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::::StillOpen); - - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); - assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::::Premature); - - System::set_block_number(2); - assert_noop!(Treasury::close_tip(Origin::NONE, h.into()), BadOrigin); - assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); - assert_eq!(Balances::free_balance(3), 10); - - assert_noop!(Treasury::close_tip(Origin::signed(100), h.into()), Error::::UnknownTip); - }); - } - - #[test] - fn retract_tip_works() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 3)); - let h = tip_hash(); - assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); - assert_noop!(Treasury::retract_tip(Origin::signed(10), h.clone()), Error::::NotFinder); - assert_ok!(Treasury::retract_tip(Origin::signed(0), h.clone())); - System::set_block_number(2); - assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::::UnknownTip); - }); - } - - #[test] - fn tip_median_calculation_works() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 0)); - let h = tip_hash(); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 1000000)); - System::set_block_number(2); - assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); - assert_eq!(Balances::free_balance(3), 10); - }); - } - - #[test] - fn tip_changing_works() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10000)); - let h = tip_hash(); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10000)); - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10000)); - assert_ok!(Treasury::tip(Origin::signed(13), h.clone(), 0)); - assert_ok!(Treasury::tip(Origin::signed(14), h.clone(), 0)); - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 1000)); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 100)); - assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); - System::set_block_number(2); - assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); - assert_eq!(Balances::free_balance(3), 10); - }); - } - - #[test] - fn minting_works() { - new_test_ext().execute_with(|| { - // Check that accumulate works when we have Some value in Dummy already. - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_eq!(Treasury::pot(), 100); - }); - } - - #[test] - fn spend_proposal_takes_min_deposit() { - new_test_ext().execute_with(|| { - assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); - assert_eq!(Balances::free_balance(0), 99); - assert_eq!(Balances::reserved_balance(0), 1); - }); - } - - #[test] - fn spend_proposal_takes_proportional_deposit() { - new_test_ext().execute_with(|| { - assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); - assert_eq!(Balances::free_balance(0), 95); - assert_eq!(Balances::reserved_balance(0), 5); - }); - } - - #[test] - fn spend_proposal_fails_when_proposer_poor() { - new_test_ext().execute_with(|| { - assert_noop!( - Treasury::propose_spend(Origin::signed(2), 100, 3), - Error::::InsufficientProposersBalance, - ); - }); - } - - #[test] - fn accepted_spend_proposal_ignored_outside_spend_period() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - - assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); - - >::on_finalize(1); - assert_eq!(Balances::free_balance(3), 0); - assert_eq!(Treasury::pot(), 100); - }); - } - - #[test] - fn unused_pot_should_diminish() { - new_test_ext().execute_with(|| { - let init_total_issuance = Balances::total_issuance(); - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_eq!(Balances::total_issuance(), init_total_issuance + 100); - - >::on_finalize(2); - assert_eq!(Treasury::pot(), 50); - assert_eq!(Balances::total_issuance(), init_total_issuance + 50); - }); - } - - #[test] - fn rejected_spend_proposal_ignored_on_spend_period() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - - assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); - assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); - - >::on_finalize(2); - assert_eq!(Balances::free_balance(3), 0); - assert_eq!(Treasury::pot(), 50); - }); - } - - #[test] - fn reject_already_rejected_spend_proposal_fails() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - - assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); - assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); - assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); - }); - } - - #[test] - fn reject_non_existent_spend_proposal_fails() { - new_test_ext().execute_with(|| { - assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); - }); - } - - #[test] - fn accept_non_existent_spend_proposal_fails() { - new_test_ext().execute_with(|| { - assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); - }); - } - - #[test] - fn accept_already_rejected_spend_proposal_fails() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - - assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); - assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); - assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); - }); - } - - #[test] - fn accepted_spend_proposal_enacted_on_spend_period() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_eq!(Treasury::pot(), 100); - - assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); - - >::on_finalize(2); - assert_eq!(Balances::free_balance(3), 100); - assert_eq!(Treasury::pot(), 0); - }); - } - - #[test] - fn pot_underflow_should_not_diminish() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_eq!(Treasury::pot(), 100); - - assert_ok!(Treasury::propose_spend(Origin::signed(0), 150, 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); - - >::on_finalize(2); - assert_eq!(Treasury::pot(), 100); // Pot hasn't changed - - let _ = Balances::deposit_into_existing(&Treasury::account_id(), 100).unwrap(); - >::on_finalize(4); - assert_eq!(Balances::free_balance(3), 150); // Fund has been spent - assert_eq!(Treasury::pot(), 25); // Pot has finally changed - }); - } - - // Treasury account doesn't get deleted if amount approved to spend is all its free balance. - // i.e. pot should not include existential deposit needed for account survival. - #[test] - fn treasury_account_doesnt_get_deleted() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_eq!(Treasury::pot(), 100); - let treasury_balance = Balances::free_balance(&Treasury::account_id()); - - assert_ok!(Treasury::propose_spend(Origin::signed(0), treasury_balance, 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); - - >::on_finalize(2); - assert_eq!(Treasury::pot(), 100); // Pot hasn't changed - - assert_ok!(Treasury::propose_spend(Origin::signed(0), Treasury::pot(), 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 1)); - - >::on_finalize(4); - assert_eq!(Treasury::pot(), 0); // Pot is emptied - assert_eq!(Balances::free_balance(Treasury::account_id()), 1); // but the account is still there - }); - } - - // In case treasury account is not existing then it works fine. - // This is useful for chain that will just update runtime. - #[test] - fn inexistent_account_works() { - let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - pallet_balances::GenesisConfig::{ - balances: vec![(0, 100), (1, 99), (2, 1)], - }.assimilate_storage(&mut t).unwrap(); - // Treasury genesis config is not build thus treasury account does not exist - let mut t: sp_io::TestExternalities = t.into(); - - t.execute_with(|| { - assert_eq!(Balances::free_balance(Treasury::account_id()), 0); // Account does not exist - assert_eq!(Treasury::pot(), 0); // Pot is empty - - assert_ok!(Treasury::propose_spend(Origin::signed(0), 99, 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); - assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 1)); - >::on_finalize(2); - assert_eq!(Treasury::pot(), 0); // Pot hasn't changed - assert_eq!(Balances::free_balance(3), 0); // Balance of `3` hasn't changed - - Balances::make_free_balance_be(&Treasury::account_id(), 100); - assert_eq!(Treasury::pot(), 99); // Pot now contains funds - assert_eq!(Balances::free_balance(Treasury::account_id()), 100); // Account does exist - - >::on_finalize(4); - - assert_eq!(Treasury::pot(), 0); // Pot has changed - assert_eq!(Balances::free_balance(3), 99); // Balance of `3` has changed - }); - } -} diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs new file mode 100644 index 0000000000..a5acb2efe5 --- /dev/null +++ b/frame/treasury/src/tests.rs @@ -0,0 +1,449 @@ +use super::*; + +use frame_support::{assert_noop, assert_ok, impl_outer_origin, parameter_types, weights::Weight}; +use frame_support::traits::Contains; +use sp_core::H256; +use sp_runtime::{ + Perbill, + testing::Header, + traits::{BlakeTwo256, OnFinalize, IdentityLookup, BadOrigin}, +}; + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +#[derive(Clone, Eq, PartialEq)] +pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} +impl frame_system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type AvailableBlockRatio = AvailableBlockRatio; + type MaximumBlockLength = MaximumBlockLength; + type Version = (); + type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); +} +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} +impl pallet_balances::Trait for Test { + type Balance = u64; + type Event = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; +} +pub struct TenToFourteen; +impl Contains for TenToFourteen { + fn contains(n: &u64) -> bool { + *n >= 10 && *n <= 14 + } + fn sorted_members() -> Vec { + vec![10, 11, 12, 13, 14] + } +} +parameter_types! { + pub const ProposalBond: Permill = Permill::from_percent(5); + pub const ProposalBondMinimum: u64 = 1; + pub const SpendPeriod: u64 = 2; + pub const Burn: Permill = Permill::from_percent(50); + pub const TipCountdown: u64 = 1; + pub const TipFindersFee: Percent = Percent::from_percent(20); + pub const TipReportDepositBase: u64 = 1; + pub const TipReportDepositPerByte: u64 = 1; +} +impl Trait for Test { + type Currency = pallet_balances::Module; + type ApproveOrigin = frame_system::EnsureRoot; + type RejectOrigin = frame_system::EnsureRoot; + type Tippers = TenToFourteen; + type TipCountdown = TipCountdown; + type TipFindersFee = TipFindersFee; + type TipReportDepositBase = TipReportDepositBase; + type TipReportDepositPerByte = TipReportDepositPerByte; + type Event = (); + type ProposalRejection = (); + type ProposalBond = ProposalBond; + type ProposalBondMinimum = ProposalBondMinimum; + type SpendPeriod = SpendPeriod; + type Burn = Burn; +} +type System = frame_system::Module; +type Balances = pallet_balances::Module; +type Treasury = Module; + +fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig::{ + // Total issuance will be 200 with treasury account initialized at ED. + balances: vec![(0, 100), (1, 98), (2, 1)], + }.assimilate_storage(&mut t).unwrap(); + GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); + t.into() +} + +#[test] +fn genesis_config_works() { + new_test_ext().execute_with(|| { + assert_eq!(Treasury::pot(), 0); + assert_eq!(Treasury::proposal_count(), 0); + }); +} + +fn tip_hash() -> H256 { + BlakeTwo256::hash_of(&(BlakeTwo256::hash(b"awesome.dot"), 3u64)) +} + +#[test] +fn tip_new_cannot_be_used_twice() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10)); + assert_noop!( + Treasury::tip_new(Origin::signed(11), b"awesome.dot".to_vec(), 3, 10), + Error::::AlreadyKnown + ); + }); +} + +#[test] +fn report_awesome_and_tip_works() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(Treasury::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 3)); + assert_eq!(Balances::reserved_balance(0), 12); + assert_eq!(Balances::free_balance(0), 88); + + // other reports don't count. + assert_noop!( + Treasury::report_awesome(Origin::signed(1), b"awesome.dot".to_vec(), 3), + Error::::AlreadyKnown + ); + + let h = tip_hash(); + assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); + assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); + assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); + assert_noop!(Treasury::tip(Origin::signed(9), h.clone(), 10), BadOrigin); + System::set_block_number(2); + assert_ok!(Treasury::close_tip(Origin::signed(100), h.into())); + assert_eq!(Balances::reserved_balance(0), 0); + assert_eq!(Balances::free_balance(0), 102); + assert_eq!(Balances::free_balance(3), 8); + }); +} + +#[test] +fn report_awesome_from_beneficiary_and_tip_works() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(Treasury::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 0)); + assert_eq!(Balances::reserved_balance(0), 12); + assert_eq!(Balances::free_balance(0), 88); + let h = BlakeTwo256::hash_of(&(BlakeTwo256::hash(b"awesome.dot"), 0u64)); + assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); + assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); + assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); + System::set_block_number(2); + assert_ok!(Treasury::close_tip(Origin::signed(100), h.into())); + assert_eq!(Balances::reserved_balance(0), 0); + assert_eq!(Balances::free_balance(0), 110); + }); +} + +#[test] +fn close_tip_works() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Treasury::pot(), 100); + + assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10)); + let h = tip_hash(); + assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); + assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::::StillOpen); + + assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); + assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::::Premature); + + System::set_block_number(2); + assert_noop!(Treasury::close_tip(Origin::NONE, h.into()), BadOrigin); + assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); + assert_eq!(Balances::free_balance(3), 10); + + assert_noop!(Treasury::close_tip(Origin::signed(100), h.into()), Error::::UnknownTip); + }); +} + +#[test] +fn retract_tip_works() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(Treasury::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 3)); + let h = tip_hash(); + assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); + assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); + assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); + assert_noop!(Treasury::retract_tip(Origin::signed(10), h.clone()), Error::::NotFinder); + assert_ok!(Treasury::retract_tip(Origin::signed(0), h.clone())); + System::set_block_number(2); + assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::::UnknownTip); + }); +} + +#[test] +fn tip_median_calculation_works() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 0)); + let h = tip_hash(); + assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); + assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 1000000)); + System::set_block_number(2); + assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); + assert_eq!(Balances::free_balance(3), 10); + }); +} + +#[test] +fn tip_changing_works() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10000)); + let h = tip_hash(); + assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10000)); + assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10000)); + assert_ok!(Treasury::tip(Origin::signed(13), h.clone(), 0)); + assert_ok!(Treasury::tip(Origin::signed(14), h.clone(), 0)); + assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 1000)); + assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 100)); + assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); + System::set_block_number(2); + assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); + assert_eq!(Balances::free_balance(3), 10); + }); +} + +#[test] +fn minting_works() { + new_test_ext().execute_with(|| { + // Check that accumulate works when we have Some value in Dummy already. + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Treasury::pot(), 100); + }); +} + +#[test] +fn spend_proposal_takes_min_deposit() { + new_test_ext().execute_with(|| { + assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); + assert_eq!(Balances::free_balance(0), 99); + assert_eq!(Balances::reserved_balance(0), 1); + }); +} + +#[test] +fn spend_proposal_takes_proportional_deposit() { + new_test_ext().execute_with(|| { + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_eq!(Balances::free_balance(0), 95); + assert_eq!(Balances::reserved_balance(0), 5); + }); +} + +#[test] +fn spend_proposal_fails_when_proposer_poor() { + new_test_ext().execute_with(|| { + assert_noop!( + Treasury::propose_spend(Origin::signed(2), 100, 3), + Error::::InsufficientProposersBalance, + ); + }); +} + +#[test] +fn accepted_spend_proposal_ignored_outside_spend_period() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + + >::on_finalize(1); + assert_eq!(Balances::free_balance(3), 0); + assert_eq!(Treasury::pot(), 100); + }); +} + +#[test] +fn unused_pot_should_diminish() { + new_test_ext().execute_with(|| { + let init_total_issuance = Balances::total_issuance(); + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Balances::total_issuance(), init_total_issuance + 100); + + >::on_finalize(2); + assert_eq!(Treasury::pot(), 50); + assert_eq!(Balances::total_issuance(), init_total_issuance + 50); + }); +} + +#[test] +fn rejected_spend_proposal_ignored_on_spend_period() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); + + >::on_finalize(2); + assert_eq!(Balances::free_balance(3), 0); + assert_eq!(Treasury::pot(), 50); + }); +} + +#[test] +fn reject_already_rejected_spend_proposal_fails() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); + assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); + }); +} + +#[test] +fn reject_non_existent_spend_proposal_fails() { + new_test_ext().execute_with(|| { + assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); + }); +} + +#[test] +fn accept_non_existent_spend_proposal_fails() { + new_test_ext().execute_with(|| { + assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); + }); +} + +#[test] +fn accept_already_rejected_spend_proposal_fails() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); + assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); + }); +} + +#[test] +fn accepted_spend_proposal_enacted_on_spend_period() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Treasury::pot(), 100); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + + >::on_finalize(2); + assert_eq!(Balances::free_balance(3), 100); + assert_eq!(Treasury::pot(), 0); + }); +} + +#[test] +fn pot_underflow_should_not_diminish() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Treasury::pot(), 100); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 150, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + + >::on_finalize(2); + assert_eq!(Treasury::pot(), 100); // Pot hasn't changed + + let _ = Balances::deposit_into_existing(&Treasury::account_id(), 100).unwrap(); + >::on_finalize(4); + assert_eq!(Balances::free_balance(3), 150); // Fund has been spent + assert_eq!(Treasury::pot(), 25); // Pot has finally changed + }); +} + +// Treasury account doesn't get deleted if amount approved to spend is all its free balance. +// i.e. pot should not include existential deposit needed for account survival. +#[test] +fn treasury_account_doesnt_get_deleted() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Treasury::pot(), 100); + let treasury_balance = Balances::free_balance(&Treasury::account_id()); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), treasury_balance, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + + >::on_finalize(2); + assert_eq!(Treasury::pot(), 100); // Pot hasn't changed + + assert_ok!(Treasury::propose_spend(Origin::signed(0), Treasury::pot(), 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 1)); + + >::on_finalize(4); + assert_eq!(Treasury::pot(), 0); // Pot is emptied + assert_eq!(Balances::free_balance(Treasury::account_id()), 1); // but the account is still there + }); +} + +// In case treasury account is not existing then it works fine. +// This is useful for chain that will just update runtime. +#[test] +fn inexistent_account_works() { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig::{ + balances: vec![(0, 100), (1, 99), (2, 1)], + }.assimilate_storage(&mut t).unwrap(); + // Treasury genesis config is not build thus treasury account does not exist + let mut t: sp_io::TestExternalities = t.into(); + + t.execute_with(|| { + assert_eq!(Balances::free_balance(Treasury::account_id()), 0); // Account does not exist + assert_eq!(Treasury::pot(), 0); // Pot is empty + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 99, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 1)); + >::on_finalize(2); + assert_eq!(Treasury::pot(), 0); // Pot hasn't changed + assert_eq!(Balances::free_balance(3), 0); // Balance of `3` hasn't changed + + Balances::make_free_balance_be(&Treasury::account_id(), 100); + assert_eq!(Treasury::pot(), 99); // Pot now contains funds + assert_eq!(Balances::free_balance(Treasury::account_id()), 100); // Account does exist + + >::on_finalize(4); + + assert_eq!(Treasury::pot(), 0); // Pot has changed + assert_eq!(Balances::free_balance(3), 99); // Balance of `3` has changed + }); +} -- GitLab From 79859463bb0deb986488541098872d877435b1d6 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 20 Mar 2020 16:41:35 +0100 Subject: [PATCH 029/300] Ensure schnorrkel is always _at least_ 0.9.1 (#5333) --- client/consensus/babe/Cargo.toml | 2 +- primitives/consensus/babe/Cargo.toml | 2 +- primitives/core/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index 8a5d70e755..5486342ef7 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -40,7 +40,7 @@ futures = "0.3.1" futures-timer = "3.0.1" parking_lot = "0.10.0" log = "0.4.8" -schnorrkel = { version = "0.9", features = ["preaudit_deprecated"] } +schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated"] } rand = "0.7.2" merlin = "2.0" pdqselect = "0.1.0" diff --git a/primitives/consensus/babe/Cargo.toml b/primitives/consensus/babe/Cargo.toml index 2457bdac20..a948a30f2d 100644 --- a/primitives/consensus/babe/Cargo.toml +++ b/primitives/consensus/babe/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/paritytech/substrate/" sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../std" } -schnorrkel = { version = "0.9", features = ["preaudit_deprecated"], optional = true } +schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated"], optional = true } sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../api" } sp-consensus = { version = "0.8.0-alpha.4", optional = true, path = "../common" } sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../inherents" } diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 78e4f49a39..c20de3392f 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -40,7 +40,7 @@ futures = { version = "0.3.1", optional = true } ed25519-dalek = { version = "1.0.0-pre.3", default-features = false, features = ["u64_backend", "alloc"], optional = true } blake2-rfc = { version = "0.2.18", default-features = false, optional = true } tiny-keccak = { version = "2.0.1", features = ["keccak"], optional = true } -schnorrkel = { version = "0.9", features = ["preaudit_deprecated", "u64_backend"], default-features = false, optional = true } +schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated", "u64_backend"], default-features = false, optional = true } sha2 = { version = "0.8.0", default-features = false, optional = true } hex = { version = "0.4", default-features = false, optional = true } twox-hash = { version = "1.5.0", default-features = false, optional = true } -- GitLab From 0e213ba3027c89a032ea90412246280f0fe19973 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 20 Mar 2020 16:42:00 +0100 Subject: [PATCH 030/300] Remove the #[doc(hidden)] reexports of sc_network (#5264) * Remove the #[doc(hidden)] reexports of sc_network * Fix tests not building --- client/network-gossip/src/bridge.rs | 24 +--- client/network-gossip/src/state_machine.rs | 121 +++++++++--------- client/network/src/lib.rs | 7 - .../src/protocol/generic_proto/tests.rs | 2 +- client/network/src/protocol/light_dispatch.rs | 2 +- client/network/src/protocol/sync/blocks.rs | 2 +- 6 files changed, 71 insertions(+), 87 deletions(-) diff --git a/client/network-gossip/src/bridge.rs b/client/network-gossip/src/bridge.rs index 85e06a1d6f..0b3a58bba2 100644 --- a/client/network-gossip/src/bridge.rs +++ b/client/network-gossip/src/bridge.rs @@ -17,7 +17,6 @@ use crate::{Network, Validator}; use crate::state_machine::{ConsensusGossip, TopicNotification, PERIODIC_MAINTENANCE_INTERVAL}; -use sc_network::message::generic::ConsensusMessage; use sc_network::{Event, ReputationChange}; use futures::{prelude::*, channel::mpsc}; @@ -77,12 +76,7 @@ impl GossipEngine { topic: B::Hash, message: Vec, ) { - let message = ConsensusMessage { - engine_id: self.engine_id, - data: message, - }; - - self.state_machine.register_message(topic, message); + self.state_machine.register_message(topic, self.engine_id, message); } /// Broadcast all messages with given topic. @@ -114,22 +108,14 @@ impl GossipEngine { message: Vec, force: bool, ) { - let message = ConsensusMessage { - engine_id: self.engine_id, - data: message, - }; - - self.state_machine.multicast(&mut *self.network, topic, message, force) + self.state_machine.multicast(&mut *self.network, topic, self.engine_id, message, force) } /// Send addressed message to the given peers. The message is not kept or multicast /// later on. pub fn send_message(&mut self, who: Vec, data: Vec) { for who in &who { - self.state_machine.send_message(&mut *self.network, who, ConsensusMessage { - engine_id: self.engine_id, - data: data.clone(), - }); + self.state_machine.send_message(&mut *self.network, who, self.engine_id, data.clone()); } } @@ -170,9 +156,7 @@ impl Future for GossipEngine { remote, messages.into_iter() .filter_map(|(engine, data)| if engine == engine_id { - Some(ConsensusMessage { - engine_id: engine, data: data.to_vec(), - }) + Some((engine, data.to_vec())) } else { None }) .collect() ); diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index 675f021365..a800f1e3aa 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -26,7 +26,6 @@ use lru::LruCache; use libp2p::PeerId; use sp_runtime::traits::{Block as BlockT, Hash, HashFor}; use sp_runtime::ConsensusEngineId; -pub use sc_network::message::generic::{Message, ConsensusMessage}; use sc_network::config::Roles; use wasm_timer::Instant; @@ -67,7 +66,8 @@ pub struct TopicNotification { struct MessageEntry { message_hash: B::Hash, topic: B::Hash, - message: ConsensusMessage, + engine_id: ConsensusEngineId, + message: Vec, sender: Option, } @@ -89,7 +89,8 @@ impl<'g, 'p, B: BlockT> ValidatorContext for NetworkContext<'g, 'p, B> { self.gossip.multicast( self.network, topic, - ConsensusMessage{ data: message, engine_id: self.engine_id.clone() }, + self.engine_id.clone(), + message, force, ); } @@ -113,11 +114,10 @@ fn propagate<'a, B: BlockT, I>( validators: &HashMap>>, ) // (msg_hash, topic, message) - where I: Clone + IntoIterator, + where I: Clone + IntoIterator)>, { let mut check_fns = HashMap::new(); - let mut message_allowed = move |who: &PeerId, intent: MessageIntent, topic: &B::Hash, message: &ConsensusMessage| { - let engine_id = message.engine_id; + let mut message_allowed = move |who: &PeerId, intent: MessageIntent, topic: &B::Hash, engine_id: ConsensusEngineId, message: &Vec| { let check_fn = match check_fns.entry(engine_id) { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(vacant) => match validators.get(&engine_id) { @@ -126,11 +126,11 @@ fn propagate<'a, B: BlockT, I>( } }; - (check_fn)(who, intent, topic, &message.data) + (check_fn)(who, intent, topic, &message) }; for (id, ref mut peer) in peers.iter_mut() { - for (message_hash, topic, message) in messages.clone() { + for (message_hash, topic, engine_id, message) in messages.clone() { let intent = match intent { MessageIntent::Broadcast { .. } => if peer.known_messages.contains(&message_hash) { @@ -149,14 +149,14 @@ fn propagate<'a, B: BlockT, I>( other => other, }; - if !message_allowed(id, intent, &topic, &message) { + if !message_allowed(id, intent, &topic, engine_id, &message) { continue; } peer.known_messages.insert(message_hash.clone()); trace!(target: "gossip", "Propagating to {}: {:?}", id, message); - network.write_notification(id.clone(), message.engine_id, message.data.clone()); + network.write_notification(id.clone(), engine_id, message.clone()); } } } @@ -225,13 +225,15 @@ impl ConsensusGossip { &mut self, message_hash: B::Hash, topic: B::Hash, - message: ConsensusMessage, + engine_id: ConsensusEngineId, + message: Vec, sender: Option, ) { if self.known_messages.put(message_hash.clone(), ()).is_none() { self.messages.push(MessageEntry { message_hash, topic, + engine_id, message, sender, }); @@ -246,10 +248,11 @@ impl ConsensusGossip { pub fn register_message( &mut self, topic: B::Hash, - message: ConsensusMessage, + engine_id: ConsensusEngineId, + message: Vec, ) { - let message_hash = HashFor::::hash(&message.data[..]); - self.register_message_hashed(message_hash, topic, message, None); + let message_hash = HashFor::::hash(&message[..]); + self.register_message_hashed(message_hash, topic, engine_id, message, None); } /// Call when a peer has been disconnected to stop tracking gossip status. @@ -273,7 +276,7 @@ impl ConsensusGossip { /// Rebroadcast all messages to all peers. fn rebroadcast(&mut self, network: &mut dyn Network) { let messages = self.messages.iter() - .map(|entry| (&entry.message_hash, &entry.topic, &entry.message)); + .map(|entry| (&entry.message_hash, &entry.topic, entry.engine_id, &entry.message)); propagate(network, messages, MessageIntent::PeriodicRebroadcast, &mut self.peers, &self.validators); } @@ -281,7 +284,9 @@ impl ConsensusGossip { pub fn broadcast_topic(&mut self, network: &mut dyn Network, topic: B::Hash, force: bool) { let messages = self.messages.iter() .filter_map(|entry| - if entry.topic == topic { Some((&entry.message_hash, &entry.topic, &entry.message)) } else { None } + if entry.topic == topic { + Some((&entry.message_hash, &entry.topic, entry.engine_id, &entry.message)) + } else { None } ); let intent = if force { MessageIntent::ForcedBroadcast } else { MessageIntent::Broadcast }; propagate(network, messages, intent, &mut self.peers, &self.validators); @@ -301,7 +306,7 @@ impl ConsensusGossip { let mut check_fns = HashMap::new(); let mut message_expired = move |entry: &MessageEntry| { - let engine_id = entry.message.engine_id; + let engine_id = entry.engine_id; let check_fn = match check_fns.entry(engine_id) { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(vacant) => match validators.get(&engine_id) { @@ -310,7 +315,7 @@ impl ConsensusGossip { } }; - (check_fn)(entry.topic, &entry.message.data) + (check_fn)(entry.topic, &entry.message) }; self.messages.retain(|entry| !message_expired(entry)); @@ -332,10 +337,10 @@ impl ConsensusGossip { { let (tx, rx) = mpsc::unbounded(); for entry in self.messages.iter_mut() - .filter(|e| e.topic == topic && e.message.engine_id == engine_id) + .filter(|e| e.topic == topic && e.engine_id == engine_id) { tx.unbounded_send(TopicNotification { - message: entry.message.data.clone(), + message: entry.message.clone(), sender: entry.sender.clone(), }) .expect("receiver known to be live; qed"); @@ -346,22 +351,22 @@ impl ConsensusGossip { rx } - /// Handle an incoming ConsensusMessage for topic by who via protocol. Discard message if topic - /// already known, the message is old, its source peers isn't a registered peer or the connection - /// to them is broken. Return `Some(topic, message)` if it was added to the internal queue, `None` + /// Handle an incoming message for topic by who via protocol. Discard message if topic already + /// known, the message is old, its source peers isn't a registered peer or the connection to + /// them is broken. Return `Some(topic, message)` if it was added to the internal queue, `None` /// in all other cases. pub fn on_incoming( &mut self, network: &mut dyn Network, who: PeerId, - messages: Vec, + messages: Vec<(ConsensusEngineId, Vec)>, ) { if !messages.is_empty() { trace!(target: "gossip", "Received {} messages from peer {}", messages.len(), who); } - for message in messages { - let message_hash = HashFor::::hash(&message.data[..]); + for (engine_id, message) in messages { + let message_hash = HashFor::::hash(&message[..]); if self.known_messages.contains(&message_hash) { trace!(target:"gossip", "Ignored already known message from {}", who); @@ -369,13 +374,12 @@ impl ConsensusGossip { continue; } - let engine_id = message.engine_id; // validate the message let validation = self.validators.get(&engine_id) .cloned() .map(|v| { let mut context = NetworkContext { gossip: self, network, engine_id }; - v.validate(&mut context, &who, &message.data) + v.validate(&mut context, &who, &message) }); let validation_result = match validation { @@ -398,7 +402,7 @@ impl ConsensusGossip { debug!(target: "gossip", "Pushing consensus message to sinks for {}.", topic); entry.get_mut().retain(|sink| { if let Err(e) = sink.unbounded_send(TopicNotification { - message: message.data.clone(), + message: message.clone(), sender: Some(who.clone()) }) { trace!(target: "gossip", "Error broadcasting message notification: {:?}", e); @@ -410,7 +414,7 @@ impl ConsensusGossip { } } if keep { - self.register_message_hashed(message_hash, topic, message, Some(who.clone())); + self.register_message_hashed(message_hash, topic, engine_id, message, Some(who.clone())); } } else { trace!(target:"gossip", "Ignored statement from unregistered peer {}", who); @@ -438,7 +442,7 @@ impl ConsensusGossip { }; if let Some(ref mut peer) = self.peers.get_mut(who) { - for entry in self.messages.iter().filter(|m| m.topic == topic && m.message.engine_id == engine_id) { + for entry in self.messages.iter().filter(|m| m.topic == topic && m.engine_id == engine_id) { let intent = if force { MessageIntent::ForcedBroadcast } else { @@ -449,14 +453,14 @@ impl ConsensusGossip { continue; } - if !message_allowed(who, intent, &entry.topic, &entry.message.data) { + if !message_allowed(who, intent, &entry.topic, &entry.message) { continue; } peer.known_messages.insert(entry.message_hash.clone()); trace!(target: "gossip", "Sending topic message to {}: {:?}", who, entry.message); - network.write_notification(who.clone(), engine_id, entry.message.data.clone()); + network.write_notification(who.clone(), engine_id, entry.message.clone()); } } } @@ -466,13 +470,14 @@ impl ConsensusGossip { &mut self, network: &mut dyn Network, topic: B::Hash, - message: ConsensusMessage, + engine_id: ConsensusEngineId, + message: Vec, force: bool, ) { - let message_hash = HashFor::::hash(&message.data); - self.register_message_hashed(message_hash, topic, message.clone(), None); + let message_hash = HashFor::::hash(&message); + self.register_message_hashed(message_hash, topic, engine_id, message.clone(), None); let intent = if force { MessageIntent::ForcedBroadcast } else { MessageIntent::Broadcast }; - propagate(network, iter::once((&message_hash, &topic, &message)), intent, &mut self.peers, &self.validators); + propagate(network, iter::once((&message_hash, &topic, engine_id, &message)), intent, &mut self.peers, &self.validators); } /// Send addressed message to a peer. The message is not kept or multicast @@ -481,19 +486,20 @@ impl ConsensusGossip { &mut self, network: &mut dyn Network, who: &PeerId, - message: ConsensusMessage, + engine_id: ConsensusEngineId, + message: Vec, ) { let peer = match self.peers.get_mut(who) { None => return, Some(peer) => peer, }; - let message_hash = HashFor::::hash(&message.data); + let message_hash = HashFor::::hash(&message); trace!(target: "gossip", "Sending direct to {}: {:?}", who, message); peer.known_messages.insert(message_hash); - network.write_notification(who.clone(), message.engine_id, message.data); + network.write_notification(who.clone(), engine_id, message); } } @@ -513,7 +519,8 @@ mod tests { $consensus.messages.push(MessageEntry { message_hash: $hash, topic: $topic, - message: ConsensusMessage { data: $m, engine_id: [0, 0, 0, 0]}, + engine_id: [0, 0, 0, 0], + message: $m, sender: None, }); } @@ -588,13 +595,14 @@ mod tests { let mut consensus = ConsensusGossip::::new(); consensus.register_validator_internal([0, 0, 0, 0], Arc::new(AllowAll)); - let message = ConsensusMessage { data: vec![4, 5, 6], engine_id: [0, 0, 0, 0] }; + let engine_id = [0, 0, 0, 0]; + let message = vec![4, 5, 6]; let topic = HashFor::::hash(&[1,2,3]); - consensus.register_message(topic, message.clone()); + consensus.register_message(topic, engine_id, message.clone()); let mut stream = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); - assert_eq!(stream.next(), Some(TopicNotification { message: message.data, sender: None })); + assert_eq!(stream.next(), Some(TopicNotification { message: message, sender: None })); } #[test] @@ -602,11 +610,11 @@ mod tests { let mut consensus = ConsensusGossip::::new(); let topic = [1; 32].into(); - let msg_a = ConsensusMessage { data: vec![1, 2, 3], engine_id: [0, 0, 0, 0] }; - let msg_b = ConsensusMessage { data: vec![4, 5, 6], engine_id: [0, 0, 0, 0] }; + let msg_a = vec![1, 2, 3]; + let msg_b = vec![4, 5, 6]; - consensus.register_message(topic, msg_a); - consensus.register_message(topic, msg_b); + consensus.register_message(topic, [0, 0, 0, 0], msg_a); + consensus.register_message(topic, [0, 0, 0, 0], msg_b); assert_eq!(consensus.messages.len(), 2); } @@ -616,17 +624,16 @@ mod tests { let mut consensus = ConsensusGossip::::new(); consensus.register_validator_internal([0, 0, 0, 0], Arc::new(AllowAll)); - let data = vec![4, 5, 6]; - let message = ConsensusMessage { data: data.clone(), engine_id: [0, 0, 0, 0] }; + let message = vec![4, 5, 6]; let topic = HashFor::::hash(&[1, 2, 3]); - consensus.register_message(topic, message.clone()); + consensus.register_message(topic, [0, 0, 0, 0], message.clone()); let mut stream1 = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); let mut stream2 = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); - assert_eq!(stream1.next(), Some(TopicNotification { message: data.clone(), sender: None })); - assert_eq!(stream2.next(), Some(TopicNotification { message: data, sender: None })); + assert_eq!(stream1.next(), Some(TopicNotification { message: message.clone(), sender: None })); + assert_eq!(stream2.next(), Some(TopicNotification { message, sender: None })); } #[test] @@ -635,11 +642,11 @@ mod tests { consensus.register_validator_internal([0, 0, 0, 0], Arc::new(AllowAll)); let topic = [1; 32].into(); - let msg_a = ConsensusMessage { data: vec![1, 2, 3], engine_id: [0, 0, 0, 0] }; - let msg_b = ConsensusMessage { data: vec![4, 5, 6], engine_id: [0, 0, 0, 1] }; + let msg_a = vec![1, 2, 3]; + let msg_b = vec![4, 5, 6]; - consensus.register_message(topic, msg_a); - consensus.register_message(topic, msg_b); + consensus.register_message(topic, [0, 0, 0, 0], msg_a); + consensus.register_message(topic, [0, 0, 0, 1], msg_b); let mut stream = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index a5397a4e3e..f29fb00a4f 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -183,13 +183,6 @@ pub use libp2p::{Multiaddr, PeerId}; #[doc(inline)] pub use libp2p::multiaddr; -// Note: these re-exports shouldn't be part of the public API of the crate and will be removed in -// the future. -#[doc(hidden)] -pub use protocol::message; -#[doc(hidden)] -pub use protocol::message::Status as StatusMessage; - pub use sc_peerset::ReputationChange; /// Extension trait for `NetworkBehaviour` that also accepts discovering nodes. diff --git a/client/network/src/protocol/generic_proto/tests.rs b/client/network/src/protocol/generic_proto/tests.rs index b8436e2c7f..632e06ec39 100644 --- a/client/network/src/protocol/generic_proto/tests.rs +++ b/client/network/src/protocol/generic_proto/tests.rs @@ -26,7 +26,7 @@ use libp2p::{PeerId, Multiaddr, Transport}; use rand::seq::SliceRandom; use std::{error, io, task::Context, task::Poll, time::Duration}; use std::collections::HashSet; -use crate::message::{generic::BlockResponse, Message}; +use crate::protocol::message::{generic::BlockResponse, Message}; use crate::protocol::generic_proto::{GenericProto, GenericProtoOut}; use sp_test_primitives::Block; diff --git a/client/network/src/protocol/light_dispatch.rs b/client/network/src/protocol/light_dispatch.rs index 8146172e15..22d26075b3 100644 --- a/client/network/src/protocol/light_dispatch.rs +++ b/client/network/src/protocol/light_dispatch.rs @@ -689,7 +689,7 @@ pub mod tests { ChangesProof, RemoteCallRequest, RemoteReadRequest, RemoteReadChildRequest, RemoteChangesRequest, RemoteBodyRequest}; use crate::config::Roles; - use crate::message::{self, BlockAttributes, Direction, FromBlock, RequestId}; + use crate::protocol::message::{self, BlockAttributes, Direction, FromBlock, RequestId}; use libp2p::PeerId; use super::{REQUEST_TIMEOUT, LightDispatch, LightDispatchNetwork, RequestData, StorageProof}; use sp_test_primitives::{Block, Header}; diff --git a/client/network/src/protocol/sync/blocks.rs b/client/network/src/protocol/sync/blocks.rs index 31b798ace2..359287701e 100644 --- a/client/network/src/protocol/sync/blocks.rs +++ b/client/network/src/protocol/sync/blocks.rs @@ -212,7 +212,7 @@ impl BlockCollection { #[cfg(test)] mod test { use super::{BlockCollection, BlockData, BlockRangeState}; - use crate::{message, PeerId}; + use crate::{protocol::message, PeerId}; use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper}; use sp_core::H256; -- GitLab From c436863762eeb2b5b1f7c2bc3d93b434b781bf7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 20 Mar 2020 16:57:39 +0100 Subject: [PATCH 031/300] Make sure frame examples compile for wasm (#5332) * Make sure frame examples compile for wasm This makes sure that `frame-example` and `frame-example-offchain-worker` compile for wasm. This also fixes compilation for these crates. The offchain worker example doesn't use serde-json anymore as that is too heavy and breaks `no_std` compilation. * Apply suggestions from code review Co-Authored-By: Nikolay Volf Co-authored-by: Nikolay Volf --- .gitlab-ci.yml | 18 +++++++ Cargo.lock | 19 +++++-- frame/example-offchain-worker/Cargo.toml | 3 +- frame/example-offchain-worker/src/lib.rs | 61 ++++++++++++++-------- frame/example-offchain-worker/src/tests.rs | 22 ++++++-- frame/example/Cargo.toml | 2 +- 6 files changed, 93 insertions(+), 32 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8791690d89..8083e34ea9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -214,6 +214,24 @@ test-frame-staking: - WASM_BUILD_NO_COLOR=1 time cargo test --release --verbose --no-default-features --features std - sccache -s +test-frame-examples-compile-to-wasm: + stage: test + <<: *docker-env + variables: + # Enable debug assertions since we are running optimized builds for testing + # but still want to have debug assertions. + RUSTFLAGS: -Cdebug-assertions=y + RUST_BACKTRACE: 1 + except: + variables: + - $DEPLOY_TAG + script: + - cd frame/example-offchain-worker/ + - cargo +nightly build --target=wasm32-unknown-unknown --no-default-features + - cd ../example + - cargo +nightly build --target=wasm32-unknown-unknown --no-default-features + - sccache -s + test-wasmtime: stage: test <<: *docker-env diff --git a/Cargo.lock b/Cargo.lock index dc3530103a..8a55a09772 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3063,6 +3063,15 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "lite-json" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faa835713bb12ba5204013497da16caf2dd2eee25ca829d0efaa054fb38c4ddd" +dependencies = [ + "paste", +] + [[package]] name = "lock_api" version = "0.3.3" @@ -4147,9 +4156,9 @@ version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", + "lite-json", "parity-scale-codec", "serde", - "serde_json", "sp-core", "sp-io", "sp-runtime", @@ -6718,18 +6727,18 @@ checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" [[package]] name = "serde" -version = "1.0.104" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +checksum = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.104" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" +checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" dependencies = [ "proc-macro2", "quote", diff --git a/frame/example-offchain-worker/Cargo.toml b/frame/example-offchain-worker/Cargo.toml index 3c705138f4..a700c6fad7 100644 --- a/frame/example-offchain-worker/Cargo.toml +++ b/frame/example-offchain-worker/Cargo.toml @@ -17,7 +17,7 @@ sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../p sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -serde_json = { version = "1.0.46", default-features = false, features = ["alloc"] } +lite-json = { version = "0.1", default-features = false } [features] default = ["std"] @@ -26,6 +26,7 @@ std = [ "frame-support/std", "frame-system/std", "serde", + "lite-json/std", "sp-core/std", "sp-io/std", "sp-runtime/std", diff --git a/frame/example-offchain-worker/src/lib.rs b/frame/example-offchain-worker/src/lib.rs index b05d7c38da..5a417fa078 100644 --- a/frame/example-offchain-worker/src/lib.rs +++ b/frame/example-offchain-worker/src/lib.rs @@ -47,13 +47,14 @@ use frame_support::{ weights::SimpleDispatchInfo, }; use frame_system::{self as system, ensure_signed, ensure_none, offchain}; -use serde_json as json; use sp_core::crypto::KeyTypeId; use sp_runtime::{ offchain::{http, Duration, storage::StorageValueRef}, traits::Zero, transaction_validity::{InvalidTransaction, ValidTransaction, TransactionValidity}, }; +use sp_std::{vec, vec::Vec}; +use lite_json::json::JsonValue; #[cfg(test)] mod tests; @@ -320,7 +321,7 @@ impl Module { } /// A helper function to fetch the price and send signed transaction. - fn fetch_price_and_send_signed() -> Result<(), String> { + fn fetch_price_and_send_signed() -> Result<(), &'static str> { use system::offchain::SubmitSignedTransaction; // Firstly we check if there are any accounts in the local keystore that are capable of // signing the transaction. @@ -334,7 +335,7 @@ impl Module { // Make an external HTTP request to fetch the current price. // Note this call will block until response is received. - let price = Self::fetch_price().map_err(|e| format!("{:?}", e))?; + let price = Self::fetch_price().map_err(|_| "Failed to fetch price")?; // Received price is wrapped into a call to `submit_price` public function of this pallet. // This means that the transaction, when executed, will simply call that function passing @@ -357,20 +358,18 @@ impl Module { } /// A helper function to fetch the price and send unsigned transaction. - fn fetch_price_and_send_unsigned(block_number: T::BlockNumber) -> Result<(), String> { + fn fetch_price_and_send_unsigned(block_number: T::BlockNumber) -> Result<(), &'static str> { use system::offchain::SubmitUnsignedTransaction; // Make sure we don't fetch the price if unsigned transaction is going to be rejected // anyway. let next_unsigned_at = >::get(); if next_unsigned_at > block_number { - return Err( - format!("Too early to send unsigned transaction. Next at: {:?}", next_unsigned_at) - )? + return Err("Too early to send unsigned transaction") } // Make an external HTTP request to fetch the current price. // Note this call will block until response is received. - let price = Self::fetch_price().map_err(|e| format!("{:?}", e))?; + let price = Self::fetch_price().map_err(|_| "Failed to fetch price")?; // Received price is wrapped into a call to `submit_price_unsigned` public function of this // pallet. This means that the transaction, when executed, will simply call that function @@ -428,21 +427,17 @@ impl Module { // Note that the return object allows you to read the body in chunks as well // with a way to control the deadline. let body = response.body().collect::>(); - // Next we parse the response using `serde_json`. Even though it's possible to use - // `serde_derive` and deserialize to a struct it's not recommended due to blob size - // overhead introduced by such code. Deserializing to `json::Value` is much more - // lightweight and should be preferred, especially if we only care about a small number - // of properties from the response. - let val: Result = json::from_slice(&body); - // Let's parse the price as float value. Note that you should avoid using floats in the - // runtime, it's fine to do that in the offchain worker, but we do convert it to an integer - // before submitting on-chain. - let price = val.ok().and_then(|v| v.get("USD").and_then(|v| v.as_f64())); - let price = match price { - Some(pricef) => Ok((pricef * 100.) as u32), + + // Create a str slice from the body. + let body_str = sp_std::str::from_utf8(&body).map_err(|_| { + debug::warn!("No UTF8 body"); + http::Error::Unknown + })?; + + let price = match Self::parse_price(body_str) { + Some(price) => Ok(price), None => { - let s = core::str::from_utf8(&body); - debug::warn!("Unable to extract price from the response: {:?}", s); + debug::warn!("Unable to extract price from the response: {:?}", body_str); Err(http::Error::Unknown) } }?; @@ -452,6 +447,28 @@ impl Module { Ok(price) } + /// Parse the price from the given JSON string using `lite-json`. + /// + /// Returns `None` when parsing failed or `Some(price in cents)` when parsing is successful. + fn parse_price(price_str: &str) -> Option { + let val = lite_json::parse_json(price_str); + let price = val.ok().and_then(|v| match v { + JsonValue::Object(obj) => { + let mut chars = "USD".chars(); + obj.into_iter() + .find(|(k, _)| k.iter().all(|k| Some(*k) == chars.next())) + .and_then(|v| match v.1 { + JsonValue::Number(number) => Some(number), + _ => None, + }) + }, + _ => None + })?; + + let exp = price.fraction_length.checked_sub(2).unwrap_or(0); + Some(price.integer as u32 * 100 + (price.fraction / 10_u64.pow(exp)) as u32) + } + /// Add new price to the list. fn add_price(who: T::AccountId, price: u32) { debug::info!("Adding to the average: {}", price); diff --git a/frame/example-offchain-worker/src/tests.rs b/frame/example-offchain-worker/src/tests.rs index 9b6a567a17..f64503b0a9 100644 --- a/frame/example-offchain-worker/src/tests.rs +++ b/frame/example-offchain-worker/src/tests.rs @@ -132,7 +132,7 @@ fn should_make_http_call_and_parse_result() { // when let price = Example::fetch_price().unwrap(); // then - assert_eq!(price, 15522); + assert_eq!(price, 15523); }); } @@ -164,7 +164,7 @@ fn should_submit_signed_transaction_on_chain() { assert!(pool_state.read().transactions.is_empty()); let tx = Extrinsic::decode(&mut &*tx).unwrap(); assert_eq!(tx.signature.unwrap().0, 0); - assert_eq!(tx.call, Call::submit_price(15522)); + assert_eq!(tx.call, Call::submit_price(15523)); }); } @@ -186,7 +186,7 @@ fn should_submit_unsigned_transaction_on_chain() { assert!(pool_state.read().transactions.is_empty()); let tx = Extrinsic::decode(&mut &*tx).unwrap(); assert_eq!(tx.signature, None); - assert_eq!(tx.call, Call::submit_price_unsigned(1, 15522)); + assert_eq!(tx.call, Call::submit_price_unsigned(1, 15523)); }); } @@ -208,3 +208,19 @@ fn price_oracle_response(state: &mut testing::OffchainState) { ..Default::default() }); } + +#[test] +fn parse_price_works() { + let test_data = vec![ + ("{\"USD\":6536.92}", Some(653692)), + ("{\"USD\":65.92}", Some(6592)), + ("{\"USD\":6536.924565}", Some(653692)), + ("{\"USD\":6536}", Some(653600)), + ("{\"USD2\":6536}", None), + ("{\"USD\":\"6432\"}", None), + ]; + + for (json, expected) in test_data { + assert_eq!(expected, Example::parse_price(json)); + } +} diff --git a/frame/example/Cargo.toml b/frame/example/Cargo.toml index ee1b870e03..5db9aca45b 100644 --- a/frame/example/Cargo.toml +++ b/frame/example/Cargo.toml @@ -20,7 +20,7 @@ sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../pr sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core", default-features = false } [features] default = ["std"] -- GitLab From bfb6d4dc9f67d2862d5976c6d785ce5cfc53512b Mon Sep 17 00:00:00 2001 From: Hero Bird Date: Fri, 20 Mar 2020 18:46:51 +0100 Subject: [PATCH 032/300] Implement ext_ hashes for contracts (issue #5258) (#5326) * Implement ext_ hashes for contracts (issue #5258) * load cryto hash .wat from raw string literal instead of file * update .wat contents for testing crypto hashes * remove unnecessary 'static * fix bug in input (call_indirect required 1+ at least it seems) * no longer use scratch buffer for crypto hash functions * improve doc comments of ext_ hash functions * remove unnecessary comment in .wat test file * add return value (const 0) to contract test to hopefully enable result buffer * fix bug in contract assertion * implement proper output_len in contract * implement proper test for crypto hashes * bump spec_version 238 -> 239 * fix COMPLEXITY description * remove final invalid instances of scratch buffer from docs --- bin/node/runtime/src/lib.rs | 2 +- frame/contracts/COMPLEXITY.md | 25 ++++ frame/contracts/src/tests.rs | 146 +++++++++++++++++++ frame/contracts/src/wasm/runtime.rs | 218 ++++++++++++++++++++++++++++ 4 files changed, 390 insertions(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 98194af924..e6c2ca05f0 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -82,7 +82,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 238, + spec_version: 239, impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/contracts/COMPLEXITY.md b/frame/contracts/COMPLEXITY.md index f11e835bc1..a5e6a651ee 100644 --- a/frame/contracts/COMPLEXITY.md +++ b/frame/contracts/COMPLEXITY.md @@ -454,3 +454,28 @@ function performs a DB read. This function serializes the current block's number into the scratch buffer. **complexity**: Assuming that the block number is of constant size, this function has constant complexity. + +## Built-in hashing functions + +This paragraph concerns the following supported built-in hash functions: + +- `SHA2` with 256-bit width +- `KECCAK` with 256-bit width +- `BLAKE2` with 128-bit and 256-bit widths +- `TWOX` with 64-bit, 128-bit and 256-bit widths + +These functions compute a cryptographic hash on the given inputs and copy the +resulting hash directly back into the sandboxed Wasm contract output buffer. + +Execution of the function consists of the following steps: + +1. Load data stored in the input buffer into an intermediate buffer. +2. Compute the cryptographic hash `H` on the intermediate buffer. +3. Copy back the bytes of `H` into the contract side output buffer. + +**complexity**: Complexity is proportional to the size of the input buffer in bytes +as well as to the size of the output buffer in bytes. Also different cryptographic +algorithms have different inherent complexity so users must expect the above +mentioned crypto hashes to have varying gas costs. +The complexity of each cryptographic hash function highly depends on the underlying +implementation. diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 165e23e8b8..6a47b2ee17 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -2736,3 +2736,149 @@ fn get_runtime_storage() { )); }); } + +const CODE_CRYPTO_HASHES: &str = r#" +(module + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) + + (import "env" "ext_hash_sha2_256" (func $ext_hash_sha2_256 (param i32 i32 i32))) + (import "env" "ext_hash_keccak_256" (func $ext_hash_keccak_256 (param i32 i32 i32))) + (import "env" "ext_hash_blake2_256" (func $ext_hash_blake2_256 (param i32 i32 i32))) + (import "env" "ext_hash_blake2_128" (func $ext_hash_blake2_128 (param i32 i32 i32))) + (import "env" "ext_hash_twox_256" (func $ext_hash_twox_256 (param i32 i32 i32))) + (import "env" "ext_hash_twox_128" (func $ext_hash_twox_128 (param i32 i32 i32))) + (import "env" "ext_hash_twox_64" (func $ext_hash_twox_64 (param i32 i32 i32))) + + (import "env" "memory" (memory 1 1)) + + (type $hash_fn_sig (func (param i32 i32 i32))) + (table 8 funcref) + (elem (i32.const 1) + $ext_hash_sha2_256 + $ext_hash_keccak_256 + $ext_hash_blake2_256 + $ext_hash_blake2_128 + $ext_hash_twox_256 + $ext_hash_twox_128 + $ext_hash_twox_64 + ) + (data (i32.const 1) "20202010201008") ;; Output sizes of the hashes in order in hex. + + ;; Not in use by the tests besides instantiating the contract. + (func (export "deploy")) + + ;; Called by the tests. + ;; + ;; The `call` function expects data in a certain format in the scratch + ;; buffer. + ;; + ;; 1. The first byte encodes an identifier for the crypto hash function + ;; under test. (*) + ;; 2. The rest encodes the input data that is directly fed into the + ;; crypto hash function chosen in 1. + ;; + ;; The `deploy` function then computes the chosen crypto hash function + ;; given the input and puts the result back into the scratch buffer. + ;; After contract execution the test driver then asserts that the returned + ;; values are equal to the expected bytes for the input and chosen hash + ;; function. + ;; + ;; (*) The possible value for the crypto hash identifiers can be found below: + ;; + ;; | value | Algorithm | Bit Width | + ;; |-------|-----------|-----------| + ;; | 0 | SHA2 | 256 | + ;; | 1 | KECCAK | 256 | + ;; | 2 | BLAKE2 | 256 | + ;; | 3 | BLAKE2 | 128 | + ;; | 4 | TWOX | 256 | + ;; | 5 | TWOX | 128 | + ;; | 6 | TWOX | 64 | + ;; --------------------------------- + (func (export "call") (result i32) + (local $chosen_hash_fn i32) + (local $input_ptr i32) + (local $input_len i32) + (local $output_ptr i32) + (local $output_len i32) + (local.set $input_ptr (i32.const 10)) + (call $ext_scratch_read (local.get $input_ptr) (i32.const 0) (call $ext_scratch_size)) + (local.set $chosen_hash_fn (i32.load8_u (local.get $input_ptr))) + (if (i32.gt_u (local.get $chosen_hash_fn) (i32.const 7)) + ;; We check that the chosen hash fn identifier is within bounds: [0,7] + (unreachable) + ) + (local.set $input_ptr (i32.add (local.get $input_ptr) (i32.const 1))) + (local.set $input_len (i32.sub (call $ext_scratch_size) (i32.const 1))) + (local.set $output_ptr (i32.const 100)) + (local.set $output_len (i32.load8_u (local.get $chosen_hash_fn))) + (call_indirect (type $hash_fn_sig) + (local.get $input_ptr) + (local.get $input_len) + (local.get $output_ptr) + (local.get $chosen_hash_fn) ;; Which crypto hash function to execute. + ) + (call $ext_scratch_write + (local.get $output_ptr) ;; Linear memory location of the output buffer. + (local.get $output_len) ;; Number of output buffer bytes. + ) + (i32.const 0) + ) +) +"#; + +#[test] +fn crypto_hashes() { + let (wasm, code_hash) = compile_module::(&CODE_CRYPTO_HASHES).unwrap(); + + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // Instantiate the CRYPTO_HASHES contract. + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 100_000, + 100_000, + code_hash.into(), + vec![], + )); + // Perform the call. + let input = b"_DEAD_BEEF"; + use sp_io::hashing::*; + // Wraps a hash function into a more dynamic form usable for testing. + macro_rules! dyn_hash_fn { + ($name:ident) => { + Box::new(|input| $name(input).as_ref().to_vec().into_boxed_slice()) + }; + } + // All hash functions and their associated output byte lengths. + let test_cases: &[(Box Box<[u8]>>, usize)] = &[ + (dyn_hash_fn!(sha2_256), 32), + (dyn_hash_fn!(keccak_256), 32), + (dyn_hash_fn!(blake2_256), 32), + (dyn_hash_fn!(blake2_128), 16), + (dyn_hash_fn!(twox_256), 32), + (dyn_hash_fn!(twox_128), 16), + (dyn_hash_fn!(twox_64), 8), + ]; + // Test the given hash functions for the input: "_DEAD_BEEF" + for (n, (hash_fn, expected_size)) in test_cases.iter().enumerate() { + // We offset data in the contract tables by 1. + let mut params = vec![(n + 1) as u8]; + params.extend_from_slice(input); + let result = >::bare_call( + ALICE, + BOB, + 0, + 100_000, + params, + ).unwrap(); + assert_eq!(result.status, 0); + let expected = hash_fn(input.as_ref()); + assert_eq!(&result.data[..*expected_size], &*expected); + } + }) +} diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index c8c5e1e6a4..92f2ff782b 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -26,6 +26,15 @@ use frame_system; use sp_std::{prelude::*, mem, convert::TryInto}; use codec::{Decode, Encode}; use sp_runtime::traits::{Bounded, SaturatedConversion}; +use sp_io::hashing::{ + keccak_256, + blake2_256, + blake2_128, + twox_256, + twox_128, + twox_64, + sha2_256, +}; /// The value returned from ext_call and ext_instantiate contract external functions if the call or /// instantiation traps. This value is chosen as if the execution does not trap, the return value @@ -1013,8 +1022,217 @@ define_env!(Env, , } } }, + + // Computes the SHA2 256-bit hash on the given input buffer. + // + // Returns the result directly into the given output buffer. + // + // # Note + // + // - The `input` and `output` buffer may overlap. + // - The output buffer is expected to hold at least 32 bytes (256 bits). + // - It is the callers responsibility to provide an output buffer that + // is large enough to hold the expected amount of bytes returned by the + // chosen hash function. + // + // # Parameters + // + // - `input_ptr`: the pointer into the linear memory where the input + // data is placed. + // - `input_len`: the length of the input data in bytes. + // - `output_ptr`: the pointer into the linear memory where the output + // data is placed. The function will write the result + // directly into this buffer. + ext_hash_sha2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { + compute_hash_on_intermediate_buffer(ctx, sha2_256, input_ptr, input_len, output_ptr) + }, + + // Computes the KECCAK 256-bit hash on the given input buffer. + // + // Returns the result directly into the given output buffer. + // + // # Note + // + // - The `input` and `output` buffer may overlap. + // - The output buffer is expected to hold at least 32 bytes (256 bits). + // - It is the callers responsibility to provide an output buffer that + // is large enough to hold the expected amount of bytes returned by the + // chosen hash function. + // + // # Parameters + // + // - `input_ptr`: the pointer into the linear memory where the input + // data is placed. + // - `input_len`: the length of the input data in bytes. + // - `output_ptr`: the pointer into the linear memory where the output + // data is placed. The function will write the result + // directly into this buffer. + ext_hash_keccak_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { + compute_hash_on_intermediate_buffer(ctx, keccak_256, input_ptr, input_len, output_ptr) + }, + + // Computes the BLAKE2 256-bit hash on the given input buffer. + // + // Returns the result directly into the given output buffer. + // + // # Note + // + // - The `input` and `output` buffer may overlap. + // - The output buffer is expected to hold at least 32 bytes (256 bits). + // - It is the callers responsibility to provide an output buffer that + // is large enough to hold the expected amount of bytes returned by the + // chosen hash function. + // + // # Parameters + // + // - `input_ptr`: the pointer into the linear memory where the input + // data is placed. + // - `input_len`: the length of the input data in bytes. + // - `output_ptr`: the pointer into the linear memory where the output + // data is placed. The function will write the result + // directly into this buffer. + ext_hash_blake2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { + compute_hash_on_intermediate_buffer(ctx, blake2_256, input_ptr, input_len, output_ptr) + }, + + // Computes the BLAKE2 128-bit hash on the given input buffer. + // + // Returns the result directly into the given output buffer. + // + // # Note + // + // - The `input` and `output` buffer may overlap. + // - The output buffer is expected to hold at least 16 bytes (128 bits). + // - It is the callers responsibility to provide an output buffer that + // is large enough to hold the expected amount of bytes returned by the + // chosen hash function. + // + // # Parameters + // + // - `input_ptr`: the pointer into the linear memory where the input + // data is placed. + // - `input_len`: the length of the input data in bytes. + // - `output_ptr`: the pointer into the linear memory where the output + // data is placed. The function will write the result + // directly into this buffer. + ext_hash_blake2_128(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { + compute_hash_on_intermediate_buffer(ctx, blake2_128, input_ptr, input_len, output_ptr) + }, + + // Computes the TWOX 256-bit hash on the given input buffer. + // + // Returns the result directly into the given output buffer. + // + // # Note + // + // - The `input` and `output` buffer may overlap. + // - The output buffer is expected to hold at least 32 bytes (256 bits). + // - It is the callers responsibility to provide an output buffer that + // is large enough to hold the expected amount of bytes returned by the + // chosen hash function. + // + // # Parameters + // + // - `input_ptr`: the pointer into the linear memory where the input + // data is placed. + // - `input_len`: the length of the input data in bytes. + // - `output_ptr`: the pointer into the linear memory where the output + // data is placed. The function will write the result + // directly into this buffer. + ext_hash_twox_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { + compute_hash_on_intermediate_buffer(ctx, twox_256, input_ptr, input_len, output_ptr) + }, + + // Computes the TWOX 128-bit hash on the given input buffer. + // + // Returns the result directly into the given output buffer. + // + // # Note + // + // - The `input` and `output` buffer may overlap. + // - The output buffer is expected to hold at least 16 bytes (128 bits). + // - It is the callers responsibility to provide an output buffer that + // is large enough to hold the expected amount of bytes returned by the + // chosen hash function. + // + // # Parameters + // + // - `input_ptr`: the pointer into the linear memory where the input + // data is placed. + // - `input_len`: the length of the input data in bytes. + // - `output_ptr`: the pointer into the linear memory where the output + // data is placed. The function will write the result + // directly into this buffer. + ext_hash_twox_128(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { + compute_hash_on_intermediate_buffer(ctx, twox_128, input_ptr, input_len, output_ptr) + }, + + // Computes the TWOX 64-bit hash on the given input buffer. + // + // Returns the result directly into the given output buffer. + // + // # Note + // + // - The `input` and `output` buffer may overlap. + // - The output buffer is expected to hold at least 8 bytes (64 bits). + // - It is the callers responsibility to provide an output buffer that + // is large enough to hold the expected amount of bytes returned by the + // chosen hash function. + // + // # Parameters + // + // - `input_ptr`: the pointer into the linear memory where the input + // data is placed. + // - `input_len`: the length of the input data in bytes. + // - `output_ptr`: the pointer into the linear memory where the output + // data is placed. The function will write the result + // directly into this buffer. + ext_hash_twox_64(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { + compute_hash_on_intermediate_buffer(ctx, twox_64, input_ptr, input_len, output_ptr) + }, ); +/// Computes the given hash function on the scratch buffer. +/// +/// Reads from the sandboxed input buffer into an intermediate buffer. +/// Returns the result directly to the output buffer of the sandboxed memory. +/// +/// It is the callers responsibility to provide an output buffer that +/// is large enough to hold the expected amount of bytes returned by the +/// chosen hash function. +/// +/// # Note +/// +/// The `input` and `output` buffers may overlap. +fn compute_hash_on_intermediate_buffer( + ctx: &mut Runtime, + hash_fn: F, + input_ptr: u32, + input_len: u32, + output_ptr: u32, +) -> Result<(), sp_sandbox::HostError> +where + E: Ext, + F: FnOnce(&[u8]) -> R, + R: AsRef<[u8]>, +{ + // Copy the input buffer directly into the scratch buffer to avoid + // heap allocations. + let input = read_sandbox_memory(ctx, input_ptr, input_len)?; + // Compute the hash on the scratch buffer using the given hash function. + let hash = hash_fn(&input); + // Write the resulting hash back into the sandboxed output buffer. + write_sandbox_memory( + ctx.schedule, + &mut ctx.special_trap, + ctx.gas_meter, + &ctx.memory, + output_ptr, + hash.as_ref(), + )?; + Ok(()) +} + /// Finds duplicates in a given vector. /// /// This function has complexity of O(n log n) and no additional memory is required, although -- GitLab From df481b798c5effe0d434b138c211c6afce2b8635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 20 Mar 2020 19:00:39 +0100 Subject: [PATCH 033/300] Update sysinfo to fix compilation on Windows (#5338) --- Cargo.lock | 4 ++-- client/service/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a55a09772..7848d75c8b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7966,9 +7966,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.11.7" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e15d793f059727ad34a9245503c13b38262bb32e9906d8122ca64d6ca54b0858" +checksum = "7ccb41798287e8e299a701b5560d886d6ca2c3e7115e9ea2cb68c123aec339b7" dependencies = [ "cfg-if", "doc-comment", diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 4bc4d1fd78..a75ac428ae 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -31,7 +31,7 @@ wasm-timer = "0.2" exit-future = "0.2.0" serde = "1.0.101" serde_json = "1.0.41" -sysinfo = "0.11.7" +sysinfo = "0.12.0" target_info = "0.1.0" sc-keystore = { version = "2.0.0-alpha.4", path = "../keystore" } sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } -- GitLab From 7b99267357ca454706466913233a25c5e240f2e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Fri, 20 Mar 2020 18:07:10 +0000 Subject: [PATCH 034/300] grandpa: allow noting same set in gossip with different authorities (#5323) * grandpa: allow noting same set in gossip with different authorities * grandpa: add test for note_set behavior --- .../src/communication/gossip.rs | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/client/finality-grandpa/src/communication/gossip.rs b/client/finality-grandpa/src/communication/gossip.rs index 89c507f39a..6b245a4652 100644 --- a/client/finality-grandpa/src/communication/gossip.rs +++ b/client/finality-grandpa/src/communication/gossip.rs @@ -722,7 +722,15 @@ impl Inner { last_commit: None, }), Some(ref mut v) => if v.set_id == set_id { - return None + if self.authorities != authorities { + debug!(target: "afg", + "Gossip validator noted set {:?} twice with different authorities. \ + Was the authority set hard forked?", + set_id, + ); + self.authorities = authorities; + } + return None; } else { v }, @@ -788,6 +796,7 @@ impl Inner { // ensure authority is part of the set. if !self.authorities.contains(&full.message.id) { + debug!(target: "afg", "Message from unknown voter: {}", full.message.id); telemetry!(CONSENSUS_DEBUG; "afg.bad_msg_signature"; "signature" => ?full.message.id); return Action::Discard(cost::UNKNOWN_VOTER); } @@ -1380,6 +1389,11 @@ impl GossipValidator { (action, broadcast_topics, peer_reply) } + + #[cfg(test)] + fn inner(&self) -> &parking_lot::RwLock> { + &self.inner + } } impl sc_network_gossip::Validator for GossipValidator { @@ -2555,4 +2569,19 @@ mod tests { &commit(0, 1, 2), )); } + + #[test] + fn allow_noting_different_authorities_for_same_set() { + let (val, _) = GossipValidator::::new(config(), voter_set_state(), None); + + let a1 = vec![AuthorityId::default()]; + val.note_set(SetId(1), a1.clone(), |_, _| {}); + + assert_eq!(val.inner().read().authorities, a1); + + let a2 = vec![AuthorityId::default(), AuthorityId::default()]; + val.note_set(SetId(1), a2.clone(), |_, _| {}); + + assert_eq!(val.inner().read().authorities, a2); + } } -- GitLab From 2c87fe171bc341755a43a3b32d67560469f8daac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 20 Mar 2020 19:34:51 +0100 Subject: [PATCH 035/300] Adds new event phase `Initialization` (#5302) * Adds new event phase `Initialization` Every event that was deposited inside of `on_initialize` was assigned to the `ApplyExtrinsic(0)` phase which wasn't correct. This pr introduces a new phase `Initialization`. This is the new phase while initializing a block. After initialization we switch to `ApplyExtrinsic(N)` and at the end to `Finalization` as before. * Set `ExecutionPhase` in `initialize` * Increment `spec_version` --- frame/collective/src/lib.rs | 26 ++++----- frame/contracts/src/tests.rs | 104 +++++++++++++++++------------------ frame/executive/src/lib.rs | 2 + frame/offences/src/tests.rs | 4 +- frame/system/src/lib.rs | 31 +++++++++-- 5 files changed, 96 insertions(+), 71 deletions(-) diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 8b46856cbb..0f5a16ed7a 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -608,7 +608,7 @@ mod tests { System::set_block_number(4); assert_ok!(Collective::close(Origin::signed(4), hash.clone(), 0)); - let record = |event| EventRecord { phase: Phase::Finalization, event, topics: vec![] }; + let record = |event| EventRecord { phase: Phase::Initialization, event, topics: vec![] }; assert_eq!(System::events(), vec![ record(Event::collective_Instance1(RawEvent::Proposed(1, 0, hash.clone(), 3))), record(Event::collective_Instance1(RawEvent::Voted(2, hash.clone(), true, 2, 0))), @@ -632,7 +632,7 @@ mod tests { System::set_block_number(4); assert_ok!(Collective::close(Origin::signed(4), hash.clone(), 0)); - let record = |event| EventRecord { phase: Phase::Finalization, event, topics: vec![] }; + let record = |event| EventRecord { phase: Phase::Initialization, event, topics: vec![] }; assert_eq!(System::events(), vec![ record(Event::collective_Instance1(RawEvent::Proposed(1, 0, hash.clone(), 3))), record(Event::collective_Instance1(RawEvent::Voted(2, hash.clone(), true, 2, 0))), @@ -656,7 +656,7 @@ mod tests { System::set_block_number(4); assert_ok!(Collective::close(Origin::signed(4), hash.clone(), 0)); - let record = |event| EventRecord { phase: Phase::Finalization, event, topics: vec![] }; + let record = |event| EventRecord { phase: Phase::Initialization, event, topics: vec![] }; assert_eq!(System::events(), vec![ record(Event::collective_Instance1(RawEvent::Proposed(1, 0, hash.clone(), 3))), record(Event::collective_Instance1(RawEvent::Voted(2, hash.clone(), true, 2, 0))), @@ -754,7 +754,7 @@ mod tests { assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::Finalization, + phase: Phase::Initialization, event: Event::collective_Instance1(RawEvent::Proposed( 1, 0, @@ -835,7 +835,7 @@ mod tests { assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::Finalization, + phase: Phase::Initialization, event: Event::collective_Instance1(RawEvent::Proposed( 1, 0, @@ -845,7 +845,7 @@ mod tests { topics: vec![], }, EventRecord { - phase: Phase::Finalization, + phase: Phase::Initialization, event: Event::collective_Instance1(RawEvent::Voted( 1, hex!["68eea8f20b542ec656c6ac2d10435ae3bd1729efc34d1354ab85af840aad2d35"].into(), @@ -884,7 +884,7 @@ mod tests { assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::Finalization, + phase: Phase::Initialization, event: Event::collective_Instance1( RawEvent::Proposed( 1, @@ -895,7 +895,7 @@ mod tests { topics: vec![], }, EventRecord { - phase: Phase::Finalization, + phase: Phase::Initialization, event: Event::collective_Instance1(RawEvent::Voted( 2, hex!["68eea8f20b542ec656c6ac2d10435ae3bd1729efc34d1354ab85af840aad2d35"].into(), @@ -906,7 +906,7 @@ mod tests { topics: vec![], }, EventRecord { - phase: Phase::Finalization, + phase: Phase::Initialization, event: Event::collective_Instance1(RawEvent::Disapproved( hex!["68eea8f20b542ec656c6ac2d10435ae3bd1729efc34d1354ab85af840aad2d35"].into(), )), @@ -927,7 +927,7 @@ mod tests { assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::Finalization, + phase: Phase::Initialization, event: Event::collective_Instance1(RawEvent::Proposed( 1, 0, @@ -937,7 +937,7 @@ mod tests { topics: vec![], }, EventRecord { - phase: Phase::Finalization, + phase: Phase::Initialization, event: Event::collective_Instance1(RawEvent::Voted( 2, hex!["68eea8f20b542ec656c6ac2d10435ae3bd1729efc34d1354ab85af840aad2d35"].into(), @@ -948,14 +948,14 @@ mod tests { topics: vec![], }, EventRecord { - phase: Phase::Finalization, + phase: Phase::Initialization, event: Event::collective_Instance1(RawEvent::Approved( hex!["68eea8f20b542ec656c6ac2d10435ae3bd1729efc34d1354ab85af840aad2d35"].into(), )), topics: vec![], }, EventRecord { - phase: Phase::Finalization, + phase: Phase::Initialization, event: Event::collective_Instance1(RawEvent::Executed( hex!["68eea8f20b542ec656c6ac2d10435ae3bd1729efc34d1354ab85af840aad2d35"].into(), false, diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 6a47b2ee17..3f01096b88 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -422,44 +422,44 @@ fn instantiate_and_call_and_deposit_event() { assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances( pallet_balances::RawEvent::Endowed(BOB, 100) ), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::Transfer(ALICE, BOB, 100)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::ContractExecution(BOB, vec![1, 2, 3, 4])), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), topics: vec![], } @@ -505,17 +505,17 @@ fn dispatch_call() { // wasm source this test will fail and will show you the actual hash. assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), topics: vec![], }, @@ -539,58 +539,58 @@ fn dispatch_call() { assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances( pallet_balances::RawEvent::Endowed(BOB, 100) ), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::Transfer(ALICE, BOB, 100)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), topics: vec![], }, // Dispatching the call. EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(frame_system::RawEvent::NewAccount(CHARLIE)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances( pallet_balances::RawEvent::Endowed(CHARLIE, 50) ), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances( pallet_balances::RawEvent::Transfer(BOB, CHARLIE, 50) ), @@ -599,7 +599,7 @@ fn dispatch_call() { // Event emitted as a result of dispatch. EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::Dispatched(BOB, true)), topics: vec![], } @@ -643,17 +643,17 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { // wasm source this test will fail and will show you the actual hash. assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), topics: vec![], }, @@ -681,39 +681,39 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { ); assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances( pallet_balances::RawEvent::Endowed(BOB, 100) ), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::Transfer(ALICE, BOB, 100)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), topics: vec![], }, @@ -898,17 +898,17 @@ fn test_set_rent_code_and_hash() { // and will show you the actual hash. assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), topics: vec![], }, @@ -1225,7 +1225,7 @@ fn call_removed_contract() { // Calling a contract that is about to evict shall emit an event. assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::Evicted(BOB, true)), topics: vec![], }, @@ -1414,22 +1414,22 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: // and will show you the actual hash. assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::CodeStored(restoration_code_hash.into())), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::CodeStored(set_rent_code_hash.into())), topics: vec![], }, @@ -1473,7 +1473,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts( RawEvent::Evicted(BOB.clone(), true) ), @@ -1526,7 +1526,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: (true, false) => { assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts( RawEvent::Restored(DJANGO, BOB, bob_code_hash, 50, false) ), @@ -1537,42 +1537,42 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: (_, true) => { assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::Evicted(BOB, true)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(frame_system::RawEvent::NewAccount(CHARLIE)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(CHARLIE, 1_000_000)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(frame_system::RawEvent::NewAccount(DJANGO)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(DJANGO, 30_000)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::Transfer(CHARLIE, DJANGO, 30_000)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::Instantiated(CHARLIE, DJANGO)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts(RawEvent::Restored( DJANGO, BOB, @@ -1599,12 +1599,12 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: assert!(ContractInfoOf::::get(DJANGO).is_none()); assert_eq!(System::events(), vec![ EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::system(system::RawEvent::KilledAccount(DJANGO)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: MetaEvent::contracts( RawEvent::Restored(DJANGO, BOB, bob_contract.code_hash, 50, true) ), diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 117607d9b6..1b3867cf6e 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -199,6 +199,8 @@ where >::register_extra_weight_unchecked( >::on_finalize(*block_number) ); + + frame_system::Module::::note_finished_initialize(); } /// Returns if the runtime was upgraded since the last time this function was called. diff --git a/frame/offences/src/tests.rs b/frame/offences/src/tests.rs index 0ed98427c6..7e9c3986ed 100644 --- a/frame/offences/src/tests.rs +++ b/frame/offences/src/tests.rs @@ -129,7 +129,7 @@ fn should_deposit_event() { assert_eq!( System::events(), vec![EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: TestEvent::offences(crate::Event::Offence(KIND, time_slot.encode())), topics: vec![], }] @@ -164,7 +164,7 @@ fn doesnt_deposit_event_for_dups() { assert_eq!( System::events(), vec![EventRecord { - phase: Phase::ApplyExtrinsic(0), + phase: Phase::Initialization, event: TestEvent::offences(crate::Event::Offence(KIND, time_slot.encode())), topics: vec![], }] diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index e59788c600..138a151427 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -235,8 +235,16 @@ pub type KeyValue = (Vec, Vec); pub enum Phase { /// Applying an extrinsic. ApplyExtrinsic(u32), - /// The end. + /// Finalizing the block. Finalization, + /// Initializing the block. + Initialization, +} + +impl Default for Phase { + fn default() -> Self { + Self::Initialization + } } /// Record of an event happening. @@ -393,6 +401,9 @@ decl_storage! { /// Stores the `spec_version` and `spec_name` of when the last runtime upgrade happened. pub LastRuntimeUpgrade build(|_| Some(LastRuntimeUpgradeInfo::from(T::Version::get()))): Option; + + /// The execution phase of the block. + ExecutionPhase: Option; } add_extra_genesis { config(changes_trie_config): Option; @@ -710,8 +721,7 @@ impl Module { /// This will update storage entries that correspond to the specified topics. /// It is expected that light-clients could subscribe to this topics. pub fn deposit_event_indexed(topics: &[T::Hash], event: T::Event) { - let extrinsic_index = Self::extrinsic_index(); - let phase = extrinsic_index.map_or(Phase::Finalization, |c| Phase::ApplyExtrinsic(c)); + let phase = ExecutionPhase::get().unwrap_or_default(); let event = EventRecord { phase, event, @@ -803,6 +813,7 @@ impl Module { kind: InitKind, ) { // populate environment + ExecutionPhase::put(Phase::Initialization); storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &0u32); >::put(number); >::put(digest); @@ -819,6 +830,7 @@ impl Module { /// Remove temporary "environment" entries in storage. pub fn finalize() -> T::Header { + ExecutionPhase::kill(); ExtrinsicCount::kill(); AllExtrinsicsWeight::kill(); AllExtrinsicsLen::kill(); @@ -949,6 +961,7 @@ impl Module { let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32; storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &next_extrinsic_index); + ExecutionPhase::put(Phase::ApplyExtrinsic(next_extrinsic_index)); } /// To be called immediately after `note_applied_extrinsic` of the last extrinsic of the block @@ -957,6 +970,13 @@ impl Module { let extrinsic_index: u32 = storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX) .unwrap_or_default(); ExtrinsicCount::put(extrinsic_index); + ExecutionPhase::put(Phase::Finalization); + } + + /// To be called immediately after finishing the initialization of the block + /// (e.g., called `on_initialize` for all modules). + pub fn note_finished_initialize() { + ExecutionPhase::put(Phase::ApplyExtrinsic(0)) } /// Remove all extrinsic data and save the extrinsics trie root. @@ -1645,6 +1665,8 @@ mod tests { &Default::default(), InitKind::Full, ); + System::deposit_event(32u16); + System::note_finished_initialize(); System::deposit_event(42u16); System::note_applied_extrinsic(&Ok(()), 0, Default::default()); System::note_applied_extrinsic(&Err(DispatchError::BadOrigin), 0, Default::default()); @@ -1654,6 +1676,7 @@ mod tests { assert_eq!( System::events(), vec![ + EventRecord { phase: Phase::Initialization, event: 32u16, topics: vec![] }, EventRecord { phase: Phase::ApplyExtrinsic(0), event: 42u16, topics: vec![] }, EventRecord { phase: Phase::ApplyExtrinsic(0), event: 100u16, topics: vec![] }, EventRecord { phase: Phase::ApplyExtrinsic(1), event: 101u16, topics: vec![] }, @@ -1997,7 +2020,7 @@ mod tests { assert_eq!( System::events(), - vec![EventRecord { phase: Phase::ApplyExtrinsic(0), event: 102u16, topics: vec![] }], + vec![EventRecord { phase: Phase::Initialization, event: 102u16, topics: vec![] }], ); }); } -- GitLab From 34c5cb3f66ba47cea6c50aefbf24d35cbf742630 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 20 Mar 2020 20:03:19 +0100 Subject: [PATCH 036/300] latest unleash and on all ci-release-prefixed tags (#5334) --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8083e34ea9..13943ba22c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -38,7 +38,7 @@ variables: DOCKER_OS: "debian:stretch" ARCH: "x86_64" # FIXME set to release - CARGO_UNLEASH_INSTALL_PARAMS: "--version 1.0.0-alpha.8" + CARGO_UNLEASH_INSTALL_PARAMS: "--version 1.0.0-alpha.10" CARGO_UNLEASH_PKG_DEF: "--skip node node-* pallet-template pallet-example pallet-example-* subkey chain-spec-builder" @@ -596,7 +596,7 @@ publish-to-crates-io: <<: *docker-env only: - tags - - ci-release + - /^ci-release-.*$/ script: - cargo install cargo-unleash ${CARGO_UNLEASH_INSTALL_PARAMS} - cargo unleash em-dragons --no-check ${CARGO_UNLEASH_PKG_DEF} -- GitLab From 1b2a30cd9938ee776ebe441279374d88e8e81a27 Mon Sep 17 00:00:00 2001 From: cheme Date: Fri, 20 Mar 2020 20:47:40 +0100 Subject: [PATCH 037/300] Using `PrefixedStorageKey` type for child storage key that are prefixed. --- Cargo.lock | 21 +++++ client/api/src/backend.rs | 4 +- client/api/src/light.rs | 6 +- client/api/src/proof_provider.rs | 4 +- client/db/src/changes_tries_storage.rs | 3 +- client/network/src/protocol.rs | 42 +++++---- .../src/protocol/light_client_handler.rs | 36 ++++--- client/network/src/protocol/light_dispatch.rs | 13 ++- client/rpc-api/src/child_state/mod.rs | 10 +- client/rpc/src/state/mod.rs | 18 ++-- client/rpc/src/state/state_full.rs | 14 +-- client/rpc/src/state/state_light.rs | 11 ++- client/rpc/src/state/tests.rs | 11 ++- client/src/client.rs | 16 ++-- client/src/light/fetcher.rs | 7 +- primitives/state-machine/src/backend.rs | 4 +- primitives/state-machine/src/basic.rs | 2 +- .../state-machine/src/changes_trie/build.rs | 6 +- .../src/changes_trie/build_cache.rs | 15 +-- .../src/changes_trie/changes_iterator.rs | 26 ++++-- .../state-machine/src/changes_trie/input.rs | 18 +++- .../state-machine/src/changes_trie/mod.rs | 3 +- .../state-machine/src/changes_trie/prune.rs | 3 +- .../state-machine/src/changes_trie/storage.rs | 5 +- primitives/state-machine/src/ext.rs | 4 +- .../state-machine/src/in_memory_backend.rs | 2 +- primitives/storage/Cargo.toml | 1 + primitives/storage/src/lib.rs | 93 ++++++++++++++----- test-utils/runtime/client/src/lib.rs | 2 +- 29 files changed, 256 insertions(+), 144 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 189f85013c..1ff40208eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5341,6 +5341,26 @@ dependencies = [ "rust-argon2", ] +[[package]] +name = "ref-cast" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "077f197a31bfe7e4169145f9eca08d32705c6c6126c139c26793acdf163ac3ef" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c36eb52b69b87c9e3a07387f476c88fd0dba9a1713b38e56617ed66b45392c1f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "regex" version = "1.3.4" @@ -7420,6 +7440,7 @@ name = "sp-storage" version = "2.0.0-alpha.4" dependencies = [ "impl-serde 0.2.3", + "ref-cast", "serde", "sp-debug-derive", "sp-std", diff --git a/client/api/src/backend.rs b/client/api/src/backend.rs index 68dd61b233..33a370c7cb 100644 --- a/client/api/src/backend.rs +++ b/client/api/src/backend.rs @@ -26,7 +26,7 @@ use sp_state_machine::{ ChangesTrieState, ChangesTrieStorage as StateChangesTrieStorage, ChangesTrieTransaction, StorageCollection, ChildStorageCollection, }; -use sp_storage::{StorageData, StorageKey, ChildInfo}; +use sp_storage::{StorageData, StorageKey, PrefixedStorageKey, ChildInfo}; use crate::{ blockchain::{ Backend as BlockchainBackend, well_known_cache_keys @@ -349,7 +349,7 @@ pub trait StorageProvider> { &self, first: NumberFor, last: BlockId, - storage_key: Option<&StorageKey>, + storage_key: Option<&PrefixedStorageKey>, key: &StorageKey ) -> sp_blockchain::Result, u32)>>; } diff --git a/client/api/src/light.rs b/client/api/src/light.rs index 2911d77f18..30e6d14d55 100644 --- a/client/api/src/light.rs +++ b/client/api/src/light.rs @@ -26,7 +26,7 @@ use sp_runtime::{ }, generic::BlockId }; -use sp_core::ChangesTrieConfigurationRange; +use sp_core::{ChangesTrieConfigurationRange, storage::PrefixedStorageKey}; use sp_state_machine::StorageProof; use sp_blockchain::{ HeaderMetadata, well_known_cache_keys, HeaderBackend, Cache as BlockchainCache, @@ -81,7 +81,7 @@ pub struct RemoteReadChildRequest { /// Header of block at which read is performed. pub header: Header, /// Storage key for child. - pub storage_key: Vec, + pub storage_key: PrefixedStorageKey, /// Child storage key to read. pub keys: Vec>, /// Number of times to retry request. None means that default RETRY_COUNT is used. @@ -105,7 +105,7 @@ pub struct RemoteChangesRequest { /// Proofs for roots of ascendants of tries_roots.0 are provided by the remote node. pub tries_roots: (Header::Number, Header::Hash, Vec), /// Optional Child Storage key to read. - pub storage_key: Option>, + pub storage_key: Option, /// Storage key to read. pub key: Vec, /// Number of times to retry request. None means that default RETRY_COUNT is used. diff --git a/client/api/src/proof_provider.rs b/client/api/src/proof_provider.rs index a805baf42b..93160855ea 100644 --- a/client/api/src/proof_provider.rs +++ b/client/api/src/proof_provider.rs @@ -19,7 +19,7 @@ use sp_runtime::{ traits::{Block as BlockT}, }; use crate::{StorageProof, ChangesProof}; -use sp_storage::{ChildInfo, StorageKey}; +use sp_storage::{ChildInfo, StorageKey, PrefixedStorageKey}; /// Interface for providing block proving utilities. pub trait ProofProvider { @@ -64,7 +64,7 @@ pub trait ProofProvider { last: Block::Hash, min: Block::Hash, max: Block::Hash, - storage_key: Option<&StorageKey>, + storage_key: Option<&PrefixedStorageKey>, key: &StorageKey, ) -> sp_blockchain::Result>; } diff --git a/client/db/src/changes_tries_storage.rs b/client/db/src/changes_tries_storage.rs index a28cd604fe..55e740f434 100644 --- a/client/db/src/changes_tries_storage.rs +++ b/client/db/src/changes_tries_storage.rs @@ -27,6 +27,7 @@ use sp_trie::MemoryDB; use sc_client_api::backend::PrunableStateChangesTrieStorage; use sp_blockchain::{well_known_cache_keys, Cache as BlockchainCache}; use sp_core::{ChangesTrieConfiguration, ChangesTrieConfigurationRange, convert_hash}; +use sp_core::storage::PrefixedStorageKey; use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, HashFor, NumberFor, One, Zero, CheckedSub, }; @@ -481,7 +482,7 @@ where fn with_cached_changed_keys( &self, root: &Block::Hash, - functor: &mut dyn FnMut(&HashMap>, HashSet>>), + functor: &mut dyn FnMut(&HashMap, HashSet>>), ) -> bool { self.build_cache.read().with_changed_keys(root, functor) } diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 1e6158a59e..2635a24f8d 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -23,7 +23,7 @@ use libp2p::{Multiaddr, PeerId}; use libp2p::core::{ConnectedPoint, nodes::listeners::ListenerId}; use libp2p::swarm::{ProtocolsHandler, IntoProtocolsHandler}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; -use sp_core::storage::{StorageKey, ChildInfo, ChildType}; +use sp_core::storage::{StorageKey, PrefixedStorageKey, ChildInfo, ChildType}; use sp_consensus::{ BlockOrigin, block_validation::BlockAnnounceValidator, @@ -312,14 +312,14 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a> { who: &PeerId, id: RequestId, block: ::Hash, - storage_key: Vec, + storage_key: PrefixedStorageKey, keys: Vec>, ) { let message: Message = message::generic::Message::RemoteReadChildRequest( message::RemoteReadChildRequest { id, block, - storage_key, + storage_key: storage_key.key(), keys, }); @@ -352,7 +352,7 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a> { last: ::Hash, min: ::Hash, max: ::Hash, - storage_key: Option>, + storage_key: Option, key: Vec, ) { let message: Message = message::generic::Message::RemoteChangesRequest(message::RemoteChangesRequest { @@ -361,7 +361,7 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a> { last, min, max, - storage_key, + storage_key: storage_key.map(|p| p.key()), key, }); @@ -1608,7 +1608,8 @@ impl Protocol { trace!(target: "sync", "Remote read child request {} from {} ({} {} at {})", request.id, who, request.storage_key.to_hex::(), keys_str(), request.block); - let child_info = match ChildType::from_prefixed_key(&request.storage_key) { + let prefixed_key = PrefixedStorageKey::new_ref(&request.storage_key); + let child_info = match prefixed_key.and_then(|key| ChildType::from_prefixed_key(key)) { Some((ChildType::ParentKeyId, storage_key)) => Ok(ChildInfo::new_default(storage_key)), None => Err("Invalid child storage key".into()), }; @@ -1708,23 +1709,32 @@ impl Protocol { request.first, request.last ); - let storage_key = request.storage_key.map(|sk| StorageKey(sk)); let key = StorageKey(request.key); - let proof = match self.context_data.chain.key_changes_proof( - request.first, - request.last, - request.min, - request.max, - storage_key.as_ref(), + let prefixed_key = if let Some(storage_key) = request.storage_key.as_ref() { + if let Some(storage_key) = PrefixedStorageKey::new_ref(storage_key) { + Ok(Some(storage_key)) + } else { + Err("Invalid prefixed storage key".into()) + } + } else { + Ok(None) + }; + let (first, last, min, max) = (request.first, request.last, request.min, request.max); + let proof = match prefixed_key.and_then(|p_key| self.context_data.chain.key_changes_proof( + first, + last, + min, + max, + p_key, &key, - ) { + )) { Ok(proof) => proof, Err(error) => { trace!(target: "sync", "Remote changes proof request {} from {} for key {} ({}..{}) failed with: {}", request.id, who, - if let Some(sk) = storage_key { - format!("{} : {}", sk.0.to_hex::(), key.0.to_hex::()) + if let Some(sk) = request.storage_key.as_ref() { + format!("{} : {}", sk.to_hex::(), key.0.to_hex::()) } else { key.0.to_hex::() }, diff --git a/client/network/src/protocol/light_client_handler.rs b/client/network/src/protocol/light_client_handler.rs index ecbd62e431..085bd06e4c 100644 --- a/client/network/src/protocol/light_client_handler.rs +++ b/client/network/src/protocol/light_client_handler.rs @@ -55,7 +55,7 @@ use rustc_hex::ToHex; use sc_client::light::fetcher; use sc_client_api::StorageProof; use sc_peerset::ReputationChange; -use sp_core::storage::{ChildInfo, ChildType, StorageKey}; +use sp_core::storage::{ChildInfo, ChildType, StorageKey, PrefixedStorageKey}; use sp_blockchain::{Error as ClientError}; use sp_runtime::{ traits::{Block, Header, NumberFor, Zero}, @@ -510,7 +510,8 @@ where let block = Decode::decode(&mut request.block.as_ref())?; - let child_info = match ChildType::from_prefixed_key(&request.storage_key) { + let prefixed_key = PrefixedStorageKey::new_ref(&request.storage_key); + let child_info = match prefixed_key.and_then(|key| ChildType::from_prefixed_key(key)) { Some((ChildType::ParentKeyId, storage_key)) => Ok(ChildInfo::new_default(storage_key)), None => Err("Invalid child storage key".into()), }; @@ -588,20 +589,25 @@ where let min = Decode::decode(&mut request.min.as_ref())?; let max = Decode::decode(&mut request.max.as_ref())?; let key = StorageKey(request.key.clone()); - let storage_key = - if request.storage_key.is_empty() { - None + let storage_key = if request.storage_key.is_empty() { + Ok(None) + } else { + if let Some(storage_key) = PrefixedStorageKey::new_ref(&request.storage_key) { + Ok(Some(storage_key)) } else { - Some(StorageKey(request.storage_key.clone())) - }; + Err("Invalid prefix for storage key.".into()) + } + }; - let proof = match self.chain.key_changes_proof(first, last, min, max, storage_key.as_ref(), &key) { + let proof = match storage_key.and_then(|storage_key| { + self.chain.key_changes_proof(first, last, min, max, storage_key, &key) + }) { Ok(proof) => proof, Err(error) => { log::trace!("remote changes proof request from {} for key {} ({:?}..{:?}) failed with: {}", peer, - if let Some(sk) = storage_key { - format!("{} : {}", sk.0.to_hex::(), key.0.to_hex::()) + if !request.storage_key.is_empty() { + format!("{} : {}", request.storage_key.to_hex::(), key.0.to_hex::()) } else { key.0.to_hex::() }, @@ -918,7 +924,7 @@ fn serialize_request(request: &Request) -> api::v1::light::Request Request::ReadChild { request, .. } => { let r = api::v1::light::RemoteReadChildRequest { block: request.block.encode(), - storage_key: request.storage_key.clone(), + storage_key: request.storage_key.clone().key(), keys: request.keys.clone(), }; api::v1::light::request::Request::RemoteReadChildRequest(r) @@ -937,7 +943,7 @@ fn serialize_request(request: &Request) -> api::v1::light::Request last: request.last_block.1.encode(), min: request.tries_roots.1.encode(), max: request.max_block.1.encode(), - storage_key: request.storage_key.clone().unwrap_or_default(), + storage_key: request.storage_key.clone().map(|s| s.key()).unwrap_or_default(), key: request.key.clone(), }; api::v1::light::request::Request::RemoteChangesRequest(r) @@ -1562,10 +1568,11 @@ mod tests { #[test] fn receives_remote_read_child_response() { let mut chan = oneshot::channel(); + let child_info = ChildInfo::new_default(&b":child_storage:default:sub"[..]); let request = fetcher::RemoteReadChildRequest { header: dummy_header(), block: Default::default(), - storage_key: b":child_storage:default:sub".to_vec(), + storage_key: child_info.prefixed_storage_key(), keys: vec![b":key".to_vec()], retry_count: None, }; @@ -1662,10 +1669,11 @@ mod tests { #[test] fn send_receive_read_child() { let chan = oneshot::channel(); + let child_info = ChildInfo::new_default(&b":child_storage:default:sub"[..]); let request = fetcher::RemoteReadChildRequest { header: dummy_header(), block: Default::default(), - storage_key: b":child_storage:default:sub".to_vec(), + storage_key: child_info.prefixed_storage_key(), keys: vec![b":key".to_vec()], retry_count: None, }; diff --git a/client/network/src/protocol/light_dispatch.rs b/client/network/src/protocol/light_dispatch.rs index 94d2e35a12..d35855d9c4 100644 --- a/client/network/src/protocol/light_dispatch.rs +++ b/client/network/src/protocol/light_dispatch.rs @@ -35,6 +35,7 @@ use libp2p::PeerId; use crate::config::Roles; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use sc_peerset::ReputationChange; +use sp_core::storage::PrefixedStorageKey; /// Remote request timeout. const REQUEST_TIMEOUT: Duration = Duration::from_secs(15); @@ -69,7 +70,7 @@ pub trait LightDispatchNetwork { who: &PeerId, id: RequestId, block: ::Hash, - storage_key: Vec, + storage_key: PrefixedStorageKey, keys: Vec>, ); @@ -92,7 +93,7 @@ pub trait LightDispatchNetwork { last: ::Hash, min: ::Hash, max: ::Hash, - storage_key: Option>, + storage_key: Option, key: Vec, ); @@ -678,6 +679,7 @@ pub mod tests { use std::sync::Arc; use std::time::Instant; use futures::channel::oneshot; + use sp_core::storage::PrefixedStorageKey; use sp_runtime::traits::{Block as BlockT, NumberFor, Header as HeaderT}; use sp_blockchain::{Error as ClientError, Result as ClientResult}; use sc_client_api::{FetchChecker, RemoteHeaderRequest, @@ -821,11 +823,11 @@ pub mod tests { } fn send_header_request(&mut self, _: &PeerId, _: RequestId, _: <::Header as HeaderT>::Number) {} fn send_read_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: Vec>) {} - fn send_read_child_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: Vec, + fn send_read_child_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: PrefixedStorageKey, _: Vec>) {} fn send_call_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: String, _: Vec) {} fn send_changes_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: ::Hash, - _: ::Hash, _: ::Hash, _: Option>, _: Vec) {} + _: ::Hash, _: ::Hash, _: Option, _: Vec) {} fn send_body_request(&mut self, _: &PeerId, _: RequestId, _: BlockAttributes, _: FromBlock<::Hash, <::Header as HeaderT>::Number>, _: Option, _: Direction, _: Option) {} } @@ -1043,12 +1045,13 @@ pub mod tests { let peer0 = PeerId::random(); light_dispatch.on_connect(&mut network_interface, peer0.clone(), Roles::FULL, 1000); + let child_info = sp_core::storage::ChildInfo::new_default(&b":child_storage:default:sub"[..]); let (tx, response) = oneshot::channel(); light_dispatch.add_request(&mut network_interface, RequestData::RemoteReadChild( RemoteReadChildRequest { header: dummy_header(), block: Default::default(), - storage_key: b":child_storage:default:sub".to_vec(), + storage_key: child_info.prefixed_storage_key(), keys: vec![b":key".to_vec()], retry_count: None, }, tx)); diff --git a/client/rpc-api/src/child_state/mod.rs b/client/rpc-api/src/child_state/mod.rs index f9027b0f15..3c530b64de 100644 --- a/client/rpc-api/src/child_state/mod.rs +++ b/client/rpc-api/src/child_state/mod.rs @@ -17,7 +17,7 @@ //! Substrate state API. use jsonrpc_derive::rpc; -use sp_core::storage::{StorageKey, StorageData}; +use sp_core::storage::{StorageKey, PrefixedStorageKey, StorageData}; use crate::state::error::FutureResult; pub use self::gen_client::Client as ChildStateClient; @@ -32,7 +32,7 @@ pub trait ChildStateApi { #[rpc(name = "childstate_getKeys")] fn storage_keys( &self, - child_storage_key: StorageKey, + child_storage_key: PrefixedStorageKey, prefix: StorageKey, hash: Option ) -> FutureResult>; @@ -41,7 +41,7 @@ pub trait ChildStateApi { #[rpc(name = "childstate_getStorage")] fn storage( &self, - child_storage_key: StorageKey, + child_storage_key: PrefixedStorageKey, key: StorageKey, hash: Option ) -> FutureResult>; @@ -50,7 +50,7 @@ pub trait ChildStateApi { #[rpc(name = "childstate_getStorageHash")] fn storage_hash( &self, - child_storage_key: StorageKey, + child_storage_key: PrefixedStorageKey, key: StorageKey, hash: Option ) -> FutureResult>; @@ -59,7 +59,7 @@ pub trait ChildStateApi { #[rpc(name = "childstate_getStorageSize")] fn storage_size( &self, - child_storage_key: StorageKey, + child_storage_key: PrefixedStorageKey, key: StorageKey, hash: Option ) -> FutureResult>; diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index 1805ac5351..d61cd43773 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -28,7 +28,7 @@ use rpc::{Result as RpcResult, futures::{Future, future::result}}; use sc_rpc_api::Subscriptions; use sc_client::{light::{blockchain::RemoteBlockchain, fetcher::Fetcher}}; -use sp_core::{Bytes, storage::{StorageKey, StorageData, StorageChangeSet}}; +use sp_core::{Bytes, storage::{StorageKey, PrefixedStorageKey, StorageData, StorageChangeSet}}; use sp_version::RuntimeVersion; use sp_runtime::traits::Block as BlockT; @@ -320,7 +320,7 @@ pub trait ChildStateBackend: Send + Sync + 'static fn storage_keys( &self, block: Option, - storage_key: StorageKey, + storage_key: PrefixedStorageKey, prefix: StorageKey, ) -> FutureResult>; @@ -328,7 +328,7 @@ pub trait ChildStateBackend: Send + Sync + 'static fn storage( &self, block: Option, - storage_key: StorageKey, + storage_key: PrefixedStorageKey, key: StorageKey, ) -> FutureResult>; @@ -336,7 +336,7 @@ pub trait ChildStateBackend: Send + Sync + 'static fn storage_hash( &self, block: Option, - storage_key: StorageKey, + storage_key: PrefixedStorageKey, key: StorageKey, ) -> FutureResult>; @@ -344,7 +344,7 @@ pub trait ChildStateBackend: Send + Sync + 'static fn storage_size( &self, block: Option, - storage_key: StorageKey, + storage_key: PrefixedStorageKey, key: StorageKey, ) -> FutureResult> { Box::new(self.storage(block, storage_key, key) @@ -366,7 +366,7 @@ impl ChildStateApi for ChildState fn storage( &self, - storage_key: StorageKey, + storage_key: PrefixedStorageKey, key: StorageKey, block: Option ) -> FutureResult> { @@ -375,7 +375,7 @@ impl ChildStateApi for ChildState fn storage_keys( &self, - storage_key: StorageKey, + storage_key: PrefixedStorageKey, key_prefix: StorageKey, block: Option ) -> FutureResult> { @@ -384,7 +384,7 @@ impl ChildStateApi for ChildState fn storage_hash( &self, - storage_key: StorageKey, + storage_key: PrefixedStorageKey, key: StorageKey, block: Option ) -> FutureResult> { @@ -393,7 +393,7 @@ impl ChildStateApi for ChildState fn storage_size( &self, - storage_key: StorageKey, + storage_key: PrefixedStorageKey, key: StorageKey, block: Option ) -> FutureResult> { diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index 599b8af349..273d421dc9 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -30,7 +30,7 @@ use sp_blockchain::{Result as ClientResult, Error as ClientError, HeaderMetadata use sc_client::BlockchainEvents; use sp_core::{ Bytes, storage::{well_known_keys, StorageKey, StorageData, StorageChangeSet, - ChildInfo, ChildType}, + ChildInfo, ChildType, PrefixedStorageKey}, }; use sp_version::RuntimeVersion; use sp_runtime::{ @@ -471,13 +471,13 @@ impl ChildStateBackend for FullState, - storage_key: StorageKey, + storage_key: PrefixedStorageKey, prefix: StorageKey, ) -> FutureResult> { Box::new(result( self.block_or_best(block) .and_then(|block| { - let child_info = match ChildType::from_prefixed_key(&storage_key.0[..]) { + let child_info = match ChildType::from_prefixed_key(&storage_key) { Some((ChildType::ParentKeyId, storage_key)) => ChildInfo::new_default(storage_key), None => return Err("Invalid child storage key".into()), }; @@ -493,13 +493,13 @@ impl ChildStateBackend for FullState, - storage_key: StorageKey, + storage_key: PrefixedStorageKey, key: StorageKey, ) -> FutureResult> { Box::new(result( self.block_or_best(block) .and_then(|block| { - let child_info = match ChildType::from_prefixed_key(&storage_key.0[..]) { + let child_info = match ChildType::from_prefixed_key(&storage_key) { Some((ChildType::ParentKeyId, storage_key)) => ChildInfo::new_default(storage_key), None => return Err("Invalid child storage key".into()), }; @@ -515,13 +515,13 @@ impl ChildStateBackend for FullState, - storage_key: StorageKey, + storage_key: PrefixedStorageKey, key: StorageKey, ) -> FutureResult> { Box::new(result( self.block_or_best(block) .and_then(|block| { - let child_info = match ChildType::from_prefixed_key(&storage_key.0[..]) { + let child_info = match ChildType::from_prefixed_key(&storage_key) { Some((ChildType::ParentKeyId, storage_key)) => ChildInfo::new_default(storage_key), None => return Err("Invalid child storage key".into()), }; diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index 22bee62950..ae33bd44cc 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -48,7 +48,8 @@ use sc_client::{ }, }; use sp_core::{ - Bytes, OpaqueMetadata, storage::{StorageKey, StorageData, StorageChangeSet}, + Bytes, OpaqueMetadata, + storage::{StorageKey, PrefixedStorageKey, StorageData, StorageChangeSet}, }; use sp_version::RuntimeVersion; use sp_runtime::{generic::BlockId, traits::{Block as BlockT, HashFor}}; @@ -458,7 +459,7 @@ impl ChildStateBackend for LightState, - _storage_key: StorageKey, + _storage_key: PrefixedStorageKey, _prefix: StorageKey, ) -> FutureResult> { Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) @@ -467,7 +468,7 @@ impl ChildStateBackend for LightState, - storage_key: StorageKey, + storage_key: PrefixedStorageKey, key: StorageKey, ) -> FutureResult> { let block = self.block_or_best(block); @@ -477,7 +478,7 @@ impl ChildStateBackend for LightState Either::Left(fetcher.remote_read_child(RemoteReadChildRequest { block, header, - storage_key: storage_key.0, + storage_key, keys: vec![key.0.clone()], retry_count: Default::default(), }).then(move |result| ready(result @@ -497,7 +498,7 @@ impl ChildStateBackend for LightState, - storage_key: StorageKey, + storage_key: PrefixedStorageKey, key: StorageKey, ) -> FutureResult> { Box::new(ChildStateBackend::storage(self, block, storage_key, key) diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index 24ea59dc48..74455c99f6 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -32,7 +32,11 @@ use substrate_test_runtime_client::{ }; const STORAGE_KEY: &[u8] = b"child"; -const PREFIXED_STORAGE_KEY: &[u8] = b":child_storage:default:child"; + +fn prefixed_storage_key() -> PrefixedStorageKey { + let child_info = ChildInfo::new_default(&b":child_storage:default:child"[..]); + child_info.prefixed_storage_key() +} #[test] fn should_return_storage() { @@ -49,7 +53,6 @@ fn should_return_storage() { let genesis_hash = client.genesis_hash(); let (client, child) = new_full(Arc::new(client), Subscriptions::new(Arc::new(core.executor()))); let key = StorageKey(KEY.to_vec()); - let storage_key = StorageKey(PREFIXED_STORAGE_KEY.to_vec()); assert_eq!( client.storage(key.clone(), Some(genesis_hash).into()).wait() @@ -67,7 +70,7 @@ fn should_return_storage() { ); assert_eq!( core.block_on( - child.storage(storage_key, key, Some(genesis_hash).into()) + child.storage(prefixed_storage_key(), key, Some(genesis_hash).into()) .map(|x| x.map(|x| x.0.len())) ).unwrap().unwrap() as usize, CHILD_VALUE.len(), @@ -84,7 +87,7 @@ fn should_return_child_storage() { .build()); let genesis_hash = client.genesis_hash(); let (_client, child) = new_full(client, Subscriptions::new(Arc::new(core.executor()))); - let child_key = StorageKey(PREFIXED_STORAGE_KEY.to_vec()); + let child_key = prefixed_storage_key(); let key = StorageKey(b"key".to_vec()); diff --git a/client/src/client.rs b/client/src/client.rs index 8ec045b7f5..f273cae650 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -26,8 +26,8 @@ use parking_lot::{Mutex, RwLock}; use codec::{Encode, Decode}; use hash_db::Prefix; use sp_core::{ - ChangesTrieConfiguration, convert_hash, traits::CodeExecutor, - NativeOrEncoded, storage::{StorageKey, StorageData, well_known_keys, ChildInfo}, + ChangesTrieConfiguration, convert_hash, traits::CodeExecutor, NativeOrEncoded, + storage::{StorageKey, PrefixedStorageKey, StorageData, well_known_keys, ChildInfo}, }; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; use sp_runtime::{ @@ -344,7 +344,7 @@ impl Client where last: Block::Hash, min: Block::Hash, max: Block::Hash, - storage_key: Option<&StorageKey>, + storage_key: Option<&PrefixedStorageKey>, key: &StorageKey, cht_size: NumberFor, ) -> sp_blockchain::Result> { @@ -393,7 +393,7 @@ impl Client where fn with_cached_changed_keys( &self, root: &Block::Hash, - functor: &mut dyn FnMut(&HashMap>, HashSet>>), + functor: &mut dyn FnMut(&HashMap, HashSet>>), ) -> bool { self.storage.with_cached_changed_keys(root, functor) } @@ -438,7 +438,7 @@ impl Client where number: last_number, }, max_number, - storage_key.as_ref().map(|x| &x.0[..]), + storage_key, &key.0, ) .map_err(|err| sp_blockchain::Error::ChangesTrieAccessFailed(err))?; @@ -1146,7 +1146,7 @@ impl ProofProvider for Client where last: Block::Hash, min: Block::Hash, max: Block::Hash, - storage_key: Option<&StorageKey>, + storage_key: Option<&PrefixedStorageKey>, key: &StorageKey, ) -> sp_blockchain::Result> { self.key_changes_proof_with_cht_size( @@ -1345,7 +1345,7 @@ impl StorageProvider for Client wher &self, first: NumberFor, last: BlockId, - storage_key: Option<&StorageKey>, + storage_key: Option<&PrefixedStorageKey>, key: &StorageKey ) -> sp_blockchain::Result, u32)>> { let last_number = self.backend.blockchain().expect_block_number_from_id(&last)?; @@ -1376,7 +1376,7 @@ impl StorageProvider for Client wher range_first, &range_anchor, best_number, - storage_key.as_ref().map(|x| &x.0[..]), + storage_key, &key.0) .and_then(|r| r.map(|r| r.map(|(block, tx)| (block, tx))).collect::>()) .map_err(|err| sp_blockchain::Error::ChangesTrieAccessFailed(err))?; diff --git a/client/src/light/fetcher.rs b/client/src/light/fetcher.rs index ce2434d6c6..ef6a062cf3 100644 --- a/client/src/light/fetcher.rs +++ b/client/src/light/fetcher.rs @@ -136,7 +136,7 @@ impl> LightDataChecker { number: request.last_block.0, }, remote_max_block, - request.storage_key.as_ref().map(Vec::as_slice), + request.storage_key.as_ref(), &request.key) .map_err(|err| ClientError::ChangesTrieAccessFailed(err))?; result.extend(result_range); @@ -243,7 +243,7 @@ impl FetchChecker for LightDataChecker request: &RemoteReadChildRequest, remote_proof: StorageProof, ) -> ClientResult, Option>>> { - let child_info = match ChildType::from_prefixed_key(&request.storage_key[..]) { + let child_info = match ChildType::from_prefixed_key(&request.storage_key) { Some((ChildType::ParentKeyId, storage_key)) => ChildInfo::new_default(storage_key), None => return Err("Invalid child type".into()), }; @@ -512,6 +512,7 @@ pub mod tests { #[test] fn storage_child_read_proof_is_generated_and_checked() { + let child_info = ChildInfo::new_default(&b"child1"[..]); let ( local_checker, remote_block_header, @@ -522,7 +523,7 @@ pub mod tests { &RemoteReadChildRequest::
{ block: remote_block_header.hash(), header: remote_block_header, - storage_key: b":child_storage:default:child1".to_vec(), + storage_key: child_info.prefixed_storage_key(), keys: vec![b"key1".to_vec()], retry_count: None, }, diff --git a/primitives/state-machine/src/backend.rs b/primitives/state-machine/src/backend.rs index 5334a3b8c4..c3b2146a73 100644 --- a/primitives/state-machine/src/backend.rs +++ b/primitives/state-machine/src/backend.rs @@ -187,9 +187,9 @@ pub trait Backend: std::fmt::Debug { let prefixed_storage_key = child_info.prefixed_storage_key(); txs.consolidate(child_txs); if empty { - child_roots.push((prefixed_storage_key, None)); + child_roots.push((prefixed_storage_key.key(), None)); } else { - child_roots.push((prefixed_storage_key, Some(child_root.encode()))); + child_roots.push((prefixed_storage_key.key(), Some(child_root.encode()))); } } let (root, parent_txs) = self.storage_root( diff --git a/primitives/state-machine/src/basic.rs b/primitives/state-machine/src/basic.rs index 54c21dfc20..b8b3210a87 100644 --- a/primitives/state-machine/src/basic.rs +++ b/primitives/state-machine/src/basic.rs @@ -242,7 +242,7 @@ impl Externalities for BasicExternalities { if &empty_hash[..] == &child_root[..] { top.remove(prefixed_storage_key.as_slice()); } else { - top.insert(prefixed_storage_key, child_root); + top.insert(prefixed_storage_key.key(), child_root); } } diff --git a/primitives/state-machine/src/changes_trie/build.rs b/primitives/state-machine/src/changes_trie/build.rs index cf1a2e3bfb..0f60c8e317 100644 --- a/primitives/state-machine/src/changes_trie/build.rs +++ b/primitives/state-machine/src/changes_trie/build.rs @@ -32,7 +32,7 @@ use crate::{ input::{InputKey, InputPair, DigestIndex, ExtrinsicIndex, ChildIndex}, }, }; -use sp_core::storage::{ChildInfo, ChildType}; +use sp_core::storage::{ChildInfo, ChildType, PrefixedStorageKey}; /// Prepare input pairs for building a changes trie of given block. /// @@ -280,7 +280,7 @@ fn prepare_digest_input<'a, H, Number>( return Ok((map, child_map)); } - let mut children_roots = BTreeMap::::new(); + let mut children_roots = BTreeMap::::new(); { let trie_storage = TrieBackendEssence::<_, H>::new( crate::changes_trie::TrieBackendStorageAdapter(storage), @@ -774,7 +774,7 @@ mod test { ], ); assert_eq!( - child_changes_tries_nodes.get(&ChildIndex { block: 16u64, storage_key: child_trie_key2.to_vec() }).unwrap(), + child_changes_tries_nodes.get(&ChildIndex { block: 16u64, storage_key: child_trie_key2.clone() }).unwrap(), &vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16u64, key: vec![100] }, vec![0, 2]), diff --git a/primitives/state-machine/src/changes_trie/build_cache.rs b/primitives/state-machine/src/changes_trie/build_cache.rs index 9d0dbb4c1f..aebebf3a17 100644 --- a/primitives/state-machine/src/changes_trie/build_cache.rs +++ b/primitives/state-machine/src/changes_trie/build_cache.rs @@ -19,6 +19,7 @@ use std::collections::{HashMap, HashSet}; use crate::StorageKey; +use sp_core::storage::PrefixedStorageKey; /// Changes trie build cache. /// @@ -38,7 +39,7 @@ pub struct BuildCache { /// The `Option>` in inner `HashMap` stands for the child storage key. /// If it is `None`, then the `HashSet` contains keys changed in top-level storage. /// If it is `Some`, then the `HashSet` contains keys changed in child storage, identified by the key. - changed_keys: HashMap, HashSet>>, + changed_keys: HashMap, HashSet>>, } /// The action to perform when block-with-changes-trie is imported. @@ -56,7 +57,7 @@ pub struct CachedBuildData { block: N, trie_root: H, digest_input_blocks: Vec, - changed_keys: HashMap, HashSet>, + changed_keys: HashMap, HashSet>, } /// The action to perform when block-with-changes-trie is imported. @@ -72,7 +73,7 @@ pub(crate) enum IncompleteCacheAction { #[derive(Debug, PartialEq)] pub(crate) struct IncompleteCachedBuildData { digest_input_blocks: Vec, - changed_keys: HashMap, HashSet>, + changed_keys: HashMap, HashSet>, } impl BuildCache @@ -89,7 +90,7 @@ impl BuildCache } /// Get cached changed keys for changes trie with given root. - pub fn get(&self, root: &H) -> Option<&HashMap, HashSet>> { + pub fn get(&self, root: &H) -> Option<&HashMap, HashSet>> { self.changed_keys.get(&root) } @@ -98,7 +99,7 @@ impl BuildCache pub fn with_changed_keys( &self, root: &H, - functor: &mut dyn FnMut(&HashMap, HashSet>), + functor: &mut dyn FnMut(&HashMap, HashSet>), ) -> bool { match self.changed_keys.get(&root) { Some(changed_keys) => { @@ -164,7 +165,7 @@ impl IncompleteCacheAction { /// Insert changed keys of given storage into cached data. pub(crate) fn insert( self, - storage_key: Option, + storage_key: Option, changed_keys: HashSet, ) -> Self { match self { @@ -200,7 +201,7 @@ impl IncompleteCachedBuildData { fn insert( mut self, - storage_key: Option, + storage_key: Option, changed_keys: HashSet, ) -> Self { self.changed_keys.insert(storage_key, changed_keys); diff --git a/primitives/state-machine/src/changes_trie/changes_iterator.rs b/primitives/state-machine/src/changes_trie/changes_iterator.rs index 685786218c..f5a936069b 100644 --- a/primitives/state-machine/src/changes_trie/changes_iterator.rs +++ b/primitives/state-machine/src/changes_trie/changes_iterator.rs @@ -22,6 +22,7 @@ use std::collections::VecDeque; use codec::{Decode, Encode, Codec}; use hash_db::Hasher; use num_traits::Zero; +use sp_core::storage::PrefixedStorageKey; use sp_trie::Recorder; use crate::changes_trie::{AnchorBlockId, ConfigurationRange, RootsStorage, Storage, BlockNumber}; use crate::changes_trie::input::{DigestIndex, ExtrinsicIndex, DigestIndexValue, ExtrinsicIndexValue}; @@ -40,7 +41,7 @@ pub fn key_changes<'a, H: Hasher, Number: BlockNumber>( begin: Number, end: &'a AnchorBlockId, max: Number, - storage_key: Option<&'a [u8]>, + storage_key: Option<&'a PrefixedStorageKey>, key: &'a [u8], ) -> Result, String> { // we can't query any roots before root @@ -79,7 +80,7 @@ pub fn key_changes_proof<'a, H: Hasher, Number: BlockNumber>( begin: Number, end: &AnchorBlockId, max: Number, - storage_key: Option<&[u8]>, + storage_key: Option<&PrefixedStorageKey>, key: &[u8], ) -> Result>, String> where H::Out: Codec { // we can't query any roots before root @@ -127,7 +128,7 @@ pub fn key_changes_proof_check<'a, H: Hasher, Number: BlockNumber>( begin: Number, end: &AnchorBlockId, max: Number, - storage_key: Option<&[u8]>, + storage_key: Option<&PrefixedStorageKey>, key: &[u8] ) -> Result, String> where H::Out: Encode { key_changes_proof_check_with_db( @@ -150,7 +151,7 @@ pub fn key_changes_proof_check_with_db<'a, H: Hasher, Number: BlockNumber>( begin: Number, end: &AnchorBlockId, max: Number, - storage_key: Option<&[u8]>, + storage_key: Option<&PrefixedStorageKey>, key: &[u8] ) -> Result, String> where H::Out: Encode { // we can't query any roots before root @@ -188,7 +189,7 @@ pub struct DrilldownIteratorEssence<'a, H, Number> Number: BlockNumber, H::Out: 'a, { - storage_key: Option<&'a [u8]>, + storage_key: Option<&'a PrefixedStorageKey>, key: &'a [u8], roots_storage: &'a dyn RootsStorage, storage: &'a dyn Storage, @@ -238,7 +239,7 @@ impl<'a, H, Number> DrilldownIteratorEssence<'a, H, Number> let trie_root = if let Some(storage_key) = self.storage_key { let child_key = ChildIndex { block: block.clone(), - storage_key: storage_key.to_vec(), + storage_key: storage_key.clone(), }.encode(); if let Some(trie_root) = trie_reader(self.storage, trie_root, &child_key)? .and_then(|v| >::decode(&mut &v[..]).ok()) @@ -382,6 +383,11 @@ mod tests { use sp_runtime::traits::BlakeTwo256; use super::*; + fn child_key() -> PrefixedStorageKey { + let child_info = sp_core::storage::ChildInfo::new_default(&b"1"[..]); + child_info.prefixed_storage_key() + } + fn prepare_for_drilldown() -> (Configuration, InMemoryStorage) { let config = Configuration { digest_interval: 4, digest_levels: 2 }; let backend = InMemoryStorage::with_inputs(vec![ @@ -418,7 +424,7 @@ mod tests { (16, vec![ InputPair::DigestIndex(DigestIndex { block: 16, key: vec![42] }, vec![4, 8]), ]), - ], vec![(b"1".to_vec(), vec![ + ], vec![(child_key(), vec![ (1, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 1, key: vec![42] }, vec![0]), ]), @@ -535,7 +541,7 @@ mod tests { 1, &AnchorBlockId { hash: Default::default(), number: 100 }, 1000, - Some(&b"1"[..]), + Some(&child_key()), &[42], ).and_then(|i| i.collect::, _>>()).is_err()); } @@ -577,7 +583,7 @@ mod tests { let (remote_config, remote_storage) = prepare_for_drilldown(); let remote_proof_child = key_changes_proof::( configuration_range(&remote_config, 0), &remote_storage, 1, - &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&b"1"[..]), &[42]).unwrap(); + &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&child_key()), &[42]).unwrap(); // happens on local light node: @@ -592,7 +598,7 @@ mod tests { local_storage.clear_storage(); let local_result_child = key_changes_proof_check::( configuration_range(&local_config, 0), &local_storage, remote_proof_child, 1, - &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&b"1"[..]), &[42]); + &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&child_key()), &[42]); // check that drilldown result is the same as if it was happening at the full node assert_eq!(local_result, Ok(vec![(8, 2), (8, 1), (6, 3), (3, 0)])); diff --git a/primitives/state-machine/src/changes_trie/input.rs b/primitives/state-machine/src/changes_trie/input.rs index 4a1420f848..4007620f92 100644 --- a/primitives/state-machine/src/changes_trie/input.rs +++ b/primitives/state-machine/src/changes_trie/input.rs @@ -21,6 +21,7 @@ use crate::{ StorageKey, StorageValue, changes_trie::BlockNumber }; +use sp_core::storage::PrefixedStorageKey; /// Key of { changed key => set of extrinsic indices } mapping. #[derive(Clone, Debug, PartialEq, Eq)] @@ -49,7 +50,7 @@ pub struct ChildIndex { /// Block at which this key has been inserted in the trie. pub block: Number, /// Storage key this node is responsible for. - pub storage_key: StorageKey, + pub storage_key: PrefixedStorageKey, } /// Value of { changed key => block/digest block numbers } mapping. @@ -176,10 +177,17 @@ impl Decode for InputKey { block: Decode::decode(input)?, key: Decode::decode(input)?, })), - 3 => Ok(InputKey::ChildIndex(ChildIndex { - block: Decode::decode(input)?, - storage_key: Decode::decode(input)?, - })), + 3 => { + let block = Decode::decode(input)?; + if let Some(storage_key) = PrefixedStorageKey::new(Decode::decode(input)?) { + Ok(InputKey::ChildIndex(ChildIndex { + block, + storage_key, + })) + } else { + Err("Invalid prefixed key in change trie".into()) + } + }, _ => Err("Invalid input key variant".into()), } } diff --git a/primitives/state-machine/src/changes_trie/mod.rs b/primitives/state-machine/src/changes_trie/mod.rs index d614992df3..ee6c6778e0 100644 --- a/primitives/state-machine/src/changes_trie/mod.rs +++ b/primitives/state-machine/src/changes_trie/mod.rs @@ -71,6 +71,7 @@ use hash_db::{Hasher, Prefix}; use num_traits::{One, Zero}; use codec::{Decode, Encode}; use sp_core; +use sp_core::storage::PrefixedStorageKey; use sp_trie::{MemoryDB, DBValue, TrieMut}; use sp_trie::trie_types::TrieDBMut; use crate::{ @@ -156,7 +157,7 @@ pub trait Storage: RootsStorage { fn with_cached_changed_keys( &self, root: &H::Out, - functor: &mut dyn FnMut(&HashMap, HashSet>), + functor: &mut dyn FnMut(&HashMap, HashSet>), ) -> bool; /// Get a trie node. fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String>; diff --git a/primitives/state-machine/src/changes_trie/prune.rs b/primitives/state-machine/src/changes_trie/prune.rs index 87923dc2f5..05555df305 100644 --- a/primitives/state-machine/src/changes_trie/prune.rs +++ b/primitives/state-machine/src/changes_trie/prune.rs @@ -137,7 +137,8 @@ mod tests { #[test] fn prune_works() { fn prepare_storage() -> InMemoryStorage { - let child_key = ChildIndex { block: 67u64, storage_key: b"1".to_vec() }.encode(); + let child_info = sp_core::storage::ChildInfo::new_default(&b"1"[..]); + let child_key = ChildIndex { block: 67u64, storage_key: child_info.prefixed_storage_key() }.encode(); let mut mdb1 = MemoryDB::::default(); let root1 = insert_into_memory_db::( &mut mdb1, vec![(vec![10], vec![20])]).unwrap(); diff --git a/primitives/state-machine/src/changes_trie/storage.rs b/primitives/state-machine/src/changes_trie/storage.rs index 7fb4186728..81651dd2e7 100644 --- a/primitives/state-machine/src/changes_trie/storage.rs +++ b/primitives/state-machine/src/changes_trie/storage.rs @@ -18,6 +18,7 @@ use std::collections::{BTreeMap, HashSet, HashMap}; use hash_db::{Hasher, Prefix, EMPTY_PREFIX}; +use sp_core::storage::PrefixedStorageKey; use sp_trie::DBValue; use sp_trie::MemoryDB; use parking_lot::RwLock; @@ -96,7 +97,7 @@ impl InMemoryStorage { #[cfg(test)] pub fn with_inputs( mut top_inputs: Vec<(Number, Vec>)>, - children_inputs: Vec<(StorageKey, Vec<(Number, Vec>)>)>, + children_inputs: Vec<(PrefixedStorageKey, Vec<(Number, Vec>)>)>, ) -> Self { let mut mdb = MemoryDB::default(); let mut roots = BTreeMap::new(); @@ -182,7 +183,7 @@ impl Storage for InMemoryStorage, HashSet>), + functor: &mut dyn FnMut(&HashMap, HashSet>), ) -> bool { self.cache.with_changed_keys(root, functor) } diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index 12d40873e0..33f502a75b 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -458,9 +458,9 @@ where // A better design would be to manage 'child_storage_transaction' in a // similar way as 'storage_transaction' but for each child trie. if is_empty { - self.overlay.set_storage(prefixed_storage_key, None); + self.overlay.set_storage(prefixed_storage_key.key(), None); } else { - self.overlay.set_storage(prefixed_storage_key, Some(root.clone())); + self.overlay.set_storage(prefixed_storage_key.key(), Some(root.clone())); } trace!(target: "state-trace", "{:04x}: ChildRoot({}) {}", diff --git a/primitives/state-machine/src/in_memory_backend.rs b/primitives/state-machine/src/in_memory_backend.rs index 9245b53a04..b0048d90f4 100644 --- a/primitives/state-machine/src/in_memory_backend.rs +++ b/primitives/state-machine/src/in_memory_backend.rs @@ -331,7 +331,7 @@ impl Backend for InMemory where H::Out: Codec { if let Some(child_info) = child_info.as_ref() { let prefix_storage_key = child_info.prefixed_storage_key(); let ch = insert_into_memory_db::(&mut mdb, map.clone().into_iter())?; - new_child_roots.push((prefix_storage_key, ch.as_ref().into())); + new_child_roots.push((prefix_storage_key.key(), ch.as_ref().into())); } else { root_map = Some(map); } diff --git a/primitives/storage/Cargo.toml b/primitives/storage/Cargo.toml index 9e90b6ecc6..0df854170a 100644 --- a/primitives/storage/Cargo.toml +++ b/primitives/storage/Cargo.toml @@ -14,6 +14,7 @@ sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" serde = { version = "1.0.101", optional = true, features = ["derive"] } impl-serde = { version = "0.2.3", optional = true } sp-debug-derive = { version = "2.0.0-alpha.4", path = "../debug-derive" } +ref-cast = "1.0.0" [features] default = [ "std" ] diff --git a/primitives/storage/src/lib.rs b/primitives/storage/src/lib.rs index 984c8e4738..de2a0d7e01 100644 --- a/primitives/storage/src/lib.rs +++ b/primitives/storage/src/lib.rs @@ -23,6 +23,8 @@ use serde::{Serialize, Deserialize}; use sp_debug_derive::RuntimeDebug; use sp_std::vec::Vec; +use sp_std::ops::{Deref, DerefMut}; +use ref_cast::RefCast; /// Storage key. #[derive(PartialEq, Eq, RuntimeDebug)] @@ -32,6 +34,67 @@ pub struct StorageKey( pub Vec, ); +/// Storage key of a child trie, it contains the prefix to the key. +#[derive(PartialEq, Eq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord, Clone))] +#[repr(transparent)] +#[derive(RefCast)] +pub struct PrefixedStorageKey( + #[cfg_attr(feature = "std", serde(with="impl_serde::serialize"))] + Vec, +); + +impl Deref for PrefixedStorageKey { + type Target = Vec; + + fn deref(&self) -> &Vec { + &self.0 + } +} + +impl DerefMut for PrefixedStorageKey { + fn deref_mut(&mut self) -> &mut Vec { + &mut self.0 + } +} + +impl PrefixedStorageKey { + /// Create a prefixed storage key from its byte array + /// representation. + /// Returns `None` on unknown prefix. + pub fn new(inner: Vec) -> Option { + let result = PrefixedStorageKey(inner); + // currently only support for child trie key + // note that this function should not be use in a runtime + // as it will change its behavior with future child types. + if ChildType::from_prefixed_key(&result).is_some() { + Some(result) + } else { + None + } + } + + pub fn new_ref(inner: &Vec) -> Option<&Self> { + let result = PrefixedStorageKey::ref_cast(inner); + // currently only support for child trie key + // note that this function should not be use in a runtime + // as it will change its behavior with future child types. + if ChildType::from_prefixed_key(&result).is_some() { + Some(result) + } else { + None + } + } + + /// Get inner key, this should + /// only be needed when writing + /// into parent trie to avoid an + /// allocation. + pub fn key(self) -> Vec { + self.0 + } +} + /// Storage data associated to a [`StorageKey`]. #[derive(PartialEq, Eq, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord, Clone))] @@ -109,24 +172,6 @@ pub mod well_known_keys { // Other code might depend on this, so be careful changing this. key.starts_with(CHILD_STORAGE_KEY_PREFIX) } - - /// Determine whether a child trie key is valid. - /// - /// For now, the only valid child trie keys are those starting with `:child_storage:default:`. - /// - /// `child_trie_root` and `child_delta_trie_root` can panic if invalid value is provided to them. - pub fn is_child_trie_key_valid(storage_key: &[u8]) -> bool { - let has_right_prefix = storage_key.starts_with(super::DEFAULT_CHILD_TYPE_PARENT_PREFIX); - if has_right_prefix { - // This is an attempt to catch a change of `is_child_storage_key`, which - // just checks if the key has prefix `:child_storage:` at the moment of writing. - debug_assert!( - is_child_storage_key(&storage_key), - "`is_child_trie_key_valid` is a subset of `is_child_storage_key`", - ); - } - has_right_prefix - } } /// Information related to a child state. @@ -212,7 +257,7 @@ impl ChildInfo { /// Return a the full location in the direct parent of /// this trie. - pub fn prefixed_storage_key(&self) -> Vec { + pub fn prefixed_storage_key(&self) -> PrefixedStorageKey { match self { ChildInfo::ParentKeyId(ChildTrieParentKeyId { data, @@ -222,13 +267,13 @@ impl ChildInfo { /// Returns a the full location in the direct parent of /// this trie. - pub fn into_prefixed_storage_key(self) -> Vec { + pub fn into_prefixed_storage_key(self) -> PrefixedStorageKey { match self { ChildInfo::ParentKeyId(ChildTrieParentKeyId { mut data, }) => { ChildType::ParentKeyId.do_prefix_key(&mut data); - data + PrefixedStorageKey(data) }, } } @@ -264,7 +309,7 @@ impl ChildType { /// Transform a prefixed key into a tuple of the child type /// and the unprefixed representation of the key. - pub fn from_prefixed_key<'a>(storage_key: &'a [u8]) -> Option<(Self, &'a [u8])> { + pub fn from_prefixed_key<'a>(storage_key: &'a PrefixedStorageKey) -> Option<(Self, &'a [u8])> { let match_type = |storage_key: &'a [u8], child_type: ChildType| { let prefix = child_type.parent_prefix(); if storage_key.starts_with(prefix) { @@ -277,12 +322,12 @@ impl ChildType { } /// Produce a prefixed key for a given child type. - fn new_prefixed_key(&self, key: &[u8]) -> Vec { + fn new_prefixed_key(&self, key: &[u8]) -> PrefixedStorageKey { let parent_prefix = self.parent_prefix(); let mut result = Vec::with_capacity(parent_prefix.len() + key.len()); result.extend_from_slice(parent_prefix); result.extend_from_slice(key); - result + PrefixedStorageKey(result) } /// Prefixes a vec with the prefix for this child type. diff --git a/test-utils/runtime/client/src/lib.rs b/test-utils/runtime/client/src/lib.rs index 3c56fbdcdc..e4849dee99 100644 --- a/test-utils/runtime/client/src/lib.rs +++ b/test-utils/runtime/client/src/lib.rs @@ -128,7 +128,7 @@ impl substrate_test_client::GenesisInit for GenesisParameters { child_content.data.clone().into_iter().collect() ); let prefixed_storage_key = child_content.child_info.prefixed_storage_key(); - (prefixed_storage_key, state_root.encode()) + (prefixed_storage_key.key(), state_root.encode()) }); let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( storage.top.clone().into_iter().chain(child_roots).collect() -- GitLab From 93cf07ad527c5209ba8b75615f0ec69d40cb76da Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Sat, 21 Mar 2020 08:52:57 +0100 Subject: [PATCH 038/300] Minor fixes to CLI arg docs (#5339) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * minor fixes to CLI arg docs * Update client/cli/src/params/shared_params.rs Co-authored-by: Bastian Köcher --- client/cli/src/commands/mod.rs | 8 ++++---- client/cli/src/commands/runcmd.rs | 20 +++++++++---------- client/cli/src/params/import_params.rs | 4 ++-- .../params/network_configuration_params.rs | 4 ++-- client/cli/src/params/node_key_params.rs | 4 ++-- client/cli/src/params/shared_params.rs | 7 +++++-- 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/client/cli/src/commands/mod.rs b/client/cli/src/commands/mod.rs index 50e34856f1..d87b08f7f4 100644 --- a/client/cli/src/commands/mod.rs +++ b/client/cli/src/commands/mod.rs @@ -50,7 +50,7 @@ const DEFAULT_NETWORK_CONFIG_PATH : &'static str = "network"; /// `Run` are exported as main executable parameters. #[derive(Debug, Clone, StructOpt)] pub enum Subcommand { - /// Build a spec.json file, outputing to stdout. + /// Build a spec.json file, outputs to stdout. BuildSpec(build_spec_cmd::BuildSpecCmd), /// Export blocks to a file. @@ -70,7 +70,7 @@ pub enum Subcommand { } impl Subcommand { - /// Get the shared parameters of a `CoreParams` command + /// Get the shared parameters of a `CoreParams` command. pub fn get_shared_params(&self) -> &SharedParams { use Subcommand::*; @@ -84,7 +84,7 @@ impl Subcommand { } } - /// Run any `CoreParams` command + /// Run any `CoreParams` command. pub fn run( self, config: Configuration, @@ -107,7 +107,7 @@ impl Subcommand { } } - /// Update and prepare a `Configuration` with command line parameters + /// Update and prepare a `Configuration` with command line parameters. pub fn update_config( &self, mut config: &mut Configuration, diff --git a/client/cli/src/commands/runcmd.rs b/client/cli/src/commands/runcmd.rs index 3544486363..c8af14359c 100644 --- a/client/cli/src/commands/runcmd.rs +++ b/client/cli/src/commands/runcmd.rs @@ -82,7 +82,7 @@ pub struct RunCmd { )] pub sentry: bool, - /// Disable GRANDPA voter when running in validator mode, otherwise disables the GRANDPA observer. + /// Disable GRANDPA voter when running in validator mode, otherwise disable the GRANDPA observer. #[structopt(long = "no-grandpa")] pub no_grandpa: bool, @@ -92,7 +92,7 @@ pub struct RunCmd { /// Listen to all RPC interfaces. /// - /// Default is local. Note: not all RPC methods are safe to be exposed publicly. Use a RPC proxy + /// Default is local. Note: not all RPC methods are safe to be exposed publicly. Use an RPC proxy /// server to filter out dangerous methods. More details: https://github.com/paritytech/substrate/wiki/Public-RPC. /// Use `--unsafe-rpc-external` to suppress the warning if you understand the risks. #[structopt(long = "rpc-external")] @@ -106,7 +106,7 @@ pub struct RunCmd { /// Listen to all Websocket interfaces. /// - /// Default is local. Note: not all RPC methods are safe to be exposed publicly. Use a RPC proxy + /// Default is local. Note: not all RPC methods are safe to be exposed publicly. Use an RPC proxy /// server to filter out dangerous methods. More details: https://github.com/paritytech/substrate/wiki/Public-RPC. /// Use `--unsafe-ws-external` to suppress the warning if you understand the risks. #[structopt(long = "ws-external")] @@ -169,7 +169,7 @@ pub struct RunCmd { /// The URL of the telemetry server to connect to. /// - /// This flag can be passed multiple times as a mean to specify multiple + /// This flag can be passed multiple times as a means to specify multiple /// telemetry endpoints. Verbosity levels range from 0-9, with 0 denoting /// the least verbosity. If no verbosity level is specified the default is /// 0. @@ -275,7 +275,7 @@ pub struct RunCmd { } impl RunCmd { - /// Get the `Sr25519Keyring` matching one of the flag + /// Get the `Sr25519Keyring` matching one of the flag. pub fn get_keyring(&self) -> Option { use sp_keyring::Sr25519Keyring::*; @@ -290,7 +290,7 @@ impl RunCmd { else { None } } - /// Update and prepare a `Configuration` with command line parameters of `RunCmd` and `VersionInfo` + /// Update and prepare a `Configuration` with command line parameters of `RunCmd` and `VersionInfo`. pub fn update_config( &self, mut config: &mut Configuration, @@ -444,7 +444,7 @@ impl RunCmd { Ok(()) } - /// Run the command that runs the node + /// Run the command that runs the node. pub fn run( self, config: Configuration, @@ -489,7 +489,7 @@ impl RunCmd { } } -/// Check whether a node name is considered as valid +/// Check whether a node name is considered as valid. pub fn is_node_name_valid(_name: &str) -> Result<(), &str> { let name = _name.to_string(); if name.chars().count() >= NODE_NAME_MAX_LENGTH { @@ -586,7 +586,7 @@ fn parse_telemetry_endpoints(s: &str) -> Result<(String, u8), Box), @@ -601,7 +601,7 @@ impl From for Option> { } } -/// Parse cors origins +/// Parse cors origins. fn parse_cors(s: &str) -> Result> { let mut is_all = false; let mut origins = Vec::new(); diff --git a/client/cli/src/params/import_params.rs b/client/cli/src/params/import_params.rs index 2b826d69c7..b647feeece 100644 --- a/client/cli/src/params/import_params.rs +++ b/client/cli/src/params/import_params.rs @@ -62,11 +62,11 @@ pub struct ImportParams { #[structopt(long = "state-cache-size", value_name = "Bytes", default_value = "67108864")] pub state_cache_size: usize, - /// Comma separated list of targets for tracing + /// Comma separated list of targets for tracing. #[structopt(long = "tracing-targets", value_name = "TARGETS")] pub tracing_targets: Option, - /// Receiver to process tracing messages + /// Receiver to process tracing messages. #[structopt( long = "tracing-receiver", value_name = "RECEIVER", diff --git a/client/cli/src/params/network_configuration_params.rs b/client/cli/src/params/network_configuration_params.rs index 974fa0be93..4de5e44fb5 100644 --- a/client/cli/src/params/network_configuration_params.rs +++ b/client/cli/src/params/network_configuration_params.rs @@ -83,9 +83,9 @@ pub struct NetworkConfigurationParams { #[structopt(long = "no-mdns")] pub no_mdns: bool, - /// Maximum number of peers to ask the same blocks in parallel. + /// Maximum number of peers from which to ask for the same blocks in parallel. /// - /// This allows downlading announced blocks from multiple peers. Decrease to save + /// This allows downloading announced blocks from multiple peers. Decrease to save /// traffic and risk increased latency. #[structopt(long = "max-parallel-downloads", value_name = "COUNT", default_value = "5")] pub max_parallel_downloads: u32, diff --git a/client/cli/src/params/node_key_params.rs b/client/cli/src/params/node_key_params.rs index aef3af94c7..c55ec8ee69 100644 --- a/client/cli/src/params/node_key_params.rs +++ b/client/cli/src/params/node_key_params.rs @@ -38,7 +38,7 @@ pub struct NodeKeyParams { /// `--node-key-type` as follows: /// /// `ed25519`: - /// The value is parsed as a hex-encoded Ed25519 32 bytes secret key, + /// The value is parsed as a hex-encoded Ed25519 32 byte secret key, /// i.e. 64 hex characters. /// /// The value of this option takes precedence over `--node-key-file`. @@ -82,7 +82,7 @@ pub struct NodeKeyParams { /// as follows: /// /// `ed25519`: - /// The file must contain an unencoded 32 bytes Ed25519 secret key. + /// The file must contain an unencoded 32 byte Ed25519 secret key. /// /// If the file does not exist, it is created with a newly generated secret key of /// the chosen type. diff --git a/client/cli/src/params/shared_params.rs b/client/cli/src/params/shared_params.rs index 310e3de5da..41b9cce826 100644 --- a/client/cli/src/params/shared_params.rs +++ b/client/cli/src/params/shared_params.rs @@ -30,7 +30,7 @@ const DEFAULT_DB_CONFIG_PATH : &'static str = "db"; /// Shared parameters used by all `CoreParams`. #[derive(Debug, StructOpt, Clone)] pub struct SharedParams { - /// Specify the chain specification (one of dev, local or staging). + /// Specify the chain specification (one of dev, local, or staging). #[structopt(long = "chain", value_name = "CHAIN_SPEC")] pub chain: Option, @@ -42,7 +42,10 @@ pub struct SharedParams { #[structopt(long = "base-path", short = "d", value_name = "PATH", parse(from_os_str))] pub base_path: Option, - /// Sets a custom logging filter. + /// Sets a custom logging filter. Syntax is =, e.g. -lsync=debug. + /// + /// Log levels (least to most verbose) are error, warn, info, debug, and trace. + /// By default, all targets log `info`. The global log level can be set with -l. #[structopt(short = "l", long = "log", value_name = "LOG_PATTERN")] pub log: Option, } -- GitLab From 2eb9c260a2eef339d1f7ce119008b2bca45a50bc Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sat, 21 Mar 2020 16:08:48 +0100 Subject: [PATCH 039/300] Redesign Democracy pallet (#5294) * Repot a bit of democracy code * Basic logic is drafted * Lazy democracy builds. * Add non-locked split-voting and instant-scheduling. * Introduce delegation that works. * Builds again. * Indentation * Building. * Docs and migration * Fix half of the tests * Fix up & repot tests * Fix runtime build * Update docs * Docs * Nits. * Turnout counts full capital * Delegations could towards capital * proxy delegation & proxy unvoting * Fix * Tests for split-voting * Add missing file * Persistent locking. --- bin/node/runtime/src/lib.rs | 8 +- frame/democracy/src/conviction.rs | 113 + frame/democracy/src/lib.rs | 2346 ++++------------- frame/democracy/src/tests.rs | 250 ++ frame/democracy/src/tests/cancellation.rs | 94 + frame/democracy/src/tests/delegation.rs | 178 ++ .../democracy/src/tests/external_proposing.rs | 289 ++ frame/democracy/src/tests/fast_tracking.rs | 88 + frame/democracy/src/tests/lock_voting.rs | 364 +++ frame/democracy/src/tests/preimage.rs | 164 ++ frame/democracy/src/tests/proxying.rs | 104 + frame/democracy/src/tests/public_proposals.rs | 104 + frame/democracy/src/tests/scheduling.rs | 115 + frame/democracy/src/tests/voting.rs | 170 ++ frame/democracy/src/types.rs | 217 ++ frame/democracy/src/vote.rs | 181 ++ frame/democracy/src/vote_threshold.rs | 34 +- frame/support/src/lib.rs | 2 +- frame/support/src/storage/migration.rs | 76 + 19 files changed, 3078 insertions(+), 1819 deletions(-) create mode 100644 frame/democracy/src/conviction.rs create mode 100644 frame/democracy/src/tests.rs create mode 100644 frame/democracy/src/tests/cancellation.rs create mode 100644 frame/democracy/src/tests/delegation.rs create mode 100644 frame/democracy/src/tests/external_proposing.rs create mode 100644 frame/democracy/src/tests/fast_tracking.rs create mode 100644 frame/democracy/src/tests/lock_voting.rs create mode 100644 frame/democracy/src/tests/preimage.rs create mode 100644 frame/democracy/src/tests/proxying.rs create mode 100644 frame/democracy/src/tests/public_proposals.rs create mode 100644 frame/democracy/src/tests/scheduling.rs create mode 100644 frame/democracy/src/tests/voting.rs create mode 100644 frame/democracy/src/types.rs create mode 100644 frame/democracy/src/vote.rs diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index e6c2ca05f0..ccd2eba78f 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -68,6 +68,7 @@ use impls::{CurrencyToVoteHandler, Author, LinearWeightToFee, TargetedFeeAdjustm /// Constant values used within the runtime. pub mod constants; use constants::{time::*, currency::*}; +use frame_system::Trait; // Make the WASM binary available. #[cfg(feature = "std")] @@ -302,7 +303,8 @@ impl pallet_staking::Trait for Runtime { parameter_types! { pub const LaunchPeriod: BlockNumber = 28 * 24 * 60 * MINUTES; pub const VotingPeriod: BlockNumber = 28 * 24 * 60 * MINUTES; - pub const EmergencyVotingPeriod: BlockNumber = 3 * 24 * 60 * MINUTES; + pub const FastTrackVotingPeriod: BlockNumber = 3 * 24 * 60 * MINUTES; + pub const InstantAllowed: bool = true; pub const MinimumDeposit: Balance = 100 * DOLLARS; pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES; pub const CooloffPeriod: BlockNumber = 28 * 24 * 60 * MINUTES; @@ -328,7 +330,9 @@ impl pallet_democracy::Trait for Runtime { /// Two thirds of the technical committee can have an ExternalMajority/ExternalDefault vote /// be tabled immediately and with a shorter voting/enactment period. type FastTrackOrigin = pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>; - type EmergencyVotingPeriod = EmergencyVotingPeriod; + type InstantOrigin = pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>; + type InstantAllowed = InstantAllowed; + type FastTrackVotingPeriod = FastTrackVotingPeriod; // To cancel a proposal which has been passed, 2/3 of the council must agree to it. type CancellationOrigin = pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>; // Any single technical committee member may veto a coming council proposal, however they can diff --git a/frame/democracy/src/conviction.rs b/frame/democracy/src/conviction.rs new file mode 100644 index 0000000000..a057ee2a35 --- /dev/null +++ b/frame/democracy/src/conviction.rs @@ -0,0 +1,113 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The conviction datatype. + +use sp_std::{result::Result, convert::TryFrom}; +use sp_runtime::{RuntimeDebug, traits::{Zero, Bounded, CheckedMul, CheckedDiv}}; +use codec::{Encode, Decode}; +use crate::types::Delegations; + +/// A value denoting the strength of conviction of a vote. +#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)] +pub enum Conviction { + /// 0.1x votes, unlocked. + None, + /// 1x votes, locked for an enactment period following a successful vote. + Locked1x, + /// 2x votes, locked for 2x enactment periods following a successful vote. + Locked2x, + /// 3x votes, locked for 4x... + Locked3x, + /// 4x votes, locked for 8x... + Locked4x, + /// 5x votes, locked for 16x... + Locked5x, + /// 6x votes, locked for 32x... + Locked6x, +} + +impl Default for Conviction { + fn default() -> Self { + Conviction::None + } +} + +impl From for u8 { + fn from(c: Conviction) -> u8 { + match c { + Conviction::None => 0, + Conviction::Locked1x => 1, + Conviction::Locked2x => 2, + Conviction::Locked3x => 3, + Conviction::Locked4x => 4, + Conviction::Locked5x => 5, + Conviction::Locked6x => 6, + } + } +} + +impl TryFrom for Conviction { + type Error = (); + fn try_from(i: u8) -> Result { + Ok(match i { + 0 => Conviction::None, + 1 => Conviction::Locked1x, + 2 => Conviction::Locked2x, + 3 => Conviction::Locked3x, + 4 => Conviction::Locked4x, + 5 => Conviction::Locked5x, + 6 => Conviction::Locked6x, + _ => return Err(()), + }) + } +} + +impl Conviction { + /// The amount of time (in number of periods) that our conviction implies a successful voter's + /// balance should be locked for. + pub fn lock_periods(self) -> u32 { + match self { + Conviction::None => 0, + Conviction::Locked1x => 1, + Conviction::Locked2x => 2, + Conviction::Locked3x => 4, + Conviction::Locked4x => 8, + Conviction::Locked5x => 16, + Conviction::Locked6x => 32, + } + } + + /// The votes of a voter of the given `balance` with our conviction. + pub fn votes< + B: From + Zero + Copy + CheckedMul + CheckedDiv + Bounded + >(self, capital: B) -> Delegations { + let votes = match self { + Conviction::None => capital.checked_div(&10u8.into()).unwrap_or_else(Zero::zero), + x => capital.checked_mul(&u8::from(x).into()).unwrap_or_else(B::max_value), + }; + Delegations { votes, capital } + } +} + +impl Bounded for Conviction { + fn min_value() -> Self { + Conviction::None + } + fn max_value() -> Self { + Conviction::Locked6x + } +} diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index 04aef6fe41..32371c8a3a 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -51,9 +51,10 @@ //! account or an external origin) suggests that the system adopt. //! - **Referendum:** A proposal that is in the process of being voted on for //! either acceptance or rejection as a change to the system. -//! - **Proxy:** An account that votes on behalf of a separate "Stash" account +//! - **Proxy:** An account that has full voting power on behalf of a separate "Stash" account //! that holds the funds. -//! - **Delegation:** The act of granting your voting power to the decisions of another account. +//! - **Delegation:** The act of granting your voting power to the decisions of another account for +//! up to a certain conviction. //! //! ### Adaptive Quorum Biasing //! @@ -77,21 +78,33 @@ //! These calls can be made from any externally held account capable of creating //! a signed extrinsic. //! -//! - `propose` - Submits a sensitive action, represented as a hash. -//! Requires a deposit. -//! - `second` - Signals agreement with a proposal, moves it higher on the -//! proposal queue, and requires a matching deposit to the original. -//! - `vote` - Votes in a referendum, either the vote is "Aye" to enact the -//! proposal or "Nay" to keep the status quo. -//! - `proxy_vote` - Votes in a referendum on behalf of a stash account. +//! Basic actions: +//! - `propose` - Submits a sensitive action, represented as a hash. Requires a deposit. +//! - `second` - Signals agreement with a proposal, moves it higher on the proposal queue, and +//! requires a matching deposit to the original. +//! - `vote` - Votes in a referendum, either the vote is "Aye" to enact the proposal or "Nay" to +//! keep the status quo. +//! - `unvote` - Cancel a previous vote, this must be done by the voter before the vote ends. +//! - `delegate` - Delegates the voting power (tokens * conviction) to another account. +//! - `undelegate` - Stops the delegation of voting power to another account. +//! +//! Administration actions that can be done to any account: +//! - `reap_vote` - Remove some account's expired votes. +//! - `unlock` - Redetermine the account's balance lock, potentially making tokens available. +//! +//! Proxy administration: //! - `activate_proxy` - Activates a proxy that is already open to the sender. //! - `close_proxy` - Clears the proxy status, called by the proxy. -//! - `deactivate_proxy` - Deactivates a proxy back to the open status, called by -//! the stash. +//! - `deactivate_proxy` - Deactivates a proxy back to the open status, called by the stash. //! - `open_proxy` - Opens a proxy account on behalf of the sender. -//! - `delegate` - Delegates the voting power (tokens * conviction) to another -//! account. -//! - `undelegate` - Stops the delegation of voting power to another account. +//! +//! Proxy actions: +//! - `proxy_vote` - Votes in a referendum on behalf of a stash account. +//! - `proxy_unvote` - Cancel a previous vote, done on behalf of the voter by a proxy. +//! - `proxy_delegate` - Delegate voting power, done on behalf of the voter by a proxy. +//! - `proxy_undelegate` - Stop delegating voting power, done on behalf of the voter by a proxy. +//! +//! Preimage actions: //! - `note_preimage` - Registers the preimage for an upcoming proposal, requires //! a deposit that is returned once the proposal is enacted. //! - `note_imminent_preimage` - Registers the preimage for an upcoming proposal. @@ -99,7 +112,6 @@ //! - `reap_preimage` - Removes the preimage for an expired proposal. Will only //! work under the condition that it's the same account that noted it and //! after the voting period, OR it's a different account after the enactment period. -//! - `unlock` - Unlocks tokens that have an expired lock. //! //! #### Cancellation Origin //! @@ -152,14 +164,12 @@ #![cfg_attr(not(feature = "std"), no_std)] use sp_std::prelude::*; -use sp_std::{result, convert::TryFrom}; use sp_runtime::{ - RuntimeDebug, DispatchResult, - traits::{Zero, Bounded, CheckedMul, CheckedDiv, EnsureOrigin, Hash, Dispatchable, Saturating}, + DispatchResult, DispatchError, traits::{Zero, EnsureOrigin, Hash, Dispatchable, Saturating}, }; -use codec::{Ref, Encode, Decode, Input, Output}; +use codec::{Ref, Decode}; use frame_support::{ - decl_module, decl_storage, decl_event, decl_error, ensure, Parameter, IterableStorageMap, + decl_module, decl_storage, decl_event, decl_error, ensure, Parameter, weights::SimpleDispatchInfo, traits::{ Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, @@ -169,7 +179,16 @@ use frame_support::{ use frame_system::{self as system, ensure_signed, ensure_root}; mod vote_threshold; +mod vote; +mod conviction; +mod types; pub use vote_threshold::{Approved, VoteThreshold}; +pub use vote::{Vote, AccountVote, Voting}; +pub use conviction::Conviction; +pub use types::{ReferendumInfo, ReferendumStatus, ProxyState, Tally, UnvoteScope, Delegations}; + +#[cfg(test)] +mod tests; const DEMOCRACY_ID: LockIdentifier = *b"democrac"; @@ -179,134 +198,9 @@ pub type PropIndex = u32; /// A referendum index. pub type ReferendumIndex = u32; -/// A value denoting the strength of conviction of a vote. -#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)] -pub enum Conviction { - /// 0.1x votes, unlocked. - None, - /// 1x votes, locked for an enactment period following a successful vote. - Locked1x, - /// 2x votes, locked for 2x enactment periods following a successful vote. - Locked2x, - /// 3x votes, locked for 4x... - Locked3x, - /// 4x votes, locked for 8x... - Locked4x, - /// 5x votes, locked for 16x... - Locked5x, - /// 6x votes, locked for 32x... - Locked6x, -} - -impl Default for Conviction { - fn default() -> Self { - Conviction::None - } -} - -impl From for u8 { - fn from(c: Conviction) -> u8 { - match c { - Conviction::None => 0, - Conviction::Locked1x => 1, - Conviction::Locked2x => 2, - Conviction::Locked3x => 3, - Conviction::Locked4x => 4, - Conviction::Locked5x => 5, - Conviction::Locked6x => 6, - } - } -} - -impl TryFrom for Conviction { - type Error = (); - fn try_from(i: u8) -> result::Result { - Ok(match i { - 0 => Conviction::None, - 1 => Conviction::Locked1x, - 2 => Conviction::Locked2x, - 3 => Conviction::Locked3x, - 4 => Conviction::Locked4x, - 5 => Conviction::Locked5x, - 6 => Conviction::Locked6x, - _ => return Err(()), - }) - } -} - -impl Conviction { - /// The amount of time (in number of periods) that our conviction implies a successful voter's - /// balance should be locked for. - fn lock_periods(self) -> u32 { - match self { - Conviction::None => 0, - Conviction::Locked1x => 1, - Conviction::Locked2x => 2, - Conviction::Locked3x => 4, - Conviction::Locked4x => 8, - Conviction::Locked5x => 16, - Conviction::Locked6x => 32, - } - } - - /// The votes of a voter of the given `balance` with our conviction. - fn votes< - B: From + Zero + Copy + CheckedMul + CheckedDiv + Bounded - >(self, balance: B) -> (B, B) { - match self { - Conviction::None => { - let r = balance.checked_div(&10u8.into()).unwrap_or_else(Zero::zero); - (r, r) - } - x => ( - balance.checked_mul(&u8::from(x).into()).unwrap_or_else(B::max_value), - balance, - ) - } - } -} - -impl Bounded for Conviction { - fn min_value() -> Self { - Conviction::None - } - - fn max_value() -> Self { - Conviction::Locked6x - } -} - -const MAX_RECURSION_LIMIT: u32 = 16; - -/// A number of lock periods, plus a vote, one way or the other. -#[derive(Copy, Clone, Eq, PartialEq, Default, RuntimeDebug)] -pub struct Vote { - pub aye: bool, - pub conviction: Conviction, -} - -impl Encode for Vote { - fn encode_to(&self, output: &mut T) { - output.push_byte(u8::from(self.conviction) | if self.aye { 0b1000_0000 } else { 0 }); - } -} - -impl codec::EncodeLike for Vote {} - -impl Decode for Vote { - fn decode(input: &mut I) -> core::result::Result { - let b = input.read_byte()?; - Ok(Vote { - aye: (b & 0b1000_0000) == 0b1000_0000, - conviction: Conviction::try_from(b & 0b0111_1111) - .map_err(|_| codec::Error::from("Invalid conviction"))?, - }) - } -} - type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = -<::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; pub trait Trait: frame_system::Trait + Sized { type Proposal: Parameter + Dispatchable; @@ -344,13 +238,23 @@ pub trait Trait: frame_system::Trait + Sized { /// a negative-turnout-bias (default-carries) referendum. type ExternalDefaultOrigin: EnsureOrigin; - /// Origin from which the next referendum proposed by the external majority may be immediately - /// tabled to vote asynchronously in a similar manner to the emergency origin. It remains a - /// majority-carries vote. + /// Origin from which the next majority-carries (or more permissive) referendum may be tabled to + /// vote according to the `FastTrackVotingPeriod` asynchronously in a similar manner to the + /// emergency origin. It retains its threshold method. type FastTrackOrigin: EnsureOrigin; - /// Minimum voting period allowed for an fast-track/emergency referendum. - type EmergencyVotingPeriod: Get; + /// Origin from which the next majority-carries (or more permissive) referendum may be tabled to + /// vote immediately and asynchronously in a similar manner to the emergency origin. It retains + /// its threshold method. + type InstantOrigin: EnsureOrigin; + + /// Indicator for whether an emergency origin is even allowed to happen. Some chains may want + /// to set this permanently to `false`, others may want to condition it on things such as + /// an upgrade having happened recently. + type InstantAllowed: Get; + + /// Minimum voting period allowed for a fast-track referendum. + type FastTrackVotingPeriod: Get; /// Origin from which any referendum may be cancelled in an emergency. type CancellationOrigin: EnsureOrigin; @@ -368,100 +272,60 @@ pub trait Trait: frame_system::Trait + Sized { type Slash: OnUnbalanced>; } -/// Info regarding an ongoing referendum. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -pub struct ReferendumInfo { - /// When voting on this referendum will end. - end: BlockNumber, - /// The hash of the proposal being voted on. - proposal_hash: Hash, - /// The thresholding mechanism to determine whether it passed. - threshold: VoteThreshold, - /// The delay (in blocks) to wait after a successful referendum before deploying. - delay: BlockNumber, -} - -impl ReferendumInfo { - /// Create a new instance. - pub fn new( - end: BlockNumber, - proposal_hash: Hash, - threshold: VoteThreshold, - delay: BlockNumber - ) -> Self { - ReferendumInfo { end, proposal_hash, threshold, delay } - } -} - -/// State of a proxy voting account. -#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] -pub enum ProxyState { - /// Account is open to becoming a proxy but is not yet assigned. - Open(AccountId), - /// Account is actively being a proxy. - Active(AccountId), -} - -impl ProxyState { - fn as_active(self) -> Option { - match self { - ProxyState::Active(a) => Some(a), - ProxyState::Open(_) => None, - } - } -} - decl_storage! { trait Store for Module as Democracy { + // TODO: Refactor public proposal queue into its own pallet. + // https://github.com/paritytech/substrate/issues/5322 /// The number of (public) proposals that have been made so far. pub PublicPropCount get(fn public_prop_count) build(|_| 0 as PropIndex) : PropIndex; /// The public proposals. Unsorted. The second item is the proposal's hash. pub PublicProps get(fn public_props): Vec<(PropIndex, T::Hash, T::AccountId)>; + /// Those who have locked a deposit. + pub DepositOf get(fn deposit_of): + map hasher(twox_64_concat) PropIndex => Option<(BalanceOf, Vec)>; + /// Map of hashes to the proposal preimage, along with who registered it and their deposit. /// The block number is the block at which it was deposited. + // TODO: Refactor Preimages into its own pallet. + // https://github.com/paritytech/substrate/issues/5322 pub Preimages: map hasher(identity) T::Hash => Option<(Vec, T::AccountId, BalanceOf, T::BlockNumber)>; - /// Those who have locked a deposit. - pub DepositOf get(fn deposit_of): - map hasher(twox_64_concat) PropIndex => Option<(BalanceOf, Vec)>; /// The next free referendum index, aka the number of referenda started so far. pub ReferendumCount get(fn referendum_count) build(|_| 0 as ReferendumIndex): ReferendumIndex; /// The lowest referendum index representing an unbaked referendum. Equal to /// `ReferendumCount` if there isn't a unbaked referendum. pub LowestUnbaked get(fn lowest_unbaked) build(|_| 0 as ReferendumIndex): ReferendumIndex; + /// Information concerning any given referendum. pub ReferendumInfoOf get(fn referendum_info): map hasher(twox_64_concat) ReferendumIndex - => Option>; + => Option>>; + + // TODO: Refactor DispatchQueue into its own pallet. + // https://github.com/paritytech/substrate/issues/5322 /// Queue of successful referenda to be dispatched. Stored ordered by block number. pub DispatchQueue get(fn dispatch_queue): Vec<(T::BlockNumber, T::Hash, ReferendumIndex)>; - /// Get the voters for the current proposal. - pub VotersFor get(fn voters_for): - map hasher(twox_64_concat) ReferendumIndex => Vec; - - /// Get the vote in a given referendum of a particular voter. The result is meaningful only - /// if `voters_for` includes the voter when called with the referendum (you'll get the - /// default `Vote` value otherwise). If you don't want to check `voters_for`, then you can - /// also check for simple existence with `VoteOf::contains_key` first. - pub VoteOf get(fn vote_of): map hasher(twox_64_concat) (ReferendumIndex, T::AccountId) => Vote; + /// All votes for a particular voter. We store the balance for the number of votes that we + /// have recorded. The second item is the total amount of delegations, that will be added. + pub VotingOf: map hasher(twox_64_concat) T::AccountId => Voting, T::AccountId, T::BlockNumber>; /// Who is able to vote for whom. Value is the fund-holding account, key is the /// vote-transaction-sending account. + // TODO: Refactor proxy into its own pallet. + // https://github.com/paritytech/substrate/issues/5322 pub Proxy get(fn proxy): map hasher(twox_64_concat) T::AccountId => Option>; - /// Get the account (and lock periods) to which another account is delegating vote. - pub Delegations get(fn delegations): - map hasher(twox_64_concat) T::AccountId => (T::AccountId, Conviction); - /// Accounts for which there are locks in action which may be removed at some point in the /// future. The value is the block number at which the lock expires and may be removed. pub Locks get(locks): map hasher(twox_64_concat) T::AccountId => Option; /// True if the last referendum tabled was submitted externally. False if it was a public /// proposal. + // TODO: There should be any number of tabling origins, not just public and "external" (council). + // https://github.com/paritytech/substrate/issues/5322 pub LastTabledWasExternal: bool; /// The referendum to be tabled whenever it would be valid to table an external proposal. @@ -559,7 +423,7 @@ decl_error! { /// Not imminent NotImminent, /// Too early - Early, + TooEarly, /// Imminent Imminent, /// Preimage not found @@ -579,7 +443,28 @@ decl_error! { /// A proxy-pairing was attempted to an account that was open to another account. WrongOpen, /// A proxy-de-pairing was attempted to an account that was not active. - NotActive + NotActive, + /// The given account did not vote on the referendum. + NotVoter, + /// The actor has no permission to conduct the action. + NoPermission, + /// The account is already delegating. + AlreadyDelegating, + /// An unexpected integer overflow occurred. + Overflow, + /// An unexpected integer underflow occurred. + Underflow, + /// Too high a balance was provided that the account cannot afford. + InsufficientFunds, + /// The account is not currently delegating. + NotDelegating, + /// The account currently has votes attached to it and the operation cannot succeed until + /// these are removed, either through `unvote` or `reap_vote`. + VotesExist, + /// The instant referendum origin is currently disallowed. + InstantNotAllowed, + /// Delegation to oneself makes no sense. + Nonsense, } } @@ -604,7 +489,7 @@ decl_module! { const MinimumDeposit: BalanceOf = T::MinimumDeposit::get(); /// Minimum voting period allowed for an emergency referendum. - const EmergencyVotingPeriod: T::BlockNumber = T::EmergencyVotingPeriod::get(); + const FastTrackVotingPeriod: T::BlockNumber = T::FastTrackVotingPeriod::get(); /// Period in blocks where an external proposal may not be re-submitted after being vetoed. const CooloffPeriod: T::BlockNumber = T::CooloffPeriod::get(); @@ -614,6 +499,10 @@ decl_module! { fn deposit_event() = default; + fn on_runtime_upgrade() { + Self::migrate(); + } + /// Propose a sensitive action to be taken. /// /// The dispatch origin of this call must be _Signed_ and the sender must @@ -683,10 +572,10 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(200_000)] fn vote(origin, #[compact] ref_index: ReferendumIndex, - vote: Vote + vote: AccountVote>, ) -> DispatchResult { let who = ensure_signed(origin)?; - Self::do_vote(who, ref_index, vote) + Self::try_vote(&who, ref_index, vote) } /// Vote in a referendum on behalf of a stash. If `vote.is_aye()`, the vote is to enact @@ -704,11 +593,11 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(200_000)] fn proxy_vote(origin, #[compact] ref_index: ReferendumIndex, - vote: Vote + vote: AccountVote>, ) -> DispatchResult { let who = ensure_signed(origin)?; let voter = Self::proxy(who).and_then(|a| a.as_active()).ok_or(Error::::NotProxy)?; - Self::do_vote(voter, ref_index, vote) + Self::try_vote(&voter, ref_index, vote) } /// Schedule an emergency cancellation of a referendum. Cannot happen twice to the same @@ -725,12 +614,12 @@ decl_module! { fn emergency_cancel(origin, ref_index: ReferendumIndex) { T::CancellationOrigin::ensure_origin(origin)?; - let info = Self::referendum_info(ref_index).ok_or(Error::::BadIndex)?; - let h = info.proposal_hash; + let status = Self::referendum_status(ref_index)?; + let h = status.proposal_hash; ensure!(!>::contains_key(h), Error::::AlreadyCanceled); >::insert(h, true); - Self::clear_referendum(ref_index); + Self::internal_cancel_referendum(ref_index); } /// Schedule a referendum to be tabled once it is legal to schedule an external @@ -805,7 +694,7 @@ decl_module! { /// /// - `proposal_hash`: The hash of the current external proposal. /// - `voting_period`: The period that is allowed for voting on this proposal. Increased to - /// `EmergencyVotingPeriod` if too low. + /// `FastTrackVotingPeriod` if too low. /// - `delay`: The number of block after voting has ended in approval and this should be /// enacted. This doesn't have a minimum amount. /// @@ -820,10 +709,27 @@ decl_module! { fn fast_track(origin, proposal_hash: T::Hash, voting_period: T::BlockNumber, - delay: T::BlockNumber + delay: T::BlockNumber, ) { - T::FastTrackOrigin::ensure_origin(origin)?; - let (e_proposal_hash, threshold) = >::get().ok_or(Error::::ProposalMissing)?; + // Rather complicated bit of code to ensure that either: + // - `voting_period` is at least `FastTrackVotingPeriod` and `origin` is `FastTrackOrigin`; or + // - `InstantAllowed` is `true` and `origin` is `InstantOrigin`. + let maybe_ensure_instant = if voting_period < T::FastTrackVotingPeriod::get() { + Some(origin) + } else { + if let Err(origin) = T::FastTrackOrigin::try_origin(origin) { + Some(origin) + } else { + None + } + }; + if let Some(ensure_instant) = maybe_ensure_instant { + T::InstantOrigin::ensure_origin(ensure_instant)?; + ensure!(T::InstantAllowed::get(), Error::::InstantNotAllowed); + } + + let (e_proposal_hash, threshold) = >::get() + .ok_or(Error::::ProposalMissing)?; ensure!( threshold != VoteThreshold::SuperMajorityApprove, Error::::NotSimpleMajority, @@ -832,9 +738,7 @@ decl_module! { >::kill(); let now = >::block_number(); - // We don't consider it an error if `vote_period` is too low, like `emergency_propose`. - let period = voting_period.max(T::EmergencyVotingPeriod::get()); - Self::inject_referendum(now + period, proposal_hash, threshold, delay); + Self::inject_referendum(now + voting_period, proposal_hash, threshold, delay); } /// Veto and blacklist the external proposal hash. @@ -887,7 +791,7 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedOperational(10_000)] fn cancel_referendum(origin, #[compact] ref_index: ReferendumIndex) { ensure_root(origin)?; - Self::clear_referendum(ref_index); + Self::internal_cancel_referendum(ref_index); } /// Cancel a proposal queued for enactment. @@ -986,43 +890,39 @@ decl_module! { })?; } - /// Delegate vote. + /// Delegate the voting power (with some given conviction) of the sending account. /// - /// Currency is locked indefinitely for as long as it's delegated. + /// The balance delegated is locked for as long as it's delegated, and thereafter for the + /// time appropriate for the conviction's lock period. /// - /// The dispatch origin of this call must be _Signed_. + /// The dispatch origin of this call must be _Signed_, and the signing account must either: + /// - be delegating already; or + /// - have no voting activity (if there is, then it will need to be removed/consolidated + /// through `reap_vote` or `unvote`). /// - /// - `to`: The account to make a delegate of the sender. - /// - `conviction`: The conviction that will be attached to the delegated - /// votes. + /// - `to`: The account whose voting the `target` account's voting power will follow. + /// - `conviction`: The conviction that will be attached to the delegated votes. When the + /// account is undelegated, the funds will be locked for the corresponding period. + /// - `balance`: The amount of the account's balance to be used in delegating. This must + /// not be more than the account's current balance. /// /// Emits `Delegated`. /// /// # - /// - One extra DB entry. /// # #[weight = SimpleDispatchInfo::FixedNormal(500_000)] - pub fn delegate(origin, to: T::AccountId, conviction: Conviction) { + pub fn delegate(origin, to: T::AccountId, conviction: Conviction, balance: BalanceOf) { let who = ensure_signed(origin)?; - >::insert(&who, (&to, conviction)); - // Currency is locked indefinitely as long as it's delegated. - T::Currency::extend_lock( - DEMOCRACY_ID, - &who, - Bounded::max_value(), - WithdrawReason::Transfer.into() - ); - Locks::::remove(&who); - Self::deposit_event(RawEvent::Delegated(who, to)); + Self::try_delegate(who, to, conviction, balance)?; } - /// Undelegate vote. + /// Undelegate the voting power of the sending account. /// - /// Must be sent from an account that has called delegate previously. - /// The tokens will be reduced from an indefinite lock to the maximum - /// possible according to the conviction of the prior delegation. + /// Tokens may be unlocked following once an amount of time consistent with the lock period + /// of the conviction with which the delegation was issued. /// - /// The dispatch origin of this call must be _Signed_. + /// The dispatch origin of this call must be _Signed_ and the signing account must be + /// currently delegating. /// /// Emits `Undelegated`. /// @@ -1032,19 +932,7 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(500_000)] fn undelegate(origin) { let who = ensure_signed(origin)?; - ensure!(>::contains_key(&who), Error::::NotDelegated); - let (_, conviction) = >::take(&who); - // Indefinite lock is reduced to the maximum voting lock that could be possible. - let now = >::block_number(); - let locked_until = now + T::EnactmentPeriod::get() * conviction.lock_periods().into(); - Locks::::insert(&who, locked_until); - T::Currency::set_lock( - DEMOCRACY_ID, - &who, - Bounded::max_value(), - WithdrawReason::Transfer.into(), - ); - Self::deposit_event(RawEvent::Undelegated(who)); + Self::try_undelegate(who)?; } /// Clears all public proposals. @@ -1142,7 +1030,7 @@ decl_module! { let now = >::block_number(); let (voting, enactment) = (T::VotingPeriod::get(), T::EnactmentPeriod::get()); let additional = if who == old { Zero::zero() } else { enactment }; - ensure!(now >= then + voting + additional, Error::::Early); + ensure!(now >= then + voting + additional, Error::::TooEarly); let queue = >::get(); ensure!(!queue.iter().any(|item| &item.1 == &proposal_hash), Error::::Imminent); @@ -1158,21 +1046,13 @@ decl_module! { /// /// - `target`: The account to remove the lock on. /// - /// Emits `Unlocked`. - /// /// # /// - `O(1)`. /// # #[weight = SimpleDispatchInfo::FixedNormal(10_000)] fn unlock(origin, target: T::AccountId) { ensure_signed(origin)?; - - let expiry = Locks::::get(&target).ok_or(Error::::NotLocked)?; - ensure!(expiry <= system::Module::::block_number(), Error::::NotExpired); - - T::Currency::remove_lock(DEMOCRACY_ID, &target); - Locks::::remove(&target); - Self::deposit_event(RawEvent::Unlocked(target)); + Self::update_lock(&target); } /// Become a proxy. @@ -1198,119 +1078,185 @@ decl_module! { *a = Some(ProxyState::Open(target)); }); } + + /// Remove a vote for a referendum. + /// + /// If: + /// - the referendum was cancelled, or + /// - the referendum is ongoing, or + /// - the referendum has ended such that + /// - the vote of the account was in opposition to the result; or + /// - there was no conviction to the account's vote; or + /// - the account made a split vote + /// ...then the vote is removed cleanly and a following call to `unlock` may result in more + /// funds being available. + /// + /// If, however, the referendum has ended and: + /// - it finished corresponding to the vote of the account, and + /// - the account made a standard vote with conviction, and + /// - the lock period of the conviction is not over + /// ...then the lock will be aggregated into the overall account's lock, which may involve + /// *overlocking* (where the two locks are combined into a single lock that is the maximum + /// of both the amount locked and the time is it locked for). + /// + /// The dispatch origin of this call must be _Signed_, and the signer must have a vote + /// registered for referendum `index`. + /// + /// - `index`: The index of referendum of the vote to be removed. + /// + /// # + /// - `O(R + log R)` where R is the number of referenda that `target` has voted on. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + fn remove_vote(origin, index: ReferendumIndex) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::try_remove_vote(&who, index, UnvoteScope::Any) + } + + /// Remove a vote for a referendum. + /// + /// If the `target` is equal to the signer, then this function is exactly equivalent to + /// `remove_vote`. If not equal to the signer, then the vote must have expired, + /// either because the referendum was cancelled, because the voter lost the referendum or + /// because the conviction period is over. + /// + /// The dispatch origin of this call must be _Signed_. + /// + /// - `target`: The account of the vote to be removed; this account must have voted for + /// referendum `index`. + /// - `index`: The index of referendum of the vote to be removed. + /// + /// # + /// - `O(R + log R)` where R is the number of referenda that `target` has voted on. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + fn remove_other_vote(origin, target: T::AccountId, index: ReferendumIndex) -> DispatchResult { + let who = ensure_signed(origin)?; + let scope = if target == who { UnvoteScope::Any } else { UnvoteScope::OnlyExpired }; + Self::try_remove_vote(&target, index, scope)?; + Ok(()) + } + + /// Delegate the voting power (with some given conviction) of a proxied account. + /// + /// The balance delegated is locked for as long as it's delegated, and thereafter for the + /// time appropriate for the conviction's lock period. + /// + /// The dispatch origin of this call must be _Signed_, and the signing account must have + /// been set as the proxy account for `target`. + /// + /// - `target`: The account whole voting power shall be delegated and whose balance locked. + /// This account must either: + /// - be delegating already; or + /// - have no voting activity (if there is, then it will need to be removed/consolidated + /// through `reap_vote` or `unvote`). + /// - `to`: The account whose voting the `target` account's voting power will follow. + /// - `conviction`: The conviction that will be attached to the delegated votes. When the + /// account is undelegated, the funds will be locked for the corresponding period. + /// - `balance`: The amount of the account's balance to be used in delegating. This must + /// not be more than the account's current balance. + /// + /// Emits `Delegated`. + /// + /// # + /// # + #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + pub fn proxy_delegate(origin, + to: T::AccountId, + conviction: Conviction, + balance: BalanceOf, + ) { + let who = ensure_signed(origin)?; + let target = Self::proxy(who).and_then(|a| a.as_active()).ok_or(Error::::NotProxy)?; + Self::try_delegate(target, to, conviction, balance)?; + } + + /// Undelegate the voting power of a proxied account. + /// + /// Tokens may be unlocked following once an amount of time consistent with the lock period + /// of the conviction with which the delegation was issued. + /// + /// The dispatch origin of this call must be _Signed_ and the signing account must be a + /// proxy for some other account which is currently delegating. + /// + /// Emits `Undelegated`. + /// + /// # + /// - O(1). + /// # + #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + fn proxy_undelegate(origin) { + let who = ensure_signed(origin)?; + let target = Self::proxy(who).and_then(|a| a.as_active()).ok_or(Error::::NotProxy)?; + Self::try_undelegate(target)?; + } + + /// Remove a proxied vote for a referendum. + /// + /// Exactly equivalent to `remove_vote` except that it operates on the account that the + /// sender is a proxy for. + /// + /// The dispatch origin of this call must be _Signed_ and the signing account must be a + /// proxy for some other account which has a registered vote for the referendum of `index`. + /// + /// - `index`: The index of referendum of the vote to be removed. + /// + /// # + /// - `O(R + log R)` where R is the number of referenda that `target` has voted on. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + fn proxy_remove_vote(origin, index: ReferendumIndex) -> DispatchResult { + let who = ensure_signed(origin)?; + let target = Self::proxy(who).and_then(|a| a.as_active()).ok_or(Error::::NotProxy)?; + Self::try_remove_vote(&target, index, UnvoteScope::Any) + } } } impl Module { + fn migrate() { + use frame_support::{Twox64Concat, migration::{StorageKeyIterator, remove_storage_prefix}}; + remove_storage_prefix(b"Democracy", b"VotesOf", &[]); + remove_storage_prefix(b"Democracy", b"VotersFor", &[]); + remove_storage_prefix(b"Democracy", b"Delegations", &[]); + for (who, (end, proposal_hash, threshold, delay)) + in StorageKeyIterator::< + ReferendumIndex, + (T::BlockNumber, T::Hash, VoteThreshold, T::BlockNumber), + Twox64Concat, + >::new(b"Democracy", b"ReferendumInfoOf").drain() + { + let status = ReferendumStatus { + end, proposal_hash, threshold, delay, tally: Tally::default() + }; + ReferendumInfoOf::::insert(who, ReferendumInfo::Ongoing(status)) + } + } + // exposed immutables. /// Get the amount locked in support of `proposal`; `None` if proposal isn't a valid proposal /// index. - pub fn locked_for(proposal: PropIndex) -> Option> { + pub fn backing_for(proposal: PropIndex) -> Option> { Self::deposit_of(proposal).map(|(d, l)| d * (l.len() as u32).into()) } - /// Return true if `ref_index` is an on-going referendum. - pub fn is_active_referendum(ref_index: ReferendumIndex) -> bool { - >::contains_key(ref_index) - } - - /// Get all referenda currently active. - pub fn active_referenda() - -> Vec<(ReferendumIndex, ReferendumInfo)> - { - let next = Self::lowest_unbaked(); - let last = Self::referendum_count(); - (next..last).into_iter() - .filter_map(|i| Self::referendum_info(i).map(|info| (i, info))) - .collect() - } - /// Get all referenda ready for tally at block `n`. pub fn maturing_referenda_at( n: T::BlockNumber - ) -> Vec<(ReferendumIndex, ReferendumInfo)> { + ) -> Vec<(ReferendumIndex, ReferendumStatus>)> { let next = Self::lowest_unbaked(); let last = Self::referendum_count(); (next..last).into_iter() - .filter_map(|i| Self::referendum_info(i).map(|info| (i, info))) - .filter(|&(_, ref info)| info.end == n) + .map(|i| (i, Self::referendum_info(i))) + .filter_map(|(i, maybe_info)| match maybe_info { + Some(ReferendumInfo::Ongoing(status)) => Some((i, status)), + _ => None, + }) + .filter(|(_, status)| status.end == n) .collect() } - /// Get the voters for the current proposal. - pub fn tally(ref_index: ReferendumIndex) -> (BalanceOf, BalanceOf, BalanceOf) { - let (approve, against, capital): - (BalanceOf, BalanceOf, BalanceOf) = Self::voters_for(ref_index) - .iter() - .map(|voter| ( - T::Currency::total_balance(voter), Self::vote_of((ref_index, voter.clone())) - )) - .map(|(balance, Vote { aye, conviction })| { - let (votes, turnout) = conviction.votes(balance); - if aye { - (votes, Zero::zero(), turnout) - } else { - (Zero::zero(), votes, turnout) - } - }).fold( - (Zero::zero(), Zero::zero(), Zero::zero()), - |(a, b, c), (d, e, f)| (a + d, b + e, c + f) - ); - let (del_approve, del_against, del_capital) = Self::tally_delegation(ref_index); - (approve + del_approve, against + del_against, capital + del_capital) - } - - /// Get the delegated voters for the current proposal. - /// I think this goes into a worker once https://github.com/paritytech/substrate/issues/1458 is - /// done. - fn tally_delegation(ref_index: ReferendumIndex) -> (BalanceOf, BalanceOf, BalanceOf) { - Self::voters_for(ref_index).iter().fold( - (Zero::zero(), Zero::zero(), Zero::zero()), - |(approve_acc, against_acc, turnout_acc), voter| { - let Vote { aye, conviction } = Self::vote_of((ref_index, voter.clone())); - let (votes, turnout) = Self::delegated_votes( - ref_index, - voter.clone(), - conviction, - MAX_RECURSION_LIMIT - ); - if aye { - (approve_acc + votes, against_acc, turnout_acc + turnout) - } else { - (approve_acc, against_acc + votes, turnout_acc + turnout) - } - } - ) - } - - fn delegated_votes( - ref_index: ReferendumIndex, - to: T::AccountId, - parent_conviction: Conviction, - recursion_limit: u32, - ) -> (BalanceOf, BalanceOf) { - if recursion_limit == 0 { return (Zero::zero(), Zero::zero()); } - >::iter() - .filter(|(delegator, (delegate, _))| - *delegate == to && !>::contains_key(&(ref_index, delegator.clone())) - ).fold( - (Zero::zero(), Zero::zero()), - |(votes_acc, turnout_acc), (delegator, (_delegate, max_conviction))| { - let conviction = Conviction::min(parent_conviction, max_conviction); - let balance = T::Currency::total_balance(&delegator); - let (votes, turnout) = conviction.votes(balance); - let (del_votes, del_turnout) = Self::delegated_votes( - ref_index, - delegator, - conviction, - recursion_limit - 1 - ); - (votes_acc + votes + del_votes, turnout_acc + turnout + del_turnout) - } - ) - } - // Exposed mutables. #[cfg(feature = "std")] @@ -1340,21 +1286,236 @@ impl Module { /// Remove a referendum. pub fn internal_cancel_referendum(ref_index: ReferendumIndex) { Self::deposit_event(RawEvent::Cancelled(ref_index)); - >::clear_referendum(ref_index); + ReferendumInfoOf::::remove(ref_index); } // private. - /// Actually enact a vote, if legit. - fn do_vote(who: T::AccountId, ref_index: ReferendumIndex, vote: Vote) -> DispatchResult { - ensure!(Self::is_active_referendum(ref_index), Error::::ReferendumInvalid); - if !>::contains_key((ref_index, &who)) { - >::append_or_insert(ref_index, &[&who][..]); + /// Ok if the given referendum is active, Err otherwise + fn ensure_ongoing(r: ReferendumInfo>) + -> Result>, DispatchError> + { + match r { + ReferendumInfo::Ongoing(s) => Ok(s), + _ => Err(Error::::ReferendumInvalid.into()), } - >::insert((ref_index, &who), vote); + } + + fn referendum_status(ref_index: ReferendumIndex) + -> Result>, DispatchError> + { + let info = ReferendumInfoOf::::get(ref_index) + .ok_or(Error::::ReferendumInvalid)?; + Self::ensure_ongoing(info) + } + + /// Actually enact a vote, if legit. + fn try_vote(who: &T::AccountId, ref_index: ReferendumIndex, vote: AccountVote>) -> DispatchResult { + let mut status = Self::referendum_status(ref_index)?; + ensure!(vote.balance() <= T::Currency::free_balance(who), Error::::InsufficientFunds); + VotingOf::::try_mutate(who, |voting| -> DispatchResult { + if let Voting::Direct { ref mut votes, delegations, .. } = voting { + match votes.binary_search_by_key(&ref_index, |i| i.0) { + Ok(i) => { + // Shouldn't be possible to fail, but we handle it gracefully. + status.tally.remove(votes[i].1).ok_or(Error::::Underflow)?; + if let Some(approve) = votes[i].1.as_standard() { + status.tally.reduce(approve, *delegations); + } + votes[i].1 = vote; + } + Err(i) => votes.insert(i, (ref_index, vote)), + } + // Shouldn't be possible to fail, but we handle it gracefully. + status.tally.add(vote).ok_or(Error::::Overflow)?; + if let Some(approve) = vote.as_standard() { + status.tally.increase(approve, *delegations); + } + Ok(()) + } else { + Err(Error::::AlreadyDelegating.into()) + } + })?; + // Extend the lock to `balance` (rather than setting it) since we don't know what other + // votes are in place. + T::Currency::extend_lock( + DEMOCRACY_ID, + who, + vote.balance(), + WithdrawReason::Transfer.into() + ); + ReferendumInfoOf::::insert(ref_index, ReferendumInfo::Ongoing(status)); + Ok(()) + } + + /// Remove the account's vote for the given referendum if possible. This is possible when: + /// - The referendum has not finished. + /// - The referendum has finished and the voter lost their direction. + /// - The referendum has finished and the voter's lock period is up. + /// + /// This will generally be combined with a call to `unlock`. + fn try_remove_vote(who: &T::AccountId, ref_index: ReferendumIndex, scope: UnvoteScope) -> DispatchResult { + let info = ReferendumInfoOf::::get(ref_index); + VotingOf::::try_mutate(who, |voting| -> DispatchResult { + if let Voting::Direct { ref mut votes, delegations, ref mut prior } = voting { + let i = votes.binary_search_by_key(&ref_index, |i| i.0).map_err(|_| Error::::NotVoter)?; + match info { + Some(ReferendumInfo::Ongoing(mut status)) => { + ensure!(matches!(scope, UnvoteScope::Any), Error::::NoPermission); + // Shouldn't be possible to fail, but we handle it gracefully. + status.tally.remove(votes[i].1).ok_or(Error::::Underflow)?; + if let Some(approve) = votes[i].1.as_standard() { + status.tally.reduce(approve, *delegations); + } + ReferendumInfoOf::::insert(ref_index, ReferendumInfo::Ongoing(status)); + } + Some(ReferendumInfo::Finished{end, approved}) => + if let Some((lock_periods, balance)) = votes[i].1.locked_if(approved) { + let unlock_at = end + T::EnactmentPeriod::get() * lock_periods.into(); + let now = system::Module::::block_number(); + if now < unlock_at { + ensure!(matches!(scope, UnvoteScope::Any), Error::::NoPermission); + prior.accumulate(unlock_at, balance) + } + }, + None => {} // Referendum was cancelled. + } + votes.remove(i); + } + Ok(()) + })?; + Ok(()) + } + + fn increase_upstream_delegation(who: &T::AccountId, amount: Delegations>) { + VotingOf::::mutate(who, |voting| match voting { + Voting::Delegating { delegations, .. } => + // We don't support second level delegating, so we don't need to do anything more. + *delegations = delegations.saturating_add(amount), + Voting::Direct { votes, delegations, .. } => { + *delegations = delegations.saturating_add(amount); + for &(ref_index, account_vote) in votes.iter() { + if let AccountVote::Standard { vote, .. } = account_vote { + ReferendumInfoOf::::mutate(ref_index, |maybe_info| + if let Some(ReferendumInfo::Ongoing(ref mut status)) = maybe_info { + status.tally.increase(vote.aye, amount); + } + ); + } + } + } + }) + } + + fn reduce_upstream_delegation(who: &T::AccountId, amount: Delegations>) { + VotingOf::::mutate(who, |voting| match voting { + Voting::Delegating { delegations, .. } => + // We don't support second level delegating, so we don't need to do anything more. + *delegations = delegations.saturating_sub(amount), + Voting::Direct { votes, delegations, .. } => { + *delegations = delegations.saturating_sub(amount); + for &(ref_index, account_vote) in votes.iter() { + if let AccountVote::Standard { vote, .. } = account_vote { + ReferendumInfoOf::::mutate(ref_index, |maybe_info| + if let Some(ReferendumInfo::Ongoing(ref mut status)) = maybe_info { + status.tally.reduce(vote.aye, amount); + } + ); + } + } + } + }) + } + + /// Attempt to delegate `balance` times `conviction` of voting power from `who` to `target`. + fn try_delegate( + who: T::AccountId, + target: T::AccountId, + conviction: Conviction, + balance: BalanceOf, + ) -> DispatchResult { + ensure!(who != target, Error::::Nonsense); + ensure!(balance <= T::Currency::free_balance(&who), Error::::InsufficientFunds); + VotingOf::::try_mutate(&who, |voting| -> DispatchResult { + let mut old = Voting::Delegating { + balance, + target: target.clone(), + conviction, + delegations: Default::default(), + prior: Default::default(), + }; + sp_std::mem::swap(&mut old, voting); + match old { + Voting::Delegating { balance, target, conviction, delegations, prior, .. } => { + // remove any delegation votes to our current target. + Self::reduce_upstream_delegation(&target, conviction.votes(balance)); + voting.set_common(delegations, prior); + } + Voting::Direct { votes, delegations, prior } => { + // here we just ensure that we're currently idling with no votes recorded. + ensure!(votes.is_empty(), Error::::VotesExist); + voting.set_common(delegations, prior); + } + } + Self::increase_upstream_delegation(&target, conviction.votes(balance)); + // Extend the lock to `balance` (rather than setting it) since we don't know what other + // votes are in place. + T::Currency::extend_lock( + DEMOCRACY_ID, + &who, + balance, + WithdrawReason::Transfer.into() + ); + Ok(()) + })?; + Self::deposit_event(Event::::Delegated(who, target)); + Ok(()) + } + + /// Attempt to end the current delegation. + fn try_undelegate(who: T::AccountId) -> DispatchResult { + VotingOf::::try_mutate(&who, |voting| -> DispatchResult { + let mut old = Voting::default(); + sp_std::mem::swap(&mut old, voting); + match old { + Voting::Delegating { + balance, + target, + conviction, + delegations, + mut prior, + } => { + // remove any delegation votes to our current target. + Self::reduce_upstream_delegation(&target, conviction.votes(balance)); + let now = system::Module::::block_number(); + let lock_periods = conviction.lock_periods().into(); + prior.accumulate(now + T::EnactmentPeriod::get() * lock_periods, balance); + voting.set_common(delegations, prior); + } + Voting::Direct { .. } => { + return Err(Error::::NotDelegating.into()) + } + } + Ok(()) + })?; + Self::deposit_event(Event::::Undelegated(who)); Ok(()) } + /// Rejig the lock on an account. It will never get more stringent (since that would indicate + /// a security hole) but may be reduced from what they are currently. + fn update_lock(who: &T::AccountId) { + let lock_needed = VotingOf::::mutate(who, |voting| { + voting.rejig(system::Module::::block_number()); + voting.locked_balance() + }); + if lock_needed.is_zero() { + T::Currency::remove_lock(DEMOCRACY_ID, who); + } else { + T::Currency::set_lock(DEMOCRACY_ID, who, lock_needed, WithdrawReason::Transfer.into()); + } + } + /// Start a referendum fn inject_referendum( end: T::BlockNumber, @@ -1364,29 +1525,13 @@ impl Module { ) -> ReferendumIndex { let ref_index = Self::referendum_count(); ReferendumCount::put(ref_index + 1); - let item = ReferendumInfo { end, proposal_hash, threshold, delay }; + let status = ReferendumStatus { end, proposal_hash, threshold, delay, tally: Default::default() }; + let item = ReferendumInfo::Ongoing(status); >::insert(ref_index, item); Self::deposit_event(RawEvent::Started(ref_index, threshold)); ref_index } - /// Remove all info on a referendum. - fn clear_referendum(ref_index: ReferendumIndex) { - >::remove(ref_index); - - LowestUnbaked::mutate(|i| if *i == ref_index { - *i += 1; - let end = ReferendumCount::get(); - while !Self::is_active_referendum(*i) && *i < end { - *i += 1; - } - }); - >::remove(ref_index); - for v in Self::voters_for(ref_index) { - >::remove((ref_index, v)); - } - } - /// Enact a proposal from a referendum. fn enact_proposal(proposal_hash: T::Hash, index: ReferendumIndex) -> DispatchResult { if let Some((encoded_proposal, who, amount, _)) = >::take(&proposal_hash) { @@ -1440,7 +1585,7 @@ impl Module { let mut public_props = Self::public_props(); if let Some((winner_index, _)) = public_props.iter() .enumerate() - .max_by_key(|x| Self::locked_for((x.1).0).unwrap_or_else(Zero::zero) + .max_by_key(|x| Self::backing_for((x.1).0).unwrap_or_else(Zero::zero) /* ^^ defensive only: All current public proposals have an amount locked*/) { let (prop_index, proposal, _) = public_props.swap_remove(winner_index); @@ -1463,51 +1608,22 @@ impl Module { } else { Err(Error::::NoneWaiting)? } - } fn bake_referendum( now: T::BlockNumber, index: ReferendumIndex, - info: ReferendumInfo - ) -> DispatchResult { - let (approve, against, capital) = Self::tally(index); + status: ReferendumStatus>, + ) -> Result { let total_issuance = T::Currency::total_issuance(); - let approved = info.threshold.approved(approve, against, capital, total_issuance); - let enactment_period = T::EnactmentPeriod::get(); - - // Logic defined in https://www.slideshare.net/gavofyork/governance-in-polkadot-poc3 - // Essentially, we extend the lock-period of the coins behind the winning votes to be the - // vote strength times the public delay period from now. - for (a, lock_periods) in Self::voters_for(index).into_iter() - .map(|a| (a.clone(), Self::vote_of((index, a)))) - // ^^^ defensive only: all items come from `voters`; for an item to be in `voters` - // there must be a vote registered; qed - .filter(|&(_, vote)| vote.aye == approved) // Just the winning coins - .map(|(a, vote)| (a, vote.conviction.lock_periods())) - .filter(|&(_, lock_periods)| !lock_periods.is_zero()) // Just the lock votes - { - // now plus: the base lock period multiplied by the number of periods this voter - // offered to lock should they win... - let locked_until = now + enactment_period * lock_periods.into(); - Locks::::insert(&a, locked_until); - // ...extend their bondage until at least then. - T::Currency::extend_lock( - DEMOCRACY_ID, - &a, - Bounded::max_value(), - WithdrawReason::Transfer.into() - ); - } - - Self::clear_referendum(index); + let approved = status.threshold.approved(status.tally, total_issuance); if approved { Self::deposit_event(RawEvent::Passed(index)); - if info.delay.is_zero() { - let _ = Self::enact_proposal(info.proposal_hash, index); + if status.delay.is_zero() { + let _ = Self::enact_proposal(status.proposal_hash, index); } else { - let item = (now + info.delay,info.proposal_hash, index); + let item = (now + status.delay, status.proposal_hash, index); >::mutate(|queue| { let pos = queue.binary_search_by_key(&item.0, |x| x.0).unwrap_or_else(|e| e); queue.insert(pos, item); @@ -1517,7 +1633,7 @@ impl Module { Self::deposit_event(RawEvent::NotPassed(index)); } - Ok(()) + Ok(approved) } /// Current era is ending; we should finish up any proposals. @@ -1531,7 +1647,8 @@ impl Module { // tally up votes for any expiring referenda. for (index, info) in Self::maturing_referenda_at(now).into_iter() { - Self::bake_referendum(now, index, info)?; + let approved = Self::bake_referendum(now, index, info)?; + ReferendumInfoOf::::insert(index, ReferendumInfo::Finished { end: now, approved }); } let queue = >::get(); @@ -1547,1370 +1664,3 @@ impl Module { Ok(()) } } - -#[cfg(test)] -mod tests { - use super::*; - use std::cell::RefCell; - use frame_support::{ - impl_outer_origin, impl_outer_dispatch, assert_noop, assert_ok, parameter_types, - ord_parameter_types, traits::Contains, weights::Weight, - }; - use sp_core::H256; - use sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup, Bounded, BadOrigin}, - testing::Header, Perbill, - }; - use pallet_balances::{BalanceLock, Error as BalancesError}; - use frame_system::EnsureSignedBy; - - const AYE: Vote = Vote{ aye: true, conviction: Conviction::None }; - const NAY: Vote = Vote{ aye: false, conviction: Conviction::None }; - const BIG_AYE: Vote = Vote{ aye: true, conviction: Conviction::Locked1x }; - const BIG_NAY: Vote = Vote{ aye: false, conviction: Conviction::Locked1x }; - - impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} - } - - impl_outer_dispatch! { - pub enum Call for Test where origin: Origin { - pallet_balances::Balances, - democracy::Democracy, - } - } - - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, Eq, PartialEq, Debug)] - pub struct Test; - parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - } - impl frame_system::Trait for Test { - type Origin = Origin; - type Index = u64; - type BlockNumber = u64; - type Call = (); - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = (); - type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; - type Version = (); - type ModuleToIndex = (); - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - } - parameter_types! { - pub const ExistentialDeposit: u64 = 1; - } - impl pallet_balances::Trait for Test { - type Balance = u64; - type Event = (); - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - } - parameter_types! { - pub const LaunchPeriod: u64 = 2; - pub const VotingPeriod: u64 = 2; - pub const EmergencyVotingPeriod: u64 = 1; - pub const MinimumDeposit: u64 = 1; - pub const EnactmentPeriod: u64 = 2; - pub const CooloffPeriod: u64 = 2; - } - ord_parameter_types! { - pub const One: u64 = 1; - pub const Two: u64 = 2; - pub const Three: u64 = 3; - pub const Four: u64 = 4; - pub const Five: u64 = 5; - } - pub struct OneToFive; - impl Contains for OneToFive { - fn sorted_members() -> Vec { - vec![1, 2, 3, 4, 5] - } - } - thread_local! { - static PREIMAGE_BYTE_DEPOSIT: RefCell = RefCell::new(0); - } - pub struct PreimageByteDeposit; - impl Get for PreimageByteDeposit { - fn get() -> u64 { PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow()) } - } - impl super::Trait for Test { - type Proposal = Call; - type Event = (); - type Currency = pallet_balances::Module; - type EnactmentPeriod = EnactmentPeriod; - type LaunchPeriod = LaunchPeriod; - type VotingPeriod = VotingPeriod; - type EmergencyVotingPeriod = EmergencyVotingPeriod; - type MinimumDeposit = MinimumDeposit; - type ExternalOrigin = EnsureSignedBy; - type ExternalMajorityOrigin = EnsureSignedBy; - type ExternalDefaultOrigin = EnsureSignedBy; - type FastTrackOrigin = EnsureSignedBy; - type CancellationOrigin = EnsureSignedBy; - type VetoOrigin = EnsureSignedBy; - type CooloffPeriod = CooloffPeriod; - type PreimageByteDeposit = PreimageByteDeposit; - type Slash = (); - } - - fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - pallet_balances::GenesisConfig::{ - balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], - }.assimilate_storage(&mut t).unwrap(); - GenesisConfig::default().assimilate_storage(&mut t).unwrap(); - sp_io::TestExternalities::new(t) - } - - type System = frame_system::Module; - type Balances = pallet_balances::Module; - type Democracy = Module; - - #[test] - fn params_should_work() { - new_test_ext().execute_with(|| { - assert_eq!(Democracy::referendum_count(), 0); - assert_eq!(Balances::free_balance(42), 0); - assert_eq!(Balances::total_issuance(), 210); - }); - } - - fn set_balance_proposal(value: u64) -> Vec { - Call::Balances(pallet_balances::Call::set_balance(42, value, 0)).encode() - } - - fn set_balance_proposal_hash(value: u64) -> H256 { - BlakeTwo256::hash(&set_balance_proposal(value)[..]) - } - - fn set_balance_proposal_hash_and_note(value: u64) -> H256 { - let p = set_balance_proposal(value); - let h = BlakeTwo256::hash(&p[..]); - match Democracy::note_preimage(Origin::signed(6), p) { - Ok(_) => (), - Err(x) if x == Error::::DuplicatePreimage.into() => (), - Err(x) => panic!(x), - } - h - } - - fn propose_set_balance(who: u64, value: u64, delay: u64) -> DispatchResult { - Democracy::propose( - Origin::signed(who), - set_balance_proposal_hash(value), - delay - ) - } - - fn propose_set_balance_and_note(who: u64, value: u64, delay: u64) -> DispatchResult { - Democracy::propose( - Origin::signed(who), - set_balance_proposal_hash_and_note(value), - delay - ) - } - - fn next_block() { - System::set_block_number(System::block_number() + 1); - assert_eq!(Democracy::begin_block(System::block_number()), Ok(())); - } - - fn fast_forward_to(n: u64) { - while System::block_number() < n { - next_block(); - } - } - - #[test] - fn missing_preimage_should_fail() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash(2), - VoteThreshold::SuperMajorityApprove, - 0 - ); - assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); - - next_block(); - next_block(); - - assert_eq!(Balances::free_balance(42), 0); - }); - } - - #[test] - fn preimage_deposit_should_be_required_and_returned() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - // fee of 100 is too much. - PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 100); - assert_noop!( - Democracy::note_preimage(Origin::signed(6), vec![0; 500]), - BalancesError::::InsufficientBalance, - ); - // fee of 1 is reasonable. - PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 0 - ); - assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); - - assert_eq!(Balances::reserved_balance(6), 12); - - next_block(); - next_block(); - - assert_eq!(Balances::reserved_balance(6), 0); - assert_eq!(Balances::free_balance(6), 60); - assert_eq!(Balances::free_balance(42), 2); - }); - } - - #[test] - fn preimage_deposit_should_be_reapable_earlier_by_owner() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); - assert_ok!(Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2))); - - assert_eq!(Balances::reserved_balance(6), 12); - - next_block(); - assert_noop!( - Democracy::reap_preimage(Origin::signed(6), set_balance_proposal_hash(2)), - Error::::Early - ); - next_block(); - assert_ok!(Democracy::reap_preimage(Origin::signed(6), set_balance_proposal_hash(2))); - - assert_eq!(Balances::free_balance(6), 60); - assert_eq!(Balances::reserved_balance(6), 0); - }); - } - - #[test] - fn preimage_deposit_should_be_reapable() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - assert_noop!( - Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2)), - Error::::PreimageMissing - ); - - PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); - assert_ok!(Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2))); - assert_eq!(Balances::reserved_balance(6), 12); - - next_block(); - next_block(); - next_block(); - assert_noop!( - Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2)), - Error::::Early - ); - - next_block(); - assert_ok!(Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2))); - assert_eq!(Balances::reserved_balance(6), 0); - assert_eq!(Balances::free_balance(6), 48); - assert_eq!(Balances::free_balance(5), 62); - }); - } - - #[test] - fn noting_imminent_preimage_for_free_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); - - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash(2), - VoteThreshold::SuperMajorityApprove, - 1 - ); - assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); - - assert_noop!( - Democracy::note_imminent_preimage(Origin::signed(7), set_balance_proposal(2)), - Error::::NotImminent - ); - - next_block(); - - // Now we're in the dispatch queue it's all good. - assert_ok!(Democracy::note_imminent_preimage(Origin::signed(7), set_balance_proposal(2))); - - next_block(); - - assert_eq!(Balances::free_balance(42), 2); - }); - } - - #[test] - fn reaping_imminent_preimage_should_fail() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - let h = set_balance_proposal_hash_and_note(2); - let r = Democracy::inject_referendum(3, h, VoteThreshold::SuperMajorityApprove, 1); - assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); - next_block(); - next_block(); - // now imminent. - assert_noop!(Democracy::reap_preimage(Origin::signed(6), h), Error::::Imminent); - }); - } - - #[test] - fn external_and_public_interleaving_works() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - assert_ok!(Democracy::external_propose( - Origin::signed(2), - set_balance_proposal_hash_and_note(1), - )); - assert_ok!(propose_set_balance_and_note(6, 2, 2)); - - fast_forward_to(2); - - // both waiting: external goes first. - assert_eq!( - Democracy::referendum_info(0), - Some(ReferendumInfo { - end: 4, - proposal_hash: set_balance_proposal_hash_and_note(1), - threshold: VoteThreshold::SuperMajorityApprove, - delay: 2 - }) - ); - // replenish external - assert_ok!(Democracy::external_propose( - Origin::signed(2), - set_balance_proposal_hash_and_note(3), - )); - - fast_forward_to(4); - - // both waiting: public goes next. - assert_eq!( - Democracy::referendum_info(1), - Some(ReferendumInfo { - end: 6, - proposal_hash: set_balance_proposal_hash_and_note(2), - threshold: VoteThreshold::SuperMajorityApprove, - delay: 2 - }) - ); - // don't replenish public - - fast_forward_to(6); - - // it's external "turn" again, though since public is empty that doesn't really matter - assert_eq!( - Democracy::referendum_info(2), - Some(ReferendumInfo { - end: 8, - proposal_hash: set_balance_proposal_hash_and_note(3), - threshold: VoteThreshold::SuperMajorityApprove, - delay: 2 - }) - ); - // replenish external - assert_ok!(Democracy::external_propose( - Origin::signed(2), - set_balance_proposal_hash_and_note(5), - )); - - fast_forward_to(8); - - // external goes again because there's no public waiting. - assert_eq!( - Democracy::referendum_info(3), - Some(ReferendumInfo { - end: 10, - proposal_hash: set_balance_proposal_hash_and_note(5), - threshold: VoteThreshold::SuperMajorityApprove, - delay: 2 - }) - ); - // replenish both - assert_ok!(Democracy::external_propose( - Origin::signed(2), - set_balance_proposal_hash_and_note(7), - )); - assert_ok!(propose_set_balance_and_note(6, 4, 2)); - - fast_forward_to(10); - - // public goes now since external went last time. - assert_eq!( - Democracy::referendum_info(4), - Some(ReferendumInfo { - end: 12, - proposal_hash: set_balance_proposal_hash_and_note(4), - threshold: VoteThreshold::SuperMajorityApprove, - delay: 2 - }) - ); - // replenish public again - assert_ok!(propose_set_balance_and_note(6, 6, 2)); - // cancel external - let h = set_balance_proposal_hash_and_note(7); - assert_ok!(Democracy::veto_external(Origin::signed(3), h)); - - fast_forward_to(12); - - // public goes again now since there's no external waiting. - assert_eq!( - Democracy::referendum_info(5), - Some(ReferendumInfo { - end: 14, - proposal_hash: set_balance_proposal_hash_and_note(6), - threshold: VoteThreshold::SuperMajorityApprove, - delay: 2 - }) - ); - }); - } - - - #[test] - fn emergency_cancel_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 2 - ); - assert!(Democracy::referendum_info(r).is_some()); - - assert_noop!(Democracy::emergency_cancel(Origin::signed(3), r), BadOrigin); - assert_ok!(Democracy::emergency_cancel(Origin::signed(4), r)); - assert!(Democracy::referendum_info(r).is_none()); - - // some time later... - - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 2 - ); - assert!(Democracy::referendum_info(r).is_some()); - assert_noop!(Democracy::emergency_cancel(Origin::signed(4), r), Error::::AlreadyCanceled); - }); - } - - #[test] - fn veto_external_works() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - assert_ok!(Democracy::external_propose( - Origin::signed(2), - set_balance_proposal_hash_and_note(2), - )); - assert!(>::exists()); - - let h = set_balance_proposal_hash_and_note(2); - assert_ok!(Democracy::veto_external(Origin::signed(3), h.clone())); - // cancelled. - assert!(!>::exists()); - // fails - same proposal can't be resubmitted. - assert_noop!(Democracy::external_propose( - Origin::signed(2), - set_balance_proposal_hash(2), - ), Error::::ProposalBlacklisted); - - fast_forward_to(1); - // fails as we're still in cooloff period. - assert_noop!(Democracy::external_propose( - Origin::signed(2), - set_balance_proposal_hash(2), - ), Error::::ProposalBlacklisted); - - fast_forward_to(2); - // works; as we're out of the cooloff period. - assert_ok!(Democracy::external_propose( - Origin::signed(2), - set_balance_proposal_hash_and_note(2), - )); - assert!(>::exists()); - - // 3 can't veto the same thing twice. - assert_noop!( - Democracy::veto_external(Origin::signed(3), h.clone()), - Error::::AlreadyVetoed - ); - - // 4 vetoes. - assert_ok!(Democracy::veto_external(Origin::signed(4), h.clone())); - // cancelled again. - assert!(!>::exists()); - - fast_forward_to(3); - // same proposal fails as we're still in cooloff - assert_noop!(Democracy::external_propose( - Origin::signed(2), - set_balance_proposal_hash(2), - ), Error::::ProposalBlacklisted); - // different proposal works fine. - assert_ok!(Democracy::external_propose( - Origin::signed(2), - set_balance_proposal_hash_and_note(3), - )); - }); - } - - #[test] - fn external_referendum_works() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - assert_noop!( - Democracy::external_propose( - Origin::signed(1), - set_balance_proposal_hash(2), - ), - BadOrigin, - ); - assert_ok!(Democracy::external_propose( - Origin::signed(2), - set_balance_proposal_hash_and_note(2), - )); - assert_noop!(Democracy::external_propose( - Origin::signed(2), - set_balance_proposal_hash(1), - ), Error::::DuplicateProposal); - fast_forward_to(2); - assert_eq!( - Democracy::referendum_info(0), - Some(ReferendumInfo { - end: 4, - proposal_hash: set_balance_proposal_hash(2), - threshold: VoteThreshold::SuperMajorityApprove, - delay: 2 - }) - ); - }); - } - - #[test] - fn external_majority_referendum_works() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - assert_noop!( - Democracy::external_propose_majority( - Origin::signed(1), - set_balance_proposal_hash(2) - ), - BadOrigin, - ); - assert_ok!(Democracy::external_propose_majority( - Origin::signed(3), - set_balance_proposal_hash_and_note(2) - )); - fast_forward_to(2); - assert_eq!( - Democracy::referendum_info(0), - Some(ReferendumInfo { - end: 4, - proposal_hash: set_balance_proposal_hash(2), - threshold: VoteThreshold::SimpleMajority, - delay: 2, - }) - ); - }); - } - - #[test] - fn external_default_referendum_works() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - assert_noop!( - Democracy::external_propose_default( - Origin::signed(3), - set_balance_proposal_hash(2) - ), - BadOrigin, - ); - assert_ok!(Democracy::external_propose_default( - Origin::signed(1), - set_balance_proposal_hash_and_note(2) - )); - fast_forward_to(2); - assert_eq!( - Democracy::referendum_info(0), - Some(ReferendumInfo { - end: 4, - proposal_hash: set_balance_proposal_hash(2), - threshold: VoteThreshold::SuperMajorityAgainst, - delay: 2, - }) - ); - }); - } - - #[test] - fn fast_track_referendum_works() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - let h = set_balance_proposal_hash_and_note(2); - assert_noop!(Democracy::fast_track(Origin::signed(5), h, 3, 2), Error::::ProposalMissing); - assert_ok!(Democracy::external_propose_majority( - Origin::signed(3), - set_balance_proposal_hash_and_note(2) - )); - assert_noop!(Democracy::fast_track(Origin::signed(1), h, 3, 2), BadOrigin); - assert_ok!(Democracy::fast_track(Origin::signed(5), h, 0, 0)); - assert_eq!( - Democracy::referendum_info(0), - Some(ReferendumInfo { - end: 1, - proposal_hash: set_balance_proposal_hash_and_note(2), - threshold: VoteThreshold::SimpleMajority, - delay: 0, - }) - ); - }); - } - - #[test] - fn fast_track_referendum_fails_when_no_simple_majority() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - let h = set_balance_proposal_hash_and_note(2); - assert_ok!(Democracy::external_propose( - Origin::signed(2), - set_balance_proposal_hash_and_note(2) - )); - assert_noop!( - Democracy::fast_track(Origin::signed(5), h, 3, 2), - Error::::NotSimpleMajority - ); - }); - } - - #[test] - fn locked_for_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - assert_ok!(propose_set_balance_and_note(1, 2, 2)); - assert_ok!(propose_set_balance_and_note(1, 4, 4)); - assert_ok!(propose_set_balance_and_note(1, 3, 3)); - assert_eq!(Democracy::locked_for(0), Some(2)); - assert_eq!(Democracy::locked_for(1), Some(4)); - assert_eq!(Democracy::locked_for(2), Some(3)); - }); - } - - #[test] - fn single_proposal_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - assert_ok!(propose_set_balance_and_note(1, 2, 1)); - assert!(Democracy::referendum_info(0).is_none()); - - // start of 2 => next referendum scheduled. - fast_forward_to(2); - - let r = 0; - assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); - - assert_eq!(Democracy::referendum_count(), 1); - assert_eq!( - Democracy::referendum_info(0), - Some(ReferendumInfo { - end: 4, - proposal_hash: set_balance_proposal_hash_and_note(2), - threshold: VoteThreshold::SuperMajorityApprove, - delay: 2 - }) - ); - assert_eq!(Democracy::voters_for(r), vec![1]); - assert_eq!(Democracy::vote_of((r, 1)), AYE); - assert_eq!(Democracy::tally(r), (1, 0, 1)); - - fast_forward_to(3); - - // referendum still running - assert!(Democracy::referendum_info(0).is_some()); - - // referendum runs during 2 and 3, ends @ start of 4. - fast_forward_to(4); - - assert!(Democracy::referendum_info(0).is_none()); - assert_eq!(Democracy::dispatch_queue(), vec![ - (6, set_balance_proposal_hash_and_note(2), 0) - ]); - - // referendum passes and wait another two blocks for enactment. - fast_forward_to(6); - - assert_eq!(Balances::free_balance(42), 2); - }); - } - - #[test] - fn cancel_queued_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - assert_ok!(propose_set_balance_and_note(1, 2, 1)); - - // start of 2 => next referendum scheduled. - fast_forward_to(2); - - assert_ok!(Democracy::vote(Origin::signed(1), 0, AYE)); - - fast_forward_to(4); - - assert_eq!(Democracy::dispatch_queue(), vec![ - (6, set_balance_proposal_hash_and_note(2), 0) - ]); - - assert_noop!(Democracy::cancel_queued(Origin::ROOT, 1), Error::::ProposalMissing); - assert_ok!(Democracy::cancel_queued(Origin::ROOT, 0)); - assert_eq!(Democracy::dispatch_queue(), vec![]); - }); - } - - #[test] - fn proxy_should_work() { - new_test_ext().execute_with(|| { - assert_eq!(Democracy::proxy(10), None); - assert!(System::allow_death(&10)); - - assert_noop!(Democracy::activate_proxy(Origin::signed(1), 10), Error::::NotOpen); - - assert_ok!(Democracy::open_proxy(Origin::signed(10), 1)); - assert!(!System::allow_death(&10)); - assert_eq!(Democracy::proxy(10), Some(ProxyState::Open(1))); - - assert_noop!(Democracy::activate_proxy(Origin::signed(2), 10), Error::::WrongOpen); - assert_ok!(Democracy::activate_proxy(Origin::signed(1), 10)); - assert_eq!(Democracy::proxy(10), Some(ProxyState::Active(1))); - - // Can't set when already set. - assert_noop!(Democracy::activate_proxy(Origin::signed(2), 10), Error::::AlreadyProxy); - - // But this works because 11 isn't proxying. - assert_ok!(Democracy::open_proxy(Origin::signed(11), 2)); - assert_ok!(Democracy::activate_proxy(Origin::signed(2), 11)); - assert_eq!(Democracy::proxy(10), Some(ProxyState::Active(1))); - assert_eq!(Democracy::proxy(11), Some(ProxyState::Active(2))); - - // 2 cannot fire 1's proxy: - assert_noop!(Democracy::deactivate_proxy(Origin::signed(2), 10), Error::::WrongProxy); - - // 1 deactivates their proxy: - assert_ok!(Democracy::deactivate_proxy(Origin::signed(1), 10)); - assert_eq!(Democracy::proxy(10), Some(ProxyState::Open(1))); - // but the proxy account cannot be killed until the proxy is closed. - assert!(!System::allow_death(&10)); - - // and then 10 closes it completely: - assert_ok!(Democracy::close_proxy(Origin::signed(10))); - assert_eq!(Democracy::proxy(10), None); - assert!(System::allow_death(&10)); - - // 11 just closes without 2's "permission". - assert_ok!(Democracy::close_proxy(Origin::signed(11))); - assert_eq!(Democracy::proxy(11), None); - assert!(System::allow_death(&11)); - }); - } - - #[test] - fn single_proposal_should_work_with_proxy() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - assert_ok!(propose_set_balance_and_note(1, 2, 1)); - - fast_forward_to(2); - let r = 0; - assert_ok!(Democracy::open_proxy(Origin::signed(10), 1)); - assert_ok!(Democracy::activate_proxy(Origin::signed(1), 10)); - assert_ok!(Democracy::proxy_vote(Origin::signed(10), r, AYE)); - - assert_eq!(Democracy::voters_for(r), vec![1]); - assert_eq!(Democracy::vote_of((r, 1)), AYE); - assert_eq!(Democracy::tally(r), (1, 0, 1)); - - fast_forward_to(6); - assert_eq!(Balances::free_balance(42), 2); - }); - } - - #[test] - fn single_proposal_should_work_with_delegation() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - - assert_ok!(propose_set_balance_and_note(1, 2, 1)); - - fast_forward_to(2); - - // Delegate vote. - assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::max_value())); - - let r = 0; - assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); - assert_eq!(Democracy::voters_for(r), vec![1]); - assert_eq!(Democracy::vote_of((r, 1)), AYE); - // Delegated vote is counted. - assert_eq!(Democracy::tally(r), (3, 0, 3)); - - fast_forward_to(6); - - assert_eq!(Balances::free_balance(42), 2); - }); - } - - #[test] - fn single_proposal_should_work_with_cyclic_delegation() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - - assert_ok!(propose_set_balance_and_note(1, 2, 1)); - - fast_forward_to(2); - - // Check behavior with cycle. - assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::max_value())); - assert_ok!(Democracy::delegate(Origin::signed(3), 2, Conviction::max_value())); - assert_ok!(Democracy::delegate(Origin::signed(1), 3, Conviction::max_value())); - let r = 0; - assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); - assert_eq!(Democracy::voters_for(r), vec![1]); - - // Delegated vote is counted. - assert_eq!(Democracy::tally(r), (6, 0, 6)); - - fast_forward_to(6); - - assert_eq!(Balances::free_balance(42), 2); - }); - } - - #[test] - /// If transactor already voted, delegated vote is overwritten. - fn single_proposal_should_work_with_vote_and_delegation() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - - assert_ok!(propose_set_balance_and_note(1, 2, 1)); - - fast_forward_to(2); - - let r = 0; - assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); - // Vote. - assert_ok!(Democracy::vote(Origin::signed(2), r, AYE)); - // Delegate vote. - assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::max_value())); - assert_eq!(Democracy::voters_for(r), vec![1, 2]); - assert_eq!(Democracy::vote_of((r, 1)), AYE); - // Delegated vote is not counted. - assert_eq!(Democracy::tally(r), (3, 0, 3)); - - fast_forward_to(6); - - assert_eq!(Balances::free_balance(42), 2); - }); - } - - #[test] - fn single_proposal_should_work_with_undelegation() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - - assert_ok!(propose_set_balance_and_note(1, 2, 1)); - - // Delegate and undelegate vote. - assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::max_value())); - assert_ok!(Democracy::undelegate(Origin::signed(2))); - - fast_forward_to(2); - let r = 0; - assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); - - assert_eq!(Democracy::referendum_count(), 1); - assert_eq!(Democracy::voters_for(r), vec![1]); - assert_eq!(Democracy::vote_of((r, 1)), AYE); - - // Delegated vote is not counted. - assert_eq!(Democracy::tally(r), (1, 0, 1)); - - fast_forward_to(6); - - assert_eq!(Balances::free_balance(42), 2); - }); - } - - #[test] - /// If transactor voted, delegated vote is overwritten. - fn single_proposal_should_work_with_delegation_and_vote() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - - assert_ok!(propose_set_balance_and_note(1, 2, 1)); - - fast_forward_to(2); - let r = 0; - - assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); - - // Delegate vote. - assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::max_value())); - - // Vote. - assert_ok!(Democracy::vote(Origin::signed(2), r, AYE)); - - assert_eq!(Democracy::referendum_count(), 1); - assert_eq!(Democracy::voters_for(r), vec![1, 2]); - assert_eq!(Democracy::vote_of((r, 1)), AYE); - - // Delegated vote is not counted. - assert_eq!(Democracy::tally(r), (3, 0, 3)); - - fast_forward_to(6); - - assert_eq!(Balances::free_balance(42), 2); - }); - } - - #[test] - fn deposit_for_proposals_should_be_taken() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - assert_ok!(propose_set_balance_and_note(1, 2, 5)); - assert_ok!(Democracy::second(Origin::signed(2), 0)); - assert_ok!(Democracy::second(Origin::signed(5), 0)); - assert_ok!(Democracy::second(Origin::signed(5), 0)); - assert_ok!(Democracy::second(Origin::signed(5), 0)); - assert_eq!(Balances::free_balance(1), 5); - assert_eq!(Balances::free_balance(2), 15); - assert_eq!(Balances::free_balance(5), 35); - }); - } - - #[test] - fn deposit_for_proposals_should_be_returned() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - assert_ok!(propose_set_balance_and_note(1, 2, 5)); - assert_ok!(Democracy::second(Origin::signed(2), 0)); - assert_ok!(Democracy::second(Origin::signed(5), 0)); - assert_ok!(Democracy::second(Origin::signed(5), 0)); - assert_ok!(Democracy::second(Origin::signed(5), 0)); - fast_forward_to(3); - assert_eq!(Balances::free_balance(1), 10); - assert_eq!(Balances::free_balance(2), 20); - assert_eq!(Balances::free_balance(5), 50); - }); - } - - #[test] - fn proposal_with_deposit_below_minimum_should_not_work() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - assert_noop!(propose_set_balance(1, 2, 0), Error::::ValueLow); - }); - } - - #[test] - fn poor_proposer_should_not_work() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - assert_noop!(propose_set_balance(1, 2, 11), BalancesError::::InsufficientBalance); - }); - } - - #[test] - fn poor_seconder_should_not_work() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - assert_ok!(propose_set_balance_and_note(2, 2, 11)); - assert_noop!(Democracy::second(Origin::signed(1), 0), BalancesError::::InsufficientBalance); - }); - } - - #[test] - fn runners_up_should_come_after() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - assert_ok!(propose_set_balance_and_note(1, 2, 2)); - assert_ok!(propose_set_balance_and_note(1, 4, 4)); - assert_ok!(propose_set_balance_and_note(1, 3, 3)); - fast_forward_to(2); - assert_ok!(Democracy::vote(Origin::signed(1), 0, AYE)); - fast_forward_to(4); - assert_ok!(Democracy::vote(Origin::signed(1), 1, AYE)); - fast_forward_to(6); - assert_ok!(Democracy::vote(Origin::signed(1), 2, AYE)); - }); - } - - #[test] - fn ooo_inject_referendums_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - let r1 = Democracy::inject_referendum( - 3, - set_balance_proposal_hash_and_note(3), - VoteThreshold::SuperMajorityApprove, - 0 - ); - let r2 = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 0 - ); - - assert_ok!(Democracy::vote(Origin::signed(1), r2, AYE)); - assert_eq!(Democracy::voters_for(r2), vec![1]); - assert_eq!(Democracy::vote_of((r2, 1)), AYE); - assert_eq!(Democracy::tally(r2), (1, 0, 1)); - - next_block(); - assert_eq!(Balances::free_balance(42), 2); - - assert_ok!(Democracy::vote(Origin::signed(1), r1, AYE)); - assert_eq!(Democracy::voters_for(r1), vec![1]); - assert_eq!(Democracy::vote_of((r1, 1)), AYE); - assert_eq!(Democracy::tally(r1), (1, 0, 1)); - - next_block(); - assert_eq!(Balances::free_balance(42), 3); - }); - } - - #[test] - fn simple_passing_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 0 - ); - assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); - - assert_eq!(Democracy::voters_for(r), vec![1]); - assert_eq!(Democracy::vote_of((r, 1)), AYE); - assert_eq!(Democracy::tally(r), (1, 0, 1)); - - next_block(); - next_block(); - - assert_eq!(Balances::free_balance(42), 2); - }); - } - - #[test] - fn cancel_referendum_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 0 - ); - assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); - assert_ok!(Democracy::cancel_referendum(Origin::ROOT, r.into())); - - next_block(); - next_block(); - - assert_eq!(Balances::free_balance(42), 0); - }); - } - - #[test] - fn simple_failing_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 0 - ); - assert_ok!(Democracy::vote(Origin::signed(1), r, NAY)); - - assert_eq!(Democracy::voters_for(r), vec![1]); - assert_eq!(Democracy::vote_of((r, 1)), NAY); - assert_eq!(Democracy::tally(r), (0, 1, 1)); - - next_block(); - next_block(); - - assert_eq!(Balances::free_balance(42), 0); - }); - } - - #[test] - fn controversial_voting_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 0 - ); - - assert_ok!(Democracy::vote(Origin::signed(1), r, BIG_AYE)); - assert_ok!(Democracy::vote(Origin::signed(2), r, BIG_NAY)); - assert_ok!(Democracy::vote(Origin::signed(3), r, BIG_NAY)); - assert_ok!(Democracy::vote(Origin::signed(4), r, BIG_AYE)); - assert_ok!(Democracy::vote(Origin::signed(5), r, BIG_NAY)); - assert_ok!(Democracy::vote(Origin::signed(6), r, BIG_AYE)); - - assert_eq!(Democracy::tally(r), (110, 100, 210)); - - next_block(); - next_block(); - - assert_eq!(Balances::free_balance(42), 2); - }); - } - - #[test] - fn delayed_enactment_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 1 - ); - assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); - assert_ok!(Democracy::vote(Origin::signed(2), r, AYE)); - assert_ok!(Democracy::vote(Origin::signed(3), r, AYE)); - assert_ok!(Democracy::vote(Origin::signed(4), r, AYE)); - assert_ok!(Democracy::vote(Origin::signed(5), r, AYE)); - assert_ok!(Democracy::vote(Origin::signed(6), r, AYE)); - - assert_eq!(Democracy::tally(r), (21, 0, 21)); - - next_block(); - assert_eq!(Balances::free_balance(42), 0); - - next_block(); - - assert_eq!(Balances::free_balance(42), 2); - }); - } - - #[test] - fn controversial_low_turnout_voting_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 0 - ); - assert_ok!(Democracy::vote(Origin::signed(5), r, BIG_NAY)); - assert_ok!(Democracy::vote(Origin::signed(6), r, BIG_AYE)); - - assert_eq!(Democracy::tally(r), (60, 50, 110)); - - next_block(); - next_block(); - - assert_eq!(Balances::free_balance(42), 0); - }); - } - - #[test] - fn passing_low_turnout_voting_should_work() { - new_test_ext().execute_with(|| { - assert_eq!(Balances::free_balance(42), 0); - assert_eq!(Balances::total_issuance(), 210); - - System::set_block_number(1); - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 0 - ); - assert_ok!(Democracy::vote(Origin::signed(4), r, BIG_AYE)); - assert_ok!(Democracy::vote(Origin::signed(5), r, BIG_NAY)); - assert_ok!(Democracy::vote(Origin::signed(6), r, BIG_AYE)); - - assert_eq!(Democracy::tally(r), (100, 50, 150)); - - next_block(); - next_block(); - - assert_eq!(Balances::free_balance(42), 2); - }); - } - - #[test] - fn lock_voting_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 0 - ); - assert_ok!(Democracy::vote(Origin::signed(1), r, Vote { - aye: false, - conviction: Conviction::Locked5x - })); - assert_ok!(Democracy::vote(Origin::signed(2), r, Vote { - aye: true, - conviction: Conviction::Locked4x - })); - assert_ok!(Democracy::vote(Origin::signed(3), r, Vote { - aye: true, - conviction: Conviction::Locked3x - })); - assert_ok!(Democracy::vote(Origin::signed(4), r, Vote { - aye: true, - conviction: Conviction::Locked2x - })); - assert_ok!(Democracy::vote(Origin::signed(5), r, Vote { - aye: false, - conviction: Conviction::Locked1x - })); - - assert_eq!(Democracy::tally(r), (250, 100, 150)); - - fast_forward_to(2); - - assert_eq!(Balances::locks(1), vec![]); - assert_eq!(Balances::locks(2), vec![BalanceLock { - id: DEMOCRACY_ID, - amount: u64::max_value(), - reasons: pallet_balances::Reasons::Misc, - }]); - assert_eq!(Democracy::locks(2), Some(18)); - assert_eq!(Balances::locks(3), vec![BalanceLock { - id: DEMOCRACY_ID, - amount: u64::max_value(), - reasons: pallet_balances::Reasons::Misc, - }]); - assert_eq!(Democracy::locks(3), Some(10)); - assert_eq!(Balances::locks(4), vec![BalanceLock { - id: DEMOCRACY_ID, - amount: u64::max_value(), - reasons: pallet_balances::Reasons::Misc, - }]); - assert_eq!(Democracy::locks(4), Some(6)); - assert_eq!(Balances::locks(5), vec![]); - - assert_eq!(Balances::free_balance(42), 2); - - assert_noop!(Democracy::unlock(Origin::signed(1), 1), Error::::NotLocked); - - fast_forward_to(5); - assert_noop!(Democracy::unlock(Origin::signed(1), 4), Error::::NotExpired); - fast_forward_to(6); - assert_ok!(Democracy::unlock(Origin::signed(1), 4)); - assert_noop!(Democracy::unlock(Origin::signed(1), 4), Error::::NotLocked); - - fast_forward_to(9); - assert_noop!(Democracy::unlock(Origin::signed(1), 3), Error::::NotExpired); - fast_forward_to(10); - assert_ok!(Democracy::unlock(Origin::signed(1), 3)); - assert_noop!(Democracy::unlock(Origin::signed(1), 3), Error::::NotLocked); - - fast_forward_to(17); - assert_noop!(Democracy::unlock(Origin::signed(1), 2), Error::::NotExpired); - fast_forward_to(18); - assert_ok!(Democracy::unlock(Origin::signed(1), 2)); - assert_noop!(Democracy::unlock(Origin::signed(1), 2), Error::::NotLocked); - }); - } - - #[test] - fn no_locks_without_conviction_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 0, - ); - assert_ok!(Democracy::vote(Origin::signed(1), r, Vote { - aye: true, - conviction: Conviction::None, - })); - - fast_forward_to(2); - - assert_eq!(Balances::free_balance(42), 2); - assert_eq!(Balances::locks(1), vec![]); - }); - } - - #[test] - fn lock_voting_should_work_with_delegation() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - let r = Democracy::inject_referendum( - 2, - set_balance_proposal_hash_and_note(2), - VoteThreshold::SuperMajorityApprove, - 0 - ); - assert_ok!(Democracy::vote(Origin::signed(1), r, Vote { - aye: false, - conviction: Conviction::Locked5x - })); - assert_ok!(Democracy::vote(Origin::signed(2), r, Vote { - aye: true, - conviction: Conviction::Locked4x - })); - assert_ok!(Democracy::vote(Origin::signed(3), r, Vote { - aye: true, - conviction: Conviction::Locked3x - })); - assert_ok!(Democracy::delegate(Origin::signed(4), 2, Conviction::Locked2x)); - assert_ok!(Democracy::vote(Origin::signed(5), r, Vote { - aye: false, - conviction: Conviction::Locked1x - })); - - assert_eq!(Democracy::tally(r), (250, 100, 150)); - - next_block(); - next_block(); - - assert_eq!(Balances::free_balance(42), 2); - }); - } -} diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs new file mode 100644 index 0000000000..f2544470aa --- /dev/null +++ b/frame/democracy/src/tests.rs @@ -0,0 +1,250 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The crate's tests. + +use super::*; +use std::cell::RefCell; +use codec::Encode; +use frame_support::{ + impl_outer_origin, impl_outer_dispatch, assert_noop, assert_ok, parameter_types, + ord_parameter_types, traits::Contains, weights::Weight, +}; +use sp_core::H256; +use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup, BadOrigin}, + testing::Header, Perbill, +}; +use pallet_balances::{BalanceLock, Error as BalancesError}; +use frame_system::EnsureSignedBy; + +mod cancellation; +mod delegation; +mod external_proposing; +mod fast_tracking; +mod lock_voting; +mod preimage; +mod proxying; +mod public_proposals; +mod scheduling; +mod voting; + +const AYE: Vote = Vote { aye: true, conviction: Conviction::None }; +const NAY: Vote = Vote { aye: false, conviction: Conviction::None }; +const BIG_AYE: Vote = Vote { aye: true, conviction: Conviction::Locked1x }; +const BIG_NAY: Vote = Vote { aye: false, conviction: Conviction::Locked1x }; + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + pallet_balances::Balances, + democracy::Democracy, + } +} + +// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. +#[derive(Clone, Eq, PartialEq, Debug)] +pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} +impl frame_system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); +} +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} +impl pallet_balances::Trait for Test { + type Balance = u64; + type Event = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; +} +parameter_types! { + pub const LaunchPeriod: u64 = 2; + pub const VotingPeriod: u64 = 2; + pub const FastTrackVotingPeriod: u64 = 2; + pub const MinimumDeposit: u64 = 1; + pub const EnactmentPeriod: u64 = 2; + pub const CooloffPeriod: u64 = 2; +} +ord_parameter_types! { + pub const One: u64 = 1; + pub const Two: u64 = 2; + pub const Three: u64 = 3; + pub const Four: u64 = 4; + pub const Five: u64 = 5; + pub const Six: u64 = 6; +} +pub struct OneToFive; +impl Contains for OneToFive { + fn sorted_members() -> Vec { + vec![1, 2, 3, 4, 5] + } +} +thread_local! { + static PREIMAGE_BYTE_DEPOSIT: RefCell = RefCell::new(0); + static INSTANT_ALLOWED: RefCell = RefCell::new(false); +} +pub struct PreimageByteDeposit; +impl Get for PreimageByteDeposit { + fn get() -> u64 { PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow()) } +} +pub struct InstantAllowed; +impl Get for InstantAllowed { + fn get() -> bool { INSTANT_ALLOWED.with(|v| *v.borrow()) } +} +impl super::Trait for Test { + type Proposal = Call; + type Event = (); + type Currency = pallet_balances::Module; + type EnactmentPeriod = EnactmentPeriod; + type LaunchPeriod = LaunchPeriod; + type VotingPeriod = VotingPeriod; + type FastTrackVotingPeriod = FastTrackVotingPeriod; + type MinimumDeposit = MinimumDeposit; + type ExternalOrigin = EnsureSignedBy; + type ExternalMajorityOrigin = EnsureSignedBy; + type ExternalDefaultOrigin = EnsureSignedBy; + type FastTrackOrigin = EnsureSignedBy; + type CancellationOrigin = EnsureSignedBy; + type VetoOrigin = EnsureSignedBy; + type CooloffPeriod = CooloffPeriod; + type PreimageByteDeposit = PreimageByteDeposit; + type Slash = (); + type InstantOrigin = EnsureSignedBy; + type InstantAllowed = InstantAllowed; +} + +fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig::{ + balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], + }.assimilate_storage(&mut t).unwrap(); + GenesisConfig::default().assimilate_storage(&mut t).unwrap(); + sp_io::TestExternalities::new(t) +} + +type System = frame_system::Module; +type Balances = pallet_balances::Module; +type Democracy = Module; + +#[test] +fn params_should_work() { + new_test_ext().execute_with(|| { + assert_eq!(Democracy::referendum_count(), 0); + assert_eq!(Balances::free_balance(42), 0); + assert_eq!(Balances::total_issuance(), 210); + }); +} + +fn set_balance_proposal(value: u64) -> Vec { + Call::Balances(pallet_balances::Call::set_balance(42, value, 0)).encode() +} + +fn set_balance_proposal_hash(value: u64) -> H256 { + BlakeTwo256::hash(&set_balance_proposal(value)[..]) +} + +fn set_balance_proposal_hash_and_note(value: u64) -> H256 { + let p = set_balance_proposal(value); + let h = BlakeTwo256::hash(&p[..]); + match Democracy::note_preimage(Origin::signed(6), p) { + Ok(_) => (), + Err(x) if x == Error::::DuplicatePreimage.into() => (), + Err(x) => panic!(x), + } + h +} + +fn propose_set_balance(who: u64, value: u64, delay: u64) -> DispatchResult { + Democracy::propose( + Origin::signed(who), + set_balance_proposal_hash(value), + delay + ) +} + +fn propose_set_balance_and_note(who: u64, value: u64, delay: u64) -> DispatchResult { + Democracy::propose( + Origin::signed(who), + set_balance_proposal_hash_and_note(value), + delay + ) +} + +fn next_block() { + System::set_block_number(System::block_number() + 1); + assert_eq!(Democracy::begin_block(System::block_number()), Ok(())); +} + +fn fast_forward_to(n: u64) { + while System::block_number() < n { + next_block(); + } +} + +fn begin_referendum() -> ReferendumIndex { + System::set_block_number(0); + assert_ok!(propose_set_balance_and_note(1, 2, 1)); + fast_forward_to(2); + 0 +} + +fn aye(who: u64) -> AccountVote { + AccountVote::Standard { vote: AYE, balance: Balances::free_balance(&who) } +} + +fn nay(who: u64) -> AccountVote { + AccountVote::Standard { vote: NAY, balance: Balances::free_balance(&who) } +} + +fn big_aye(who: u64) -> AccountVote { + AccountVote::Standard { vote: BIG_AYE, balance: Balances::free_balance(&who) } +} + +fn big_nay(who: u64) -> AccountVote { + AccountVote::Standard { vote: BIG_NAY, balance: Balances::free_balance(&who) } +} + +fn tally(r: ReferendumIndex) -> Tally { + Democracy::referendum_status(r).unwrap().tally +} diff --git a/frame/democracy/src/tests/cancellation.rs b/frame/democracy/src/tests/cancellation.rs new file mode 100644 index 0000000000..c0e1b8b27a --- /dev/null +++ b/frame/democracy/src/tests/cancellation.rs @@ -0,0 +1,94 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The tests for cancelation functionality. + +use super::*; + +#[test] +fn cancel_referendum_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + assert_ok!(Democracy::cancel_referendum(Origin::ROOT, r.into())); + + next_block(); + next_block(); + + assert_eq!(Balances::free_balance(42), 0); + }); +} + +#[test] +fn cancel_queued_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + assert_ok!(propose_set_balance_and_note(1, 2, 1)); + + // start of 2 => next referendum scheduled. + fast_forward_to(2); + + assert_ok!(Democracy::vote(Origin::signed(1), 0, aye(1))); + + fast_forward_to(4); + + assert_eq!(Democracy::dispatch_queue(), vec![ + (6, set_balance_proposal_hash_and_note(2), 0) + ]); + + assert_noop!(Democracy::cancel_queued(Origin::ROOT, 1), Error::::ProposalMissing); + assert_ok!(Democracy::cancel_queued(Origin::ROOT, 0)); + assert_eq!(Democracy::dispatch_queue(), vec![]); + }); +} + +#[test] +fn emergency_cancel_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 2 + ); + assert!(Democracy::referendum_status(r).is_ok()); + + assert_noop!(Democracy::emergency_cancel(Origin::signed(3), r), BadOrigin); + assert_ok!(Democracy::emergency_cancel(Origin::signed(4), r)); + assert!(Democracy::referendum_info(r).is_none()); + + // some time later... + + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 2 + ); + assert!(Democracy::referendum_status(r).is_ok()); + assert_noop!( + Democracy::emergency_cancel(Origin::signed(4), r), + Error::::AlreadyCanceled, + ); + }); +} diff --git a/frame/democracy/src/tests/delegation.rs b/frame/democracy/src/tests/delegation.rs new file mode 100644 index 0000000000..061a48b587 --- /dev/null +++ b/frame/democracy/src/tests/delegation.rs @@ -0,0 +1,178 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The tests for functionality concerning delegation. + +use super::*; + +#[test] +fn single_proposal_should_work_with_delegation() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + + assert_ok!(propose_set_balance_and_note(1, 2, 1)); + + fast_forward_to(2); + + // Delegate first vote. + assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::None, 20)); + let r = 0; + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + assert_eq!(tally(r), Tally { ayes: 3, nays: 0, turnout: 30 }); + + // Delegate a second vote. + assert_ok!(Democracy::delegate(Origin::signed(3), 1, Conviction::None, 30)); + assert_eq!(tally(r), Tally { ayes: 6, nays: 0, turnout: 60 }); + + // Reduce first vote. + assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::None, 10)); + assert_eq!(tally(r), Tally { ayes: 5, nays: 0, turnout: 50 }); + + // Second vote delegates to first; we don't do tiered delegation, so it doesn't get used. + assert_ok!(Democracy::delegate(Origin::signed(3), 2, Conviction::None, 30)); + assert_eq!(tally(r), Tally { ayes: 2, nays: 0, turnout: 20 }); + + // Main voter cancels their vote + assert_ok!(Democracy::remove_vote(Origin::signed(1), r)); + assert_eq!(tally(r), Tally { ayes: 0, nays: 0, turnout: 0 }); + + // First delegator delegates half funds with conviction; nothing changes yet. + assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::Locked1x, 10)); + assert_eq!(tally(r), Tally { ayes: 0, nays: 0, turnout: 0 }); + + // Main voter reinstates their vote + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + assert_eq!(tally(r), Tally { ayes: 11, nays: 0, turnout: 20 }); + }); +} + +#[test] +fn self_delegation_not_allowed() { + new_test_ext().execute_with(|| { + assert_noop!( + Democracy::delegate(Origin::signed(1), 1, Conviction::None, 10), + Error::::Nonsense, + ); + }); +} + +#[test] +fn cyclic_delegation_should_unwind() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + + assert_ok!(propose_set_balance_and_note(1, 2, 1)); + + fast_forward_to(2); + + // Check behavior with cycle. + assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::None, 20)); + assert_ok!(Democracy::delegate(Origin::signed(3), 2, Conviction::None, 30)); + assert_ok!(Democracy::delegate(Origin::signed(1), 3, Conviction::None, 10)); + let r = 0; + assert_ok!(Democracy::undelegate(Origin::signed(3))); + assert_ok!(Democracy::vote(Origin::signed(3), r, aye(3))); + assert_ok!(Democracy::undelegate(Origin::signed(1))); + assert_ok!(Democracy::vote(Origin::signed(1), r, nay(1))); + + // Delegated vote is counted. + assert_eq!(tally(r), Tally { ayes: 3, nays: 3, turnout: 60 }); + }); +} + +#[test] +fn single_proposal_should_work_with_vote_and_delegation() { + // If transactor already voted, delegated vote is overwritten. + new_test_ext().execute_with(|| { + System::set_block_number(0); + + assert_ok!(propose_set_balance_and_note(1, 2, 1)); + + fast_forward_to(2); + + let r = 0; + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + assert_ok!(Democracy::vote(Origin::signed(2), r, nay(2))); + assert_eq!(tally(r), Tally { ayes: 1, nays: 2, turnout: 30 }); + + // Delegate vote. + assert_ok!(Democracy::remove_vote(Origin::signed(2), r)); + assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::None, 20)); + // Delegated vote replaces the explicit vote. + assert_eq!(tally(r), Tally { ayes: 3, nays: 0, turnout: 30 }); + }); +} + +#[test] +fn single_proposal_should_work_with_undelegation() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + + assert_ok!(propose_set_balance_and_note(1, 2, 1)); + + // Delegate and undelegate vote. + assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::None, 20)); + assert_ok!(Democracy::undelegate(Origin::signed(2))); + + fast_forward_to(2); + let r = 0; + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + + // Delegated vote is not counted. + assert_eq!(tally(r), Tally { ayes: 1, nays: 0, turnout: 10 }); + }); +} + +#[test] +fn single_proposal_should_work_with_delegation_and_vote() { + // If transactor voted, delegated vote is overwritten. + new_test_ext().execute_with(|| { + let r = begin_referendum(); + // Delegate, undelegate and vote. + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::None, 20)); + assert_eq!(tally(r), Tally { ayes: 3, nays: 0, turnout: 30 }); + assert_ok!(Democracy::undelegate(Origin::signed(2))); + assert_ok!(Democracy::vote(Origin::signed(2), r, aye(2))); + // Delegated vote is not counted. + assert_eq!(tally(r), Tally { ayes: 3, nays: 0, turnout: 30 }); + }); +} + +#[test] +fn conviction_should_be_honored_in_delegation() { + // If transactor voted, delegated vote is overwritten. + new_test_ext().execute_with(|| { + let r = begin_referendum(); + // Delegate, undelegate and vote. + assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::Locked6x, 20)); + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + // Delegated vote is huge. + assert_eq!(tally(r), Tally { ayes: 121, nays: 0, turnout: 30 }); + }); +} + +#[test] +fn split_vote_delegation_should_be_ignored() { + // If transactor voted, delegated vote is overwritten. + new_test_ext().execute_with(|| { + let r = begin_referendum(); + assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::Locked6x, 20)); + assert_ok!(Democracy::vote(Origin::signed(1), r, AccountVote::Split { aye: 10, nay: 0 })); + // Delegated vote is huge. + assert_eq!(tally(r), Tally { ayes: 1, nays: 0, turnout: 10 }); + }); +} diff --git a/frame/democracy/src/tests/external_proposing.rs b/frame/democracy/src/tests/external_proposing.rs new file mode 100644 index 0000000000..a249a806ee --- /dev/null +++ b/frame/democracy/src/tests/external_proposing.rs @@ -0,0 +1,289 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The tests for functionality concerning the "external" origin. + +use super::*; + +#[test] +fn veto_external_works() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + assert_ok!(Democracy::external_propose( + Origin::signed(2), + set_balance_proposal_hash_and_note(2), + )); + assert!(>::exists()); + + let h = set_balance_proposal_hash_and_note(2); + assert_ok!(Democracy::veto_external(Origin::signed(3), h.clone())); + // cancelled. + assert!(!>::exists()); + // fails - same proposal can't be resubmitted. + assert_noop!(Democracy::external_propose( + Origin::signed(2), + set_balance_proposal_hash(2), + ), Error::::ProposalBlacklisted); + + fast_forward_to(1); + // fails as we're still in cooloff period. + assert_noop!(Democracy::external_propose( + Origin::signed(2), + set_balance_proposal_hash(2), + ), Error::::ProposalBlacklisted); + + fast_forward_to(2); + // works; as we're out of the cooloff period. + assert_ok!(Democracy::external_propose( + Origin::signed(2), + set_balance_proposal_hash_and_note(2), + )); + assert!(>::exists()); + + // 3 can't veto the same thing twice. + assert_noop!( + Democracy::veto_external(Origin::signed(3), h.clone()), + Error::::AlreadyVetoed + ); + + // 4 vetoes. + assert_ok!(Democracy::veto_external(Origin::signed(4), h.clone())); + // cancelled again. + assert!(!>::exists()); + + fast_forward_to(3); + // same proposal fails as we're still in cooloff + assert_noop!(Democracy::external_propose( + Origin::signed(2), + set_balance_proposal_hash(2), + ), Error::::ProposalBlacklisted); + // different proposal works fine. + assert_ok!(Democracy::external_propose( + Origin::signed(2), + set_balance_proposal_hash_and_note(3), + )); + }); +} + +#[test] +fn external_referendum_works() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + assert_noop!( + Democracy::external_propose( + Origin::signed(1), + set_balance_proposal_hash(2), + ), + BadOrigin, + ); + assert_ok!(Democracy::external_propose( + Origin::signed(2), + set_balance_proposal_hash_and_note(2), + )); + assert_noop!(Democracy::external_propose( + Origin::signed(2), + set_balance_proposal_hash(1), + ), Error::::DuplicateProposal); + fast_forward_to(2); + assert_eq!( + Democracy::referendum_status(0), + Ok(ReferendumStatus { + end: 4, + proposal_hash: set_balance_proposal_hash(2), + threshold: VoteThreshold::SuperMajorityApprove, + delay: 2, + tally: Tally { ayes: 0, nays: 0, turnout: 0 }, + }) + ); + }); +} + +#[test] +fn external_majority_referendum_works() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + assert_noop!( + Democracy::external_propose_majority( + Origin::signed(1), + set_balance_proposal_hash(2) + ), + BadOrigin, + ); + assert_ok!(Democracy::external_propose_majority( + Origin::signed(3), + set_balance_proposal_hash_and_note(2) + )); + fast_forward_to(2); + assert_eq!( + Democracy::referendum_status(0), + Ok(ReferendumStatus { + end: 4, + proposal_hash: set_balance_proposal_hash(2), + threshold: VoteThreshold::SimpleMajority, + delay: 2, + tally: Tally { ayes: 0, nays: 0, turnout: 0 }, + }) + ); + }); +} + +#[test] +fn external_default_referendum_works() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + assert_noop!( + Democracy::external_propose_default( + Origin::signed(3), + set_balance_proposal_hash(2) + ), + BadOrigin, + ); + assert_ok!(Democracy::external_propose_default( + Origin::signed(1), + set_balance_proposal_hash_and_note(2) + )); + fast_forward_to(2); + assert_eq!( + Democracy::referendum_status(0), + Ok(ReferendumStatus { + end: 4, + proposal_hash: set_balance_proposal_hash(2), + threshold: VoteThreshold::SuperMajorityAgainst, + delay: 2, + tally: Tally { ayes: 0, nays: 0, turnout: 0 }, + }) + ); + }); +} + + +#[test] +fn external_and_public_interleaving_works() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + assert_ok!(Democracy::external_propose( + Origin::signed(2), + set_balance_proposal_hash_and_note(1), + )); + assert_ok!(propose_set_balance_and_note(6, 2, 2)); + + fast_forward_to(2); + + // both waiting: external goes first. + assert_eq!( + Democracy::referendum_status(0), + Ok(ReferendumStatus { + end: 4, + proposal_hash: set_balance_proposal_hash_and_note(1), + threshold: VoteThreshold::SuperMajorityApprove, + delay: 2, + tally: Tally { ayes: 0, nays: 0, turnout: 0 }, + }) + ); + // replenish external + assert_ok!(Democracy::external_propose( + Origin::signed(2), + set_balance_proposal_hash_and_note(3), + )); + + fast_forward_to(4); + + // both waiting: public goes next. + assert_eq!( + Democracy::referendum_status(1), + Ok(ReferendumStatus { + end: 6, + proposal_hash: set_balance_proposal_hash_and_note(2), + threshold: VoteThreshold::SuperMajorityApprove, + delay: 2, + tally: Tally { ayes: 0, nays: 0, turnout: 0 }, + }) + ); + // don't replenish public + + fast_forward_to(6); + + // it's external "turn" again, though since public is empty that doesn't really matter + assert_eq!( + Democracy::referendum_status(2), + Ok(ReferendumStatus { + end: 8, + proposal_hash: set_balance_proposal_hash_and_note(3), + threshold: VoteThreshold::SuperMajorityApprove, + delay: 2, + tally: Tally { ayes: 0, nays: 0, turnout: 0 }, + }) + ); + // replenish external + assert_ok!(Democracy::external_propose( + Origin::signed(2), + set_balance_proposal_hash_and_note(5), + )); + + fast_forward_to(8); + + // external goes again because there's no public waiting. + assert_eq!( + Democracy::referendum_status(3), + Ok(ReferendumStatus { + end: 10, + proposal_hash: set_balance_proposal_hash_and_note(5), + threshold: VoteThreshold::SuperMajorityApprove, + delay: 2, + tally: Tally { ayes: 0, nays: 0, turnout: 0 }, + }) + ); + // replenish both + assert_ok!(Democracy::external_propose( + Origin::signed(2), + set_balance_proposal_hash_and_note(7), + )); + assert_ok!(propose_set_balance_and_note(6, 4, 2)); + + fast_forward_to(10); + + // public goes now since external went last time. + assert_eq!( + Democracy::referendum_status(4), + Ok(ReferendumStatus { + end: 12, + proposal_hash: set_balance_proposal_hash_and_note(4), + threshold: VoteThreshold::SuperMajorityApprove, + delay: 2, + tally: Tally { ayes: 0, nays: 0, turnout: 0 }, + }) + ); + // replenish public again + assert_ok!(propose_set_balance_and_note(6, 6, 2)); + // cancel external + let h = set_balance_proposal_hash_and_note(7); + assert_ok!(Democracy::veto_external(Origin::signed(3), h)); + + fast_forward_to(12); + + // public goes again now since there's no external waiting. + assert_eq!( + Democracy::referendum_status(5), + Ok(ReferendumStatus { + end: 14, + proposal_hash: set_balance_proposal_hash_and_note(6), + threshold: VoteThreshold::SuperMajorityApprove, + delay: 2, + tally: Tally { ayes: 0, nays: 0, turnout: 0 }, + }) + ); + }); +} diff --git a/frame/democracy/src/tests/fast_tracking.rs b/frame/democracy/src/tests/fast_tracking.rs new file mode 100644 index 0000000000..5ce9b15baf --- /dev/null +++ b/frame/democracy/src/tests/fast_tracking.rs @@ -0,0 +1,88 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The tests for fast-tracking functionality. + +use super::*; + +#[test] +fn fast_track_referendum_works() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + let h = set_balance_proposal_hash_and_note(2); + assert_noop!(Democracy::fast_track(Origin::signed(5), h, 3, 2), Error::::ProposalMissing); + assert_ok!(Democracy::external_propose_majority( + Origin::signed(3), + set_balance_proposal_hash_and_note(2) + )); + assert_noop!(Democracy::fast_track(Origin::signed(1), h, 3, 2), BadOrigin); + assert_ok!(Democracy::fast_track(Origin::signed(5), h, 2, 0)); + assert_eq!( + Democracy::referendum_status(0), + Ok(ReferendumStatus { + end: 2, + proposal_hash: set_balance_proposal_hash_and_note(2), + threshold: VoteThreshold::SimpleMajority, + delay: 0, + tally: Tally { ayes: 0, nays: 0, turnout: 0 }, + }) + ); + }); +} + +#[test] +fn instant_referendum_works() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + let h = set_balance_proposal_hash_and_note(2); + assert_noop!(Democracy::fast_track(Origin::signed(5), h, 3, 2), Error::::ProposalMissing); + assert_ok!(Democracy::external_propose_majority( + Origin::signed(3), + set_balance_proposal_hash_and_note(2) + )); + assert_noop!(Democracy::fast_track(Origin::signed(1), h, 3, 2), BadOrigin); + assert_noop!(Democracy::fast_track(Origin::signed(5), h, 1, 0), BadOrigin); + assert_noop!(Democracy::fast_track(Origin::signed(6), h, 1, 0), Error::::InstantNotAllowed); + INSTANT_ALLOWED.with(|v| *v.borrow_mut() = true); + assert_ok!(Democracy::fast_track(Origin::signed(6), h, 1, 0)); + assert_eq!( + Democracy::referendum_status(0), + Ok(ReferendumStatus { + end: 1, + proposal_hash: set_balance_proposal_hash_and_note(2), + threshold: VoteThreshold::SimpleMajority, + delay: 0, + tally: Tally { ayes: 0, nays: 0, turnout: 0 }, + }) + ); + }); +} + +#[test] +fn fast_track_referendum_fails_when_no_simple_majority() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + let h = set_balance_proposal_hash_and_note(2); + assert_ok!(Democracy::external_propose( + Origin::signed(2), + set_balance_proposal_hash_and_note(2) + )); + assert_noop!( + Democracy::fast_track(Origin::signed(5), h, 3, 2), + Error::::NotSimpleMajority + ); + }); +} diff --git a/frame/democracy/src/tests/lock_voting.rs b/frame/democracy/src/tests/lock_voting.rs new file mode 100644 index 0000000000..c46bb47b89 --- /dev/null +++ b/frame/democracy/src/tests/lock_voting.rs @@ -0,0 +1,364 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The tests for functionality concerning locking and lock-voting. + +use super::*; +use std::convert::TryFrom; + +fn aye(x: u8, balance: u64) -> AccountVote { + AccountVote::Standard { + vote: Vote { aye: true, conviction: Conviction::try_from(x).unwrap() }, + balance + } +} + +fn nay(x: u8, balance: u64) -> AccountVote { + AccountVote::Standard { + vote: Vote { aye: false, conviction: Conviction::try_from(x).unwrap() }, + balance + } +} + +fn the_lock(amount: u64) -> BalanceLock { + BalanceLock { + id: DEMOCRACY_ID, + amount, + reasons: pallet_balances::Reasons::Misc, + } +} + +#[test] +fn lock_voting_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, nay(5, 10))); + assert_ok!(Democracy::vote(Origin::signed(2), r, aye(4, 20))); + assert_ok!(Democracy::vote(Origin::signed(3), r, aye(3, 30))); + assert_ok!(Democracy::vote(Origin::signed(4), r, aye(2, 40))); + assert_ok!(Democracy::vote(Origin::signed(5), r, nay(1, 50))); + assert_eq!(tally(r), Tally { ayes: 250, nays: 100, turnout: 150 }); + + // All balances are currently locked. + for i in 1..=5 { + assert_eq!(Balances::locks(i), vec![the_lock(i * 10)]); + } + + fast_forward_to(2); + + // Referendum passed; 1 and 5 didn't get their way and can now reap and unlock. + assert_ok!(Democracy::remove_vote(Origin::signed(1), r)); + assert_ok!(Democracy::unlock(Origin::signed(1), 1)); + // Anyone can reap and unlock anyone else's in this context. + assert_ok!(Democracy::remove_other_vote(Origin::signed(2), 5, r)); + assert_ok!(Democracy::unlock(Origin::signed(2), 5)); + + // 2, 3, 4 got their way with the vote, so they cannot be reaped by others. + assert_noop!(Democracy::remove_other_vote(Origin::signed(1), 2, r), Error::::NoPermission); + // However, they can be unvoted by the owner, though it will make no difference to the lock. + assert_ok!(Democracy::remove_vote(Origin::signed(2), r)); + assert_ok!(Democracy::unlock(Origin::signed(2), 2)); + + assert_eq!(Balances::locks(1), vec![]); + assert_eq!(Balances::locks(2), vec![the_lock(20)]); + assert_eq!(Balances::locks(3), vec![the_lock(30)]); + assert_eq!(Balances::locks(4), vec![the_lock(40)]); + assert_eq!(Balances::locks(5), vec![]); + assert_eq!(Balances::free_balance(42), 2); + + + fast_forward_to(5); + // No change yet... + assert_noop!(Democracy::remove_other_vote(Origin::signed(1), 4, r), Error::::NoPermission); + assert_ok!(Democracy::unlock(Origin::signed(1), 4)); + assert_eq!(Balances::locks(4), vec![the_lock(40)]); + fast_forward_to(6); + // 4 should now be able to reap and unlock + assert_ok!(Democracy::remove_other_vote(Origin::signed(1), 4, r)); + assert_ok!(Democracy::unlock(Origin::signed(1), 4)); + assert_eq!(Balances::locks(4), vec![]); + + fast_forward_to(9); + assert_noop!(Democracy::remove_other_vote(Origin::signed(1), 3, r), Error::::NoPermission); + assert_ok!(Democracy::unlock(Origin::signed(1), 3)); + assert_eq!(Balances::locks(3), vec![the_lock(30)]); + fast_forward_to(10); + assert_ok!(Democracy::remove_other_vote(Origin::signed(1), 3, r)); + assert_ok!(Democracy::unlock(Origin::signed(1), 3)); + assert_eq!(Balances::locks(3), vec![]); + + // 2 doesn't need to reap_vote here because it was already done before. + fast_forward_to(17); + assert_ok!(Democracy::unlock(Origin::signed(1), 2)); + assert_eq!(Balances::locks(2), vec![the_lock(20)]); + fast_forward_to(18); + assert_ok!(Democracy::unlock(Origin::signed(1), 2)); + assert_eq!(Balances::locks(2), vec![]); + }); +} + +#[test] +fn no_locks_without_conviction_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 0, + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(0, 10))); + + fast_forward_to(2); + + assert_eq!(Balances::free_balance(42), 2); + assert_ok!(Democracy::remove_other_vote(Origin::signed(2), 1, r)); + assert_ok!(Democracy::unlock(Origin::signed(2), 1)); + assert_eq!(Balances::locks(1), vec![]); + }); +} + +#[test] +fn lock_voting_should_work_with_delegation() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, nay(5, 10))); + assert_ok!(Democracy::vote(Origin::signed(2), r, aye(4, 20))); + assert_ok!(Democracy::vote(Origin::signed(3), r, aye(3, 30))); + assert_ok!(Democracy::delegate(Origin::signed(4), 2, Conviction::Locked2x, 40)); + assert_ok!(Democracy::vote(Origin::signed(5), r, nay(1, 50))); + + assert_eq!(tally(r), Tally { ayes: 250, nays: 100, turnout: 150 }); + + next_block(); + next_block(); + + assert_eq!(Balances::free_balance(42), 2); + }); +} + +fn setup_three_referenda() -> (u32, u32, u32) { + System::set_block_number(0); + let r1 = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SimpleMajority, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(5), r1, aye(4, 10))); + + let r2 = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SimpleMajority, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(5), r2, aye(3, 20))); + + let r3 = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SimpleMajority, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(5), r3, aye(2, 50))); + + fast_forward_to(2); + + (r1, r2, r3) +} + +#[test] +fn prior_lockvotes_should_be_enforced() { + new_test_ext().execute_with(|| { + let r = setup_three_referenda(); + // r.0 locked 10 until #18. + // r.1 locked 20 until #10. + // r.2 locked 50 until #6. + + fast_forward_to(5); + assert_noop!(Democracy::remove_other_vote(Origin::signed(1), 5, r.2), Error::::NoPermission); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![the_lock(50)]); + fast_forward_to(6); + assert_ok!(Democracy::remove_other_vote(Origin::signed(1), 5, r.2)); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![the_lock(20)]); + fast_forward_to(9); + assert_noop!(Democracy::remove_other_vote(Origin::signed(1), 5, r.1), Error::::NoPermission); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![the_lock(20)]); + fast_forward_to(10); + assert_ok!(Democracy::remove_other_vote(Origin::signed(1), 5, r.1)); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![the_lock(10)]); + fast_forward_to(17); + assert_noop!(Democracy::remove_other_vote(Origin::signed(1), 5, r.0), Error::::NoPermission); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![the_lock(10)]); + fast_forward_to(18); + assert_ok!(Democracy::remove_other_vote(Origin::signed(1), 5, r.0)); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![]); + }); +} + +#[test] +fn single_consolidation_of_lockvotes_should_work_as_before() { + new_test_ext().execute_with(|| { + let r = setup_three_referenda(); + // r.0 locked 10 until #18. + // r.1 locked 20 until #10. + // r.2 locked 50 until #6. + + fast_forward_to(5); + assert_ok!(Democracy::remove_vote(Origin::signed(5), r.2)); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![the_lock(50)]); + fast_forward_to(6); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![the_lock(20)]); + + fast_forward_to(9); + assert_ok!(Democracy::remove_vote(Origin::signed(5), r.1)); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![the_lock(20)]); + fast_forward_to(10); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![the_lock(10)]); + + fast_forward_to(17); + assert_ok!(Democracy::remove_vote(Origin::signed(5), r.0)); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![the_lock(10)]); + fast_forward_to(18); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![]); + }); +} + +#[test] +fn multi_consolidation_of_lockvotes_should_be_conservative() { + new_test_ext().execute_with(|| { + let r = setup_three_referenda(); + // r.0 locked 10 until #18. + // r.1 locked 20 until #10. + // r.2 locked 50 until #6. + + assert_ok!(Democracy::remove_vote(Origin::signed(5), r.2)); + assert_ok!(Democracy::remove_vote(Origin::signed(5), r.1)); + assert_ok!(Democracy::remove_vote(Origin::signed(5), r.0)); + + fast_forward_to(6); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert!(Balances::locks(5)[0].amount >= 20); + + fast_forward_to(10); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert!(Balances::locks(5)[0].amount >= 10); + + fast_forward_to(18); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![]); + }); +} + +#[test] +fn locks_should_persist_from_voting_to_delegation() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SimpleMajority, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(5), r, aye(4, 10))); + fast_forward_to(2); + assert_ok!(Democracy::remove_vote(Origin::signed(5), r)); + // locked 10 until #18. + + assert_ok!(Democracy::delegate(Origin::signed(5), 1, Conviction::Locked3x, 20)); + // locked 20. + assert!(Balances::locks(5)[0].amount == 20); + + assert_ok!(Democracy::undelegate(Origin::signed(5))); + // locked 20 until #10 + + fast_forward_to(9); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert!(Balances::locks(5)[0].amount == 20); + + fast_forward_to(10); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert!(Balances::locks(5)[0].amount >= 10); + + fast_forward_to(17); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert!(Balances::locks(5)[0].amount >= 10); + + fast_forward_to(18); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![]); + }); +} + +#[test] +fn locks_should_persist_from_delegation_to_voting() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + assert_ok!(Democracy::delegate(Origin::signed(5), 1, Conviction::Locked5x, 5)); + assert_ok!(Democracy::undelegate(Origin::signed(5))); + // locked 5 until #32 + + let r = setup_three_referenda(); + // r.0 locked 10 until #18. + // r.1 locked 20 until #10. + // r.2 locked 50 until #6. + + assert_ok!(Democracy::remove_vote(Origin::signed(5), r.2)); + assert_ok!(Democracy::remove_vote(Origin::signed(5), r.1)); + assert_ok!(Democracy::remove_vote(Origin::signed(5), r.0)); + + fast_forward_to(6); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert!(Balances::locks(5)[0].amount >= 20); + + fast_forward_to(10); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert!(Balances::locks(5)[0].amount >= 10); + + fast_forward_to(18); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert!(Balances::locks(5)[0].amount >= 5); + + fast_forward_to(32); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![]); + }); +} diff --git a/frame/democracy/src/tests/preimage.rs b/frame/democracy/src/tests/preimage.rs new file mode 100644 index 0000000000..1fb805f726 --- /dev/null +++ b/frame/democracy/src/tests/preimage.rs @@ -0,0 +1,164 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The preimage tests. + +use super::*; + +#[test] +fn missing_preimage_should_fail() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + + next_block(); + next_block(); + + assert_eq!(Balances::free_balance(42), 0); + }); +} + +#[test] +fn preimage_deposit_should_be_required_and_returned() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + // fee of 100 is too much. + PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 100); + assert_noop!( + Democracy::note_preimage(Origin::signed(6), vec![0; 500]), + BalancesError::::InsufficientBalance, + ); + // fee of 1 is reasonable. + PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + + assert_eq!(Balances::reserved_balance(6), 12); + + next_block(); + next_block(); + + assert_eq!(Balances::reserved_balance(6), 0); + assert_eq!(Balances::free_balance(6), 60); + assert_eq!(Balances::free_balance(42), 2); + }); +} + +#[test] +fn preimage_deposit_should_be_reapable_earlier_by_owner() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); + assert_ok!(Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2))); + + assert_eq!(Balances::reserved_balance(6), 12); + + next_block(); + assert_noop!( + Democracy::reap_preimage(Origin::signed(6), set_balance_proposal_hash(2)), + Error::::TooEarly + ); + next_block(); + assert_ok!(Democracy::reap_preimage(Origin::signed(6), set_balance_proposal_hash(2))); + + assert_eq!(Balances::free_balance(6), 60); + assert_eq!(Balances::reserved_balance(6), 0); + }); +} + +#[test] +fn preimage_deposit_should_be_reapable() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + assert_noop!( + Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2)), + Error::::PreimageMissing + ); + + PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); + assert_ok!(Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2))); + assert_eq!(Balances::reserved_balance(6), 12); + + next_block(); + next_block(); + next_block(); + assert_noop!( + Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2)), + Error::::TooEarly + ); + + next_block(); + assert_ok!(Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2))); + assert_eq!(Balances::reserved_balance(6), 0); + assert_eq!(Balances::free_balance(6), 48); + assert_eq!(Balances::free_balance(5), 62); + }); +} + +#[test] +fn noting_imminent_preimage_for_free_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); + + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash(2), + VoteThreshold::SuperMajorityApprove, + 1 + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + + assert_noop!( + Democracy::note_imminent_preimage(Origin::signed(7), set_balance_proposal(2)), + Error::::NotImminent + ); + + next_block(); + + // Now we're in the dispatch queue it's all good. + assert_ok!(Democracy::note_imminent_preimage(Origin::signed(7), set_balance_proposal(2))); + + next_block(); + + assert_eq!(Balances::free_balance(42), 2); + }); +} + +#[test] +fn reaping_imminent_preimage_should_fail() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let h = set_balance_proposal_hash_and_note(2); + let r = Democracy::inject_referendum(3, h, VoteThreshold::SuperMajorityApprove, 1); + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + next_block(); + next_block(); + // now imminent. + assert_noop!(Democracy::reap_preimage(Origin::signed(6), h), Error::::Imminent); + }); +} diff --git a/frame/democracy/src/tests/proxying.rs b/frame/democracy/src/tests/proxying.rs new file mode 100644 index 0000000000..412adf6be0 --- /dev/null +++ b/frame/democracy/src/tests/proxying.rs @@ -0,0 +1,104 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The tests for functionality concerning proxying. + +use super::*; + +#[test] +fn proxy_should_work() { + new_test_ext().execute_with(|| { + assert_eq!(Democracy::proxy(10), None); + assert!(System::allow_death(&10)); + + assert_noop!(Democracy::activate_proxy(Origin::signed(1), 10), Error::::NotOpen); + + assert_ok!(Democracy::open_proxy(Origin::signed(10), 1)); + assert!(!System::allow_death(&10)); + assert_eq!(Democracy::proxy(10), Some(ProxyState::Open(1))); + + assert_noop!(Democracy::activate_proxy(Origin::signed(2), 10), Error::::WrongOpen); + assert_ok!(Democracy::activate_proxy(Origin::signed(1), 10)); + assert_eq!(Democracy::proxy(10), Some(ProxyState::Active(1))); + + // Can't set when already set. + assert_noop!(Democracy::activate_proxy(Origin::signed(2), 10), Error::::AlreadyProxy); + + // But this works because 11 isn't proxying. + assert_ok!(Democracy::open_proxy(Origin::signed(11), 2)); + assert_ok!(Democracy::activate_proxy(Origin::signed(2), 11)); + assert_eq!(Democracy::proxy(10), Some(ProxyState::Active(1))); + assert_eq!(Democracy::proxy(11), Some(ProxyState::Active(2))); + + // 2 cannot fire 1's proxy: + assert_noop!(Democracy::deactivate_proxy(Origin::signed(2), 10), Error::::WrongProxy); + + // 1 deactivates their proxy: + assert_ok!(Democracy::deactivate_proxy(Origin::signed(1), 10)); + assert_eq!(Democracy::proxy(10), Some(ProxyState::Open(1))); + // but the proxy account cannot be killed until the proxy is closed. + assert!(!System::allow_death(&10)); + + // and then 10 closes it completely: + assert_ok!(Democracy::close_proxy(Origin::signed(10))); + assert_eq!(Democracy::proxy(10), None); + assert!(System::allow_death(&10)); + + // 11 just closes without 2's "permission". + assert_ok!(Democracy::close_proxy(Origin::signed(11))); + assert_eq!(Democracy::proxy(11), None); + assert!(System::allow_death(&11)); + }); +} + +#[test] +fn voting_and_removing_votes_should_work_with_proxy() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + assert_ok!(propose_set_balance_and_note(1, 2, 1)); + + fast_forward_to(2); + let r = 0; + assert_ok!(Democracy::open_proxy(Origin::signed(10), 1)); + assert_ok!(Democracy::activate_proxy(Origin::signed(1), 10)); + + assert_ok!(Democracy::proxy_vote(Origin::signed(10), r, aye(1))); + assert_eq!(tally(r), Tally { ayes: 1, nays: 0, turnout: 10 }); + + assert_ok!(Democracy::proxy_remove_vote(Origin::signed(10), r)); + assert_eq!(tally(r), Tally { ayes: 0, nays: 0, turnout: 0 }); + }); +} + +#[test] +fn delegation_and_undelegation_should_work_with_proxy() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + assert_ok!(propose_set_balance_and_note(1, 2, 1)); + fast_forward_to(2); + let r = 0; + assert_ok!(Democracy::open_proxy(Origin::signed(10), 1)); + assert_ok!(Democracy::activate_proxy(Origin::signed(1), 10)); + assert_ok!(Democracy::vote(Origin::signed(2), r, aye(2))); + + assert_ok!(Democracy::proxy_delegate(Origin::signed(10), 2, Conviction::None, 10)); + assert_eq!(tally(r), Tally { ayes: 3, nays: 0, turnout: 30 }); + + assert_ok!(Democracy::proxy_undelegate(Origin::signed(10))); + assert_eq!(tally(r), Tally { ayes: 2, nays: 0, turnout: 20 }); + }); +} + diff --git a/frame/democracy/src/tests/public_proposals.rs b/frame/democracy/src/tests/public_proposals.rs new file mode 100644 index 0000000000..ef68714601 --- /dev/null +++ b/frame/democracy/src/tests/public_proposals.rs @@ -0,0 +1,104 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The tests for the public proposal queue. + +use super::*; + +#[test] +fn backing_for_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + assert_ok!(propose_set_balance_and_note(1, 2, 2)); + assert_ok!(propose_set_balance_and_note(1, 4, 4)); + assert_ok!(propose_set_balance_and_note(1, 3, 3)); + assert_eq!(Democracy::backing_for(0), Some(2)); + assert_eq!(Democracy::backing_for(1), Some(4)); + assert_eq!(Democracy::backing_for(2), Some(3)); + }); +} + +#[test] +fn deposit_for_proposals_should_be_taken() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + assert_ok!(propose_set_balance_and_note(1, 2, 5)); + assert_ok!(Democracy::second(Origin::signed(2), 0)); + assert_ok!(Democracy::second(Origin::signed(5), 0)); + assert_ok!(Democracy::second(Origin::signed(5), 0)); + assert_ok!(Democracy::second(Origin::signed(5), 0)); + assert_eq!(Balances::free_balance(1), 5); + assert_eq!(Balances::free_balance(2), 15); + assert_eq!(Balances::free_balance(5), 35); + }); +} + +#[test] +fn deposit_for_proposals_should_be_returned() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + assert_ok!(propose_set_balance_and_note(1, 2, 5)); + assert_ok!(Democracy::second(Origin::signed(2), 0)); + assert_ok!(Democracy::second(Origin::signed(5), 0)); + assert_ok!(Democracy::second(Origin::signed(5), 0)); + assert_ok!(Democracy::second(Origin::signed(5), 0)); + fast_forward_to(3); + assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::free_balance(2), 20); + assert_eq!(Balances::free_balance(5), 50); + }); +} + +#[test] +fn proposal_with_deposit_below_minimum_should_not_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + assert_noop!(propose_set_balance(1, 2, 0), Error::::ValueLow); + }); +} + +#[test] +fn poor_proposer_should_not_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + assert_noop!(propose_set_balance(1, 2, 11), BalancesError::::InsufficientBalance); + }); +} + +#[test] +fn poor_seconder_should_not_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + assert_ok!(propose_set_balance_and_note(2, 2, 11)); + assert_noop!(Democracy::second(Origin::signed(1), 0), BalancesError::::InsufficientBalance); + }); +} + +#[test] +fn runners_up_should_come_after() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + assert_ok!(propose_set_balance_and_note(1, 2, 2)); + assert_ok!(propose_set_balance_and_note(1, 4, 4)); + assert_ok!(propose_set_balance_and_note(1, 3, 3)); + fast_forward_to(2); + assert_ok!(Democracy::vote(Origin::signed(1), 0, aye(1))); + fast_forward_to(4); + assert_ok!(Democracy::vote(Origin::signed(1), 1, aye(1))); + fast_forward_to(6); + assert_ok!(Democracy::vote(Origin::signed(1), 2, aye(1))); + }); +} diff --git a/frame/democracy/src/tests/scheduling.rs b/frame/democracy/src/tests/scheduling.rs new file mode 100644 index 0000000000..81120ea5b5 --- /dev/null +++ b/frame/democracy/src/tests/scheduling.rs @@ -0,0 +1,115 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The tests for functionality concerning normal starting, ending and enacting of referenda. + +use super::*; + +#[test] +fn simple_passing_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + assert_eq!(tally(r), Tally { ayes: 1, nays: 0, turnout: 10 }); + next_block(); + next_block(); + assert_eq!(Balances::free_balance(42), 2); + }); +} + +#[test] +fn simple_failing_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, nay(1))); + assert_eq!(tally(r), Tally { ayes: 0, nays: 1, turnout: 10 }); + + next_block(); + next_block(); + + assert_eq!(Balances::free_balance(42), 0); + }); +} + +#[test] +fn ooo_inject_referendums_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let r1 = Democracy::inject_referendum( + 3, + set_balance_proposal_hash_and_note(3), + VoteThreshold::SuperMajorityApprove, + 0 + ); + let r2 = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + + assert_ok!(Democracy::vote(Origin::signed(1), r2, aye(1))); + assert_eq!(tally(r2), Tally { ayes: 1, nays: 0, turnout: 10 }); + + next_block(); + assert_eq!(Balances::free_balance(42), 2); + + assert_ok!(Democracy::vote(Origin::signed(1), r1, aye(1))); + assert_eq!(tally(r1), Tally { ayes: 1, nays: 0, turnout: 10 }); + + next_block(); + assert_eq!(Balances::free_balance(42), 3); + }); +} + +#[test] +fn delayed_enactment_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 1 + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + assert_ok!(Democracy::vote(Origin::signed(2), r, aye(2))); + assert_ok!(Democracy::vote(Origin::signed(3), r, aye(3))); + assert_ok!(Democracy::vote(Origin::signed(4), r, aye(4))); + assert_ok!(Democracy::vote(Origin::signed(5), r, aye(5))); + assert_ok!(Democracy::vote(Origin::signed(6), r, aye(6))); + + assert_eq!(tally(r), Tally { ayes: 21, nays: 0, turnout: 210 }); + + next_block(); + assert_eq!(Balances::free_balance(42), 0); + + next_block(); + assert_eq!(Balances::free_balance(42), 2); + }); +} diff --git a/frame/democracy/src/tests/voting.rs b/frame/democracy/src/tests/voting.rs new file mode 100644 index 0000000000..06fde99cbd --- /dev/null +++ b/frame/democracy/src/tests/voting.rs @@ -0,0 +1,170 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The tests for normal voting functionality. + +use super::*; + +#[test] +fn overvoting_should_fail() { + new_test_ext().execute_with(|| { + let r = begin_referendum(); + assert_noop!(Democracy::vote(Origin::signed(1), r, aye(2)), Error::::InsufficientFunds); + }); +} + +#[test] +fn split_voting_should_work() { + new_test_ext().execute_with(|| { + let r = begin_referendum(); + let v = AccountVote::Split { aye: 40, nay: 20 }; + assert_noop!(Democracy::vote(Origin::signed(5), r, v), Error::::InsufficientFunds); + let v = AccountVote::Split { aye: 30, nay: 20 }; + assert_ok!(Democracy::vote(Origin::signed(5), r, v)); + + assert_eq!(tally(r), Tally { ayes: 3, nays: 2, turnout: 50 }); + }); +} + +#[test] +fn split_vote_cancellation_should_work() { + new_test_ext().execute_with(|| { + let r = begin_referendum(); + let v = AccountVote::Split { aye: 30, nay: 20 }; + assert_ok!(Democracy::vote(Origin::signed(5), r, v)); + assert_ok!(Democracy::remove_vote(Origin::signed(5), r)); + assert_eq!(tally(r), Tally { ayes: 0, nays: 0, turnout: 0 }); + assert_ok!(Democracy::unlock(Origin::signed(5), 5)); + assert_eq!(Balances::locks(5), vec![]); + }); +} + +#[test] +fn single_proposal_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + assert_ok!(propose_set_balance_and_note(1, 2, 1)); + let r = 0; + assert!(Democracy::referendum_info(r).is_none()); + + // start of 2 => next referendum scheduled. + fast_forward_to(2); + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + + assert_eq!(Democracy::referendum_count(), 1); + assert_eq!( + Democracy::referendum_status(0), + Ok(ReferendumStatus { + end: 4, + proposal_hash: set_balance_proposal_hash_and_note(2), + threshold: VoteThreshold::SuperMajorityApprove, + delay: 2, + tally: Tally { ayes: 1, nays: 0, turnout: 10 }, + }) + ); + + fast_forward_to(3); + + // referendum still running + assert!(Democracy::referendum_status(0).is_ok()); + + // referendum runs during 2 and 3, ends @ start of 4. + fast_forward_to(4); + + assert!(Democracy::referendum_status(0).is_err()); + assert_eq!(Democracy::dispatch_queue(), vec![ + (6, set_balance_proposal_hash_and_note(2), 0) + ]); + + // referendum passes and wait another two blocks for enactment. + fast_forward_to(6); + + assert_eq!(Balances::free_balance(42), 2); + }); +} + +#[test] +fn controversial_voting_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + + assert_ok!(Democracy::vote(Origin::signed(1), r, big_aye(1))); + assert_ok!(Democracy::vote(Origin::signed(2), r, big_nay(2))); + assert_ok!(Democracy::vote(Origin::signed(3), r, big_nay(3))); + assert_ok!(Democracy::vote(Origin::signed(4), r, big_aye(4))); + assert_ok!(Democracy::vote(Origin::signed(5), r, big_nay(5))); + assert_ok!(Democracy::vote(Origin::signed(6), r, big_aye(6))); + + assert_eq!(tally(r), Tally { ayes: 110, nays: 100, turnout: 210 }); + + next_block(); + next_block(); + + assert_eq!(Balances::free_balance(42), 2); + }); +} + +#[test] +fn controversial_low_turnout_voting_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(5), r, big_nay(5))); + assert_ok!(Democracy::vote(Origin::signed(6), r, big_aye(6))); + + assert_eq!(tally(r), Tally { ayes: 60, nays: 50, turnout: 110 }); + + next_block(); + next_block(); + + assert_eq!(Balances::free_balance(42), 0); + }); +} + +#[test] +fn passing_low_turnout_voting_should_work() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(42), 0); + assert_eq!(Balances::total_issuance(), 210); + + System::set_block_number(1); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(4), r, big_aye(4))); + assert_ok!(Democracy::vote(Origin::signed(5), r, big_nay(5))); + assert_ok!(Democracy::vote(Origin::signed(6), r, big_aye(6))); + assert_eq!(tally(r), Tally { ayes: 100, nays: 50, turnout: 150 }); + + next_block(); + next_block(); + assert_eq!(Balances::free_balance(42), 2); + }); +} diff --git a/frame/democracy/src/types.rs b/frame/democracy/src/types.rs new file mode 100644 index 0000000000..7a145701e9 --- /dev/null +++ b/frame/democracy/src/types.rs @@ -0,0 +1,217 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Miscellaneous additional datatypes. + +use codec::{Encode, Decode}; +use sp_runtime::RuntimeDebug; +use sp_runtime::traits::{Zero, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, Saturating}; +use crate::{Vote, VoteThreshold, AccountVote, Conviction}; + +/// Info regarding an ongoing referendum. +#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, RuntimeDebug)] +pub struct Tally { + /// The number of aye votes, expressed in terms of post-conviction lock-vote. + pub (crate) ayes: Balance, + /// The number of nay votes, expressed in terms of post-conviction lock-vote. + pub (crate) nays: Balance, + /// The amount of funds currently expressing its opinion. Pre-conviction. + pub (crate) turnout: Balance, +} + +/// Amount of votes and capital placed in delegation for an account. +#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug)] +pub struct Delegations { + /// The number of votes (this is post-conviction). + pub (crate) votes: Balance, + /// The amount of raw capital, used for the turnout. + pub (crate) capital: Balance, +} + +impl Saturating for Delegations { + fn saturating_add(self, o: Self) -> Self { + Self { + votes: self.votes.saturating_add(o.votes), + capital: self.capital.saturating_add(o.capital), + } + } + + fn saturating_sub(self, o: Self) -> Self { + Self { + votes: self.votes.saturating_sub(o.votes), + capital: self.capital.saturating_sub(o.capital), + } + } + + fn saturating_mul(self, o: Self) -> Self { + Self { + votes: self.votes.saturating_mul(o.votes), + capital: self.capital.saturating_mul(o.capital), + } + } +} + +impl< + Balance: From + Zero + Copy + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + Bounded + + Saturating +> Tally { + /// Create a new tally. + pub fn new( + vote: Vote, + balance: Balance, + ) -> Self { + let Delegations { votes, capital } = vote.conviction.votes(balance); + Self { + ayes: if vote.aye { votes } else { Zero::zero() }, + nays: if vote.aye { Zero::zero() } else { votes }, + turnout: capital, + } + } + + /// Add an account's vote into the tally. + pub fn add( + &mut self, + vote: AccountVote, + ) -> Option<()> { + match vote { + AccountVote::Standard { vote, balance } => { + let Delegations { votes, capital } = vote.conviction.votes(balance); + self.turnout = self.turnout.checked_add(&capital)?; + match vote.aye { + true => self.ayes = self.ayes.checked_add(&votes)?, + false => self.nays = self.nays.checked_add(&votes)?, + } + } + AccountVote::Split { aye, nay } => { + let aye = Conviction::None.votes(aye); + let nay = Conviction::None.votes(nay); + self.turnout = self.turnout.checked_add(&aye.capital)?.checked_add(&nay.capital)?; + self.ayes = self.ayes.checked_add(&aye.votes)?; + self.nays = self.nays.checked_add(&nay.votes)?; + } + } + Some(()) + } + + /// Remove an account's vote from the tally. + pub fn remove( + &mut self, + vote: AccountVote, + ) -> Option<()> { + match vote { + AccountVote::Standard { vote, balance } => { + let Delegations { votes, capital } = vote.conviction.votes(balance); + self.turnout = self.turnout.checked_sub(&capital)?; + match vote.aye { + true => self.ayes = self.ayes.checked_sub(&votes)?, + false => self.nays = self.nays.checked_sub(&votes)?, + } + } + AccountVote::Split { aye, nay } => { + let aye = Conviction::None.votes(aye); + let nay = Conviction::None.votes(nay); + self.turnout = self.turnout.checked_sub(&aye.capital)?.checked_sub(&nay.capital)?; + self.ayes = self.ayes.checked_sub(&aye.votes)?; + self.nays = self.nays.checked_sub(&nay.votes)?; + } + } + Some(()) + } + + /// Increment some amount of votes. + pub fn increase(&mut self, approve: bool, delegations: Delegations) -> Option<()> { + self.turnout = self.turnout.saturating_add(delegations.capital); + match approve { + true => self.ayes = self.ayes.saturating_add(delegations.votes), + false => self.nays = self.nays.saturating_add(delegations.votes), + } + Some(()) + } + + /// Decrement some amount of votes. + pub fn reduce(&mut self, approve: bool, delegations: Delegations) -> Option<()> { + self.turnout = self.turnout.saturating_sub(delegations.capital); + match approve { + true => self.ayes = self.ayes.saturating_sub(delegations.votes), + false => self.nays = self.nays.saturating_sub(delegations.votes), + } + Some(()) + } +} + +/// Info regarding an ongoing referendum. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] +pub struct ReferendumStatus { + /// When voting on this referendum will end. + pub (crate) end: BlockNumber, + /// The hash of the proposal being voted on. + pub (crate) proposal_hash: Hash, + /// The thresholding mechanism to determine whether it passed. + pub (crate) threshold: VoteThreshold, + /// The delay (in blocks) to wait after a successful referendum before deploying. + pub (crate) delay: BlockNumber, + /// The current tally of votes in this referendum. + pub (crate) tally: Tally, +} + +/// Info regarding a referendum, present or past. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] +pub enum ReferendumInfo { + /// Referendum is happening, the arg is the block number at which it will end. + Ongoing(ReferendumStatus), + /// Referendum finished at `end`, and has been `approved` or rejected. + Finished{approved: bool, end: BlockNumber}, +} + +impl ReferendumInfo { + /// Create a new instance. + pub fn new( + end: BlockNumber, + proposal_hash: Hash, + threshold: VoteThreshold, + delay: BlockNumber, + ) -> Self { + let s = ReferendumStatus{ end, proposal_hash, threshold, delay, tally: Tally::default() }; + ReferendumInfo::Ongoing(s) + } +} + +/// State of a proxy voting account. +#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] +pub enum ProxyState { + /// Account is open to becoming a proxy but is not yet assigned. + Open(AccountId), + /// Account is actively being a proxy. + Active(AccountId), +} + +impl ProxyState { + pub (crate) fn as_active(self) -> Option { + match self { + ProxyState::Active(a) => Some(a), + ProxyState::Open(_) => None, + } + } +} + +/// Whether an `unvote` operation is able to make actions that are not strictly always in the +/// interest of an account. +pub enum UnvoteScope { + /// Permitted to do everything. + Any, + /// Permitted to do only the changes that do not need the owner's permission. + OnlyExpired, +} diff --git a/frame/democracy/src/vote.rs b/frame/democracy/src/vote.rs new file mode 100644 index 0000000000..a41eb342aa --- /dev/null +++ b/frame/democracy/src/vote.rs @@ -0,0 +1,181 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The vote datatype. + +use sp_std::{prelude::*, result::Result, convert::TryFrom}; +use codec::{Encode, EncodeLike, Decode, Output, Input}; +use sp_runtime::{RuntimeDebug, traits::{Saturating, Zero}}; +use crate::{Conviction, ReferendumIndex, Delegations}; + +/// A number of lock periods, plus a vote, one way or the other. +#[derive(Copy, Clone, Eq, PartialEq, Default, RuntimeDebug)] +pub struct Vote { + pub aye: bool, + pub conviction: Conviction, +} + +impl Encode for Vote { + fn encode_to(&self, output: &mut T) { + output.push_byte(u8::from(self.conviction) | if self.aye { 0b1000_0000 } else { 0 }); + } +} + +impl EncodeLike for Vote {} + +impl Decode for Vote { + fn decode(input: &mut I) -> Result { + let b = input.read_byte()?; + Ok(Vote { + aye: (b & 0b1000_0000) == 0b1000_0000, + conviction: Conviction::try_from(b & 0b0111_1111) + .map_err(|_| codec::Error::from("Invalid conviction"))?, + }) + } +} + +/// A vote for a referendum of a particular account. +#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, RuntimeDebug)] +pub enum AccountVote { + /// A standard vote, one-way (approve or reject) with a given amount of conviction. + Standard { vote: Vote, balance: Balance }, + /// A split vote with balances given for both ways, and with no conviction, useful for + /// parachains when voting. + Split { aye: Balance, nay: Balance }, +} + +impl AccountVote { + /// Returns `Some` of the lock periods that the account is locked for, assuming that the + /// referendum passed iff `approved` is `true`. + pub fn locked_if(self, approved: bool) -> Option<(u32, Balance)> { + // winning side: can only be removed after the lock period ends. + match self { + AccountVote::Standard { vote, balance } if vote.aye == approved => + Some((vote.conviction.lock_periods(), balance)), + _ => None, + } + } + + /// The total balance involved in this vote. + pub fn balance(self) -> Balance { + match self { + AccountVote::Standard { balance, .. } => balance, + AccountVote::Split { aye, nay } => aye.saturating_add(nay), + } + } + + /// Returns `Some` with whether the vote is an aye vote if it is standard, otherwise `None` if + /// it is split. + pub fn as_standard(self) -> Option { + match self { + AccountVote::Standard { vote, .. } => Some(vote.aye), + _ => None, + } + } +} + +/// A "prior" lock, i.e. a lock for some now-forgotten reason. +#[derive(Encode, Decode, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)] +pub struct PriorLock(BlockNumber, Balance); + +impl PriorLock { + /// Accumulates an additional lock. + pub fn accumulate(&mut self, until: BlockNumber, amount: Balance) { + self.0 = self.0.max(until); + self.1 = self.1.max(amount); + } + + pub fn locked(&self) -> Balance { + self.1 + } + + pub fn rejig(&mut self, now: BlockNumber) { + if now >= self.0 { + self.0 = Zero::zero(); + self.1 = Zero::zero(); + } + } +} + +/// An indicator for what an account is doing; it can either be delegating or voting. +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug)] +pub enum Voting { + /// The account is voting directly. `delegations` is the total amount of post-conviction voting + /// weight that it controls from those that have delegated to it. + Direct { + /// The current votes of the account. + votes: Vec<(ReferendumIndex, AccountVote)>, + /// The total amount of delegations that this account has received. + delegations: Delegations, + /// Any pre-existing locks from past voting/delegating activity. + prior: PriorLock, + }, + /// The account is delegating `balance` of its balance to a `target` account with `conviction`. + Delegating { + balance: Balance, + target: AccountId, + conviction: Conviction, + /// The total amount of delegations that this account has received. + delegations: Delegations, + /// Any pre-existing locks from past voting/delegating activity. + prior: PriorLock, + }, +} + +impl Default for Voting { + fn default() -> Self { + Voting::Direct { + votes: Vec::new(), + delegations: Default::default(), + prior: PriorLock(Zero::zero(), Default::default()), + } + } +} + +impl< + Balance: Saturating + Ord + Zero + Copy, + BlockNumber: Ord + Copy + Zero, + AccountId, +> Voting { + pub fn rejig(&mut self, now: BlockNumber) { + match self { + Voting::Direct { prior, .. } => prior, + Voting::Delegating { prior, .. } => prior, + }.rejig(now); + } + + /// The amount of this account's balance that much currently be locked due to voting. + pub fn locked_balance(&self) -> Balance { + match self { + Voting::Direct { votes, prior, .. } => votes.iter() + .map(|i| i.1.balance()) + .fold(prior.locked(), |a, i| a.max(i)), + Voting::Delegating { balance, .. } => *balance, + } + } + + pub fn set_common(&mut self, + delegations: Delegations, + prior: PriorLock + ) { + let (d, p) = match self { + Voting::Direct { ref mut delegations, ref mut prior, .. } => (delegations, prior), + Voting::Delegating { ref mut delegations, ref mut prior, .. } => (delegations, prior), + }; + *d = delegations; + *p = prior; + } +} diff --git a/frame/democracy/src/vote_threshold.rs b/frame/democracy/src/vote_threshold.rs index 46612af09a..fd976b4400 100644 --- a/frame/democracy/src/vote_threshold.rs +++ b/frame/democracy/src/vote_threshold.rs @@ -21,6 +21,7 @@ use serde::{Serialize, Deserialize}; use codec::{Encode, Decode}; use sp_runtime::traits::{Zero, IntegerSquareRoot}; use sp_std::ops::{Add, Mul, Div, Rem}; +use crate::Tally; /// A means of determining if a vote is past pass threshold. #[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, sp_runtime::RuntimeDebug)] @@ -35,10 +36,9 @@ pub enum VoteThreshold { } pub trait Approved { - /// Given `approve` votes for and `against` votes against from a total electorate size of - /// `electorate` (`electorate - (approve + against)` are abstainers), then returns true if the - /// overall outcome is in favor of approval. - fn approved(&self, approve: Balance, against: Balance, voters: Balance, electorate: Balance) -> bool; + /// Given a `tally` of votes and a total size of `electorate`, this returns `true` if the + /// overall outcome is in favor of approval according to `self`'s threshold method. + fn approved(&self, tally: Tally, electorate: Balance) -> bool; } /// Return `true` iff `n1 / d1 < n2 / d2`. `d1` and `d2` may not be zero. @@ -69,23 +69,21 @@ fn compare_rationals + Div + Rem + Mul + Div + Rem + Copy> Approved for VoteThreshold { - /// Given `approve` votes for and `against` votes against from a total electorate size of - /// `electorate` of whom `voters` voted (`electorate - voters` are abstainers) then returns true if the - /// overall outcome is in favor of approval. - /// - /// We assume each *voter* may cast more than one *vote*, hence `voters` is not necessarily equal to - /// `approve + against`. - fn approved(&self, approve: Balance, against: Balance, voters: Balance, electorate: Balance) -> bool { - let sqrt_voters = voters.integer_sqrt(); +impl< + Balance: IntegerSquareRoot + Zero + Ord + Add + + Mul + Div + + Rem + Copy, +> Approved for VoteThreshold { + fn approved(&self, tally: Tally, electorate: Balance) -> bool { + let sqrt_voters = tally.turnout.integer_sqrt(); let sqrt_electorate = electorate.integer_sqrt(); if sqrt_voters.is_zero() { return false; } match *self { VoteThreshold::SuperMajorityApprove => - compare_rationals(against, sqrt_voters, approve, sqrt_electorate), + compare_rationals(tally.nays, sqrt_voters, tally.ayes, sqrt_electorate), VoteThreshold::SuperMajorityAgainst => - compare_rationals(against, sqrt_electorate, approve, sqrt_voters), - VoteThreshold::SimpleMajority => approve > against, + compare_rationals(tally.nays, sqrt_electorate, tally.ayes, sqrt_voters), + VoteThreshold::SimpleMajority => tally.ayes > tally.nays, } } } @@ -96,7 +94,7 @@ mod tests { #[test] fn should_work() { - assert_eq!(VoteThreshold::SuperMajorityApprove.approved(60, 50, 110, 210), false); - assert_eq!(VoteThreshold::SuperMajorityApprove.approved(100, 50, 150, 210), true); + assert!(!VoteThreshold::SuperMajorityApprove.approved(Tally{ayes: 60, nays: 50, turnout: 110}, 210)); + assert!(VoteThreshold::SuperMajorityApprove.approved(Tally{ayes: 100, nays: 50, turnout: 150}, 210)); } } diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 8fe32cbda9..f242efecc4 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -72,7 +72,7 @@ pub use self::hash::{ }; pub use self::storage::{ StorageValue, StorageMap, StorageDoubleMap, StoragePrefixedMap, IterableStorageMap, - IterableStorageDoubleMap, + IterableStorageDoubleMap, migration }; pub use self::dispatch::{Parameter, Callable, IsSubType}; pub use sp_runtime::{self, ConsensusEngineId, print, traits::Printable}; diff --git a/frame/support/src/storage/migration.rs b/frame/support/src/storage/migration.rs index df9758ba69..67df4d04c0 100644 --- a/frame/support/src/storage/migration.rs +++ b/frame/support/src/storage/migration.rs @@ -19,6 +19,7 @@ use sp_std::prelude::*; use codec::{Encode, Decode}; use crate::{StorageHasher, Twox128}; +use crate::hash::ReversibleStorageHasher; /// Utility to iterate through raw items in storage. pub struct StorageIterator { @@ -78,6 +79,72 @@ impl Iterator for StorageIterator { } } +/// Utility to iterate through raw items in storage. +pub struct StorageKeyIterator { + prefix: Vec, + previous_key: Vec, + drain: bool, + _phantom: ::sp_std::marker::PhantomData<(K, T, H)>, +} + +impl StorageKeyIterator { + /// Construct iterator to iterate over map items in `module` for the map called `item`. + pub fn new(module: &[u8], item: &[u8]) -> Self { + Self::with_suffix(module, item, &[][..]) + } + + /// Construct iterator to iterate over map items in `module` for the map called `item`. + pub fn with_suffix(module: &[u8], item: &[u8], suffix: &[u8]) -> Self { + let mut prefix = Vec::new(); + prefix.extend_from_slice(&Twox128::hash(module)); + prefix.extend_from_slice(&Twox128::hash(item)); + prefix.extend_from_slice(suffix); + let previous_key = prefix.clone(); + Self { prefix, previous_key, drain: false, _phantom: Default::default() } + } + + /// Mutate this iterator into a draining iterator; items iterated are removed from storage. + pub fn drain(mut self) -> Self { + self.drain = true; + self + } +} + +impl Iterator + for StorageKeyIterator +{ + type Item = (K, T); + + fn next(&mut self) -> Option<(K, T)> { + loop { + let maybe_next = sp_io::storage::next_key(&self.previous_key) + .filter(|n| n.starts_with(&self.prefix)); + break match maybe_next { + Some(next) => { + self.previous_key = next.clone(); + let mut key_material = H::reverse(&next[self.prefix.len()..]); + match K::decode(&mut key_material) { + Ok(key) => { + let maybe_value = frame_support::storage::unhashed::get::(&next); + match maybe_value { + Some(value) => { + if self.drain { + frame_support::storage::unhashed::kill(&next); + } + Some((key, value)) + } + None => continue, + } + } + Err(_) => continue, + } + } + None => None, + } + } + } +} + /// Get a particular value in storage by the `module`, the map's `item` name and the key `hash`. pub fn have_storage_value(module: &[u8], item: &[u8], hash: &[u8]) -> bool { get_storage_value::<()>(module, item, hash).is_some() @@ -109,3 +176,12 @@ pub fn put_storage_value(module: &[u8], item: &[u8], hash: &[u8], val key[32..].copy_from_slice(hash); frame_support::storage::unhashed::put(&key, &value); } + +/// Get a particular value in storage by the `module`, the map's `item` name and the key `hash`. +pub fn remove_storage_prefix(module: &[u8], item: &[u8], hash: &[u8]) { + let mut key = vec![0u8; 32 + hash.len()]; + key[0..16].copy_from_slice(&Twox128::hash(module)); + key[16..32].copy_from_slice(&Twox128::hash(item)); + key[32..].copy_from_slice(hash); + frame_support::storage::unhashed::kill_prefix(&key) +} -- GitLab From 42ec6948af7ee2773d95e68bdf04d89abe2f716b Mon Sep 17 00:00:00 2001 From: ddorgan Date: Sat, 21 Mar 2020 15:49:51 +0000 Subject: [PATCH 040/300] Make pushing consensus message loglevel trace (#5342) --- client/network-gossip/src/state_machine.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index a800f1e3aa..0eff93653c 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -20,7 +20,7 @@ use std::collections::{HashMap, HashSet, hash_map::Entry}; use std::sync::Arc; use std::iter; use std::time; -use log::{trace, debug}; +use log::trace; use futures::channel::mpsc; use lru::LruCache; use libp2p::PeerId; @@ -399,7 +399,7 @@ impl ConsensusGossip { if let Some(ref mut peer) = self.peers.get_mut(&who) { peer.known_messages.insert(message_hash); if let Entry::Occupied(mut entry) = self.live_message_sinks.entry((engine_id, topic)) { - debug!(target: "gossip", "Pushing consensus message to sinks for {}.", topic); + trace!(target: "gossip", "Pushing consensus message to sinks for {}.", topic); entry.get_mut().retain(|sink| { if let Err(e) = sink.unbounded_send(TopicNotification { message: message.clone(), -- GitLab From 5039ef8f2c1872f075bf607443158f36b3497410 Mon Sep 17 00:00:00 2001 From: Stanislav Tkach Date: Sat, 21 Mar 2020 23:17:06 +0200 Subject: [PATCH 041/300] Rename ExecutionContext::parent to caller (#5285) --- frame/contracts/src/exec.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index d550756730..402622331d 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -289,7 +289,7 @@ pub enum DeferredAction { } pub struct ExecutionContext<'a, T: Trait + 'a, V, L> { - pub parent: Option<&'a ExecutionContext<'a, T, V, L>>, + pub caller: Option<&'a ExecutionContext<'a, T, V, L>>, pub self_account: T::AccountId, pub self_trie_id: Option, pub overlay: OverlayAccountDb<'a, T>, @@ -314,7 +314,7 @@ where /// account (not a contract). pub fn top_level(origin: T::AccountId, cfg: &'a Config, vm: &'a V, loader: &'a L) -> Self { ExecutionContext { - parent: None, + caller: None, self_trie_id: None, self_account: origin, overlay: OverlayAccountDb::::new(&DirectAccountDb), @@ -332,7 +332,7 @@ where -> ExecutionContext<'b, T, V, L> { ExecutionContext { - parent: Some(self), + caller: Some(self), self_trie_id: trie_id, self_account: dest, overlay: OverlayAccountDb::new(&self.overlay), @@ -535,8 +535,8 @@ where ) -> Result<(), DispatchError> { let self_id = self.self_account.clone(); let value = self.overlay.get_balance(&self_id); - if let Some(parent) = self.parent { - if parent.is_live(&self_id) { + if let Some(caller) = self.caller { + if caller.is_live(&self_id) { return Err(DispatchError::Other( "Cannot terminate a contract that is present on the call stack", )); @@ -592,7 +592,7 @@ where /// stack, meaning it is in the middle of an execution. fn is_live(&self, account: &T::AccountId) -> bool { &self.self_account == account || - self.parent.map_or(false, |parent| parent.is_live(account)) + self.caller.map_or(false, |caller| caller.is_live(account)) } } -- GitLab From feac1d9bce3a3a94c731ed0c57a07edd8f2940d5 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Sun, 22 Mar 2020 20:37:40 +0100 Subject: [PATCH 042/300] deduplicate parity-util-mem (#5348) --- Cargo.lock | 53 +++++++++++++---------------------- primitives/trie/Cargo.toml | 4 +-- test-utils/runtime/Cargo.toml | 2 +- 3 files changed, 23 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7848d75c8b..22da38136f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2504,7 +2504,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cad096c6849b2ef027fabe35c4aed356d0e3d3f586d0a8361e5e17f1e50a7ce5" dependencies = [ - "parity-util-mem 0.6.0", + "parity-util-mem", "smallvec 1.2.0", ] @@ -2515,7 +2515,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4aa954d12cfac958822dfd77aab34f3eec71f103b918c4ab79ab59a36ee594ea" dependencies = [ "kvdb", - "parity-util-mem 0.6.0", + "parity-util-mem", "parking_lot 0.10.0", ] @@ -2531,7 +2531,7 @@ dependencies = [ "log 0.4.8", "num_cpus", "owning_ref", - "parity-util-mem 0.6.0", + "parity-util-mem", "parking_lot 0.10.0", "regex", "rocksdb", @@ -2549,7 +2549,7 @@ dependencies = [ "kvdb", "kvdb-memorydb", "log 0.4.8", - "parity-util-mem 0.6.0", + "parity-util-mem", "send_wrapper 0.3.0", "wasm-bindgen", "web-sys", @@ -3146,14 +3146,14 @@ dependencies = [ [[package]] name = "memory-db" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "198831fe8722331a395bc199a5d08efbc197497ef354cb4c77b969c02ffc0fc4" +checksum = "f58381b20ebe2c578e75dececd9da411414903415349548ccc46aac3209cdfbc" dependencies = [ "ahash", "hash-db", "hashbrown", - "parity-util-mem 0.5.2", + "parity-util-mem", ] [[package]] @@ -4644,19 +4644,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" -[[package]] -name = "parity-util-mem" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9344bc978467339b9ae688f9dcf279d1aaa0ccfc88e9a780c729b765a82d57d5" -dependencies = [ - "cfg-if", - "impl-trait-for-tuples", - "parity-util-mem-derive", - "parking_lot 0.10.0", - "winapi 0.3.8", -] - [[package]] name = "parity-util-mem" version = "0.6.0" @@ -5705,7 +5692,7 @@ dependencies = [ "lazy_static", "log 0.4.8", "names", - "parity-util-mem 0.6.0", + "parity-util-mem", "regex", "rpassword", "sc-client-api", @@ -5810,7 +5797,7 @@ dependencies = [ "linked-hash-map", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.6.0", + "parity-util-mem", "parking_lot 0.10.0", "quickcheck", "rand 0.7.3", @@ -6167,7 +6154,7 @@ dependencies = [ "ansi_term 0.12.1", "futures 0.3.4", "log 0.4.8", - "parity-util-mem 0.6.0", + "parity-util-mem", "sc-client-api", "sc-network", "sc-service", @@ -6435,7 +6422,7 @@ dependencies = [ "log 0.4.8", "parity-multiaddr", "parity-scale-codec", - "parity-util-mem 0.6.0", + "parity-util-mem", "parking_lot 0.10.0", "sc-chain-spec", "sc-client", @@ -6500,7 +6487,7 @@ dependencies = [ "env_logger 0.7.1", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.6.0", + "parity-util-mem", "parity-util-mem-derive", "parking_lot 0.10.0", "sc-client-api", @@ -6554,7 +6541,7 @@ dependencies = [ "linked-hash-map", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.6.0", + "parity-util-mem", "parking_lot 0.10.0", "serde", "sp-blockchain", @@ -6575,7 +6562,7 @@ dependencies = [ "futures-timer 2.0.2", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.6.0", + "parity-util-mem", "parking_lot 0.10.0", "sc-client-api", "sc-transaction-graph", @@ -7149,7 +7136,7 @@ dependencies = [ "log 0.4.8", "num-traits", "parity-scale-codec", - "parity-util-mem 0.6.0", + "parity-util-mem", "parking_lot 0.10.0", "pretty_assertions", "primitive-types", @@ -7296,7 +7283,7 @@ dependencies = [ "impl-trait-for-tuples", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.6.0", + "parity-util-mem", "paste", "rand 0.7.3", "serde", @@ -7442,7 +7429,7 @@ name = "sp-test-primitives" version = "2.0.0-dev" dependencies = [ "parity-scale-codec", - "parity-util-mem 0.6.0", + "parity-util-mem", "serde", "sp-application-crypto", "sp-core", @@ -7766,7 +7753,7 @@ dependencies = [ "pallet-babe", "pallet-timestamp", "parity-scale-codec", - "parity-util-mem 0.6.0", + "parity-util-mem", "sc-block-builder", "sc-client", "sc-executor", @@ -8479,9 +8466,9 @@ checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" [[package]] name = "trie-bench" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dcd9bac85703d8f974ee1e6dfe668784b105d3385c174ad729adb7427ad5d81" +checksum = "f105ed33e42b534284b691e804e909c42a8898afcf22896a32255c05a1a50488" dependencies = [ "criterion 0.2.11", "hash-db", diff --git a/primitives/trie/Cargo.toml b/primitives/trie/Cargo.toml index 15d0febe9a..446a2da111 100644 --- a/primitives/trie/Cargo.toml +++ b/primitives/trie/Cargo.toml @@ -19,11 +19,11 @@ sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" hash-db = { version = "0.15.2", default-features = false } trie-db = { version = "0.20.0", default-features = false } trie-root = { version = "0.16.0", default-features = false } -memory-db = { version = "0.19.0", default-features = false } +memory-db = { version = "0.20.0", default-features = false } sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } [dev-dependencies] -trie-bench = "0.20.0" +trie-bench = "0.21.0" trie-standardmap = "0.15.2" criterion = "0.2.11" hex-literal = "0.2.1" diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index 33470a20e2..0096d90083 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -20,7 +20,7 @@ frame-executive = { version = "2.0.0-alpha.4", default-features = false, path = sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } sp-keyring = { version = "2.0.0-alpha.4", optional = true, path = "../../primitives/keyring" } log = { version = "0.4.8", optional = true } -memory-db = { version = "0.19.0", default-features = false } +memory-db = { version = "0.20.0", default-features = false } sp-offchain = { path = "../../primitives/offchain", default-features = false, version = "2.0.0-alpha.4"} sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -- GitLab From 750cdd8af4e916cf74633825b1f7998a1a415eb1 Mon Sep 17 00:00:00 2001 From: cheme Date: Mon, 23 Mar 2020 10:00:50 +0100 Subject: [PATCH 043/300] Fix rpc test. --- client/rpc/src/state/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index 74455c99f6..57c91c1354 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -34,7 +34,7 @@ use substrate_test_runtime_client::{ const STORAGE_KEY: &[u8] = b"child"; fn prefixed_storage_key() -> PrefixedStorageKey { - let child_info = ChildInfo::new_default(&b":child_storage:default:child"[..]); + let child_info = ChildInfo::new_default(&STORAGE_KEY[..]); child_info.prefixed_storage_key() } -- GitLab From cc65f4483528b27012c446a590555869bb77b20a Mon Sep 17 00:00:00 2001 From: cheme Date: Mon, 23 Mar 2020 10:08:20 +0100 Subject: [PATCH 044/300] bump spec version --- bin/node/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index ccd2eba78f..ba219a1890 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 239, + spec_version: 240, impl_version: 0, apis: RUNTIME_API_VERSIONS, }; -- GitLab From 682ff1f9f0e4850cf385385b9ebe464ae70b87d8 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 23 Mar 2020 11:04:48 +0100 Subject: [PATCH 045/300] client/network-gossip/state_machine: Fix log message (#5350) A gossip validator returns `ValidationResult::Discard` for messages that should not be processed nor kept due to not being useful for the node. Examples are out-of-scope messages or messages with bad signatures. The corresponding log message did not reflect this, thus the update through this patch. One caveat is a finality grandpa neighbor packet. Given that the concept of neighbor packets is handled in the finality grandpa gossip validator only, valid neighbor packets are always discarded on the `client/network-gossip` layer. --- client/network-gossip/src/state_machine.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index 0eff93653c..e2d7ec45b5 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -353,8 +353,7 @@ impl ConsensusGossip { /// Handle an incoming message for topic by who via protocol. Discard message if topic already /// known, the message is old, its source peers isn't a registered peer or the connection to - /// them is broken. Return `Some(topic, message)` if it was added to the internal queue, `None` - /// in all other cases. + /// them is broken. pub fn on_incoming( &mut self, network: &mut dyn Network, @@ -421,7 +420,7 @@ impl ConsensusGossip { network.report_peer(who.clone(), rep::UNREGISTERED_TOPIC); } } else { - trace!(target:"gossip", "Handled valid one hop message from peer {}", who); + trace!(target:"gossip", "Discard message from peer {}", who); } } } -- GitLab From dd23d45c299261463e09ee1ecb6b7c819a8b2c02 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 23 Mar 2020 11:50:11 +0100 Subject: [PATCH 046/300] Rewrite reconnect_after_disconnect test (#5351) --- .../src/protocol/generic_proto/tests.rs | 81 ++++++++++--------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/client/network/src/protocol/generic_proto/tests.rs b/client/network/src/protocol/generic_proto/tests.rs index 632e06ec39..b63a725c07 100644 --- a/client/network/src/protocol/generic_proto/tests.rs +++ b/client/network/src/protocol/generic_proto/tests.rs @@ -345,13 +345,21 @@ fn reconnect_after_disconnect() { let mut service1_state = ServiceState::NotConnected; let mut service2_state = ServiceState::NotConnected; - // Run the events loops. - futures::executor::block_on(future::poll_fn(|cx| -> Poll> { + futures::executor::block_on(async move { loop { - let mut service1_not_ready = false; + // Grab next event from services. + let event = { + let s1 = service1.next(); + let s2 = service2.next(); + futures::pin_mut!(s1, s2); + match future::select(s1, s2).await { + future::Either::Left((ev, _)) => future::Either::Left(ev), + future::Either::Right((ev, _)) => future::Either::Right(ev), + } + }; - match service1.poll_next_unpin(cx) { - Poll::Ready(Some(GenericProtoOut::CustomProtocolOpen { .. })) => { + match event { + future::Either::Left(GenericProtoOut::CustomProtocolOpen { .. }) => { match service1_state { ServiceState::NotConnected => { service1_state = ServiceState::FirstConnec; @@ -363,19 +371,14 @@ fn reconnect_after_disconnect() { ServiceState::FirstConnec | ServiceState::ConnectedAgain => panic!(), } }, - Poll::Ready(Some(GenericProtoOut::CustomProtocolClosed { .. })) => { + future::Either::Left(GenericProtoOut::CustomProtocolClosed { .. }) => { match service1_state { ServiceState::FirstConnec => service1_state = ServiceState::Disconnected, ServiceState::ConnectedAgain| ServiceState::NotConnected | ServiceState::Disconnected => panic!(), } }, - Poll::Pending => service1_not_ready = true, - _ => panic!() - } - - match service2.poll_next_unpin(cx) { - Poll::Ready(Some(GenericProtoOut::CustomProtocolOpen { .. })) => { + future::Either::Right(GenericProtoOut::CustomProtocolOpen { .. }) => { match service2_state { ServiceState::NotConnected => { service2_state = ServiceState::FirstConnec; @@ -387,43 +390,43 @@ fn reconnect_after_disconnect() { ServiceState::FirstConnec | ServiceState::ConnectedAgain => panic!(), } }, - Poll::Ready(Some(GenericProtoOut::CustomProtocolClosed { .. })) => { + future::Either::Right(GenericProtoOut::CustomProtocolClosed { .. }) => { match service2_state { ServiceState::FirstConnec => service2_state = ServiceState::Disconnected, ServiceState::ConnectedAgain| ServiceState::NotConnected | ServiceState::Disconnected => panic!(), } }, - Poll::Pending if service1_not_ready => break, - Poll::Pending => {} - _ => panic!() + _ => {} } - } - if service1_state == ServiceState::ConnectedAgain && service2_state == ServiceState::ConnectedAgain { - Poll::Ready(Ok(())) - } else { - Poll::Pending - } - })).unwrap(); - - // Do a second 3-seconds run to make sure we don't get disconnected immediately again. - let mut delay = futures_timer::Delay::new(Duration::from_secs(3)); - futures::executor::block_on(future::poll_fn(|cx| -> Poll> { - match service1.poll_next_unpin(cx) { - Poll::Pending => {}, - _ => panic!() + if service1_state == ServiceState::ConnectedAgain && service2_state == ServiceState::ConnectedAgain { + break; + } } - match service2.poll_next_unpin(cx) { - Poll::Pending => {}, - _ => panic!() - } + // Now that the two services have disconnected and reconnected, wait for 3 seconds and + // check whether they're still connected. + let mut delay = futures_timer::Delay::new(Duration::from_secs(3)); - if let Poll::Ready(()) = delay.poll_unpin(cx) { - Poll::Ready(Ok(())) - } else { - Poll::Pending + loop { + // Grab next event from services. + let event = { + let s1 = service1.next(); + let s2 = service2.next(); + futures::pin_mut!(s1, s2); + match future::select(future::select(s1, s2), &mut delay).await { + future::Either::Right(_) => break, // success + future::Either::Left((future::Either::Left((ev, _)), _)) => ev, + future::Either::Left((future::Either::Right((ev, _)), _)) => ev, + } + }; + + match event { + GenericProtoOut::CustomProtocolOpen { .. } | + GenericProtoOut::CustomProtocolClosed { .. } => panic!(), + _ => {} + } } - })).unwrap(); + }); } -- GitLab From 8854e6a7aa133df03e8850873514aa75dcbed8ae Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Mon, 23 Mar 2020 11:52:44 +0100 Subject: [PATCH 047/300] Sensible way of selecting Prime member (#5346) * Calculate prime votes only during the election * Migration * Fix build, enable migration * Fix tests * Bump runtime version * Update frame/elections-phragmen/src/lib.rs Co-Authored-By: Marcio Diaz Co-authored-by: Marcio Diaz --- bin/node/runtime/src/lib.rs | 2 +- frame/elections-phragmen/src/lib.rs | 126 ++++++++++++++++++------- frame/staking/src/lib.rs | 12 ++- frame/support/src/storage/migration.rs | 9 ++ primitives/phragmen/src/lib.rs | 9 +- primitives/phragmen/src/mock.rs | 5 +- primitives/phragmen/src/tests.rs | 51 +++++----- 7 files changed, 135 insertions(+), 79 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index ccd2eba78f..ba219a1890 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 239, + spec_version: 240, impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index d1a3c6af5f..d74fb4bdcd 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -158,13 +158,11 @@ decl_storage! { /// The total number of vote rounds that have happened, excluding the upcoming one. pub ElectionRounds get(fn election_rounds): u32 = Zero::zero(); - /// Votes of a particular voter, with the round index of the votes. - pub VotesOf get(fn votes_of): map hasher(twox_64_concat) T::AccountId => Vec; - /// Locked stake of a voter. - pub StakeOf get(fn stake_of): map hasher(twox_64_concat) T::AccountId => BalanceOf; + /// Votes and locked stake of a particular voter. + pub Voting: map hasher(twox_64_concat) T::AccountId => (BalanceOf, Vec); - /// The present candidate list. Sorted based on account-id. A current member or a runner can - /// never enter this vector and is always implicitly assumed to be a candidate. + /// The present candidate list. Sorted based on account-id. A current member or runner-up + /// can never enter this vector and is always implicitly assumed to be a candidate. pub Candidates get(fn candidates): Vec; } } @@ -203,12 +201,32 @@ decl_error! { } } +mod migration { + use super::*; + use frame_support::{migration::{StorageKeyIterator, take_storage_item}, Twox64Concat}; + pub fn migrate() { + for (who, votes) in StorageKeyIterator + ::, Twox64Concat> + ::new(b"PhragmenElection", b"VotesOf") + .drain() + { + if let Some(stake) = take_storage_item::<_, BalanceOf, Twox64Concat>(b"PhragmenElection", b"StakeOf", &who) { + Voting::::insert(who, (stake, votes)); + } + } + } +} + decl_module! { pub struct Module for enum Call where origin: T::Origin { type Error = Error; fn deposit_event() = default; + fn on_runtime_upgrade() { + migration::migrate::(); + } + const CandidacyBond: BalanceOf = T::CandidacyBond::get(); const VotingBond: BalanceOf = T::VotingBond::get(); const DesiredMembers: u32 = T::DesiredMembers::get(); @@ -264,8 +282,8 @@ decl_module! { locked_balance, WithdrawReasons::except(WithdrawReason::TransactionPayment), ); - >::insert(&who, locked_balance); - >::insert(&who, votes); + + Voting::::insert(&who, (locked_balance, votes)); } /// Remove `origin` as a voter. This removes the lock and returns the bond. @@ -522,7 +540,7 @@ impl Module { /// /// State: O(1). fn is_voter(who: &T::AccountId) -> bool { - >::contains_key(who) + Voting::::contains_key(who) } /// Check if `who` is currently an active member. @@ -585,8 +603,7 @@ impl Module { /// lock. Optionally, it would also return the reserved voting bond if indicated by `unreserve`. fn do_remove_voter(who: &T::AccountId, unreserve: bool) { // remove storage and lock. - >::remove(who); - >::remove(who); + Voting::::remove(who); T::Currency::remove_lock(MODULE_ID, who); if unreserve { @@ -596,7 +613,12 @@ impl Module { /// The locked stake of a voter. fn locked_stake_of(who: &T::AccountId) -> BalanceOf { - Self::stake_of(who) + Voting::::get(who).0 + } + + /// The locked stake of a voter. + fn votes_of(who: &T::AccountId) -> Vec { + Voting::::get(who).1 } /// Check there's nothing to do this block. @@ -627,7 +649,7 @@ impl Module { let num_to_elect = desired_runners_up + desired_seats; let mut candidates = Self::candidates(); - // candidates who explicitly called `submit_candidacy`. Only these folks are at the risk of + // candidates who explicitly called `submit_candidacy`. Only these folks are at risk of // losing their bond. let exposed_candidates = candidates.clone(); // current members are always a candidate for the next round as well. @@ -636,15 +658,14 @@ impl Module { // previous runners_up are also always candidates for the next round. candidates.append(&mut Self::runners_up_ids()); - let voters_and_votes = VotesOf::::iter() - .map(|(v, i)| (v, i)) - .collect::)>>(); - let maybe_phragmen_result = sp_phragmen::elect::<_, _, _, T::CurrencyToVote, Perbill>( + let voters_and_votes = Voting::::iter() + .map(|(voter, (stake, targets))| { (voter, stake, targets) }) + .collect::>(); + let maybe_phragmen_result = sp_phragmen::elect::<_, _, T::CurrencyToVote, Perbill>( num_to_elect, 0, candidates, - voters_and_votes, - Self::locked_stake_of, + voters_and_votes.clone(), ); if let Some(phragmen_result) = maybe_phragmen_result { @@ -689,12 +710,24 @@ impl Module { // split new set into winners and runners up. let split_point = desired_seats.min(new_set_with_stake.len()); let mut new_members = (&new_set_with_stake[..split_point]).to_vec(); - let most_popular = new_members.first().map(|x| x.0.clone()); // save the runners up as-is. They are sorted based on desirability. // sort and save the members. new_members.sort_by(|i, j| i.0.cmp(&j.0)); + let mut prime_votes: Vec<_> = new_members.iter().map(|c| (&c.0, BalanceOf::::zero())).collect(); + for (_, stake, targets) in voters_and_votes.into_iter() { + for (votes, who) in targets.iter() + .enumerate() + .map(|(votes, who)| ((MAXIMUM_VOTE - votes) as u32, who)) + { + if let Ok(i) = prime_votes.binary_search_by_key(&who, |k| k.0) { + prime_votes[i].1 += stake * votes.into(); + } + } + } + let prime = prime_votes.into_iter().max_by_key(|x| x.1).map(|x| x.0.clone()); + // new_members_ids is sorted by account id. let new_members_ids = new_members .iter() @@ -722,7 +755,7 @@ impl Module { &outgoing.clone(), &new_members_ids, ); - T::ChangeMembers::set_prime(most_popular); + T::ChangeMembers::set_prime(prime); // outgoing candidates lose their bond. let mut to_burn_bond = outgoing.to_vec(); @@ -1012,7 +1045,7 @@ mod tests { } fn all_voters() -> Vec { - >::iter().map(|(v, _)| v).collect::>() + Voting::::iter().map(|(v, _)| v).collect::>() } fn balances(who: &u64) -> (u64, u64) { @@ -1231,13 +1264,13 @@ mod tests { assert_eq!(balances(&2), (18, 2)); assert_eq!(has_lock(&2), 20); - assert_eq!(Elections::stake_of(2), 20); + assert_eq!(Elections::locked_stake_of(&2), 20); // can update; different stake; different lock and reserve. assert_ok!(Elections::vote(Origin::signed(2), vec![5, 4], 15)); assert_eq!(balances(&2), (18, 2)); assert_eq!(has_lock(&2), 15); - assert_eq!(Elections::stake_of(2), 15); + assert_eq!(Elections::locked_stake_of(&2), 15); }); } @@ -1293,6 +1326,31 @@ mod tests { }); } + #[test] + fn prime_votes_for_exiting_members_are_removed() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + + assert_ok!(Elections::vote(Origin::signed(1), vec![4, 3], 10)); + assert_ok!(Elections::vote(Origin::signed(2), vec![4], 20)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + assert_ok!(Elections::renounce_candidacy(Origin::signed(4))); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members_ids(), vec![3, 5]); + assert_eq!(Elections::candidates(), vec![]); + + assert_eq!(PRIME.with(|p| *p.borrow()), Some(5)); + }); + } + #[test] fn cannot_vote_for_more_than_candidates() { ExtBuilder::default().build().execute_with(|| { @@ -1327,7 +1385,7 @@ mod tests { assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 30)); // you can lie but won't get away with it. - assert_eq!(Elections::stake_of(2), 20); + assert_eq!(Elections::locked_stake_of(&2), 20); assert_eq!(has_lock(&2), 20); }); } @@ -1341,16 +1399,16 @@ mod tests { assert_ok!(Elections::vote(Origin::signed(3), vec![5], 30)); assert_eq_uvec!(all_voters(), vec![2, 3]); - assert_eq!(Elections::stake_of(2), 20); - assert_eq!(Elections::stake_of(3), 30); - assert_eq!(Elections::votes_of(2), vec![5]); - assert_eq!(Elections::votes_of(3), vec![5]); + assert_eq!(Elections::locked_stake_of(&2), 20); + assert_eq!(Elections::locked_stake_of(&3), 30); + assert_eq!(Elections::votes_of(&2), vec![5]); + assert_eq!(Elections::votes_of(&3), vec![5]); assert_ok!(Elections::remove_voter(Origin::signed(2))); assert_eq_uvec!(all_voters(), vec![3]); - assert_eq!(Elections::votes_of(2), vec![]); - assert_eq!(Elections::stake_of(2), 0); + assert_eq!(Elections::votes_of(&2), vec![]); + assert_eq!(Elections::locked_stake_of(&2), 0); assert_eq!(balances(&2), (20, 0)); assert_eq!(Balances::locks(&2).len(), 0); @@ -1521,9 +1579,9 @@ mod tests { assert_eq_uvec!(all_voters(), vec![2, 3, 4]); - assert_eq!(Elections::votes_of(2), vec![5]); - assert_eq!(Elections::votes_of(3), vec![3]); - assert_eq!(Elections::votes_of(4), vec![4]); + assert_eq!(Elections::votes_of(&2), vec![5]); + assert_eq!(Elections::votes_of(&3), vec![3]); + assert_eq!(Elections::votes_of(&4), vec![4]); assert_eq!(Elections::candidates(), vec![3, 4, 5]); assert_eq!(>::decode_len().unwrap(), 3); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 4851768074..53ef7b41e4 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -1810,11 +1810,11 @@ impl Module { /// /// Assumes storage is coherent with the declaration. fn select_validators(current_era: EraIndex) -> Option> { - let mut all_nominators: Vec<(T::AccountId, Vec)> = Vec::new(); + let mut all_nominators: Vec<(T::AccountId, BalanceOf, Vec)> = Vec::new(); let mut all_validators_and_prefs = BTreeMap::new(); let mut all_validators = Vec::new(); for (validator, preference) in >::iter() { - let self_vote = (validator.clone(), vec![validator.clone()]); + let self_vote = (validator.clone(), Self::slashable_balance_of(&validator), vec![validator.clone()]); all_nominators.push(self_vote); all_validators_and_prefs.insert(validator.clone(), preference); all_validators.push(validator); @@ -1834,14 +1834,16 @@ impl Module { (nominator, targets) }); - all_nominators.extend(nominator_votes); + all_nominators.extend(nominator_votes.map(|(n, ns)| { + let s = Self::slashable_balance_of(&n); + (n, s, ns) + })); - let maybe_phragmen_result = sp_phragmen::elect::<_, _, _, T::CurrencyToVote, Perbill>( + let maybe_phragmen_result = sp_phragmen::elect::<_, _, T::CurrencyToVote, Perbill>( Self::validator_count() as usize, Self::minimum_validator_count().max(1) as usize, all_validators, all_nominators, - Self::slashable_balance_of, ); if let Some(phragmen_result) = maybe_phragmen_result { diff --git a/frame/support/src/storage/migration.rs b/frame/support/src/storage/migration.rs index 67df4d04c0..8e6beefa88 100644 --- a/frame/support/src/storage/migration.rs +++ b/frame/support/src/storage/migration.rs @@ -185,3 +185,12 @@ pub fn remove_storage_prefix(module: &[u8], item: &[u8], hash: &[u8]) { key[32..].copy_from_slice(hash); frame_support::storage::unhashed::kill_prefix(&key) } + +/// Get a particular value in storage by the `module`, the map's `item` name and the key `hash`. +pub fn take_storage_item( + module: &[u8], + item: &[u8], + key: K, +) -> Option { + take_storage_value(module, item, key.using_encoded(H::hash).as_ref()) +} diff --git a/primitives/phragmen/src/lib.rs b/primitives/phragmen/src/lib.rs index 23acec19da..aba714faeb 100644 --- a/primitives/phragmen/src/lib.rs +++ b/primitives/phragmen/src/lib.rs @@ -149,16 +149,14 @@ pub type SupportMap = BTreeMap>; /// responsibility of the caller to make sure only those candidates who have a sensible economic /// value are passed in. From the perspective of this function, a candidate can easily be among the /// winner with no backing stake. -pub fn elect( +pub fn elect( candidate_count: usize, minimum_candidate_count: usize, initial_candidates: Vec, - initial_voters: Vec<(AccountId, Vec)>, - stake_of: FS, + initial_voters: Vec<(AccountId, Balance, Vec)>, ) -> Option> where AccountId: Default + Ord + Member, Balance: Default + Copy + AtLeast32Bit, - for<'r> FS: Fn(&'r AccountId) -> Balance, C: Convert + Convert, R: PerThing, { @@ -191,8 +189,7 @@ pub fn elect( // collect voters. use `c_idx_cache` for fast access and aggregate `approval_stake` of // candidates. - voters.extend(initial_voters.into_iter().map(|(who, votes)| { - let voter_stake = stake_of(&who); + voters.extend(initial_voters.into_iter().map(|(who, voter_stake, votes)| { let mut edges: Vec> = Vec::with_capacity(votes.len()); for v in votes { if let Some(idx) = c_idx_cache.get(&v) { diff --git a/primitives/phragmen/src/mock.rs b/primitives/phragmen/src/mock.rs index b3110a5dba..66ef64a6c2 100644 --- a/primitives/phragmen/src/mock.rs +++ b/primitives/phragmen/src/mock.rs @@ -335,12 +335,11 @@ pub(crate) fn run_and_compare( min_to_elect: usize, ) { // run fixed point code. - let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Perbill>( + let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Perbill>( to_elect, min_to_elect, candidates.clone(), - voters.clone(), - &stake_of, + voters.iter().map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())).collect::>(), ).unwrap(); // run float poc code. diff --git a/primitives/phragmen/src/tests.rs b/primitives/phragmen/src/tests.rs index 9027cc335f..8bcf007c7b 100644 --- a/primitives/phragmen/src/tests.rs +++ b/primitives/phragmen/src/tests.rs @@ -80,12 +80,12 @@ fn phragmen_poc_works() { (30, vec![2, 3]), ]; - let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>( + let stake_of = create_stake_of(&[(10, 10), (20, 20), (30, 30)]); + let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Output>( 2, 2, candidates, - voters, - create_stake_of(&[(10, 10), (20, 20), (30, 30)]), + voters.iter().map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())).collect::>(), ).unwrap(); assert_eq_uvec!(winners, vec![(2, 40), (3, 50)]); @@ -149,12 +149,11 @@ fn phragmen_accuracy_on_large_scale_only_validators() { (5, (u64::max_value() - 2).into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Output>( 2, 2, candidates.clone(), - auto_generate_self_voters(&candidates), - stake_of, + auto_generate_self_voters(&candidates).iter().map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())).collect::>(), ).unwrap(); assert_eq_uvec!(winners, vec![(1, 18446744073709551614u128), (5, 18446744073709551613u128)]); @@ -180,12 +179,11 @@ fn phragmen_accuracy_on_large_scale_validators_and_nominators() { (14, u64::max_value().into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Output>( 2, 2, candidates, - voters, - stake_of, + voters.iter().map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())).collect::>(), ).unwrap(); assert_eq_uvec!(winners, vec![(2, 36893488147419103226u128), (1, 36893488147419103219u128)]); @@ -212,12 +210,11 @@ fn phragmen_accuracy_on_small_scale_self_vote() { (30, 1), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments: _ } = elect::<_, _, TestCurrencyToVote, Output>( 3, 3, candidates, - voters, - stake_of, + voters.iter().map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())).collect::>(), ).unwrap(); assert_eq_uvec!(winners, vec![(20, 2), (10, 1), (30, 1)]); @@ -243,12 +240,11 @@ fn phragmen_accuracy_on_small_scale_no_self_vote() { (3, 1), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments: _ } = elect::<_, _, TestCurrencyToVote, Output>( 3, 3, candidates, - voters, - stake_of, + voters.iter().map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())).collect::>(), ).unwrap(); assert_eq_uvec!(winners, vec![(20, 2), (10, 1), (30, 1)]); @@ -277,12 +273,11 @@ fn phragmen_large_scale_test() { (50, 990000000000000000), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Output>( 2, 2, candidates, - voters, - stake_of, + voters.iter().map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())).collect::>(), ).unwrap(); assert_eq_uvec!(winners, vec![(24, 1490000000000200000u128), (22, 1490000000000100000u128)]); @@ -304,12 +299,11 @@ fn phragmen_large_scale_test_2() { (50, nom_budget.into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Output>( 2, 2, candidates, - voters, - stake_of, + voters.iter().map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())).collect::>(), ).unwrap(); assert_eq_uvec!(winners, vec![(2, 1000000000004000000u128), (4, 1000000000004000000u128)]); @@ -369,12 +363,11 @@ fn elect_has_no_entry_barrier() { (2, 10), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments: _ } = elect::<_, _, TestCurrencyToVote, Output>( 3, 3, candidates, - voters, - stake_of, + voters.iter().map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())).collect::>(), ).unwrap(); // 30 is elected with stake 0. The caller is responsible for stripping this. @@ -397,12 +390,11 @@ fn minimum_to_elect_is_respected() { (2, 10), ]); - let maybe_result = elect::<_, _, _, TestCurrencyToVote, Output>( + let maybe_result = elect::<_, _, TestCurrencyToVote, Output>( 10, 10, candidates, - voters, - stake_of, + voters.iter().map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())).collect::>(), ); assert!(maybe_result.is_none()); @@ -424,12 +416,11 @@ fn self_votes_should_be_kept() { (1, 8), ]); - let result = elect::<_, _, _, TestCurrencyToVote, Output>( + let result = elect::<_, _, TestCurrencyToVote, Output>( 2, 2, candidates, - voters, - &stake_of, + voters.iter().map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())).collect::>(), ).unwrap(); assert_eq!(result.winners, vec![(20, 28), (10, 18)]); -- GitLab From 3b347059755c926843bbb75ae09d4b24827bb636 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 23 Mar 2020 11:53:41 +0100 Subject: [PATCH 048/300] Simplify BABE pre-digest definitions (#5289) * Init vrf crate without type alias * Generic PreDigest definition for BABE * Fix BABE vrf interface change * Missing default-features def in sp-consensus-babe * Fix sp-consensus-babe compile * frame-babe: fix type inference * Unify type definitions of vrf output/proof and randomness * frame-babe: fix tests * Bump node impl version * Update cargo lock * Derive Copy for RawVRFOutput and RawVRFProof * Fix duplicated derive Co-authored-by: Gavin Wood --- Cargo.lock | 15 +- Cargo.toml | 1 + bin/node/runtime/src/lib.rs | 2 +- client/consensus/babe/Cargo.toml | 2 +- client/consensus/babe/src/authorship.rs | 5 +- client/consensus/babe/src/verification.rs | 2 +- frame/babe/Cargo.toml | 4 +- frame/babe/src/lib.rs | 30 ++- frame/babe/src/tests.rs | 11 +- primitives/consensus/babe/Cargo.toml | 4 +- primitives/consensus/babe/src/digests.rs | 189 ++++------------ primitives/consensus/babe/src/lib.rs | 12 +- primitives/consensus/vrf/Cargo.toml | 24 ++ primitives/consensus/vrf/src/lib.rs | 20 ++ primitives/consensus/vrf/src/schnorrkel.rs | 249 +++++++++++++++++++++ primitives/core/src/lib.rs | 2 +- primitives/core/src/uint.rs | 2 +- 17 files changed, 388 insertions(+), 186 deletions(-) create mode 100644 primitives/consensus/vrf/Cargo.toml create mode 100644 primitives/consensus/vrf/src/lib.rs create mode 100644 primitives/consensus/vrf/src/schnorrkel.rs diff --git a/Cargo.lock b/Cargo.lock index 22da38136f..308ac78871 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3942,6 +3942,7 @@ dependencies = [ "parking_lot 0.10.0", "serde", "sp-consensus-babe", + "sp-consensus-vrf", "sp-core", "sp-inherents", "sp-io", @@ -5893,6 +5894,7 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-consensus-babe", + "sp-consensus-vrf", "sp-core", "sp-inherents", "sp-io", @@ -7095,10 +7097,10 @@ name = "sp-consensus-babe" version = "0.8.0-alpha.4" dependencies = [ "parity-scale-codec", - "schnorrkel", "sp-api", "sp-application-crypto", "sp-consensus", + "sp-consensus-vrf", "sp-inherents", "sp-runtime", "sp-std", @@ -7116,6 +7118,17 @@ dependencies = [ "sp-std", ] +[[package]] +name = "sp-consensus-vrf" +version = "0.8.0-alpha.4" +dependencies = [ + "parity-scale-codec", + "schnorrkel", + "sp-core", + "sp-runtime", + "sp-std", +] + [[package]] name = "sp-core" version = "2.0.0-alpha.4" diff --git a/Cargo.toml b/Cargo.toml index 5af37839ad..5a88ed28dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -118,6 +118,7 @@ members = [ "primitives/consensus/babe", "primitives/consensus/common", "primitives/consensus/pow", + "primitives/consensus/vrf", "primitives/core", "primitives/debug-derive", "primitives/storage", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index ba219a1890..58728a507b 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -84,7 +84,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 240, - impl_version: 0, + impl_version: 1, apis: RUNTIME_API_VERSIONS, }; diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index 5486342ef7..ec5e3cbbb7 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -9,7 +9,6 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sc-consensus-babe" - [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/babe" } @@ -32,6 +31,7 @@ sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } sp-block-builder = { version = "2.0.0-alpha.4", path = "../../../primitives/block-builder" } sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +sp-consensus-vrf = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/vrf" } sc-consensus-uncles = { version = "0.8.0-alpha.4", path = "../uncles" } sc-consensus-slots = { version = "0.8.0-alpha.4", path = "../slots" } sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } diff --git a/client/consensus/babe/src/authorship.rs b/client/consensus/babe/src/authorship.rs index a01ea63bbe..fb7be52766 100644 --- a/client/consensus/babe/src/authorship.rs +++ b/client/consensus/babe/src/authorship.rs @@ -22,6 +22,7 @@ use sp_consensus_babe::{ SlotNumber, AuthorityPair, BabeConfiguration }; use sp_consensus_babe::digests::PreDigest; +use sp_consensus_vrf::schnorrkel::{VRFOutput, VRFProof}; use sp_core::{U256, blake2_256}; use codec::Encode; use schnorrkel::vrf::VRFInOut; @@ -201,8 +202,8 @@ fn claim_primary_slot( .map(|s| { PreDigest::Primary { slot_number, - vrf_output: s.0.to_output(), - vrf_proof: s.1, + vrf_output: VRFOutput(s.0.to_output()), + vrf_proof: VRFProof(s.1), authority_index: authority_index as u32, } }); diff --git a/client/consensus/babe/src/verification.rs b/client/consensus/babe/src/verification.rs index 70418b8aea..1eb73588a8 100644 --- a/client/consensus/babe/src/verification.rs +++ b/client/consensus/babe/src/verification.rs @@ -15,11 +15,11 @@ // along with Substrate. If not, see . //! Verification for BABE headers. -use schnorrkel::vrf::{VRFOutput, VRFProof}; use sp_runtime::{traits::Header, traits::DigestItemFor}; use sp_core::{Pair, Public}; use sp_consensus_babe::{AuthoritySignature, SlotNumber, AuthorityIndex, AuthorityPair, AuthorityId}; use sp_consensus_babe::digests::{PreDigest, CompatibleDigestItem}; +use sp_consensus_vrf::schnorrkel::{VRFOutput, VRFProof}; use sc_consensus_slots::CheckedHeader; use log::{debug, trace}; use super::{find_pre_digest, babe_err, Epoch, BlockT, Error}; diff --git a/frame/babe/Cargo.toml b/frame/babe/Cargo.toml index 28f3d98701..4cf7c13cd6 100644 --- a/frame/babe/Cargo.toml +++ b/frame/babe/Cargo.toml @@ -22,7 +22,8 @@ pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/timestamp" } pallet-session = { version = "2.0.0-alpha.4", default-features = false, path = "../session" } sp-consensus-babe = { version = "0.8.0-alpha.4", default-features = false, path = "../../primitives/consensus/babe" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} +sp-consensus-vrf = { version = "0.8.0-alpha.4", default-features = false, path = "../../primitives/consensus/vrf" } +sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} [dev-dependencies] lazy_static = "1.4.0" @@ -45,6 +46,7 @@ std = [ "sp-timestamp/std", "sp-inherents/std", "sp-consensus-babe/std", + "sp-consensus-vrf/std", "pallet-session/std", "sp-io/std", ] diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 29e8625419..27a471f6f8 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -39,7 +39,8 @@ use sp_consensus_babe::{ inherents::{INHERENT_IDENTIFIER, BabeInherentData}, digests::{NextEpochDescriptor, RawPreDigest}, }; -pub use sp_consensus_babe::{AuthorityId, VRF_OUTPUT_LENGTH, PUBLIC_KEY_LENGTH}; +use sp_consensus_vrf::schnorrkel; +pub use sp_consensus_babe::{AuthorityId, VRF_OUTPUT_LENGTH, RANDOMNESS_LENGTH, PUBLIC_KEY_LENGTH}; #[cfg(all(feature = "std", test))] mod tests; @@ -96,12 +97,9 @@ impl EpochChangeTrigger for SameAuthoritiesForever { } } -/// The length of the BABE randomness -pub const RANDOMNESS_LENGTH: usize = 32; - const UNDER_CONSTRUCTION_SEGMENT_LENGTH: usize = 256; -type MaybeVrf = Option<[u8; 32 /* VRF_OUTPUT_LENGTH */]>; +type MaybeVrf = Option; decl_storage! { trait Store for Module as Babe { @@ -131,10 +129,10 @@ decl_storage! { // NOTE: the following fields don't use the constants to define the // array size because the metadata API currently doesn't resolve the // variable to its underlying value. - pub Randomness get(fn randomness): [u8; 32 /* RANDOMNESS_LENGTH */]; + pub Randomness get(fn randomness): schnorrkel::Randomness; /// Next epoch randomness. - NextRandomness: [u8; 32 /* RANDOMNESS_LENGTH */]; + NextRandomness: schnorrkel::Randomness; /// Randomness under construction. /// @@ -146,7 +144,7 @@ decl_storage! { /// We reset all segments and return to `0` at the beginning of every /// epoch. SegmentIndex build(|_| 0): u32; - UnderConstruction: map hasher(twox_64_concat) u32 => Vec<[u8; 32 /* VRF_OUTPUT_LENGTH */]>; + UnderConstruction: map hasher(twox_64_concat) u32 => Vec; /// Temporary value (cleared at block finalization) which is `Some` /// if per-block initialization has already been called for current block. @@ -210,7 +208,7 @@ impl FindAuthor for Module { { for (id, mut data) in digests.into_iter() { if id == BABE_ENGINE_ID { - let pre_digest = RawPreDigest::decode(&mut data).ok()?; + let pre_digest: RawPreDigest = RawPreDigest::decode(&mut data).ok()?; return Some(match pre_digest { RawPreDigest::Primary { authority_index, .. } => authority_index, @@ -373,7 +371,7 @@ impl Module { >::deposit_log(log.into()) } - fn deposit_vrf_output(vrf_output: &[u8; VRF_OUTPUT_LENGTH]) { + fn deposit_vrf_output(vrf_output: &schnorrkel::RawVRFOutput) { let segment_idx = ::get(); let mut segment = ::get(&segment_idx); if segment.len() < UNDER_CONSTRUCTION_SEGMENT_LENGTH { @@ -383,7 +381,7 @@ impl Module { } else { // move onto the next segment and update the index. let segment_idx = segment_idx + 1; - ::insert(&segment_idx, &vec![*vrf_output]); + ::insert(&segment_idx, &vec![vrf_output.clone()]); ::put(&segment_idx); } } @@ -396,7 +394,7 @@ impl Module { return; } - let maybe_pre_digest = >::digest() + let maybe_pre_digest: Option = >::digest() .logs .iter() .filter_map(|s| s.as_pre_runtime()) @@ -446,7 +444,7 @@ impl Module { /// Call this function exactly once when an epoch changes, to update the /// randomness. Returns the new randomness. - fn randomness_change_epoch(next_epoch_index: u64) -> [u8; RANDOMNESS_LENGTH] { + fn randomness_change_epoch(next_epoch_index: u64) -> schnorrkel::Randomness { let this_randomness = NextRandomness::get(); let segment_idx: u32 = ::mutate(|s| sp_std::mem::replace(s, 0)); @@ -513,11 +511,11 @@ impl pallet_session::OneSessionHandler for Module { // // an optional size hint as to how many VRF outputs there were may be provided. fn compute_randomness( - last_epoch_randomness: [u8; RANDOMNESS_LENGTH], + last_epoch_randomness: schnorrkel::Randomness, epoch_index: u64, - rho: impl Iterator, + rho: impl Iterator, rho_size_hint: Option, -) -> [u8; RANDOMNESS_LENGTH] { +) -> schnorrkel::Randomness { let mut s = Vec::with_capacity(40 + rho_size_hint.unwrap_or(0) * VRF_OUTPUT_LENGTH); s.extend_from_slice(&last_epoch_randomness); s.extend_from_slice(&epoch_index.to_le_bytes()); diff --git a/frame/babe/src/tests.rs b/frame/babe/src/tests.rs index 84f8166b10..3fcb78ae5f 100644 --- a/frame/babe/src/tests.rs +++ b/frame/babe/src/tests.rs @@ -19,6 +19,7 @@ use super::*; use mock::{new_test_ext, Babe, System}; use sp_runtime::{traits::OnFinalize, testing::{Digest, DigestItem}}; +use sp_consensus_vrf::schnorrkel::{RawVRFOutput, RawVRFProof}; use pallet_session::ShouldEndSession; const EMPTY_RANDOMNESS: [u8; 32] = [ @@ -31,8 +32,8 @@ const EMPTY_RANDOMNESS: [u8; 32] = [ fn make_pre_digest( authority_index: sp_consensus_babe::AuthorityIndex, slot_number: sp_consensus_babe::SlotNumber, - vrf_output: [u8; sp_consensus_babe::VRF_OUTPUT_LENGTH], - vrf_proof: [u8; sp_consensus_babe::VRF_PROOF_LENGTH], + vrf_output: RawVRFOutput, + vrf_proof: RawVRFProof, ) -> Digest { let digest_data = sp_consensus_babe::digests::RawPreDigest::Primary { authority_index, @@ -70,12 +71,12 @@ fn check_module() { fn first_block_epoch_zero_start() { new_test_ext(vec![0, 1, 2, 3]).execute_with(|| { let genesis_slot = 100; - let first_vrf = [1; 32]; + let first_vrf = RawVRFOutput([1; 32]); let pre_digest = make_pre_digest( 0, genesis_slot, - first_vrf, - [0xff; 64], + first_vrf.clone(), + RawVRFProof([0xff; 64]), ); assert_eq!(Babe::genesis_slot(), 0); diff --git a/primitives/consensus/babe/Cargo.toml b/primitives/consensus/babe/Cargo.toml index a948a30f2d..f7581601e5 100644 --- a/primitives/consensus/babe/Cargo.toml +++ b/primitives/consensus/babe/Cargo.toml @@ -12,9 +12,9 @@ repository = "https://github.com/paritytech/substrate/" sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../std" } -schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated"], optional = true } sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../api" } sp-consensus = { version = "0.8.0-alpha.4", optional = true, path = "../common" } +sp-consensus-vrf = { version = "0.8.0-alpha.4", path = "../vrf", default-features = false } sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../inherents" } sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../runtime" } sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../timestamp" } @@ -25,9 +25,9 @@ std = [ "sp-application-crypto/std", "codec/std", "sp-std/std", - "schnorrkel", "sp-api/std", "sp-consensus", + "sp-consensus-vrf/std", "sp-inherents/std", "sp-runtime/std", "sp-timestamp/std", diff --git a/primitives/consensus/babe/src/digests.rs b/primitives/consensus/babe/src/digests.rs index 7ec0f9b977..fca0c3a7b3 100644 --- a/primitives/consensus/babe/src/digests.rs +++ b/primitives/consensus/babe/src/digests.rs @@ -18,44 +18,45 @@ #[cfg(feature = "std")] use super::{BABE_ENGINE_ID, AuthoritySignature}; -#[cfg(not(feature = "std"))] -use super::{VRF_OUTPUT_LENGTH, VRF_PROOF_LENGTH}; use super::{AuthorityId, AuthorityIndex, SlotNumber, BabeAuthorityWeight}; #[cfg(feature = "std")] use sp_runtime::{DigestItem, generic::OpaqueDigestItemId}; #[cfg(feature = "std")] -use std::fmt::Debug; +use std::{fmt::Debug, convert::{TryFrom, TryInto}}; use codec::{Decode, Encode}; #[cfg(feature = "std")] -use codec::{Codec, Input, Error}; -#[cfg(feature = "std")] -use schnorrkel::{ - SignatureError, errors::MultiSignatureStage, - vrf::{VRFProof, VRFOutput, VRF_OUTPUT_LENGTH, VRF_PROOF_LENGTH} -}; +use codec::Codec; use sp_std::vec::Vec; - +use sp_consensus_vrf::schnorrkel::{self, Randomness}; +#[cfg(feature = "std")] +use sp_consensus_vrf::schnorrkel::SignatureError; /// A BABE pre-runtime digest. This contains all data required to validate a /// block and for the BABE runtime module. Slots can be assigned to a primary /// (VRF based) and to a secondary (slot number based). -#[cfg(feature = "std")] -#[derive(Clone, Debug)] -pub enum PreDigest { +#[derive(Clone, Debug, Encode, Decode)] +pub enum RawPreDigest { /// A primary VRF-based slot assignment. + #[codec(index = "1")] Primary { - /// VRF output - vrf_output: VRFOutput, - /// VRF proof - vrf_proof: VRFProof, /// Authority index authority_index: super::AuthorityIndex, /// Slot number slot_number: SlotNumber, + /// VRF output + vrf_output: VRFOutput, + /// VRF proof + vrf_proof: VRFProof, }, /// A secondary deterministic slot assignment. + #[codec(index = "2")] Secondary { /// Authority index + /// + /// This is not strictly-speaking necessary, since the secondary slots + /// are assigned based on slot number and epoch randomness. But including + /// it makes things easier for higher-level users of the chain data to + /// be aware of the author of a secondary-slot block. authority_index: super::AuthorityIndex, /// Slot number slot_number: SlotNumber, @@ -63,20 +64,23 @@ pub enum PreDigest { } #[cfg(feature = "std")] -impl PreDigest { +/// A BABE pre-runtime digest for std. +pub type PreDigest = RawPreDigest; + +impl RawPreDigest { /// Returns the slot number of the pre digest. pub fn authority_index(&self) -> AuthorityIndex { match self { - PreDigest::Primary { authority_index, .. } => *authority_index, - PreDigest::Secondary { authority_index, .. } => *authority_index, + RawPreDigest::Primary { authority_index, .. } => *authority_index, + RawPreDigest::Secondary { authority_index, .. } => *authority_index, } } /// Returns the slot number of the pre digest. pub fn slot_number(&self) -> SlotNumber { match self { - PreDigest::Primary { slot_number, .. } => *slot_number, - PreDigest::Secondary { slot_number, .. } => *slot_number, + RawPreDigest::Primary { slot_number, .. } => *slot_number, + RawPreDigest::Secondary { slot_number, .. } => *slot_number, } } @@ -84,109 +88,31 @@ impl PreDigest { /// of the chain. pub fn added_weight(&self) -> crate::BabeBlockWeight { match self { - PreDigest::Primary { .. } => 1, - PreDigest::Secondary { .. } => 0, - } - } -} - -/// A raw version of `BabePreDigest`, usable on `no_std`. -#[derive(Copy, Clone, Encode, Decode)] -pub enum RawPreDigest { - /// A primary VRF-based slot assignment. - #[codec(index = "1")] - Primary { - /// Authority index - authority_index: AuthorityIndex, - /// Slot number - slot_number: SlotNumber, - /// VRF output - vrf_output: [u8; VRF_OUTPUT_LENGTH], - /// VRF proof - vrf_proof: [u8; VRF_PROOF_LENGTH], - }, - /// A secondary deterministic slot assignment. - #[codec(index = "2")] - Secondary { - /// Authority index - /// - /// This is not strictly-speaking necessary, since the secondary slots - /// are assigned based on slot number and epoch randomness. But including - /// it makes things easier for higher-level users of the chain data to - /// be aware of the author of a secondary-slot block. - authority_index: AuthorityIndex, - /// Slot number - slot_number: SlotNumber, - }, -} - -impl RawPreDigest { - /// Returns the slot number of the pre digest. - pub fn slot_number(&self) -> SlotNumber { - match self { - RawPreDigest::Primary { slot_number, .. } => *slot_number, - RawPreDigest::Secondary { slot_number, .. } => *slot_number, + RawPreDigest::Primary { .. } => 1, + RawPreDigest::Secondary { .. } => 0, } } } #[cfg(feature = "std")] -impl Encode for PreDigest { - fn encode(&self) -> Vec { - let raw = match self { - PreDigest::Primary { - vrf_output, - vrf_proof, - authority_index, - slot_number, - } => { +impl TryFrom for PreDigest { + type Error = SignatureError; + + fn try_from(raw: RawPreDigest) -> Result { + Ok(match raw { + RawPreDigest::Primary { authority_index, slot_number, vrf_output, vrf_proof } => RawPreDigest::Primary { - vrf_output: *vrf_output.as_bytes(), - vrf_proof: vrf_proof.to_bytes(), - authority_index: *authority_index, - slot_number: *slot_number, - } - }, - PreDigest::Secondary { - authority_index, - slot_number, - } => { + authority_index, + slot_number, + vrf_output: vrf_output.try_into()?, + vrf_proof: vrf_proof.try_into()?, + }, + RawPreDigest::Secondary { authority_index, slot_number } => RawPreDigest::Secondary { - authority_index: *authority_index, - slot_number: *slot_number, - } - }, - }; - - codec::Encode::encode(&raw) - } -} - -#[cfg(feature = "std")] -impl codec::EncodeLike for PreDigest {} - -#[cfg(feature = "std")] -impl Decode for PreDigest { - fn decode(i: &mut R) -> Result { - let pre_digest = match Decode::decode(i)? { - RawPreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number } => { - // Verify (at compile time) that the sizes in babe_primitives are correct - let _: [u8; super::VRF_OUTPUT_LENGTH] = vrf_output; - let _: [u8; super::VRF_PROOF_LENGTH] = vrf_proof; - - PreDigest::Primary { - vrf_proof: VRFProof::from_bytes(&vrf_proof).map_err(convert_error)?, - vrf_output: VRFOutput::from_bytes(&vrf_output).map_err(convert_error)?, authority_index, slot_number, } - }, - RawPreDigest::Secondary { authority_index, slot_number } => { - PreDigest::Secondary { authority_index, slot_number } - }, - }; - - Ok(pre_digest) + }) } } @@ -198,7 +124,7 @@ pub struct NextEpochDescriptor { pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, /// The value of randomness to use for the slot-assignment. - pub randomness: [u8; VRF_OUTPUT_LENGTH], + pub randomness: Randomness, } /// A digest item which is usable with BABE consensus. @@ -248,34 +174,3 @@ impl CompatibleDigestItem for DigestItem where }) } } - -#[cfg(feature = "std")] -fn convert_error(e: SignatureError) -> codec::Error { - use SignatureError::*; - use MultiSignatureStage::*; - match e { - EquationFalse => "Signature error: `EquationFalse`".into(), - PointDecompressionError => "Signature error: `PointDecompressionError`".into(), - ScalarFormatError => "Signature error: `ScalarFormatError`".into(), - NotMarkedSchnorrkel => "Signature error: `NotMarkedSchnorrkel`".into(), - BytesLengthError { .. } => "Signature error: `BytesLengthError`".into(), - MuSigAbsent { musig_stage: Commitment } => - "Signature error: `MuSigAbsent` at stage `Commitment`".into(), - MuSigAbsent { musig_stage: Reveal } => - "Signature error: `MuSigAbsent` at stage `Reveal`".into(), - MuSigAbsent { musig_stage: Cosignature } => - "Signature error: `MuSigAbsent` at stage `Commitment`".into(), - MuSigInconsistent { musig_stage: Commitment, duplicate: true } => - "Signature error: `MuSigInconsistent` at stage `Commitment` on duplicate".into(), - MuSigInconsistent { musig_stage: Commitment, duplicate: false } => - "Signature error: `MuSigInconsistent` at stage `Commitment` on not duplicate".into(), - MuSigInconsistent { musig_stage: Reveal, duplicate: true } => - "Signature error: `MuSigInconsistent` at stage `Reveal` on duplicate".into(), - MuSigInconsistent { musig_stage: Reveal, duplicate: false } => - "Signature error: `MuSigInconsistent` at stage `Reveal` on not duplicate".into(), - MuSigInconsistent { musig_stage: Cosignature, duplicate: true } => - "Signature error: `MuSigInconsistent` at stage `Cosignature` on duplicate".into(), - MuSigInconsistent { musig_stage: Cosignature, duplicate: false } => - "Signature error: `MuSigInconsistent` at stage `Cosignature` on not duplicate".into(), - } -} diff --git a/primitives/consensus/babe/src/lib.rs b/primitives/consensus/babe/src/lib.rs index 392dcb560b..33701860d1 100644 --- a/primitives/consensus/babe/src/lib.rs +++ b/primitives/consensus/babe/src/lib.rs @@ -22,6 +22,10 @@ pub mod digests; pub mod inherents; +pub use sp_consensus_vrf::schnorrkel::{ + Randomness, VRF_PROOF_LENGTH, VRF_OUTPUT_LENGTH, RANDOMNESS_LENGTH +}; + use codec::{Encode, Decode}; use sp_std::vec::Vec; use sp_runtime::{ConsensusEngineId, RuntimeDebug}; @@ -50,12 +54,6 @@ pub type AuthorityId = app::Public; /// The `ConsensusEngineId` of BABE. pub const BABE_ENGINE_ID: ConsensusEngineId = *b"BABE"; -/// The length of the VRF output -pub const VRF_OUTPUT_LENGTH: usize = 32; - -/// The length of the VRF proof -pub const VRF_PROOF_LENGTH: usize = 64; - /// The length of the public key pub const PUBLIC_KEY_LENGTH: usize = 32; @@ -115,7 +113,7 @@ pub struct BabeConfiguration { pub genesis_authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, /// The randomness for the genesis epoch. - pub randomness: [u8; VRF_OUTPUT_LENGTH], + pub randomness: Randomness, /// Whether this chain should run with secondary slots, which are assigned /// in round-robin manner. diff --git a/primitives/consensus/vrf/Cargo.toml b/primitives/consensus/vrf/Cargo.toml new file mode 100644 index 0000000000..dc2631d270 --- /dev/null +++ b/primitives/consensus/vrf/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "sp-consensus-vrf" +version = "0.8.0-alpha.4" +authors = ["Parity Technologies "] +description = "Primitives for VRF based consensus" +edition = "2018" +license = "GPL-3.0" + +[dependencies] +codec = { version = "1.0.0", package = "parity-scale-codec", default-features = false } +schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated"], optional = true } +sp-std = { version = "2.0.0-alpha.4", path = "../../std", default-features = false } +sp-core = { version = "2.0.0-alpha.4", path = "../../core", default-features = false } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../runtime" } + +[features] +default = ["std"] +std = [ + "codec/std", + "schnorrkel", + "sp-std/std", + "sp-core/std", + "sp-runtime/std", +] diff --git a/primitives/consensus/vrf/src/lib.rs b/primitives/consensus/vrf/src/lib.rs new file mode 100644 index 0000000000..4ec6e376d6 --- /dev/null +++ b/primitives/consensus/vrf/src/lib.rs @@ -0,0 +1,20 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Primitives for VRF-based consensus engines. +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod schnorrkel; diff --git a/primitives/consensus/vrf/src/schnorrkel.rs b/primitives/consensus/vrf/src/schnorrkel.rs new file mode 100644 index 0000000000..e4ae68ced4 --- /dev/null +++ b/primitives/consensus/vrf/src/schnorrkel.rs @@ -0,0 +1,249 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Schnorrkel-based VRF. + +use codec::{Encode, Decode}; +use sp_core::U512; +use sp_runtime::RuntimeDebug; +use sp_std::ops::{Deref, DerefMut}; +#[cfg(feature = "std")] +use std::convert::TryFrom; +#[cfg(feature = "std")] +use codec::EncodeLike; +#[cfg(feature = "std")] +use schnorrkel::errors::MultiSignatureStage; + +#[cfg(feature = "std")] +pub use schnorrkel::{SignatureError, vrf::{VRF_PROOF_LENGTH, VRF_OUTPUT_LENGTH}}; + +/// The length of the VRF proof. +#[cfg(not(feature = "std"))] +pub const VRF_PROOF_LENGTH: usize = 64; + +/// The length of the VRF output. +#[cfg(not(feature = "std"))] +pub const VRF_OUTPUT_LENGTH: usize = 32; + +/// The length of the Randomness. +pub const RANDOMNESS_LENGTH: usize = VRF_OUTPUT_LENGTH; + +/// Raw VRF output. +#[derive(Clone, Copy, Eq, PartialEq, RuntimeDebug, Encode, Decode)] +pub struct RawVRFOutput(pub [u8; VRF_OUTPUT_LENGTH]); + +impl Deref for RawVRFOutput { + type Target = [u8; VRF_OUTPUT_LENGTH]; + fn deref(&self) -> &Self::Target { &self.0 } +} + +impl DerefMut for RawVRFOutput { + fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } +} + +/// VRF output type available for `std` environment, suitable for schnorrkel operations. +#[cfg(feature = "std")] +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct VRFOutput(pub schnorrkel::vrf::VRFOutput); + +#[cfg(feature = "std")] +impl Deref for VRFOutput { + type Target = schnorrkel::vrf::VRFOutput; + fn deref(&self) -> &Self::Target { &self.0 } +} + +#[cfg(feature = "std")] +impl DerefMut for VRFOutput { + fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } +} + +#[cfg(feature = "std")] +impl Encode for VRFOutput { + fn encode(&self) -> Vec { + self.0.as_bytes().encode() + } +} + +#[cfg(feature = "std")] +impl EncodeLike for VRFOutput { } + +#[cfg(feature = "std")] +impl Decode for VRFOutput { + fn decode(i: &mut R) -> Result { + let decoded = <[u8; VRF_OUTPUT_LENGTH]>::decode(i)?; + Ok(Self(schnorrkel::vrf::VRFOutput::from_bytes(&decoded).map_err(convert_error)?)) + } +} + +#[cfg(feature = "std")] +impl TryFrom<[u8; VRF_OUTPUT_LENGTH]> for VRFOutput { + type Error = SignatureError; + + fn try_from(raw: [u8; VRF_OUTPUT_LENGTH]) -> Result { + schnorrkel::vrf::VRFOutput::from_bytes(&raw).map(VRFOutput) + } +} + +#[cfg(feature = "std")] +impl TryFrom for VRFOutput { + type Error = SignatureError; + + fn try_from(raw: RawVRFOutput) -> Result { + schnorrkel::vrf::VRFOutput::from_bytes(&raw.0).map(VRFOutput) + } +} + +#[cfg(feature = "std")] +impl From for RawVRFOutput { + fn from(output: VRFOutput) -> RawVRFOutput { + RawVRFOutput(output.to_bytes()) + } +} + +/// Raw VRF proof. +#[derive(Clone, Copy, Encode, Decode)] +pub struct RawVRFProof(pub [u8; VRF_PROOF_LENGTH]); + +impl Deref for RawVRFProof { + type Target = [u8; VRF_PROOF_LENGTH]; + fn deref(&self) -> &Self::Target { &self.0 } +} + +impl DerefMut for RawVRFProof { + fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } +} + +#[cfg(feature = "std")] +impl std::fmt::Debug for RawVRFProof { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", &self) + } +} + +impl core::cmp::PartialEq for RawVRFProof { + fn eq(&self, other: &Self) -> bool { + self == other + } +} + +impl core::cmp::Eq for RawVRFProof { } + +/// VRF proof type available for `std` environment, suitable for schnorrkel operations. +#[cfg(feature = "std")] +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct VRFProof(pub schnorrkel::vrf::VRFProof); + +#[cfg(feature = "std")] +impl PartialOrd for VRFProof { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +#[cfg(feature = "std")] +impl Ord for VRFProof { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + U512::from(self.0.to_bytes()).cmp(&U512::from(other.0.to_bytes())) + } +} + +#[cfg(feature = "std")] +impl Deref for VRFProof { + type Target = schnorrkel::vrf::VRFProof; + fn deref(&self) -> &Self::Target { &self.0 } +} + +#[cfg(feature = "std")] +impl DerefMut for VRFProof { + fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } +} + +#[cfg(feature = "std")] +impl Encode for VRFProof { + fn encode(&self) -> Vec { + self.0.to_bytes().encode() + } +} + +#[cfg(feature = "std")] +impl EncodeLike for VRFProof { } + +#[cfg(feature = "std")] +impl Decode for VRFProof { + fn decode(i: &mut R) -> Result { + let decoded = <[u8; VRF_PROOF_LENGTH]>::decode(i)?; + Ok(Self(schnorrkel::vrf::VRFProof::from_bytes(&decoded).map_err(convert_error)?)) + } +} + +#[cfg(feature = "std")] +impl TryFrom<[u8; VRF_PROOF_LENGTH]> for VRFProof { + type Error = SignatureError; + + fn try_from(raw: [u8; VRF_PROOF_LENGTH]) -> Result { + schnorrkel::vrf::VRFProof::from_bytes(&raw).map(VRFProof) + } +} + +#[cfg(feature = "std")] +impl TryFrom for VRFProof { + type Error = SignatureError; + + fn try_from(raw: RawVRFProof) -> Result { + schnorrkel::vrf::VRFProof::from_bytes(&raw.0).map(VRFProof) + } +} + +#[cfg(feature = "std")] +impl From for RawVRFProof { + fn from(output: VRFProof) -> RawVRFProof { + RawVRFProof(output.to_bytes()) + } +} + +#[cfg(feature = "std")] +fn convert_error(e: SignatureError) -> codec::Error { + use SignatureError::*; + use MultiSignatureStage::*; + match e { + EquationFalse => "Signature error: `EquationFalse`".into(), + PointDecompressionError => "Signature error: `PointDecompressionError`".into(), + ScalarFormatError => "Signature error: `ScalarFormatError`".into(), + NotMarkedSchnorrkel => "Signature error: `NotMarkedSchnorrkel`".into(), + BytesLengthError { .. } => "Signature error: `BytesLengthError`".into(), + MuSigAbsent { musig_stage: Commitment } => + "Signature error: `MuSigAbsent` at stage `Commitment`".into(), + MuSigAbsent { musig_stage: Reveal } => + "Signature error: `MuSigAbsent` at stage `Reveal`".into(), + MuSigAbsent { musig_stage: Cosignature } => + "Signature error: `MuSigAbsent` at stage `Commitment`".into(), + MuSigInconsistent { musig_stage: Commitment, duplicate: true } => + "Signature error: `MuSigInconsistent` at stage `Commitment` on duplicate".into(), + MuSigInconsistent { musig_stage: Commitment, duplicate: false } => + "Signature error: `MuSigInconsistent` at stage `Commitment` on not duplicate".into(), + MuSigInconsistent { musig_stage: Reveal, duplicate: true } => + "Signature error: `MuSigInconsistent` at stage `Reveal` on duplicate".into(), + MuSigInconsistent { musig_stage: Reveal, duplicate: false } => + "Signature error: `MuSigInconsistent` at stage `Reveal` on not duplicate".into(), + MuSigInconsistent { musig_stage: Cosignature, duplicate: true } => + "Signature error: `MuSigInconsistent` at stage `Cosignature` on duplicate".into(), + MuSigInconsistent { musig_stage: Cosignature, duplicate: false } => + "Signature error: `MuSigInconsistent` at stage `Cosignature` on not duplicate".into(), + } +} + +/// Schnorrkel randomness value. Same size as `VRFOutput`. +pub type Randomness = [u8; RANDOMNESS_LENGTH]; diff --git a/primitives/core/src/lib.rs b/primitives/core/src/lib.rs index 79380a6fc6..8d5ad7daae 100644 --- a/primitives/core/src/lib.rs +++ b/primitives/core/src/lib.rs @@ -74,7 +74,7 @@ pub mod testing; pub mod tasks; pub use self::hash::{H160, H256, H512, convert_hash}; -pub use self::uint::U256; +pub use self::uint::{U256, U512}; pub use changes_trie::{ChangesTrieConfiguration, ChangesTrieConfigurationRange}; #[cfg(feature = "full_crypto")] pub use crypto::{DeriveJunction, Pair, Public}; diff --git a/primitives/core/src/uint.rs b/primitives/core/src/uint.rs index 54ed7ca317..e666137c08 100644 --- a/primitives/core/src/uint.rs +++ b/primitives/core/src/uint.rs @@ -16,7 +16,7 @@ //! An unsigned fixed-size integer. -pub use primitive_types::U256; +pub use primitive_types::{U256, U512}; #[cfg(test)] mod tests { -- GitLab From 49fff310d63085d5a98c62d6b105829bcbb49a50 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 23 Mar 2020 13:19:15 +0100 Subject: [PATCH 049/300] Switch Treasury to `on_initialize`, Tips `KeepAlive` (#5352) * Switch Treasury to `on_initialize` * Fix bench compile --- frame/treasury/src/benchmarking.rs | 8 ++++---- frame/treasury/src/lib.rs | 12 ++++++------ frame/treasury/src/tests.rs | 24 +++++++++++++----------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/frame/treasury/src/benchmarking.rs b/frame/treasury/src/benchmarking.rs index 08318bdd6c..fb16af740a 100644 --- a/frame/treasury/src/benchmarking.rs +++ b/frame/treasury/src/benchmarking.rs @@ -20,7 +20,7 @@ use super::*; use frame_system::RawOrigin; use frame_benchmarking::{benchmarks, account}; -use sp_runtime::traits::OnFinalize; +use sp_runtime::traits::OnInitialize; use crate::Module as Treasury; @@ -82,7 +82,7 @@ fn create_tips(t: u32, hash: T::Hash, value: BalanceOf) -> Result<( Ok(()) } -// Create proposals that are approved for use in `on_finalize`. +// Create proposals that are approved for use in `on_initialize`. fn create_approved_proposals(n: u32) -> Result<(), &'static str> { for i in 0 .. n { let (caller, value, lookup) = setup_proposal::(i); @@ -199,13 +199,13 @@ benchmarks! { let caller = account("caller", t, SEED); }: _(RawOrigin::Signed(caller), hash) - on_finalize { + on_initialize { let p in 0 .. 100; let pot_account = Treasury::::account_id(); let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000.into()); let _ = T::Currency::make_free_balance_be(&pot_account, value); create_approved_proposals::(p)?; }: { - Treasury::::on_finalize(T::BlockNumber::zero()); + Treasury::::on_initialize(T::BlockNumber::zero()); } } diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index d7562d0767..2c808e0659 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -92,7 +92,7 @@ use serde::{Serialize, Deserialize}; use sp_std::prelude::*; use frame_support::{decl_module, decl_storage, decl_event, ensure, print, decl_error, Parameter}; use frame_support::traits::{ - Currency, ExistenceRequirement, Get, Imbalance, OnUnbalanced, ExistenceRequirement::AllowDeath, + Currency, Get, Imbalance, OnUnbalanced, ExistenceRequirement::KeepAlive, ReservableCurrency, WithdrawReason }; use sp_runtime::{Permill, ModuleId, Percent, RuntimeDebug, traits::{ @@ -553,7 +553,7 @@ decl_module! { Self::payout_tip(tip); } - fn on_finalize(n: T::BlockNumber) { + fn on_initialize(n: T::BlockNumber) { // Check to see if we should spend some funds! if (n % T::SpendPeriod::get()).is_zero() { Self::spend_funds(); @@ -631,7 +631,7 @@ impl Module { Self::retain_active_tips(&mut tips); tips.sort_by_key(|i| i.1); let treasury = Self::account_id(); - let max_payout = T::Currency::free_balance(&treasury); + let max_payout = Self::pot(); let mut payout = tips[tips.len() / 2].1.min(max_payout); if let Some((finder, deposit)) = tip.finder { let _ = T::Currency::unreserve(&finder, deposit); @@ -641,11 +641,11 @@ impl Module { payout -= finders_fee; // this should go through given we checked it's at most the free balance, but still // we only make a best-effort. - let _ = T::Currency::transfer(&treasury, &finder, finders_fee, AllowDeath); + let _ = T::Currency::transfer(&treasury, &finder, finders_fee, KeepAlive); } } // same as above: best-effort only. - let _ = T::Currency::transfer(&treasury, &tip.who, payout, AllowDeath); + let _ = T::Currency::transfer(&treasury, &tip.who, payout, KeepAlive); } // Spend some money! @@ -697,7 +697,7 @@ impl Module { &Self::account_id(), imbalance, WithdrawReason::Transfer.into(), - ExistenceRequirement::KeepAlive + KeepAlive ) { print("Inconsistent state - couldn't settle imbalance for funds spent by treasury"); // Nothing else to do here. diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index a5acb2efe5..d7e710639d 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -6,7 +6,7 @@ use sp_core::H256; use sp_runtime::{ Perbill, testing::Header, - traits::{BlakeTwo256, OnFinalize, IdentityLookup, BadOrigin}, + traits::{BlakeTwo256, OnInitialize, IdentityLookup, BadOrigin}, }; impl_outer_origin! { @@ -60,6 +60,8 @@ impl Contains for TenToFourteen { fn sorted_members() -> Vec { vec![10, 11, 12, 13, 14] } + #[cfg(feature = "runtime-benchmarks")] + fn add(_: &u64) { unimplemented!() } } parameter_types! { pub const ProposalBond: Permill = Permill::from_percent(5); @@ -287,7 +289,7 @@ fn accepted_spend_proposal_ignored_outside_spend_period() { assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); - >::on_finalize(1); + >::on_initialize(1); assert_eq!(Balances::free_balance(3), 0); assert_eq!(Treasury::pot(), 100); }); @@ -300,7 +302,7 @@ fn unused_pot_should_diminish() { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_eq!(Balances::total_issuance(), init_total_issuance + 100); - >::on_finalize(2); + >::on_initialize(2); assert_eq!(Treasury::pot(), 50); assert_eq!(Balances::total_issuance(), init_total_issuance + 50); }); @@ -314,7 +316,7 @@ fn rejected_spend_proposal_ignored_on_spend_period() { assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); - >::on_finalize(2); + >::on_initialize(2); assert_eq!(Balances::free_balance(3), 0); assert_eq!(Treasury::pot(), 50); }); @@ -365,7 +367,7 @@ fn accepted_spend_proposal_enacted_on_spend_period() { assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); - >::on_finalize(2); + >::on_initialize(2); assert_eq!(Balances::free_balance(3), 100); assert_eq!(Treasury::pot(), 0); }); @@ -380,11 +382,11 @@ fn pot_underflow_should_not_diminish() { assert_ok!(Treasury::propose_spend(Origin::signed(0), 150, 3)); assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); - >::on_finalize(2); + >::on_initialize(2); assert_eq!(Treasury::pot(), 100); // Pot hasn't changed let _ = Balances::deposit_into_existing(&Treasury::account_id(), 100).unwrap(); - >::on_finalize(4); + >::on_initialize(4); assert_eq!(Balances::free_balance(3), 150); // Fund has been spent assert_eq!(Treasury::pot(), 25); // Pot has finally changed }); @@ -402,13 +404,13 @@ fn treasury_account_doesnt_get_deleted() { assert_ok!(Treasury::propose_spend(Origin::signed(0), treasury_balance, 3)); assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); - >::on_finalize(2); + >::on_initialize(2); assert_eq!(Treasury::pot(), 100); // Pot hasn't changed assert_ok!(Treasury::propose_spend(Origin::signed(0), Treasury::pot(), 3)); assert_ok!(Treasury::approve_proposal(Origin::ROOT, 1)); - >::on_finalize(4); + >::on_initialize(4); assert_eq!(Treasury::pot(), 0); // Pot is emptied assert_eq!(Balances::free_balance(Treasury::account_id()), 1); // but the account is still there }); @@ -433,7 +435,7 @@ fn inexistent_account_works() { assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); assert_ok!(Treasury::approve_proposal(Origin::ROOT, 1)); - >::on_finalize(2); + >::on_initialize(2); assert_eq!(Treasury::pot(), 0); // Pot hasn't changed assert_eq!(Balances::free_balance(3), 0); // Balance of `3` hasn't changed @@ -441,7 +443,7 @@ fn inexistent_account_works() { assert_eq!(Treasury::pot(), 99); // Pot now contains funds assert_eq!(Balances::free_balance(Treasury::account_id()), 100); // Account does exist - >::on_finalize(4); + >::on_initialize(4); assert_eq!(Treasury::pot(), 0); // Pot has changed assert_eq!(Balances::free_balance(3), 99); // Balance of `3` has changed -- GitLab From 1d8fa432949b99fac4ea0bebfdd6675dee973aa1 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 23 Mar 2020 13:30:40 +0100 Subject: [PATCH 050/300] pallet-evm: configurable gasometer config (#5320) * pallet-evm: configurable gasometer config * Bump runtime impl_version * Update evm to 0.16.1 Documentation updates Co-authored-by: Gavin Wood --- Cargo.lock | 18 +++++++++--------- frame/evm/src/backend.rs | 5 ----- frame/evm/src/lib.rs | 11 +++++++++-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 308ac78871..5ac286d14c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1227,9 +1227,9 @@ dependencies = [ [[package]] name = "evm" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3fd803d8dd69ee382f5d2010b6da5442bf41f94e46606357e8ebb994021cc7a" +checksum = "23a5c0ebf219b2b878bde1838282e0bb69828338df37fd136f1e93182ae35a59" dependencies = [ "evm-core", "evm-gasometer", @@ -1242,18 +1242,18 @@ dependencies = [ [[package]] name = "evm-core" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06f59a5b6832f6826a0d222f354ac4a83747b6b7cadc6b539056daafea948536" +checksum = "d944a07232006a3435df8aa014fd364ed04cb28d731782339e9c56436594f2d4" dependencies = [ "primitive-types", ] [[package]] name = "evm-gasometer" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66330d03fbd117156b3c54a7d41d22b40ba8bf2a07b80f23f95359e22eada4da" +checksum = "6a0d986953234d3786d0ca1beaaabab6a581d2128f8ec36c8c57e9c45e3d2b32" dependencies = [ "evm-core", "evm-runtime", @@ -1262,9 +1262,9 @@ dependencies = [ [[package]] name = "evm-runtime" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca05dc5b906d3c93b8e679a6dc0973c9d072e9962f8b4483530eb9a0ffc14ea5" +checksum = "1833c22f9518007d3cc28e14ff586263543516a1c7a147b260c603e4deb95403" dependencies = [ "evm-core", "primitive-types", @@ -8562,7 +8562,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" dependencies = [ - "rand 0.7.3", + "rand 0.6.5", ] [[package]] diff --git a/frame/evm/src/backend.rs b/frame/evm/src/backend.rs index d72c8b785e..e0cb816c60 100644 --- a/frame/evm/src/backend.rs +++ b/frame/evm/src/backend.rs @@ -7,7 +7,6 @@ use sp_core::{U256, H256, H160}; use sp_runtime::traits::UniqueSaturatedInto; use frame_support::storage::{StorageMap, StorageDoubleMap}; use sha3::{Keccak256, Digest}; -use evm::Config; use evm::backend::{Backend as BackendT, ApplyBackend, Apply}; use crate::{Trait, Accounts, AccountStorages, AccountCodes, Module, Event}; @@ -43,10 +42,6 @@ pub struct Vicinity { pub origin: H160, } -/// Gasometer config used for executor. Currently this is hard-coded to -/// Istanbul hard fork. -pub static GASOMETER_CONFIG: Config = Config::istanbul(); - /// Substrate backend for EVM. pub struct Backend<'vicinity, T> { vicinity: &'vicinity Vicinity, diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 5a9cb852fd..efb4c3c4f9 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -35,7 +35,7 @@ use sp_runtime::{ DispatchResult, traits::{UniqueSaturatedInto, AccountIdConversion, SaturatedConversion}, }; use sha3::{Digest, Keccak256}; -use evm::{ExitReason, ExitSucceed, ExitError}; +use evm::{ExitReason, ExitSucceed, ExitError, Config}; use evm::executor::StackExecutor; use evm::backend::ApplyBackend; @@ -116,6 +116,8 @@ impl Precompiles for () { } } +static ISTANBUL_CONFIG: Config = Config::istanbul(); + /// EVM module trait pub trait Trait: frame_system::Trait + pallet_timestamp::Trait { /// Calculator for current gas price. @@ -128,6 +130,11 @@ pub trait Trait: frame_system::Trait + pallet_timestamp::Trait { type Event: From + Into<::Event>; /// Precompiles associated with this EVM engine. type Precompiles: Precompiles; + + /// EVM config used in the module. + fn config() -> &'static Config { + &ISTANBUL_CONFIG + } } decl_storage! { @@ -381,7 +388,7 @@ impl Module { let mut executor = StackExecutor::new_with_precompile( &backend, gas_limit as usize, - &backend::GASOMETER_CONFIG, + T::config(), T::Precompiles::execute, ); -- GitLab From 64bfc963a942ecbc6d7f68dd899499483290c028 Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Mon, 23 Mar 2020 14:07:25 +0100 Subject: [PATCH 051/300] Regression algorithm for runtime benchmarks (#5288) * Add linregress * Regression, initial stuff. * More analytics * whitespace * Fix * Median slopes regression algo * Warnings * Update to lastest benchmark changes. * Use both algorithms temp. * Move analysis to frame. * Fix tests. * Only build analysis in std Co-authored-by: Gav Wood --- Cargo.lock | 103 ++++++++++ frame/benchmarking/Cargo.toml | 1 + frame/benchmarking/src/analysis.rs | 243 ++++++++++++++++++++++++ frame/benchmarking/src/lib.rs | 7 +- utils/frame/benchmarking-cli/src/lib.rs | 13 +- 5 files changed, 365 insertions(+), 2 deletions(-) create mode 100644 frame/benchmarking/src/analysis.rs diff --git a/Cargo.lock b/Cargo.lock index 5ac286d14c..d216ed9cdc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,6 +68,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "alga" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658f9468113d34781f6ca9d014d174c74b73de870f1e0e3ad32079bbab253b19" +dependencies = [ + "approx", + "libm", + "num-complex", + "num-traits", +] + [[package]] name = "ansi_term" version = "0.11.0" @@ -104,6 +116,15 @@ dependencies = [ "xdg", ] +[[package]] +name = "approx" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +dependencies = [ + "num-traits", +] + [[package]] name = "arc-swap" version = "0.4.4" @@ -1429,6 +1450,7 @@ version = "2.0.0-alpha.4" dependencies = [ "frame-support", "frame-system", + "linregress", "parity-scale-codec", "sp-api", "sp-io", @@ -2595,6 +2617,12 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "libm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" + [[package]] name = "libp2p" version = "0.16.2" @@ -3063,6 +3091,17 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "linregress" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9290cf6f928576eeb9c096c6fad9d8d452a0a1a70a2bbffa6e36064eedc0aac9" +dependencies = [ + "failure", + "nalgebra", + "statrs", +] + [[package]] name = "lite-json" version = "0.1.0" @@ -3123,6 +3162,15 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +[[package]] +name = "matrixmultiply" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4f7ec66360130972f34830bfad9ef05c6610a43938a467bcc9ab9369ab3478f" +dependencies = [ + "rawpointer", +] + [[package]] name = "maybe-uninit" version = "2.0.0" @@ -3272,6 +3320,23 @@ dependencies = [ "unsigned-varint", ] +[[package]] +name = "nalgebra" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaa9fddbc34c8c35dd2108515587b8ce0cab396f17977b8c738568e4edb521a2" +dependencies = [ + "alga", + "approx", + "generic-array", + "matrixmultiply", + "num-complex", + "num-rational", + "num-traits", + "rand 0.6.5", + "typenum", +] + [[package]] name = "names" version = "0.11.0" @@ -3721,6 +3786,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg 1.0.0", + "num-traits", +] + [[package]] name = "num-integer" version = "0.1.42" @@ -5122,6 +5197,19 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "winapi 0.3.8", +] + [[package]] name = "rand" version = "0.6.5" @@ -5291,6 +5379,12 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rayon" version = "1.3.0" @@ -7532,6 +7626,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "statrs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10102ac8d55e35db2b3fafc26f81ba8647da2e15879ab686a67e6d19af2685e8" +dependencies = [ + "rand 0.5.6", +] + [[package]] name = "stream-cipher" version = "0.3.2" diff --git a/frame/benchmarking/Cargo.toml b/frame/benchmarking/Cargo.toml index efd15cf004..d12b415159 100644 --- a/frame/benchmarking/Cargo.toml +++ b/frame/benchmarking/Cargo.toml @@ -9,6 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "Macro for benchmarking a FRAME runtime." [dependencies] +linregress = "0.1" codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api", default-features = false } sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../primitives/runtime-interface", default-features = false } diff --git a/frame/benchmarking/src/analysis.rs b/frame/benchmarking/src/analysis.rs new file mode 100644 index 0000000000..fdf1210832 --- /dev/null +++ b/frame/benchmarking/src/analysis.rs @@ -0,0 +1,243 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Tools for analysing the benchmark results. + +use std::collections::BTreeMap; +use linregress::{FormulaRegressionBuilder, RegressionDataBuilder, RegressionModel}; +use crate::BenchmarkResults; + +pub struct Analysis { + base: u128, + slopes: Vec, + names: Vec, + value_dists: Option, u128, u128)>>, + model: Option, +} + +impl Analysis { + pub fn median_slopes(r: &Vec) -> Option { + let results = r[0].0.iter().enumerate().map(|(i, &(param, _))| { + let mut counted = BTreeMap::, usize>::new(); + for (params, _, _) in r.iter() { + let mut p = params.iter().map(|x| x.1).collect::>(); + p[i] = 0; + *counted.entry(p).or_default() += 1; + } + let others: Vec = counted.iter().max_by_key(|i| i.1).expect("r is not empty; qed").0.clone(); + let values = r.iter() + .filter(|v| + v.0.iter() + .map(|x| x.1) + .zip(others.iter()) + .enumerate() + .all(|(j, (v1, v2))| j == i || v1 == *v2) + ).map(|(ps, v, _)| (ps[i].1, *v)) + .collect::>(); + (format!("{:?}", param), i, others, values) + }).collect::>(); + + let models = results.iter().map(|(_, _, _, ref values)| { + let mut slopes = vec![]; + for (i, &(x1, y1)) in values.iter().enumerate() { + for &(x2, y2) in values.iter().skip(i + 1) { + if x1 != x2 { + slopes.push((y1 as f64 - y2 as f64) / (x1 as f64 - x2 as f64)); + } + } + } + slopes.sort_by(|a, b| a.partial_cmp(b).expect("values well defined; qed")); + let slope = slopes[slopes.len() / 2]; + + let mut offsets = vec![]; + for &(x, y) in values.iter() { + offsets.push(y as f64 - slope * x as f64); + } + offsets.sort_by(|a, b| a.partial_cmp(b).expect("values well defined; qed")); + let offset = offsets[offsets.len() / 2]; + + (offset, slope) + }).collect::>(); + + let models = models.iter() + .zip(results.iter()) + .map(|((offset, slope), (_, i, others, _))| { + let over = others.iter() + .enumerate() + .filter(|(j, _)| j != i) + .map(|(j, v)| models[j].1 * *v as f64) + .fold(0f64, |acc, i| acc + i); + (*offset - over, *slope) + }) + .collect::>(); + + let base = models[0].0.max(0f64) as u128; + let slopes = models.iter().map(|x| x.1.max(0f64) as u128).collect::>(); + + Some(Self { + base, + slopes, + names: results.into_iter().map(|x| x.0).collect::>(), + value_dists: None, + model: None, + }) + } + + pub fn min_squares_iqr(r: &Vec) -> Option { + let mut results = BTreeMap::, Vec>::new(); + for &(ref params, t, _) in r.iter() { + let p = params.iter().map(|x| x.1).collect::>(); + results.entry(p).or_default().push(t); + } + for (_, rs) in results.iter_mut() { + rs.sort(); + let ql = rs.len() / 4; + *rs = rs[ql..rs.len() - ql].to_vec(); + } + + let mut data = vec![("Y", results.iter().flat_map(|x| x.1.iter().map(|v| *v as f64)).collect())]; + + let names = r[0].0.iter().map(|x| format!("{:?}", x.0)).collect::>(); + data.extend(names.iter() + .enumerate() + .map(|(i, p)| ( + p.as_str(), + results.iter() + .flat_map(|x| Some(x.0[i] as f64) + .into_iter() + .cycle() + .take(x.1.len()) + ).collect::>() + )) + ); + + let data = RegressionDataBuilder::new().build_from(data).ok()?; + + let model = FormulaRegressionBuilder::new() + .data(&data) + .formula(format!("Y ~ {}", names.join(" + "))) + .fit() + .ok()?; + + let slopes = model.parameters.regressor_values.iter() + .enumerate() + .map(|(_, x)| (*x + 0.5) as u128) + .collect(); + + let value_dists = results.iter().map(|(p, vs)| { + let total = vs.iter() + .fold(0u128, |acc, v| acc + *v); + let mean = total / vs.len() as u128; + let sum_sq_diff = vs.iter() + .fold(0u128, |acc, v| { + let d = mean.max(*v) - mean.min(*v); + acc + d * d + }); + let stddev = (sum_sq_diff as f64 / vs.len() as f64).sqrt() as u128; + (p.clone(), mean, stddev) + }).collect::>(); + + Some(Self { + base: (model.parameters.intercept_value + 0.5) as u128, + slopes, + names, + value_dists: Some(value_dists), + model: Some(model), + }) + } +} + +fn ms(mut nanos: u128) -> String { + let mut x = 100_000u128; + while x > 1 { + if nanos > x * 1_000 { + nanos = nanos / x * x; + break; + } + x /= 10; + } + format!("{}", nanos as f64 / 1_000f64) +} + +impl std::fmt::Display for Analysis { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + if let Some(ref value_dists) = self.value_dists { + writeln!(f, "\nData points distribution:")?; + writeln!(f, "{} mean µs sigma µs %", self.names.iter().map(|p| format!("{:>5}", p)).collect::>().join(" "))?; + for (param_values, mean, sigma) in value_dists.iter() { + writeln!(f, "{} {:>8} {:>8} {:>3}.{}%", + param_values.iter().map(|v| format!("{:>5}", v)).collect::>().join(" "), + ms(*mean), + ms(*sigma), + (sigma * 100 / mean), + (sigma * 1000 / mean % 10) + )?; + } + } + if let Some(ref model) = self.model { + writeln!(f, "\nQuality and confidence:")?; + writeln!(f, "param error")?; + for (p, se) in self.names.iter().zip(model.se.regressor_values.iter()) { + writeln!(f, "{} {:>8}", p, ms(*se as u128))?; + } + } + + writeln!(f, "\nModel:")?; + writeln!(f, "Time ~= {:>8}", ms(self.base))?; + for (&t, n) in self.slopes.iter().zip(self.names.iter()) { + writeln!(f, " + {} {:>8}", n, ms(t))?; + } + writeln!(f, " µs") + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::BenchmarkParameter; + + #[test] + fn analysis_median_slopes_should_work() { + let a = Analysis::median_slopes(&vec![ + (vec![(BenchmarkParameter::n, 1), (BenchmarkParameter::m, 5)], 11_500_000, 0), + (vec![(BenchmarkParameter::n, 2), (BenchmarkParameter::m, 5)], 12_500_000, 0), + (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 5)], 13_500_000, 0), + (vec![(BenchmarkParameter::n, 4), (BenchmarkParameter::m, 5)], 14_500_000, 0), + (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 1)], 13_100_000, 0), + (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 3)], 13_300_000, 0), + (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 7)], 13_700_000, 0), + (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 10)], 14_000_000, 0), + ]).unwrap(); + assert_eq!(a.base, 10_000_000); + assert_eq!(a.slopes, vec![1_000_000, 100_000]); + } + + #[test] + fn analysis_median_min_squares_should_work() { + let a = Analysis::min_squares_iqr(&vec![ + (vec![(BenchmarkParameter::n, 1), (BenchmarkParameter::m, 5)], 11_500_000, 0), + (vec![(BenchmarkParameter::n, 2), (BenchmarkParameter::m, 5)], 12_500_000, 0), + (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 5)], 13_500_000, 0), + (vec![(BenchmarkParameter::n, 4), (BenchmarkParameter::m, 5)], 14_500_000, 0), + (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 1)], 13_100_000, 0), + (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 3)], 13_300_000, 0), + (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 7)], 13_700_000, 0), + (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 10)], 14_000_000, 0), + ]).unwrap(); + assert_eq!(a.base, 10_000_000); + assert_eq!(a.slopes, vec![1_000_000, 100_000]); + } +} diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index a18048d305..f6094739bf 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -20,7 +20,12 @@ mod tests; mod utils; +#[cfg(feature = "std")] +mod analysis; + pub use utils::*; +#[cfg(feature = "std")] +pub use analysis::Analysis; #[doc(hidden)] pub use sp_io::storage::root as storage_root; pub use sp_runtime::traits::Dispatchable; @@ -157,7 +162,7 @@ macro_rules! benchmarks_iter { $( $rest:tt )* ) => { $crate::benchmarks_iter! { - { $( $common )* } ( $( $names )* ) $name { $( $code )* }: { + { $( $common )* } ( $( $names )* ) $name { $( $code )* }: { as $crate::Dispatchable>::dispatch(Call::::$dispatch($($arg),*), $origin.into())?; } $( $rest )* } diff --git a/utils/frame/benchmarking-cli/src/lib.rs b/utils/frame/benchmarking-cli/src/lib.rs index b2aa4bd6a2..1c02a75401 100644 --- a/utils/frame/benchmarking-cli/src/lib.rs +++ b/utils/frame/benchmarking-cli/src/lib.rs @@ -22,7 +22,7 @@ use sc_client_db::BenchmarkingState; use sc_service::{Configuration, ChainSpec}; use sc_executor::{NativeExecutor, NativeExecutionDispatch}; use codec::{Encode, Decode}; -use frame_benchmarking::BenchmarkResults; +use frame_benchmarking::{BenchmarkResults, Analysis}; use sp_core::{ tasks, traits::KeystoreExt, @@ -163,6 +163,17 @@ impl BenchmarkCmd { print!("{:?},{:?}\n", result.1, result.2); }); + print!("\n"); + + // Conduct analysis. + if let Some(analysis) = Analysis::median_slopes(&results) { + println!("Median Slopes Analysis\n========\n{}", analysis); + } + + if let Some(analysis) = Analysis::min_squares_iqr(&results) { + println!("Min Squares Analysis\n========\n{}", analysis); + } + eprintln!("Done."); } Err(error) => eprintln!("Error: {:?}", error), -- GitLab From 22f13a80ab7b012f677b9a8690c8c1e50acfa28b Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Mon, 23 Mar 2020 14:11:46 +0100 Subject: [PATCH 052/300] Update yamux to version 0.4.5 (#5354) --- Cargo.lock | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d216ed9cdc..f7bf247e02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9273,17 +9273,16 @@ checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" [[package]] name = "yamux" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03098897b734bd943ab23f6aa9f98aafd72a88516deedd66f9d564c57bf2f19" +checksum = "84300bb493cc878f3638b981c62b4632ec1a5c52daaa3036651e8c106d3b55ea" dependencies = [ - "bytes 0.5.4", "futures 0.3.4", "log 0.4.8", "nohash-hasher", "parking_lot 0.10.0", "rand 0.7.3", - "thiserror", + "static_assertions", ] [[package]] -- GitLab From 9557c6f1a0a99a61e5c465beca94bb3a8707e629 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 23 Mar 2020 07:09:05 -0700 Subject: [PATCH 053/300] Versioning for #[runtime-interface] (#5328) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * versionned runtime-interface * use only one additional wasm blob * alter docs * formatting, naming and docs * add comment for test * version duplicate err * RuntimeInterfaceItem -> RuntimeInterfaceFunction< * test naming * version checking * remove spaces * Update primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs Co-Authored-By: Bastian Köcher * remove sanity checks and reduce coverage * add doc comment Co-authored-by: Bastian Köcher --- Cargo.lock | 12 ++ Cargo.toml | 1 + .../bare_function_interface.rs | 74 +++++++-- .../host_function_interface.rs | 48 +++--- .../src/runtime_interface/trait_decl_impl.rs | 76 ++++++--- .../runtime-interface/proc-macro/src/utils.rs | 146 +++++++++++++++++- primitives/runtime-interface/src/lib.rs | 54 +++++-- .../test-wasm-deprecated/Cargo.toml | 23 +++ .../test-wasm-deprecated/build.rs | 26 ++++ .../test-wasm-deprecated/src/lib.rs | 52 +++++++ .../runtime-interface/test-wasm/src/lib.rs | 21 ++- primitives/runtime-interface/test/Cargo.toml | 1 + primitives/runtime-interface/test/src/lib.rs | 51 ++++-- .../tests/ui/no_duplicate_versions.rs | 11 ++ .../tests/ui/no_duplicate_versions.stderr | 11 ++ .../tests/ui/no_gaps_in_versions.rs | 17 ++ .../tests/ui/no_gaps_in_versions.stderr | 5 + .../tests/ui/no_generic_parameters.stderr | 11 -- .../tests/ui/no_generic_parameters_method.rs | 8 + .../ui/no_generic_parameters_method.stderr | 5 + ...ters.rs => no_generic_parameters_trait.rs} | 2 +- .../ui/no_generic_parameters_trait.stderr | 5 + 22 files changed, 556 insertions(+), 104 deletions(-) create mode 100644 primitives/runtime-interface/test-wasm-deprecated/Cargo.toml create mode 100644 primitives/runtime-interface/test-wasm-deprecated/build.rs create mode 100644 primitives/runtime-interface/test-wasm-deprecated/src/lib.rs create mode 100644 primitives/runtime-interface/tests/ui/no_duplicate_versions.rs create mode 100644 primitives/runtime-interface/tests/ui/no_duplicate_versions.stderr create mode 100644 primitives/runtime-interface/tests/ui/no_gaps_in_versions.rs create mode 100644 primitives/runtime-interface/tests/ui/no_gaps_in_versions.stderr delete mode 100644 primitives/runtime-interface/tests/ui/no_generic_parameters.stderr create mode 100644 primitives/runtime-interface/tests/ui/no_generic_parameters_method.rs create mode 100644 primitives/runtime-interface/tests/ui/no_generic_parameters_method.stderr rename primitives/runtime-interface/tests/ui/{no_generic_parameters.rs => no_generic_parameters_trait.rs} (85%) create mode 100644 primitives/runtime-interface/tests/ui/no_generic_parameters_trait.stderr diff --git a/Cargo.lock b/Cargo.lock index f7bf247e02..ba96516dd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7442,6 +7442,7 @@ dependencies = [ "sp-runtime", "sp-runtime-interface", "sp-runtime-interface-test-wasm", + "sp-runtime-interface-test-wasm-deprecated", "sp-state-machine", ] @@ -7456,6 +7457,17 @@ dependencies = [ "substrate-wasm-builder-runner", ] +[[package]] +name = "sp-runtime-interface-test-wasm-deprecated" +version = "2.0.0-dev" +dependencies = [ + "sp-core", + "sp-io", + "sp-runtime-interface", + "sp-std", + "substrate-wasm-builder-runner", +] + [[package]] name = "sp-sandbox" version = "0.8.0-alpha.4" diff --git a/Cargo.toml b/Cargo.toml index 5a88ed28dd..d86bab8abd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -134,6 +134,7 @@ members = [ "primitives/runtime-interface", "primitives/runtime-interface/proc-macro", "primitives/runtime-interface/test-wasm", + "primitives/runtime-interface/test-wasm-deprecated", "primitives/runtime-interface/test", "primitives/serializer", "primitives/session", diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs index bdddc5eba7..e7c34fbf99 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs @@ -30,7 +30,7 @@ use crate::utils::{ generate_crate_access, create_exchangeable_host_function_ident, get_function_arguments, - get_function_argument_names, get_trait_methods, + get_function_argument_names, get_runtime_interface, create_function_ident_with_version, }; use syn::{ @@ -47,19 +47,40 @@ use std::iter; /// of the trait method. pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool) -> Result { let trait_name = &trait_def.ident; - get_trait_methods(trait_def).try_fold(TokenStream::new(), |mut t, m| { - t.extend(function_for_method(trait_name, m, is_wasm_only)?); + let runtime_interface = get_runtime_interface(trait_def)?; + + // latest version dispatch + let token_stream: Result = runtime_interface.latest_versions() + .try_fold( + TokenStream::new(), + |mut t, (latest_version, method)| { + t.extend(function_for_method(method, latest_version, is_wasm_only)?); + Ok(t) + } + ); + + // earlier versions compatibility dispatch (only std variant) + let result: Result = runtime_interface.all_versions().try_fold(token_stream?, |mut t, (version, method)| + { + t.extend(function_std_impl(trait_name, method, version, is_wasm_only)?); Ok(t) - }) + }); + + result } /// Generates the bare function implementation for the given method for the host and wasm side. fn function_for_method( - trait_name: &Ident, method: &TraitItemMethod, + latest_version: u32, is_wasm_only: bool, ) -> Result { - let std_impl = function_std_impl(trait_name, method, is_wasm_only)?; + let std_impl = if !is_wasm_only { + function_std_latest_impl(method, latest_version)? + } else { + quote!() + }; + let no_std_impl = function_no_std_impl(method)?; Ok( @@ -78,7 +99,7 @@ fn function_no_std_impl(method: &TraitItemMethod) -> Result { let args = get_function_arguments(&method.sig); let arg_names = get_function_argument_names(&method.sig); let return_value = &method.sig.output; - let attrs = &method.attrs; + let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version")); Ok( quote! { @@ -92,13 +113,40 @@ fn function_no_std_impl(method: &TraitItemMethod) -> Result { ) } +/// Generate call to latest function version for `cfg((feature = "std")` +/// +/// This should generate simple `fn func(..) { func_version_(..) }`. +fn function_std_latest_impl( + method: &TraitItemMethod, + latest_version: u32, +) -> Result { + let function_name = &method.sig.ident; + let args = get_function_arguments(&method.sig).map(FnArg::Typed); + let arg_names = get_function_argument_names(&method.sig).collect::>(); + let return_value = &method.sig.output; + let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version")); + let latest_function_name = create_function_ident_with_version(&method.sig.ident, latest_version); + + Ok(quote_spanned! { method.span() => + #[cfg(feature = "std")] + #( #attrs )* + pub fn #function_name( #( #args, )* ) #return_value { + #latest_function_name( + #( #arg_names, )* + ) + } + }) +} + /// Generates the bare function implementation for `cfg(feature = "std")`. fn function_std_impl( trait_name: &Ident, method: &TraitItemMethod, + version: u32, is_wasm_only: bool, ) -> Result { - let function_name = &method.sig.ident; + let function_name = create_function_ident_with_version(&method.sig.ident, version); + let crate_ = generate_crate_access(); let args = get_function_arguments(&method.sig).map(FnArg::Typed).chain( // Add the function context as last parameter when this is a wasm only interface. @@ -115,16 +163,15 @@ fn function_std_impl( ).take(1), ); let return_value = &method.sig.output; - let attrs = &method.attrs; + let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version")); // Don't make the function public accessible when this is a wasm only interface. - let vis = if is_wasm_only { quote!() } else { quote!(pub) }; - let call_to_trait = generate_call_to_trait(trait_name, method, is_wasm_only); + let call_to_trait = generate_call_to_trait(trait_name, method, version, is_wasm_only); Ok( quote_spanned! { method.span() => #[cfg(feature = "std")] #( #attrs )* - #vis fn #function_name( #( #args, )* ) #return_value { + fn #function_name( #( #args, )* ) #return_value { #call_to_trait } } @@ -135,10 +182,11 @@ fn function_std_impl( fn generate_call_to_trait( trait_name: &Ident, method: &TraitItemMethod, + version: u32, is_wasm_only: bool, ) -> TokenStream { let crate_ = generate_crate_access(); - let method_name = &method.sig.ident; + let method_name = create_function_ident_with_version(&method.sig.ident, version); let expect_msg = format!( "`{}` called outside of an Externalities-provided environment.", method_name, diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs index 42bfe3c712..205ee87105 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs @@ -23,13 +23,13 @@ use crate::utils::{ generate_crate_access, create_host_function_ident, get_function_argument_names, get_function_argument_types_without_ref, get_function_argument_types_ref_and_mut, - get_function_argument_names_and_types_without_ref, get_trait_methods, get_function_arguments, - get_function_argument_types, create_exchangeable_host_function_ident, + get_function_argument_names_and_types_without_ref, get_function_arguments, + get_function_argument_types, create_exchangeable_host_function_ident, get_runtime_interface, + create_function_ident_with_version, }; use syn::{ - ItemTrait, TraitItemMethod, Result, ReturnType, Ident, TraitItem, Pat, Error, Signature, - spanned::Spanned, + ItemTrait, TraitItemMethod, Result, ReturnType, Ident, Pat, Error, Signature, spanned::Spanned, }; use proc_macro2::{TokenStream, Span}; @@ -44,13 +44,15 @@ use std::iter::{Iterator, self}; /// implementations for the host functions on the host. pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool) -> Result { let trait_name = &trait_def.ident; - let extern_host_function_impls = get_trait_methods(trait_def) - .try_fold(TokenStream::new(), |mut t, m| { - t.extend(generate_extern_host_function(m, trait_name)?); + let extern_host_function_impls = get_runtime_interface(trait_def)? + .latest_versions() + .try_fold(TokenStream::new(), |mut t, (version, method)| { + t.extend(generate_extern_host_function(method, version, trait_name)?); Ok::<_, Error>(t) })?; - let exchangeable_host_functions = get_trait_methods(trait_def) - .try_fold(TokenStream::new(), |mut t, m| { + let exchangeable_host_functions = get_runtime_interface(trait_def)? + .latest_versions() + .try_fold(TokenStream::new(), |mut t, (_, m)| { t.extend(generate_exchangeable_host_function(m)?); Ok::<_, Error>(t) })?; @@ -76,7 +78,7 @@ pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool) -> Result Result { +fn generate_extern_host_function(method: &TraitItemMethod, version: u32, trait_name: &Ident) -> Result { let crate_ = generate_crate_access(); let args = get_function_arguments(&method.sig); let arg_types = get_function_argument_types_without_ref(&method.sig); @@ -85,7 +87,7 @@ fn generate_extern_host_function(method: &TraitItemMethod, trait_name: &Ident) - let arg_names2 = get_function_argument_names(&method.sig); let arg_names3 = get_function_argument_names(&method.sig); let function = &method.sig.ident; - let ext_function = create_host_function_ident(&method.sig.ident, trait_name); + let ext_function = create_host_function_ident(&method.sig.ident, version, trait_name); let doc_string = format!( " Default extern host function implementation for [`super::{}`].", method.sig.ident, @@ -157,14 +159,12 @@ fn generate_exchangeable_host_function(method: &TraitItemMethod) -> Result Result { let crate_ = generate_crate_access(); - let host_functions = trait_def - .items - .iter() - .filter_map(|i| match i { - TraitItem::Method(ref method) => Some(method), - _ => None, - }) - .map(|m| generate_host_function_implementation(&trait_def.ident, m, is_wasm_only)) + + let host_functions = get_runtime_interface(trait_def)? + .all_versions() + .map(|(version, method)| + generate_host_function_implementation(&trait_def.ident, method, version, is_wasm_only) + ) .collect::>>()?; Ok( @@ -191,9 +191,10 @@ fn generate_host_functions_struct(trait_def: &ItemTrait, is_wasm_only: bool) -> fn generate_host_function_implementation( trait_name: &Ident, method: &TraitItemMethod, + version: u32, is_wasm_only: bool, ) -> Result { - let name = create_host_function_ident(&method.sig.ident, trait_name).to_string(); + let name = create_host_function_ident(&method.sig.ident, version, trait_name).to_string(); let struct_name = Ident::new(&name.to_pascal_case(), Span::call_site()); let crate_ = generate_crate_access(); let signature = generate_wasm_interface_signature_for_host_function(&method.sig)?; @@ -202,7 +203,7 @@ fn generate_host_function_implementation( trait_name, ).collect::>>()?; let ffi_to_host_values = generate_ffi_to_host_value(&method.sig).collect::>>()?; - let host_function_call = generate_host_function_call(&method.sig, is_wasm_only); + let host_function_call = generate_host_function_call(&method.sig, version, is_wasm_only); let into_preallocated_ffi_value = generate_into_preallocated_ffi_value(&method.sig)?; let convert_return_value = generate_return_value_into_wasm_value(&method.sig); @@ -211,7 +212,6 @@ fn generate_host_function_implementation( { struct #struct_name; - #[allow(unused)] impl #crate_::sp_wasm_interface::Function for #struct_name { fn name(&self) -> &str { #name @@ -322,8 +322,8 @@ fn generate_ffi_to_host_value<'a>( } /// Generate the code to call the host function and the ident that stores the result. -fn generate_host_function_call(sig: &Signature, is_wasm_only: bool) -> TokenStream { - let host_function_name = &sig.ident; +fn generate_host_function_call(sig: &Signature, version: u32, is_wasm_only: bool) -> TokenStream { + let host_function_name = create_function_ident_with_version(&sig.ident, version); let result_var_name = generate_host_function_result_var_name(&sig.ident); let ref_and_mut = get_function_argument_types_ref_and_mut(sig).map(|ram| ram.map(|(vr, vm)| quote!(#vr #vm)) diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs index af71ba3241..542c4ca4b8 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs @@ -17,10 +17,15 @@ //! Checks the trait declaration, makes the trait declaration module local, removes all method //! default implementations and implements the trait for `&mut dyn Externalities`. -use crate::utils::{generate_crate_access, get_function_argument_types_without_ref}; +use crate::utils::{ + generate_crate_access, + get_function_argument_types_without_ref, + get_runtime_interface, + create_function_ident_with_version, +}; use syn::{ - ItemTrait, TraitItemMethod, Result, TraitItem, Error, fold::{self, Fold}, spanned::Spanned, + ItemTrait, TraitItemMethod, Result, Error, fold::{self, Fold}, spanned::Spanned, Visibility, Receiver, Type, Generics, }; @@ -32,7 +37,7 @@ use quote::quote; /// essential definition and implement this essential definition for `dyn Externalities`. pub fn process(trait_def: &ItemTrait, is_wasm_only: bool) -> Result { let impl_trait = impl_trait_for_externalities(trait_def, is_wasm_only)?; - let essential_trait_def = ToEssentialTraitDef::convert(trait_def.clone())?; + let essential_trait_def = declare_essential_trait(trait_def)?; Ok( quote! { @@ -48,29 +53,35 @@ pub fn process(trait_def: &ItemTrait, is_wasm_only: bool) -> Result struct ToEssentialTraitDef { /// All errors found while doing the conversion. errors: Vec, + methods: Vec, } impl ToEssentialTraitDef { - /// Convert the given trait definition to the essential trait definition. - fn convert(trait_def: ItemTrait) -> Result { - let mut folder = ToEssentialTraitDef { - errors: Vec::new(), - }; - - let res = folder.fold_item_trait(trait_def); + fn new() -> Self { + ToEssentialTraitDef { errors: vec![], methods: vec![] } + } - if let Some(first_error) = folder.errors.pop() { + fn into_methods(self) -> Result> { + let mut errors = self.errors; + let methods = self.methods; + if let Some(first_error) = errors.pop() { Err( - folder.errors.into_iter().fold(first_error, |mut o, n| { + errors.into_iter().fold(first_error, |mut o, n| { o.combine(n); o }) ) } else { - Ok(res) + Ok(methods) } } + fn process(&mut self, method: &TraitItemMethod, version: u32) { + let mut folded = self.fold_trait_item_method(method.clone()); + folded.sig.ident = create_function_ident_with_version(&folded.sig.ident, version); + self.methods.push(folded); + } + fn push_error(&mut self, span: &S, msg: &str) { self.errors.push(Error::new(span.span(), msg)); } @@ -98,6 +109,8 @@ impl Fold for ToEssentialTraitDef { self.error_on_generic_parameters(&method.sig.generics); + method.attrs.retain(|a| !a.path.is_ident("version")); + fold::fold_trait_item_method(self, method) } @@ -117,17 +130,40 @@ impl Fold for ToEssentialTraitDef { } } +fn declare_essential_trait(trait_def: &ItemTrait) -> Result { + let trait_ = &trait_def.ident; + + if let Some(param) = trait_def.generics.params.first() { + return Err(Error::new(param.span(), "Generic parameters not supported.")) + } + + let interface = get_runtime_interface(trait_def)?; + let mut folder = ToEssentialTraitDef::new(); + for (version, interface_method) in interface.all_versions() { + folder.process(interface_method, version); + } + let methods = folder.into_methods()?; + + Ok( + quote! { + trait #trait_ { + #( #methods )* + } + } + ) +} + /// Implements the given trait definition for `dyn Externalities`. fn impl_trait_for_externalities(trait_def: &ItemTrait, is_wasm_only: bool) -> Result { let trait_ = &trait_def.ident; let crate_ = generate_crate_access(); - let methods = trait_def - .items - .iter() - .filter_map(|i| match i { - TraitItem::Method(ref method) => Some(method), - _ => None, - }); + let interface = get_runtime_interface(trait_def)?; + let methods = interface.all_versions().map(|(version, method)| { + let mut cloned = method.clone(); + cloned.attrs.retain(|a| !a.path.is_ident("version")); + cloned.sig.ident = create_function_ident_with_version(&cloned.sig.ident, version); + cloned + }); let impl_type = if is_wasm_only { quote!( &mut dyn #crate_::sp_wasm_interface::FunctionContext ) diff --git a/primitives/runtime-interface/proc-macro/src/utils.rs b/primitives/runtime-interface/proc-macro/src/utils.rs index 15c65f11ca..45f66e3bf6 100644 --- a/primitives/runtime-interface/proc-macro/src/utils.rs +++ b/primitives/runtime-interface/proc-macro/src/utils.rs @@ -20,17 +20,60 @@ use proc_macro2::{TokenStream, Span}; use syn::{ Ident, Error, Signature, Pat, PatType, FnArg, Type, token, TraitItemMethod, ItemTrait, - TraitItem, parse_quote, spanned::Spanned, + TraitItem, parse_quote, spanned::Spanned, Result, Meta, NestedMeta, Lit, Attribute, }; use proc_macro_crate::crate_name; use std::env; +use std::collections::{BTreeMap, btree_map::Entry}; use quote::quote; use inflector::Inflector; +/// Runtime interface function with all associated versions of this function. +pub struct RuntimeInterfaceFunction<'a> { + latest_version: u32, + versions: BTreeMap, +} + +impl<'a> RuntimeInterfaceFunction<'a> { + fn new(version: u32, trait_item: &'a TraitItemMethod) -> Self { + Self { + latest_version: version, + versions: { + let mut res = BTreeMap::new(); + res.insert(version, trait_item); + res + }, + } + } + + pub fn latest_version(&self) -> (u32, &TraitItemMethod) { + ( + self.latest_version, + self.versions.get(&self.latest_version) + .expect("If latest_version has a value, the key with this value is in the versions; qed") + ) + } +} + +/// All functions of a runtime interface grouped by the function names. +pub struct RuntimeInterface<'a> { + items: BTreeMap>, +} + +impl<'a> RuntimeInterface<'a> { + pub fn latest_versions(&self) -> impl Iterator { + self.items.iter().map(|(_, item)| item.latest_version()) + } + + pub fn all_versions(&self) -> impl Iterator { + self.items.iter().flat_map(|(_, item)| item.versions.iter()).map(|(v, i)| (*v, *i)) + } + } + /// Generates the include for the runtime-interface crate. pub fn generate_runtime_interface_include() -> TokenStream { if env::var("CARGO_PKG_NAME").unwrap() == "sp-runtime-interface" { @@ -67,12 +110,25 @@ pub fn create_exchangeable_host_function_ident(name: &Ident) -> Ident { } /// Create the host function identifier for the given function name. -pub fn create_host_function_ident(name: &Ident, trait_name: &Ident) -> Ident { +pub fn create_host_function_ident(name: &Ident, version: u32, trait_name: &Ident) -> Ident { Ident::new( &format!( - "ext_{}_{}_version_1", + "ext_{}_{}_version_{}", trait_name.to_string().to_snake_case(), name, + version, + ), + Span::call_site(), + ) +} + +/// Create the host function identifier for the given function name. +pub fn create_function_ident_with_version(name: &Ident, version: u32) -> Ident { + Ident::new( + &format!( + "{}_version_{}", + name, + version, ), Span::call_site(), ) @@ -151,7 +207,7 @@ pub fn get_function_argument_types_ref_and_mut<'a>( } /// Returns an iterator over all trait methods for the given trait definition. -pub fn get_trait_methods<'a>(trait_def: &'a ItemTrait) -> impl Iterator { +fn get_trait_methods<'a>(trait_def: &'a ItemTrait) -> impl Iterator { trait_def .items .iter() @@ -160,3 +216,85 @@ pub fn get_trait_methods<'a>(trait_def: &'a ItemTrait) -> impl Iterator None, }) } + +/// Parse version attribute. +/// +/// Returns error if it is in incorrent format. Correct format is only `#[version(X)]`. +fn parse_version_attribute(version: &Attribute) -> Result { + let meta = version.parse_meta()?; + + let err = Err(Error::new( + meta.span(), + "Unexpected `version` attribute. The supported format is `#[version(1)]`", + ) + ); + + match meta { + Meta::List(list) => { + if list.nested.len() != 1 { + err + } else if let Some(NestedMeta::Lit(Lit::Int(i))) = list.nested.first() { + i.base10_parse() + } else { + err + } + }, + _ => err, + } +} + +/// Return item version (`#[version(X)]`) attribute, if present. +fn get_item_version(item: &TraitItemMethod) -> Result> { + item.attrs.iter().find(|attr| attr.path.is_ident("version")) + .map(|attr| parse_version_attribute(attr)) + .transpose() +} + +/// Returns all runtime interface members, with versions. +pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait) + -> Result> +{ + let mut functions: BTreeMap> = BTreeMap::new(); + + for item in get_trait_methods(trait_def) { + let name = item.sig.ident.clone(); + let version = get_item_version(item)?.unwrap_or(1); + + match functions.entry(name.clone()) { + Entry::Vacant(entry) => { entry.insert(RuntimeInterfaceFunction::new(version, item)); }, + Entry::Occupied(mut entry) => { + if let Some(existing_item) = entry.get().versions.get(&version) { + let mut err = Error::new( + item.span(), + "Duplicated version attribute", + ); + err.combine(Error::new( + existing_item.span(), + "Previous version with the same number defined here", + )); + + return Err(err); + } + + let interface_item = entry.get_mut(); + if interface_item.latest_version < version { interface_item.latest_version = version; } + interface_item.versions.insert(version, item); + } + } + } + + for function in functions.values() { + let mut next_expected = 1; + for (version, item) in function.versions.iter() { + if next_expected != *version { + return Err(Error::new( + item.span(), + format!("Unexpected version attribute: missing version '{}' for this function", next_expected), + )); + } + next_expected += 1; + } + } + + Ok(RuntimeInterface { items: functions }) +} \ No newline at end of file diff --git a/primitives/runtime-interface/src/lib.rs b/primitives/runtime-interface/src/lib.rs index 609f4f600b..fd158d4b8a 100644 --- a/primitives/runtime-interface/src/lib.rs +++ b/primitives/runtime-interface/src/lib.rs @@ -129,11 +129,22 @@ pub use sp_std; /// /// A function that can be called from native/wasm. /// /// /// /// The implementation given to this function is only compiled on native. -/// fn call_some_complex_code(data: &[u8]) -> Vec { +/// fn call(data: &[u8]) -> Vec { /// // Here you could call some rather complex code that only compiles on native or /// // is way faster in native than executing it in wasm. /// Vec::new() /// } +/// /// Call function, but different version. +/// /// +/// /// For new runtimes, only function with latest version is reachable. +/// /// But old version (above) is still accessible for old runtimes. +/// /// Default version is 1. +/// #[version(2)] +/// fn call(data: &[u8]) -> Vec { +/// // Here you could call some rather complex code that only compiles on native or +/// // is way faster in native than executing it in wasm. +/// [17].to_vec() +/// } /// /// /// A function can take a `&self` or `&mut self` argument to get access to the /// /// `Externalities`. (The generated method does not require @@ -157,13 +168,15 @@ pub use sp_std; /// // on the visibility of the trait declaration. /// mod interface { /// trait Interface { -/// fn call_some_complex_code(data: &[u8]) -> Vec; -/// fn set_or_clear(&mut self, optional: Option>); +/// fn call_version_1(data: &[u8]) -> Vec; +/// fn call_version_2(data: &[u8]) -> Vec; +/// fn set_or_clear_version_1(&mut self, optional: Option>); /// } /// /// impl Interface for &mut dyn sp_externalities::Externalities { -/// fn call_some_complex_code(data: &[u8]) -> Vec { Vec::new() } -/// fn set_or_clear(&mut self, optional: Option>) { +/// fn call_version_1(data: &[u8]) -> Vec { Vec::new() } +/// fn call_version_2(data: &[u8]) -> Vec { [17].to_vec() } +/// fn set_or_clear_version_1(&mut self, optional: Option>) { /// match optional { /// Some(value) => self.set_storage([1, 2, 3, 4].to_vec(), value), /// None => self.clear_storage(&[1, 2, 3, 4]), @@ -171,12 +184,25 @@ pub use sp_std; /// } /// } /// -/// pub fn call_some_complex_code(data: &[u8]) -> Vec { -/// <&mut dyn sp_externalities::Externalities as Interface>::call_some_complex_code(data) +/// pub fn call(data: &[u8]) -> Vec { +/// // only latest version is exposed +/// call_version_2(data) +/// } +/// +/// fn call_version_1(data: &[u8]) -> Vec { +/// <&mut dyn sp_externalities::Externalities as Interface>::call_version_1(data) +/// } +/// +/// fn call_version_2(data: &[u8]) -> Vec { +/// <&mut dyn sp_externalities::Externalities as Interface>::call_version_2(data) /// } /// /// pub fn set_or_clear(optional: Option>) { -/// sp_externalities::with_externalities(|mut ext| Interface::set_or_clear(&mut ext, optional)) +/// set_or_clear_version_1(optional) +/// } +/// +/// fn set_or_clear_version_1(optional: Option>) { +/// sp_externalities::with_externalities(|mut ext| Interface::set_or_clear_version_1(&mut ext, optional)) /// .expect("`set_or_clear` called outside of an Externalities-provided environment.") /// } /// @@ -205,7 +231,7 @@ pub use sp_std; /// /// `::FFIType`. /// /// /// /// `data` holds the pointer and the length to the `[u8]` slice. -/// pub fn ext_Interface_call_some_complex_code_version_1(data: u64) -> u64; +/// pub fn ext_Interface_call_version_1(data: u64) -> u64; /// /// `optional` holds the pointer and the length of the encoded value. /// pub fn ext_Interface_set_or_clear_version_1(optional: u64); /// } @@ -213,18 +239,18 @@ pub use sp_std; /// /// /// The type is actually `ExchangeableFunction` (from `sp-runtime-interface`). /// /// -/// /// This can be used to replace the implementation of the `call_some_complex_code` function. +/// /// This can be used to replace the implementation of the `call` function. /// /// Instead of calling into the host, the callee will automatically call the other /// /// implementation. /// /// /// /// To replace the implementation: /// /// -/// /// `host_call_some_complex_code.replace_implementation(some_other_impl)` -/// pub static host_call_some_complex_code: () = (); +/// /// `host_call.replace_implementation(some_other_impl)` +/// pub static host_call: () = (); /// pub static host_set_or_clear: () = (); /// -/// pub fn call_some_complex_code(data: &[u8]) -> Vec { -/// // This is the actual call: `host_call_some_complex_code.get()(data)` +/// pub fn call(data: &[u8]) -> Vec { +/// // This is the actual call: `host_call.get()(data)` /// // /// // But that does not work for several reasons in this example, so we just return an /// // empty vector. diff --git a/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml new file mode 100644 index 0000000000..128f6c9acc --- /dev/null +++ b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "sp-runtime-interface-test-wasm-deprecated" +version = "2.0.0-dev" +authors = ["Parity Technologies "] +edition = "2018" +build = "build.rs" +license = "GPL-3.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +publish = false + +[dependencies] +sp-runtime-interface = { version = "2.0.0-alpha.2", default-features = false, path = "../" } +sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../std" } +sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../io" } +sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../core" } + +[build-dependencies] +wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } + +[features] +default = [ "std" ] +std = [ "sp-runtime-interface/std", "sp-std/std", "sp-core/std", "sp-io/std" ] diff --git a/primitives/runtime-interface/test-wasm-deprecated/build.rs b/primitives/runtime-interface/test-wasm-deprecated/build.rs new file mode 100644 index 0000000000..647b476814 --- /dev/null +++ b/primitives/runtime-interface/test-wasm-deprecated/build.rs @@ -0,0 +1,26 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use wasm_builder_runner::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .with_wasm_builder_from_crates_or_path("1.0.9", "../../../utils/wasm-builder") + .export_heap_base() + .import_memory() + .build() +} diff --git a/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs b/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs new file mode 100644 index 0000000000..29d28c75fa --- /dev/null +++ b/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs @@ -0,0 +1,52 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Tests for the runtime interface traits and proc macros. + +#![cfg_attr(not(feature = "std"), no_std)] + +use sp_core::wasm_export_functions; +use sp_runtime_interface::runtime_interface; + +// Include the WASM binary +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +/// This function is not used, but we require it for the compiler to include `sp-io`. +/// `sp-io` is required for its panic and oom handler. +#[no_mangle] +pub fn import_sp_io() { + sp_io::misc::print_utf8(&[]); +} + +#[runtime_interface] +pub trait TestApi { + fn test_versionning(&self, _data: u32) -> bool { + // should not be called + unimplemented!() + } +} + +wasm_export_functions! { + fn test_versionning_works() { + // old api allows only 42 and 50 + assert!(test_api::test_versionning(42)); + assert!(test_api::test_versionning(50)); + + assert!(!test_api::test_versionning(142)); + assert!(!test_api::test_versionning(0)); + } +} \ No newline at end of file diff --git a/primitives/runtime-interface/test-wasm/src/lib.rs b/primitives/runtime-interface/test-wasm/src/lib.rs index ee7120b1b8..700c77854a 100644 --- a/primitives/runtime-interface/test-wasm/src/lib.rs +++ b/primitives/runtime-interface/test-wasm/src/lib.rs @@ -21,7 +21,7 @@ use sp_runtime_interface::runtime_interface; #[cfg(not(feature = "std"))] -use sp_std::{vec, vec::Vec, mem, convert::TryFrom}; +use sp_std::{prelude::*, mem, convert::TryFrom}; use sp_core::{sr25519::Public, wasm_export_functions}; @@ -103,6 +103,15 @@ pub trait TestApi { fn get_and_return_i128(val: i128) -> i128 { val } + + fn test_versionning(&self, data: u32) -> bool { + data == 42 || data == 50 + } + + #[version(2)] + fn test_versionning(&self, data: u32) -> bool { + data == 42 + } } /// This function is not used, but we require it for the compiler to include `sp-io`. @@ -231,4 +240,14 @@ wasm_export_functions! { } assert_eq!(0, len); } + + fn test_versionning_works() { + // we fix new api to accept only 42 as a proper input + // as opposed to sp-runtime-interface-test-wasm-deprecated::test_api::verify_input + // which accepted 42 and 50. + assert!(test_api::test_versionning(42)); + + assert!(!test_api::test_versionning(50)); + assert!(!test_api::test_versionning(102)); + } } diff --git a/primitives/runtime-interface/test/Cargo.toml b/primitives/runtime-interface/test/Cargo.toml index b8da8042ed..53bdcd18bb 100644 --- a/primitives/runtime-interface/test/Cargo.toml +++ b/primitives/runtime-interface/test/Cargo.toml @@ -12,6 +12,7 @@ repository = "https://github.com/paritytech/substrate/" sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../" } sc-executor = { version = "0.8.0-alpha.4", path = "../../../client/executor" } sp-runtime-interface-test-wasm = { version = "2.0.0-dev", path = "../test-wasm" } +sp-runtime-interface-test-wasm-deprecated = { version = "2.0.0-dev", path = "../test-wasm-deprecated" } sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } sp-runtime = { version = "2.0.0-alpha.4", path = "../../runtime" } sp-io = { version = "2.0.0-alpha.4", path = "../../io" } diff --git a/primitives/runtime-interface/test/src/lib.rs b/primitives/runtime-interface/test/src/lib.rs index 5236bf147e..110eda980f 100644 --- a/primitives/runtime-interface/test/src/lib.rs +++ b/primitives/runtime-interface/test/src/lib.rs @@ -20,13 +20,16 @@ #![cfg(test)] use sp_runtime_interface::*; + use sp_runtime_interface_test_wasm::{WASM_BINARY, test_api::HostFunctions}; +use sp_runtime_interface_test_wasm_deprecated::WASM_BINARY as WASM_BINARY_DEPRECATED; + use sp_wasm_interface::HostFunctions as HostFunctionsT; use sc_executor::CallInWasm; type TestExternalities = sp_state_machine::TestExternalities; -fn call_wasm_method(method: &str) -> TestExternalities { +fn call_wasm_method(binary: &[u8], method: &str) -> TestExternalities { let mut ext = TestExternalities::default(); let mut ext_ext = ext.ext(); let mut host_functions = HF::host_functions(); @@ -40,7 +43,7 @@ fn call_wasm_method(method: &str) -> TestExternalities { 8, ); executor.call_in_wasm( - &WASM_BINARY[..], + binary, None, method, &[], @@ -52,17 +55,17 @@ fn call_wasm_method(method: &str) -> TestExternalities { #[test] fn test_return_data() { - call_wasm_method::("test_return_data"); + call_wasm_method::(&WASM_BINARY[..], "test_return_data"); } #[test] fn test_return_option_data() { - call_wasm_method::("test_return_option_data"); + call_wasm_method::(&WASM_BINARY[..], "test_return_option_data"); } #[test] fn test_set_storage() { - let mut ext = call_wasm_method::("test_set_storage"); + let mut ext = call_wasm_method::(&WASM_BINARY[..], "test_set_storage"); let expected = "world"; assert_eq!(expected.as_bytes(), &ext.ext().storage("hello".as_bytes()).unwrap()[..]); @@ -70,22 +73,22 @@ fn test_set_storage() { #[test] fn test_return_value_into_mutable_reference() { - call_wasm_method::("test_return_value_into_mutable_reference"); + call_wasm_method::(&WASM_BINARY[..], "test_return_value_into_mutable_reference"); } #[test] fn test_get_and_return_array() { - call_wasm_method::("test_get_and_return_array"); + call_wasm_method::(&WASM_BINARY[..], "test_get_and_return_array"); } #[test] fn test_array_as_mutable_reference() { - call_wasm_method::("test_array_as_mutable_reference"); + call_wasm_method::(&WASM_BINARY[..], "test_array_as_mutable_reference"); } #[test] fn test_return_input_public_key() { - call_wasm_method::("test_return_input_public_key"); + call_wasm_method::(&WASM_BINARY[..], "test_return_input_public_key"); } #[test] @@ -93,7 +96,7 @@ fn test_return_input_public_key() { expected = "Instantiation: Export ext_test_api_return_input_version_1 not found" )] fn host_function_not_found() { - call_wasm_method::<()>("test_return_data"); + call_wasm_method::<()>(&WASM_BINARY[..], "test_return_data"); } #[test] @@ -104,30 +107,46 @@ fn host_function_not_found() { \\\"Invalid utf8 data provided\\\")) }\"" )] fn test_invalid_utf8_data_should_return_an_error() { - call_wasm_method::("test_invalid_utf8_data_should_return_an_error"); + call_wasm_method::(&WASM_BINARY[..], "test_invalid_utf8_data_should_return_an_error"); } #[test] fn test_overwrite_native_function_implementation() { - call_wasm_method::("test_overwrite_native_function_implementation"); + call_wasm_method::(&WASM_BINARY[..], "test_overwrite_native_function_implementation"); } #[test] fn test_u128_i128_as_parameter_and_return_value() { - call_wasm_method::("test_u128_i128_as_parameter_and_return_value"); + call_wasm_method::(&WASM_BINARY[..], "test_u128_i128_as_parameter_and_return_value"); } #[test] fn test_vec_return_value_memory_is_freed() { - call_wasm_method::("test_vec_return_value_memory_is_freed"); + call_wasm_method::(&WASM_BINARY[..], "test_vec_return_value_memory_is_freed"); } #[test] fn test_encoded_return_value_memory_is_freed() { - call_wasm_method::("test_encoded_return_value_memory_is_freed"); + call_wasm_method::(&WASM_BINARY[..], "test_encoded_return_value_memory_is_freed"); } #[test] fn test_array_return_value_memory_is_freed() { - call_wasm_method::("test_array_return_value_memory_is_freed"); + call_wasm_method::(&WASM_BINARY[..], "test_array_return_value_memory_is_freed"); +} + +#[test] +fn test_versionining_with_new_host_works() { + // We call to the new wasm binary with new host function. + call_wasm_method::( + &WASM_BINARY[..], + "test_versionning_works", + ); + + // we call to the old wasm binary with a new host functions + // old versions of host functions should be called and test should be ok! + call_wasm_method::( + &WASM_BINARY_DEPRECATED[..], + "test_versionning_works", + ); } diff --git a/primitives/runtime-interface/tests/ui/no_duplicate_versions.rs b/primitives/runtime-interface/tests/ui/no_duplicate_versions.rs new file mode 100644 index 0000000000..948c327aa1 --- /dev/null +++ b/primitives/runtime-interface/tests/ui/no_duplicate_versions.rs @@ -0,0 +1,11 @@ +use sp_runtime_interface::runtime_interface; + +#[runtime_interface] +trait Test { + #[version(2)] + fn test() { } + #[version(2)] + fn test() { } +} + +fn main() {} diff --git a/primitives/runtime-interface/tests/ui/no_duplicate_versions.stderr b/primitives/runtime-interface/tests/ui/no_duplicate_versions.stderr new file mode 100644 index 0000000000..592dd9928c --- /dev/null +++ b/primitives/runtime-interface/tests/ui/no_duplicate_versions.stderr @@ -0,0 +1,11 @@ +error: Duplicated version attribute + --> $DIR/no_duplicate_versions.rs:7:2 + | +7 | #[version(2)] + | ^ + +error: Previous version with the same number defined here + --> $DIR/no_duplicate_versions.rs:5:2 + | +5 | #[version(2)] + | ^ diff --git a/primitives/runtime-interface/tests/ui/no_gaps_in_versions.rs b/primitives/runtime-interface/tests/ui/no_gaps_in_versions.rs new file mode 100644 index 0000000000..c468f48e37 --- /dev/null +++ b/primitives/runtime-interface/tests/ui/no_gaps_in_versions.rs @@ -0,0 +1,17 @@ +use sp_runtime_interface::runtime_interface; + +#[runtime_interface] +trait Test { + #[version(1)] + fn test2() {} + #[version(2)] + fn test2() {} + #[version(3)] + fn test2() {} + + fn test() { } + #[version(3)] + fn test() { } +} + +fn main() {} diff --git a/primitives/runtime-interface/tests/ui/no_gaps_in_versions.stderr b/primitives/runtime-interface/tests/ui/no_gaps_in_versions.stderr new file mode 100644 index 0000000000..cdefcf60c5 --- /dev/null +++ b/primitives/runtime-interface/tests/ui/no_gaps_in_versions.stderr @@ -0,0 +1,5 @@ +error: Unexpected version attribute: missing version '2' for this function + --> $DIR/no_gaps_in_versions.rs:13:2 + | +13 | #[version(3)] + | ^ diff --git a/primitives/runtime-interface/tests/ui/no_generic_parameters.stderr b/primitives/runtime-interface/tests/ui/no_generic_parameters.stderr deleted file mode 100644 index c3e46655e5..0000000000 --- a/primitives/runtime-interface/tests/ui/no_generic_parameters.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: Generic parameters not supported. - --> $DIR/no_generic_parameters.rs:5:10 - | -5 | fn test() {} - | ^ - -error: Generic parameters not supported. - --> $DIR/no_generic_parameters.rs:4:12 - | -4 | trait Test { - | ^ diff --git a/primitives/runtime-interface/tests/ui/no_generic_parameters_method.rs b/primitives/runtime-interface/tests/ui/no_generic_parameters_method.rs new file mode 100644 index 0000000000..407942eb5e --- /dev/null +++ b/primitives/runtime-interface/tests/ui/no_generic_parameters_method.rs @@ -0,0 +1,8 @@ +use sp_runtime_interface::runtime_interface; + +#[runtime_interface] +trait Test { + fn test() {} +} + +fn main() {} diff --git a/primitives/runtime-interface/tests/ui/no_generic_parameters_method.stderr b/primitives/runtime-interface/tests/ui/no_generic_parameters_method.stderr new file mode 100644 index 0000000000..8a549753ac --- /dev/null +++ b/primitives/runtime-interface/tests/ui/no_generic_parameters_method.stderr @@ -0,0 +1,5 @@ +error: Generic parameters not supported. + --> $DIR/no_generic_parameters_method.rs:5:10 + | +5 | fn test() {} + | ^ diff --git a/primitives/runtime-interface/tests/ui/no_generic_parameters.rs b/primitives/runtime-interface/tests/ui/no_generic_parameters_trait.rs similarity index 85% rename from primitives/runtime-interface/tests/ui/no_generic_parameters.rs rename to primitives/runtime-interface/tests/ui/no_generic_parameters_trait.rs index 17ddb00fab..35efac6761 100644 --- a/primitives/runtime-interface/tests/ui/no_generic_parameters.rs +++ b/primitives/runtime-interface/tests/ui/no_generic_parameters_trait.rs @@ -2,7 +2,7 @@ use sp_runtime_interface::runtime_interface; #[runtime_interface] trait Test { - fn test() {} + fn test() {} } fn main() {} diff --git a/primitives/runtime-interface/tests/ui/no_generic_parameters_trait.stderr b/primitives/runtime-interface/tests/ui/no_generic_parameters_trait.stderr new file mode 100644 index 0000000000..794e30bca7 --- /dev/null +++ b/primitives/runtime-interface/tests/ui/no_generic_parameters_trait.stderr @@ -0,0 +1,5 @@ +error: Generic parameters not supported. + --> $DIR/no_generic_parameters_trait.rs:4:12 + | +4 | trait Test { + | ^ -- GitLab From b9ea236f1e5a5e824c740d5e13b954cd23bd6520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 23 Mar 2020 18:49:49 +0100 Subject: [PATCH 054/300] Show an error when we connect to a bootnode with a different peer id (#5365) Currently when we connect to a bootnode and it returns a different peer id, than the one we provided, we disconnect silently. This pr changes the behavior to printing an error when a bootnode returns a different peer id than the provided one. --- client/network/src/service.rs | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 81bea868b4..83492e2e93 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -171,12 +171,14 @@ impl NetworkWorker { let mut known_addresses = Vec::new(); let mut bootnodes = Vec::new(); let mut reserved_nodes = Vec::new(); + let mut boot_node_ids = HashSet::new(); // Process the bootnodes. for bootnode in params.network_config.boot_nodes.iter() { match parse_str_addr(bootnode) { Ok((peer_id, addr)) => { bootnodes.push(peer_id.clone()); + boot_node_ids.insert(peer_id.clone()); known_addresses.push((peer_id, addr)); }, Err(_) => warn!(target: "sub-libp2p", "Not a valid bootnode address: {}", bootnode), @@ -331,7 +333,8 @@ impl NetworkWorker { metrics: match params.metrics_registry { Some(registry) => Some(Metrics::register(®istry)?), None => None - } + }, + boot_node_ids, }) } @@ -772,6 +775,8 @@ pub struct NetworkWorker { event_streams: Vec>, /// Prometheus network metrics. metrics: Option, + /// The `PeerId`'s of all boot nodes. + boot_node_ids: HashSet, } struct Metrics { @@ -991,8 +996,29 @@ impl Future for NetworkWorker { trace!(target: "sub-libp2p", "Libp2p => NewListenAddr({})", addr), Poll::Ready(SwarmEvent::ExpiredListenAddr(addr)) => trace!(target: "sub-libp2p", "Libp2p => ExpiredListenAddr({})", addr), - Poll::Ready(SwarmEvent::UnreachableAddr { peer_id, address, error }) => - trace!(target: "sub-libp2p", "Libp2p => Failed to reach {:?} through {:?}: {}", peer_id, address, error), + Poll::Ready(SwarmEvent::UnreachableAddr { peer_id, address, error }) => { + let error = error.to_string(); + + trace!( + target: "sub-libp2p", "Libp2p => Failed to reach {:?} through {:?}: {}", + peer_id, + address, + error, + ); + + if let Some(peer_id) = peer_id { + if this.boot_node_ids.contains(&peer_id) + && error.contains("Peer ID mismatch") + { + error!( + "Connecting to bootnode with peer id `{}` and address `{}` failed \ + because it returned a different peer id!", + peer_id, + address, + ); + } + } + }, Poll::Ready(SwarmEvent::StartConnect(peer_id)) => trace!(target: "sub-libp2p", "Libp2p => StartConnect({:?})", peer_id), }; -- GitLab From 501d963765baf0ab1d277df0a201442ae289749b Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 23 Mar 2020 21:57:36 +0100 Subject: [PATCH 055/300] Add `runtime-benchmarks` compile/test in CI pipeline (#5371) * Add `runtime-benchmarks` compile * Use cargo check and no wasm build --- .gitlab-ci.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 13943ba22c..ccaac81f83 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -248,6 +248,22 @@ test-wasmtime: - WASM_BUILD_NO_COLOR=1 time cargo test --release --verbose --features wasmtime - sccache -s +test-runtime-benchmarks: + stage: test + <<: *docker-env + variables: + # Enable debug assertions since we are running optimized builds for testing + # but still want to have debug assertions. + RUSTFLAGS: -Cdebug-assertions=y + RUST_BACKTRACE: 1 + except: + variables: + - $DEPLOY_TAG + script: + - cd bin/node/cli + - BUILD_DUMMY_WASM_BINARY=1 time cargo check --verbose --features runtime-benchmarks + - sccache -s + test-linux-stable-int: <<: *test-linux except: -- GitLab From 05956d705b5f8e08655bb5eaf75b9f3b56f6a200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Tue, 24 Mar 2020 11:40:58 +0100 Subject: [PATCH 056/300] Update COMPLEXITY.md for ext_terminate (#5275) --- frame/contracts/COMPLEXITY.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/frame/contracts/COMPLEXITY.md b/frame/contracts/COMPLEXITY.md index a5e6a651ee..482cb45baf 100644 --- a/frame/contracts/COMPLEXITY.md +++ b/frame/contracts/COMPLEXITY.md @@ -166,7 +166,8 @@ This function performs the following steps: In the course of the execution this function can perform up to 2 DB reads to `get_balance` of source and destination accounts. It can also induce up to 2 DB writes via `set_balance` if flushed to the storage. -Moreover, if the source balance goes below `existential_deposit` then the account will be deleted along with all its storage which requires time proportional to the number of storage entries of that account. +Moreover, if the source balance goes below `existential_deposit` then the transfer is denied and +returns with an error. Assuming marshaled size of a balance value is of the constant size we can neglect its effect on the performance. @@ -187,6 +188,23 @@ implementation they just involve a DB read. For subsequent calls and instantiations during contract execution, the initialization requires no expensive operations. +## Terminate + +This function performs the following steps: + +1. Check the calling contract is not already on the callstack by calling `is_live`. +2. `transfer` funds from caller to the beneficiary. +3. Flag the caller contract as deleted in the overlay. + +`is_live` does not do any database access nor does it allocate memory. It walks up the call +stack and therefore executes in linear time depending on size of the call stack. Because +the call stack is of a fixed maximum size we consider this operation as constant time. + +**complexity**: Database accesses as described in Transfer + Removal of the contract. Currently, +we are using child trie removal which is linear in the amount of stored keys. Upcoming changes +will make the account removal constant time. + + ## Call This function receives input data for the contract execution. The execution consists of the following steps: -- GitLab From 56d69d78151bc0222bc222b2de7e83327b599628 Mon Sep 17 00:00:00 2001 From: Stanislav Tkach Date: Tue, 24 Mar 2020 12:48:23 +0200 Subject: [PATCH 057/300] Get rid of rustc_hex in favor of hex (#5370) * Get rid of rustc_hex in favor of hex * Use HexDisplay --- Cargo.lock | 6 +--- bin/node/runtime/Cargo.toml | 2 -- bin/node/runtime/src/lib.rs | 1 - bin/utils/subkey/Cargo.toml | 1 - bin/utils/subkey/src/main.rs | 4 +-- client/network/Cargo.toml | 2 +- client/network/src/protocol.rs | 32 ++++++++++--------- .../src/protocol/light_client_handler.rs | 24 +++++++------- client/rpc/Cargo.toml | 1 - primitives/core/Cargo.toml | 2 -- 10 files changed, 34 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba96516dd7..955da67362 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3598,7 +3598,6 @@ dependencies = [ "pallet-utility", "pallet-vesting", "parity-scale-codec", - "rustc-hex", "serde", "sp-api", "sp-authority-discovery", @@ -6291,6 +6290,7 @@ dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", "futures_codec", + "hex", "libp2p", "linked-hash-map", "linked_hash_set", @@ -6304,7 +6304,6 @@ dependencies = [ "prost-build", "quickcheck", "rand 0.7.3", - "rustc-hex", "sc-block-builder", "sc-client", "sc-client-api", @@ -6430,7 +6429,6 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", - "rustc-hex", "sc-block-builder", "sc-client", "sc-client-api", @@ -7249,7 +7247,6 @@ dependencies = [ "primitive-types", "rand 0.7.3", "regex", - "rustc-hex", "schnorrkel", "serde", "serde_json", @@ -7746,7 +7743,6 @@ dependencies = [ "parity-scale-codec", "rand 0.7.3", "rpassword", - "rustc-hex", "sc-rpc", "serde_json", "sp-core", diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index dffde93eb4..a39343e581 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -13,7 +13,6 @@ repository = "https://github.com/paritytech/substrate/" # third-party dependencies codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } integer-sqrt = { version = "0.1.2" } -rustc-hex = { version = "2.0", optional = true } serde = { version = "1.0.102", optional = true } # primitives @@ -108,7 +107,6 @@ std = [ "sp-core/std", "pallet-randomness-collective-flip/std", "sp-std/std", - "rustc-hex", "serde", "pallet-session/std", "sp-api/std", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 58728a507b..7347db2124 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -68,7 +68,6 @@ use impls::{CurrencyToVoteHandler, Author, LinearWeightToFee, TargetedFeeAdjustm /// Constant values used within the runtime. pub mod constants; use constants::{time::*, currency::*}; -use frame_system::Trait; // Make the WASM binary available. #[cfg(feature = "std")] diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index 06e91cf591..d8a116b378 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -16,7 +16,6 @@ sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } rand = "0.7.2" clap = "2.33.0" tiny-bip39 = "0.7" -rustc-hex = "2.0.1" substrate-bip39 = "0.4.1" hex = "0.4.0" hex-literal = "0.2.1" diff --git a/bin/utils/subkey/src/main.rs b/bin/utils/subkey/src/main.rs index ae020a062f..bc7d7a602a 100644 --- a/bin/utils/subkey/src/main.rs +++ b/bin/utils/subkey/src/main.rs @@ -648,7 +648,7 @@ fn read_pair( } fn format_signature(signature: &SignatureOf) -> String { - format!("{}", hex::encode(signature)) + format!("{}", HexDisplay::from(&signature.as_ref())) } fn format_seed(seed: SeedOf) -> String { @@ -711,7 +711,7 @@ fn create_extrinsic( } fn print_extrinsic(extrinsic: UncheckedExtrinsic) { - println!("0x{}", hex::encode(&extrinsic.encode())); + println!("0x{}", HexDisplay::from(&extrinsic.encode())); } fn print_usage(matches: &ArgMatches) { diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index e8422cc0a3..6502ad3cb8 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -35,7 +35,7 @@ nohash-hasher = "0.2.0" parking_lot = "0.10.0" prost = "0.6.1" rand = "0.7.2" -rustc-hex = "2.0.1" +hex = "0.4.0" sc-block-builder = { version = "0.8.0-alpha.4", path = "../block-builder" } sc-client = { version = "0.8.0-alpha.4", path = "../" } sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 846440ac39..f76c49fd76 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -23,7 +23,10 @@ use libp2p::{Multiaddr, PeerId}; use libp2p::core::{ConnectedPoint, nodes::listeners::ListenerId}; use libp2p::swarm::{ProtocolsHandler, IntoProtocolsHandler}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; -use sp_core::storage::{StorageKey, ChildInfo}; +use sp_core::{ + storage::{StorageKey, ChildInfo}, + hexdisplay::HexDisplay +}; use sp_consensus::{ BlockOrigin, block_validation::BlockAnnounceValidator, @@ -42,7 +45,6 @@ use prometheus_endpoint::{Registry, Gauge, GaugeVec, PrometheusError, Opts, regi use sync::{ChainSync, SyncState}; use crate::service::{TransactionPool, ExHashT}; use crate::config::{BoxFinalityProofRequestBuilder, Roles}; -use rustc_hex::ToHex; use std::borrow::Cow; use std::collections::{BTreeMap, HashMap, HashSet}; use std::sync::Arc; @@ -1553,11 +1555,11 @@ impl Protocol { } let keys_str = || match request.keys.len() { - 1 => request.keys[0].to_hex::(), + 1 => HexDisplay::from(&request.keys[0]).to_string(), _ => format!( "{}..{}", - request.keys[0].to_hex::(), - request.keys[request.keys.len() - 1].to_hex::(), + HexDisplay::from(&request.keys[0]), + HexDisplay::from(&request.keys[request.keys.len() - 1]), ), }; @@ -1601,16 +1603,16 @@ impl Protocol { } let keys_str = || match request.keys.len() { - 1 => request.keys[0].to_hex::(), + 1 => HexDisplay::from(&request.keys[0]).to_string(), _ => format!( "{}..{}", - request.keys[0].to_hex::(), - request.keys[request.keys.len() - 1].to_hex::(), + HexDisplay::from(&request.keys[0]), + HexDisplay::from(&request.keys[request.keys.len() - 1]), ), }; trace!(target: "sync", "Remote read child request {} from {} ({} {} at {})", - request.id, who, request.storage_key.to_hex::(), keys_str(), request.block); + request.id, who, HexDisplay::from(&request.storage_key), keys_str(), request.block); let proof = if let Some(child_info) = ChildInfo::resolve_child_info(request.child_type, &request.child_info[..]) { match self.context_data.chain.read_child_proof( &BlockId::Hash(request.block), @@ -1623,7 +1625,7 @@ impl Protocol { trace!(target: "sync", "Remote read child request {} from {} ({} {} at {}) failed with: {}", request.id, who, - request.storage_key.to_hex::(), + HexDisplay::from(&request.storage_key), keys_str(), request.block, error @@ -1635,7 +1637,7 @@ impl Protocol { trace!(target: "sync", "Remote read child request {} from {} ({} {} at {}) failed with: {}", request.id, who, - request.storage_key.to_hex::(), + HexDisplay::from(&request.storage_key), keys_str(), request.block, "invalid child info and type", @@ -1714,9 +1716,9 @@ impl Protocol { request.id, who, if let Some(sk) = request.storage_key.as_ref() { - format!("{} : {}", sk.to_hex::(), request.key.to_hex::()) + format!("{} : {}", HexDisplay::from(sk), HexDisplay::from(&request.key)) } else { - request.key.to_hex::() + HexDisplay::from(&request.key).to_string() }, request.first, request.last @@ -1737,9 +1739,9 @@ impl Protocol { request.id, who, if let Some(sk) = storage_key { - format!("{} : {}", sk.0.to_hex::(), key.0.to_hex::()) + format!("{} : {}", HexDisplay::from(&sk.0), HexDisplay::from(&key.0)) } else { - key.0.to_hex::() + HexDisplay::from(&key.0).to_string() }, request.first, request.last, diff --git a/client/network/src/protocol/light_client_handler.rs b/client/network/src/protocol/light_client_handler.rs index d48bd4b91b..c96c5d0818 100644 --- a/client/network/src/protocol/light_client_handler.rs +++ b/client/network/src/protocol/light_client_handler.rs @@ -51,11 +51,13 @@ use libp2p::{ }; use nohash_hasher::IntMap; use prost::Message; -use rustc_hex::ToHex; use sc_client::light::fetcher; use sc_client_api::StorageProof; use sc_peerset::ReputationChange; -use sp_core::storage::{ChildInfo, StorageKey}; +use sp_core::{ + storage::{ChildInfo, StorageKey}, + hexdisplay::HexDisplay, +}; use sp_blockchain::{Error as ClientError}; use sp_runtime::{ traits::{Block, Header, NumberFor, Zero}, @@ -504,7 +506,7 @@ where log::trace!("remote read child request from {} ({} {} at {:?})", peer, - request.storage_key.to_hex::(), + HexDisplay::from(&request.storage_key), fmt_keys(request.keys.first(), request.keys.last()), request.block); @@ -522,7 +524,7 @@ where Err(error) => { log::trace!("remote read child request from {} ({} {} at {:?}) failed with: {}", peer, - request.storage_key.to_hex::(), + HexDisplay::from(&request.storage_key), fmt_keys(request.keys.first(), request.keys.last()), request.block, error); @@ -532,7 +534,7 @@ where } else { log::trace!("remote read child request from {} ({} {} at {:?}) failed with: {}", peer, - request.storage_key.to_hex::(), + HexDisplay::from(&request.storage_key), fmt_keys(request.keys.first(), request.keys.last()), request.block, "invalid child info and type" @@ -585,9 +587,9 @@ where log::trace!("remote changes proof request from {} for key {} ({:?}..{:?})", peer, if !request.storage_key.is_empty() { - format!("{} : {}", request.storage_key.to_hex::(), request.key.to_hex::()) + format!("{} : {}", HexDisplay::from(&request.storage_key), HexDisplay::from(&request.key)) } else { - request.key.to_hex::() + HexDisplay::from(&request.key).to_string() }, request.first, request.last); @@ -610,9 +612,9 @@ where log::trace!("remote changes proof request from {} for key {} ({:?}..{:?}) failed with: {}", peer, if let Some(sk) = storage_key { - format!("{} : {}", sk.0.to_hex::(), key.0.to_hex::()) + format!("{} : {}", HexDisplay::from(&sk.0), HexDisplay::from(&key.0)) } else { - key.0.to_hex::() + HexDisplay::from(&key.0).to_string() }, request.first, request.last, @@ -1089,9 +1091,9 @@ where fn fmt_keys(first: Option<&Vec>, last: Option<&Vec>) -> String { if let (Some(first), Some(last)) = (first, last) { if first == last { - first.to_hex::() + HexDisplay::from(first).to_string() } else { - format!("{}..{}", first.to_hex::(), last.to_hex::()) + format!("{}..{}", HexDisplay::from(first), HexDisplay::from(last)) } } else { String::from("n/a") diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index dee2fca9f9..7f329b47c1 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -38,7 +38,6 @@ parking_lot = "0.10.0" assert_matches = "1.3.0" futures01 = { package = "futures", version = "0.1.29" } sc-network = { version = "0.8.0-alpha.4", path = "../network" } -rustc-hex = "2.0.1" sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } tokio = "0.1.22" diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index c20de3392f..a22ad18d73 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -12,7 +12,6 @@ documentation = "https://docs.rs/sp-core" [dependencies] sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -rustc-hex = { version = "2.0.1", default-features = false } log = { version = "0.4.8", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } byteorder = { version = "1.3.2", default-features = false } @@ -81,7 +80,6 @@ std = [ "hash-db/std", "sp-std/std", "serde", - "rustc-hex/std", "twox-hash/std", "blake2-rfc/std", "ed25519-dalek/std", -- GitLab From dec08f2a30f3703e964114cef12bf2703f0f0a26 Mon Sep 17 00:00:00 2001 From: gabriel klawitter Date: Tue, 24 Mar 2020 18:29:11 +0530 Subject: [PATCH 058/300] check polkadot for companion pull requests (#5262) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * check_polkadot: move to external script * check_polkadot: check for companion pr Co-authored-by: Bastian Köcher Co-authored-by: Bastian Köcher --- .gitlab-ci.yml | 33 ++++-------- .maintain/gitlab/check_polkadot.sh | 80 ++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 24 deletions(-) create mode 100755 .maintain/gitlab/check_polkadot.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ccaac81f83..962ecbe3e4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -127,6 +127,15 @@ check-line-width: allow_failure: true +check-polkadot: + stage: build + <<: *docker-env + script: + - ./.maintain/gitlab/check_polkadot.sh + interruptible: true + allow_failure: true + + cargo-audit: stage: test <<: *docker-env @@ -410,30 +419,6 @@ check_warnings: echo "___No warnings___"; fi -# Nightly check whether Polkadot 'master' branch builds. -check_polkadot: - stage: build - <<: *docker-env - allow_failure: true - only: - - master - - schedules - script: - - SUBSTRATE_PATH=$(pwd) - # Clone the current Polkadot master branch into ./polkadot. - - git clone --depth 1 https://gitlab.parity.io/parity/polkadot.git - - cd polkadot - # Make sure we override the crates in native and wasm build - - mkdir .cargo - - echo "paths = [ \"$SUBSTRATE_PATH\" ]" > .cargo/config - - mkdir -p target/debug/wbuild/.cargo - - echo "paths = [ \"$SUBSTRATE_PATH\" ]" > target/debug/wbuild/.cargo/config - # package, others are updated along the way. - - cargo update - # Check whether Polkadot 'master' branch builds with this Substrate commit. - - time cargo check - - cd - - - sccache -s trigger-contracts-ci: stage: publish diff --git a/.maintain/gitlab/check_polkadot.sh b/.maintain/gitlab/check_polkadot.sh new file mode 100755 index 0000000000..6087d86cde --- /dev/null +++ b/.maintain/gitlab/check_polkadot.sh @@ -0,0 +1,80 @@ +#!/bin/sh +# +# check if a pr is compatible with polkadot companion pr or master if not +# available +# +# mark companion pr in the body of the polkadot pr like +# +# polkadot companion: paritytech/polkadot#567 + + +github_api_substrate_pull_url="https://api.github.com/repos/paritytech/substrate/pulls" +# use github api v3 in order to access the data without authentication +github_header="Accept: application/vnd.github.v3+json" + +boldprint () { printf "|\n| \033[1m${@}\033[0m\n|\n" ; } +boldcat () { printf "|\n"; while read l; do printf "| \033[1m${l}\033[0m\n"; done; printf "|\n" ; } + + + +boldcat <<-EOT + + +check_polkadot +============== + +this job checks if there is a string in the description of the pr like + +polkadot companion: paritytech/polkadot#567 + + +it will then run cargo check from this polkadot's branch with substrate code +from this pull request. + + +EOT + + + +SUBSTRATE_PATH=$(pwd) + +# Clone the current Polkadot master branch into ./polkadot. +git clone --depth 1 https://github.com/paritytech/polkadot.git + +cd polkadot + +# either it's a pull request then check for a companion otherwise use +# polkadot:master +if expr match "${CI_COMMIT_REF_NAME}" '^[0-9]\+$' >/dev/null +then + boldprint "this is pull request no ${CI_COMMIT_REF_NAME}" + # get the last reference to a pr in polkadot + comppr="$(curl -H "${github_header}" -s ${github_api_substrate_pull_url}/${CI_COMMIT_REF_NAME} \ + | sed -n -r 's;^[[:space:]]+"body":[[:space:]]+".*polkadot companion: paritytech/polkadot#([0-9]+).*"[^"]+$;\1;p;$!d')" + if [ "${comppr}" ] + then + boldprint "companion pr specified: #${comppr}" + git fetch --depth 1 origin refs/pull/${comppr}/head:pr/${comppr} + git checkout pr/${comppr} + else + boldprint "no companion pr declared - building polkadot:master" + fi +else + boldprint "this is not a pull request - building polkadot:master" +fi + +# Make sure we override the crates in native and wasm build +# patching the git path as described in the link below did not test correctly +# https://doc.rust-lang.org/cargo/reference/overriding-dependencies.html +mkdir .cargo +echo "paths = [ \"$SUBSTRATE_PATH\" ]" > .cargo/config + +mkdir -p target/debug/wbuild/.cargo +cp .cargo/config target/debug/wbuild/.cargo/config + +# package, others are updated along the way. +cargo update + +# Test Polkadot pr or master branch with this Substrate commit. +time cargo test --all --release --verbose + -- GitLab From d9e989a4b2ac16f6484eb954ed893091c6ac5ae1 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Tue, 24 Mar 2020 15:08:02 +0100 Subject: [PATCH 059/300] Releasing 2.0.0-alpha.5 (#5340) * bump pre-version * Changelog alpha.4->alpha.5 * repo + homepage to sp-consensus-vrf * Add default rocksdb feature to `frame-benchmarking-cli` (#5367) * Add default rocksdb feature * Update Cargo.toml Co-authored-by: Shawn Tabrizi --- Cargo.lock | 304 +++++++++--------- bin/node-template/node/Cargo.toml | 40 +-- bin/node-template/pallets/template/Cargo.toml | 12 +- bin/node-template/runtime/Cargo.toml | 48 +-- bin/node/cli/Cargo.toml | 108 +++---- bin/node/executor/Cargo.toml | 48 +-- bin/node/inspect/Cargo.toml | 14 +- bin/node/primitives/Cargo.toml | 8 +- bin/node/rpc-client/Cargo.toml | 6 +- bin/node/rpc/Cargo.toml | 34 +- bin/node/runtime/Cargo.toml | 106 +++--- bin/node/testing/Cargo.toml | 68 ++-- bin/node/transaction-factory/Cargo.toml | 24 +- bin/utils/chain-spec-builder/Cargo.toml | 8 +- bin/utils/subkey/Cargo.toml | 18 +- client/Cargo.toml | 38 +-- client/api/Cargo.toml | 34 +- client/authority-discovery/Cargo.toml | 22 +- client/basic-authorship/Cargo.toml | 24 +- client/block-builder/Cargo.toml | 20 +- client/chain-spec/Cargo.toml | 12 +- client/chain-spec/derive/Cargo.toml | 2 +- client/cli/Cargo.toml | 28 +- client/consensus/aura/Cargo.toml | 46 +-- client/consensus/babe/Cargo.toml | 54 ++-- client/consensus/babe/rpc/Cargo.toml | 24 +- client/consensus/epochs/Cargo.toml | 10 +- client/consensus/manual-seal/Cargo.toml | 20 +- client/consensus/pow/Cargo.toml | 22 +- client/consensus/slots/Cargo.toml | 20 +- client/consensus/uncles/Cargo.toml | 14 +- client/db/Cargo.toml | 26 +- client/executor/Cargo.toml | 30 +- client/executor/common/Cargo.toml | 12 +- client/executor/runtime-test/Cargo.toml | 12 +- client/executor/wasmi/Cargo.toml | 12 +- client/executor/wasmtime/Cargo.toml | 12 +- client/finality-grandpa/Cargo.toml | 48 +-- client/informant/Cargo.toml | 12 +- client/keystore/Cargo.toml | 6 +- client/network-gossip/Cargo.toml | 6 +- client/network/Cargo.toml | 20 +- client/network/test/Cargo.toml | 18 +- client/offchain/Cargo.toml | 22 +- client/peerset/Cargo.toml | 2 +- client/rpc-api/Cargo.toml | 12 +- client/rpc-servers/Cargo.toml | 4 +- client/rpc/Cargo.toml | 36 +-- client/service/Cargo.toml | 54 ++-- client/service/test/Cargo.toml | 14 +- client/state-db/Cargo.toml | 6 +- client/telemetry/Cargo.toml | 2 +- client/tracing/Cargo.toml | 4 +- client/transaction-pool/Cargo.toml | 18 +- client/transaction-pool/graph/Cargo.toml | 10 +- docs/CHANGELOG.md | 8 + frame/assets/Cargo.toml | 14 +- frame/aura/Cargo.toml | 26 +- frame/authority-discovery/Cargo.toml | 22 +- frame/authorship/Cargo.toml | 18 +- frame/babe/Cargo.toml | 30 +- frame/balances/Cargo.toml | 18 +- frame/benchmark/Cargo.toml | 14 +- frame/benchmarking/Cargo.toml | 16 +- frame/collective/Cargo.toml | 16 +- frame/contracts/Cargo.toml | 24 +- frame/contracts/common/Cargo.toml | 6 +- frame/contracts/rpc/Cargo.toml | 16 +- frame/contracts/rpc/runtime-api/Cargo.toml | 10 +- frame/democracy/Cargo.toml | 18 +- frame/elections-phragmen/Cargo.toml | 20 +- frame/elections/Cargo.toml | 16 +- frame/evm/Cargo.toml | 18 +- frame/example-offchain-worker/Cargo.toml | 14 +- frame/example/Cargo.toml | 18 +- frame/executive/Cargo.toml | 22 +- frame/finality-tracker/Cargo.toml | 18 +- frame/generic-asset/Cargo.toml | 14 +- frame/grandpa/Cargo.toml | 22 +- frame/identity/Cargo.toml | 18 +- frame/im-online/Cargo.toml | 24 +- frame/indices/Cargo.toml | 18 +- frame/membership/Cargo.toml | 14 +- frame/metadata/Cargo.toml | 6 +- frame/nicks/Cargo.toml | 16 +- frame/offences/Cargo.toml | 18 +- frame/randomness-collective-flip/Cargo.toml | 14 +- frame/recovery/Cargo.toml | 16 +- frame/scored-pool/Cargo.toml | 16 +- frame/session/Cargo.toml | 22 +- frame/session/benchmarking/Cargo.toml | 14 +- frame/society/Cargo.toml | 16 +- frame/staking/Cargo.toml | 36 +-- frame/staking/reward-curve/Cargo.toml | 4 +- frame/sudo/Cargo.toml | 14 +- frame/support/Cargo.toml | 22 +- frame/support/procedural/Cargo.toml | 4 +- frame/support/procedural/tools/Cargo.toml | 4 +- .../procedural/tools/derive/Cargo.toml | 2 +- frame/support/test/Cargo.toml | 12 +- frame/system/Cargo.toml | 16 +- frame/system/rpc/runtime-api/Cargo.toml | 4 +- frame/timestamp/Cargo.toml | 22 +- frame/transaction-payment/Cargo.toml | 18 +- frame/transaction-payment/rpc/Cargo.toml | 14 +- .../rpc/runtime-api/Cargo.toml | 10 +- frame/treasury/Cargo.toml | 16 +- frame/utility/Cargo.toml | 18 +- frame/vesting/Cargo.toml | 20 +- primitives/allocator/Cargo.toml | 8 +- primitives/api/Cargo.toml | 14 +- primitives/api/proc-macro/Cargo.toml | 2 +- primitives/api/test/Cargo.toml | 16 +- primitives/application-crypto/Cargo.toml | 8 +- primitives/application-crypto/test/Cargo.toml | 8 +- primitives/arithmetic/Cargo.toml | 6 +- primitives/authority-discovery/Cargo.toml | 10 +- primitives/authorship/Cargo.toml | 8 +- primitives/block-builder/Cargo.toml | 10 +- primitives/blockchain/Cargo.toml | 10 +- primitives/consensus/aura/Cargo.toml | 14 +- primitives/consensus/babe/Cargo.toml | 18 +- primitives/consensus/common/Cargo.toml | 14 +- primitives/consensus/pow/Cargo.toml | 10 +- primitives/consensus/vrf/Cargo.toml | 10 +- primitives/core/Cargo.toml | 14 +- primitives/debug-derive/Cargo.toml | 2 +- primitives/externalities/Cargo.toml | 6 +- primitives/finality-grandpa/Cargo.toml | 10 +- primitives/finality-tracker/Cargo.toml | 6 +- primitives/inherents/Cargo.toml | 6 +- primitives/io/Cargo.toml | 16 +- primitives/keyring/Cargo.toml | 6 +- primitives/offchain/Cargo.toml | 6 +- primitives/panic-handler/Cargo.toml | 2 +- primitives/phragmen/Cargo.toml | 10 +- primitives/rpc/Cargo.toml | 4 +- primitives/runtime-interface/Cargo.toml | 16 +- .../runtime-interface/proc-macro/Cargo.toml | 2 +- .../runtime-interface/test-wasm/Cargo.toml | 8 +- primitives/runtime-interface/test/Cargo.toml | 10 +- primitives/runtime/Cargo.toml | 14 +- primitives/sandbox/Cargo.toml | 10 +- primitives/serializer/Cargo.toml | 2 +- primitives/session/Cargo.toml | 10 +- primitives/staking/Cargo.toml | 6 +- primitives/state-machine/Cargo.toml | 12 +- primitives/std/Cargo.toml | 2 +- primitives/storage/Cargo.toml | 6 +- primitives/test-primitives/Cargo.toml | 6 +- primitives/timestamp/Cargo.toml | 10 +- primitives/transaction-pool/Cargo.toml | 6 +- primitives/trie/Cargo.toml | 8 +- primitives/version/Cargo.toml | 6 +- primitives/wasm-interface/Cargo.toml | 4 +- test-utils/Cargo.toml | 2 +- test-utils/client/Cargo.toml | 20 +- test-utils/runtime/Cargo.toml | 54 ++-- test-utils/runtime/client/Cargo.toml | 14 +- .../runtime/transaction-pool/Cargo.toml | 8 +- utils/browser/Cargo.toml | 10 +- utils/build-script-utils/Cargo.toml | 2 +- utils/fork-tree/Cargo.toml | 2 +- utils/frame/benchmarking-cli/Cargo.toml | 26 +- utils/frame/rpc/support/Cargo.toml | 10 +- utils/frame/rpc/system/Cargo.toml | 18 +- utils/prometheus/Cargo.toml | 2 +- 167 files changed, 1537 insertions(+), 1523 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 955da67362..4f1e5a4c56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -579,7 +579,7 @@ dependencies = [ [[package]] name = "chain-spec-builder" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "ansi_term 0.12.1", "node-cli", @@ -1439,14 +1439,14 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "parity-scale-codec", ] [[package]] name = "frame-benchmarking" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -1461,7 +1461,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-benchmarking", "parity-scale-codec", @@ -1479,7 +1479,7 @@ dependencies = [ [[package]] name = "frame-executive" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -1498,7 +1498,7 @@ dependencies = [ [[package]] name = "frame-metadata" -version = "11.0.0-alpha.4" +version = "11.0.0-alpha.5" dependencies = [ "parity-scale-codec", "serde", @@ -1508,7 +1508,7 @@ dependencies = [ [[package]] name = "frame-support" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "bitmask", "frame-metadata", @@ -1533,7 +1533,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support-procedural-tools", "proc-macro2", @@ -1543,7 +1543,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -1554,7 +1554,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "proc-macro2", "quote", @@ -1579,7 +1579,7 @@ dependencies = [ [[package]] name = "frame-system" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "criterion 0.2.11", "frame-support", @@ -1597,7 +1597,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "parity-scale-codec", "sp-api", @@ -3390,7 +3390,7 @@ dependencies = [ [[package]] name = "node-cli" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "assert_cmd", "frame-benchmarking-cli", @@ -3461,7 +3461,7 @@ dependencies = [ [[package]] name = "node-executor" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "criterion 0.3.1", "frame-benchmarking", @@ -3495,7 +3495,7 @@ dependencies = [ [[package]] name = "node-inspect" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "derive_more", "log 0.4.8", @@ -3511,7 +3511,7 @@ dependencies = [ [[package]] name = "node-primitives" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "pretty_assertions", "sp-core", @@ -3521,7 +3521,7 @@ dependencies = [ [[package]] name = "node-rpc" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "jsonrpc-core", "node-primitives", @@ -3544,7 +3544,7 @@ dependencies = [ [[package]] name = "node-rpc-client" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "env_logger 0.7.1", "futures 0.1.29", @@ -3557,7 +3557,7 @@ dependencies = [ [[package]] name = "node-runtime" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-benchmarking", "frame-executive", @@ -3619,7 +3619,7 @@ dependencies = [ [[package]] name = "node-template" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "futures 0.3.4", "log 0.4.8", @@ -3648,7 +3648,7 @@ dependencies = [ [[package]] name = "node-template-runtime" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-executive", "frame-support", @@ -3680,7 +3680,7 @@ dependencies = [ [[package]] name = "node-testing" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "criterion 0.3.1", "frame-support", @@ -3726,7 +3726,7 @@ dependencies = [ [[package]] name = "node-transaction-factory" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "log 0.4.8", "parity-scale-codec", @@ -3934,7 +3934,7 @@ dependencies = [ [[package]] name = "pallet-assets" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -3948,7 +3948,7 @@ dependencies = [ [[package]] name = "pallet-aura" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -3970,7 +3970,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -3988,7 +3988,7 @@ dependencies = [ [[package]] name = "pallet-authorship" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4004,7 +4004,7 @@ dependencies = [ [[package]] name = "pallet-babe" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4030,7 +4030,7 @@ dependencies = [ [[package]] name = "pallet-balances" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-benchmarking", "frame-support", @@ -4046,7 +4046,7 @@ dependencies = [ [[package]] name = "pallet-benchmark" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-benchmarking", "frame-support", @@ -4060,7 +4060,7 @@ dependencies = [ [[package]] name = "pallet-collective" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4076,7 +4076,7 @@ dependencies = [ [[package]] name = "pallet-contracts" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "assert_matches", "frame-support", @@ -4101,7 +4101,7 @@ dependencies = [ [[package]] name = "pallet-contracts-primitives" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -4110,7 +4110,7 @@ dependencies = [ [[package]] name = "pallet-contracts-rpc" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4129,7 +4129,7 @@ dependencies = [ [[package]] name = "pallet-contracts-rpc-runtime-api" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "pallet-contracts-primitives", "parity-scale-codec", @@ -4140,7 +4140,7 @@ dependencies = [ [[package]] name = "pallet-democracy" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4157,7 +4157,7 @@ dependencies = [ [[package]] name = "pallet-elections" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4173,7 +4173,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4191,7 +4191,7 @@ dependencies = [ [[package]] name = "pallet-evm" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "evm", "frame-support", @@ -4211,7 +4211,7 @@ dependencies = [ [[package]] name = "pallet-example" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-benchmarking", "frame-support", @@ -4227,7 +4227,7 @@ dependencies = [ [[package]] name = "pallet-example-offchain-worker" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4242,7 +4242,7 @@ dependencies = [ [[package]] name = "pallet-finality-tracker" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4259,7 +4259,7 @@ dependencies = [ [[package]] name = "pallet-generic-asset" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4273,7 +4273,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4291,7 +4291,7 @@ dependencies = [ [[package]] name = "pallet-identity" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "enumflags2", "frame-benchmarking", @@ -4308,7 +4308,7 @@ dependencies = [ [[package]] name = "pallet-im-online" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-benchmarking", "frame-support", @@ -4327,7 +4327,7 @@ dependencies = [ [[package]] name = "pallet-indices" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4343,7 +4343,7 @@ dependencies = [ [[package]] name = "pallet-membership" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4357,7 +4357,7 @@ dependencies = [ [[package]] name = "pallet-nicks" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4372,7 +4372,7 @@ dependencies = [ [[package]] name = "pallet-offences" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4388,7 +4388,7 @@ dependencies = [ [[package]] name = "pallet-randomness-collective-flip" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4402,7 +4402,7 @@ dependencies = [ [[package]] name = "pallet-recovery" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "enumflags2", "frame-support", @@ -4418,7 +4418,7 @@ dependencies = [ [[package]] name = "pallet-scored-pool" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4433,7 +4433,7 @@ dependencies = [ [[package]] name = "pallet-session" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4453,7 +4453,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-benchmarking", "frame-system", @@ -4465,7 +4465,7 @@ dependencies = [ [[package]] name = "pallet-society" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4481,7 +4481,7 @@ dependencies = [ [[package]] name = "pallet-staking" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-benchmarking", "frame-support", @@ -4506,7 +4506,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -4517,7 +4517,7 @@ dependencies = [ [[package]] name = "pallet-sudo" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4531,7 +4531,7 @@ dependencies = [ [[package]] name = "pallet-template" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4544,7 +4544,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-benchmarking", "frame-support", @@ -4562,7 +4562,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4577,7 +4577,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4594,7 +4594,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "parity-scale-codec", @@ -4607,7 +4607,7 @@ dependencies = [ [[package]] name = "pallet-treasury" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-benchmarking", "frame-support", @@ -4623,7 +4623,7 @@ dependencies = [ [[package]] name = "pallet-utility" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -4638,7 +4638,7 @@ dependencies = [ [[package]] name = "pallet-vesting" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "enumflags2", "frame-benchmarking", @@ -5677,7 +5677,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "bytes 0.5.4", "derive_more", @@ -5707,7 +5707,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", @@ -5731,7 +5731,7 @@ dependencies = [ [[package]] name = "sc-block-builder" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -5748,7 +5748,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "impl-trait-for-tuples", "sc-chain-spec-derive", @@ -5762,7 +5762,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5772,7 +5772,7 @@ dependencies = [ [[package]] name = "sc-cli" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "ansi_term 0.12.1", "app_dirs", @@ -5811,7 +5811,7 @@ dependencies = [ [[package]] name = "sc-client" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "derive_more", "env_logger 0.7.1", @@ -5849,7 +5849,7 @@ dependencies = [ [[package]] name = "sc-client-api" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "derive_more", "fnv", @@ -5881,7 +5881,7 @@ dependencies = [ [[package]] name = "sc-client-db" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "env_logger 0.7.1", "hash-db", @@ -5913,7 +5913,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "derive_more", "env_logger 0.7.1", @@ -5951,7 +5951,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "derive_more", "env_logger 0.7.1", @@ -6001,7 +6001,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "derive_more", "futures 0.3.4", @@ -6026,7 +6026,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "fork-tree", "parity-scale-codec", @@ -6038,7 +6038,7 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "assert_matches", "derive_more", @@ -6067,7 +6067,7 @@ dependencies = [ [[package]] name = "sc-consensus-pow" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "derive_more", "futures 0.3.4", @@ -6087,7 +6087,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", @@ -6108,7 +6108,7 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "log 0.4.8", "sc-client-api", @@ -6121,7 +6121,7 @@ dependencies = [ [[package]] name = "sc-executor" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "assert_matches", "derive_more", @@ -6155,7 +6155,7 @@ dependencies = [ [[package]] name = "sc-executor-common" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "derive_more", "log 0.4.8", @@ -6170,7 +6170,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "log 0.4.8", "parity-scale-codec", @@ -6185,7 +6185,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "assert_matches", "log 0.4.8", @@ -6202,7 +6202,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "assert_matches", "env_logger 0.7.1", @@ -6244,7 +6244,7 @@ dependencies = [ [[package]] name = "sc-informant" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "ansi_term 0.12.1", "futures 0.3.4", @@ -6260,7 +6260,7 @@ dependencies = [ [[package]] name = "sc-keystore" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "derive_more", "hex", @@ -6275,7 +6275,7 @@ dependencies = [ [[package]] name = "sc-network" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "assert_matches", "async-std", @@ -6334,7 +6334,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", @@ -6374,7 +6374,7 @@ dependencies = [ [[package]] name = "sc-offchain" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "bytes 0.5.4", "env_logger 0.7.1", @@ -6406,7 +6406,7 @@ dependencies = [ [[package]] name = "sc-peerset" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "futures 0.3.4", "libp2p", @@ -6418,7 +6418,7 @@ dependencies = [ [[package]] name = "sc-rpc" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "assert_matches", "futures 0.1.29", @@ -6455,7 +6455,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "derive_more", "futures 0.3.4", @@ -6477,7 +6477,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "jsonrpc-core", "jsonrpc-http-server", @@ -6504,7 +6504,7 @@ dependencies = [ [[package]] name = "sc-service" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "derive_more", "exit-future", @@ -6576,7 +6576,7 @@ dependencies = [ [[package]] name = "sc-state-db" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "env_logger 0.7.1", "log 0.4.8", @@ -6590,7 +6590,7 @@ dependencies = [ [[package]] name = "sc-telemetry" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "bytes 0.5.4", "futures 0.3.4", @@ -6611,7 +6611,7 @@ dependencies = [ [[package]] name = "sc-tracing" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "erased-serde", "log 0.4.8", @@ -6626,7 +6626,7 @@ dependencies = [ [[package]] name = "sc-transaction-graph" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "assert_matches", "criterion 0.3.1", @@ -6648,7 +6648,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "derive_more", "futures 0.3.4", @@ -7011,7 +7011,7 @@ dependencies = [ [[package]] name = "sp-allocator" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "derive_more", "log 0.4.8", @@ -7022,7 +7022,7 @@ dependencies = [ [[package]] name = "sp-api" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "hash-db", "parity-scale-codec", @@ -7037,7 +7037,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "blake2-rfc", "proc-macro-crate", @@ -7067,7 +7067,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "parity-scale-codec", "serde", @@ -7089,7 +7089,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "criterion 0.3.1", "integer-sqrt", @@ -7104,7 +7104,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "parity-scale-codec", "sp-api", @@ -7115,7 +7115,7 @@ dependencies = [ [[package]] name = "sp-authorship" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -7125,7 +7125,7 @@ dependencies = [ [[package]] name = "sp-block-builder" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "parity-scale-codec", "sp-api", @@ -7136,7 +7136,7 @@ dependencies = [ [[package]] name = "sp-blockchain" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "derive_more", "log 0.4.8", @@ -7151,7 +7151,7 @@ dependencies = [ [[package]] name = "sp-consensus" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "derive_more", "futures 0.3.4", @@ -7173,7 +7173,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "parity-scale-codec", "sp-api", @@ -7186,7 +7186,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "parity-scale-codec", "sp-api", @@ -7201,7 +7201,7 @@ dependencies = [ [[package]] name = "sp-consensus-pow" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "parity-scale-codec", "sp-api", @@ -7212,7 +7212,7 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "parity-scale-codec", "schnorrkel", @@ -7223,7 +7223,7 @@ dependencies = [ [[package]] name = "sp-core" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "base58", "blake2-rfc", @@ -7267,7 +7267,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "proc-macro2", "quote", @@ -7276,7 +7276,7 @@ dependencies = [ [[package]] name = "sp-externalities" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "environmental", "sp-std", @@ -7285,7 +7285,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "parity-scale-codec", "serde", @@ -7297,7 +7297,7 @@ dependencies = [ [[package]] name = "sp-finality-tracker" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -7306,7 +7306,7 @@ dependencies = [ [[package]] name = "sp-inherents" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "derive_more", "parity-scale-codec", @@ -7317,7 +7317,7 @@ dependencies = [ [[package]] name = "sp-io" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "hash-db", "libsecp256k1", @@ -7334,7 +7334,7 @@ dependencies = [ [[package]] name = "sp-keyring" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "lazy_static", "sp-core", @@ -7344,7 +7344,7 @@ dependencies = [ [[package]] name = "sp-offchain" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "sp-api", "sp-runtime", @@ -7352,7 +7352,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "backtrace", "log 0.4.8", @@ -7360,7 +7360,7 @@ dependencies = [ [[package]] name = "sp-phragmen" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "rand 0.7.3", "serde", @@ -7372,7 +7372,7 @@ dependencies = [ [[package]] name = "sp-rpc" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "serde", "serde_json", @@ -7381,7 +7381,7 @@ dependencies = [ [[package]] name = "sp-runtime" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "hash256-std-hasher", "impl-trait-for-tuples", @@ -7402,7 +7402,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "parity-scale-codec", "primitive-types", @@ -7421,7 +7421,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "Inflector", "proc-macro-crate", @@ -7467,7 +7467,7 @@ dependencies = [ [[package]] name = "sp-sandbox" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "assert_matches", "parity-scale-codec", @@ -7481,7 +7481,7 @@ dependencies = [ [[package]] name = "sp-serializer" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "serde", "serde_json", @@ -7489,7 +7489,7 @@ dependencies = [ [[package]] name = "sp-session" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "sp-api", "sp-core", @@ -7499,7 +7499,7 @@ dependencies = [ [[package]] name = "sp-staking" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -7508,7 +7508,7 @@ dependencies = [ [[package]] name = "sp-state-machine" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "hash-db", "hex-literal", @@ -7528,11 +7528,11 @@ dependencies = [ [[package]] name = "sp-std" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" [[package]] name = "sp-storage" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "impl-serde 0.2.3", "serde", @@ -7554,7 +7554,7 @@ dependencies = [ [[package]] name = "sp-timestamp" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -7567,7 +7567,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "derive_more", "futures 0.3.4", @@ -7580,7 +7580,7 @@ dependencies = [ [[package]] name = "sp-trie" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "criterion 0.2.11", "hash-db", @@ -7598,7 +7598,7 @@ dependencies = [ [[package]] name = "sp-version" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "impl-serde 0.2.3", "parity-scale-codec", @@ -7609,7 +7609,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -7724,7 +7724,7 @@ dependencies = [ [[package]] name = "subkey" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "clap", "derive_more", @@ -7765,7 +7765,7 @@ dependencies = [ [[package]] name = "substrate-browser-utils" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "chrono", "clear_on_drop", @@ -7790,11 +7790,11 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" [[package]] name = "substrate-frame-rpc-support" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", @@ -7810,7 +7810,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "env_logger 0.7.1", "frame-system-rpc-runtime-api", @@ -7833,7 +7833,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" dependencies = [ "async-std", "derive_more", @@ -7939,7 +7939,7 @@ dependencies = [ [[package]] name = "substrate-test-utils" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" [[package]] name = "substrate-wasm-builder" diff --git a/bin/node-template/node/Cargo.toml b/bin/node-template/node/Cargo.toml index e46e930c3f..201909bfd0 100644 --- a/bin/node-template/node/Cargo.toml +++ b/bin/node-template/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-template" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Anonymous"] edition = "2018" license = "Unlicense" @@ -16,26 +16,26 @@ futures = "0.3.1" log = "0.4.8" structopt = "0.3.8" -sc-cli = { version = "0.8.0-alpha.4", path = "../../../client/cli" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sc-executor = { version = "0.8.0-alpha.4", path = "../../../client/executor" } -sc-service = { version = "0.8.0-alpha.4", path = "../../../client/service" } -sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } -sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../client/transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../primitives/transaction-pool" } -sc-network = { version = "0.8.0-alpha.4", path = "../../../client/network" } -sc-consensus-aura = { version = "0.8.0-alpha.4", path = "../../../client/consensus/aura" } -sp-consensus-aura = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/aura" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } -grandpa = { version = "0.8.0-alpha.4", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } -grandpa-primitives = { version = "2.0.0-alpha.4", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } -sc-client = { version = "0.8.0-alpha.4", path = "../../../client/" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../../../client/api" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sc-basic-authorship = { path = "../../../client/basic-authorship", version = "0.8.0-alpha.4"} +sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sc-executor = { version = "0.8.0-alpha.5", path = "../../../client/executor" } +sc-service = { version = "0.8.0-alpha.5", path = "../../../client/service" } +sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } +sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } +sc-network = { version = "0.8.0-alpha.5", path = "../../../client/network" } +sc-consensus-aura = { version = "0.8.0-alpha.5", path = "../../../client/consensus/aura" } +sp-consensus-aura = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/aura" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } +grandpa = { version = "0.8.0-alpha.5", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } +grandpa-primitives = { version = "2.0.0-alpha.5", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } +sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sc-basic-authorship = { path = "../../../client/basic-authorship", version = "0.8.0-alpha.5"} -node-template-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } +node-template-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } [build-dependencies] vergen = "3.0.4" -build-script-utils = { version = "2.0.0-alpha.4", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } +build-script-utils = { version = "2.0.0-alpha.5", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } diff --git a/bin/node-template/pallets/template/Cargo.toml b/bin/node-template/pallets/template/Cargo.toml index fe934b4747..285d05b560 100644 --- a/bin/node-template/pallets/template/Cargo.toml +++ b/bin/node-template/pallets/template/Cargo.toml @@ -2,7 +2,7 @@ authors = ['Anonymous'] edition = '2018' name = 'pallet-template' -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" license = "Unlicense" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -14,27 +14,27 @@ safe-mix = { default-features = false, version = '1.0.0' } [dependencies.frame-support] default-features = false -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" path = "../../../../frame/support" [dependencies.system] default-features = false package = 'frame-system' -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" path = "../../../../frame/system" [dev-dependencies.sp-core] default-features = false -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" path = "../../../../primitives/core" [dev-dependencies.sp-io] default-features = false -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" path = "../../../../primitives/io" [dev-dependencies.sp-runtime] default-features = false -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" path = "../../../../primitives/runtime" diff --git a/bin/node-template/runtime/Cargo.toml b/bin/node-template/runtime/Cargo.toml index fa4c0a9f14..c5f778e055 100644 --- a/bin/node-template/runtime/Cargo.toml +++ b/bin/node-template/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-template-runtime" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Anonymous"] edition = "2018" license = "Unlicense" @@ -10,31 +10,31 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -aura = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-aura", path = "../../../frame/aura" } -balances = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-balances", path = "../../../frame/balances" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/support" } -grandpa = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-grandpa", path = "../../../frame/grandpa" } -randomness-collective-flip = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-randomness-collective-flip", path = "../../../frame/randomness-collective-flip" } -sudo = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-sudo", path = "../../../frame/sudo" } -system = { version = "2.0.0-alpha.4", default-features = false, package = "frame-system", path = "../../../frame/system" } -timestamp = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-timestamp", path = "../../../frame/timestamp" } -transaction-payment = { version = "2.0.0-alpha.4", default-features = false, package = "pallet-transaction-payment", path = "../../../frame/transaction-payment" } -frame-executive = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/executive" } +aura = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-aura", path = "../../../frame/aura" } +balances = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-balances", path = "../../../frame/balances" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/support" } +grandpa = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-grandpa", path = "../../../frame/grandpa" } +randomness-collective-flip = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-randomness-collective-flip", path = "../../../frame/randomness-collective-flip" } +sudo = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-sudo", path = "../../../frame/sudo" } +system = { version = "2.0.0-alpha.5", default-features = false, package = "frame-system", path = "../../../frame/system" } +timestamp = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-timestamp", path = "../../../frame/timestamp" } +transaction-payment = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-transaction-payment", path = "../../../frame/transaction-payment" } +frame-executive = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/executive" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/api" } -sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.4"} -sp-consensus-aura = { version = "0.8.0-alpha.4", default-features = false, path = "../../../primitives/consensus/aura" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/core" } -sp-inherents = { path = "../../../primitives/inherents", default-features = false, version = "2.0.0-alpha.4"} -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/io" } -sp-offchain = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/offchain" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } -sp-session = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/session" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/std" } -sp-transaction-pool = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/transaction-pool" } -sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/version" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/api" } +sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.5"} +sp-consensus-aura = { version = "0.8.0-alpha.5", default-features = false, path = "../../../primitives/consensus/aura" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/core" } +sp-inherents = { path = "../../../primitives/inherents", default-features = false, version = "2.0.0-alpha.5"} +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/io" } +sp-offchain = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/offchain" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } +sp-session = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/session" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" } +sp-transaction-pool = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/transaction-pool" } +sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/version" } -template = { version = "2.0.0-alpha.4", default-features = false, path = "../pallets/template", package = "pallet-template" } +template = { version = "2.0.0-alpha.5", default-features = false, path = "../pallets/template", package = "pallet-template" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index f9a999763e..9a286c5880 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-cli" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] description = "Substrate node implementation in Rust." build = "build.rs" @@ -42,68 +42,68 @@ structopt = { version = "0.3.8", optional = true } tracing = "0.1.10" # primitives -sp-authority-discovery = { version = "2.0.0-alpha.4", path = "../../../primitives/authority-discovery" } -sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/babe" } -grandpa-primitives = { version = "2.0.0-alpha.4", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/timestamp" } -sp-finality-tracker = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/finality-tracker" } -sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.4", path = "../../../primitives/keyring" } -sp-io = { version = "2.0.0-alpha.4", path = "../../../primitives/io" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +sp-authority-discovery = { version = "2.0.0-alpha.5", path = "../../../primitives/authority-discovery" } +sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/babe" } +grandpa-primitives = { version = "2.0.0-alpha.5", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/timestamp" } +sp-finality-tracker = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/finality-tracker" } +sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } +sp-keyring = { version = "2.0.0-alpha.5", path = "../../../primitives/keyring" } +sp-io = { version = "2.0.0-alpha.5", path = "../../../primitives/io" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } # client dependencies -sc-client-api = { version = "2.0.0-alpha.4", path = "../../../client/api" } -sc-client = { version = "0.8.0-alpha.4", path = "../../../client/" } -sc-chain-spec = { version = "2.0.0-alpha.4", path = "../../../client/chain-spec" } -sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../client/transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../primitives/transaction-pool" } -sc-network = { version = "0.8.0-alpha.4", path = "../../../client/network" } -sc-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../client/consensus/babe" } -grandpa = { version = "0.8.0-alpha.4", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } -sc-client-db = { version = "0.8.0-alpha.4", default-features = false, path = "../../../client/db" } -sc-offchain = { version = "2.0.0-alpha.4", path = "../../../client/offchain" } -sc-rpc = { version = "2.0.0-alpha.4", path = "../../../client/rpc" } -sc-basic-authorship = { version = "0.8.0-alpha.4", path = "../../../client/basic-authorship" } -sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../../../client/service" } -sc-tracing = { version = "2.0.0-alpha.4", path = "../../../client/tracing" } -sc-telemetry = { version = "2.0.0-alpha.4", path = "../../../client/telemetry" } -sc-authority-discovery = { version = "0.8.0-alpha.4", path = "../../../client/authority-discovery" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } +sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } +sc-chain-spec = { version = "2.0.0-alpha.5", path = "../../../client/chain-spec" } +sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } +sc-network = { version = "0.8.0-alpha.5", path = "../../../client/network" } +sc-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../client/consensus/babe" } +grandpa = { version = "0.8.0-alpha.5", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } +sc-client-db = { version = "0.8.0-alpha.5", default-features = false, path = "../../../client/db" } +sc-offchain = { version = "2.0.0-alpha.5", path = "../../../client/offchain" } +sc-rpc = { version = "2.0.0-alpha.5", path = "../../../client/rpc" } +sc-basic-authorship = { version = "0.8.0-alpha.5", path = "../../../client/basic-authorship" } +sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../../../client/service" } +sc-tracing = { version = "2.0.0-alpha.5", path = "../../../client/tracing" } +sc-telemetry = { version = "2.0.0-alpha.5", path = "../../../client/telemetry" } +sc-authority-discovery = { version = "0.8.0-alpha.5", path = "../../../client/authority-discovery" } # frame dependencies -pallet-indices = { version = "2.0.0-alpha.4", path = "../../../frame/indices" } -pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/timestamp" } -pallet-contracts = { version = "2.0.0-alpha.4", path = "../../../frame/contracts" } -frame-system = { version = "2.0.0-alpha.4", path = "../../../frame/system" } -pallet-balances = { version = "2.0.0-alpha.4", path = "../../../frame/balances" } -pallet-transaction-payment = { version = "2.0.0-alpha.4", path = "../../../frame/transaction-payment" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/support" } -pallet-im-online = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/im-online" } -pallet-authority-discovery = { version = "2.0.0-alpha.4", path = "../../../frame/authority-discovery" } +pallet-indices = { version = "2.0.0-alpha.5", path = "../../../frame/indices" } +pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/timestamp" } +pallet-contracts = { version = "2.0.0-alpha.5", path = "../../../frame/contracts" } +frame-system = { version = "2.0.0-alpha.5", path = "../../../frame/system" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../../../frame/balances" } +pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../../../frame/transaction-payment" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/support" } +pallet-im-online = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/im-online" } +pallet-authority-discovery = { version = "2.0.0-alpha.5", path = "../../../frame/authority-discovery" } # node-specific dependencies -node-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } -node-rpc = { version = "2.0.0-alpha.4", path = "../rpc" } -node-primitives = { version = "2.0.0-alpha.4", path = "../primitives" } -node-executor = { version = "2.0.0-alpha.4", path = "../executor" } +node-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } +node-rpc = { version = "2.0.0-alpha.5", path = "../rpc" } +node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } +node-executor = { version = "2.0.0-alpha.5", path = "../executor" } # CLI-specific dependencies -sc-cli = { version = "0.8.0-alpha.4", optional = true, path = "../../../client/cli" } -frame-benchmarking-cli = { version = "2.0.0-alpha.4", optional = true, path = "../../../utils/frame/benchmarking-cli" } -node-transaction-factory = { version = "0.8.0-alpha.4", optional = true, path = "../transaction-factory" } -node-inspect = { version = "0.8.0-alpha.4", optional = true, path = "../inspect" } +sc-cli = { version = "0.8.0-alpha.5", optional = true, path = "../../../client/cli" } +frame-benchmarking-cli = { version = "2.0.0-alpha.5", optional = true, path = "../../../utils/frame/benchmarking-cli" } +node-transaction-factory = { version = "0.8.0-alpha.5", optional = true, path = "../transaction-factory" } +node-inspect = { version = "0.8.0-alpha.5", optional = true, path = "../inspect" } # WASM-specific dependencies wasm-bindgen = { version = "0.2.57", optional = true } wasm-bindgen-futures = { version = "0.4.7", optional = true } -browser-utils = { package = "substrate-browser-utils", path = "../../../utils/browser", optional = true, version = "0.8.0-alpha.4"} +browser-utils = { package = "substrate-browser-utils", path = "../../../utils/browser", optional = true, version = "0.8.0-alpha.5"} [dev-dependencies] -sc-keystore = { version = "2.0.0-alpha.4", path = "../../../client/keystore" } -sc-consensus-babe = { version = "0.8.0-alpha.4", features = ["test-helpers"], path = "../../../client/consensus/babe" } -sc-consensus-epochs = { version = "0.8.0-alpha.4", path = "../../../client/consensus/epochs" } +sc-keystore = { version = "2.0.0-alpha.5", path = "../../../client/keystore" } +sc-consensus-babe = { version = "0.8.0-alpha.5", features = ["test-helpers"], path = "../../../client/consensus/babe" } +sc-consensus-epochs = { version = "0.8.0-alpha.5", path = "../../../client/consensus/epochs" } sc-service-test = { version = "2.0.0-dev", path = "../../../client/service/test" } futures = "0.3.1" tempfile = "3.1.0" @@ -112,14 +112,14 @@ nix = "0.17" serde_json = "1.0" [build-dependencies] -build-script-utils = { version = "2.0.0-alpha.4", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } +build-script-utils = { version = "2.0.0-alpha.5", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } structopt = { version = "0.3.8", optional = true } -node-transaction-factory = { version = "0.8.0-alpha.4", optional = true, path = "../transaction-factory" } -node-inspect = { version = "0.8.0-alpha.4", optional = true, path = "../inspect" } -frame-benchmarking-cli = { version = "2.0.0-alpha.4", optional = true, path = "../../../utils/frame/benchmarking-cli" } +node-transaction-factory = { version = "0.8.0-alpha.5", optional = true, path = "../transaction-factory" } +node-inspect = { version = "0.8.0-alpha.5", optional = true, path = "../inspect" } +frame-benchmarking-cli = { version = "2.0.0-alpha.5", optional = true, path = "../../../utils/frame/benchmarking-cli" } [build-dependencies.sc-cli] -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" package = "sc-cli" path = "../../../client/cli" optional = true diff --git a/bin/node/executor/Cargo.toml b/bin/node/executor/Cargo.toml index 6d02e7de80..02c6a141e9 100644 --- a/bin/node/executor/Cargo.toml +++ b/bin/node/executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-executor" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] description = "Substrate node implementation in Rust." edition = "2018" @@ -10,33 +10,33 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0" } -node-primitives = { version = "2.0.0-alpha.4", path = "../primitives" } -node-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } -sc-executor = { version = "0.8.0-alpha.4", path = "../../../client/executor" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-io = { version = "2.0.0-alpha.4", path = "../../../primitives/io" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } -sp-trie = { version = "2.0.0-alpha.4", path = "../../../primitives/trie" } +node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } +node-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } +sc-executor = { version = "0.8.0-alpha.5", path = "../../../client/executor" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-io = { version = "2.0.0-alpha.5", path = "../../../primitives/io" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } +sp-trie = { version = "2.0.0-alpha.5", path = "../../../primitives/trie" } trie-root = "0.16.0" -frame-benchmarking = { version = "2.0.0-alpha.4", path = "../../../frame/benchmarking" } +frame-benchmarking = { version = "2.0.0-alpha.5", path = "../../../frame/benchmarking" } [dev-dependencies] criterion = "0.3.0" -frame-support = { version = "2.0.0-alpha.4", path = "../../../frame/support" } -frame-system = { version = "2.0.0-alpha.4", path = "../../../frame/system" } -node-testing = { version = "2.0.0-alpha.4", path = "../testing" } -pallet-balances = { version = "2.0.0-alpha.4", path = "../../../frame/balances" } -pallet-contracts = { version = "2.0.0-alpha.4", path = "../../../frame/contracts" } -pallet-grandpa = { version = "2.0.0-alpha.4", path = "../../../frame/grandpa" } -pallet-im-online = { version = "2.0.0-alpha.4", path = "../../../frame/im-online" } -pallet-indices = { version = "2.0.0-alpha.4", path = "../../../frame/indices" } -pallet-session = { version = "2.0.0-alpha.4", path = "../../../frame/session" } -pallet-timestamp = { version = "2.0.0-alpha.4", path = "../../../frame/timestamp" } -pallet-transaction-payment = { version = "2.0.0-alpha.4", path = "../../../frame/transaction-payment" } -pallet-treasury = { version = "2.0.0-alpha.4", path = "../../../frame/treasury" } -sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../../primitives/application-crypto" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-externalities = { version = "0.8.0-alpha.4", path = "../../../primitives/externalities" } +frame-support = { version = "2.0.0-alpha.5", path = "../../../frame/support" } +frame-system = { version = "2.0.0-alpha.5", path = "../../../frame/system" } +node-testing = { version = "2.0.0-alpha.5", path = "../testing" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../../../frame/balances" } +pallet-contracts = { version = "2.0.0-alpha.5", path = "../../../frame/contracts" } +pallet-grandpa = { version = "2.0.0-alpha.5", path = "../../../frame/grandpa" } +pallet-im-online = { version = "2.0.0-alpha.5", path = "../../../frame/im-online" } +pallet-indices = { version = "2.0.0-alpha.5", path = "../../../frame/indices" } +pallet-session = { version = "2.0.0-alpha.5", path = "../../../frame/session" } +pallet-timestamp = { version = "2.0.0-alpha.5", path = "../../../frame/timestamp" } +pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../../../frame/transaction-payment" } +pallet-treasury = { version = "2.0.0-alpha.5", path = "../../../frame/treasury" } +sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../../primitives/application-crypto" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-externalities = { version = "0.8.0-alpha.5", path = "../../../primitives/externalities" } substrate-test-client = { version = "2.0.0-dev", path = "../../../test-utils/client" } wabt = "0.9.2" diff --git a/bin/node/inspect/Cargo.toml b/bin/node/inspect/Cargo.toml index 6eb8523f39..36ba0c7205 100644 --- a/bin/node/inspect/Cargo.toml +++ b/bin/node/inspect/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-inspect" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,10 +11,10 @@ repository = "https://github.com/paritytech/substrate/" codec = { package = "parity-scale-codec", version = "1.2.0" } derive_more = "0.99" log = "0.4.8" -sc-cli = { version = "0.8.0-alpha.4", path = "../../../client/cli" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../../../client/api" } -sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../../../client/service" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } +sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../../../client/service" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } structopt = "0.3.8" diff --git a/bin/node/primitives/Cargo.toml b/bin/node/primitives/Cargo.toml index e200c04cdd..d4d6d99092 100644 --- a/bin/node/primitives/Cargo.toml +++ b/bin/node/primitives/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-primitives" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,11 +8,11 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } [dev-dependencies] -sp-serializer = { version = "2.0.0-alpha.4", path = "../../../primitives/serializer" } +sp-serializer = { version = "2.0.0-alpha.5", path = "../../../primitives/serializer" } pretty_assertions = "0.6.1" [features] diff --git a/bin/node/rpc-client/Cargo.toml b/bin/node/rpc-client/Cargo.toml index 46f8411b42..ec6839b71c 100644 --- a/bin/node/rpc-client/Cargo.toml +++ b/bin/node/rpc-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-rpc-client" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,5 +13,5 @@ futures = "0.1.29" hyper = "0.12.35" jsonrpc-core-client = { version = "14.0.3", features = ["http", "ws"] } log = "0.4.8" -node-primitives = { version = "2.0.0-alpha.4", path = "../primitives" } -sc-rpc = { version = "2.0.0-alpha.4", path = "../../../client/rpc" } +node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } +sc-rpc = { version = "2.0.0-alpha.5", path = "../../../client/rpc" } diff --git a/bin/node/rpc/Cargo.toml b/bin/node/rpc/Cargo.toml index dd64e3336a..ada97e5667 100644 --- a/bin/node/rpc/Cargo.toml +++ b/bin/node/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-rpc" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,20 +8,20 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sc-client = { version = "0.8.0-alpha.4", path = "../../../client/" } +sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } jsonrpc-core = "14.0.3" -node-primitives = { version = "2.0.0-alpha.4", path = "../primitives" } -node-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } -pallet-contracts-rpc = { version = "0.8.0-alpha.4", path = "../../../frame/contracts/rpc/" } -pallet-transaction-payment-rpc = { version = "2.0.0-alpha.4", path = "../../../frame/transaction-payment/rpc/" } -substrate-frame-rpc-system = { version = "2.0.0-alpha.4", path = "../../../utils/frame/rpc/system" } -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../primitives/transaction-pool" } -sc-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../client/consensus/babe" } -sc-consensus-babe-rpc = { version = "0.8.0-alpha.4", path = "../../../client/consensus/babe/rpc" } -sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/babe" } -sc-keystore = { version = "2.0.0-alpha.4", path = "../../../client/keystore" } -sc-consensus-epochs = { version = "0.8.0-alpha.4", path = "../../../client/consensus/epochs" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } +node-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } +pallet-contracts-rpc = { version = "0.8.0-alpha.5", path = "../../../frame/contracts/rpc/" } +pallet-transaction-payment-rpc = { version = "2.0.0-alpha.5", path = "../../../frame/transaction-payment/rpc/" } +substrate-frame-rpc-system = { version = "2.0.0-alpha.5", path = "../../../utils/frame/rpc/system" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } +sc-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../client/consensus/babe" } +sc-consensus-babe-rpc = { version = "0.8.0-alpha.5", path = "../../../client/consensus/babe/rpc" } +sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/babe" } +sc-keystore = { version = "2.0.0-alpha.5", path = "../../../client/keystore" } +sc-consensus-epochs = { version = "0.8.0-alpha.5", path = "../../../client/consensus/epochs" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index a39343e581..6346f3d848 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-runtime" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" @@ -16,65 +16,65 @@ integer-sqrt = { version = "0.1.2" } serde = { version = "1.0.102", optional = true } # primitives -sp-authority-discovery = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/authority-discovery" } -sp-consensus-babe = { version = "0.8.0-alpha.4", default-features = false, path = "../../../primitives/consensus/babe" } -sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.4"} -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/inherents" } -node-primitives = { version = "2.0.0-alpha.4", default-features = false, path = "../primitives" } -sp-offchain = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/offchain" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/core" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/std" } -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/staking" } -sp-keyring = { version = "2.0.0-alpha.4", optional = true, path = "../../../primitives/keyring" } -sp-session = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/session" } -sp-transaction-pool = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/transaction-pool" } -sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/version" } +sp-authority-discovery = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/authority-discovery" } +sp-consensus-babe = { version = "0.8.0-alpha.5", default-features = false, path = "../../../primitives/consensus/babe" } +sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.5"} +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/inherents" } +node-primitives = { version = "2.0.0-alpha.5", default-features = false, path = "../primitives" } +sp-offchain = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/offchain" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/staking" } +sp-keyring = { version = "2.0.0-alpha.5", optional = true, path = "../../../primitives/keyring" } +sp-session = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/session" } +sp-transaction-pool = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/transaction-pool" } +sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/version" } # frame dependencies -frame-executive = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/executive" } -frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/system" } -frame-system-rpc-runtime-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } -pallet-authority-discovery = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/authority-discovery" } -pallet-authorship = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/authorship" } -pallet-babe = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/babe" } -pallet-balances = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/balances" } -pallet-collective = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/collective" } -pallet-contracts = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/contracts" } -pallet-contracts-primitives = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/contracts/common/" } -pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.4", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" } -pallet-democracy = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/democracy" } -pallet-elections-phragmen = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/elections-phragmen" } -pallet-finality-tracker = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/finality-tracker" } -pallet-grandpa = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/grandpa" } -pallet-im-online = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/im-online" } -pallet-indices = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/indices" } -pallet-identity = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/identity" } -pallet-membership = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/membership" } -pallet-offences = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/offences" } -pallet-randomness-collective-flip = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/randomness-collective-flip" } -pallet-recovery = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/recovery" } -pallet-session = { version = "2.0.0-alpha.4", features = ["historical"], path = "../../../frame/session", default-features = false } -pallet-session-benchmarking = { version = "2.0.0-alpha.4", path = "../../../frame/session/benchmarking", default-features = false, optional = true } -pallet-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/staking" } -pallet-staking-reward-curve = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/staking/reward-curve" } -pallet-sudo = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/sudo" } -pallet-society = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/society" } -pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/timestamp" } -pallet-treasury = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/treasury" } -pallet-utility = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/utility" } -pallet-transaction-payment = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/transaction-payment" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" } -pallet-vesting = { version = "2.0.0-alpha.4", default-features = false, path = "../../../frame/vesting" } +frame-executive = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/executive" } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/system" } +frame-system-rpc-runtime-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } +pallet-authority-discovery = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/authority-discovery" } +pallet-authorship = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/authorship" } +pallet-babe = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/babe" } +pallet-balances = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/balances" } +pallet-collective = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/collective" } +pallet-contracts = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/contracts" } +pallet-contracts-primitives = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/contracts/common/" } +pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.5", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" } +pallet-democracy = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/democracy" } +pallet-elections-phragmen = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/elections-phragmen" } +pallet-finality-tracker = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/finality-tracker" } +pallet-grandpa = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/grandpa" } +pallet-im-online = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/im-online" } +pallet-indices = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/indices" } +pallet-identity = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/identity" } +pallet-membership = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/membership" } +pallet-offences = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/offences" } +pallet-randomness-collective-flip = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/randomness-collective-flip" } +pallet-recovery = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/recovery" } +pallet-session = { version = "2.0.0-alpha.5", features = ["historical"], path = "../../../frame/session", default-features = false } +pallet-session-benchmarking = { version = "2.0.0-alpha.5", path = "../../../frame/session/benchmarking", default-features = false, optional = true } +pallet-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/staking" } +pallet-staking-reward-curve = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/staking/reward-curve" } +pallet-sudo = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/sudo" } +pallet-society = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/society" } +pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/timestamp" } +pallet-treasury = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/treasury" } +pallet-utility = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/utility" } +pallet-transaction-payment = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/transaction-payment" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" } +pallet-vesting = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/vesting" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.4", path = "../../../primitives/io" } +sp-io = { version = "2.0.0-alpha.5", path = "../../../primitives/io" } [features] default = ["std"] diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index 8ef154c173..d852aaac26 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-testing" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] description = "Test utilities for Substrate node." edition = "2018" @@ -10,48 +10,48 @@ repository = "https://github.com/paritytech/substrate/" publish = true [dependencies] -pallet-balances = { version = "2.0.0-alpha.4", path = "../../../frame/balances" } -sc-client = { version = "0.8.0-alpha.4", path = "../../../client/" } -sc-client-db = { version = "0.8.0-alpha.4", path = "../../../client/db/", features = ["kvdb-rocksdb"] } -sc-client-api = { version = "2.0.0-alpha.4", path = "../../../client/api/" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../../../frame/balances" } +sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } +sc-client-db = { version = "0.8.0-alpha.5", path = "../../../client/db/", features = ["kvdb-rocksdb"] } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api/" } codec = { package = "parity-scale-codec", version = "1.2.0" } -pallet-contracts = { version = "2.0.0-alpha.4", path = "../../../frame/contracts" } -pallet-grandpa = { version = "2.0.0-alpha.4", path = "../../../frame/grandpa" } -pallet-indices = { version = "2.0.0-alpha.4", path = "../../../frame/indices" } -sp-keyring = { version = "2.0.0-alpha.4", path = "../../../primitives/keyring" } -node-executor = { version = "2.0.0-alpha.4", path = "../executor" } -node-primitives = { version = "2.0.0-alpha.4", path = "../primitives" } -node-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-io = { version = "2.0.0-alpha.4", path = "../../../primitives/io" } -frame-support = { version = "2.0.0-alpha.4", path = "../../../frame/support" } -pallet-session = { version = "2.0.0-alpha.4", path = "../../../frame/session" } -pallet-society = { version = "2.0.0-alpha.4", path = "../../../frame/society" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -pallet-staking = { version = "2.0.0-alpha.4", path = "../../../frame/staking" } -sc-executor = { version = "0.8.0-alpha.4", path = "../../../client/executor", features = ["wasmtime"] } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } -frame-system = { version = "2.0.0-alpha.4", path = "../../../frame/system" } +pallet-contracts = { version = "2.0.0-alpha.5", path = "../../../frame/contracts" } +pallet-grandpa = { version = "2.0.0-alpha.5", path = "../../../frame/grandpa" } +pallet-indices = { version = "2.0.0-alpha.5", path = "../../../frame/indices" } +sp-keyring = { version = "2.0.0-alpha.5", path = "../../../primitives/keyring" } +node-executor = { version = "2.0.0-alpha.5", path = "../executor" } +node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } +node-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-io = { version = "2.0.0-alpha.5", path = "../../../primitives/io" } +frame-support = { version = "2.0.0-alpha.5", path = "../../../frame/support" } +pallet-session = { version = "2.0.0-alpha.5", path = "../../../frame/session" } +pallet-society = { version = "2.0.0-alpha.5", path = "../../../frame/society" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +pallet-staking = { version = "2.0.0-alpha.5", path = "../../../frame/staking" } +sc-executor = { version = "0.8.0-alpha.5", path = "../../../client/executor", features = ["wasmtime"] } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } +frame-system = { version = "2.0.0-alpha.5", path = "../../../frame/system" } substrate-test-client = { version = "2.0.0-dev", path = "../../../test-utils/client" } -pallet-timestamp = { version = "2.0.0-alpha.4", path = "../../../frame/timestamp" } -pallet-transaction-payment = { version = "2.0.0-alpha.4", path = "../../../frame/transaction-payment" } -pallet-treasury = { version = "2.0.0-alpha.4", path = "../../../frame/treasury" } +pallet-timestamp = { version = "2.0.0-alpha.5", path = "../../../frame/timestamp" } +pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../../../frame/transaction-payment" } +pallet-treasury = { version = "2.0.0-alpha.5", path = "../../../frame/treasury" } wabt = "0.9.2" -sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } -sp-finality-tracker = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/finality-tracker" } -sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/timestamp" } -sp-block-builder = { version = "2.0.0-alpha.4", path = "../../../primitives/block-builder" } -sc-block-builder = { version = "0.8.0-alpha.4", path = "../../../client/block-builder" } -sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } +sp-finality-tracker = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/finality-tracker" } +sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/timestamp" } +sp-block-builder = { version = "2.0.0-alpha.5", path = "../../../primitives/block-builder" } +sc-block-builder = { version = "0.8.0-alpha.5", path = "../../../client/block-builder" } +sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } log = "0.4.8" tempfile = "3.1.0" fs_extra = "1" [dev-dependencies] criterion = "0.3.0" -sc-cli = { version = "0.8.0-alpha.4", path = "../../../client/cli" } -sc-service = { version = "0.8.0-alpha.4", path = "../../../client/service", features = ["rocksdb"] } +sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } +sc-service = { version = "0.8.0-alpha.5", path = "../../../client/service", features = ["rocksdb"] } [[bench]] name = "import" diff --git a/bin/node/transaction-factory/Cargo.toml b/bin/node/transaction-factory/Cargo.toml index 6d44faca10..b95b55a536 100644 --- a/bin/node/transaction-factory/Cargo.toml +++ b/bin/node/transaction-factory/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-transaction-factory" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,16 +8,16 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-block-builder = { version = "2.0.0-alpha.4", path = "../../../primitives/block-builder" } -sc-cli = { version = "0.8.0-alpha.4", path = "../../../client/cli" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../../../client/api" } -sc-block-builder = { version = "0.8.0-alpha.4", path = "../../../client/block-builder" } -sc-client = { version = "0.8.0-alpha.4", path = "../../../client" } +sp-block-builder = { version = "2.0.0-alpha.5", path = "../../../primitives/block-builder" } +sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } +sc-block-builder = { version = "0.8.0-alpha.5", path = "../../../client/block-builder" } +sc-client = { version = "0.8.0-alpha.5", path = "../../../client" } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } log = "0.4.8" -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../../../client/service" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../../../client/service" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } diff --git a/bin/utils/chain-spec-builder/Cargo.toml b/bin/utils/chain-spec-builder/Cargo.toml index 7068ce48e0..0cadbe7614 100644 --- a/bin/utils/chain-spec-builder/Cargo.toml +++ b/bin/utils/chain-spec-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "chain-spec-builder" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" @@ -10,8 +10,8 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] ansi_term = "0.12.1" -sc-keystore = { version = "2.0.0-alpha.4", path = "../../../client/keystore" } -node-cli = { version = "2.0.0-alpha.4", path = "../../node/cli" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sc-keystore = { version = "2.0.0-alpha.5", path = "../../../client/keystore" } +node-cli = { version = "2.0.0-alpha.5", path = "../../node/cli" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } rand = "0.7.2" structopt = "0.3.8" diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index d8a116b378..d8d7532a4c 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "subkey" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,10 +9,10 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] futures = "0.1.29" -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -node-runtime = { version = "2.0.0-alpha.4", path = "../../node/runtime" } -node-primitives = { version = "2.0.0-alpha.4", path = "../../node/primitives" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +node-runtime = { version = "2.0.0-alpha.5", path = "../../node/runtime" } +node-primitives = { version = "2.0.0-alpha.5", path = "../../node/primitives" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } rand = "0.7.2" clap = "2.33.0" tiny-bip39 = "0.7" @@ -20,13 +20,13 @@ substrate-bip39 = "0.4.1" hex = "0.4.0" hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.2.0" } -frame-system = { version = "2.0.0-alpha.4", path = "../../../frame/system" } -pallet-balances = { version = "2.0.0-alpha.4", path = "../../../frame/balances" } -pallet-transaction-payment = { version = "2.0.0-alpha.4", path = "../../../frame/transaction-payment" } +frame-system = { version = "2.0.0-alpha.5", path = "../../../frame/system" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../../../frame/balances" } +pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../../../frame/transaction-payment" } rpassword = "4.0.1" itertools = "0.8.2" derive_more = { version = "0.99.2" } -sc-rpc = { version = "2.0.0-alpha.4", path = "../../../client/rpc" } +sc-rpc = { version = "2.0.0-alpha.5", path = "../../../client/rpc" } jsonrpc-core-client = { version = "14.0.3", features = ["http"] } hyper = "0.12.35" libp2p = "0.16.2" diff --git a/client/Cargo.toml b/client/Cargo.toml index bca4ab60f3..7a38faad04 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-client" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,32 +9,32 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate Client and associated logic." [dependencies] -sc-block-builder = { version = "0.8.0-alpha.4", path = "block-builder" } -sc-client-api = { version = "2.0.0-alpha.4", path = "api" } +sc-block-builder = { version = "0.8.0-alpha.5", path = "block-builder" } +sc-client-api = { version = "2.0.0-alpha.5", path = "api" } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.4", path = "../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../primitives/consensus/common" } derive_more = { version = "0.99.2" } -sc-executor = { version = "0.8.0-alpha.4", path = "executor" } -sp-externalities = { version = "0.8.0-alpha.4", path = "../primitives/externalities" } +sc-executor = { version = "0.8.0-alpha.5", path = "executor" } +sp-externalities = { version = "0.8.0-alpha.5", path = "../primitives/externalities" } fnv = { version = "1.0.6" } futures = { version = "0.3.1", features = ["compat"] } hash-db = { version = "0.15.2" } hex-literal = { version = "0.2.1" } -sp-inherents = { version = "2.0.0-alpha.4", path = "../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.4", path = "../primitives/keyring" } +sp-inherents = { version = "2.0.0-alpha.5", path = "../primitives/inherents" } +sp-keyring = { version = "2.0.0-alpha.5", path = "../primitives/keyring" } kvdb = "0.5.0" log = { version = "0.4.8" } parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.4", path = "../primitives/core" } -sp-std = { version = "2.0.0-alpha.4", path = "../primitives/std" } -sp-version = { version = "2.0.0-alpha.4", path = "../primitives/version" } -sp-api = { version = "2.0.0-alpha.4", path = "../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../primitives/runtime" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../primitives/blockchain" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-alpha.4", path = "telemetry" } -sp-trie = { version = "2.0.0-alpha.4", path = "../primitives/trie" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.4", path = "../utils/prometheus" } +sp-core = { version = "2.0.0-alpha.5", path = "../primitives/core" } +sp-std = { version = "2.0.0-alpha.5", path = "../primitives/std" } +sp-version = { version = "2.0.0-alpha.5", path = "../primitives/version" } +sp-api = { version = "2.0.0-alpha.5", path = "../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../primitives/runtime" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../primitives/blockchain" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-alpha.5", path = "telemetry" } +sp-trie = { version = "2.0.0-alpha.5", path = "../primitives/trie" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.5", path = "../utils/prometheus" } tracing = "0.1.10" [dev-dependencies] @@ -42,4 +42,4 @@ env_logger = "0.7.0" tempfile = "3.1.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../test-utils/runtime/client" } kvdb-memorydb = "0.5.0" -sp-panic-handler = { version = "2.0.0-alpha.4", path = "../primitives/panic-handler" } +sp-panic-handler = { version = "2.0.0-alpha.5", path = "../primitives/panic-handler" } diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index 1006d92b74..c3afdee413 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-client-api" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,30 +12,30 @@ documentation = "https://docs.rs/sc-client-api" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } derive_more = { version = "0.99.2" } -sc-executor = { version = "0.8.0-alpha.4", path = "../executor" } -sp-externalities = { version = "0.8.0-alpha.4", path = "../../primitives/externalities" } +sc-executor = { version = "0.8.0-alpha.5", path = "../executor" } +sp-externalities = { version = "0.8.0-alpha.5", path = "../../primitives/externalities" } fnv = { version = "1.0.6" } futures = { version = "0.3.1" } hash-db = { version = "0.15.2", default-features = false } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } hex-literal = { version = "0.2.1" } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } +sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } kvdb = "0.5.0" log = { version = "0.4.8" } parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/version" } -sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } -sp-trie = { version = "2.0.0-alpha.4", path = "../../primitives/trie" } -sp-storage = { version = "2.0.0-alpha.4", path = "../../primitives/storage" } -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/version" } +sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } +sp-trie = { version = "2.0.0-alpha.5", path = "../../primitives/trie" } +sp-storage = { version = "2.0.0-alpha.5", path = "../../primitives/storage" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } [dev-dependencies] sp-test-primitives = { version = "2.0.0-dev", path = "../../primitives/test-primitives" } diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index c0d6804d0b..5a7f78b95d 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-authority-discovery" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" @@ -20,21 +20,21 @@ futures = "0.3.1" futures-timer = "3.0.1" libp2p = { version = "0.16.2", default-features = false, features = ["secp256k1", "libp2p-websocket"] } log = "0.4.8" -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.4"} +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.5"} prost = "0.6.1" rand = "0.7.2" -sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } -sc-keystore = { version = "2.0.0-alpha.4", path = "../keystore" } -sc-network = { version = "0.8.0-alpha.4", path = "../network" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } +sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } +sc-network = { version = "0.8.0-alpha.5", path = "../network" } serde_json = "1.0.41" -sp-authority-discovery = { version = "2.0.0-alpha.4", path = "../../primitives/authority-discovery" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } +sp-authority-discovery = { version = "2.0.0-alpha.5", path = "../../primitives/authority-discovery" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } [dev-dependencies] env_logger = "0.7.0" quickcheck = "0.9.0" -sc-peerset = { version = "2.0.0-alpha.4", path = "../peerset" } +sc-peerset = { version = "2.0.0-alpha.5", path = "../peerset" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client"} diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index f7bab74a24..34ce9c948c 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-basic-authorship" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,20 +12,20 @@ description = "Basic implementation of block-authoring logic." log = "0.4.8" futures = "0.3.1" codec = { package = "parity-scale-codec", version = "1.2.0" } -sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-alpha.4", path = "../../primitives/inherents" } -sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } -sc-block-builder = { version = "0.8.0-alpha.4", path = "../block-builder" } +sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-alpha.5", path = "../../primitives/inherents" } +sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } +sc-block-builder = { version = "0.8.0-alpha.5", path = "../block-builder" } tokio-executor = { version = "0.2.0-alpha.6", features = ["blocking"] } futures-timer = "3.0.1" [dev-dependencies] -sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../../client/transaction-pool" } +sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../../client/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } parking_lot = "0.10.0" diff --git a/client/block-builder/Cargo.toml b/client/block-builder/Cargo.toml index be97b796fb..351c3e0a77 100644 --- a/client/block-builder/Cargo.toml +++ b/client/block-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-block-builder" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,16 +10,16 @@ description = "Substrate block builder" [dependencies] -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-block-builder = { version = "2.0.0-alpha.4", path = "../../primitives/block-builder" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-block-builder = { version = "2.0.0-alpha.5", path = "../../primitives/block-builder" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } [dev-dependencies] substrate-test-runtime-client = { path = "../../test-utils/runtime/client" } -sp-trie = { version = "2.0.0-alpha.4", path = "../../primitives/trie" } +sp-trie = { version = "2.0.0-alpha.5", path = "../../primitives/trie" } diff --git a/client/chain-spec/Cargo.toml b/client/chain-spec/Cargo.toml index 72a999bca3..2eb172ffee 100644 --- a/client/chain-spec/Cargo.toml +++ b/client/chain-spec/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-chain-spec" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,11 +9,11 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate chain configurations." [dependencies] -sc-chain-spec-derive = { version = "2.0.0-alpha.4", path = "./derive" } +sc-chain-spec-derive = { version = "2.0.0-alpha.5", path = "./derive" } impl-trait-for-tuples = "0.1.3" -sc-network = { version = "0.8.0-alpha.4", path = "../network" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sc-network = { version = "0.8.0-alpha.5", path = "../network" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } -sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } diff --git a/client/chain-spec/derive/Cargo.toml b/client/chain-spec/derive/Cargo.toml index 236eb9ce09..f7e57e26f3 100644 --- a/client/chain-spec/derive/Cargo.toml +++ b/client/chain-spec/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-chain-spec-derive" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 30a53c81ca..cc1b90dd2f 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-cli" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "Substrate CLI interface." edition = "2018" @@ -23,21 +23,21 @@ tokio = { version = "0.2.9", features = [ "signal", "rt-core", "rt-threaded" ] } futures = "0.3.1" fdlimit = "0.1.4" serde_json = "1.0.41" -sc-informant = { version = "0.8.0-alpha.4", path = "../informant" } -sp-panic-handler = { version = "2.0.0-alpha.4", path = "../../primitives/panic-handler" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } -sc-network = { version = "0.8.0-alpha.4", path = "../network" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../service" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } -substrate-prometheus-endpoint = { path = "../../utils/prometheus" , version = "0.8.0-alpha.4"} -sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } +sc-informant = { version = "0.8.0-alpha.5", path = "../informant" } +sp-panic-handler = { version = "2.0.0-alpha.5", path = "../../primitives/panic-handler" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } +sc-network = { version = "0.8.0-alpha.5", path = "../network" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../service" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } +substrate-prometheus-endpoint = { path = "../../utils/prometheus" , version = "0.8.0-alpha.5"} +sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } names = "0.11.0" structopt = "0.3.8" -sc-tracing = { version = "2.0.0-alpha.4", path = "../tracing" } +sc-tracing = { version = "2.0.0-alpha.5", path = "../tracing" } chrono = "0.4.10" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } diff --git a/client/consensus/aura/Cargo.toml b/client/consensus/aura/Cargo.toml index 3ba1eaab4f..ced8617375 100644 --- a/client/consensus/aura/Cargo.toml +++ b/client/consensus/aura/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-aura" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "Aura consensus algorithm for substrate" edition = "2018" @@ -9,37 +9,37 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../../primitives/application-crypto" } -sp-consensus-aura = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/aura" } -sp-block-builder = { version = "2.0.0-alpha.4", path = "../../../primitives/block-builder" } -sc-block-builder = { version = "0.8.0-alpha.4", path = "../../../client/block-builder" } -sc-client = { version = "0.8.0-alpha.4", path = "../../" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../../api" } +sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../../primitives/application-crypto" } +sp-consensus-aura = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/aura" } +sp-block-builder = { version = "2.0.0-alpha.5", path = "../../../primitives/block-builder" } +sc-block-builder = { version = "0.8.0-alpha.5", path = "../../../client/block-builder" } +sc-client = { version = "0.8.0-alpha.5", path = "../../" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } codec = { package = "parity-scale-codec", version = "1.2.0" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } derive_more = "0.99.2" futures = "0.3.1" futures-timer = "3.0.1" -sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } -sc-keystore = { version = "2.0.0-alpha.4", path = "../../keystore" } +sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } +sc-keystore = { version = "2.0.0-alpha.5", path = "../../keystore" } log = "0.4.8" parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } -sp-io = { version = "2.0.0-alpha.4", path = "../../../primitives/io" } -sp-version = { version = "2.0.0-alpha.4", path = "../../../primitives/version" } -sc-consensus-slots = { version = "0.8.0-alpha.4", path = "../slots" } -sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-timestamp = { version = "2.0.0-alpha.4", path = "../../../primitives/timestamp" } -sc-telemetry = { version = "2.0.0-alpha.4", path = "../../telemetry" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +sp-io = { version = "2.0.0-alpha.5", path = "../../../primitives/io" } +sp-version = { version = "2.0.0-alpha.5", path = "../../../primitives/version" } +sc-consensus-slots = { version = "0.8.0-alpha.5", path = "../slots" } +sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-timestamp = { version = "2.0.0-alpha.5", path = "../../../primitives/timestamp" } +sc-telemetry = { version = "2.0.0-alpha.5", path = "../../telemetry" } [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.4", path = "../../../primitives/keyring" } -sc-executor = { version = "0.8.0-alpha.4", path = "../../executor" } -sc-network = { version = "0.8.0-alpha.4", path = "../../network" } +sp-keyring = { version = "2.0.0-alpha.5", path = "../../../primitives/keyring" } +sc-executor = { version = "0.8.0-alpha.5", path = "../../executor" } +sc-network = { version = "0.8.0-alpha.5", path = "../../network" } sc-network-test = { version = "0.8.0-dev", path = "../../network/test" } -sc-service = { version = "0.8.0-alpha.4", path = "../../service" } +sc-service = { version = "0.8.0-alpha.5", path = "../../service" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } env_logger = "0.7.0" tempfile = "3.1.0" diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index ec5e3cbbb7..a0d73180ed 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-babe" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "BABE consensus algorithm for substrate" edition = "2018" @@ -11,31 +11,31 @@ documentation = "https://docs.rs/sc-consensus-babe" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } -sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/babe" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../../primitives/application-crypto" } +sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/babe" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../../primitives/application-crypto" } num-bigint = "0.2.3" num-rational = "0.2.2" num-traits = "0.2.8" serde = { version = "1.0.104", features = ["derive"] } -sp-version = { version = "2.0.0-alpha.4", path = "../../../primitives/version" } -sp-io = { version = "2.0.0-alpha.4", path = "../../../primitives/io" } -sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } -sp-timestamp = { version = "2.0.0-alpha.4", path = "../../../primitives/timestamp" } -sc-telemetry = { version = "2.0.0-alpha.4", path = "../../telemetry" } -sc-keystore = { version = "2.0.0-alpha.4", path = "../../keystore" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../../api" } -sc-client = { version = "0.8.0-alpha.4", path = "../../" } -sc-consensus-epochs = { version = "0.8.0-alpha.4", path = "../epochs" } -sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } -sp-block-builder = { version = "2.0.0-alpha.4", path = "../../../primitives/block-builder" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } -sp-consensus-vrf = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/vrf" } -sc-consensus-uncles = { version = "0.8.0-alpha.4", path = "../uncles" } -sc-consensus-slots = { version = "0.8.0-alpha.4", path = "../slots" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -fork-tree = { version = "2.0.0-alpha.4", path = "../../../utils/fork-tree" } +sp-version = { version = "2.0.0-alpha.5", path = "../../../primitives/version" } +sp-io = { version = "2.0.0-alpha.5", path = "../../../primitives/io" } +sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } +sp-timestamp = { version = "2.0.0-alpha.5", path = "../../../primitives/timestamp" } +sc-telemetry = { version = "2.0.0-alpha.5", path = "../../telemetry" } +sc-keystore = { version = "2.0.0-alpha.5", path = "../../keystore" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } +sc-client = { version = "0.8.0-alpha.5", path = "../../" } +sc-consensus-epochs = { version = "0.8.0-alpha.5", path = "../epochs" } +sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } +sp-block-builder = { version = "2.0.0-alpha.5", path = "../../../primitives/block-builder" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } +sp-consensus-vrf = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/vrf" } +sc-consensus-uncles = { version = "0.8.0-alpha.5", path = "../uncles" } +sc-consensus-slots = { version = "0.8.0-alpha.5", path = "../slots" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +fork-tree = { version = "2.0.0-alpha.5", path = "../../../utils/fork-tree" } futures = "0.3.1" futures-timer = "3.0.1" parking_lot = "0.10.0" @@ -47,13 +47,13 @@ pdqselect = "0.1.0" derive_more = "0.99.2" [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.4", path = "../../../primitives/keyring" } -sc-executor = { version = "0.8.0-alpha.4", path = "../../executor" } -sc-network = { version = "0.8.0-alpha.4", path = "../../network" } +sp-keyring = { version = "2.0.0-alpha.5", path = "../../../primitives/keyring" } +sc-executor = { version = "0.8.0-alpha.5", path = "../../executor" } +sc-network = { version = "0.8.0-alpha.5", path = "../../network" } sc-network-test = { version = "0.8.0-dev", path = "../../network/test" } -sc-service = { version = "0.8.0-alpha.4", path = "../../service" } +sc-service = { version = "0.8.0-alpha.5", path = "../../service" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sc-block-builder = { version = "0.8.0-alpha.4", path = "../../block-builder" } +sc-block-builder = { version = "0.8.0-alpha.5", path = "../../block-builder" } env_logger = "0.7.0" tempfile = "3.1.0" diff --git a/client/consensus/babe/rpc/Cargo.toml b/client/consensus/babe/rpc/Cargo.toml index e9e7f68890..1f820cd66b 100644 --- a/client/consensus/babe/rpc/Cargo.toml +++ b/client/consensus/babe/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-babe-rpc" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "RPC extensions for the BABE consensus algorithm" edition = "2018" @@ -9,24 +9,24 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sc-consensus-babe = { version = "0.8.0-alpha.4", path = "../" } +sc-consensus-babe = { version = "0.8.0-alpha.5", path = "../" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" -sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../../primitives/consensus/babe" } +sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../../primitives/consensus/babe" } serde = { version = "1.0.104", features=["derive"] } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../../primitives/runtime" } -sc-consensus-epochs = { version = "0.8.0-alpha.4", path = "../../epochs" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../../primitives/runtime" } +sc-consensus-epochs = { version = "0.8.0-alpha.5", path = "../../epochs" } futures = "0.3.1" derive_more = "0.99.2" -sp-api = { version = "2.0.0-alpha.4", path = "../../../../primitives/api" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../../primitives/consensus/common" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../../primitives/core" } -sc-keystore = { version = "2.0.0-alpha.4", path = "../../../keystore" } +sp-api = { version = "2.0.0-alpha.5", path = "../../../../primitives/api" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../../primitives/consensus/common" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../../primitives/core" } +sc-keystore = { version = "2.0.0-alpha.5", path = "../../../keystore" } [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../../test-utils/runtime/client" } -sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../../../primitives/application-crypto" } -sp-keyring = { version = "2.0.0-alpha.4", path = "../../../../primitives/keyring" } +sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../../../primitives/application-crypto" } +sp-keyring = { version = "2.0.0-alpha.5", path = "../../../../primitives/keyring" } tempfile = "3.1.0" diff --git a/client/consensus/epochs/Cargo.toml b/client/consensus/epochs/Cargo.toml index 28ae39a5a7..acc13bd575 100644 --- a/client/consensus/epochs/Cargo.toml +++ b/client/consensus/epochs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-epochs" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "Generic epochs-based utilities for consensus" edition = "2018" @@ -11,7 +11,7 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } parking_lot = "0.10.0" -fork-tree = { version = "2.0.0-alpha.4", path = "../../../utils/fork-tree" } -sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.4"} -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } -sc-client-api = { path = "../../api" , version = "2.0.0-alpha.4"} +fork-tree = { version = "2.0.0-alpha.5", path = "../../../utils/fork-tree" } +sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.5"} +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +sc-client-api = { path = "../../api" , version = "2.0.0-alpha.5"} diff --git a/client/consensus/manual-seal/Cargo.toml b/client/consensus/manual-seal/Cargo.toml index 4e412c2f02..edb98ab21a 100644 --- a/client/consensus/manual-seal/Cargo.toml +++ b/client/consensus/manual-seal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-manual-seal" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "Manual sealing engine for Substrate" edition = "2018" @@ -19,17 +19,17 @@ parking_lot = "0.10.0" serde = { version = "1.0", features=["derive"] } assert_matches = "1.3.0" -sc-client = { path = "../../../client" , version = "0.8.0-alpha.4"} -sc-client-api = { path = "../../../client/api" , version = "2.0.0-alpha.4"} -sc-transaction-pool = { path = "../../transaction-pool" , version = "2.0.0-alpha.4"} -sp-blockchain = { path = "../../../primitives/blockchain" , version = "2.0.0-alpha.4"} -sp-consensus = { package = "sp-consensus", path = "../../../primitives/consensus/common" , version = "0.8.0-alpha.4"} -sp-inherents = { path = "../../../primitives/inherents" , version = "2.0.0-alpha.4"} -sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.4"} -sp-transaction-pool = { path = "../../../primitives/transaction-pool" , version = "2.0.0-alpha.4"} +sc-client = { path = "../../../client" , version = "0.8.0-alpha.5"} +sc-client-api = { path = "../../../client/api" , version = "2.0.0-alpha.5"} +sc-transaction-pool = { path = "../../transaction-pool" , version = "2.0.0-alpha.5"} +sp-blockchain = { path = "../../../primitives/blockchain" , version = "2.0.0-alpha.5"} +sp-consensus = { package = "sp-consensus", path = "../../../primitives/consensus/common" , version = "0.8.0-alpha.5"} +sp-inherents = { path = "../../../primitives/inherents" , version = "2.0.0-alpha.5"} +sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.5"} +sp-transaction-pool = { path = "../../../primitives/transaction-pool" , version = "2.0.0-alpha.5"} [dev-dependencies] -sc-basic-authorship = { path = "../../basic-authorship" , version = "0.8.0-alpha.4"} +sc-basic-authorship = { path = "../../basic-authorship" , version = "0.8.0-alpha.5"} substrate-test-runtime-client = { path = "../../../test-utils/runtime/client" , version = "2.0.0-dev"} substrate-test-runtime-transaction-pool = { path = "../../../test-utils/runtime/transaction-pool" , version = "2.0.0-dev"} tokio = { version = "0.2", features = ["rt-core", "macros"] } diff --git a/client/consensus/pow/Cargo.toml b/client/consensus/pow/Cargo.toml index f782a67fef..a168c0b380 100644 --- a/client/consensus/pow/Cargo.toml +++ b/client/consensus/pow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-pow" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "PoW consensus algorithm for substrate" edition = "2018" @@ -10,16 +10,16 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../../api" } -sp-block-builder = { version = "2.0.0-alpha.4", path = "../../../primitives/block-builder" } -sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } -sp-consensus-pow = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/pow" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } +sp-block-builder = { version = "2.0.0-alpha.5", path = "../../../primitives/block-builder" } +sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } +sp-consensus-pow = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/pow" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } log = "0.4.8" futures = { version = "0.3.1", features = ["compat"] } -sp-timestamp = { version = "2.0.0-alpha.4", path = "../../../primitives/timestamp" } +sp-timestamp = { version = "2.0.0-alpha.5", path = "../../../primitives/timestamp" } derive_more = "0.99.2" diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index 91498be629..fd05cf7ca4 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-slots" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "Generic slots-based utilities for consensus" edition = "2018" @@ -11,15 +11,15 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../../api" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } -sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } -sc-telemetry = { version = "2.0.0-alpha.4", path = "../../telemetry" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } +sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } +sc-telemetry = { version = "2.0.0-alpha.5", path = "../../telemetry" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } futures = "0.3.1" futures-timer = "3.0.1" parking_lot = "0.10.0" diff --git a/client/consensus/uncles/Cargo.toml b/client/consensus/uncles/Cargo.toml index 745d885416..92d36f0bfd 100644 --- a/client/consensus/uncles/Cargo.toml +++ b/client/consensus/uncles/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-uncles" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "Generic uncle inclusion utilities for consensus" edition = "2018" @@ -9,10 +9,10 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sc-client-api = { version = "2.0.0-alpha.4", path = "../../api" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-authorship = { version = "2.0.0-alpha.4", path = "../../../primitives/authorship" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-alpha.4", path = "../../../primitives/inherents" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-authorship = { version = "2.0.0-alpha.5", path = "../../../primitives/authorship" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } log = "0.4.8" diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index 955f71d34e..b2ece9b7ff 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-client-db" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -20,20 +20,20 @@ hash-db = "0.15.2" parity-util-mem = { version = "0.6.0", default-features = false, features = ["std"] } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } -sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } -sc-client = { version = "0.8.0-alpha.4", path = "../" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } -sc-executor = { version = "0.8.0-alpha.4", path = "../executor" } -sc-state-db = { version = "0.8.0-alpha.4", path = "../state-db" } -sp-trie = { version = "2.0.0-alpha.4", path = "../../primitives/trie" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.4", path = "../../utils/prometheus" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sc-client = { version = "0.8.0-alpha.5", path = "../" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } +sc-executor = { version = "0.8.0-alpha.5", path = "../executor" } +sc-state-db = { version = "0.8.0-alpha.5", path = "../state-db" } +sp-trie = { version = "2.0.0-alpha.5", path = "../../primitives/trie" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.5", path = "../../utils/prometheus" } [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } env_logger = "0.7.0" quickcheck = "0.9" diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index be4730b2a2..4dca9fa6d5 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,21 +12,21 @@ documentation = "https://docs.rs/sc-executor" [dependencies] derive_more = "0.99.2" codec = { package = "parity-scale-codec", version = "1.2.0" } -sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-trie = { version = "2.0.0-alpha.4", path = "../../primitives/trie" } -sp-serializer = { version = "2.0.0-alpha.4", path = "../../primitives/serializer" } -sp-version = { version = "2.0.0-alpha.4", path = "../../primitives/version" } -sp-panic-handler = { version = "2.0.0-alpha.4", path = "../../primitives/panic-handler" } +sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-trie = { version = "2.0.0-alpha.5", path = "../../primitives/trie" } +sp-serializer = { version = "2.0.0-alpha.5", path = "../../primitives/serializer" } +sp-version = { version = "2.0.0-alpha.5", path = "../../primitives/version" } +sp-panic-handler = { version = "2.0.0-alpha.5", path = "../../primitives/panic-handler" } wasmi = "0.6.2" parity-wasm = "0.41.0" lazy_static = "1.4.0" -sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../primitives/runtime-interface" } -sp-externalities = { version = "0.8.0-alpha.4", path = "../../primitives/externalities" } -sc-executor-common = { version = "0.8.0-alpha.4", path = "common" } -sc-executor-wasmi = { version = "0.8.0-alpha.4", path = "wasmi" } -sc-executor-wasmtime = { version = "0.8.0-alpha.4", path = "wasmtime", optional = true } +sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../primitives/runtime-interface" } +sp-externalities = { version = "0.8.0-alpha.5", path = "../../primitives/externalities" } +sc-executor-common = { version = "0.8.0-alpha.5", path = "common" } +sc-executor-wasmi = { version = "0.8.0-alpha.5", path = "wasmi" } +sc-executor-wasmtime = { version = "0.8.0-alpha.5", path = "wasmtime", optional = true } parking_lot = "0.10.0" log = "0.4.8" libsecp256k1 = "0.3.4" @@ -37,9 +37,9 @@ wabt = "0.9.2" hex-literal = "0.2.1" sc-runtime-test = { version = "2.0.0-dev", path = "runtime-test" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } test-case = "0.3.3" -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } [features] default = [ "std" ] diff --git a/client/executor/common/Cargo.toml b/client/executor/common/Cargo.toml index c1a92a8ba4..14a1f8333b 100644 --- a/client/executor/common/Cargo.toml +++ b/client/executor/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor-common" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,11 +14,11 @@ log = "0.4.8" derive_more = "0.99.2" codec = { package = "parity-scale-codec", version = "1.2.0" } wasmi = "0.6.2" -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-alpha.4", path = "../../../primitives/allocator" } -sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime-interface" } -sp-serializer = { version = "2.0.0-alpha.4", path = "../../../primitives/serializer" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-alpha.5", path = "../../../primitives/allocator" } +sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime-interface" } +sp-serializer = { version = "2.0.0-alpha.5", path = "../../../primitives/serializer" } [features] default = [] diff --git a/client/executor/runtime-test/Cargo.toml b/client/executor/runtime-test/Cargo.toml index 25de14f223..7b75992234 100644 --- a/client/executor/runtime-test/Cargo.toml +++ b/client/executor/runtime-test/Cargo.toml @@ -10,12 +10,12 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/io" } -sp-sandbox = { version = "0.8.0-alpha.4", default-features = false, path = "../../../primitives/sandbox" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } -sp-allocator = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/allocator" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/io" } +sp-sandbox = { version = "0.8.0-alpha.5", default-features = false, path = "../../../primitives/sandbox" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } +sp-allocator = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/allocator" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } diff --git a/client/executor/wasmi/Cargo.toml b/client/executor/wasmi/Cargo.toml index 8655561d43..bae36353a2 100644 --- a/client/executor/wasmi/Cargo.toml +++ b/client/executor/wasmi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor-wasmi" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,8 +14,8 @@ log = "0.4.8" wasmi = "0.6.2" parity-wasm = "0.41.0" codec = { package = "parity-scale-codec", version = "1.2.0" } -sc-executor-common = { version = "0.8.0-alpha.4", path = "../common" } -sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime-interface" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-alpha.4", path = "../../../primitives/allocator" } +sc-executor-common = { version = "0.8.0-alpha.5", path = "../common" } +sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime-interface" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-alpha.5", path = "../../../primitives/allocator" } diff --git a/client/executor/wasmtime/Cargo.toml b/client/executor/wasmtime/Cargo.toml index 9181d76d5c..3b30e63fbb 100644 --- a/client/executor/wasmtime/Cargo.toml +++ b/client/executor/wasmtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor-wasmtime" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,11 +13,11 @@ log = "0.4.8" scoped-tls = "1.0" parity-wasm = "0.41.0" codec = { package = "parity-scale-codec", version = "1.2.0" } -sc-executor-common = { version = "0.8.0-alpha.4", path = "../common" } -sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime-interface" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-alpha.4", path = "../../../primitives/allocator" } +sc-executor-common = { version = "0.8.0-alpha.5", path = "../common" } +sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime-interface" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-alpha.5", path = "../../../primitives/allocator" } wasmtime = { package = "substrate-wasmtime", version = "0.13.0-threadsafe.1" } [dev-dependencies] diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index 15c65ce5df..a202f9d205 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-finality-grandpa" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,7 +11,7 @@ documentation = "https://docs.rs/sc-finality-grandpa" [dependencies] -fork-tree = { version = "2.0.0-alpha.4", path = "../../utils/fork-tree" } +fork-tree = { version = "2.0.0-alpha.5", path = "../../utils/fork-tree" } futures = "0.3.1" futures-timer = "3.0.1" log = "0.4.8" @@ -19,36 +19,36 @@ parking_lot = "0.10.0" rand = "0.7.2" assert_matches = "1.3.0" parity-scale-codec = { version = "1.2.0", features = ["derive"] } -sp-arithmetic = { version = "2.0.0-alpha.4", path = "../../primitives/arithmetic" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } -sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } -sc-keystore = { version = "2.0.0-alpha.4", path = "../keystore" } +sp-arithmetic = { version = "2.0.0-alpha.5", path = "../../primitives/arithmetic" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } +sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } +sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } serde_json = "1.0.41" -sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } -sc-client = { version = "0.8.0-alpha.4", path = "../" } -sp-inherents = { version = "2.0.0-alpha.4", path = "../../primitives/inherents" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } -sc-network = { version = "0.8.0-alpha.4", path = "../network" } -sc-network-gossip = { version = "0.8.0-alpha.4", path = "../network-gossip" } -sp-finality-tracker = { version = "2.0.0-alpha.4", path = "../../primitives/finality-tracker" } -sp-finality-grandpa = { version = "2.0.0-alpha.4", path = "../../primitives/finality-grandpa" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.4"} -sc-block-builder = { version = "0.8.0-alpha.4", path = "../block-builder" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } +sc-client = { version = "0.8.0-alpha.5", path = "../" } +sp-inherents = { version = "2.0.0-alpha.5", path = "../../primitives/inherents" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } +sc-network = { version = "0.8.0-alpha.5", path = "../network" } +sc-network-gossip = { version = "0.8.0-alpha.5", path = "../network-gossip" } +sp-finality-tracker = { version = "2.0.0-alpha.5", path = "../../primitives/finality-tracker" } +sp-finality-grandpa = { version = "2.0.0-alpha.5", path = "../../primitives/finality-grandpa" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.5"} +sc-block-builder = { version = "0.8.0-alpha.5", path = "../block-builder" } finality-grandpa = { version = "0.11.2", features = ["derive-codec"] } pin-project = "0.4.6" [dev-dependencies] finality-grandpa = { version = "0.11.2", features = ["derive-codec", "test-helpers"] } -sc-network = { version = "0.8.0-alpha.4", path = "../network" } +sc-network = { version = "0.8.0-alpha.5", path = "../network" } sc-network-test = { version = "0.8.0-dev", path = "../network/test" } -sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } -sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/babe" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } +sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/babe" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } env_logger = "0.7.0" tokio = { version = "0.2", features = ["rt-core"] } tempfile = "3.1.0" -sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } +sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } diff --git a/client/informant/Cargo.toml b/client/informant/Cargo.toml index 9a9610bf16..9f3a93fbae 100644 --- a/client/informant/Cargo.toml +++ b/client/informant/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-informant" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "Substrate informant." edition = "2018" @@ -14,8 +14,8 @@ futures = "0.3.1" log = "0.4.8" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } wasm-timer = "0.2" -sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } -sc-network = { version = "0.8.0-alpha.4", path = "../network" } -sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../service" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } +sc-network = { version = "0.8.0-alpha.5", path = "../network" } +sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../service" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } diff --git a/client/keystore/Cargo.toml b/client/keystore/Cargo.toml index aafcd87ded..5b709630ef 100644 --- a/client/keystore/Cargo.toml +++ b/client/keystore/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-keystore" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,8 +12,8 @@ documentation = "https://docs.rs/sc-keystore" [dependencies] derive_more = "0.99.2" -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../primitives/application-crypto" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../primitives/application-crypto" } hex = "0.4.0" rand = "0.7.2" serde_json = "1.0.41" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index 57e18124ae..c0418125a4 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Gossiping for the Substrate network protocol" name = "sc-network-gossip" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -16,8 +16,8 @@ futures-timer = "3.0.1" libp2p = { version = "0.16.2", default-features = false, features = ["libp2p-websocket"] } log = "0.4.8" lru = "0.4.3" -sc-network = { version = "0.8.0-alpha.4", path = "../network" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sc-network = { version = "0.8.0-alpha.5", path = "../network" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } wasm-timer = "0.2" [dev-dependencies] diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 6502ad3cb8..a5f71d87d5 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Substrate network protocol" name = "sc-network" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -21,7 +21,7 @@ derive_more = "0.99.2" either = "1.5.3" erased-serde = "0.3.9" fnv = "1.0.6" -fork-tree = { version = "2.0.0-alpha.4", path = "../../utils/fork-tree" } +fork-tree = { version = "2.0.0-alpha.5", path = "../../utils/fork-tree" } futures = "0.3.1" futures_codec = "0.3.3" futures-timer = "3.0.1" @@ -46,13 +46,13 @@ serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } slog_derive = "0.2.0" smallvec = "0.6.10" -sp-arithmetic = { version = "2.0.0-alpha.4", path = "../../primitives/arithmetic" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } -sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/babe" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.4", path = "../../utils/prometheus" } +sp-arithmetic = { version = "2.0.0-alpha.5", path = "../../primitives/arithmetic" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } +sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/babe" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.5", path = "../../utils/prometheus" } thiserror = "1" unsigned-varint = { version = "0.3.1", features = ["futures", "futures-codec"] } void = "1.0.2" @@ -64,7 +64,7 @@ assert_matches = "1.3" env_logger = "0.7.0" quickcheck = "0.9.0" rand = "0.7.2" -sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } sp-test-primitives = { version = "2.0.0-dev", path = "../../primitives/test-primitives" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index e1abc49ff4..e3d7852dd4 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -10,21 +10,21 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sc-network = { version = "0.8.0-alpha.4", path = "../" } +sc-network = { version = "0.8.0-alpha.5", path = "../" } log = "0.4.8" parking_lot = "0.10.0" futures = "0.3.1" futures-timer = "3.0.1" rand = "0.7.2" libp2p = { version = "0.16.2", default-features = false, features = ["libp2p-websocket"] } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } -sc-client = { version = "0.8.0-alpha.4", path = "../../" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../../api" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sc-block-builder = { version = "0.8.0-alpha.4", path = "../../block-builder" } -sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/babe" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } +sc-client = { version = "0.8.0-alpha.5", path = "../../" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sc-block-builder = { version = "0.8.0-alpha.5", path = "../../block-builder" } +sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/babe" } env_logger = "0.7.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../../test-utils/runtime" } diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index f736a85990..9dac18e946 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Substrate offchain workers" name = "sc-offchain" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -10,22 +10,22 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] bytes = "0.5" -sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } -sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } +sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } fnv = "1.0.6" futures = "0.3.1" futures-timer = "3.0.1" log = "0.4.8" threadpool = "1.7" num_cpus = "1.10" -sp-offchain = { version = "2.0.0-alpha.4", path = "../../primitives/offchain" } +sp-offchain = { version = "2.0.0-alpha.5", path = "../../primitives/offchain" } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } rand = "0.7.2" -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } -sc-network = { version = "0.8.0-alpha.4", path = "../network" } -sc-keystore = { version = "2.0.0-alpha.4", path = "../keystore" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sc-network = { version = "0.8.0-alpha.5", path = "../network" } +sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } [target.'cfg(not(target_os = "unknown"))'.dependencies] hyper = "0.13.2" @@ -34,9 +34,9 @@ hyper-rustls = "0.20" [dev-dependencies] env_logger = "0.7.0" fdlimit = "0.1.4" -sc-client-db = { version = "0.8.0-alpha.4", default-features = true, path = "../db/" } -sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../../client/transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } +sc-client-db = { version = "0.8.0-alpha.5", default-features = true, path = "../db/" } +sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } tokio = "0.2" diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 4095e79ed2..ea3a6b6974 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -3,7 +3,7 @@ description = "Connectivity manager based on reputation" homepage = "http://parity.io" license = "GPL-3.0" name = "sc-peerset" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" repository = "https://github.com/paritytech/substrate/" diff --git a/client/rpc-api/Cargo.toml b/client/rpc-api/Cargo.toml index a9a625f743..7d41c4f61c 100644 --- a/client/rpc-api/Cargo.toml +++ b/client/rpc-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-rpc-api" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -18,10 +18,10 @@ jsonrpc-derive = "14.0.3" jsonrpc-pubsub = "14.0.3" log = "0.4.8" parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-version = { version = "2.0.0-alpha.4", path = "../../primitives/version" } -sp-runtime = { path = "../../primitives/runtime" , version = "2.0.0-alpha.4"} +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-version = { version = "2.0.0-alpha.5", path = "../../primitives/version" } +sp-runtime = { path = "../../primitives/runtime" , version = "2.0.0-alpha.5"} serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } -sp-rpc = { version = "2.0.0-alpha.4", path = "../../primitives/rpc" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } +sp-rpc = { version = "2.0.0-alpha.5", path = "../../primitives/rpc" } diff --git a/client/rpc-servers/Cargo.toml b/client/rpc-servers/Cargo.toml index 117589fe39..5e0feb64c8 100644 --- a/client/rpc-servers/Cargo.toml +++ b/client/rpc-servers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-rpc-server" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,7 +14,7 @@ pubsub = { package = "jsonrpc-pubsub", version = "14.0.3" } log = "0.4.8" serde = "1.0.101" serde_json = "1.0.41" -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } [target.'cfg(not(target_os = "unknown"))'.dependencies] http = { package = "jsonrpc-http-server", version = "14.0.3" } diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index 7f329b47c1..cea58e31bf 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-rpc" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,28 +9,28 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate Client RPC" [dependencies] -sc-rpc-api = { version = "0.8.0-alpha.4", path = "../rpc-api" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } -sc-client = { version = "0.8.0-alpha.4", path = "../" } -sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } +sc-rpc-api = { version = "0.8.0-alpha.5", path = "../rpc-api" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } +sc-client = { version = "0.8.0-alpha.5", path = "../" } +sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.2.0" } futures = { version = "0.3.1", features = ["compat"] } jsonrpc-pubsub = "14.0.3" log = "0.4.8" -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } rpc = { package = "jsonrpc-core", version = "14.0.3" } -sp-version = { version = "2.0.0-alpha.4", path = "../../primitives/version" } +sp-version = { version = "2.0.0-alpha.5", path = "../../primitives/version" } serde_json = "1.0.41" -sp-session = { version = "2.0.0-alpha.4", path = "../../primitives/session" } -sp-offchain = { version = "2.0.0-alpha.4", path = "../../primitives/offchain" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } -sp-rpc = { version = "2.0.0-alpha.4", path = "../../primitives/rpc" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } -sc-executor = { version = "0.8.0-alpha.4", path = "../executor" } -sc-block-builder = { version = "0.8.0-alpha.4", path = "../../client/block-builder" } -sc-keystore = { version = "2.0.0-alpha.4", path = "../keystore" } -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } +sp-session = { version = "2.0.0-alpha.5", path = "../../primitives/session" } +sp-offchain = { version = "2.0.0-alpha.5", path = "../../primitives/offchain" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-rpc = { version = "2.0.0-alpha.5", path = "../../primitives/rpc" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } +sc-executor = { version = "0.8.0-alpha.5", path = "../executor" } +sc-block-builder = { version = "0.8.0-alpha.5", path = "../../client/block-builder" } +sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } hash-db = { version = "0.15.2", default-features = false } parking_lot = "0.10.0" @@ -41,4 +41,4 @@ sc-network = { version = "0.8.0-alpha.4", path = "../network" } sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } tokio = "0.1.22" -sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../transaction-pool" } +sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../transaction-pool" } diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index a75ac428ae..eb9e3dc2a6 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-service" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -33,36 +33,36 @@ serde = "1.0.101" serde_json = "1.0.41" sysinfo = "0.12.0" target_info = "0.1.0" -sc-keystore = { version = "2.0.0-alpha.4", path = "../keystore" } -sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-session = { version = "2.0.0-alpha.4", path = "../../primitives/session" } -sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../primitives/application-crypto" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } -sc-network = { version = "0.8.0-alpha.4", path = "../network" } -sc-chain-spec = { version = "2.0.0-alpha.4", path = "../chain-spec" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } -sc-client = { version = "0.8.0-alpha.4", path = "../" } -sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } -sc-client-db = { version = "0.8.0-alpha.4", path = "../db" } +sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } +sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-session = { version = "2.0.0-alpha.5", path = "../../primitives/session" } +sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../primitives/application-crypto" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } +sc-network = { version = "0.8.0-alpha.5", path = "../network" } +sc-chain-spec = { version = "2.0.0-alpha.5", path = "../chain-spec" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } +sc-client = { version = "0.8.0-alpha.5", path = "../" } +sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } +sc-client-db = { version = "0.8.0-alpha.5", path = "../db" } codec = { package = "parity-scale-codec", version = "1.2.0" } -sc-executor = { version = "0.8.0-alpha.4", path = "../executor" } -sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } -sc-rpc-server = { version = "2.0.0-alpha.4", path = "../rpc-servers" } -sc-rpc = { version = "2.0.0-alpha.4", path = "../rpc" } -sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } -sc-offchain = { version = "2.0.0-alpha.4", path = "../offchain" } +sc-executor = { version = "0.8.0-alpha.5", path = "../executor" } +sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../transaction-pool" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } +sc-rpc-server = { version = "2.0.0-alpha.5", path = "../rpc-servers" } +sc-rpc = { version = "2.0.0-alpha.5", path = "../rpc" } +sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } +sc-offchain = { version = "2.0.0-alpha.5", path = "../offchain" } parity-multiaddr = { package = "parity-multiaddr", version = "0.7.3" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" , version = "0.8.0-alpha.4"} -sc-tracing = { version = "2.0.0-alpha.4", path = "../tracing" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" , version = "0.8.0-alpha.5"} +sc-tracing = { version = "2.0.0-alpha.5", path = "../tracing" } tracing = "0.1.10" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } -sp-consensus-babe = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/babe" } -grandpa = { version = "0.8.0-alpha.4", package = "sc-finality-grandpa", path = "../finality-grandpa" } -grandpa-primitives = { version = "2.0.0-alpha.4", package = "sp-finality-grandpa", path = "../../primitives/finality-grandpa" } +sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/babe" } +grandpa = { version = "0.8.0-alpha.5", package = "sc-finality-grandpa", path = "../finality-grandpa" } +grandpa-primitives = { version = "2.0.0-alpha.5", package = "sp-finality-grandpa", path = "../../primitives/finality-grandpa" } diff --git a/client/service/test/Cargo.toml b/client/service/test/Cargo.toml index fc2ffeae59..401ef8ae04 100644 --- a/client/service/test/Cargo.toml +++ b/client/service/test/Cargo.toml @@ -16,10 +16,10 @@ log = "0.4.8" env_logger = "0.7.0" fdlimit = "0.1.4" futures = { version = "0.3.1", features = ["compat"] } -sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../../service" } -sc-network = { version = "0.8.0-alpha.4", path = "../../network" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } -sc-client = { version = "0.8.0-alpha.4", path = "../../" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../primitives/transaction-pool" } +sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../../service" } +sc-network = { version = "0.8.0-alpha.5", path = "../../network" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } +sc-client = { version = "0.8.0-alpha.5", path = "../../" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index 58ef699884..c056ee9fac 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-state-db" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,8 +11,8 @@ description = "State database maintenance. Handles canonicalization and pruning [dependencies] parking_lot = "0.10.0" log = "0.4.8" -sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } parity-util-mem = "0.6" parity-util-mem-derive = "0.1.0" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index e643f44d0c..543abd6a8b 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-telemetry" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] description = "Telemetry utils" edition = "2018" diff --git a/client/tracing/Cargo.toml b/client/tracing/Cargo.toml index b5e75fcb03..60a449c687 100644 --- a/client/tracing/Cargo.toml +++ b/client/tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-tracing" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -17,7 +17,7 @@ serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } tracing-core = "0.1.7" -sc-telemetry = { version = "2.0.0-alpha.4", path = "../telemetry" } +sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } [dev-dependencies] tracing = "0.1.10" diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 42dc9d9968..ca7130b2d6 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-transaction-pool" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,17 +16,17 @@ futures-diagnose = "1.0" log = "0.4.8" parking_lot = "0.10.0" wasm-timer = "0.2" -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } -sc-transaction-graph = { version = "2.0.0-alpha.4", path = "./graph" } -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../primitives/transaction-pool" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sc-transaction-graph = { version = "2.0.0-alpha.5", path = "./graph" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } futures-timer = "2.0" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } substrate-test-runtime-transaction-pool = { version = "2.0.0-dev", path = "../../test-utils/runtime/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index 4445df6234..08593e6784 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-transaction-graph" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,10 +15,10 @@ log = "0.4.8" parking_lot = "0.10.0" serde = { version = "1.0.101", features = ["derive"] } wasm-timer = "0.2" -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../primitives/transaction-pool" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } linked-hash-map = "0.5.2" diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 0570f6f15d..6ac0830934 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog]. ## Unreleased +## 2.0.0-alpha.4 -> 2.0.0-alpha.5 + +Runtime +------- + +* pallet-evm: configurable gasometer config (#5320) +* Adds new event phase `Initialization` (#5302) + ## 2.0.0-alpha.3 -> 2.0.0-alpha.4 Runtime diff --git a/frame/assets/Cargo.toml b/frame/assets/Cargo.toml index 9f82331062..8b6dac4e09 100644 --- a/frame/assets/Cargo.toml +++ b/frame/assets/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-assets" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,16 +12,16 @@ description = "FRAME asset management pallet" serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } # Needed for various traits. In our case, `OnFinalize`. -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } # Needed for type-safe access to storage DB. -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } # `system` module provides us with all sorts of useful stuff and macros depend on it being around. -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.4", path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.5", path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/aura/Cargo.toml b/frame/aura/Cargo.toml index 20438c006c..eb9c4556f5 100644 --- a/frame/aura/Cargo.toml +++ b/frame/aura/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-aura" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,20 +9,20 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME AURA consensus pallet" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -pallet-session = { version = "2.0.0-alpha.4", default-features = false, path = "../session" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -sp-consensus-aura = { path = "../../primitives/consensus/aura", default-features = false, version = "0.8.0-alpha.4"} -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/timestamp" } -pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../timestamp" } +pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../session" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +sp-consensus-aura = { path = "../../primitives/consensus/aura", default-features = false, version = "0.8.0-alpha.5"} +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/timestamp" } +pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../timestamp" } [dev-dependencies] diff --git a/frame/authority-discovery/Cargo.toml b/frame/authority-discovery/Cargo.toml index 9da18af6b3..64c6c22eeb 100644 --- a/frame/authority-discovery/Cargo.toml +++ b/frame/authority-discovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-authority-discovery" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,20 +9,20 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for authority discovery" [dependencies] -sp-authority-discovery = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/authority-discovery" } -sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/application-crypto" } +sp-authority-discovery = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/authority-discovery" } +sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -pallet-session = { version = "2.0.0-alpha.4", features = ["historical" ], path = "../session", default-features = false } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +pallet-session = { version = "2.0.0-alpha.5", features = ["historical" ], path = "../session", default-features = false } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] -sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } +sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } [features] default = ["std"] diff --git a/frame/authorship/Cargo.toml b/frame/authorship/Cargo.toml index 2ec4d9df70..105ae68d59 100644 --- a/frame/authorship/Cargo.toml +++ b/frame/authorship/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-authorship" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" description = "Block and Uncle Author tracking for the FRAME" authors = ["Parity Technologies "] edition = "2018" @@ -9,15 +9,15 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } -sp-authorship = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/authorship" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } +sp-authorship = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/authorship" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} impl-trait-for-tuples = "0.1.3" [features] diff --git a/frame/babe/Cargo.toml b/frame/babe/Cargo.toml index 4cf7c13cd6..e4acd52ed3 100644 --- a/frame/babe/Cargo.toml +++ b/frame/babe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-babe" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,24 +12,24 @@ description = "Consensus extension module for BABE consensus. Collects on-chain hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../timestamp" } -sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/timestamp" } -pallet-session = { version = "2.0.0-alpha.4", default-features = false, path = "../session" } -sp-consensus-babe = { version = "0.8.0-alpha.4", default-features = false, path = "../../primitives/consensus/babe" } -sp-consensus-vrf = { version = "0.8.0-alpha.4", default-features = false, path = "../../primitives/consensus/vrf" } -sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../timestamp" } +sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/timestamp" } +pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../session" } +sp-consensus-babe = { version = "0.8.0-alpha.5", default-features = false, path = "../../primitives/consensus/babe" } +sp-consensus-vrf = { version = "0.8.0-alpha.5", default-features = false, path = "../../primitives/consensus/vrf" } +sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} [dev-dependencies] lazy_static = "1.4.0" parking_lot = "0.10.0" -sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/version" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/version" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } [features] diff --git a/frame/balances/Cargo.toml b/frame/balances/Cargo.toml index f51942bbea..1151fffe67 100644 --- a/frame/balances/Cargo.toml +++ b/frame/balances/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-balances" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "FRAME pallet to manage balances" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -pallet-transaction-payment = { version = "2.0.0-alpha.4", path = "../transaction-payment" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../transaction-payment" } [features] default = ["std"] diff --git a/frame/benchmark/Cargo.toml b/frame/benchmark/Cargo.toml index 2501e6090a..ed7f313694 100644 --- a/frame/benchmark/Cargo.toml +++ b/frame/benchmark/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-benchmark" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,12 +11,12 @@ description = "Patterns to benchmark in a FRAME runtime." [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } [features] default = ["std"] diff --git a/frame/benchmarking/Cargo.toml b/frame/benchmarking/Cargo.toml index d12b415159..dcdb4f65fa 100644 --- a/frame/benchmarking/Cargo.toml +++ b/frame/benchmarking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-benchmarking" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,13 +11,13 @@ description = "Macro for benchmarking a FRAME runtime." [dependencies] linregress = "0.1" codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-api = { version = "2.0.0-alpha.4", path = "../../primitives/api", default-features = false } -sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../../primitives/runtime-interface", default-features = false } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime", default-features = false } -sp-std = { version = "2.0.0-alpha.4", path = "../../primitives/std", default-features = false } -sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.4"} -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api", default-features = false } +sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../primitives/runtime-interface", default-features = false } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime", default-features = false } +sp-std = { version = "2.0.0-alpha.5", path = "../../primitives/std", default-features = false } +sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.5"} +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [features] default = [ "std" ] diff --git a/frame/collective/Cargo.toml b/frame/collective/Cargo.toml index 5cc0ecb381..4b037ab7c2 100644 --- a/frame/collective/Cargo.toml +++ b/frame/collective/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-collective" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "Collective system: Members of a set of account IDs can make their [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } [features] default = ["std"] diff --git a/frame/contracts/Cargo.toml b/frame/contracts/Cargo.toml index e2b0f628cd..3689eaa9d1 100644 --- a/frame/contracts/Cargo.toml +++ b/frame/contracts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,22 +14,22 @@ pwasm-utils = { version = "0.12.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } parity-wasm = { version = "0.41.0", default-features = false } wasmi-validation = { version = "0.3.0", default-features = false } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-sandbox = { version = "0.8.0-alpha.4", default-features = false, path = "../../primitives/sandbox" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -pallet-contracts-primitives = { version = "2.0.0-alpha.4", default-features = false, path = "common" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-sandbox = { version = "0.8.0-alpha.5", default-features = false, path = "../../primitives/sandbox" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +pallet-contracts-primitives = { version = "2.0.0-alpha.5", default-features = false, path = "common" } [dev-dependencies] wabt = "0.9.2" assert_matches = "1.3.0" hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } -pallet-timestamp = { version = "2.0.0-alpha.4", path = "../timestamp" } -pallet-randomness-collective-flip = { version = "2.0.0-alpha.4", path = "../randomness-collective-flip" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +pallet-timestamp = { version = "2.0.0-alpha.5", path = "../timestamp" } +pallet-randomness-collective-flip = { version = "2.0.0-alpha.5", path = "../randomness-collective-flip" } [features] default = ["std"] diff --git a/frame/contracts/common/Cargo.toml b/frame/contracts/common/Cargo.toml index dcb1763a94..19fe69b879 100644 --- a/frame/contracts/common/Cargo.toml +++ b/frame/contracts/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts-primitives" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,8 +11,8 @@ description = "A crate that hosts a common definitions that are relevant for the [dependencies] # This crate should not rely on any of the frame primitives. codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } [features] default = ["std"] diff --git a/frame/contracts/rpc/Cargo.toml b/frame/contracts/rpc/Cargo.toml index d3338a7ad4..520dc4b7e5 100644 --- a/frame/contracts/rpc/Cargo.toml +++ b/frame/contracts/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts-rpc" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,14 +13,14 @@ codec = { package = "parity-scale-codec", version = "1.2.0" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-rpc = { version = "2.0.0-alpha.4", path = "../../../primitives/rpc" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-rpc = { version = "2.0.0-alpha.5", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } -pallet-contracts-primitives = { version = "2.0.0-alpha.4", path = "../common" } -pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.4", path = "./runtime-api" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } +pallet-contracts-primitives = { version = "2.0.0-alpha.5", path = "../common" } +pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.5", path = "./runtime-api" } [dev-dependencies] serde_json = "1.0.41" diff --git a/frame/contracts/rpc/runtime-api/Cargo.toml b/frame/contracts/rpc/runtime-api/Cargo.toml index 880c53c21a..e4211dee79 100644 --- a/frame/contracts/rpc/runtime-api/Cargo.toml +++ b/frame/contracts/rpc/runtime-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts-rpc-runtime-api" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,11 +9,11 @@ repository = "https://github.com/paritytech/substrate/" description = "Runtime API definition required by Contracts RPC extensions." [dependencies] -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/api" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/runtime" } -pallet-contracts-primitives = { version = "2.0.0-alpha.4", default-features = false, path = "../../common" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/runtime" } +pallet-contracts-primitives = { version = "2.0.0-alpha.5", default-features = false, path = "../../common" } [features] default = ["std"] diff --git a/frame/democracy/Cargo.toml b/frame/democracy/Cargo.toml index cd9a94ae04..f7dd0b7f0a 100644 --- a/frame/democracy/Cargo.toml +++ b/frame/democracy/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-democracy" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "FRAME pallet for democracy" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } -sp-storage = { version = "2.0.0-alpha.4", path = "../../primitives/storage" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +sp-storage = { version = "2.0.0-alpha.5", path = "../../primitives/storage" } hex-literal = "0.2.1" [features] diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index 1b372ba565..97b7dc1243 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-elections-phragmen" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,18 +10,18 @@ description = "FRAME election pallet for PHRAGMEN" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-phragmen = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/phragmen" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-phragmen = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/phragmen" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } +sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -substrate-test-utils = { version = "2.0.0-alpha.4", path = "../../test-utils" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +substrate-test-utils = { version = "2.0.0-alpha.5", path = "../../test-utils" } serde = { version = "1.0.101" } [features] diff --git a/frame/elections/Cargo.toml b/frame/elections/Cargo.toml index 40b05a6d1e..a5cf36614e 100644 --- a/frame/elections/Cargo.toml +++ b/frame/elections/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-elections" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "FRAME pallet for elections" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } [features] default = ["std"] diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml index 87b776c118..a2c9a247f1 100644 --- a/frame/evm/Cargo.toml +++ b/frame/evm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-evm" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,14 +11,14 @@ description = "FRAME EVM contracts pallet" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../timestamp" } -pallet-balances = { version = "2.0.0-alpha.4", default-features = false, path = "../balances" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../timestamp" } +pallet-balances = { version = "2.0.0-alpha.5", default-features = false, path = "../balances" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } primitive-types = { version = "0.7.0", default-features = false, features = ["rlp"] } rlp = { version = "0.4", default-features = false } evm = { version = "0.16", default-features = false } diff --git a/frame/example-offchain-worker/Cargo.toml b/frame/example-offchain-worker/Cargo.toml index a700c6fad7..425cdb05c1 100644 --- a/frame/example-offchain-worker/Cargo.toml +++ b/frame/example-offchain-worker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-example-offchain-worker" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "Unlicense" @@ -10,13 +10,13 @@ description = "FRAME example pallet for offchain worker" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } serde = { version = "1.0.101", optional = true } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } lite-json = { version = "0.1", default-features = false } [features] diff --git a/frame/example/Cargo.toml b/frame/example/Cargo.toml index 5db9aca45b..344ceab2f5 100644 --- a/frame/example/Cargo.toml +++ b/frame/example/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-example" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "Unlicense" @@ -11,16 +11,16 @@ description = "FRAME example pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -pallet-balances = { version = "2.0.0-alpha.4", default-features = false, path = "../balances" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +pallet-balances = { version = "2.0.0-alpha.5", default-features = false, path = "../balances" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core", default-features = false } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core", default-features = false } [features] default = ["std"] diff --git a/frame/executive/Cargo.toml b/frame/executive/Cargo.toml index 0921c0433b..3ecd9753b0 100644 --- a/frame/executive/Cargo.toml +++ b/frame/executive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-executive" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,20 +10,20 @@ description = "FRAME executives engine" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } serde = { version = "1.0.101", optional = true } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } [dev-dependencies] hex-literal = "0.2.1" -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-io ={ path = "../../primitives/io", version = "2.0.0-alpha.4"} -pallet-indices = { version = "2.0.0-alpha.4", path = "../indices" } -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } -pallet-transaction-payment = { version = "2.0.0-alpha.4", path = "../transaction-payment" } -sp-version = { version = "2.0.0-alpha.4", path = "../../primitives/version" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-io ={ path = "../../primitives/io", version = "2.0.0-alpha.5"} +pallet-indices = { version = "2.0.0-alpha.5", path = "../indices" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../transaction-payment" } +sp-version = { version = "2.0.0-alpha.5", path = "../../primitives/version" } [features] default = ["std"] diff --git a/frame/finality-tracker/Cargo.toml b/frame/finality-tracker/Cargo.toml index e7e109d8ef..3c2d560e1a 100644 --- a/frame/finality-tracker/Cargo.toml +++ b/frame/finality-tracker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-finality-tracker" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,17 +13,17 @@ documentation = "https://docs.rs/pallet-finality-tracker" [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-finality-tracker = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/finality-tracker" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-finality-tracker = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/finality-tracker" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/generic-asset/Cargo.toml b/frame/generic-asset/Cargo.toml index 6fc69a09a6..2195bc064b 100644 --- a/frame/generic-asset/Cargo.toml +++ b/frame/generic-asset/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-generic-asset" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Centrality Developers "] edition = "2018" license = "GPL-3.0" @@ -11,14 +11,14 @@ description = "FRAME pallet for generic asset management" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.4", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-alpha.5", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/grandpa/Cargo.toml b/frame/grandpa/Cargo.toml index cca1fee0a5..43aa5d0c68 100644 --- a/frame/grandpa/Cargo.toml +++ b/frame/grandpa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-grandpa" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,18 +11,18 @@ description = "FRAME pallet for GRANDPA finality gadget" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-finality-grandpa = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/finality-grandpa" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -pallet-session = { version = "2.0.0-alpha.4", default-features = false, path = "../session" } -pallet-finality-tracker = { version = "2.0.0-alpha.4", default-features = false, path = "../finality-tracker" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-finality-grandpa = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/finality-grandpa" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../session" } +pallet-finality-tracker = { version = "2.0.0-alpha.5", default-features = false, path = "../finality-tracker" } [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.4", path = "../../primitives/io" } +sp-io ={ version = "2.0.0-alpha.5", path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/identity/Cargo.toml b/frame/identity/Cargo.toml index 1371b2ce50..f13970e6b2 100644 --- a/frame/identity/Cargo.toml +++ b/frame/identity/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-identity" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,16 +12,16 @@ description = "FRAME identity management pallet" serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } [features] default = ["std"] diff --git a/frame/im-online/Cargo.toml b/frame/im-online/Cargo.toml index d8df22a0f5..5d5d40079e 100644 --- a/frame/im-online/Cargo.toml +++ b/frame/im-online/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-im-online" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,20 +9,20 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME's I'm online pallet" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/application-crypto" } -pallet-authorship = { version = "2.0.0-alpha.4", default-features = false, path = "../authorship" } +sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/application-crypto" } +pallet-authorship = { version = "2.0.0-alpha.5", default-features = false, path = "../authorship" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -pallet-session = { version = "2.0.0-alpha.4", default-features = false, path = "../session" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../session" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } [features] default = ["std", "pallet-session/historical"] diff --git a/frame/indices/Cargo.toml b/frame/indices/Cargo.toml index 6909988449..859461bfe7 100644 --- a/frame/indices/Cargo.toml +++ b/frame/indices/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-indices" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "FRAME indices management pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-keyring = { version = "2.0.0-alpha.4", optional = true, path = "../../primitives/keyring" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-keyring = { version = "2.0.0-alpha.5", optional = true, path = "../../primitives/keyring" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } [features] default = ["std"] diff --git a/frame/membership/Cargo.toml b/frame/membership/Cargo.toml index ca267ae800..9272d1c76b 100644 --- a/frame/membership/Cargo.toml +++ b/frame/membership/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-membership" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,14 +11,14 @@ description = "FRAME membership management pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/metadata/Cargo.toml b/frame/metadata/Cargo.toml index a01ec9bce5..1719d98f34 100644 --- a/frame/metadata/Cargo.toml +++ b/frame/metadata/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-metadata" -version = "11.0.0-alpha.4" +version = "11.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,8 +11,8 @@ description = "Decodable variant of the RuntimeMetadata." [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/nicks/Cargo.toml b/frame/nicks/Cargo.toml index 9c48a60863..5c21fde705 100644 --- a/frame/nicks/Cargo.toml +++ b/frame/nicks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-nicks" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,15 +11,15 @@ description = "FRAME pallet for nick management" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } [features] default = ["std"] diff --git a/frame/offences/Cargo.toml b/frame/offences/Cargo.toml index 2ab98265d8..31f7b1d8f4 100644 --- a/frame/offences/Cargo.toml +++ b/frame/offences/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-offences" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,18 +9,18 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME offences pallet" [dependencies] -pallet-balances = { version = "2.0.0-alpha.4", default-features = false, path = "../balances" } +pallet-balances = { version = "2.0.0-alpha.5", default-features = false, path = "../balances" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/randomness-collective-flip/Cargo.toml b/frame/randomness-collective-flip/Cargo.toml index 645809bd13..dd897cc71f 100644 --- a/frame/randomness-collective-flip/Cargo.toml +++ b/frame/randomness-collective-flip/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-randomness-collective-flip" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,14 +11,14 @@ description = "FRAME randomness collective flip pallet" [dependencies] safe-mix = { version = "1.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/recovery/Cargo.toml b/frame/recovery/Cargo.toml index e67cd3b340..35fc394880 100644 --- a/frame/recovery/Cargo.toml +++ b/frame/recovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-recovery" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,15 +12,15 @@ description = "FRAME account recovery pallet" serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } [features] default = ["std"] diff --git a/frame/scored-pool/Cargo.toml b/frame/scored-pool/Cargo.toml index f4f54c9498..a00b80be32 100644 --- a/frame/scored-pool/Cargo.toml +++ b/frame/scored-pool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-scored-pool" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,15 +11,15 @@ description = "FRAME pallet for scored pools" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/session/Cargo.toml b/frame/session/Cargo.toml index 3211399bd6..2e1e9e2433 100644 --- a/frame/session/Cargo.toml +++ b/frame/session/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-session" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,19 +11,19 @@ description = "FRAME sessions pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../timestamp" } -sp-trie = { optional = true, path = "../../primitives/trie", default-features = false, version = "2.0.0-alpha.4"} -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../timestamp" } +sp-trie = { optional = true, path = "../../primitives/trie", default-features = false, version = "2.0.0-alpha.5"} +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-application-crypto = { version = "2.0.0-alpha.4", path = "../../primitives/application-crypto" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../primitives/application-crypto" } lazy_static = "1.4.0" [features] diff --git a/frame/session/benchmarking/Cargo.toml b/frame/session/benchmarking/Cargo.toml index 91721f05d4..434a9e1ec5 100644 --- a/frame/session/benchmarking/Cargo.toml +++ b/frame/session/benchmarking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-session-benchmarking" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,12 +9,12 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME sessions pallet benchmarking" [dependencies] -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../../system" } -frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../../benchmarking" } -pallet-staking = { version = "2.0.0-alpha.4", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } -pallet-session = { version = "2.0.0-alpha.4", default-features = false, path = "../../session" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../../system" } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../../benchmarking" } +pallet-staking = { version = "2.0.0-alpha.5", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } +pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../../session" } [features] default = ["std"] diff --git a/frame/society/Cargo.toml b/frame/society/Cargo.toml index feeebfac2c..5130536ffd 100644 --- a/frame/society/Cargo.toml +++ b/frame/society/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-society" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "FRAME society pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } rand_chacha = { version = "0.2", default-features = false } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } [features] default = ["std"] diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index ca21317e5c..82409b9cb4 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-staking" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,27 +11,27 @@ description = "FRAME pallet staking" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-keyring = { version = "2.0.0-alpha.4", optional = true, path = "../../primitives/keyring" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-phragmen = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/phragmen" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -pallet-session = { version = "2.0.0-alpha.4", features = ["historical"], path = "../session", default-features = false } -pallet-authorship = { version = "2.0.0-alpha.4", default-features = false, path = "../authorship" } +sp-keyring = { version = "2.0.0-alpha.5", optional = true, path = "../../primitives/keyring" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-phragmen = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/phragmen" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-alpha.5", features = ["historical"], path = "../session", default-features = false } +pallet-authorship = { version = "2.0.0-alpha.5", default-features = false, path = "../authorship" } -frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } rand_chacha = { version = "0.2", default-features = false, optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } -pallet-timestamp = { version = "2.0.0-alpha.4", path = "../timestamp" } -pallet-staking-reward-curve = { version = "2.0.0-alpha.4", path = "../staking/reward-curve" } -substrate-test-utils = { version = "2.0.0-alpha.4", path = "../../test-utils" } -frame-benchmarking = { version = "2.0.0-alpha.4", path = "../benchmarking" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +pallet-timestamp = { version = "2.0.0-alpha.5", path = "../timestamp" } +pallet-staking-reward-curve = { version = "2.0.0-alpha.5", path = "../staking/reward-curve" } +substrate-test-utils = { version = "2.0.0-alpha.5", path = "../../test-utils" } +frame-benchmarking = { version = "2.0.0-alpha.5", path = "../benchmarking" } rand_chacha = { version = "0.2" } [features] diff --git a/frame/staking/reward-curve/Cargo.toml b/frame/staking/reward-curve/Cargo.toml index abdcf6426b..1f3fd436fa 100644 --- a/frame/staking/reward-curve/Cargo.toml +++ b/frame/staking/reward-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-staking-reward-curve" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -18,4 +18,4 @@ proc-macro2 = "1.0.6" proc-macro-crate = "0.1.4" [dev-dependencies] -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } diff --git a/frame/sudo/Cargo.toml b/frame/sudo/Cargo.toml index d15349b8f7..bb2bb09002 100644 --- a/frame/sudo/Cargo.toml +++ b/frame/sudo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-sudo" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,14 +11,14 @@ description = "FRAME pallet for sudo" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index ae906ef2c0..fc7fbb4835 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,24 +12,24 @@ description = "Support code for the runtime." log = "0.4" serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -frame-metadata = { version = "11.0.0-alpha.4", default-features = false, path = "../metadata" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-arithmetic = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/arithmetic" } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } -frame-support-procedural = { version = "2.0.0-alpha.4", path = "./procedural" } +frame-metadata = { version = "11.0.0-alpha.5", default-features = false, path = "../metadata" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-arithmetic = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/arithmetic" } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } +frame-support-procedural = { version = "2.0.0-alpha.5", path = "./procedural" } paste = "0.1.6" once_cell = { version = "1", default-features = false, optional = true } -sp-state-machine = { version = "0.8.0-alpha.4", optional = true, path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-alpha.5", optional = true, path = "../../primitives/state-machine" } bitmask = { version = "0.5.0", default-features = false } impl-trait-for-tuples = "0.1.3" tracing = { version = "0.1.10", optional = true } [dev-dependencies] pretty_assertions = "0.6.1" -frame-system = { version = "2.0.0-alpha.4", path = "../system" } +frame-system = { version = "2.0.0-alpha.5", path = "../system" } [features] default = ["std"] diff --git a/frame/support/procedural/Cargo.toml b/frame/support/procedural/Cargo.toml index 9ef0ea56d5..8befc50cd7 100644 --- a/frame/support/procedural/Cargo.toml +++ b/frame/support/procedural/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support-procedural" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,7 +12,7 @@ description = "Proc macro of Support code for the runtime." proc-macro = true [dependencies] -frame-support-procedural-tools = { version = "2.0.0-alpha.4", path = "./tools" } +frame-support-procedural-tools = { version = "2.0.0-alpha.5", path = "./tools" } proc-macro2 = "1.0.6" quote = "1.0.3" syn = { version = "1.0.7", features = ["full"] } diff --git a/frame/support/procedural/tools/Cargo.toml b/frame/support/procedural/tools/Cargo.toml index 4bd008c877..ab24e371d3 100644 --- a/frame/support/procedural/tools/Cargo.toml +++ b/frame/support/procedural/tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support-procedural-tools" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "Proc macro helpers for procedural macros" [dependencies] -frame-support-procedural-tools-derive = { version = "2.0.0-alpha.4", path = "./derive" } +frame-support-procedural-tools-derive = { version = "2.0.0-alpha.5", path = "./derive" } proc-macro2 = "1.0.6" quote = "1.0.3" syn = { version = "1.0.7", features = ["full", "visit"] } diff --git a/frame/support/procedural/tools/derive/Cargo.toml b/frame/support/procedural/tools/derive/Cargo.toml index 837c5b5b40..39ac99e4fd 100644 --- a/frame/support/procedural/tools/derive/Cargo.toml +++ b/frame/support/procedural/tools/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support-procedural-tools-derive" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index cd0375f066..0f7c89f5c0 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -11,12 +11,12 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-io ={ path = "../../../primitives/io", default-features = false , version = "2.0.0-alpha.4"} -sp-state-machine = { version = "0.8.0-alpha.4", optional = true, path = "../../../primitives/state-machine" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../" } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/inherents" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../../primitives/core" } +sp-io ={ path = "../../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} +sp-state-machine = { version = "0.8.0-alpha.5", optional = true, path = "../../../primitives/state-machine" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../" } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/inherents" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/core" } trybuild = "1.0.17" pretty_assertions = "0.6.1" diff --git a/frame/system/Cargo.toml b/frame/system/Cargo.toml index 369083f97a..92b7655566 100644 --- a/frame/system/Cargo.toml +++ b/frame/system/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-system" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,17 +11,17 @@ description = "FRAME system module" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.4"} -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/version" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.5"} +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/version" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] criterion = "0.2.11" -sp-externalities = { version = "0.8.0-alpha.4", path = "../../primitives/externalities" } +sp-externalities = { version = "0.8.0-alpha.5", path = "../../primitives/externalities" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } [features] diff --git a/frame/system/rpc/runtime-api/Cargo.toml b/frame/system/rpc/runtime-api/Cargo.toml index 861d72a748..6df4f0ea61 100644 --- a/frame/system/rpc/runtime-api/Cargo.toml +++ b/frame/system/rpc/runtime-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-system-rpc-runtime-api" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "Runtime API definition required by System RPC extensions." [dependencies] -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/api" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } [features] diff --git a/frame/timestamp/Cargo.toml b/frame/timestamp/Cargo.toml index 2c186a97ca..ed5e77cb5d 100644 --- a/frame/timestamp/Cargo.toml +++ b/frame/timestamp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-timestamp" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,19 +13,19 @@ documentation = "https://docs.rs/pallet-timestamp" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io", optional = true } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } -frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/timestamp" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io", optional = true } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/timestamp" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.4", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-alpha.5", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/transaction-payment/Cargo.toml b/frame/transaction-payment/Cargo.toml index 0b8d681d39..c9f952d0c4 100644 --- a/frame/transaction-payment/Cargo.toml +++ b/frame/transaction-payment/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-payment" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,16 +10,16 @@ description = "FRAME pallet to manage transaction payments" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.4", default-features = false, path = "./rpc/runtime-api" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.5", default-features = false, path = "./rpc/runtime-api" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } [features] default = ["std"] diff --git a/frame/transaction-payment/rpc/Cargo.toml b/frame/transaction-payment/rpc/Cargo.toml index 5b1fa9bb97..2e27e53009 100644 --- a/frame/transaction-payment/rpc/Cargo.toml +++ b/frame/transaction-payment/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-payment-rpc" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,10 +13,10 @@ codec = { package = "parity-scale-codec", version = "1.2.0" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sp-rpc = { version = "2.0.0-alpha.4", path = "../../../primitives/rpc" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-rpc = { version = "2.0.0-alpha.5", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.4", path = "./runtime-api" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.5", path = "./runtime-api" } diff --git a/frame/transaction-payment/rpc/runtime-api/Cargo.toml b/frame/transaction-payment/rpc/runtime-api/Cargo.toml index ca1258c5e9..02d1232037 100644 --- a/frame/transaction-payment/rpc/runtime-api/Cargo.toml +++ b/frame/transaction-payment/rpc/runtime-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-payment-rpc-runtime-api" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,11 +10,11 @@ description = "RPC runtime API for transaction payment FRAME pallet" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/api" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../../../support" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../../support" } [dev-dependencies] serde_json = "1.0.41" diff --git a/frame/treasury/Cargo.toml b/frame/treasury/Cargo.toml index 9c1589e322..a673c7ce81 100644 --- a/frame/treasury/Cargo.toml +++ b/frame/treasury/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-treasury" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,17 +11,17 @@ description = "FRAME pallet to manage treasury" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -pallet-balances = { version = "2.0.0-alpha.4", default-features = false, path = "../balances" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +pallet-balances = { version = "2.0.0-alpha.5", default-features = false, path = "../balances" } frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.4", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-alpha.5", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/utility/Cargo.toml b/frame/utility/Cargo.toml index d77e5fcd69..690465b5d2 100644 --- a/frame/utility/Cargo.toml +++ b/frame/utility/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-utility" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ description = "FRAME utilities pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } [features] default = ["std"] diff --git a/frame/vesting/Cargo.toml b/frame/vesting/Cargo.toml index 1563813361..c8d46855c5 100644 --- a/frame/vesting/Cargo.toml +++ b/frame/vesting/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-vesting" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,17 +12,17 @@ description = "FRAME pallet for manage vesting" serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.4", path = "../balances" } -sp-storage = { version = "2.0.0-alpha.4", path = "../../primitives/storage" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +sp-storage = { version = "2.0.0-alpha.5", path = "../../primitives/storage" } hex-literal = "0.2.1" [features] diff --git a/primitives/allocator/Cargo.toml b/primitives/allocator/Cargo.toml index 358d74b79e..eee82771d6 100644 --- a/primitives/allocator/Cargo.toml +++ b/primitives/allocator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-allocator" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,9 +10,9 @@ description = "Collection of allocator implementations." documentation = "https://docs.rs/sp-allocator" [dependencies] -sp-std = { version = "2.0.0-alpha.4", path = "../std", default-features = false } -sp-core = { version = "2.0.0-alpha.4", path = "../core", default-features = false } -sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../wasm-interface", default-features = false } +sp-std = { version = "2.0.0-alpha.5", path = "../std", default-features = false } +sp-core = { version = "2.0.0-alpha.5", path = "../core", default-features = false } +sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../wasm-interface", default-features = false } log = { version = "0.4.8", optional = true } derive_more = { version = "0.99.2", optional = true } diff --git a/primitives/api/Cargo.toml b/primitives/api/Cargo.toml index 94f8545e6d..3e33295afe 100644 --- a/primitives/api/Cargo.toml +++ b/primitives/api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-api" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,12 +10,12 @@ description = "Substrate runtime api primitives" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-api-proc-macro = { version = "2.0.0-alpha.4", path = "proc-macro" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } -sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../version" } -sp-state-machine = { version = "0.8.0-alpha.4", optional = true, path = "../../primitives/state-machine" } +sp-api-proc-macro = { version = "2.0.0-alpha.5", path = "proc-macro" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } +sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../version" } +sp-state-machine = { version = "0.8.0-alpha.5", optional = true, path = "../../primitives/state-machine" } hash-db = { version = "0.15.2", optional = true } [dev-dependencies] diff --git a/primitives/api/proc-macro/Cargo.toml b/primitives/api/proc-macro/Cargo.toml index 88819c047d..841da78832 100644 --- a/primitives/api/proc-macro/Cargo.toml +++ b/primitives/api/proc-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-api-proc-macro" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/api/test/Cargo.toml b/primitives/api/test/Cargo.toml index 53405a8a5f..54d66470cf 100644 --- a/primitives/api/test/Cargo.toml +++ b/primitives/api/test/Cargo.toml @@ -9,22 +9,22 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-api = { version = "2.0.0-alpha.4", path = "../" } +sp-api = { version = "2.0.0-alpha.5", path = "../" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-version = { version = "2.0.0-alpha.4", path = "../../version" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../runtime" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../blockchain" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../../primitives/consensus/common" } -sc-block-builder = { version = "0.8.0-alpha.4", path = "../../../client/block-builder" } +sp-version = { version = "2.0.0-alpha.5", path = "../../version" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../blockchain" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } +sc-block-builder = { version = "0.8.0-alpha.5", path = "../../../client/block-builder" } codec = { package = "parity-scale-codec", version = "1.2.0" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } trybuild = "1.0.17" rustversion = "1.0.0" [dev-dependencies] criterion = "0.3.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-core = { version = "2.0.0-alpha.4", path = "../../core" } +sp-core = { version = "2.0.0-alpha.5", path = "../../core" } [[bench]] name = "bench" diff --git a/primitives/application-crypto/Cargo.toml b/primitives/application-crypto/Cargo.toml index d6ab604e46..c65584c2fb 100644 --- a/primitives/application-crypto/Cargo.toml +++ b/primitives/application-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-application-crypto" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" description = "Provides facilities for generating application specific crypto wrapper types." @@ -11,11 +11,11 @@ documentation = "https://docs.rs/sp-application-crypto" [dependencies] -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } [features] default = [ "std" ] diff --git a/primitives/application-crypto/test/Cargo.toml b/primitives/application-crypto/test/Cargo.toml index f1231a0561..fae91e6783 100644 --- a/primitives/application-crypto/test/Cargo.toml +++ b/primitives/application-crypto/test/Cargo.toml @@ -10,8 +10,8 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../core" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../core" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../runtime" } -sp-api = { version = "2.0.0-alpha.4", path = "../../api" } -sp-application-crypto = { version = "2.0.0-alpha.4", path = "../" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } +sp-api = { version = "2.0.0-alpha.5", path = "../../api" } +sp-application-crypto = { version = "2.0.0-alpha.5", path = "../" } diff --git a/primitives/arithmetic/Cargo.toml b/primitives/arithmetic/Cargo.toml index 96402567cd..f41cac4fb5 100644 --- a/primitives/arithmetic/Cargo.toml +++ b/primitives/arithmetic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-arithmetic" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,9 +14,9 @@ documentation = "https://docs.rs/sp-arithmetic" codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } integer-sqrt = "0.1.2" num-traits = { version = "0.2.8", default-features = false } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-debug-derive = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/debug-derive" } +sp-debug-derive = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/debug-derive" } [dev-dependencies] primitive-types = "0.7.0" diff --git a/primitives/authority-discovery/Cargo.toml b/primitives/authority-discovery/Cargo.toml index 332d1cf938..3f40bb1b75 100644 --- a/primitives/authority-discovery/Cargo.toml +++ b/primitives/authority-discovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-authority-discovery" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] description = "Authority discovery primitives" edition = "2018" @@ -9,11 +9,11 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../application-crypto" } codec = { package = "parity-scale-codec", default-features = false, version = "1.2.0" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/authorship/Cargo.toml b/primitives/authorship/Cargo.toml index 1da224be76..a69ce303bc 100644 --- a/primitives/authorship/Cargo.toml +++ b/primitives/authorship/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-authorship" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] description = "Authorship primitives" edition = "2018" @@ -9,9 +9,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../inherents" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../inherents" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } [features] diff --git a/primitives/block-builder/Cargo.toml b/primitives/block-builder/Cargo.toml index f14b9691e4..13c8062ade 100644 --- a/primitives/block-builder/Cargo.toml +++ b/primitives/block-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-block-builder" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,11 +9,11 @@ repository = "https://github.com/paritytech/substrate/" description = "The block builder runtime api." [dependencies] -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../inherents" } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../inherents" } [features] default = [ "std" ] diff --git a/primitives/blockchain/Cargo.toml b/primitives/blockchain/Cargo.toml index 1425caa364..097f9048e5 100644 --- a/primitives/blockchain/Cargo.toml +++ b/primitives/blockchain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-blockchain" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,7 +16,7 @@ lru = "0.4.0" parking_lot = "0.10.0" derive_more = "0.99.2" codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.4", path = "../consensus/common" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } -sp-block-builder = { version = "2.0.0-alpha.4", path = "../block-builder" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../state-machine" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../consensus/common" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } +sp-block-builder = { version = "2.0.0-alpha.5", path = "../block-builder" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../state-machine" } diff --git a/primitives/consensus/aura/Cargo.toml b/primitives/consensus/aura/Cargo.toml index 7ffdc96fa0..af25bfaba5 100644 --- a/primitives/consensus/aura/Cargo.toml +++ b/primitives/consensus/aura/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-aura" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" @@ -9,13 +9,13 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../std" } -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../api" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../runtime" } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../inherents" } -sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../timestamp" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../std" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../api" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../runtime" } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../inherents" } +sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../timestamp" } [features] default = ["std"] diff --git a/primitives/consensus/babe/Cargo.toml b/primitives/consensus/babe/Cargo.toml index f7581601e5..d036040643 100644 --- a/primitives/consensus/babe/Cargo.toml +++ b/primitives/consensus/babe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-babe" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "Primitives for BABE consensus" edition = "2018" @@ -9,15 +9,15 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../std" } -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../api" } -sp-consensus = { version = "0.8.0-alpha.4", optional = true, path = "../common" } -sp-consensus-vrf = { version = "0.8.0-alpha.4", path = "../vrf", default-features = false } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../inherents" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../runtime" } -sp-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../timestamp" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../std" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../api" } +sp-consensus = { version = "0.8.0-alpha.5", optional = true, path = "../common" } +sp-consensus-vrf = { version = "0.8.0-alpha.5", path = "../vrf", default-features = false } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../inherents" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../runtime" } +sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../timestamp" } [features] default = ["std"] diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index a34e16af1e..db66fd0d57 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,15 +14,15 @@ documentation = "https://docs.rs/sp-consensus/" derive_more = "0.99.2" libp2p = { version = "0.16.2", default-features = false } log = "0.4.8" -sp-core = { path= "../../core" , version = "2.0.0-alpha.4"} -sp-inherents = { version = "2.0.0-alpha.4", path = "../../inherents" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } +sp-core = { path= "../../core" , version = "2.0.0-alpha.5"} +sp-inherents = { version = "2.0.0-alpha.5", path = "../../inherents" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } futures = { version = "0.3.1", features = ["thread-pool"] } futures-timer = "3.0.1" futures-diagnose = "1.0" -sp-std = { version = "2.0.0-alpha.4", path = "../../std" } -sp-version = { version = "2.0.0-alpha.4", path = "../../version" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../runtime" } +sp-std = { version = "2.0.0-alpha.5", path = "../../std" } +sp-version = { version = "2.0.0-alpha.5", path = "../../version" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } parking_lot = "0.10.0" serde = { version = "1.0", features = ["derive"] } diff --git a/primitives/consensus/pow/Cargo.toml b/primitives/consensus/pow/Cargo.toml index fb8b774854..38be986d1d 100644 --- a/primitives/consensus/pow/Cargo.toml +++ b/primitives/consensus/pow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-pow" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" @@ -9,10 +9,10 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../api" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../runtime" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../core" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../api" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../runtime" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../core" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } [features] diff --git a/primitives/consensus/vrf/Cargo.toml b/primitives/consensus/vrf/Cargo.toml index dc2631d270..8fedd3f0e1 100644 --- a/primitives/consensus/vrf/Cargo.toml +++ b/primitives/consensus/vrf/Cargo.toml @@ -1,17 +1,19 @@ [package] name = "sp-consensus-vrf" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "Primitives for VRF based consensus" edition = "2018" license = "GPL-3.0" +repository = "https://github.com/paritytech/substrate/" +homepage = "https://substrate.dev" [dependencies] codec = { version = "1.0.0", package = "parity-scale-codec", default-features = false } schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated"], optional = true } -sp-std = { version = "2.0.0-alpha.4", path = "../../std", default-features = false } -sp-core = { version = "2.0.0-alpha.4", path = "../../core", default-features = false } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../runtime" } +sp-std = { version = "2.0.0-alpha.5", path = "../../std", default-features = false } +sp-core = { version = "2.0.0-alpha.5", path = "../../core", default-features = false } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../runtime" } [features] default = ["std"] diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index a22ad18d73..5def0e8b3f 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-core" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,7 +10,7 @@ description = "Shareable Substrate types." documentation = "https://docs.rs/sp-core" [dependencies] -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } log = { version = "0.4.8", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } @@ -29,9 +29,9 @@ num-traits = { version = "0.2.8", default-features = false } zeroize = { version = "1.0.0", default-features = false } lazy_static = { version = "1.4.0", default-features = false, optional = true } parking_lot = { version = "0.10.0", optional = true } -sp-debug-derive = { version = "2.0.0-alpha.4", path = "../debug-derive" } -sp-externalities = { version = "0.8.0-alpha.4", optional = true, path = "../externalities" } -sp-storage = { version = "2.0.0-alpha.4", default-features = false, path = "../storage" } +sp-debug-derive = { version = "2.0.0-alpha.5", path = "../debug-derive" } +sp-externalities = { version = "0.8.0-alpha.5", optional = true, path = "../externalities" } +sp-storage = { version = "2.0.0-alpha.5", default-features = false, path = "../storage" } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } futures = { version = "0.3.1", optional = true } @@ -45,10 +45,10 @@ hex = { version = "0.4", default-features = false, optional = true } twox-hash = { version = "1.5.0", default-features = false, optional = true } libsecp256k1 = { version = "0.3.2", default-features = false, features = ["hmac"], optional = true } -sp-runtime-interface = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime-interface" } +sp-runtime-interface = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime-interface" } [dev-dependencies] -sp-serializer = { version = "2.0.0-alpha.4", path = "../serializer" } +sp-serializer = { version = "2.0.0-alpha.5", path = "../serializer" } pretty_assertions = "0.6.1" hex-literal = "0.2.1" rand = "0.7.2" diff --git a/primitives/debug-derive/Cargo.toml b/primitives/debug-derive/Cargo.toml index 5b1dc12722..83db220461 100644 --- a/primitives/debug-derive/Cargo.toml +++ b/primitives/debug-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-debug-derive" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/externalities/Cargo.toml b/primitives/externalities/Cargo.toml index 18ccf50e30..3eed98bd6e 100644 --- a/primitives/externalities/Cargo.toml +++ b/primitives/externalities/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-externalities" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -10,6 +10,6 @@ description = "Substrate externalities abstraction" documentation = "https://docs.rs/sp-externalities" [dependencies] -sp-storage = { version = "2.0.0-alpha.4", path = "../storage" } -sp-std = { version = "2.0.0-alpha.4", path = "../std" } +sp-storage = { version = "2.0.0-alpha.5", path = "../storage" } +sp-std = { version = "2.0.0-alpha.5", path = "../std" } environmental = { version = "1.1.1" } diff --git a/primitives/finality-grandpa/Cargo.toml b/primitives/finality-grandpa/Cargo.toml index d615d5bb50..94bcd2bce4 100644 --- a/primitives/finality-grandpa/Cargo.toml +++ b/primitives/finality-grandpa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-finality-grandpa" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,12 +11,12 @@ documentation = "https://docs.rs/sp-finality-grandpa" [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/finality-tracker/Cargo.toml b/primitives/finality-tracker/Cargo.toml index 5a7c15c896..e6cf53495a 100644 --- a/primitives/finality-tracker/Cargo.toml +++ b/primitives/finality-tracker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-finality-tracker" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,8 +10,8 @@ description = "FRAME module that tracks the last finalized block, as perceived b [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } [features] default = ["std"] diff --git a/primitives/inherents/Cargo.toml b/primitives/inherents/Cargo.toml index 948d1b609f..8cc9cb4dd0 100644 --- a/primitives/inherents/Cargo.toml +++ b/primitives/inherents/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-inherents" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,8 +12,8 @@ documentation = "https://docs.rs/sp-inherents" [dependencies] parking_lot = { version = "0.10.0", optional = true } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } derive_more = { version = "0.99.2", optional = true } diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index 2b445be657..7531df7e81 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-io" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,14 +13,14 @@ documentation = "https://docs.rs/sp-io" [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } hash-db = { version = "0.15.2", default-features = false } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } libsecp256k1 = { version = "0.3.4", optional = true } -sp-state-machine = { version = "0.8.0-alpha.4", optional = true, path = "../../primitives/state-machine" } -sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../../primitives/wasm-interface", default-features = false } -sp-runtime-interface = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime-interface" } -sp-trie = { version = "2.0.0-alpha.4", optional = true, path = "../../primitives/trie" } -sp-externalities = { version = "0.8.0-alpha.4", optional = true, path = "../externalities" } +sp-state-machine = { version = "0.8.0-alpha.5", optional = true, path = "../../primitives/state-machine" } +sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../primitives/wasm-interface", default-features = false } +sp-runtime-interface = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime-interface" } +sp-trie = { version = "2.0.0-alpha.5", optional = true, path = "../../primitives/trie" } +sp-externalities = { version = "0.8.0-alpha.5", optional = true, path = "../externalities" } log = { version = "0.4.8", optional = true } [features] diff --git a/primitives/keyring/Cargo.toml b/primitives/keyring/Cargo.toml index 030258aad2..29c0a35a54 100644 --- a/primitives/keyring/Cargo.toml +++ b/primitives/keyring/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-keyring" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,7 +11,7 @@ documentation = "https://docs.rs/sp-keyring" [dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../core" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } +sp-core = { version = "2.0.0-alpha.5", path = "../core" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } lazy_static = "1.4.0" strum = { version = "0.16.0", features = ["derive"] } diff --git a/primitives/offchain/Cargo.toml b/primitives/offchain/Cargo.toml index 22205613a3..a92f7e20c4 100644 --- a/primitives/offchain/Cargo.toml +++ b/primitives/offchain/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Substrate offchain workers primitives" name = "sp-offchain" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -9,8 +9,8 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/panic-handler/Cargo.toml b/primitives/panic-handler/Cargo.toml index 78697a991e..e16cc5dc76 100644 --- a/primitives/panic-handler/Cargo.toml +++ b/primitives/panic-handler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-panic-handler" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/phragmen/Cargo.toml b/primitives/phragmen/Cargo.toml index 53429480bb..2290b44c5f 100644 --- a/primitives/phragmen/Cargo.toml +++ b/primitives/phragmen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-phragmen" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,12 +10,12 @@ description = "PHRAGMENT primitives" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } [dev-dependencies] -substrate-test-utils = { version = "2.0.0-alpha.4", path = "../../test-utils" } -sp-io ={ version = "2.0.0-alpha.4", path = "../../primitives/io" } +substrate-test-utils = { version = "2.0.0-alpha.5", path = "../../test-utils" } +sp-io ={ version = "2.0.0-alpha.5", path = "../../primitives/io" } rand = "0.7.2" [features] diff --git a/primitives/rpc/Cargo.toml b/primitives/rpc/Cargo.toml index 5c151a4fe4..5631f7a891 100644 --- a/primitives/rpc/Cargo.toml +++ b/primitives/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-rpc" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,7 +10,7 @@ description = "Substrate RPC primitives and utilities." [dependencies] serde = { version = "1.0.101", features = ["derive"] } -sp-core = { version = "2.0.0-alpha.4", path = "../core" } +sp-core = { version = "2.0.0-alpha.5", path = "../core" } [dev-dependencies] serde_json = "1.0.41" diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 880306380e..68da7f1bf8 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-runtime-interface" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,19 +10,19 @@ description = "Substrate runtime interface" documentation = "https://docs.rs/sp-runtime-interface/" [dependencies] -sp-wasm-interface = { version = "2.0.0-alpha.4", path = "../wasm-interface", default-features = false } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } -sp-runtime-interface-proc-macro = { version = "2.0.0-alpha.4", path = "proc-macro" } -sp-externalities = { version = "0.8.0-alpha.4", optional = true, path = "../externalities" } +sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../wasm-interface", default-features = false } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-runtime-interface-proc-macro = { version = "2.0.0-alpha.5", path = "proc-macro" } +sp-externalities = { version = "0.8.0-alpha.5", optional = true, path = "../externalities" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } static_assertions = "1.0.0" primitive-types = { version = "0.7.0", default-features = false } [dev-dependencies] sp-runtime-interface-test-wasm = { version = "2.0.0-dev", path = "test-wasm" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } -sp-core = { version = "2.0.0-alpha.4", path = "../core" } -sp-io = { version = "2.0.0-alpha.4", path = "../io" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } +sp-core = { version = "2.0.0-alpha.5", path = "../core" } +sp-io = { version = "2.0.0-alpha.5", path = "../io" } rustversion = "1.0.0" trybuild = "1.0.23" diff --git a/primitives/runtime-interface/proc-macro/Cargo.toml b/primitives/runtime-interface/proc-macro/Cargo.toml index 3d6585bf11..c8c12b9bdb 100644 --- a/primitives/runtime-interface/proc-macro/Cargo.toml +++ b/primitives/runtime-interface/proc-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-runtime-interface-proc-macro" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/runtime-interface/test-wasm/Cargo.toml b/primitives/runtime-interface/test-wasm/Cargo.toml index 65c9cc9765..cf72a10749 100644 --- a/primitives/runtime-interface/test-wasm/Cargo.toml +++ b/primitives/runtime-interface/test-wasm/Cargo.toml @@ -10,10 +10,10 @@ repository = "https://github.com/paritytech/substrate/" publish = false [dependencies] -sp-runtime-interface = { version = "2.0.0-alpha.4", default-features = false, path = "../" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../io" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../core" } +sp-runtime-interface = { version = "2.0.0-alpha.5", default-features = false, path = "../" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../io" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../core" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } diff --git a/primitives/runtime-interface/test/Cargo.toml b/primitives/runtime-interface/test/Cargo.toml index 53bdcd18bb..18cff357d8 100644 --- a/primitives/runtime-interface/test/Cargo.toml +++ b/primitives/runtime-interface/test/Cargo.toml @@ -9,10 +9,10 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -sp-runtime-interface = { version = "2.0.0-alpha.4", path = "../" } -sc-executor = { version = "0.8.0-alpha.4", path = "../../../client/executor" } +sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../" } +sc-executor = { version = "0.8.0-alpha.5", path = "../../../client/executor" } sp-runtime-interface-test-wasm = { version = "2.0.0-dev", path = "../test-wasm" } sp-runtime-interface-test-wasm-deprecated = { version = "2.0.0-dev", path = "../test-wasm-deprecated" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../runtime" } -sp-io = { version = "2.0.0-alpha.4", path = "../../io" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } +sp-io = { version = "2.0.0-alpha.5", path = "../../io" } diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index 09a031b39d..743748fc10 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-runtime" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,16 +13,16 @@ documentation = "https://docs.rs/sp-runtime" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } -sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../application-crypto" } -sp-arithmetic = { version = "2.0.0-alpha.4", default-features = false, path = "../arithmetic" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../io" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } +sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../application-crypto" } +sp-arithmetic = { version = "2.0.0-alpha.5", default-features = false, path = "../arithmetic" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../io" } log = { version = "0.4.8", optional = true } paste = "0.1.6" rand = { version = "0.7.2", optional = true } impl-trait-for-tuples = "0.1.3" -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../inherents" } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../inherents" } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } hash256-std-hasher = { version = "0.15.2", default-features = false } diff --git a/primitives/sandbox/Cargo.toml b/primitives/sandbox/Cargo.toml index fb01e32acd..3b9408dc8e 100755 --- a/primitives/sandbox/Cargo.toml +++ b/primitives/sandbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-sandbox" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,10 +10,10 @@ description = "This crate provides means to instantiate and execute wasm modules [dependencies] wasmi = { version = "0.6.2", optional = true } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../io" } -sp-wasm-interface = { version = "2.0.0-alpha.4", default-features = false, path = "../wasm-interface" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../io" } +sp-wasm-interface = { version = "2.0.0-alpha.5", default-features = false, path = "../wasm-interface" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } [dev-dependencies] diff --git a/primitives/serializer/Cargo.toml b/primitives/serializer/Cargo.toml index 58577964dd..355fe596de 100644 --- a/primitives/serializer/Cargo.toml +++ b/primitives/serializer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-serializer" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/session/Cargo.toml b/primitives/session/Cargo.toml index 3e41d1084f..0a10107f98 100644 --- a/primitives/session/Cargo.toml +++ b/primitives/session/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-session" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,10 +9,10 @@ repository = "https://github.com/paritytech/substrate/" description = "Primitives for sessions" [dependencies] -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } -sp-runtime = { version = "2.0.0-alpha.4", optional = true, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } +sp-runtime = { version = "2.0.0-alpha.5", optional = true, path = "../runtime" } [features] default = [ "std" ] diff --git a/primitives/staking/Cargo.toml b/primitives/staking/Cargo.toml index 175f478f00..01f68ac3ce 100644 --- a/primitives/staking/Cargo.toml +++ b/primitives/staking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-staking" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,8 +10,8 @@ description = "A crate which contains primitives that are useful for implementat [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } [features] default = ["std"] diff --git a/primitives/state-machine/Cargo.toml b/primitives/state-machine/Cargo.toml index c9969e318a..47321181c7 100644 --- a/primitives/state-machine/Cargo.toml +++ b/primitives/state-machine/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-state-machine" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "Substrate State Machine" edition = "2018" @@ -15,17 +15,17 @@ parking_lot = "0.10.0" hash-db = "0.15.2" trie-db = "0.20.0" trie-root = "0.16.0" -sp-trie = { version = "2.0.0-alpha.4", path = "../trie" } -sp-core = { version = "2.0.0-alpha.4", path = "../core" } -sp-panic-handler = { version = "2.0.0-alpha.4", path = "../panic-handler" } +sp-trie = { version = "2.0.0-alpha.5", path = "../trie" } +sp-core = { version = "2.0.0-alpha.5", path = "../core" } +sp-panic-handler = { version = "2.0.0-alpha.5", path = "../panic-handler" } codec = { package = "parity-scale-codec", version = "1.2.0" } num-traits = "0.2.8" rand = "0.7.2" -sp-externalities = { version = "0.8.0-alpha.4", path = "../externalities" } +sp-externalities = { version = "0.8.0-alpha.5", path = "../externalities" } [dev-dependencies] hex-literal = "0.2.1" -sp-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } [features] default = [] diff --git a/primitives/std/Cargo.toml b/primitives/std/Cargo.toml index 86b6e037b8..e33b9d88aa 100644 --- a/primitives/std/Cargo.toml +++ b/primitives/std/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-std" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/storage/Cargo.toml b/primitives/storage/Cargo.toml index 9e90b6ecc6..fa06f0cc24 100644 --- a/primitives/storage/Cargo.toml +++ b/primitives/storage/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-storage" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" description = "Storage related primitives" @@ -10,10 +10,10 @@ repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sp-storage/" [dependencies] -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } impl-serde = { version = "0.2.3", optional = true } -sp-debug-derive = { version = "2.0.0-alpha.4", path = "../debug-derive" } +sp-debug-derive = { version = "2.0.0-alpha.5", path = "../debug-derive" } [features] default = [ "std" ] diff --git a/primitives/test-primitives/Cargo.toml b/primitives/test-primitives/Cargo.toml index fa48bd85ac..20f7d13dc9 100644 --- a/primitives/test-primitives/Cargo.toml +++ b/primitives/test-primitives/Cargo.toml @@ -9,11 +9,11 @@ repository = "https://github.com/paritytech/substrate/" publish = false [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../application-crypto" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [features] diff --git a/primitives/timestamp/Cargo.toml b/primitives/timestamp/Cargo.toml index 52cb523ca5..cd31c1db25 100644 --- a/primitives/timestamp/Cargo.toml +++ b/primitives/timestamp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-timestamp" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,11 +9,11 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate core types and inherents for timestamps." [dependencies] -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../inherents" } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../inherents" } impl-trait-for-tuples = "0.1.3" wasm-timer = "0.2" diff --git a/primitives/transaction-pool/Cargo.toml b/primitives/transaction-pool/Cargo.toml index e17607921b..e345b1a1f0 100644 --- a/primitives/transaction-pool/Cargo.toml +++ b/primitives/transaction-pool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-transaction-pool" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,8 +16,8 @@ derive_more = { version = "0.99.2", optional = true } futures = { version = "0.3.1", optional = true } log = { version = "0.4.8", optional = true } serde = { version = "1.0.101", features = ["derive"], optional = true} -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } [features] default = [ "std" ] diff --git a/primitives/trie/Cargo.toml b/primitives/trie/Cargo.toml index 446a2da111..cb91377f96 100644 --- a/primitives/trie/Cargo.toml +++ b/primitives/trie/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-trie" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] description = "Patricia trie stuff using a parity-scale-codec node format" repository = "https://github.com/paritytech/substrate/" @@ -15,19 +15,19 @@ harness = false [dependencies] codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } hash-db = { version = "0.15.2", default-features = false } trie-db = { version = "0.20.0", default-features = false } trie-root = { version = "0.16.0", default-features = false } memory-db = { version = "0.20.0", default-features = false } -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../core" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } [dev-dependencies] trie-bench = "0.21.0" trie-standardmap = "0.15.2" criterion = "0.2.11" hex-literal = "0.2.1" -sp-runtime = { version = "2.0.0-alpha.4", path = "../runtime" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } [features] default = ["std"] diff --git a/primitives/version/Cargo.toml b/primitives/version/Cargo.toml index e917909266..406eff4fbf 100644 --- a/primitives/version/Cargo.toml +++ b/primitives/version/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-version" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,8 +14,8 @@ documentation = "https://docs.rs/sp-version" impl-serde = { version = "0.2.3", optional = true } serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/wasm-interface/Cargo.toml b/primitives/wasm-interface/Cargo.toml index e8bbbc3ebe..998463d6e9 100644 --- a/primitives/wasm-interface/Cargo.toml +++ b/primitives/wasm-interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-wasm-interface" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,7 +12,7 @@ documentation = "https://docs.rs/sp-wasm-interface" [dependencies] wasmi = { version = "0.6.2", optional = true } impl-trait-for-tuples = "0.1.2" -sp-std = { version = "2.0.0-alpha.4", path = "../std", default-features = false } +sp-std = { version = "2.0.0-alpha.5", path = "../std", default-features = false } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } [features] diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml index 9ebfa16dac..4584c37910 100644 --- a/test-utils/Cargo.toml +++ b/test-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-test-utils" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/test-utils/client/Cargo.toml b/test-utils/client/Cargo.toml index fcdc81a2db..66fd728696 100644 --- a/test-utils/client/Cargo.toml +++ b/test-utils/client/Cargo.toml @@ -9,16 +9,16 @@ repository = "https://github.com/paritytech/substrate/" publish = false [dependencies] -sc-client-api = { version = "2.0.0-alpha.4", path = "../../client/api" } -sc-client = { version = "0.8.0-alpha.4", path = "../../client/" } -sc-client-db = { version = "0.8.0-alpha.4", features = ["test-helpers"], path = "../../client/db" } -sp-consensus = { version = "0.8.0-alpha.4", path = "../../primitives/consensus/common" } -sc-executor = { version = "0.8.0-alpha.4", path = "../../client/executor" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../client/api" } +sc-client = { version = "0.8.0-alpha.5", path = "../../client/" } +sc-client-db = { version = "0.8.0-alpha.5", features = ["test-helpers"], path = "../../client/db" } +sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } +sc-executor = { version = "0.8.0-alpha.5", path = "../../client/executor" } futures = "0.3.1" hash-db = "0.15.2" -sp-keyring = { version = "2.0.0-alpha.4", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } codec = { package = "parity-scale-codec", version = "1.2.0" } -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../primitives/runtime" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../primitives/blockchain" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } +sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index 0096d90083..39920688e2 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -10,43 +10,43 @@ repository = "https://github.com/paritytech/substrate/" publish = false [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/application-crypto" } -sp-consensus-aura = { version = "0.8.0-alpha.4", default-features = false, path = "../../primitives/consensus/aura" } -sp-consensus-babe = { version = "0.8.0-alpha.4", default-features = false, path = "../../primitives/consensus/babe" } -sp-block-builder = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/block-builder" } +sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/application-crypto" } +sp-consensus-aura = { version = "0.8.0-alpha.5", default-features = false, path = "../../primitives/consensus/aura" } +sp-consensus-babe = { version = "0.8.0-alpha.5", default-features = false, path = "../../primitives/consensus/babe" } +sp-block-builder = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/block-builder" } cfg-if = "0.1.10" codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -frame-executive = { version = "2.0.0-alpha.4", default-features = false, path = "../../frame/executive" } -sp-inherents = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.4", optional = true, path = "../../primitives/keyring" } +frame-executive = { version = "2.0.0-alpha.5", default-features = false, path = "../../frame/executive" } +sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } +sp-keyring = { version = "2.0.0-alpha.5", optional = true, path = "../../primitives/keyring" } log = { version = "0.4.8", optional = true } memory-db = { version = "0.20.0", default-features = false } -sp-offchain = { path = "../../primitives/offchain", default-features = false, version = "2.0.0-alpha.4"} -sp-core = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-runtime-interface = { path = "../../primitives/runtime-interface", default-features = false, version = "2.0.0-alpha.4"} -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../../frame/support" } -sp-version = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/version" } +sp-offchain = { path = "../../primitives/offchain", default-features = false, version = "2.0.0-alpha.5"} +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-runtime-interface = { path = "../../primitives/runtime-interface", default-features = false, version = "2.0.0-alpha.5"} +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../frame/support" } +sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/version" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-session = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/session" } -sp-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -pallet-babe = { version = "2.0.0-alpha.4", default-features = false, path = "../../frame/babe" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../../frame/system" } -frame-system-rpc-runtime-api = { version = "2.0.0-alpha.4", default-features = false, path = "../../frame/system/rpc/runtime-api" } -pallet-timestamp = { version = "2.0.0-alpha.4", default-features = false, path = "../../frame/timestamp" } -sc-client = { version = "0.8.0-alpha.4", optional = true, path = "../../client" } -sp-trie = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/trie" } -sp-transaction-pool = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/transaction-pool" } +sp-session = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/session" } +sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +pallet-babe = { version = "2.0.0-alpha.5", default-features = false, path = "../../frame/babe" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../../frame/system" } +frame-system-rpc-runtime-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../frame/system/rpc/runtime-api" } +pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../frame/timestamp" } +sc-client = { version = "0.8.0-alpha.5", optional = true, path = "../../client" } +sp-trie = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/trie" } +sp-transaction-pool = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/transaction-pool" } trie-db = { version = "0.20.0", default-features = false } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] -sc-block-builder = { version = "0.8.0-alpha.4", path = "../../client/block-builder" } -sc-executor = { version = "0.8.0-alpha.4", path = "../../client/executor" } +sc-block-builder = { version = "0.8.0-alpha.5", path = "../../client/block-builder" } +sc-executor = { version = "0.8.0-alpha.5", path = "../../client/executor" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "./client" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../utils/wasm-builder-runner" } diff --git a/test-utils/runtime/client/Cargo.toml b/test-utils/runtime/client/Cargo.toml index e8e233855c..3af6c4967e 100644 --- a/test-utils/runtime/client/Cargo.toml +++ b/test-utils/runtime/client/Cargo.toml @@ -9,14 +9,14 @@ repository = "https://github.com/paritytech/substrate/" publish = false [dependencies] -sc-block-builder = { version = "0.8.0-alpha.4", path = "../../../client/block-builder" } +sc-block-builder = { version = "0.8.0-alpha.5", path = "../../../client/block-builder" } substrate-test-client = { version = "2.0.0-dev", path = "../../client" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../runtime" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.4", path = "../../../primitives/api" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } codec = { package = "parity-scale-codec", version = "1.2.0" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../../../client/api" } -sc-client = { version = "0.8.0-alpha.4", path = "../../../client/" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } +sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } futures = "0.3.1" diff --git a/test-utils/runtime/transaction-pool/Cargo.toml b/test-utils/runtime/transaction-pool/Cargo.toml index a33f91785f..cc58bdcbd0 100644 --- a/test-utils/runtime/transaction-pool/Cargo.toml +++ b/test-utils/runtime/transaction-pool/Cargo.toml @@ -12,9 +12,9 @@ publish = false substrate-test-runtime-client = { version = "2.0.0-dev", path = "../client" } parking_lot = "0.10.0" codec = { package = "parity-scale-codec", version = "1.2.0" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../primitives/transaction-pool" } -sc-transaction-graph = { version = "2.0.0-alpha.4", path = "../../../client/transaction-pool/graph" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } +sc-transaction-graph = { version = "2.0.0-alpha.5", path = "../../../client/transaction-pool/graph" } futures = { version = "0.3.1", features = ["compat"] } derive_more = "0.99.2" diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 10aa17a875..4e0a6ac7d1 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-browser-utils" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" authors = ["Parity Technologies "] description = "Utilities for creating a browser light-client." edition = "2018" @@ -19,10 +19,10 @@ js-sys = "0.3.34" wasm-bindgen = "0.2.57" wasm-bindgen-futures = "0.4.7" kvdb-web = "0.5" -sc-informant = { version = "0.8.0-alpha.4", path = "../../client/informant" } -sc-service = { version = "0.8.0-alpha.4", path = "../../client/service", default-features = false } -sc-network = { path = "../../client/network", version = "0.8.0-alpha.4"} -sc-chain-spec = { path = "../../client/chain-spec", version = "2.0.0-alpha.4"} +sc-informant = { version = "0.8.0-alpha.5", path = "../../client/informant" } +sc-service = { version = "0.8.0-alpha.5", path = "../../client/service", default-features = false } +sc-network = { path = "../../client/network", version = "0.8.0-alpha.5"} +sc-chain-spec = { path = "../../client/chain-spec", version = "2.0.0-alpha.5"} # Imported just for the `no_cc` feature clear_on_drop = { version = "0.2.3", features = ["no_cc"] } diff --git a/utils/build-script-utils/Cargo.toml b/utils/build-script-utils/Cargo.toml index b0008f77c4..c5862a40ee 100644 --- a/utils/build-script-utils/Cargo.toml +++ b/utils/build-script-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-build-script-utils" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/utils/fork-tree/Cargo.toml b/utils/fork-tree/Cargo.toml index 604a87bf86..0814a761ec 100644 --- a/utils/fork-tree/Cargo.toml +++ b/utils/fork-tree/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fork-tree" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/utils/frame/benchmarking-cli/Cargo.toml b/utils/frame/benchmarking-cli/Cargo.toml index 3ba1b16481..d63e516b45 100644 --- a/utils/frame/benchmarking-cli/Cargo.toml +++ b/utils/frame/benchmarking-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-benchmarking-cli" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,15 +9,19 @@ repository = "https://github.com/paritytech/substrate/" description = "CLI for benchmarking FRAME" [dependencies] -frame-benchmarking = { version = "2.0.0-alpha.4", path = "../../../frame/benchmarking" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../primitives/core" } -sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../../../client/service" } -sc-cli = { version = "0.8.0-alpha.4", path = "../../../client/cli" } -sc-client = { version = "0.8.0-alpha.4", path = "../../../client" } -sc-client-db = { version = "0.8.0-alpha.4", path = "../../../client/db" } -sc-executor = { version = "0.8.0-alpha.4", path = "../../../client/executor" } -sp-externalities = { version = "0.8.0-alpha.4", path = "../../../primitives/externalities" } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" } +frame-benchmarking = { version = "2.0.0-alpha.5", path = "../../../frame/benchmarking" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../../../client/service" } +sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } +sc-client = { version = "0.8.0-alpha.5", path = "../../../client" } +sc-client-db = { version = "0.8.0-alpha.5", path = "../../../client/db" } +sc-executor = { version = "0.8.0-alpha.5", path = "../../../client/executor" } +sp-externalities = { version = "0.8.0-alpha.5", path = "../../../primitives/externalities" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } structopt = "0.3.8" codec = { version = "1.2.0", package = "parity-scale-codec" } + +[features] +default = ["rocksdb"] +rocksdb = ["sc-client-db/kvdb-rocksdb"] diff --git a/utils/frame/rpc/support/Cargo.toml b/utils/frame/rpc/support/Cargo.toml index 6ebc79a391..4de85524e7 100644 --- a/utils/frame/rpc/support/Cargo.toml +++ b/utils/frame/rpc/support/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-frame-rpc-support" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies ", "Andrew Dirksen "] edition = "2018" license = "GPL-3.0" @@ -14,10 +14,10 @@ jsonrpc-client-transports = "14" jsonrpc-core = "14" codec = { package = "parity-scale-codec", version = "1" } serde = "1" -frame-support = { version = "2.0.0-alpha.4", path = "../../../../frame/support" } -sp-storage = { version = "2.0.0-alpha.4", path = "../../../../primitives/storage" } -sc-rpc-api = { version = "0.8.0-alpha.4", path = "../../../../client/rpc-api" } +frame-support = { version = "2.0.0-alpha.5", path = "../../../../frame/support" } +sp-storage = { version = "2.0.0-alpha.5", path = "../../../../primitives/storage" } +sc-rpc-api = { version = "0.8.0-alpha.5", path = "../../../../client/rpc-api" } [dev-dependencies] -frame-system = { version = "2.0.0-alpha.4", path = "../../../../frame/system" } +frame-system = { version = "2.0.0-alpha.5", path = "../../../../frame/system" } tokio = "0.2" diff --git a/utils/frame/rpc/system/Cargo.toml b/utils/frame/rpc/system/Cargo.toml index aaec43b451..a4f6833fad 100644 --- a/utils/frame/rpc/system/Cargo.toml +++ b/utils/frame/rpc/system/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-frame-rpc-system" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME's system exposed over Substrate RPC" [dependencies] -sc-client = { version = "0.8.0-alpha.4", path = "../../../../client/" } +sc-client = { version = "0.8.0-alpha.5", path = "../../../../client/" } codec = { package = "parity-scale-codec", version = "1.2.0" } futures = "0.3.1" jsonrpc-core = "14.0.3" @@ -17,14 +17,14 @@ jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" log = "0.4.8" serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.4", path = "../../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.4", path = "../../../../primitives/api" } -frame-system-rpc-runtime-api = { version = "2.0.0-alpha.4", path = "../../../../frame/system/rpc/runtime-api" } -sp-core = { version = "2.0.0-alpha.4", path = "../../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.4", path = "../../../../primitives/blockchain" } -sp-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../../primitives/transaction-pool" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.5", path = "../../../../primitives/api" } +frame-system-rpc-runtime-api = { version = "2.0.0-alpha.5", path = "../../../../frame/system/rpc/runtime-api" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../../primitives/blockchain" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../../primitives/transaction-pool" } [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../../test-utils/runtime/client" } env_logger = "0.7.0" -sc-transaction-pool = { version = "2.0.0-alpha.4", path = "../../../../client/transaction-pool" } +sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../../client/transaction-pool" } diff --git a/utils/prometheus/Cargo.toml b/utils/prometheus/Cargo.toml index 8448283e74..bad77b1ea6 100644 --- a/utils/prometheus/Cargo.toml +++ b/utils/prometheus/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Endpoint to expose Prometheus metrics" name = "substrate-prometheus-endpoint" -version = "0.8.0-alpha.4" +version = "0.8.0-alpha.5" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" -- GitLab From e796df1898d5ef1dc4321e53cfdd238f16cb8b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 24 Mar 2020 15:24:09 +0100 Subject: [PATCH 060/300] Print an error when a bootnode is on a different chain (#5377) * Print an error when a bootnode is on a different chain * Fix tests --- client/network/src/protocol.rs | 22 +++++++++++++++++++--- client/network/src/service.rs | 7 +++++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index f76c49fd76..7cf568065e 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -225,6 +225,8 @@ pub struct Protocol { protocol_engine_by_name: HashMap, ConsensusEngineId>, /// Prometheus metrics. metrics: Option, + /// The `PeerId`'s of all boot nodes. + boot_node_ids: Arc>, } #[derive(Default)] @@ -434,7 +436,8 @@ impl Protocol { protocol_id: ProtocolId, peerset_config: sc_peerset::PeersetConfig, block_announce_validator: Box + Send>, - metrics_registry: Option<&Registry> + metrics_registry: Option<&Registry>, + boot_node_ids: Arc>, ) -> error::Result<(Protocol, sc_peerset::PeersetHandle)> { let info = chain.info(); let sync = ChainSync::new( @@ -483,7 +486,8 @@ impl Protocol { Some(Metrics::register(r)?) } else { None - } + }, + boot_node_ids, }; Ok((protocol, peerset_handle)) @@ -1014,6 +1018,17 @@ impl Protocol { ); self.peerset_handle.report_peer(who.clone(), rep::GENESIS_MISMATCH); self.behaviour.disconnect_peer(&who); + + if self.boot_node_ids.contains(&who) { + error!( + target: "sync", + "Bootnode with peer id `{}` is on a different chain (our genesis: {} theirs: {})", + who, + self.genesis_hash, + status.genesis_hash, + ); + } + return CustomMessageOutcome::None; } if status.version < MIN_VERSION && CURRENT_VERSION < status.min_supported_version { @@ -2151,7 +2166,8 @@ mod tests { reserved_nodes: Vec::new(), }, Box::new(DefaultBlockAnnounceValidator::new(client.clone())), - None + None, + Default::default(), ).unwrap(); let dummy_peer_id = PeerId::random(); diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 83492e2e93..e06d3bd13e 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -185,6 +185,8 @@ impl NetworkWorker { } } + let boot_node_ids = Arc::new(boot_node_ids); + // Check for duplicate bootnodes. known_addresses.iter() .try_for_each(|(peer_id, addr)| @@ -245,7 +247,8 @@ impl NetworkWorker { params.protocol_id.clone(), peerset_config, params.block_announce_validator, - params.metrics_registry.as_ref() + params.metrics_registry.as_ref(), + boot_node_ids.clone(), )?; // Build the swarm. @@ -776,7 +779,7 @@ pub struct NetworkWorker { /// Prometheus network metrics. metrics: Option, /// The `PeerId`'s of all boot nodes. - boot_node_ids: HashSet, + boot_node_ids: Arc>, } struct Metrics { -- GitLab From 1ce4be050a5fe8b2af5b5b4d362238bf570b2a9f Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Tue, 24 Mar 2020 10:05:57 -0700 Subject: [PATCH 061/300] Update schnorrkel with versioning (#5358) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * use versioning for deprecated api, remove deprecated api from regular verification * Update primitives/core/src/sr25519.rs * add test to transaction pool Co-authored-by: Bastian Köcher --- Cargo.lock | 2 + client/transaction-pool/Cargo.toml | 2 + client/transaction-pool/src/testing/pool.rs | 40 ++++++++++++++++-- primitives/core/src/sr25519.rs | 47 ++++++++++++++------- primitives/io/src/lib.rs | 9 ++++ 5 files changed, 81 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f1e5a4c56..dd14f4bc5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6650,10 +6650,12 @@ dependencies = [ name = "sc-transaction-pool" version = "2.0.0-alpha.5" dependencies = [ + "assert_matches", "derive_more", "futures 0.3.4", "futures-diagnose", "futures-timer 2.0.2", + "hex", "log 0.4.8", "parity-scale-codec", "parity-util-mem", diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index ca7130b2d6..f5b6539a29 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -27,6 +27,8 @@ futures-timer = "2.0" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] +assert_matches = "1.3.0" +hex = "0.4" sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } substrate-test-runtime-transaction-pool = { version = "2.0.0-dev", path = "../../test-utils/runtime/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index 27cb6c62a5..fe777c9e67 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -20,15 +20,16 @@ use futures::executor::block_on; use txpool::{self, Pool}; use sp_runtime::{ generic::BlockId, - transaction_validity::ValidTransaction, + transaction_validity::{ValidTransaction, InvalidTransaction}, }; use substrate_test_runtime_client::{ - runtime::{Block, Hash, Index, Header, Extrinsic}, + runtime::{Block, Hash, Index, Header, Extrinsic, Transfer}, AccountKeyring::*, }; use substrate_test_runtime_transaction_pool::{TestApi, uxt}; use crate::revalidation::BACKGROUND_REVALIDATION_INTERVAL; use futures::task::Poll; +use codec::Encode; fn pool() -> Pool { Pool::new(Default::default(), TestApi::with_alice_nonce(209).into()) @@ -653,4 +654,37 @@ fn ready_set_should_eventually_resolve_when_block_update_arrives() { assert_eq!(data.len(), 1); } } -} \ No newline at end of file +} + +#[test] +fn should_not_accept_old_signatures() { + use std::convert::TryFrom; + + let client = Arc::new(substrate_test_runtime_client::new()); + let pool = Arc::new( + BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client))).0 + ); + + let transfer = Transfer { + from: Alice.into(), + to: Bob.into(), + nonce: 0, + amount: 1, + }; + let _bytes: sp_core::sr25519::Signature = transfer.using_encoded(|e| Alice.sign(e)).into(); + + // generated with schnorrkel 0.1.1 from `_bytes` + let old_singature = sp_core::sr25519::Signature::try_from(&hex::decode( + "c427eb672e8c441c86d31f1a81b22b43102058e9ce237cabe9897ea5099ffd426cd1c6a1f4f2869c3df57901d36bedcb295657adb3a4355add86ed234eb83108" + ).expect("hex invalid")[..]).expect("signature construction failed"); + + let xt = Extrinsic::Transfer { transfer, signature: old_singature, exhaust_resources_when_not_first: false }; + + assert_matches::assert_matches!( + block_on(pool.submit_one(&BlockId::number(0), xt.clone())), + Err(error::Error::Pool( + sp_transaction_pool::error::Error::InvalidTransaction(InvalidTransaction::BadProof) + )), + "Should be invalid transactiono with bad proof", + ); +} diff --git a/primitives/core/src/sr25519.rs b/primitives/core/src/sr25519.rs index 3495f32872..de643dbb0a 100644 --- a/primitives/core/src/sr25519.rs +++ b/primitives/core/src/sr25519.rs @@ -529,25 +529,24 @@ impl TraitPair for Pair { self.0.sign(context.bytes(message)).into() } - /// Verify a signature on a message. Returns true if the signature is good. fn verify>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool { Self::verify_weak(&sig.0[..], message, pubkey) } - /// Verify a signature on a message. Returns true if the signature is good. fn verify_weak, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool { - // Match both schnorrkel 0.1.1 and 0.8.0+ signatures, supporting both wallets - // that have not been upgraded and those that have. To swap to 0.8.0 only, - // create `schnorrkel::Signature` and pass that into `verify_simple` - match PublicKey::from_bytes(pubkey.as_ref()) { - Ok(pk) => pk.verify_simple_preaudit_deprecated( - SIGNING_CTX, message.as_ref(), &sig, - ).is_ok(), - Err(_) => false, - } + let signature = match schnorrkel::Signature::from_bytes(sig) { + Ok(signature) => signature, + Err(_) => return false, + }; + + let pub_key = match PublicKey::from_bytes(pubkey.as_ref()) { + Ok(pub_key) => pub_key, + Err(_) => return false, + }; + + pub_key.verify_simple(SIGNING_CTX, message.as_ref(), &signature).is_ok() } - /// Return a vec filled with raw data. fn to_raw_vec(&self) -> Vec { self.0.secret.to_bytes().to_vec() } @@ -566,6 +565,20 @@ impl Pair { let kp = mini_key.expand_to_keypair(ExpansionMode::Ed25519); (Pair(kp), mini_key.to_bytes()) } + + /// Verify a signature on a message. Returns `true` if the signature is good. + /// Supports old 0.1.1 deprecated signatures and should be used only for backward + /// compatibility. + pub fn verify_deprecated>(sig: &Signature, message: M, pubkey: &Public) -> bool { + // Match both schnorrkel 0.1.1 and 0.8.0+ signatures, supporting both wallets + // that have not been upgraded and those that have. + match PublicKey::from_bytes(pubkey.as_ref()) { + Ok(pk) => pk.verify_simple_preaudit_deprecated( + SIGNING_CTX, message.as_ref(), &sig.0[..], + ).is_ok(), + Err(_) => false, + } + } } impl CryptoType for Public { @@ -609,14 +622,15 @@ mod compatibility_test { } #[test] - fn verify_known_message_should_work() { + fn verify_known_old_message_should_work() { let public = Public::from_raw(hex!("b4bfa1f7a5166695eb75299fd1c4c03ea212871c342f2c5dfea0902b2c246918")); // signature generated by the 1.1 version with the same ^^ public key. let signature = Signature::from_raw(hex!( "5a9755f069939f45d96aaf125cf5ce7ba1db998686f87f2fb3cbdea922078741a73891ba265f70c31436e18a9acd14d189d73c12317ab6c313285cd938453202" )); let message = b"Verifying that I am the owner of 5G9hQLdsKQswNPgB499DeA5PkFBbgkLPJWkkS6FAM6xGQ8xD. Hash: 221455a3\n"; - assert!(Pair::verify(&signature, &message[..], &public)); + assert!(Pair::verify_deprecated(&signature, &message[..], &public)); + assert!(!Pair::verify(&signature, &message[..], &public)); } } @@ -776,7 +790,7 @@ mod test { } #[test] - fn verify_from_wasm_works() { + fn verify_from_old_wasm_works() { // The values in this test case are compared to the output of `node-test.js` in schnorrkel-js. // // This is to make sure that the wasm library is compatible. @@ -787,7 +801,8 @@ mod test { let js_signature = Signature::from_raw(hex!( "28a854d54903e056f89581c691c1f7d2ff39f8f896c9e9c22475e60902cc2b3547199e0e91fa32902028f2ca2355e8cdd16cfe19ba5e8b658c94aa80f3b81a00" )); - assert!(Pair::verify(&js_signature, b"SUBSTRATE", &public)); + assert!(Pair::verify_deprecated(&js_signature, b"SUBSTRATE", &public)); + assert!(!Pair::verify(&js_signature, b"SUBSTRATE", &public)); } #[test] diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index 2702be0207..a6dcfd1b76 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -466,9 +466,18 @@ pub trait Crypto { .map(|k| k.sign(msg)) } + /// Verify an `sr25519` signature. + /// + /// Returns `true` when the verification in successful regardless of + /// signature version. + fn sr25519_verify(sig: &sr25519::Signature, msg: &[u8], pubkey: &sr25519::Public) -> bool { + sr25519::Pair::verify_deprecated(sig, msg, pubkey) + } + /// Verify an `sr25519` signature. /// /// Returns `true` when the verification in successful. + #[version(2)] fn sr25519_verify(sig: &sr25519::Signature, msg: &[u8], pubkey: &sr25519::Public) -> bool { sr25519::Pair::verify(sig, msg, pubkey) } -- GitLab From f4460efc9570b4990f3a9d965d198502d0c0339d Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Tue, 24 Mar 2020 18:06:29 +0100 Subject: [PATCH 062/300] Benchmark Collective Pallet (#5343) * Init * Fix execute. * Duplicate macro for instances temporarilly * Add propose. * Add vote, close. * Propose from own module * Add old members to set_members. * Add previous proposals to propose. * Compress a bit the macro. Co-authored-by: Shawn Tabrizi --- Cargo.lock | 1 + bin/node/runtime/Cargo.toml | 1 + bin/node/runtime/src/lib.rs | 7 + frame/benchmarking/src/lib.rs | 244 ++++++++++++++++++++++++--- frame/benchmarking/src/utils.rs | 9 + frame/collective/Cargo.toml | 3 + frame/collective/src/benchmarking.rs | 185 ++++++++++++++++++++ frame/collective/src/lib.rs | 7 +- 8 files changed, 429 insertions(+), 28 deletions(-) create mode 100644 frame/collective/src/benchmarking.rs diff --git a/Cargo.lock b/Cargo.lock index dd14f4bc5b..76fabe80eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4062,6 +4062,7 @@ dependencies = [ name = "pallet-collective" version = "2.0.0-alpha.5" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", "hex-literal", diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 6346f3d848..24ae560607 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -142,6 +142,7 @@ runtime-benchmarks = [ "pallet-session-benchmarking", "pallet-staking/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", + "pallet-collective/runtime-benchmarks", "pallet-session-benchmarking", "pallet-staking/runtime-benchmarks", "pallet-im-online/runtime-benchmarks", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 7347db2124..319c0f4618 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -916,6 +916,13 @@ impl_runtime_apis! { steps, repeat, ), + b"pallet-collective" | b"collective" => Council::run_benchmark( + extrinsic, + lowest_range_values, + highest_range_values, + steps, + repeat, + ), _ => Err("Benchmark not found for this pallet."), }; diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index f6094739bf..4254edcac5 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -134,7 +134,23 @@ macro_rules! benchmarks { } $( $rest:tt )* ) => { - $crate::benchmarks_iter!({ + $crate::benchmarks_iter!(NO_INSTANCE { + $( { $common , $common_from , $common_to , $common_instancer } )* + } ( ) $( $rest )* ); + } +} + +#[macro_export] +macro_rules! benchmarks_instance { + ( + _ { + $( + let $common:ident in $common_from:tt .. $common_to:expr => $common_instancer:expr; + )* + } + $( $rest:tt )* + ) => { + $crate::benchmarks_iter!(INSTANCE { $( { $common , $common_from , $common_to , $common_instancer } )* } ( ) $( $rest )* ); } @@ -145,44 +161,63 @@ macro_rules! benchmarks { macro_rules! benchmarks_iter { // mutation arm: ( + $instance:ident { $( $common:tt )* } ( $( $names:ident )* ) $name:ident { $( $code:tt )* }: _ ( $origin:expr $( , $arg:expr )* ) $( $rest:tt )* ) => { $crate::benchmarks_iter! { - { $( $common )* } ( $( $names )* ) $name { $( $code )* }: $name ( $origin $( , $arg )* ) $( $rest )* + $instance { $( $common )* } ( $( $names )* ) $name { $( $code )* }: $name ( $origin $( , $arg )* ) $( $rest )* } }; - // mutation arm: + // no instance mutation arm: ( + NO_INSTANCE { $( $common:tt )* } ( $( $names:ident )* ) $name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* ) $( $rest:tt )* ) => { $crate::benchmarks_iter! { + NO_INSTANCE { $( $common )* } ( $( $names )* ) $name { $( $code )* }: { as $crate::Dispatchable>::dispatch(Call::::$dispatch($($arg),*), $origin.into())?; } $( $rest )* } }; + // instance mutation arm: + ( + INSTANCE + { $( $common:tt )* } + ( $( $names:ident )* ) + $name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* ) + $( $rest:tt )* + ) => { + $crate::benchmarks_iter! { + INSTANCE + { $( $common )* } ( $( $names )* ) $name { $( $code )* }: { + as $crate::Dispatchable>::dispatch(Call::::$dispatch($($arg),*), $origin.into())?; + } $( $rest )* + } + }; // iteration arm: ( + $instance:ident { $( $common:tt )* } ( $( $names:ident )* ) $name:ident { $( $code:tt )* }: $eval:block $( $rest:tt )* ) => { $crate::benchmark_backend! { - $name { $( $common )* } { } { $eval } { $( $code )* } + $instance $name { $( $common )* } { } { $eval } { $( $code )* } } - $crate::benchmarks_iter!( { $( $common )* } ( $( $names )* $name ) $( $rest )* ); + $crate::benchmarks_iter!( $instance { $( $common )* } ( $( $names )* $name ) $( $rest )* ); }; // iteration-exit arm - ( { $( $common:tt )* } ( $( $names:ident )* ) ) => { - $crate::selected_benchmark!( $( $names ),* ); - $crate::impl_benchmark!( $( $names ),* ); + ( $instance:ident { $( $common:tt )* } ( $( $names:ident )* ) ) => { + $crate::selected_benchmark!( $instance $( $names ),* ); + $crate::impl_benchmark!( $instance $( $names ),* ); } } @@ -190,7 +225,7 @@ macro_rules! benchmarks_iter { #[allow(missing_docs)] macro_rules! benchmark_backend { // parsing arms - ($name:ident { + ($instance:ident $name:ident { $( $common:tt )* } { $( PRE { $( $pre_parsed:tt )* } )* @@ -199,13 +234,13 @@ macro_rules! benchmark_backend { $( $rest:tt )* } ) => { $crate::benchmark_backend! { - $name { $( $common )* } { + $instance $name { $( $common )* } { $( PRE { $( $pre_parsed )* } )* PRE { $pre_id , $pre_ty , $pre_ex } } { $eval } { $( $rest )* } } }; - ($name:ident { + ($instance:ident $name:ident { $( $common:tt )* } { $( $parsed:tt )* @@ -214,14 +249,14 @@ macro_rules! benchmark_backend { $( $rest:tt )* }) => { $crate::benchmark_backend! { - $name { $( $common )* } { + $instance $name { $( $common )* } { $( $parsed )* PARAM { $param , $param_from , $param_to , $param_instancer } } { $eval } { $( $rest )* } } }; // mutation arm to look after defaulting to a common param - ($name:ident { + ($instance:ident $name:ident { $( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )* } { $( $parsed:tt )* @@ -230,7 +265,7 @@ macro_rules! benchmark_backend { $( $rest:tt )* }) => { $crate::benchmark_backend! { - $name { + $instance $name { $( { $common , $common_from , $common_to , $common_instancer } )* } { $( $parsed )* @@ -244,7 +279,7 @@ macro_rules! benchmark_backend { } }; // mutation arm to look after defaulting only the range to common param - ($name:ident { + ($instance:ident $name:ident { $( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )* } { $( $parsed:tt )* @@ -253,7 +288,7 @@ macro_rules! benchmark_backend { $( $rest:tt )* }) => { $crate::benchmark_backend! { - $name { + $instance $name { $( { $common , $common_from , $common_to , $common_instancer } )* } { $( $parsed )* @@ -267,7 +302,7 @@ macro_rules! benchmark_backend { } }; // mutation arm to look after a single tt for param_from. - ($name:ident { + ($instance:ident $name:ident { $( $common:tt )* } { $( $parsed:tt )* @@ -276,14 +311,14 @@ macro_rules! benchmark_backend { $( $rest:tt )* }) => { $crate::benchmark_backend! { - $name { $( $common )* } { $( $parsed )* } { $eval } { + $instance $name { $( $common )* } { $( $parsed )* } { $eval } { let $param in ( $param_from ) .. $param_to => $param_instancer; $( $rest )* } } }; // mutation arm to look after the default tail of `=> ()` - ($name:ident { + ($instance:ident $name:ident { $( $common:tt )* } { $( $parsed:tt )* @@ -292,14 +327,14 @@ macro_rules! benchmark_backend { $( $rest:tt )* }) => { $crate::benchmark_backend! { - $name { $( $common )* } { $( $parsed )* } { $eval } { + $instance $name { $( $common )* } { $( $parsed )* } { $eval } { let $param in $param_from .. $param_to => (); $( $rest )* } } }; // mutation arm to look after `let _ =` - ($name:ident { + ($instance:ident $name:ident { $( $common:tt )* } { $( $parsed:tt )* @@ -308,14 +343,14 @@ macro_rules! benchmark_backend { $( $rest:tt )* }) => { $crate::benchmark_backend! { - $name { $( $common )* } { $( $parsed )* } { $eval } { + $instance $name { $( $common )* } { $( $parsed )* } { $eval } { let $pre_id : _ = $pre_ex; $( $rest )* } } }; - // actioning arm - ($name:ident { + // no instance actioning arm + (NO_INSTANCE $name:ident { $( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )* } { $( PRE { $pre_id:tt , $pre_ty:ty , $pre_ex:expr } )* @@ -333,6 +368,45 @@ macro_rules! benchmark_backend { ] } + fn instance(&self, components: &[($crate::BenchmarkParameter, u32)]) + -> Result Result<(), &'static str>>, &'static str> + { + $( + let $common = $common_from; + )* + $( + // Prepare instance + let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1; + )* + $( + let $pre_id : $pre_ty = $pre_ex; + )* + $( $param_instancer ; )* + $( $post )* + + Ok(Box::new(move || -> Result<(), &'static str> { $eval; Ok(()) })) + } + } + }; + // instance actioning arm + (INSTANCE $name:ident { + $( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )* + } { + $( PRE { $pre_id:tt , $pre_ty:ty , $pre_ex:expr } )* + $( PARAM { $param:ident , $param_from:expr , $param_to:expr , $param_instancer:expr } )* + } { $eval:block } { $( $post:tt )* } ) => { + #[allow(non_camel_case_types)] + struct $name; + #[allow(unused_variables)] + impl, I: Instance> $crate::BenchmarkingSetupInstance for $name { + fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> { + vec! [ + $( + ($crate::BenchmarkParameter::$param, $param_from, $param_to) + ),* + ] + } + fn instance(&self, components: &[($crate::BenchmarkParameter, u32)]) -> Result Result<(), &'static str>>, &'static str> { @@ -372,7 +446,7 @@ macro_rules! benchmark_backend { #[macro_export] macro_rules! selected_benchmark { ( - $( $bench:ident ),* + NO_INSTANCE $( $bench:ident ),* ) => { // The list of available benchmarks for this pallet. #[allow(non_camel_case_types)] @@ -397,12 +471,38 @@ macro_rules! selected_benchmark { } } }; + ( + INSTANCE $( $bench:ident ),* + ) => { + // The list of available benchmarks for this pallet. + #[allow(non_camel_case_types)] + enum SelectedBenchmark { + $( $bench, )* + } + + // Allow us to select a benchmark from the list of available benchmarks. + impl, I: Instance> $crate::BenchmarkingSetupInstance for SelectedBenchmark { + fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> { + match self { + $( Self::$bench => <$bench as $crate::BenchmarkingSetupInstance>::components(&$bench), )* + } + } + + fn instance(&self, components: &[($crate::BenchmarkParameter, u32)]) + -> Result Result<(), &'static str>>, &'static str> + { + match self { + $( Self::$bench => <$bench as $crate::BenchmarkingSetupInstance>::instance(&$bench, components), )* + } + } + } + } } #[macro_export] macro_rules! impl_benchmark { ( - $( $name:ident ),* + NO_INSTANCE $( $name:ident ),* ) => { impl $crate::Benchmarking<$crate::BenchmarkResults> for Module { fn run_benchmark( @@ -492,5 +592,97 @@ macro_rules! impl_benchmark { return Ok(results); } } + }; + ( + INSTANCE $( $name:ident ),* + ) => { + impl, I: Instance> $crate::Benchmarking<$crate::BenchmarkResults> for Module { + fn run_benchmark( + extrinsic: Vec, + lowest_range_values: Vec, + highest_range_values: Vec, + steps: Vec, + repeat: u32, + ) -> Result, &'static str> { + // Map the input to the selected benchmark. + let extrinsic = sp_std::str::from_utf8(extrinsic.as_slice()) + .map_err(|_| "`extrinsic` is not a valid utf8 string!")?; + let selected_benchmark = match extrinsic { + $( stringify!($name) => SelectedBenchmark::$name, )* + _ => return Err("Could not find extrinsic."), + }; + + // Warm up the DB + $crate::benchmarking::commit_db(); + $crate::benchmarking::wipe_db(); + + let components = >::components(&selected_benchmark); + let mut results: Vec<$crate::BenchmarkResults> = Vec::new(); + + // Default number of steps for a component. + let mut prev_steps = 10; + + // Select the component we will be benchmarking. Each component will be benchmarked. + for (idx, (name, low, high)) in components.iter().enumerate() { + // Get the number of steps for this component. + let steps = steps.get(idx).cloned().unwrap_or(prev_steps); + prev_steps = steps; + + let lowest = lowest_range_values.get(idx).cloned().unwrap_or(*low); + let highest = highest_range_values.get(idx).cloned().unwrap_or(*high); + + let diff = highest - lowest; + + // Create up to `STEPS` steps for that component between high and low. + let step_size = (diff / steps).max(1); + let num_of_steps = diff / step_size + 1; + + for s in 0..num_of_steps { + // This is the value we will be testing for component `name` + let component_value = lowest + step_size * s; + + // Select the max value for all the other components. + let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter() + .enumerate() + .map(|(idx, (n, _, h))| + if n == name { + (*n, component_value) + } else { + (*n, *highest_range_values.get(idx).unwrap_or(h)) + } + ) + .collect(); + + // Run the benchmark `repeat` times. + for _ in 0..repeat { + // Set up the externalities environment for the setup we want to benchmark. + let closure_to_benchmark = >::instance(&selected_benchmark, &c)?; + + // Commit the externalities to the database, flushing the DB cache. + // This will enable worst case scenario for reading from the database. + $crate::benchmarking::commit_db(); + + // Time the extrinsic logic. + let start_extrinsic = $crate::benchmarking::current_time(); + closure_to_benchmark()?; + let finish_extrinsic = $crate::benchmarking::current_time(); + let elapsed_extrinsic = finish_extrinsic - start_extrinsic; + + // Time the storage root recalculation. + let start_storage_root = $crate::benchmarking::current_time(); + $crate::storage_root(); + let finish_storage_root = $crate::benchmarking::current_time(); + let elapsed_storage_root = finish_storage_root - start_storage_root; + + results.push((c.clone(), elapsed_extrinsic, elapsed_storage_root)); + + // Wipe the DB back to the genesis state. + $crate::benchmarking::wipe_db(); + } + } + } + return Ok(results); + } + } } } diff --git a/frame/benchmarking/src/utils.rs b/frame/benchmarking/src/utils.rs index bc6cfbcc86..122ef02997 100644 --- a/frame/benchmarking/src/utils.rs +++ b/frame/benchmarking/src/utils.rs @@ -101,6 +101,15 @@ pub trait BenchmarkingSetup { fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result Result<(), &'static str>>, &'static str>; } +/// The required setup for creating a benchmark. +pub trait BenchmarkingSetupInstance { + /// Return the components and their ranges which should be tested in this benchmark. + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)>; + + /// Set up the storage, and prepare a closure to test in a single run of the benchmark. + fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result Result<(), &'static str>>, &'static str>; +} + /// Grab an account, seeded by a name and index. pub fn account(name: &'static str, index: u32, seed: u32) -> AccountId { let entropy = (name, index, seed).using_encoded(blake2_256); diff --git a/frame/collective/Cargo.toml b/frame/collective/Cargo.toml index 4b037ab7c2..353a3873d5 100644 --- a/frame/collective/Cargo.toml +++ b/frame/collective/Cargo.toml @@ -15,6 +15,7 @@ sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../p sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } @@ -30,7 +31,9 @@ std = [ "sp-std/std", "serde", "sp-io/std", + "frame-benchmarking/std", "frame-support/std", "sp-runtime/std", "frame-system/std", ] +runtime-benchmarks = ["frame-benchmarking"] diff --git a/frame/collective/src/benchmarking.rs b/frame/collective/src/benchmarking.rs new file mode 100644 index 0000000000..51db4ee109 --- /dev/null +++ b/frame/collective/src/benchmarking.rs @@ -0,0 +1,185 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Staking pallet benchmarking. + +use super::*; + +use frame_system::RawOrigin as SystemOrigin; +use frame_benchmarking::{benchmarks_instance, account}; + +use frame_system::Module as System; +use crate::Module as Collective; + +const SEED: u32 = 0; + +benchmarks_instance! { + _{ + // User account seed. + let u in 1 .. 1000 => (); + // Old members. + let n in 1 .. 1000 => (); + // New members. + let m in 1 .. 1000 => (); + // Existing proposals. + let p in 1 .. 100 => (); + } + + set_members { + let m in ...; + let n in ...; + + // Construct `new_members`. + // It should influence timing since it will sort this vector. + let mut new_members = vec![]; + for i in 0 .. m { + let member = account("member", i, SEED); + new_members.push(member); + } + + // Set old members. + // We compute the difference of old and new members, so it should influence timing. + let mut old_members = vec![]; + for i in 0 .. n { + let old_member = account("old member", i, SEED); + old_members.push(old_member); + } + + let prime = Some(account("prime", 0, SEED)); + + Collective::::set_members(SystemOrigin::Root.into(), old_members, prime.clone())?; + + }: _(SystemOrigin::Root, new_members, prime) + + execute { + let u in ...; + + let caller: T::AccountId = account("caller", u, SEED); + let proposal: T::Proposal = Call::::close(Default::default(), Default::default()).into(); + + Collective::::set_members(SystemOrigin::Root.into(), vec![caller.clone()], None)?; + + }: _(SystemOrigin::Signed(caller), Box::new(proposal)) + + propose { + let u in ...; + + let caller: T::AccountId = account("caller", u, SEED); + let proposal: T::Proposal = Call::::close(Default::default(), Default::default()).into(); + + Collective::::set_members(SystemOrigin::Root.into(), vec![caller.clone()], None)?; + + let member_count = 0; + + }: _(SystemOrigin::Signed(caller), member_count, Box::new(proposal.into())) + + propose_else_branch { + let u in ...; + let p in ...; + + let caller: T::AccountId = account("caller", u, SEED); + let proposal: T::Proposal = Call::::close(Default::default(), Default::default()).into(); + + Collective::::set_members(SystemOrigin::Root.into(), vec![caller.clone()], None)?; + + let member_count = 3; + + // Add previous proposals. + for i in 0 .. p { + let proposal: T::Proposal = Call::::close(Default::default(), (i + 1).into()).into(); + Collective::::propose(SystemOrigin::Signed(caller.clone()).into(), member_count.clone(), Box::new(proposal.into()))?; + } + + }: propose(SystemOrigin::Signed(caller), member_count, Box::new(proposal.into())) + + vote { + let u in ...; + + let caller1: T::AccountId = account("caller1", u, SEED); + let caller2: T::AccountId = account("caller2", u, SEED); + + let proposal: Box = Box::new(Call::::close(Default::default(), Default::default()).into()); + let proposal_hash = T::Hashing::hash_of(&proposal); + + Collective::::set_members(SystemOrigin::Root.into(), vec![caller1.clone(), caller2.clone()], None)?; + + let member_count = 3; + Collective::::propose(SystemOrigin::Signed(caller1.clone()).into(), member_count, proposal)?; + + let index = 0; + let approve = true; + + }: _(SystemOrigin::Signed(caller2), proposal_hash, index, approve) + + vote_not_approve { + let u in ...; + + let caller1: T::AccountId = account("caller1", u, SEED); + let caller2: T::AccountId = account("caller2", u, SEED); + + let proposal: Box = Box::new(Call::::close(Default::default(), Default::default()).into()); + let proposal_hash = T::Hashing::hash_of(&proposal); + + Collective::::set_members(SystemOrigin::Root.into(), vec![caller1.clone(), caller2.clone()], None)?; + + let member_count = 3; + Collective::::propose(SystemOrigin::Signed(caller1.clone()).into(), member_count, proposal)?; + + let index = 0; + let approve = false; + + }: vote(SystemOrigin::Signed(caller2), proposal_hash, index, approve) + + vote_approved { + let u in ...; + + let caller1: T::AccountId = account("caller1", u, SEED); + let caller2: T::AccountId = account("caller2", u, SEED); + + let proposal: Box = Box::new(Call::::close(Default::default(), Default::default()).into()); + let proposal_hash = T::Hashing::hash_of(&proposal); + + Collective::::set_members(SystemOrigin::Root.into(), vec![caller1.clone(), caller2.clone()], None)?; + + let member_count = 2; + Collective::::propose(SystemOrigin::Signed(caller1.clone()).into(), member_count, proposal)?; + + let index = 0; + let approve = true; + + }: vote(SystemOrigin::Signed(caller2), proposal_hash, index, approve) + + close { + let u in ...; + + let caller1: T::AccountId = account("caller1", u, SEED); + let caller2: T::AccountId = account("caller2", u, SEED); + + let proposal: Box = Box::new(Call::::close(Default::default(), Default::default()).into()); + let proposal_hash = T::Hashing::hash_of(&proposal); + + Collective::::set_members(SystemOrigin::Root.into(), vec![caller1.clone(), caller2.clone()], None)?; + let member_count = 2; + Collective::::propose(SystemOrigin::Signed(caller1.clone()).into(), member_count, proposal)?; + + let index = 0; + let approve = true; + + let vote_end = T::MotionDuration::get() + 1u32.into(); + System::::set_block_number(vote_end); + + }: _(SystemOrigin::Signed(caller2), proposal_hash, index) +} diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 0f5a16ed7a..84bb76cfd0 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -48,6 +48,9 @@ use frame_support::{ }; use frame_system::{self as system, ensure_signed, ensure_root}; +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + /// Simple index type for proposal counting. pub type ProposalIndex = u32; @@ -57,12 +60,12 @@ pub type ProposalIndex = u32; /// vote exactly once, therefore also the number of votes for any given motion. pub type MemberCount = u32; -pub trait Trait: frame_system::Trait { +pub trait Trait: frame_system::Trait { /// The outer origin type. type Origin: From>; /// The outer call dispatch type. - type Proposal: Parameter + Dispatchable>::Origin>; + type Proposal: Parameter + Dispatchable>::Origin> + From>; /// The outer event type. type Event: From> + Into<::Event>; -- GitLab From e7f974eb505ae31b18229b02f078e17ee620ba81 Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Tue, 24 Mar 2020 18:07:28 +0100 Subject: [PATCH 063/300] add cargo-deny job (#5347) * add cargo-deny job * feat(ci): add cargo-deny CI job, checks registries, licenses, dependencies dupes and advisories --- .gitlab-ci.yml | 16 +++- .maintain/deny.toml | 193 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 .maintain/deny.toml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 962ecbe3e4..549e8f42fb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -145,6 +145,20 @@ cargo-audit: - cargo audit allow_failure: true +cargo-deny: + stage: test + <<: *docker-env + script: + - cargo deny check --hide-inclusion-graph -c .maintain/deny.toml + after_script: + - echo "___The complete log is in the artifacts___" + - cargo deny check -c .maintain/deny.toml 2> deny.log + artifacts: + name: $CI_COMMIT_SHORT_SHA + expire_in: 3 days + when: always + paths: + - deny.log cargo-check-benches: stage: test @@ -176,7 +190,7 @@ test-linux-stable: &test-linux variables: - $DEPLOY_TAG script: - - WASM_BUILD_NO_COLOR=1 time cargo test --all --release --verbose --locked | + - WASM_BUILD_NO_COLOR=1 time cargo test --all --release --verbose --locked |& tee output.log - sccache -s after_script: diff --git a/.maintain/deny.toml b/.maintain/deny.toml new file mode 100644 index 0000000000..8cc7635d50 --- /dev/null +++ b/.maintain/deny.toml @@ -0,0 +1,193 @@ +# This template contains all of the possible sections and their default values + +# Note that all fields that take a lint level have these possible values: +# * deny - An error will be produced and the check will fail +# * warn - A warning will be produced, but the check will not fail +# * allow - No warning or error will be produced, though in some cases a note +# will be + +# The values provided in this template are the default values that will be used +# when any section or field is not specified in your own configuration + +# If 1 or more target triples (and optionally, target_features) are specified, +# only the specified targets will be checked when running `cargo deny check`. +# This means, if a particular package is only ever used as a target specific +# dependency, such as, for example, the `nix` crate only being used via the +# `target_family = "unix"` configuration, that only having windows targets in +# this list would mean the nix crate, as well as any of its exclusive +# dependencies not shared by any other crates, would be ignored, as the target +# list here is effectively saying which targets you are building for. +targets = [ + # The triple can be any string, but only the target triples built in to + # rustc (as of 1.40) can be checked against actual config expressions + #{ triple = "x86_64-unknown-linux-musl" }, + # You can also specify which target_features you promise are enabled for a + # particular target. target_features are currently not validated against + # the actual valid features supported by the target architecture. + #{ triple = "wasm32-unknown-unknown", features = ["atomics"] }, +] + +# This section is considered when running `cargo deny check advisories` +# More documentation for the advisories section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html +[advisories] +# The path where the advisory database is cloned/fetched into +db-path = "~/.cargo/advisory-db" +# The url of the advisory database to use +db-url = "https://github.com/rustsec/advisory-db" +# The lint level for security vulnerabilities +vulnerability = "deny" +# The lint level for unmaintained crates +unmaintained = "warn" +# The lint level for crates that have been yanked from their source registry +yanked = "warn" +# The lint level for crates with security notices. Note that as of +# 2019-12-17 there are no security notice advisories in +# https://github.com/rustsec/advisory-db +notice = "warn" +# A list of advisory IDs to ignore. Note that ignored advisories will still +# output a note when they are encountered. +ignore = [ + #"RUSTSEC-0000-0000", +] +# Threshold for security vulnerabilities, any vulnerability with a CVSS score +# lower than the range specified will be ignored. Note that ignored advisories +# will still output a note when they are encountered. +# * None - CVSS Score 0.0 +# * Low - CVSS Score 0.1 - 3.9 +# * Medium - CVSS Score 4.0 - 6.9 +# * High - CVSS Score 7.0 - 8.9 +# * Critical - CVSS Score 9.0 - 10.0 +#severity-threshold = + +# This section is considered when running `cargo deny check licenses` +# More documentation for the licenses section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html +[licenses] +# The lint level for crates which do not have a detectable license +unlicensed = "deny" +# List of explictly allowed licenses +# See https://spdx.org/licenses/ for list of possible licenses +# [possible values: any SPDX 3.7 short identifier (+ optional exception)]. +allow = [ + #"MIT", + #"Apache-2.0", + #"Apache-2.0 WITH LLVM-exception", +] +# List of explictly disallowed licenses +# See https://spdx.org/licenses/ for list of possible licenses +# [possible values: any SPDX 3.7 short identifier (+ optional exception)]. +deny = [ + #"Nokia", +] +# Lint level for licenses considered copyleft +copyleft = "allow" +# Blanket approval or denial for OSI-approved or FSF Free/Libre licenses +# * both - The license will be approved if it is both OSI-approved *AND* FSF +# * either - The license will be approved if it is either OSI-approved *OR* FSF +# * osi-only - The license will be approved if is OSI-approved *AND NOT* FSF +# * fsf-only - The license will be approved if is FSF *AND NOT* OSI-approved +# * neither - This predicate is ignored and the default lint level is used +allow-osi-fsf-free = "either" +# Lint level used when no other predicates are matched +# 1. License isn't in the allow or deny lists +# 2. License isn't copyleft +# 3. License isn't OSI/FSF, or allow-osi-fsf-free = "neither" +default = "deny" +# The confidence threshold for detecting a license from license text. +# The higher the value, the more closely the license text must be to the +# canonical license text of a valid SPDX license file. +# [possible values: any between 0.0 and 1.0]. +confidence-threshold = 0.9 +# Allow 1 or more licenses on a per-crate basis, so that particular licenses +# aren't accepted for every possible crate as with the normal allow list +exceptions = [ + # Each entry is the crate and version constraint, and its specific allow + # list + #{ allow = ["Zlib"], name = "adler32", version = "*" }, +] + +# Some crates don't have (easily) machine readable licensing information, +# adding a clarification entry for it allows you to manually specify the +# licensing information +[[licenses.clarify]] +# The name of the crate the clarification applies to +name = "ring" +# THe optional version constraint for the crate +#version = "*" +# The SPDX expression for the license requirements of the crate +expression = "OpenSSL" +# One or more files in the crate's source used as the "source of truth" for +# the license expression. If the contents match, the clarification will be used +# when running the license check, otherwise the clarification will be ignored +# and the crate will be checked normally, which may produce warnings or errors +# depending on the rest of your configuration +license-files = [ + # Each entry is a crate relative path, and the (opaque) hash of its contents + { path = "LICENSE", hash = 0xbd0eed23 } +] +[[licenses.clarify]] +name = "webpki" +expression = "ISC" +license-files = [{ path = "LICENSE", hash = 0x001c7e6c }] + +[licenses.private] +# If true, ignores workspace crates that aren't published, or are only +# published to private registries +ignore = false +# One or more private registries that you might publish crates to, if a crate +# is only published to private registries, and ignore is true, the crate will +# not have its license(s) checked +registries = [ + #"https://sekretz.com/registry +] + +# This section is considered when running `cargo deny check bans`. +# More documentation about the 'bans' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html +[bans] +# Lint level for when multiple versions of the same crate are detected +multiple-versions = "warn" +# The graph highlighting used when creating dotgraphs for crates +# with multiple versions +# * lowest-version - The path to the lowest versioned duplicate is highlighted +# * simplest-path - The path to the version with the fewest edges is highlighted +# * all - Both lowest-version and simplest-path are used +highlight = "lowest-version" +# List of crates that are allowed. Use with care! +allow = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +# List of crates to deny +deny = [ + { name = "parity-util-mem", version = "<0.6" } + # Each entry the name of a crate and a version range. If version is + # not specified, all versions will be matched. +] +# Certain crates/versions that will be skipped when doing duplicate detection. +skip = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +# Similarly to `skip` allows you to skip certain crates during duplicate +# detection. Unlike skip, it also includes the entire tree of transitive +# dependencies starting at the specified crate, up to a certain depth, which is +# by default infinite +skip-tree = [ + #{ name = "ansi_term", version = "=0.11.0", depth = 20 }, +] + +# This section is considered when running `cargo deny check sources`. +# More documentation about the 'sources' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html +[sources] +# Lint level for what to happen when a crate from a crate registry that is not +# in the allow list is encountered +unknown-registry = "deny" +# Lint level for what to happen when a crate from a git repository that is not +# in the allow list is encountered +unknown-git = "warn" +# List of URLs for allowed crate registries. Defaults to the crates.io index +# if not specified. If it is specified but empty, no registries are allowed. +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +# List of URLs for allowed Git repositories +allow-git = [] -- GitLab From 468432099d8e2ac3a1597a75035c8443d0156513 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 24 Mar 2020 18:07:51 +0100 Subject: [PATCH 064/300] Split PrimaryPreDigest and SecondaryPreDigest (#5373) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Split PrimaryPreDigest and SecondaryPreDigest * Update client/consensus/babe/src/lib.rs Co-Authored-By: André Silva * Update primitives/consensus/babe/src/digests.rs Co-Authored-By: André Silva * Update primitives/consensus/babe/src/digests.rs Co-Authored-By: André Silva * Update primitives/consensus/babe/src/digests.rs Co-Authored-By: André Silva Co-authored-by: André Silva --- client/consensus/babe/src/authorship.rs | 10 +-- client/consensus/babe/src/lib.rs | 8 +- client/consensus/babe/src/tests.rs | 4 +- client/consensus/babe/src/verification.rs | 39 ++++----- frame/babe/src/lib.rs | 11 +-- frame/babe/src/tests.rs | 14 +-- primitives/consensus/babe/src/digests.rs | 99 +++++++++++++--------- primitives/consensus/vrf/src/schnorrkel.rs | 1 + 8 files changed, 98 insertions(+), 88 deletions(-) diff --git a/client/consensus/babe/src/authorship.rs b/client/consensus/babe/src/authorship.rs index fb7be52766..074e582bff 100644 --- a/client/consensus/babe/src/authorship.rs +++ b/client/consensus/babe/src/authorship.rs @@ -21,7 +21,7 @@ use sp_consensus_babe::{ AuthorityId, BabeAuthorityWeight, BABE_ENGINE_ID, BABE_VRF_PREFIX, SlotNumber, AuthorityPair, BabeConfiguration }; -use sp_consensus_babe::digests::PreDigest; +use sp_consensus_babe::digests::{PreDigest, PrimaryPreDigest, SecondaryPreDigest}; use sp_consensus_vrf::schnorrkel::{VRFOutput, VRFProof}; use sp_core::{U256, blake2_256}; use codec::Encode; @@ -128,10 +128,10 @@ fn claim_secondary_slot( }) { if pair.public() == *expected_author { - let pre_digest = PreDigest::Secondary { + let pre_digest = PreDigest::Secondary(SecondaryPreDigest { slot_number, authority_index: authority_index as u32, - }; + }); return Some((pre_digest, pair)); } @@ -200,12 +200,12 @@ fn claim_primary_slot( let pre_digest = get_keypair(&pair) .vrf_sign_after_check(transcript, |inout| super::authorship::check_primary_threshold(inout, threshold)) .map(|s| { - PreDigest::Primary { + PreDigest::Primary(PrimaryPreDigest { slot_number, vrf_output: VRFOutput(s.0.to_output()), vrf_proof: VRFProof(s.1), authority_index: authority_index as u32, - } + }) }); // early exit on first successful claim diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index f4373da47f..6ce9fc7e72 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -62,7 +62,9 @@ pub use sp_consensus_babe::{ BabeApi, ConsensusLog, BABE_ENGINE_ID, SlotNumber, BabeConfiguration, AuthorityId, AuthorityPair, AuthoritySignature, BabeAuthorityWeight, VRF_OUTPUT_LENGTH, - digests::{PreDigest, CompatibleDigestItem, NextEpochDescriptor}, + digests::{ + CompatibleDigestItem, NextEpochDescriptor, PreDigest, PrimaryPreDigest, SecondaryPreDigest, + }, }; pub use sp_consensus::SyncOracle; use std::{ @@ -580,10 +582,10 @@ fn find_pre_digest(header: &B::Header) -> Result> // genesis block doesn't contain a pre digest so let's generate a // dummy one to not break any invariants in the rest of the code if header.number().is_zero() { - return Ok(PreDigest::Secondary { + return Ok(PreDigest::Secondary(SecondaryPreDigest { slot_number: 0, authority_index: 0, - }); + })); } let mut pre_digest: Option<_> = None; diff --git a/client/consensus/babe/src/tests.rs b/client/consensus/babe/src/tests.rs index ec5a6032f5..20b924669d 100644 --- a/client/consensus/babe/src/tests.rs +++ b/client/consensus/babe/src/tests.rs @@ -553,10 +553,10 @@ fn propose_and_import_block( let pre_digest = sp_runtime::generic::Digest { logs: vec![ Item::babe_pre_digest( - PreDigest::Secondary { + PreDigest::Secondary(SecondaryPreDigest { authority_index: 0, slot_number, - }, + }), ), ], }; diff --git a/client/consensus/babe/src/verification.rs b/client/consensus/babe/src/verification.rs index 1eb73588a8..2fd37280b3 100644 --- a/client/consensus/babe/src/verification.rs +++ b/client/consensus/babe/src/verification.rs @@ -17,9 +17,10 @@ //! Verification for BABE headers. use sp_runtime::{traits::Header, traits::DigestItemFor}; use sp_core::{Pair, Public}; -use sp_consensus_babe::{AuthoritySignature, SlotNumber, AuthorityIndex, AuthorityPair, AuthorityId}; -use sp_consensus_babe::digests::{PreDigest, CompatibleDigestItem}; -use sp_consensus_vrf::schnorrkel::{VRFOutput, VRFProof}; +use sp_consensus_babe::{AuthoritySignature, SlotNumber, AuthorityPair, AuthorityId}; +use sp_consensus_babe::digests::{ + PreDigest, PrimaryPreDigest, SecondaryPreDigest, CompatibleDigestItem +}; use sc_consensus_slots::CheckedHeader; use log::{debug, trace}; use super::{find_pre_digest, babe_err, Epoch, BlockT, Error}; @@ -93,27 +94,23 @@ pub(super) fn check_header( }; match &pre_digest { - PreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number } => { + PreDigest::Primary(primary) => { debug!(target: "babe", "Verifying Primary block"); - let digest = (vrf_output, vrf_proof, *authority_index, *slot_number); - check_primary_header::( pre_hash, - digest, + primary, sig, &epoch, config.c, )?; }, - PreDigest::Secondary { authority_index, slot_number } if config.secondary_slots => { + PreDigest::Secondary(secondary) if config.secondary_slots => { debug!(target: "babe", "Verifying Secondary block"); - let digest = (*authority_index, *slot_number); - check_secondary_header::( pre_hash, - digest, + secondary, sig, &epoch, )?; @@ -143,25 +140,23 @@ pub(super) struct VerifiedHeaderInfo { /// its parent since it is a primary block. fn check_primary_header( pre_hash: B::Hash, - pre_digest: (&VRFOutput, &VRFProof, AuthorityIndex, SlotNumber), + pre_digest: &PrimaryPreDigest, signature: AuthoritySignature, epoch: &Epoch, c: (u64, u64), ) -> Result<(), Error> { - let (vrf_output, vrf_proof, authority_index, slot_number) = pre_digest; - - let author = &epoch.authorities[authority_index as usize].0; + let author = &epoch.authorities[pre_digest.authority_index as usize].0; if AuthorityPair::verify(&signature, pre_hash, &author) { let (inout, _) = { let transcript = make_transcript( &epoch.randomness, - slot_number, + pre_digest.slot_number, epoch.epoch_index, ); schnorrkel::PublicKey::from_bytes(author.as_slice()).and_then(|p| { - p.vrf_verify(transcript, vrf_output, vrf_proof) + p.vrf_verify(transcript, &pre_digest.vrf_output, &pre_digest.vrf_proof) }).map_err(|s| { babe_err(Error::VRFVerificationFailed(s)) })? @@ -170,7 +165,7 @@ fn check_primary_header( let threshold = calculate_primary_threshold( c, &epoch.authorities, - authority_index as usize, + pre_digest.authority_index as usize, ); if !check_primary_threshold(&inout, threshold) { @@ -189,21 +184,19 @@ fn check_primary_header( /// compared to its parent since it is a secondary block. fn check_secondary_header( pre_hash: B::Hash, - pre_digest: (AuthorityIndex, SlotNumber), + pre_digest: &SecondaryPreDigest, signature: AuthoritySignature, epoch: &Epoch, ) -> Result<(), Error> { - let (authority_index, slot_number) = pre_digest; - // check the signature is valid under the expected authority and // chain state. let expected_author = secondary_slot_author( - slot_number, + pre_digest.slot_number, &epoch.authorities, epoch.randomness, ).ok_or_else(|| Error::NoSecondaryAuthorExpected)?; - let author = &epoch.authorities[authority_index as usize].0; + let author = &epoch.authorities[pre_digest.authority_index as usize].0; if expected_author != author { return Err(Error::InvalidAuthor(expected_author.clone(), author.clone())); diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 27a471f6f8..51c1bdb553 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -209,12 +209,7 @@ impl FindAuthor for Module { for (id, mut data) in digests.into_iter() { if id == BABE_ENGINE_ID { let pre_digest: RawPreDigest = RawPreDigest::decode(&mut data).ok()?; - return Some(match pre_digest { - RawPreDigest::Primary { authority_index, .. } => - authority_index, - RawPreDigest::Secondary { authority_index, .. } => - authority_index, - }); + return Some(pre_digest.authority_index()) } } @@ -426,11 +421,11 @@ impl Module { CurrentSlot::put(digest.slot_number()); - if let RawPreDigest::Primary { vrf_output, .. } = digest { + if let RawPreDigest::Primary(primary) = digest { // place the VRF output into the `Initialized` storage item // and it'll be put onto the under-construction randomness // later, once we've decided which epoch this block is in. - Some(vrf_output) + Some(primary.vrf_output) } else { None } diff --git a/frame/babe/src/tests.rs b/frame/babe/src/tests.rs index 3fcb78ae5f..c13d77c116 100644 --- a/frame/babe/src/tests.rs +++ b/frame/babe/src/tests.rs @@ -35,12 +35,14 @@ fn make_pre_digest( vrf_output: RawVRFOutput, vrf_proof: RawVRFProof, ) -> Digest { - let digest_data = sp_consensus_babe::digests::RawPreDigest::Primary { - authority_index, - slot_number, - vrf_output, - vrf_proof, - }; + let digest_data = sp_consensus_babe::digests::RawPreDigest::Primary( + sp_consensus_babe::digests::RawPrimaryPreDigest { + authority_index, + slot_number, + vrf_output, + vrf_proof, + } + ); let log = DigestItem::PreRuntime(sp_consensus_babe::BABE_ENGINE_ID, digest_data.encode()); Digest { logs: vec![log] } } diff --git a/primitives/consensus/babe/src/digests.rs b/primitives/consensus/babe/src/digests.rs index fca0c3a7b3..6079aa88c8 100644 --- a/primitives/consensus/babe/src/digests.rs +++ b/primitives/consensus/babe/src/digests.rs @@ -27,40 +27,67 @@ use codec::{Decode, Encode}; #[cfg(feature = "std")] use codec::Codec; use sp_std::vec::Vec; +use sp_runtime::RuntimeDebug; use sp_consensus_vrf::schnorrkel::{self, Randomness}; #[cfg(feature = "std")] use sp_consensus_vrf::schnorrkel::SignatureError; +/// Raw BABE primary slot assignment pre-digest. +#[derive(Clone, RuntimeDebug, Encode, Decode)] +pub struct RawPrimaryPreDigest { + /// Authority index + pub authority_index: super::AuthorityIndex, + /// Slot number + pub slot_number: SlotNumber, + /// VRF output + pub vrf_output: VRFOutput, + /// VRF proof + pub vrf_proof: VRFProof, +} + +#[cfg(feature = "std")] +/// BABE primary slot assignment pre-digest for std environment. +pub type PrimaryPreDigest = RawPrimaryPreDigest; + +#[cfg(feature = "std")] +impl TryFrom for PrimaryPreDigest { + type Error = SignatureError; + + fn try_from(raw: RawPrimaryPreDigest) -> Result { + Ok(PrimaryPreDigest { + authority_index: raw.authority_index, + slot_number: raw.slot_number, + vrf_output: raw.vrf_output.try_into()?, + vrf_proof: raw.vrf_proof.try_into()?, + }) + } +} + +/// BABE secondary slot assignment pre-digest. +#[derive(Clone, RuntimeDebug, Encode, Decode)] +pub struct SecondaryPreDigest { + /// Authority index + /// + /// This is not strictly-speaking necessary, since the secondary slots + /// are assigned based on slot number and epoch randomness. But including + /// it makes things easier for higher-level users of the chain data to + /// be aware of the author of a secondary-slot block. + pub authority_index: super::AuthorityIndex, + /// Slot number + pub slot_number: SlotNumber, +} + /// A BABE pre-runtime digest. This contains all data required to validate a /// block and for the BABE runtime module. Slots can be assigned to a primary /// (VRF based) and to a secondary (slot number based). -#[derive(Clone, Debug, Encode, Decode)] +#[derive(Clone, RuntimeDebug, Encode, Decode)] pub enum RawPreDigest { /// A primary VRF-based slot assignment. #[codec(index = "1")] - Primary { - /// Authority index - authority_index: super::AuthorityIndex, - /// Slot number - slot_number: SlotNumber, - /// VRF output - vrf_output: VRFOutput, - /// VRF proof - vrf_proof: VRFProof, - }, + Primary(RawPrimaryPreDigest), /// A secondary deterministic slot assignment. #[codec(index = "2")] - Secondary { - /// Authority index - /// - /// This is not strictly-speaking necessary, since the secondary slots - /// are assigned based on slot number and epoch randomness. But including - /// it makes things easier for higher-level users of the chain data to - /// be aware of the author of a secondary-slot block. - authority_index: super::AuthorityIndex, - /// Slot number - slot_number: SlotNumber, - }, + Secondary(SecondaryPreDigest), } #[cfg(feature = "std")] @@ -71,16 +98,16 @@ impl RawPreDigest { /// Returns the slot number of the pre digest. pub fn authority_index(&self) -> AuthorityIndex { match self { - RawPreDigest::Primary { authority_index, .. } => *authority_index, - RawPreDigest::Secondary { authority_index, .. } => *authority_index, + RawPreDigest::Primary(primary) => primary.authority_index, + RawPreDigest::Secondary(secondary) => secondary.authority_index, } } /// Returns the slot number of the pre digest. pub fn slot_number(&self) -> SlotNumber { match self { - RawPreDigest::Primary { slot_number, .. } => *slot_number, - RawPreDigest::Secondary { slot_number, .. } => *slot_number, + RawPreDigest::Primary(primary) => primary.slot_number, + RawPreDigest::Secondary(secondary) => secondary.slot_number, } } @@ -88,8 +115,8 @@ impl RawPreDigest { /// of the chain. pub fn added_weight(&self) -> crate::BabeBlockWeight { match self { - RawPreDigest::Primary { .. } => 1, - RawPreDigest::Secondary { .. } => 0, + RawPreDigest::Primary(_) => 1, + RawPreDigest::Secondary(_) => 0, } } } @@ -100,25 +127,15 @@ impl TryFrom for PreDigest { fn try_from(raw: RawPreDigest) -> Result { Ok(match raw { - RawPreDigest::Primary { authority_index, slot_number, vrf_output, vrf_proof } => - RawPreDigest::Primary { - authority_index, - slot_number, - vrf_output: vrf_output.try_into()?, - vrf_proof: vrf_proof.try_into()?, - }, - RawPreDigest::Secondary { authority_index, slot_number } => - RawPreDigest::Secondary { - authority_index, - slot_number, - } + RawPreDigest::Primary(primary) => PreDigest::Primary(primary.try_into()?), + RawPreDigest::Secondary(secondary) => PreDigest::Secondary(secondary), }) } } /// Information about the next epoch. This is broadcast in the first block /// of the epoch. -#[derive(Decode, Encode, Default, PartialEq, Eq, Clone, sp_runtime::RuntimeDebug)] +#[derive(Decode, Encode, Default, PartialEq, Eq, Clone, RuntimeDebug)] pub struct NextEpochDescriptor { /// The authorities. pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, diff --git a/primitives/consensus/vrf/src/schnorrkel.rs b/primitives/consensus/vrf/src/schnorrkel.rs index e4ae68ced4..635160aa00 100644 --- a/primitives/consensus/vrf/src/schnorrkel.rs +++ b/primitives/consensus/vrf/src/schnorrkel.rs @@ -17,6 +17,7 @@ //! Schnorrkel-based VRF. use codec::{Encode, Decode}; +#[cfg(feature = "std")] use sp_core::U512; use sp_runtime::RuntimeDebug; use sp_std::ops::{Deref, DerefMut}; -- GitLab From 6ce091737dc7f114dd420f8b879f8a467c1d501b Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 24 Mar 2020 19:51:04 +0100 Subject: [PATCH 065/300] on_initialize return weight consumed and default cost to default DispatchInfo instead of zero (#5382) * frame update * doc * move offchain worker trait also * fix weigh merge * indentation * reorder for better git diff * comment * fix benchmark * remove test --- bin/node/runtime/src/lib.rs | 33 +-- frame/authorship/src/lib.rs | 6 +- frame/babe/src/lib.rs | 9 +- frame/babe/src/tests.rs | 3 +- frame/democracy/src/lib.rs | 10 +- frame/elections-phragmen/src/lib.rs | 13 +- frame/elections/src/lib.rs | 5 +- frame/example/src/lib.rs | 18 +- frame/executive/src/lib.rs | 39 ++- frame/finality-tracker/src/lib.rs | 6 +- frame/grandpa/src/tests.rs | 3 +- frame/im-online/src/tests.rs | 2 +- frame/indices/src/lib.rs | 5 +- frame/offences/src/lib.rs | 5 +- frame/randomness-collective-flip/src/lib.rs | 15 +- frame/recovery/src/mock.rs | 3 +- frame/scored-pool/src/lib.rs | 4 +- frame/scored-pool/src/tests.rs | 4 +- frame/session/src/historical.rs | 4 +- frame/session/src/lib.rs | 14 +- frame/session/src/tests.rs | 4 +- frame/society/src/lib.rs | 6 +- frame/society/src/mock.rs | 6 +- frame/staking/src/mock.rs | 5 +- frame/staking/src/tests.rs | 4 +- frame/support/src/dispatch.rs | 274 ++++++++------------ frame/support/src/traits.rs | 93 ++++++- frame/support/src/weights.rs | 42 +-- frame/treasury/src/benchmarking.rs | 2 +- frame/treasury/src/lib.rs | 6 +- frame/treasury/src/tests.rs | 8 +- primitives/runtime/src/traits.rs | 45 ---- 32 files changed, 331 insertions(+), 365 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 319c0f4618..7bb230ec0f 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -935,6 +935,7 @@ impl_runtime_apis! { mod tests { use super::*; use frame_system::offchain::{SignAndSubmitTransaction, SubmitSignedTransaction}; + use frame_support::traits::OnInitialize; #[test] fn validate_transaction_submitter_bounds() { @@ -958,36 +959,4 @@ mod tests { is_submit_signed_transaction::(); is_sign_and_submit_transaction::(); } - - #[test] - fn block_hooks_weight_should_not_exceed_limits() { - use frame_support::weights::WeighBlock; - let check_for_block = |b| { - let block_hooks_weight = - >::on_initialize(b) + - >::on_finalize(b); - - assert_eq!( - block_hooks_weight, - 0, - "This test might fail simply because the value being compared to has increased to a \ - module declaring a new weight for a hook or call. In this case update the test and \ - happily move on.", - ); - - // Invariant. Always must be like this to have a sane chain. - assert!(block_hooks_weight < MaximumBlockWeight::get()); - - // Warning. - if block_hooks_weight > MaximumBlockWeight::get() / 2 { - println!( - "block hooks weight is consuming more than a block's capacity. You probably want \ - to re-think this. This test will fail now." - ); - assert!(false); - } - }; - - let _ = (0..100_000).for_each(check_for_block); - } } diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index d3c1bf752a..d71a71e5bf 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -27,7 +27,7 @@ use frame_support::traits::{FindAuthor, VerifySeal, Get}; use codec::{Encode, Decode}; use frame_system::ensure_none; use sp_runtime::traits::{Header as HeaderT, One, Zero}; -use frame_support::weights::SimpleDispatchInfo; +use frame_support::weights::{Weight, SimpleDispatchInfo, WeighData}; use sp_inherents::{InherentIdentifier, ProvideInherent, InherentData}; use sp_authorship::{INHERENT_IDENTIFIER, UnclesInherentData, InherentError}; @@ -185,7 +185,7 @@ decl_module! { pub struct Module for enum Call where origin: T::Origin { type Error = Error; - fn on_initialize(now: T::BlockNumber) { + fn on_initialize(now: T::BlockNumber) -> Weight { let uncle_generations = T::UncleGenerations::get(); // prune uncles that are older than the allowed number of generations. if uncle_generations <= now { @@ -196,6 +196,8 @@ decl_module! { ::DidSetUncles::put(false); T::EventHandler::note_author(Self::author()); + + SimpleDispatchInfo::default().weigh_data(()) } fn on_finalize() { diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 51c1bdb553..29b6eb00a3 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -23,7 +23,10 @@ pub use pallet_timestamp; use sp_std::{result, prelude::*}; -use frame_support::{decl_storage, decl_module, traits::{FindAuthor, Get, Randomness as RandomnessT}}; +use frame_support::{ + decl_storage, decl_module, traits::{FindAuthor, Get, Randomness as RandomnessT}, + weights::{Weight, SimpleDispatchInfo, WeighData}, +}; use sp_timestamp::OnTimestampSet; use sp_runtime::{generic::DigestItem, ConsensusEngineId, Perbill, PerThing}; use sp_runtime::traits::{IsMember, SaturatedConversion, Saturating, Hash}; @@ -171,8 +174,10 @@ decl_module! { const ExpectedBlockTime: T::Moment = T::ExpectedBlockTime::get(); /// Initialization - fn on_initialize(now: T::BlockNumber) { + fn on_initialize(now: T::BlockNumber) -> Weight { Self::do_initialize(now); + + SimpleDispatchInfo::default().weigh_data(()) } /// Block finalization diff --git a/frame/babe/src/tests.rs b/frame/babe/src/tests.rs index c13d77c116..5769b1235c 100644 --- a/frame/babe/src/tests.rs +++ b/frame/babe/src/tests.rs @@ -17,8 +17,9 @@ //! Consensus extension module tests for BABE consensus. use super::*; +use frame_support::traits::OnFinalize; use mock::{new_test_ext, Babe, System}; -use sp_runtime::{traits::OnFinalize, testing::{Digest, DigestItem}}; +use sp_runtime::testing::{Digest, DigestItem}; use sp_consensus_vrf::schnorrkel::{RawVRFOutput, RawVRFProof}; use pallet_session::ShouldEndSession; diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index 32371c8a3a..a4366c4ef2 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -170,7 +170,7 @@ use sp_runtime::{ use codec::{Ref, Decode}; use frame_support::{ decl_module, decl_storage, decl_event, decl_error, ensure, Parameter, - weights::SimpleDispatchInfo, + weights::{SimpleDispatchInfo, Weight, WeighData}, traits::{ Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, OnUnbalanced, BalanceStatus @@ -499,8 +499,10 @@ decl_module! { fn deposit_event() = default; - fn on_runtime_upgrade() { + fn on_runtime_upgrade() -> Weight { Self::migrate(); + + SimpleDispatchInfo::default().weigh_data(()) } /// Propose a sensitive action to be taken. @@ -813,10 +815,12 @@ decl_module! { >::put(items); } - fn on_initialize(n: T::BlockNumber) { + fn on_initialize(n: T::BlockNumber) -> Weight { if let Err(e) = Self::begin_block(n) { sp_runtime::print(e); } + + SimpleDispatchInfo::default().weigh_data(()) } /// Specify a proxy that is already open to us. Called by the stash. diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index d74fb4bdcd..0030f2608f 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -87,8 +87,9 @@ use sp_runtime::{ print, DispatchResult, DispatchError, Perbill, traits::{Zero, StaticLookup, Convert}, }; use frame_support::{ - decl_storage, decl_event, ensure, decl_module, decl_error, weights::SimpleDispatchInfo, - storage::{StorageMap, IterableStorageMap}, traits::{ + decl_storage, decl_event, ensure, decl_module, decl_error, + weights::{SimpleDispatchInfo, Weight, WeighData}, storage::{StorageMap, IterableStorageMap}, + traits::{ Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons, ChangeMembers, OnUnbalanced, WithdrawReason, Contains, BalanceStatus } @@ -223,8 +224,10 @@ decl_module! { fn deposit_event() = default; - fn on_runtime_upgrade() { + fn on_runtime_upgrade() -> Weight { migration::migrate::(); + + SimpleDispatchInfo::default().weigh_data(()) } const CandidacyBond: BalanceOf = T::CandidacyBond::get(); @@ -461,11 +464,13 @@ decl_module! { } /// What to do at the end of each block. Checks if an election needs to happen or not. - fn on_initialize(n: T::BlockNumber) { + fn on_initialize(n: T::BlockNumber) -> Weight { if let Err(e) = Self::end_block(n) { print("Guru meditation"); print(e); } + + SimpleDispatchInfo::default().weigh_data(()) } } } diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index 6f89c4b938..a8ea0b8c2e 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -30,7 +30,7 @@ use sp_runtime::{ }; use frame_support::{ decl_storage, decl_event, ensure, decl_module, decl_error, - weights::SimpleDispatchInfo, + weights::{Weight, SimpleDispatchInfo, WeighData}, traits::{ Currency, ExistenceRequirement, Get, LockableCurrency, LockIdentifier, BalanceStatus, OnUnbalanced, ReservableCurrency, WithdrawReason, WithdrawReasons, ChangeMembers @@ -698,11 +698,12 @@ decl_module! { >::put(count); } - fn on_initialize(n: T::BlockNumber) { + fn on_initialize(n: T::BlockNumber) -> Weight { if let Err(e) = Self::end_block(n) { print("Guru meditation"); print(e); } + SimpleDispatchInfo::default().weigh_data(()) } } } diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index d6036b3af8..70b3472ea0 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -256,7 +256,10 @@ use sp_std::marker::PhantomData; use frame_support::{ dispatch::DispatchResult, decl_module, decl_storage, decl_event, - weights::{SimpleDispatchInfo, DispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee}, + weights::{ + SimpleDispatchInfo, DispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight, + PaysFee, + }, }; use sp_std::prelude::*; use frame_benchmarking::{benchmarks, account}; @@ -516,14 +519,14 @@ decl_module! { // This function could also very well have a weight annotation, similar to any other. The // only difference being that if it is not annotated, the default is // `SimpleDispatchInfo::zero()`, which resolves into no weight. - #[weight = SimpleDispatchInfo::FixedNormal(1000)] - fn on_initialize(_n: T::BlockNumber) { + fn on_initialize(_n: T::BlockNumber) -> Weight { // Anything that needs to be done at the start of the block. // We don't do anything here. + + SimpleDispatchInfo::default().weigh_data(()) } // The signature could also look like: `fn on_finalize()` - #[weight = SimpleDispatchInfo::FixedNormal(2000)] fn on_finalize(_n: T::BlockNumber) { // Anything that needs to be done at the end of the block. // We just kill our dummy storage item. @@ -688,14 +691,17 @@ benchmarks!{ mod tests { use super::*; - use frame_support::{assert_ok, impl_outer_origin, parameter_types, weights::GetDispatchInfo}; + use frame_support::{ + assert_ok, impl_outer_origin, parameter_types, weights::GetDispatchInfo, + traits::{OnInitialize, OnFinalize} + }; use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ Perbill, testing::Header, - traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup}, + traits::{BlakeTwo256, IdentityLookup}, }; impl_outer_origin! { diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 1b3867cf6e..caab493cb1 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -75,16 +75,18 @@ #![cfg_attr(not(feature = "std"), no_std)] use sp_std::{prelude::*, marker::PhantomData}; -use frame_support::{storage::StorageValue, weights::{GetDispatchInfo, WeighBlock, DispatchInfo}}; +use frame_support::{ + storage::StorageValue, weights::{GetDispatchInfo, DispatchInfo}, + traits::{OnInitialize, OnFinalize, OnRuntimeUpgrade, OffchainWorker}, +}; use sp_runtime::{ generic::Digest, ApplyExtrinsicResult, traits::{ - self, Header, Zero, One, Checkable, Applyable, CheckEqual, OnFinalize, OnInitialize, - NumberFor, Block as BlockT, OffchainWorker, Dispatchable, Saturating, OnRuntimeUpgrade, + self, Header, Zero, One, Checkable, Applyable, CheckEqual, ValidateUnsigned, NumberFor, + Block as BlockT, Dispatchable, Saturating, }, transaction_validity::TransactionValidity, }; -use sp_runtime::traits::ValidateUnsigned; use codec::{Codec, Encode}; use frame_system::{extrinsics_root, DigestOf}; @@ -111,8 +113,7 @@ impl< OnRuntimeUpgrade + OnInitialize + OnFinalize + - OffchainWorker + - WeighBlock, + OffchainWorker, > ExecuteBlock for Executive where Block::Extrinsic: Checkable + Codec, @@ -137,8 +138,7 @@ impl< OnRuntimeUpgrade + OnInitialize + OnFinalize + - OffchainWorker + - WeighBlock, + OffchainWorker, > Executive where Block::Extrinsic: Checkable + Codec, @@ -179,10 +179,8 @@ where if Self::runtime_upgraded() { // System is not part of `AllModules`, so we need to call this manually. as OnRuntimeUpgrade>::on_runtime_upgrade(); - ::on_runtime_upgrade(); - >::register_extra_weight_unchecked( - >::on_runtime_upgrade() - ); + let weight = ::on_runtime_upgrade(); + >::register_extra_weight_unchecked(weight); } >::initialize( block_number, @@ -192,13 +190,8 @@ where frame_system::InitKind::Full, ); as OnInitialize>::on_initialize(*block_number); - >::on_initialize(*block_number); - >::register_extra_weight_unchecked( - >::on_initialize(*block_number) - ); - >::register_extra_weight_unchecked( - >::on_finalize(*block_number) - ); + let weight = >::on_initialize(*block_number); + >::register_extra_weight_unchecked(weight); frame_system::Module::::note_finished_initialize(); } @@ -400,7 +393,7 @@ mod tests { use hex_literal::hex; mod custom { - use frame_support::weights::SimpleDispatchInfo; + use frame_support::weights::{SimpleDispatchInfo, Weight}; pub trait Trait: frame_system::Trait {} @@ -422,11 +415,11 @@ mod tests { // module hooks. // one with block number arg and one without - #[weight = SimpleDispatchInfo::FixedNormal(25)] - fn on_initialize(n: T::BlockNumber) { + fn on_initialize(n: T::BlockNumber) -> Weight { println!("on_initialize({})", n); + 175 } - #[weight = SimpleDispatchInfo::FixedNormal(150)] + fn on_finalize() { println!("on_finalize(?)"); } diff --git a/frame/finality-tracker/src/lib.rs b/frame/finality-tracker/src/lib.rs index c7d5ad30d9..d3bd2d18ad 100644 --- a/frame/finality-tracker/src/lib.rs +++ b/frame/finality-tracker/src/lib.rs @@ -207,9 +207,11 @@ mod tests { use sp_core::H256; use sp_runtime::{ testing::Header, Perbill, - traits::{BlakeTwo256, IdentityLookup, OnFinalize, Header as HeaderT}, + traits::{BlakeTwo256, IdentityLookup, Header as HeaderT}, + }; + use frame_support::{ + assert_ok, impl_outer_origin, parameter_types, weights::Weight, traits::OnFinalize }; - use frame_support::{assert_ok, impl_outer_origin, parameter_types, weights::Weight}; use frame_system as system; use std::cell::RefCell; diff --git a/frame/grandpa/src/tests.rs b/frame/grandpa/src/tests.rs index 19e42a301f..b583c31968 100644 --- a/frame/grandpa/src/tests.rs +++ b/frame/grandpa/src/tests.rs @@ -18,7 +18,8 @@ #![cfg(test)] -use sp_runtime::{testing::{H256, Digest}, traits::{Header, OnFinalize}}; +use sp_runtime::{testing::{H256, Digest}, traits::Header}; +use frame_support::traits::OnFinalize; use crate::mock::*; use frame_system::{EventRecord, Phase}; use codec::{Decode, Encode}; diff --git a/frame/im-online/src/tests.rs b/frame/im-online/src/tests.rs index b43adca0fd..c7bf2afcca 100644 --- a/frame/im-online/src/tests.rs +++ b/frame/im-online/src/tests.rs @@ -190,7 +190,7 @@ fn late_heartbeat_should_fail() { #[test] fn should_generate_heartbeats() { - use sp_runtime::traits::OffchainWorker; + use frame_support::traits::OffchainWorker; let mut ext = new_test_ext(); let (offchain, _state) = TestOffchainExt::new(); diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index 95ac6cf752..e3e74e6e9e 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -25,6 +25,7 @@ use sp_runtime::traits::{ StaticLookup, Member, LookupError, Zero, One, BlakeTwo256, Hash, Saturating, AtLeast32Bit }; use frame_support::{Parameter, decl_module, decl_error, decl_event, decl_storage, ensure}; +use frame_support::weights::{Weight, SimpleDispatchInfo, WeighData}; use frame_support::dispatch::DispatchResult; use frame_support::traits::{Currency, ReservableCurrency, Get, BalanceStatus::Reserved}; use frame_support::storage::migration::take_storage_value; @@ -98,8 +99,10 @@ decl_module! { pub struct Module for enum Call where origin: T::Origin, system = frame_system { fn deposit_event() = default; - fn on_initialize() { + fn on_initialize() -> Weight { Self::migrations(); + + SimpleDispatchInfo::default().weigh_data(()) } /// Assign an previously unassigned index. diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index 325ceceb8b..3e7f8c9537 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -27,6 +27,7 @@ mod tests; use sp_std::vec::Vec; use frame_support::{ decl_module, decl_event, decl_storage, Parameter, + weights::{Weight, SimpleDispatchInfo, WeighData}, }; use sp_runtime::traits::Hash; use sp_staking::{ @@ -86,10 +87,12 @@ decl_module! { pub struct Module for enum Call where origin: T::Origin { fn deposit_event() = default; - fn on_runtime_upgrade() { + fn on_runtime_upgrade() -> Weight { Reports::::remove_all(); ConcurrentReportsIndex::::remove_all(); ReportsByKindIndex::remove_all(); + + SimpleDispatchInfo::default().weigh_data(()) } } } diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index 0ded7dd6b0..323af78793 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -54,7 +54,10 @@ use sp_std::{prelude::*, convert::TryInto}; use sp_runtime::traits::Hash; -use frame_support::{decl_module, decl_storage, traits::Randomness}; +use frame_support::{ + decl_module, decl_storage, traits::Randomness, + weights::{Weight, SimpleDispatchInfo, WeighData} +}; use safe_mix::TripletMix; use codec::Encode; use frame_system::Trait; @@ -69,7 +72,7 @@ fn block_number_to_index(block_number: T::BlockNumber) -> usize { decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn on_initialize(block_number: T::BlockNumber) { + fn on_initialize(block_number: T::BlockNumber) -> Weight { let parent_hash = >::parent_hash(); >::mutate(|ref mut values| if values.len() < RANDOM_MATERIAL_LEN as usize { @@ -78,6 +81,8 @@ decl_module! { let index = block_number_to_index::(block_number); values[index] = parent_hash; }); + + SimpleDispatchInfo::default().weigh_data(()) } } } @@ -156,9 +161,11 @@ mod tests { use sp_runtime::{ Perbill, testing::Header, - traits::{BlakeTwo256, OnInitialize, Header as _, IdentityLookup}, + traits::{BlakeTwo256, Header as _, IdentityLookup}, + }; + use frame_support::{ + impl_outer_origin, parameter_types, weights::Weight, traits::{Randomness, OnInitialize}, }; - use frame_support::{impl_outer_origin, parameter_types, weights::Weight, traits::Randomness}; #[derive(Clone, PartialEq, Eq)] pub struct Test; diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index a5b7731c22..9327ece572 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -21,12 +21,13 @@ use super::*; use frame_support::{ impl_outer_origin, impl_outer_dispatch, impl_outer_event, parameter_types, weights::Weight, + traits::{OnInitialize, OnFinalize}, }; use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ - Perbill, traits::{BlakeTwo256, IdentityLookup, OnInitialize, OnFinalize}, testing::Header, + Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, }; use crate as recovery; diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index ebabe79105..9ebac91e93 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -96,6 +96,7 @@ use sp_std::{ use frame_support::{ decl_module, decl_storage, decl_event, ensure, decl_error, traits::{ChangeMembers, InitializeMembers, Currency, Get, ReservableCurrency}, + weights::{Weight, SimpleDispatchInfo, WeighData}, }; use frame_system::{self as system, ensure_root, ensure_signed}; use sp_runtime::{ @@ -245,11 +246,12 @@ decl_module! { /// Every `Period` blocks the `Members` set is refreshed from the /// highest scoring members in the pool. - fn on_initialize(n: T::BlockNumber) { + fn on_initialize(n: T::BlockNumber) -> Weight { if n % T::Period::get() == Zero::zero() { let pool = >::get(); >::refresh_members(pool, ChangeReceiver::MembershipChanged); } + SimpleDispatchInfo::default().weigh_data(()) } /// Add `origin` to the pool of candidates. diff --git a/frame/scored-pool/src/tests.rs b/frame/scored-pool/src/tests.rs index 4b21339505..8d87a20f75 100644 --- a/frame/scored-pool/src/tests.rs +++ b/frame/scored-pool/src/tests.rs @@ -19,8 +19,8 @@ use super::*; use mock::*; -use frame_support::{assert_ok, assert_noop}; -use sp_runtime::traits::{OnInitialize, BadOrigin}; +use frame_support::{assert_ok, assert_noop, traits::OnInitialize}; +use sp_runtime::traits::BadOrigin; type ScoredPool = Module; type System = frame_system::Module; diff --git a/frame/session/src/historical.rs b/frame/session/src/historical.rs index 12b88b347c..f9990dd1e8 100644 --- a/frame/session/src/historical.rs +++ b/frame/session/src/historical.rs @@ -310,12 +310,12 @@ impl> frame_support::traits::KeyOwnerProofSystem<(KeyTy mod tests { use super::*; use sp_core::crypto::key_types::DUMMY; - use sp_runtime::{traits::OnInitialize, testing::UintAuthorityId}; + use sp_runtime::testing::UintAuthorityId; use crate::mock::{ NEXT_VALIDATORS, force_new_session, set_next_validators, Test, System, Session, }; - use frame_support::traits::KeyOwnerProofSystem; + use frame_support::traits::{KeyOwnerProofSystem, OnInitialize}; type Historical = Module; diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index f4490e50a0..b11ae1d818 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -102,12 +102,14 @@ use sp_std::{prelude::*, marker::PhantomData, ops::{Sub, Rem}}; use codec::Decode; use sp_runtime::{KeyTypeId, Perbill, RuntimeAppPublic, BoundToRuntimeAppPublic}; -use frame_support::weights::SimpleDispatchInfo; use sp_runtime::traits::{Convert, Zero, Member, OpaqueKeys}; use sp_staking::SessionIndex; -use frame_support::{ensure, decl_module, decl_event, decl_storage, decl_error, ConsensusEngineId}; -use frame_support::{traits::{Get, FindAuthor, ValidatorRegistration}, Parameter}; -use frame_support::dispatch::{self, DispatchResult, DispatchError}; +use frame_support::{ + ensure, decl_module, decl_event, decl_storage, decl_error, ConsensusEngineId, Parameter, + weights::{Weight, SimpleDispatchInfo, WeighData}, + traits::{Get, FindAuthor, ValidatorRegistration}, + dispatch::{self, DispatchResult, DispatchError}, +}; use frame_system::{self as system, ensure_signed}; #[cfg(test)] @@ -495,10 +497,12 @@ decl_module! { /// Called when a block is initialized. Will rotate session if it is the last /// block of the current session. - fn on_initialize(n: T::BlockNumber) { + fn on_initialize(n: T::BlockNumber) -> Weight { if T::ShouldEndSession::should_end_session(n) { Self::rotate_session(); } + + SimpleDispatchInfo::default().weigh_data(()) } } } diff --git a/frame/session/src/tests.rs b/frame/session/src/tests.rs index 052313f21d..4e95d91cc7 100644 --- a/frame/session/src/tests.rs +++ b/frame/session/src/tests.rs @@ -17,9 +17,9 @@ // Tests for the Session Pallet use super::*; -use frame_support::assert_ok; +use frame_support::{traits::OnInitialize, assert_ok}; use sp_core::crypto::key_types::DUMMY; -use sp_runtime::{traits::OnInitialize, testing::UintAuthorityId}; +use sp_runtime::testing::UintAuthorityId; use mock::{ NEXT_VALIDATORS, SESSION_CHANGED, TEST_SESSION_CHANGED, authorities, force_new_session, set_next_validators, set_session_length, session_changed, Test, Origin, System, Session, diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index 03c61ba532..b4896b8dd9 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -260,7 +260,7 @@ use sp_runtime::{Percent, ModuleId, RuntimeDebug, } }; use frame_support::{decl_error, decl_module, decl_storage, decl_event, ensure, dispatch::DispatchResult}; -use frame_support::weights::SimpleDispatchInfo; +use frame_support::weights::{SimpleDispatchInfo, Weight, WeighData}; use frame_support::traits::{ Currency, ReservableCurrency, Randomness, Get, ChangeMembers, BalanceStatus, ExistenceRequirement::AllowDeath @@ -1028,7 +1028,7 @@ decl_module! { Self::deposit_event(RawEvent::NewMaxMembers(max)); } - fn on_initialize(n: T::BlockNumber) { + fn on_initialize(n: T::BlockNumber) -> Weight { let mut members = vec![]; // Run a candidate/membership rotation @@ -1045,6 +1045,8 @@ decl_module! { } Self::rotate_challenge(&mut members); } + + SimpleDispatchInfo::default().weigh_data(()) } } } diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index 158f139df5..a66a5e6e04 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -18,14 +18,16 @@ use super::*; -use frame_support::{impl_outer_origin, parameter_types, ord_parameter_types}; +use frame_support::{ + impl_outer_origin, parameter_types, ord_parameter_types, traits::{OnInitialize, OnFinalize} +}; use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ Perbill, testing::Header, - traits::{BlakeTwo256, IdentityLookup, OnInitialize, OnFinalize}, + traits::{BlakeTwo256, IdentityLookup}, }; use frame_system::EnsureSignedBy; diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 8754751629..d4add81168 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -19,14 +19,15 @@ use std::{collections::{HashSet, HashMap}, cell::RefCell}; use sp_runtime::{Perbill, KeyTypeId}; use sp_runtime::curve::PiecewiseLinear; -use sp_runtime::traits::{IdentityLookup, Convert, OpaqueKeys, OnInitialize, OnFinalize, SaturatedConversion}; +use sp_runtime::traits::{IdentityLookup, Convert, OpaqueKeys, SaturatedConversion}; use sp_runtime::testing::{Header, UintAuthorityId}; use sp_staking::{SessionIndex, offence::{OffenceDetails, OnOffenceHandler}}; use sp_core::{H256, crypto::key_types}; use sp_io; use frame_support::{ assert_ok, impl_outer_origin, parameter_types, StorageValue, StorageMap, - StorageDoubleMap, IterableStorageMap, traits::{Currency, Get, FindAuthor}, weights::Weight, + StorageDoubleMap, IterableStorageMap, + traits::{Currency, Get, FindAuthor, OnFinalize, OnInitialize}, weights::Weight, }; use crate::{ EraIndex, GenesisConfig, Module, Trait, StakerStatus, ValidatorPrefs, RewardDestination, diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index d11457671f..d97982db12 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -18,11 +18,11 @@ use super::*; use mock::*; -use sp_runtime::{assert_eq_error_rate, traits::{OnInitialize, BadOrigin}}; +use sp_runtime::{assert_eq_error_rate, traits::BadOrigin}; use sp_staking::offence::OffenceDetails; use frame_support::{ assert_ok, assert_noop, - traits::{Currency, ReservableCurrency}, + traits::{Currency, ReservableCurrency, OnInitialize}, StorageMap, }; use pallet_balances::Error as BalancesError; diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index a9c48097ad..75d4428797 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -25,7 +25,7 @@ pub use frame_metadata::{ }; pub use crate::weights::{ SimpleDispatchInfo, GetDispatchInfo, DispatchInfo, WeighData, ClassifyDispatch, - TransactionPriority, Weight, WeighBlock, PaysFee, + TransactionPriority, Weight, PaysFee, }; pub use sp_runtime::{traits::Dispatchable, DispatchError, DispatchResult}; pub use crate::traits::{CallMetadata, GetCallMetadata, GetCallName}; @@ -200,13 +200,23 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// is a runtime upgrade. This allows each module to upgrade its storage before the storage items are used. /// As such, **calling other modules must be avoided**!! Using this function will implement the /// [`OnRuntimeUpgrade`](../sp_runtime/traits/trait.OnRuntimeUpgrade.html) trait. +/// Function signature must be `fn on_runtime_upgrade() -> frame_support::weights::Weight`. +/// /// * `on_initialize`: Executes at the beginning of a block. Using this function will -/// implement the [`OnInitialize`](../sp_runtime/traits/trait.OnInitialize.html) trait. +/// implement the [`OnInitialize`](./trait.OnInitialize.html) trait. +/// Function signature can be either: +/// * `fn on_initialize(n: BlockNumber) -> frame_support::weights::Weight` or +/// * `fn on_initialize() -> frame_support::weights::Weight` +/// /// * `on_finalize`: Executes at the end of a block. Using this function will -/// implement the [`OnFinalize`](../sp_runtime/traits/trait.OnFinalize.html) trait. +/// implement the [`OnFinalize`](./traits/trait.OnFinalize.html) trait. +/// Function signature can be either: +/// * `fn on_finalize(n: BlockNumber) -> frame_support::weights::Weight` or +/// * `fn on_finalize() -> frame_support::weights::Weight` +/// /// * `offchain_worker`: Executes at the beginning of a block and produces extrinsics for a future block /// upon completion. Using this function will implement the -/// [`OffchainWorker`](../sp_runtime/traits/trait.OffchainWorker.html) trait. +/// [`OffchainWorker`](./traits/trait.OffchainWorker.html) trait. #[macro_export] macro_rules! decl_module { // Entry point #1. @@ -327,7 +337,7 @@ macro_rules! decl_module { "`deposit_event` function is reserved and must follow the syntax: `$vis:vis fn deposit_event() = default;`" ); }; - // Add on_finalize, without a given weight. + // Add on_finalize (@normalize $(#[$attr:meta])* pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)?> @@ -354,7 +364,6 @@ macro_rules! decl_module { { $( $on_initialize )* } { $( $on_runtime_upgrade )* } { - #[weight = $crate::dispatch::SimpleDispatchInfo::zero()] fn on_finalize( $( $param_name : $param ),* ) { $( $impl )* } } { $( $offchain )* } @@ -364,7 +373,7 @@ macro_rules! decl_module { $($rest)* ); }; - // Add on_finalize, given weight. + // compile_error on_finalize, given weight removed syntax. (@normalize $(#[$attr:meta])* pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)?> @@ -383,26 +392,12 @@ macro_rules! decl_module { fn on_finalize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } $($rest:tt)* ) => { - $crate::decl_module!(@normalize - $(#[$attr])* - pub struct $mod_type<$trait_instance: $trait_name$(, I: $instantiable $(= $module_default_instance)?)?> - for enum $call_type where origin: $origin_type, system = $system - { $( $other_where_bounds )* } - { $( $deposit_event )* } - { $( $on_initialize )* } - { $( $on_runtime_upgrade )* } - { - #[weight = $weight] - fn on_finalize( $( $param_name : $param ),* ) { $( $impl )* } - } - { $( $offchain )* } - { $( $constants )* } - { $( $error_type )* } - [ $( $dispatchables )* ] - $($rest)* + compile_error!( + "`on_finalize` can't be given weight attribute anymore, weight must be returned by \ + `on_initialize` or `on_runtime_upgrade` instead" ); }; - // Add on_runtime_upgrade, without a given weight. + // compile_error on_runtime_upgrade, without a given weight removed syntax. (@normalize $(#[$attr:meta])* pub struct $mod_type:ident< @@ -422,26 +417,11 @@ macro_rules! decl_module { fn on_runtime_upgrade( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } $($rest:tt)* ) => { - $crate::decl_module!(@normalize - $(#[$attr])* - pub struct $mod_type<$trait_instance: $trait_name$(, I: $instantiable $(= $module_default_instance)?)?> - for enum $call_type where origin: $origin_type, system = $system - { $( $other_where_bounds )* } - { $( $deposit_event )* } - { $( $on_initialize )* } - { - #[weight = $crate::dispatch::SimpleDispatchInfo::zero()] - fn on_runtime_upgrade( $( $param_name : $param ),* ) { $( $impl )* } - } - { $( $on_finalize )* } - { $( $offchain )* } - { $( $constants )* } - { $( $error_type )* } - [ $( $dispatchables )* ] - $($rest)* + compile_error!( + "`on_runtime_upgrade` must return Weight, signature has changed." ); }; - // Add on_runtime_upgrade, given weight. + // compile_error on_runtime_upgrade, given weight removed syntax. (@normalize $(#[$attr:meta])* pub struct $mod_type:ident< @@ -461,6 +441,31 @@ macro_rules! decl_module { #[weight = $weight:expr] fn on_runtime_upgrade( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } $($rest:tt)* + ) => { + compile_error!( + "`on_runtime_upgrade` can't be given weight attribute anymore, weight must be returned \ + by the function directly." + ); + }; + // Add on_runtime_upgrade + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident< + $trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)? + > + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $other_where_bounds:tt )* } + { $( $deposit_event:tt )* } + { $( $on_initialize:tt )* } + {} + { $( $on_finalize:tt )* } + { $( $offchain:tt )* } + { $( $constants:tt )* } + { $( $error_type:tt )* } + [ $( $dispatchables:tt )* ] + $(#[doc = $doc_attr:tt])* + fn on_runtime_upgrade( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* } + $($rest:tt)* ) => { $crate::decl_module!(@normalize $(#[$attr])* @@ -470,8 +475,7 @@ macro_rules! decl_module { { $( $deposit_event )* } { $( $on_initialize )* } { - #[weight = $weight] - fn on_runtime_upgrade( $( $param_name : $param ),* ) { $( $impl )* } + fn on_runtime_upgrade( $( $param_name : $param ),* ) -> $return { $( $impl )* } } { $( $on_finalize )* } { $( $offchain )* } @@ -481,7 +485,7 @@ macro_rules! decl_module { $($rest)* ); }; - // Add on_initialize, without a given weight. + // compile_error on_initialize, without a given weight removed syntax. (@normalize $(#[$attr:meta])* pub struct $mod_type:ident< @@ -501,26 +505,11 @@ macro_rules! decl_module { fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } $($rest:tt)* ) => { - $crate::decl_module!(@normalize - $(#[$attr])* - pub struct $mod_type<$trait_instance: $trait_name$(, I: $instantiable $(= $module_default_instance)?)?> - for enum $call_type where origin: $origin_type, system = $system - { $( $other_where_bounds )* } - { $( $deposit_event )* } - { - #[weight = $crate::dispatch::SimpleDispatchInfo::zero()] - fn on_initialize( $( $param_name : $param ),* ) { $( $impl )* } - } - { $( $on_runtime_upgrade )* } - { $( $on_finalize )* } - { $( $offchain )* } - { $( $constants )* } - { $( $error_type )* } - [ $( $dispatchables )* ] - $($rest)* + compile_error!( + "`on_initialize` must return Weight, signature has changed." ); }; - // Add on_initialize, given weight. + // compile_error on_initialize, with given weight removed syntax. (@normalize $(#[$attr:meta])* pub struct $mod_type:ident< @@ -540,6 +529,31 @@ macro_rules! decl_module { #[weight = $weight:expr] fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } $($rest:tt)* + ) => { + compile_error!( + "`on_initialize` can't be given weight attribute anymore, weight must be returned \ + by the function directly." + ); + }; + // Add on_initialize + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident< + $trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)? + > + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $other_where_bounds:tt )* } + { $( $deposit_event:tt )* } + {} + { $( $on_runtime_upgrade:tt )* } + { $( $on_finalize:tt )* } + { $( $offchain:tt )* } + { $( $constants:tt )* } + { $( $error_type:tt )* } + [ $( $dispatchables:tt )* ] + $(#[doc = $doc_attr:tt])* + fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* } + $($rest:tt)* ) => { $crate::decl_module!(@normalize $(#[$attr])* @@ -548,8 +562,7 @@ macro_rules! decl_module { { $( $other_where_bounds )* } { $( $deposit_event )* } { - #[weight = $weight] - fn on_initialize( $( $param_name : $param ),* ) { $( $impl )* } + fn on_initialize( $( $param_name : $param ),* ) -> $return { $( $impl )* } } { $( $on_runtime_upgrade )* } { $( $on_finalize )* } @@ -965,14 +978,13 @@ macro_rules! decl_module { (@impl_on_initialize $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; { $( $other_where_bounds:tt )* } - #[weight = $weight:expr] - fn on_initialize() { $( $impl:tt )* } + fn on_initialize() -> $return:ty { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sp_runtime::traits::OnInitialize<$trait_instance::BlockNumber> + $crate::traits::OnInitialize<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { - fn on_initialize(_block_number_not_used: $trait_instance::BlockNumber) { + fn on_initialize(_block_number_not_used: $trait_instance::BlockNumber) -> $return { use $crate::sp_std::if_std; if_std! { use $crate::tracing; @@ -987,14 +999,13 @@ macro_rules! decl_module { (@impl_on_initialize $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; { $( $other_where_bounds:tt )* } - #[weight = $weight:expr] - fn on_initialize($param:ident : $param_ty:ty) { $( $impl:tt )* } + fn on_initialize($param:ident : $param_ty:ty) -> $return:ty { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sp_runtime::traits::OnInitialize<$trait_instance::BlockNumber> + $crate::traits::OnInitialize<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { - fn on_initialize($param: $param_ty) { + fn on_initialize($param: $param_ty) -> $return { use $crate::sp_std::if_std; if_std! { use $crate::tracing; @@ -1011,7 +1022,7 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sp_runtime::traits::OnInitialize<$trait_instance::BlockNumber> + $crate::traits::OnInitialize<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* {} }; @@ -1019,14 +1030,13 @@ macro_rules! decl_module { (@impl_on_runtime_upgrade $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; { $( $other_where_bounds:tt )* } - #[weight = $weight:expr] - fn on_runtime_upgrade() { $( $impl:tt )* } + fn on_runtime_upgrade() -> $return:ty { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sp_runtime::traits::OnRuntimeUpgrade + $crate::traits::OnRuntimeUpgrade for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { - fn on_runtime_upgrade() { + fn on_runtime_upgrade() -> $return { use $crate::sp_std::if_std; if_std! { use $crate::tracing; @@ -1043,7 +1053,7 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sp_runtime::traits::OnRuntimeUpgrade + $crate::traits::OnRuntimeUpgrade for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* {} }; @@ -1052,11 +1062,10 @@ macro_rules! decl_module { (@impl_on_finalize $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; { $( $other_where_bounds:tt )* } - #[weight = $weight:expr] fn on_finalize() { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sp_runtime::traits::OnFinalize<$trait_instance::BlockNumber> + $crate::traits::OnFinalize<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_finalize(_block_number_not_used: $trait_instance::BlockNumber) { @@ -1074,11 +1083,10 @@ macro_rules! decl_module { (@impl_on_finalize $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; { $( $other_where_bounds:tt )* } - #[weight = $weight:expr] fn on_finalize($param:ident : $param_ty:ty) { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sp_runtime::traits::OnFinalize<$trait_instance::BlockNumber> + $crate::traits::OnFinalize<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_finalize($param: $param_ty) { @@ -1098,57 +1106,19 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sp_runtime::traits::OnFinalize<$trait_instance::BlockNumber> + $crate::traits::OnFinalize<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { } }; - (@impl_block_hooks_weight - $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; - { $( $other_where_bounds:tt )* } - @runtime_upgrade $( - #[weight = $weight_runtime_update:expr] - fn on_runtime_upgrade($( $param_runtime_upgrade:ident : $param_ty_runtime_upgrade:ty )*) { $( $impl_runtime_upgrade:tt )* } - )? - @init $( - #[weight = $weight_initialize:expr] - fn on_initialize($( $param_initialize:ident : $param_ty_initialize:ty )*) { $( $impl_initialize:tt )* } - )? - @fin $( - #[weight = $weight_finalize:expr] - fn on_finalize($( $param_finalize:ident : $param_ty_finalize:ty )*) { $( $impl_finalize:tt )* } - )? - ) => { - impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::dispatch::WeighBlock<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where - $( $other_where_bounds )* - { - $( - fn on_runtime_upgrade() -> $crate::dispatch::Weight { - >::weigh_data(&$weight_initialize, ()) - } - )? - $( - fn on_initialize(n: $trait_instance::BlockNumber) -> $crate::dispatch::Weight { - >::weigh_data(&$weight_initialize, n) - } - )? - $( - fn on_finalize(n: $trait_instance::BlockNumber) -> $crate::dispatch::Weight { - >::weigh_data(&$weight_finalize, n) - } - )? - } - }; - (@impl_offchain $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; { $( $other_where_bounds:tt )* } fn offchain_worker() { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sp_runtime::traits::OffchainWorker<$trait_instance::BlockNumber> + $crate::traits::OffchainWorker<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn offchain_worker(_block_number_not_used: $trait_instance::BlockNumber) { $( $impl )* } @@ -1161,7 +1131,7 @@ macro_rules! decl_module { fn offchain_worker($param:ident : $param_ty:ty) { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sp_runtime::traits::OffchainWorker<$trait_instance::BlockNumber> + $crate::traits::OffchainWorker<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn offchain_worker($param: $param_ty) { $( $impl )* } @@ -1173,7 +1143,7 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sp_runtime::traits::OffchainWorker<$trait_instance::BlockNumber> + $crate::traits::OffchainWorker<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* {} }; @@ -1402,15 +1372,6 @@ macro_rules! decl_module { $( $on_finalize )* } - $crate::decl_module! { - @impl_block_hooks_weight - $mod_type<$trait_instance: $trait_name $(, $instance: $instantiable)?>; - { $( $other_where_bounds )* } - @runtime_upgrade $( $on_runtime_upgrade )* - @init $( $on_initialize )* - @fin $( $on_finalize )* - } - $crate::decl_module! { @impl_offchain $mod_type<$trait_instance: $trait_name $(, $instance: $instantiable)?>; @@ -2076,9 +2037,10 @@ macro_rules! __check_reserved_fn_name { #[allow(dead_code)] mod tests { use super::*; - use crate::sp_runtime::traits::{OnInitialize, OnFinalize, OnRuntimeUpgrade}; use crate::weights::{DispatchInfo, DispatchClass}; - use crate::traits::{CallMetadata, GetCallMetadata, GetCallName}; + use crate::traits::{ + CallMetadata, GetCallMetadata, GetCallName, OnInitialize, OnFinalize, OnRuntimeUpgrade + }; pub trait Trait: system::Trait + Sized where Self::AccountId: From { type Origin; @@ -2098,14 +2060,6 @@ mod tests { } } - struct BlockWeight; - impl> WeighData for BlockWeight { - fn weigh_data(&self, target: BlockNumber) -> Weight { - let target: u32 = target.into(); - if target % 2 == 0 { 10 } else { 0 } - } - } - decl_module! { pub struct Module for enum Call where origin: T::Origin, T::AccountId: From { /// Hi, this is a comment. @@ -2117,12 +2071,9 @@ mod tests { fn aux_4(_origin, _data: i32) -> DispatchResult { unreachable!() } fn aux_5(_origin, _data: i32, #[compact] _data2: u32,) -> DispatchResult { unreachable!() } - #[weight = SimpleDispatchInfo::FixedNormal(7)] - fn on_initialize(n: T::BlockNumber,) { if n.into() == 42 { panic!("on_initialize") } } - #[weight = BlockWeight] - fn on_finalize(n: T::BlockNumber) { if n.into() == 42 { panic!("on_finalize") } } - #[weight = SimpleDispatchInfo::FixedOperational(69)] - fn on_runtime_upgrade() { } + fn on_initialize(n: T::BlockNumber,) -> Weight { if n.into() == 42 { panic!("on_initialize") } 7 } + fn on_finalize(n: T::BlockNumber,) { if n.into() == 42 { panic!("on_finalize") } } + fn on_runtime_upgrade() -> Weight { 10 } fn offchain_worker() {} #[weight = SimpleDispatchInfo::FixedOperational(5)] @@ -2254,10 +2205,15 @@ mod tests { #[test] #[should_panic(expected = "on_initialize")] - fn on_initialize_should_work() { + fn on_initialize_should_work_1() { as OnInitialize>::on_initialize(42); } + #[test] + fn on_initialize_should_work_2() { + assert_eq!( as OnInitialize>::on_initialize(10), 7); + } + #[test] #[should_panic(expected = "on_finalize")] fn on_finalize_should_work() { @@ -2266,7 +2222,7 @@ mod tests { #[test] fn on_runtime_upgrade_should_work() { - as OnRuntimeUpgrade>::on_runtime_upgrade(); + assert_eq!( as OnRuntimeUpgrade>::on_runtime_upgrade(), 10); } #[test] @@ -2288,18 +2244,6 @@ mod tests { ); } - #[test] - fn weight_for_block_hooks() { - // independent of block number - assert_eq!(>::on_initialize(0), 7); - assert_eq!(>::on_initialize(10), 7); - assert_eq!(>::on_initialize(100), 7); - - // dependent - assert_eq!(>::on_finalize(2), 10); - assert_eq!(>::on_finalize(3), 0); - } - #[test] fn call_name() { let name = Call::::aux_3().get_call_name(); diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 585e17d80d..bd1534bac5 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -28,6 +28,7 @@ use sp_runtime::{ }; use crate::dispatch::Parameter; use crate::storage::StorageMap; +use impl_trait_for_tuples::impl_for_tuples; /// An abstraction of a value stored within storage, but possibly as part of a larger composite /// item. @@ -193,14 +194,14 @@ impl IsDeadAccount for () { } /// Handler for when a new account has been created. -#[impl_trait_for_tuples::impl_for_tuples(30)] +#[impl_for_tuples(30)] pub trait OnNewAccount { /// A new account `who` has been registered. fn on_new_account(who: &AccountId); } /// The account with the given id was reaped. -#[impl_trait_for_tuples::impl_for_tuples(30)] +#[impl_for_tuples(30)] pub trait OnKilledAccount { /// The account with the given id was reaped. fn on_killed_account(who: &AccountId); @@ -1042,3 +1043,91 @@ pub trait GetCallMetadata { /// Return a [`CallMetadata`], containing function and pallet name of the Call. fn get_call_metadata(&self) -> CallMetadata; } + +/// The block finalization trait. Implementing this lets you express what should happen +/// for your module when the block is ending. +#[impl_for_tuples(30)] +pub trait OnFinalize { + /// The block is being finalized. Implement to have something happen. + fn on_finalize(_n: BlockNumber) {} +} + +/// The block initialization trait. Implementing this lets you express what should happen +/// for your module when the block is beginning (right before the first extrinsic is executed). +pub trait OnInitialize { + /// The block is being initialized. Implement to have something happen. + /// + /// Return the non-negotiable weight consumed in the block. + fn on_initialize(_n: BlockNumber) -> crate::weights::Weight { 0 } +} + +#[impl_for_tuples(30)] +impl OnInitialize for Tuple { + fn on_initialize(_n: BlockNumber) -> crate::weights::Weight { + let mut weight = 0; + for_tuples!( #( weight = weight.saturating_add(Tuple::on_initialize(_n.clone())); )* ); + weight + } +} + +/// The runtime upgrade trait. Implementing this lets you express what should happen +/// when the runtime upgrades, and changes may need to occur to your module. +pub trait OnRuntimeUpgrade { + /// Perform a module upgrade. + /// + /// Return the non-negotiable weight consumed for runtime upgrade. + fn on_runtime_upgrade() -> crate::weights::Weight { 0 } +} + +#[impl_for_tuples(30)] +impl OnRuntimeUpgrade for Tuple { + fn on_runtime_upgrade() -> crate::weights::Weight { + let mut weight = 0; + for_tuples!( #( weight = weight.saturating_add(Tuple::on_runtime_upgrade()); )* ); + weight + } +} + +/// Off-chain computation trait. +/// +/// Implementing this trait on a module allows you to perform long-running tasks +/// that make (by default) validators generate transactions that feed results +/// of those long-running computations back on chain. +/// +/// NOTE: This function runs off-chain, so it can access the block state, +/// but cannot preform any alterations. More specifically alterations are +/// not forbidden, but they are not persisted in any way after the worker +/// has finished. +#[impl_for_tuples(30)] +pub trait OffchainWorker { + /// This function is being called after every block import (when fully synced). + /// + /// Implement this and use any of the `Offchain` `sp_io` set of APIs + /// to perform off-chain computations, calls and submit transactions + /// with results to trigger any on-chain changes. + /// Any state alterations are lost and are not persisted. + fn offchain_worker(_n: BlockNumber) {} +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn on_initialize_and_on_runtime_upgrade_weight_merge_works() { + struct Test; + impl OnInitialize for Test { + fn on_initialize(_n: u8) -> crate::weights::Weight { + 10 + } + } + impl OnRuntimeUpgrade for Test { + fn on_runtime_upgrade() -> crate::weights::Weight { + 20 + } + } + + assert_eq!(<(Test, Test)>::on_initialize(0), 20); + assert_eq!(<(Test, Test)>::on_runtime_upgrade(), 40); + } +} diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index 8926ed9493..7e8174ca7b 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -37,9 +37,8 @@ #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; -use impl_trait_for_tuples::impl_for_tuples; use codec::{Encode, Decode}; -use sp_arithmetic::traits::{Bounded, Zero}; +use sp_arithmetic::traits::Bounded; use sp_runtime::{ RuntimeDebug, traits::SignedExtension, @@ -67,17 +66,6 @@ pub trait ClassifyDispatch { fn classify_dispatch(&self, target: T) -> DispatchClass; } -/// Means of determining the weight of a block's life cycle hooks: `on_initialize`, `on_finalize`, -/// `on_runtime_upgrade`, and such. -pub trait WeighBlock { - /// Return the weight of the block's on_runtime_upgrade hook. - fn on_runtime_upgrade() -> Weight { Zero::zero() } - /// Return the weight of the block's on_initialize hook. - fn on_initialize(_: BlockNumber) -> Weight { Zero::zero() } - /// Return the weight of the block's on_finalize hook. - fn on_finalize(_: BlockNumber) -> Weight { Zero::zero() } -} - /// Indicates if dispatch function should pay fees or not. /// If set to false, the block resource limits are applied, yet no fee is deducted. pub trait PaysFee { @@ -86,34 +74,6 @@ pub trait PaysFee { } } -/// Maybe I can do something to remove the duplicate code here. -#[impl_for_tuples(30)] -impl WeighBlock for SingleModule { - fn on_runtime_upgrade() -> Weight { - let mut accumulated_weight: Weight = Zero::zero(); - for_tuples!( - #( accumulated_weight = accumulated_weight.saturating_add(SingleModule::on_runtime_upgrade()); )* - ); - accumulated_weight - } - - fn on_initialize(n: BlockNumber) -> Weight { - let mut accumulated_weight: Weight = Zero::zero(); - for_tuples!( - #( accumulated_weight = accumulated_weight.saturating_add(SingleModule::on_initialize(n)); )* - ); - accumulated_weight - } - - fn on_finalize(n: BlockNumber) -> Weight { - let mut accumulated_weight: Weight = Zero::zero(); - for_tuples!( - #( accumulated_weight = accumulated_weight.saturating_add(SingleModule::on_finalize(n)); )* - ); - accumulated_weight - } -} - /// A generalized group of dispatch types. This is only distinguishing normal, user-triggered transactions /// (`Normal`) and anything beyond which serves a higher purpose to the system (`Operational`). #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] diff --git a/frame/treasury/src/benchmarking.rs b/frame/treasury/src/benchmarking.rs index fb16af740a..a47c89df45 100644 --- a/frame/treasury/src/benchmarking.rs +++ b/frame/treasury/src/benchmarking.rs @@ -20,7 +20,7 @@ use super::*; use frame_system::RawOrigin; use frame_benchmarking::{benchmarks, account}; -use sp_runtime::traits::OnInitialize; +use frame_support::traits::OnInitialize; use crate::Module as Treasury; diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 2c808e0659..376ec85fc9 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -98,7 +98,7 @@ use frame_support::traits::{ use sp_runtime::{Permill, ModuleId, Percent, RuntimeDebug, traits::{ Zero, EnsureOrigin, StaticLookup, AccountIdConversion, Saturating, Hash, BadOrigin }}; -use frame_support::{weights::SimpleDispatchInfo, traits::Contains}; +use frame_support::{weights::{Weight, WeighData, SimpleDispatchInfo}, traits::Contains}; use codec::{Encode, Decode}; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -553,11 +553,13 @@ decl_module! { Self::payout_tip(tip); } - fn on_initialize(n: T::BlockNumber) { + fn on_initialize(n: T::BlockNumber) -> Weight { // Check to see if we should spend some funds! if (n % T::SpendPeriod::get()).is_zero() { Self::spend_funds(); } + + SimpleDispatchInfo::default().weigh_data(()) } } } diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index d7e710639d..262afb3819 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -1,12 +1,14 @@ use super::*; -use frame_support::{assert_noop, assert_ok, impl_outer_origin, parameter_types, weights::Weight}; -use frame_support::traits::Contains; +use frame_support::{ + assert_noop, assert_ok, impl_outer_origin, parameter_types, weights::Weight, + traits::{Contains, OnInitialize} +}; use sp_core::H256; use sp_runtime::{ Perbill, testing::Header, - traits::{BlakeTwo256, OnInitialize, IdentityLookup, BadOrigin}, + traits::{BlakeTwo256, IdentityLookup, BadOrigin}, }; impl_outer_origin! { diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 81b7733319..2f4727a394 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -329,51 +329,6 @@ impl > SimpleBitOps for T {} -/// The block finalization trait. Implementing this lets you express what should happen -/// for your module when the block is ending. -#[impl_for_tuples(30)] -pub trait OnFinalize { - /// The block is being finalized. Implement to have something happen. - fn on_finalize(_n: BlockNumber) {} -} - -/// The block initialization trait. Implementing this lets you express what should happen -/// for your module when the block is beginning (right before the first extrinsic is executed). -#[impl_for_tuples(30)] -pub trait OnInitialize { - /// The block is being initialized. Implement to have something happen. - fn on_initialize(_n: BlockNumber) {} -} - -/// The runtime upgrade trait. Implementing this lets you express what should happen -/// when the runtime upgrades, and changes may need to occur to your module. -#[impl_for_tuples(30)] -pub trait OnRuntimeUpgrade { - /// Perform a module upgrade. - fn on_runtime_upgrade() {} -} - -/// Off-chain computation trait. -/// -/// Implementing this trait on a module allows you to perform long-running tasks -/// that make (by default) validators generate transactions that feed results -/// of those long-running computations back on chain. -/// -/// NOTE: This function runs off-chain, so it can access the block state, -/// but cannot preform any alterations. More specifically alterations are -/// not forbidden, but they are not persisted in any way after the worker -/// has finished. -#[impl_for_tuples(30)] -pub trait OffchainWorker { - /// This function is being called after every block import (when fully synced). - /// - /// Implement this and use any of the `Offchain` `sp_io` set of APIs - /// to perform off-chain computations, calls and submit transactions - /// with results to trigger any on-chain changes. - /// Any state alterations are lost and are not persisted. - fn offchain_worker(_n: BlockNumber) {} -} - /// Abstraction around hashing // Stupid bug in the Rust compiler believes derived // traits must be fulfilled by all type parameters. -- GitLab From 7bbf973a6804e5fe065225525230a10871d387d2 Mon Sep 17 00:00:00 2001 From: Bernhard Schuster Date: Wed, 25 Mar 2020 10:50:22 +0100 Subject: [PATCH 066/300] frame: base 2 pow is just a shift left op (#5393) --- frame/staking/reward-curve/src/log.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frame/staking/reward-curve/src/log.rs b/frame/staking/reward-curve/src/log.rs index 1a25dbb986..e0929a9597 100644 --- a/frame/staking/reward-curve/src/log.rs +++ b/frame/staking/reward-curve/src/log.rs @@ -14,13 +14,13 @@ pub fn log2(p: u32, q: u32) -> u32 { } let mut n = 0u32; - while !(p >= 2u32.pow(n)*q) || !(p < 2u32.pow(n+1)*q) { + while !(p >= (1u32 << n)*q) || !(p < (1u32 << (n+1))*q) { n += 1; } - assert!(p < 2u32.pow(n+1) * q); + assert!(p < (1u32 << (n+1)) * q); - let y_num: u32 = (p - 2u32.pow(n) * q).try_into().unwrap(); - let y_den: u32 = (p + 2u32.pow(n) * q).try_into().unwrap(); + let y_num: u32 = (p - (1u32 << n) * q).try_into().unwrap(); + let y_den: u32 = (p + (1u32 << n) * q).try_into().unwrap(); let _2_div_ln_2 = 2_885_390u32; -- GitLab From 7368fe749296959daaa005819c1945f7e5516bc4 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Wed, 25 Mar 2020 10:53:27 +0100 Subject: [PATCH 067/300] Remove XX hash from contract API. (#5383) --- frame/contracts/COMPLEXITY.md | 1 - frame/contracts/src/tests.rs | 12 ----- frame/contracts/src/wasm/runtime.rs | 75 ----------------------------- 3 files changed, 88 deletions(-) diff --git a/frame/contracts/COMPLEXITY.md b/frame/contracts/COMPLEXITY.md index 482cb45baf..7e8c2903c7 100644 --- a/frame/contracts/COMPLEXITY.md +++ b/frame/contracts/COMPLEXITY.md @@ -480,7 +480,6 @@ This paragraph concerns the following supported built-in hash functions: - `SHA2` with 256-bit width - `KECCAK` with 256-bit width - `BLAKE2` with 128-bit and 256-bit widths -- `TWOX` with 64-bit, 128-bit and 256-bit widths These functions compute a cryptographic hash on the given inputs and copy the resulting hash directly back into the sandboxed Wasm contract output buffer. diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 3f01096b88..2fcd2e58fb 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -2747,9 +2747,6 @@ const CODE_CRYPTO_HASHES: &str = r#" (import "env" "ext_hash_keccak_256" (func $ext_hash_keccak_256 (param i32 i32 i32))) (import "env" "ext_hash_blake2_256" (func $ext_hash_blake2_256 (param i32 i32 i32))) (import "env" "ext_hash_blake2_128" (func $ext_hash_blake2_128 (param i32 i32 i32))) - (import "env" "ext_hash_twox_256" (func $ext_hash_twox_256 (param i32 i32 i32))) - (import "env" "ext_hash_twox_128" (func $ext_hash_twox_128 (param i32 i32 i32))) - (import "env" "ext_hash_twox_64" (func $ext_hash_twox_64 (param i32 i32 i32))) (import "env" "memory" (memory 1 1)) @@ -2760,9 +2757,6 @@ const CODE_CRYPTO_HASHES: &str = r#" $ext_hash_keccak_256 $ext_hash_blake2_256 $ext_hash_blake2_128 - $ext_hash_twox_256 - $ext_hash_twox_128 - $ext_hash_twox_64 ) (data (i32.const 1) "20202010201008") ;; Output sizes of the hashes in order in hex. @@ -2793,9 +2787,6 @@ const CODE_CRYPTO_HASHES: &str = r#" ;; | 1 | KECCAK | 256 | ;; | 2 | BLAKE2 | 256 | ;; | 3 | BLAKE2 | 128 | - ;; | 4 | TWOX | 256 | - ;; | 5 | TWOX | 128 | - ;; | 6 | TWOX | 64 | ;; --------------------------------- (func (export "call") (result i32) (local $chosen_hash_fn i32) @@ -2860,9 +2851,6 @@ fn crypto_hashes() { (dyn_hash_fn!(keccak_256), 32), (dyn_hash_fn!(blake2_256), 32), (dyn_hash_fn!(blake2_128), 16), - (dyn_hash_fn!(twox_256), 32), - (dyn_hash_fn!(twox_128), 16), - (dyn_hash_fn!(twox_64), 8), ]; // Test the given hash functions for the input: "_DEAD_BEEF" for (n, (hash_fn, expected_size)) in test_cases.iter().enumerate() { diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index 92f2ff782b..7cede5542f 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -30,9 +30,6 @@ use sp_io::hashing::{ keccak_256, blake2_256, blake2_128, - twox_256, - twox_128, - twox_64, sha2_256, }; @@ -1118,78 +1115,6 @@ define_env!(Env, , ext_hash_blake2_128(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { compute_hash_on_intermediate_buffer(ctx, blake2_128, input_ptr, input_len, output_ptr) }, - - // Computes the TWOX 256-bit hash on the given input buffer. - // - // Returns the result directly into the given output buffer. - // - // # Note - // - // - The `input` and `output` buffer may overlap. - // - The output buffer is expected to hold at least 32 bytes (256 bits). - // - It is the callers responsibility to provide an output buffer that - // is large enough to hold the expected amount of bytes returned by the - // chosen hash function. - // - // # Parameters - // - // - `input_ptr`: the pointer into the linear memory where the input - // data is placed. - // - `input_len`: the length of the input data in bytes. - // - `output_ptr`: the pointer into the linear memory where the output - // data is placed. The function will write the result - // directly into this buffer. - ext_hash_twox_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { - compute_hash_on_intermediate_buffer(ctx, twox_256, input_ptr, input_len, output_ptr) - }, - - // Computes the TWOX 128-bit hash on the given input buffer. - // - // Returns the result directly into the given output buffer. - // - // # Note - // - // - The `input` and `output` buffer may overlap. - // - The output buffer is expected to hold at least 16 bytes (128 bits). - // - It is the callers responsibility to provide an output buffer that - // is large enough to hold the expected amount of bytes returned by the - // chosen hash function. - // - // # Parameters - // - // - `input_ptr`: the pointer into the linear memory where the input - // data is placed. - // - `input_len`: the length of the input data in bytes. - // - `output_ptr`: the pointer into the linear memory where the output - // data is placed. The function will write the result - // directly into this buffer. - ext_hash_twox_128(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { - compute_hash_on_intermediate_buffer(ctx, twox_128, input_ptr, input_len, output_ptr) - }, - - // Computes the TWOX 64-bit hash on the given input buffer. - // - // Returns the result directly into the given output buffer. - // - // # Note - // - // - The `input` and `output` buffer may overlap. - // - The output buffer is expected to hold at least 8 bytes (64 bits). - // - It is the callers responsibility to provide an output buffer that - // is large enough to hold the expected amount of bytes returned by the - // chosen hash function. - // - // # Parameters - // - // - `input_ptr`: the pointer into the linear memory where the input - // data is placed. - // - `input_len`: the length of the input data in bytes. - // - `output_ptr`: the pointer into the linear memory where the output - // data is placed. The function will write the result - // directly into this buffer. - ext_hash_twox_64(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { - compute_hash_on_intermediate_buffer(ctx, twox_64, input_ptr, input_len, output_ptr) - }, ); /// Computes the given hash function on the scratch buffer. -- GitLab From 1037d23f0fe2c6d75aeaab2302cf0d988d87f406 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Wed, 25 Mar 2020 05:03:58 -0700 Subject: [PATCH 068/300] Fix propagation in network (#5395) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix propagation in network * Update client/service/src/lib.rs Co-Authored-By: Bastian Köcher * fix suggestion Co-authored-by: Bastian Köcher --- client/service/src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 0a7d5ff103..74f6ee4917 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -648,7 +648,11 @@ where } fn transaction(&self, hash: &H) -> Option { - self.pool.ready_transaction(hash).map(|tx| tx.data().clone()) + self.pool.ready_transaction(hash) + .and_then( + // Only propagable transactions should be resolved for network service. + |tx| if tx.is_propagable() { Some(tx.data().clone()) } else { None } + ) } } -- GitLab From 3b7496c4cdd2bc20c44f7ae31a1373d4469de5de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 25 Mar 2020 13:17:42 +0100 Subject: [PATCH 069/300] Upgrade `bumpalo` to make cargo deny happy (#5398) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76fabe80eb..b57b403707 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -472,9 +472,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.2.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742" +checksum = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187" [[package]] name = "byte-slice-cast" -- GitLab From 29fa243d279789373658a60ad226a7f32d5595e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 25 Mar 2020 14:09:23 +0100 Subject: [PATCH 070/300] Pass transaction source to validate_transaction (#5366) * WiP * Support source in the runtime API. * Finish implementation in txpool. * Fix warning. * Fix tests. * Apply suggestions from code review Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-Authored-By: Nikolay Volf * Extra changes. * Fix test and benches. * fix test * Fix test & benches again. * Fix tests. * Update bumpalo * Fix doc test. * Fix doctest. * Fix doctest. Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Nikolay Volf --- bin/node-template/runtime/src/lib.rs | 11 +- bin/node/executor/tests/submit_transaction.rs | 5 +- bin/node/runtime/src/lib.rs | 9 +- .../basic-authorship/src/basic_authorship.rs | 12 +- client/consensus/manual-seal/src/lib.rs | 14 ++- client/offchain/src/lib.rs | 3 +- client/rpc/src/author/mod.rs | 14 ++- client/rpc/src/state/tests.rs | 2 +- client/service/src/lib.rs | 12 +- client/service/test/src/lib.rs | 3 +- .../transaction-pool/graph/benches/basics.rs | 10 +- .../transaction-pool/graph/src/base_pool.rs | 44 ++++++- client/transaction-pool/graph/src/future.rs | 2 + client/transaction-pool/graph/src/pool.rs | 98 ++++++++++------ client/transaction-pool/graph/src/ready.rs | 4 + client/transaction-pool/graph/src/rotator.rs | 3 + .../graph/src/validated_pool.rs | 4 +- client/transaction-pool/src/api.rs | 23 +++- client/transaction-pool/src/lib.rs | 19 ++- client/transaction-pool/src/revalidation.rs | 11 +- client/transaction-pool/src/testing/pool.rs | 111 +++++++++++------- frame/example-offchain-worker/src/lib.rs | 9 +- frame/executive/src/lib.rs | 25 ++-- frame/im-online/src/benchmarking.rs | 3 +- frame/im-online/src/lib.rs | 7 +- .../procedural/src/construct_runtime/mod.rs | 7 +- frame/support/src/unsigned.rs | 18 ++- .../runtime/src/generic/checked_extrinsic.rs | 7 +- primitives/runtime/src/testing.rs | 3 +- primitives/runtime/src/traits.rs | 8 +- .../runtime/src/transaction_validity.rs | 29 +++++ primitives/transaction-pool/src/lib.rs | 2 +- primitives/transaction-pool/src/pool.rs | 9 +- .../transaction-pool/src/runtime_api.rs | 18 ++- test-utils/runtime/src/lib.rs | 11 +- .../runtime/transaction-pool/src/lib.rs | 2 + utils/frame/rpc/system/src/lib.rs | 5 +- 37 files changed, 414 insertions(+), 163 deletions(-) diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 0414759a5a..94f033fd8f 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -11,8 +11,8 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); use sp_std::prelude::*; use sp_core::OpaqueMetadata; use sp_runtime::{ - ApplyExtrinsicResult, transaction_validity::TransactionValidity, generic, create_runtime_str, - impl_opaque_keys, MultiSignature, + ApplyExtrinsicResult, generic, create_runtime_str, impl_opaque_keys, MultiSignature, + transaction_validity::{TransactionValidity, TransactionSource}, }; use sp_runtime::traits::{ BlakeTwo256, Block as BlockT, IdentityLookup, Verify, ConvertInto, IdentifyAccount @@ -318,8 +318,11 @@ impl_runtime_apis! { } impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity { - Executive::validate_transaction(tx) + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx) } } diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index 1a92aeca6b..5e5be5bade 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -138,7 +138,7 @@ fn should_submit_signed_twice_from_the_same_account() { fn submitted_transaction_should_be_valid() { use codec::Encode; use frame_support::storage::StorageMap; - use sp_runtime::transaction_validity::ValidTransaction; + use sp_runtime::transaction_validity::{ValidTransaction, TransactionSource}; use sp_runtime::traits::StaticLookup; let mut t = new_test_ext(COMPACT_CODE, false); @@ -163,6 +163,7 @@ fn submitted_transaction_should_be_valid() { let tx0 = state.read().transactions[0].clone(); let mut t = new_test_ext(COMPACT_CODE, false); t.execute_with(|| { + let source = TransactionSource::External; let extrinsic = UncheckedExtrinsic::decode(&mut &*tx0).unwrap(); // add balance to the account let author = extrinsic.signature.clone().unwrap().0; @@ -172,7 +173,7 @@ fn submitted_transaction_should_be_valid() { >::insert(&address, account); // check validity - let res = Executive::validate_transaction(extrinsic); + let res = Executive::validate_transaction(source, extrinsic); assert_eq!(res.unwrap(), ValidTransaction { priority: 2_411_002_000_000, diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 7bb230ec0f..2330c89a86 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -35,7 +35,7 @@ use sp_runtime::{ impl_opaque_keys, generic, create_runtime_str, }; use sp_runtime::curve::PiecewiseLinear; -use sp_runtime::transaction_validity::TransactionValidity; +use sp_runtime::transaction_validity::{TransactionValidity, TransactionSource}; use sp_runtime::traits::{ self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion, ConvertInto, OpaqueKeys, @@ -734,8 +734,11 @@ impl_runtime_apis! { } impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity { - Executive::validate_transaction(tx) + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx) } } diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index 986d797ca7..e70f3b8464 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -315,13 +315,15 @@ mod tests { prelude::*, runtime::{Extrinsic, Transfer}, }; - use sp_transaction_pool::{ChainEvent, MaintainedTransactionPool}; + use sp_transaction_pool::{ChainEvent, MaintainedTransactionPool, TransactionSource}; use sc_transaction_pool::{BasicPool, FullChainApi}; use sp_api::Core; use backend::Backend; use sp_blockchain::HeaderBackend; use sp_runtime::traits::NumberFor; + const SOURCE: TransactionSource = TransactionSource::External; + fn extrinsic(nonce: u64) -> Extrinsic { Transfer { amount: Default::default(), @@ -338,7 +340,7 @@ mod tests { id: BlockId::Number(block_number.into()), retracted: vec![], is_new_best: true, - header: header, + header, } } @@ -351,7 +353,7 @@ mod tests { ); futures::executor::block_on( - txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)]) + txpool.submit_at(&BlockId::number(0), SOURCE, vec![extrinsic(0), extrinsic(1)]) ).unwrap(); futures::executor::block_on( @@ -403,7 +405,7 @@ mod tests { let block_id = BlockId::Hash(genesis_hash); futures::executor::block_on( - txpool.submit_at(&BlockId::number(0), vec![extrinsic(0)]), + txpool.submit_at(&BlockId::number(0), SOURCE, vec![extrinsic(0)]), ).unwrap(); futures::executor::block_on( @@ -454,7 +456,7 @@ mod tests { ); futures::executor::block_on( - txpool.submit_at(&BlockId::number(0), vec![ + txpool.submit_at(&BlockId::number(0), SOURCE, vec![ extrinsic(0), extrinsic(1), Transfer { diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs index 36d12a0046..f3a0ca887f 100644 --- a/client/consensus/manual-seal/src/lib.rs +++ b/client/consensus/manual-seal/src/lib.rs @@ -224,7 +224,7 @@ mod tests { txpool::Options, }; use substrate_test_runtime_transaction_pool::{TestApi, uxt}; - use sp_transaction_pool::{TransactionPool, MaintainedTransactionPool}; + use sp_transaction_pool::{TransactionPool, MaintainedTransactionPool, TransactionSource}; use sp_runtime::generic::BlockId; use sp_blockchain::HeaderBackend; use sp_consensus::ImportedAux; @@ -236,6 +236,8 @@ mod tests { Arc::new(TestApi::empty()) } + const SOURCE: TransactionSource = TransactionSource::External; + #[tokio::test] async fn instant_seal() { let builder = TestClientBuilder::new(); @@ -278,7 +280,7 @@ mod tests { rt.block_on(future); }); // submit a transaction to pool. - let result = pool.submit_one(&BlockId::Number(0), uxt(Alice, 0)).await; + let result = pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Alice, 0)).await; // assert that it was successfully imported assert!(result.is_ok()); // assert that the background task returns ok @@ -330,7 +332,7 @@ mod tests { rt.block_on(future); }); // submit a transaction to pool. - let result = pool.submit_one(&BlockId::Number(0), uxt(Alice, 0)).await; + let result = pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Alice, 0)).await; // assert that it was successfully imported assert!(result.is_ok()); let (tx, rx) = futures::channel::oneshot::channel(); @@ -399,7 +401,7 @@ mod tests { rt.block_on(future); }); // submit a transaction to pool. - let result = pool.submit_one(&BlockId::Number(0), uxt(Alice, 0)).await; + let result = pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Alice, 0)).await; // assert that it was successfully imported assert!(result.is_ok()); @@ -430,7 +432,7 @@ mod tests { ); // assert that there's a new block in the db. assert!(backend.blockchain().header(BlockId::Number(0)).unwrap().is_some()); - assert!(pool.submit_one(&BlockId::Number(1), uxt(Alice, 1)).await.is_ok()); + assert!(pool.submit_one(&BlockId::Number(1), SOURCE, uxt(Alice, 1)).await.is_ok()); pool.maintain(sp_transaction_pool::ChainEvent::NewBlock { id: BlockId::Number(1), @@ -453,7 +455,7 @@ mod tests { assert!(backend.blockchain().header(BlockId::Number(1)).unwrap().is_some()); pool_api.increment_nonce(Alice.into()); - assert!(pool.submit_one(&BlockId::Number(2), uxt(Alice, 2)).await.is_ok()); + assert!(pool.submit_one(&BlockId::Number(2), SOURCE, uxt(Alice, 2)).await.is_ok()); let (tx2, rx2) = futures::channel::oneshot::channel(); assert!(sink.send(EngineCommand::SealNewBlock { parent_hash: Some(created_block.hash), diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index 27a7f50845..94850e3fd3 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -191,7 +191,8 @@ mod tests { at: &BlockId, extrinsic: ::Extrinsic, ) -> Result<(), ()> { - futures::executor::block_on(self.0.submit_one(&at, extrinsic)) + let source = sp_transaction_pool::TransactionSource::Local; + futures::executor::block_on(self.0.submit_one(&at, source, extrinsic)) .map(|_| ()) .map_err(|_| ()) } diff --git a/client/rpc/src/author/mod.rs b/client/rpc/src/author/mod.rs index 80a3a4349e..a3f23e8e14 100644 --- a/client/rpc/src/author/mod.rs +++ b/client/rpc/src/author/mod.rs @@ -37,7 +37,7 @@ use sp_core::{Bytes, traits::BareCryptoStorePtr}; use sp_api::ProvideRuntimeApi; use sp_runtime::generic; use sp_transaction_pool::{ - TransactionPool, InPoolTransaction, TransactionStatus, + TransactionPool, InPoolTransaction, TransactionStatus, TransactionSource, BlockHash, TxHash, TransactionFor, error::IntoPoolError, }; use sp_session::SessionKeys; @@ -75,6 +75,14 @@ impl Author { } } + +/// Currently we treat all RPC transactions as externals. +/// +/// Possibly in the future we could allow opt-in for special treatment +/// of such transactions, so that the block authors can inject +/// some unique transactions via RPC and have them included in the pool. +const TX_SOURCE: TransactionSource = TransactionSource::External; + impl AuthorApi, BlockHash

> for Author where P: TransactionPool + Sync + Send + 'static, @@ -127,7 +135,7 @@ impl AuthorApi, BlockHash

> for Author }; let best_block_hash = self.client.info().best_hash; Box::new(self.pool - .submit_one(&generic::BlockId::hash(best_block_hash), xt) + .submit_one(&generic::BlockId::hash(best_block_hash), TX_SOURCE, xt) .compat() .map_err(|e| e.into_pool_error() .map(Into::into) @@ -173,7 +181,7 @@ impl AuthorApi, BlockHash

=

::Hash; diff --git a/primitives/utils/Cargo.toml b/primitives/utils/Cargo.toml new file mode 100644 index 0000000000..97e5ce1d9b --- /dev/null +++ b/primitives/utils/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "sp-utils" +version = "2.0.0-alpha.5" +authors = ["Parity Technologies "] +edition = "2018" +license = "GPL-3.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "I/O for Substrate runtimes" + +[dependencies] +futures = "0.3.4" +futures-core = "0.3.4" +lazy_static = "1.4.0" +prometheus = "0.8.0" + +[features] +default = ["metered"] +metered = [] diff --git a/primitives/utils/src/lib.rs b/primitives/utils/src/lib.rs new file mode 100644 index 0000000000..385a9b6689 --- /dev/null +++ b/primitives/utils/src/lib.rs @@ -0,0 +1,20 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Utilities Primitives for Substrate + +pub mod metrics; +pub mod mpsc; \ No newline at end of file diff --git a/primitives/utils/src/metrics.rs b/primitives/utils/src/metrics.rs new file mode 100644 index 0000000000..160714fdca --- /dev/null +++ b/primitives/utils/src/metrics.rs @@ -0,0 +1,58 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Metering primitives and globals + +use lazy_static::lazy_static; +use prometheus::{ + Registry, Error as PrometheusError, + core::{ AtomicU64, GenericGauge, GenericCounter }, +}; + +#[cfg(features = "metered")] +use prometheus::{core::GenericGaugeVec, Opts}; + + +lazy_static! { + pub static ref TOKIO_THREADS_TOTAL: GenericCounter = GenericCounter::new( + "tokio_threads_total", "Total number of threads created" + ).expect("Creating of statics doesn't fail. qed"); + + pub static ref TOKIO_THREADS_ALIVE: GenericGauge = GenericGauge::new( + "tokio_threads_alive", "Number of threads alive right now" + ).expect("Creating of statics doesn't fail. qed"); +} + +#[cfg(features = "metered")] +lazy_static! { + pub static ref UNBOUNDED_CHANNELS_COUNTER : GenericGaugeVec = GenericGaugeVec::new( + Opts::new("unbounded_channel_len", "Items in each mpsc::unbounded instance"), + &["entity", "action"] // 'name of channel, send|received|dropped + ).expect("Creating of statics doesn't fail. qed"); + +} + + +/// Register the statics to report to registry +pub fn register_globals(registry: &Registry) -> Result<(), PrometheusError> { + registry.register(Box::new(TOKIO_THREADS_ALIVE.clone()))?; + registry.register(Box::new(TOKIO_THREADS_TOTAL.clone()))?; + + #[cfg(features = "metered")] + registry.register(Box::new(UNBOUNDED_CHANNELS_COUNTER.clone()))?; + + Ok(()) +} diff --git a/primitives/utils/src/mpsc.rs b/primitives/utils/src/mpsc.rs new file mode 100644 index 0000000000..42fb287c18 --- /dev/null +++ b/primitives/utils/src/mpsc.rs @@ -0,0 +1,232 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Features to meter unbounded channels + +#[cfg(not(features = "metered"))] +mod inner { + // just aliased, non performance implications + use futures::channel::mpsc::{self, UnboundedReceiver, UnboundedSender}; + pub type TracingUnboundedSender = UnboundedSender; + pub type TracingUnboundedReceiver = UnboundedReceiver; + + /// Alias `mpsc::unbounded` + pub fn tracing_unbounded(_key: &'static str) ->(TracingUnboundedSender, TracingUnboundedReceiver) { + mpsc::unbounded() + } +} + + +#[cfg(features = "metered")] +mod inner { + //tracing implementation + use futures::channel::mpsc::{self, + UnboundedReceiver, UnboundedSender, + TryRecvError, TrySendError, SendError + }; + use futures::{sink::Sink, task::{Poll, Context}, stream::Stream}; + use std::pin::Pin; + use crate::metrics::UNBOUNDED_CHANNELS_COUNTER; + + /// Wrapper Type around `UnboundedSender` that increases the global + /// measure when a message is added + #[derive(Debug, Clone)] + pub struct TracingUnboundedSender(&'static str, UnboundedSender); + + /// Wrapper Type around `UnboundedReceiver` that decreases the global + /// measure when a message is polled + #[derive(Debug)] + pub struct TracingUnboundedReceiver(&'static str, UnboundedReceiver); + + /// Wrapper around `mpsc::unbounded` that tracks the in- and outflow via + /// `UNBOUNDED_CHANNELS_COUNTER` + pub fn tracing_unbounded(key: &'static str) ->(TracingUnboundedSender, TracingUnboundedReceiver) { + let (s, r) = mpsc::unbounded(); + (TracingUnboundedSender(key.clone(), s), TracingUnboundedReceiver(key,r)) + } + + impl TracingUnboundedSender { + /// Proxy function to mpsc::UnboundedSender + pub fn poll_ready(&self, ctx: &mut Context) -> Poll> { + self.1.poll_ready(ctx) + } + + /// Proxy function to mpsc::UnboundedSender + pub fn is_closed(&self) -> bool { + self.1.is_closed() + } + + /// Proxy function to mpsc::UnboundedSender + pub fn close_channel(&self) { + self.1.close_channel() + } + + /// Proxy function to mpsc::UnboundedSender + pub fn disconnect(&mut self) { + self.1.disconnect() + } + + /// Proxy function to mpsc::UnboundedSender + pub fn start_send(&mut self, msg: T) -> Result<(), SendError> { + self.1.start_send(msg) + } + + /// Proxy function to mpsc::UnboundedSender + pub fn unbounded_send(&self, msg: T) -> Result<(), TrySendError> { + self.1.unbounded_send(msg).map(|s|{ + UNBOUNDED_CHANNELS_COUNTER.with_label_values(&[self.0, &"send"]).incr(); + s + }) + } + + /// Proxy function to mpsc::UnboundedSender + pub fn same_receiver(&self, other: &UnboundedSender) -> bool { + self.1.same_receiver(other) + } + } + + impl TracingUnboundedReceiver { + + fn consume(&mut self) { + // consume all items, make sure to reflect the updated count + let mut count = 0; + while let Ok(Some(..)) = self.try_next() { + count += 1; + } + + // and discount the messages + if count > 0 { + UNBOUNDED_CHANNELS_COUNTER.with_label_values(&[self.0, &"dropped"]).incr_by(count); + } + + } + + /// Proxy function to mpsc::UnboundedReceiver + /// that consumes all messages first and updates the counter + pub fn close(&mut self) { + self.consume(); + self.1.close() + } + + /// Proxy function to mpsc::UnboundedReceiver + /// that discounts the messages taken out + pub fn try_next(&mut self) -> Result, TryRecvError> { + self.1.try_next().map(|s| { + if s.is_some() { + UNBOUNDED_CHANNELS_COUNTER.with_label_values(&[self.0, &"received"]).incr(); + } + s + }) + } + } + + impl Drop for TracingUnboundedReceiver { + fn drop(&mut self) { + self.consume(); + } + } + + impl Unpin for TracingUnboundedReceiver {} + + impl Stream for TracingUnboundedReceiver { + type Item = T; + + fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let s = self.get_mut(); + match Pin::new(&mut s.1).poll_next(cx) { + Poll::Ready(msg) => { + if msg.is_some() { + UNBOUNDED_CHANNELS_COUNTER.with_label_values(&[self.0, "received"]).incr(); + } + Poll::Ready(msg) + } + Poll::Pending => { + Poll::Pending + } + } + } + } + + + impl Sink for TracingUnboundedSender { + type Error = SendError; + + fn poll_ready( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + TracingUnboundedSender::poll_ready(&*self, cx) + } + + fn start_send( + mut self: Pin<&mut Self>, + msg: T, + ) -> Result<(), Self::Error> { + TracingUnboundedSender::start_send(&mut *self, msg) + } + + fn poll_flush( + self: Pin<&mut Self>, + _: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_close( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + ) -> Poll> { + self.disconnect(); + Poll::Ready(Ok(())) + } + } + + impl Sink for &TracingUnboundedSender { + type Error = SendError; + + fn poll_ready( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + TracingUnboundedSender::poll_ready(*self, cx) + } + + fn start_send(self: Pin<&mut Self>, msg: T) -> Result<(), Self::Error> { + self.unbounded_send(msg) + .map_err(TrySendError::into_send_error) + } + + fn poll_flush( + self: Pin<&mut Self>, + _: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_close( + self: Pin<&mut Self>, + _: &mut Context<'_>, + ) -> Poll> { + self.close_channel(); + Poll::Ready(Ok(())) + } + } +} + +pub use inner::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; diff --git a/utils/prometheus/Cargo.toml b/utils/prometheus/Cargo.toml index d2913c5e59..add4b0da5f 100644 --- a/utils/prometheus/Cargo.toml +++ b/utils/prometheus/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] log = "0.4.8" -prometheus = "0.7" +prometheus = "0.8" futures-util = { version = "0.3.1", default-features = false, features = ["io"] } derive_more = "0.99" diff --git a/utils/prometheus/src/lib.rs b/utils/prometheus/src/lib.rs index 9dab2a2695..00f0fb4f97 100644 --- a/utils/prometheus/src/lib.rs +++ b/utils/prometheus/src/lib.rs @@ -16,6 +16,7 @@ use futures_util::{FutureExt, future::Future}; pub use prometheus::{ + self, Registry, Error as PrometheusError, Opts, Histogram, HistogramOpts, HistogramVec, core::{ -- GitLab From d8d871471175ebfe7f4be30c36efd384965fedf5 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Sat, 4 Apr 2020 19:52:19 +0200 Subject: [PATCH 163/300] Fix non-linux build of sc-client (#5524) * procfs is linux only * also for the import * fixup non-linux build --- client/service/Cargo.toml | 8 ++++---- client/service/src/metrics.rs | 22 +++++++++------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 7dc987b303..530142c745 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -62,13 +62,13 @@ sc-tracing = { version = "2.0.0-alpha.5", path = "../tracing" } tracing = "0.1.10" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } -[target.'cfg(unix)'.dependencies] -procfs = '0.7.8' -netstat2 = "0.8.1" -[target.'cfg(windows)'.dependencies] +[target.'cfg(any(unix, windows))'.dependencies] netstat2 = "0.8.1" +[target.'cfg(target_os = "linux")'.dependencies] +procfs = '0.7.8' + [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } diff --git a/client/service/src/metrics.rs b/client/service/src/metrics.rs index 931d59b5f1..740a795eda 100644 --- a/client/service/src/metrics.rs +++ b/client/service/src/metrics.rs @@ -24,15 +24,12 @@ use sp_transaction_pool::PoolStatus; use sp_utils::metrics::register_globals; #[cfg(any(windows, unix))] -use sysinfo::{ProcessExt, System, SystemExt}; +use sysinfo::{self, ProcessExt, SystemExt}; #[cfg(any(unix, windows))] use netstat2::{TcpState, ProtocolSocketInfo, iterate_sockets_info, AddressFamilyFlags, ProtocolFlags}; -#[cfg(not(unix))] -use sysinfo::get_current_pid; - -#[cfg(unix)] +#[cfg(target_os = "linux")] use procfs; struct PrometheusMetrics { @@ -183,11 +180,11 @@ struct ProcessInfo { pub struct MetricsService { metrics: Option, #[cfg(any(windows, unix))] - system: System, + system: sysinfo::System, pid: Option, } -#[cfg(unix)] +#[cfg(target_os = "linux")] impl MetricsService { fn inner_new(metrics: Option) -> Self { let process = procfs::process::Process::myself() @@ -195,7 +192,7 @@ impl MetricsService { Self { metrics, - system: System::new(), + system: sysinfo::System::new(), pid: Some(process.pid), } } @@ -224,19 +221,18 @@ impl MetricsService { } - -#[cfg(windows)] +#[cfg(all(any(unix, windows), not(target_os = "linux")))] impl MetricsService { fn inner_new(metrics: Option) -> Self { Self { metrics, - system: System(), - pid: get_current_pid().ok() + system: sysinfo::System::new(), + pid: sysinfo::get_current_pid().ok() } } fn process_info(&mut self) -> ProcessInfo { - self.pid.map(|pid| self._process_info_for(pid)).or_else(ProcessInfo::default) + self.pid.map(|pid| self._process_info_for(&pid)).unwrap_or_else(ProcessInfo::default) } } -- GitLab From e6f3fa106aa35ffa81c095d192a5e6f35e671b1f Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sun, 5 Apr 2020 14:27:17 +0200 Subject: [PATCH 164/300] Fix Benchmarks to enable batch run (#5523) * some fixes * Update tips benchmark to be resiliant to genesis * Update Cargo.lock --- frame/democracy/src/benchmarking.rs | 5 +++-- frame/staking/src/benchmarking.rs | 6 +++--- frame/treasury/src/benchmarking.rs | 16 +++++++++++----- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/frame/democracy/src/benchmarking.rs b/frame/democracy/src/benchmarking.rs index 1df205a4f5..83f7ca795f 100644 --- a/frame/democracy/src/benchmarking.rs +++ b/frame/democracy/src/benchmarking.rs @@ -111,14 +111,15 @@ benchmarks! { second { let s in 0 .. MAX_SECONDERS; + let caller = funded_account::("caller", 0); + let proposal_hash = add_proposal::(s)?; + // Create s existing "seconds" for i in 0 .. s { let seconder = funded_account::("seconder", i); Democracy::::second(RawOrigin::Signed(seconder).into(), 0)?; } - let caller = funded_account::("caller", 0); - let proposal_hash = add_proposal::(s)?; }: _(RawOrigin::Signed(caller), 0) vote { diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index d4edac63d2..60d0c13237 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -219,11 +219,11 @@ benchmarks! { let c in 0 .. 1000; }: _(RawOrigin::Root, c) - force_no_eras { let i in 1 .. 1; }: _(RawOrigin::Root) + force_no_eras { let i in 0 .. 1; }: _(RawOrigin::Root) - force_new_era {let i in 1 .. 1; }: _(RawOrigin::Root) + force_new_era {let i in 0 .. 1; }: _(RawOrigin::Root) - force_new_era_always { let i in 1 .. 1; }: _(RawOrigin::Root) + force_new_era_always { let i in 0 .. 1; }: _(RawOrigin::Root) // Worst case scenario, the list of invulnerables is very long. set_invulnerables { diff --git a/frame/treasury/src/benchmarking.rs b/frame/treasury/src/benchmarking.rs index 925832e04c..0f9582ebc4 100644 --- a/frame/treasury/src/benchmarking.rs +++ b/frame/treasury/src/benchmarking.rs @@ -58,12 +58,15 @@ fn setup_awesome(length: u32) -> (T::AccountId, Vec, T::AccountId) fn setup_tip(r: u32, t: u32) -> Result<(T::AccountId, Vec, T::AccountId, BalanceOf), &'static str> { + let tippers_count = T::Tippers::count(); + for i in 0 .. t { let member = account("member", i, SEED); T::Tippers::add(&member); + ensure!(T::Tippers::contains(&member), "failed to add tipper"); } - ensure!(T::Tippers::count() == t as usize, "problem creating tippers"); + ensure!(T::Tippers::count() == tippers_count + t as usize, "problem creating tippers"); let caller = account("member", t - 1, SEED); let reason = vec![0; r as usize]; let beneficiary = account("beneficiary", t, SEED); @@ -71,16 +74,19 @@ fn setup_tip(r: u32, t: u32) -> Ok((caller, reason, beneficiary, value)) } -// Create `t` new types for the tip proposal with `hash`. -// This function automatically moves forward the block number to a time which -// would resolve the tipping process. +// Create `t` new tips for the tip proposal with `hash`. +// This function automatically makes the tip able to close. fn create_tips(t: u32, hash: T::Hash, value: BalanceOf) -> Result<(), &'static str> { for i in 0 .. t { let caller = account("member", i, SEED); ensure!(T::Tippers::contains(&caller), "caller is not a tipper"); Treasury::::tip(RawOrigin::Signed(caller).into(), hash, value)?; } - frame_system::Module::::set_block_number(T::TipCountdown::get() * 10.into()); + Tips::::mutate(hash, |maybe_tip| { + if let Some(open_tip) = maybe_tip { + open_tip.closes = Some(T::BlockNumber::zero()); + } + }); Ok(()) } -- GitLab From 1d973972015693e71f09281081a4eaa9d817063b Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sun, 5 Apr 2020 14:27:30 +0200 Subject: [PATCH 165/300] Mandatory dispatch class (#5515) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Mandatory dispatch class * Tweaks * Docs * Fix test * Update frame/support/src/weights.rs Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Introduce logic that was stated in PR. * Use * Docs. * Fix test * Fix merge * Update frame/support/src/weights.rs Co-Authored-By: Bastian Köcher * Fix. * Fix Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Co-authored-by: Bastian Köcher --- bin/node/executor/tests/basic.rs | 4 +-- .../basic-authorship/src/basic_authorship.rs | 21 +++++++++--- frame/authorship/src/lib.rs | 2 +- frame/finality-tracker/src/lib.rs | 2 +- frame/support/src/weights.rs | 24 +++++++++++-- frame/system/src/lib.rs | 34 ++++++++++++++++--- frame/timestamp/src/lib.rs | 2 +- .../runtime/src/generic/checked_extrinsic.rs | 8 +++-- primitives/runtime/src/traits.rs | 32 ++++++++++++++--- .../runtime/src/transaction_validity.rs | 28 +++++++++++++++ 10 files changed, 132 insertions(+), 25 deletions(-) diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index 1ee0a17c81..fccf4a62cc 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -338,7 +338,7 @@ fn full_native_block_import_works() { EventRecord { phase: Phase::ApplyExtrinsic(0), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 10000, class: DispatchClass::Operational, pays_fee: true } + DispatchInfo { weight: 10000, class: DispatchClass::Mandatory, pays_fee: true } )), topics: vec![], }, @@ -391,7 +391,7 @@ fn full_native_block_import_works() { EventRecord { phase: Phase::ApplyExtrinsic(0), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 10000, class: DispatchClass::Operational, pays_fee: true } + DispatchInfo { weight: 10000, class: DispatchClass::Mandatory, pays_fee: true } )), topics: vec![], }, diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index b3bf486aae..37bb34a4b6 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -23,7 +23,7 @@ use sc_client_api::backend; use codec::Decode; use sp_consensus::{evaluation, Proposal, RecordProof}; use sp_inherents::InherentData; -use log::{error, info, debug, trace}; +use log::{error, info, debug, trace, warn}; use sp_core::ExecutionContext; use sp_runtime::{ generic::BlockId, @@ -34,7 +34,7 @@ use sc_telemetry::{telemetry, CONSENSUS_INFO}; use sc_block_builder::{BlockBuilderApi, BlockBuilderProvider}; use sp_api::{ProvideRuntimeApi, ApiExt}; use futures::{executor, future, future::Either}; -use sp_blockchain::{HeaderBackend, ApplyExtrinsicFailed}; +use sp_blockchain::{HeaderBackend, ApplyExtrinsicFailed::Validity, Error::ApplyExtrinsicFailed}; use std::marker::PhantomData; /// Proposer factory. @@ -196,14 +196,25 @@ impl ProposerInner // We don't check the API versions any further here since the dispatch compatibility // check should be enough. - for extrinsic in self.client.runtime_api() + for inherent in self.client.runtime_api() .inherent_extrinsics_with_context( &self.parent_id, ExecutionContext::BlockConstruction, inherent_data )? { - block_builder.push(extrinsic)?; + match block_builder.push(inherent) { + Err(ApplyExtrinsicFailed(Validity(e))) if e.exhausted_resources() => + warn!("⚠️ Dropping non-mandatory inherent from overweight block."), + Err(ApplyExtrinsicFailed(Validity(e))) if e.was_mandatory() => { + error!("❌️ Mandatory inherent extrinsic returned error. Block cannot be produced."); + Err(ApplyExtrinsicFailed(Validity(e)))? + } + Err(e) => { + warn!("❗️ Inherent extrinsic returned unexpected error: {}. Dropping.", e); + } + Ok(_) => {} + } } // proceed with transactions @@ -241,7 +252,7 @@ impl ProposerInner Ok(()) => { debug!("[{:?}] Pushed to the block.", pending_tx_hash); } - Err(sp_blockchain::Error::ApplyExtrinsicFailed(ApplyExtrinsicFailed::Validity(e))) + Err(ApplyExtrinsicFailed(Validity(e))) if e.exhausted_resources() => { if is_first { debug!("[{:?}] Invalid transaction: FullBlock on empty block", pending_tx_hash); diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index d71a71e5bf..e6249849bf 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -207,7 +207,7 @@ decl_module! { } /// Provide a set of uncles. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + #[weight = SimpleDispatchInfo::FixedMandatory(10_000)] fn set_uncles(origin, new_uncles: Vec) -> dispatch::DispatchResult { ensure_none(origin)?; ensure!(new_uncles.len() <= MAX_UNCLES, Error::::TooManyUncles); diff --git a/frame/finality-tracker/src/lib.rs b/frame/finality-tracker/src/lib.rs index 4a6e2392f2..8200543ffa 100644 --- a/frame/finality-tracker/src/lib.rs +++ b/frame/finality-tracker/src/lib.rs @@ -76,7 +76,7 @@ decl_module! { /// Hint that the author of this block thinks the best finalized /// block is the given number. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = frame_support::weights::SimpleDispatchInfo::FixedMandatory(10_000)] fn final_hint(origin, #[compact] hint: T::BlockNumber) { ensure_none(origin)?; ensure!(!::Update::exists(), Error::::AlreadyUpdated); diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index 4d501305f0..ea3368550f 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -85,6 +85,19 @@ pub enum DispatchClass { Normal, /// An operational dispatch. Operational, + /// A mandatory dispatch. These kinds of dispatch are always included regardless of their + /// weight, therefore it is critical that they are separately validated to ensure that a + /// malicious validator cannot craft a valid but impossibly heavy block. Usually this just means + /// ensuring that the extrinsic can only be included once and that it is always very light. + /// + /// Do *NOT* use it for extrinsics that can be heavy. + /// + /// The only real use case for this is inherent extrinsics that are required to execute in a + /// block for the block to be valid, and it solves the issue in the case that the block + /// initialization is sufficiently heavy to mean that those inherents do not fit into the + /// block. Essentially, we assume that in these exceptional circumstances, it is better to + /// allow an overweight block to be created than to not allow any block at all to be created. + Mandatory, } impl Default for DispatchClass { @@ -102,6 +115,8 @@ impl From for DispatchClass { SimpleDispatchInfo::FixedNormal(_) => DispatchClass::Normal, SimpleDispatchInfo::MaxNormal => DispatchClass::Normal, SimpleDispatchInfo::InsecureFreeNormal => DispatchClass::Normal, + + SimpleDispatchInfo::FixedMandatory(_) => DispatchClass::Mandatory, } } } @@ -212,6 +227,11 @@ pub enum SimpleDispatchInfo { FixedOperational(Weight), /// An operational dispatch with the maximum weight. MaxOperational, + /// A mandatory dispatch with fixed weight. + /// + /// NOTE: Signed transactions may not (directly) dispatch this kind of a call, so the other + /// attributes concerning transactability (e.g. priority, fee paying) are moot. + FixedMandatory(Weight), } impl WeighData for SimpleDispatchInfo { @@ -220,9 +240,9 @@ impl WeighData for SimpleDispatchInfo { SimpleDispatchInfo::FixedNormal(w) => *w, SimpleDispatchInfo::MaxNormal => Bounded::max_value(), SimpleDispatchInfo::InsecureFreeNormal => Bounded::min_value(), - SimpleDispatchInfo::FixedOperational(w) => *w, SimpleDispatchInfo::MaxOperational => Bounded::max_value(), + SimpleDispatchInfo::FixedMandatory(w) => *w, } } } @@ -239,9 +259,9 @@ impl PaysFee for SimpleDispatchInfo { SimpleDispatchInfo::FixedNormal(_) => true, SimpleDispatchInfo::MaxNormal => true, SimpleDispatchInfo::InsecureFreeNormal => true, - SimpleDispatchInfo::FixedOperational(_) => true, SimpleDispatchInfo::MaxOperational => true, + SimpleDispatchInfo::FixedMandatory(_) => true, } } } diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 7823916347..050ab2654b 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -99,7 +99,7 @@ use sp_std::marker::PhantomData; use sp_std::fmt::Debug; use sp_version::RuntimeVersion; use sp_runtime::{ - RuntimeDebug, Perbill, DispatchOutcome, DispatchError, + RuntimeDebug, Perbill, DispatchOutcome, DispatchError, DispatchResult, generic::{self, Era}, transaction_validity::{ ValidTransaction, TransactionPriority, TransactionLongevity, TransactionValidityError, @@ -119,7 +119,7 @@ use frame_support::{ Contains, Get, ModuleToIndex, OnNewAccount, OnKilledAccount, IsDeadAccount, Happened, StoredMap, EnsureOrigin, }, - weights::{Weight, DispatchInfo, DispatchClass, SimpleDispatchInfo, FunctionOf}, + weights::{Weight, DispatchInfo, DispatchClass, SimpleDispatchInfo, FunctionOf} }; use codec::{Encode, Decode, FullCodec, EncodeLike}; @@ -1170,7 +1170,8 @@ impl CheckWeight { /// a portion. fn get_dispatch_limit_ratio(class: DispatchClass) -> Perbill { match class { - DispatchClass::Operational => ::one(), + DispatchClass::Operational | DispatchClass::Mandatory + => ::one(), DispatchClass::Normal => T::AvailableBlockRatio::get(), } } @@ -1186,7 +1187,7 @@ impl CheckWeight { let limit = Self::get_dispatch_limit_ratio(info.class) * maximum_weight; let added_weight = info.weight.min(limit); let next_weight = current_weight.saturating_add(added_weight); - if next_weight > limit { + if next_weight > limit && info.class != DispatchClass::Mandatory { Err(InvalidTransaction::ExhaustsResources.into()) } else { Ok(next_weight) @@ -1216,7 +1217,9 @@ impl CheckWeight { fn get_priority(info: ::DispatchInfo) -> TransactionPriority { match info.class { DispatchClass::Normal => info.weight.into(), - DispatchClass::Operational => Bounded::max_value() + DispatchClass::Operational => Bounded::max_value(), + // Mandatory extrinsics are only for inherents; never transactions. + DispatchClass::Mandatory => Bounded::min_value(), } } @@ -1271,6 +1274,9 @@ impl SignedExtension for CheckWeight { info: Self::DispatchInfo, len: usize, ) -> Result<(), TransactionValidityError> { + if info.class == DispatchClass::Mandatory { + Err(InvalidTransaction::MandatoryDispatch)? + } Self::do_pre_dispatch(info, len) } @@ -1281,6 +1287,9 @@ impl SignedExtension for CheckWeight { info: Self::DispatchInfo, len: usize, ) -> TransactionValidity { + if info.class == DispatchClass::Mandatory { + Err(InvalidTransaction::MandatoryDispatch)? + } Self::do_validate(info, len) } @@ -1299,6 +1308,21 @@ impl SignedExtension for CheckWeight { ) -> TransactionValidity { Self::do_validate(info, len) } + + fn post_dispatch( + _pre: Self::Pre, + info: Self::DispatchInfo, + _len: usize, + result: &DispatchResult, + ) -> Result<(), TransactionValidityError> { + // Since mandatory dispatched do not get validated for being overweight, we are sensitive + // to them actually being useful. Block producers are thus not allowed to include mandatory + // extrinsics that result in error. + if info.class == DispatchClass::Mandatory && result.is_err() { + Err(InvalidTransaction::BadMandatory)? + } + Ok(()) + } } impl Debug for CheckWeight { diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 54b4eeca6b..8ba756d683 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -147,7 +147,7 @@ decl_module! { /// `MinimumPeriod`. /// /// The dispatch origin for this call must be `Inherent`. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + #[weight = SimpleDispatchInfo::FixedMandatory(10_000)] fn set(origin, #[compact] now: T::Moment) { ensure_none(origin)?; assert!(!::DidUpdate::exists(), "Timestamp must be updated only once in the block"); diff --git a/primitives/runtime/src/generic/checked_extrinsic.rs b/primitives/runtime/src/generic/checked_extrinsic.rs index 7a71ef5218..673501bb91 100644 --- a/primitives/runtime/src/generic/checked_extrinsic.rs +++ b/primitives/runtime/src/generic/checked_extrinsic.rs @@ -78,8 +78,10 @@ where U::pre_dispatch(&self.function)?; (None, pre) }; - let res = self.function.dispatch(Origin::from(maybe_who)); - Extra::post_dispatch(pre, info, len); - Ok(res.map(|_| ()).map_err(|e| e.error)) + let res = self.function.dispatch(Origin::from(maybe_who)) + .map(|_| ()) + .map_err(|e| e.error); + Extra::post_dispatch(pre, info.clone(), len, &res)?; + Ok(res) } } diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 8bbaa50266..da5d5c4a81 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -39,6 +39,7 @@ pub use sp_arithmetic::traits::{ }; use sp_application_crypto::AppKey; use impl_trait_for_tuples::impl_for_tuples; +use crate::DispatchResult; /// A lazy value. pub trait Lazy { @@ -627,7 +628,7 @@ pub trait Dispatchable { /// Additional information that is returned by `dispatch`. Can be used to supply the caller /// with information about a `Dispatchable` that is ownly known post dispatch. type PostInfo: Eq + PartialEq + Clone + Copy + Encode + Decode + Printable; - /// Actually dispatch this call and result the result of it. + /// Actually dispatch this call and return the result of it. fn dispatch(self, origin: Self::Origin) -> crate::DispatchResultWithInfo; } @@ -735,8 +736,27 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq .map_err(Into::into) } - /// Do any post-flight stuff for a transaction. - fn post_dispatch(_pre: Self::Pre, _info: Self::DispatchInfo, _len: usize) { } + /// Do any post-flight stuff for an extrinsic. + /// + /// This gets given the `DispatchResult` `_result` from the extrinsic and can, if desired, + /// introduce a `TransactionValidityError`, causing the block to become invalid for including + /// it. + /// + /// WARNING: It is dangerous to return an error here. To do so will fundamentally invalidate the + /// transaction and any block that it is included in, causing the block author to not be + /// compensated for their work in validating the transaction or producing the block so far. + /// + /// It can only be used safely when you *know* that the extrinsic is one that can only be + /// introduced by the current block author; generally this implies that it is an inherent and + /// will come from either an offchain-worker or via `InherentData`. + fn post_dispatch( + _pre: Self::Pre, + _info: Self::DispatchInfo, + _len: usize, + _result: &DispatchResult, + ) -> Result<(), TransactionValidityError> { + Ok(()) + } /// Returns the list of unique identifier for this signed extension. /// @@ -804,8 +824,10 @@ impl SignedExtension for Tuple { pre: Self::Pre, info: Self::DispatchInfo, len: usize, - ) { - for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info.clone(), len); )* ) + result: &DispatchResult, + ) -> Result<(), TransactionValidityError> { + for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info.clone(), len, result)?; )* ); + Ok(()) } fn identifier() -> Vec<&'static str> { diff --git a/primitives/runtime/src/transaction_validity.rs b/primitives/runtime/src/transaction_validity.rs index 78f724b4d2..94cf44384d 100644 --- a/primitives/runtime/src/transaction_validity.rs +++ b/primitives/runtime/src/transaction_validity.rs @@ -52,6 +52,13 @@ pub enum InvalidTransaction { ExhaustsResources, /// Any other custom invalid validity that is not covered by this enum. Custom(u8), + /// An extrinsic with a Mandatory dispatch resulted in Error. This is indicative of either a + /// malicious validator or a buggy `provide_inherent`. In any case, it can result in dangerously + /// overweight blocks and therefore if found, invalidates the block. + BadMandatory, + /// A transaction with a mandatory dispatch. This is invalid; only inherent extrinsics are + /// allowed to have mandatory dispatches. + MandatoryDispatch, } impl InvalidTransaction { @@ -62,6 +69,14 @@ impl InvalidTransaction { _ => false, } } + + /// Returns if the reason for the invalidity was a mandatory call failing. + pub fn was_mandatory(&self) -> bool { + match self { + Self::BadMandatory => true, + _ => false, + } + } } impl From for &'static str { @@ -76,6 +91,10 @@ impl From for &'static str { "Transaction would exhausts the block limits", InvalidTransaction::Payment => "Inability to pay some fees (e.g. account balance too low)", + InvalidTransaction::BadMandatory => + "A call was labelled as mandatory, but resulted in an Error.", + InvalidTransaction::MandatoryDispatch => + "Tranaction dispatch is mandatory; transactions may not have mandatory dispatches.", InvalidTransaction::Custom(_) => "InvalidTransaction custom error", } } @@ -123,6 +142,15 @@ impl TransactionValidityError { Self::Unknown(_) => false, } } + + /// Returns `true` if the reason for the error was it being a mandatory dispatch that could not + /// be completed successfully. + pub fn was_mandatory(&self) -> bool { + match self { + Self::Invalid(e) => e.was_mandatory(), + Self::Unknown(_) => false, + } + } } impl From for &'static str { -- GitLab From aeee19510131ea1ed2471e51fb230511fb405c6f Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sun, 5 Apr 2020 14:28:37 +0200 Subject: [PATCH 166/300] Sort members in elections-phragmen genesis (#5522) * Sort members in elections-phragmen genesis * panic if duplicate member * print duplicate member --- frame/elections-phragmen/src/lib.rs | 33 ++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 28fc66bef9..036a5f492c 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -185,8 +185,12 @@ decl_storage! { // Note: all members will only vote for themselves, hence they must be given exactly // their own stake as total backing. Any sane election should behave as such. // Nonetheless, stakes will be updated for term 1 onwards according to the election. - >::append(&[(member.clone(), *stake)]) - .expect("Failed to append genesis members."); + Members::::mutate(|members| { + match members.binary_search_by(|(a, _b)| a.cmp(member)) { + Ok(_) => panic!("Duplicate member in elections phragmen genesis: {}", member), + Err(pos) => members.insert(pos, (member.clone(), *stake)), + } + }); // set self-votes to make persistent. >::vote( @@ -759,7 +763,7 @@ impl Module { let mut new_members = (&new_set_with_stake[..split_point]).to_vec(); // save the runners up as-is. They are sorted based on desirability. - // sort and save the members. + // save the members, sorted based on account id. new_members.sort_by(|i, j| i.0.cmp(&j.0)); let mut prime_votes: Vec<_> = new_members.iter().map(|c| (&c.0, BalanceOf::::zero())).collect(); @@ -1154,6 +1158,23 @@ mod tests { }) } + #[test] + fn genesis_members_unsorted_should_work() { + ExtBuilder::default().genesis_members(vec![(2, 20), (1, 10)]).build().execute_with(|| { + System::set_block_number(1); + assert_eq!(Elections::members(), vec![(1, 10), (2, 20)]); + + assert_eq!(Elections::voting(1), (10, vec![1])); + assert_eq!(Elections::voting(2), (20, vec![2])); + + // they will persist since they have self vote. + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members_ids(), vec![1, 2]); + }) + } + #[test] #[should_panic = "Genesis member does not have enough stake"] fn genesis_members_cannot_over_stake_0() { @@ -1168,6 +1189,12 @@ mod tests { ExtBuilder::default().voter_bond(20).genesis_members(vec![(1, 10), (2, 20)]).build(); } + #[test] + #[should_panic = "Duplicate member in elections phragmen genesis: 2"] + fn genesis_members_cannot_be_duplicate() { + ExtBuilder::default().genesis_members(vec![(1, 10), (2, 10), (2, 10)]).build(); + } + #[test] fn term_duration_zero_is_passive() { ExtBuilder::default() -- GitLab From 8cee4fe1a3eda836bd69383753dac54e51f6af04 Mon Sep 17 00:00:00 2001 From: pscott <30843220+pscott@users.noreply.github.com> Date: Sun, 5 Apr 2020 14:36:45 +0200 Subject: [PATCH 167/300] Make verbosity level mandatory with telemetry opt (#5057) * Make verbosity level mandatory instead of defaulting to 0 when using --telemetry-url * Update README docs * Change TelemetryError struct to enum * Return TelemetryParsingError instead of a Boxed dyn error * Replace spaces by tabs * Add example of expected format for telemetry-url * Remove UrlParsingError; Call to_string instead of parse for TelemetryEndpoints url --- bin/node-template/README.md | 4 ++-- client/cli/src/commands/runcmd.rs | 33 ++++++++++++++++++++++--------- docs/README.adoc | 4 ++-- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/bin/node-template/README.md b/bin/node-template/README.md index 4ae60478fc..c1730d51e5 100644 --- a/bin/node-template/README.md +++ b/bin/node-template/README.md @@ -56,7 +56,7 @@ cargo run -- \ --chain=local \ --alice \ --node-key 0000000000000000000000000000000000000000000000000000000000000001 \ - --telemetry-url ws://telemetry.polkadot.io:1024 \ + --telemetry-url 'ws://telemetry.polkadot.io:1024 0' \ --validator ``` @@ -69,7 +69,7 @@ cargo run -- \ --chain=local \ --bob \ --port 30334 \ - --telemetry-url ws://telemetry.polkadot.io:1024 \ + --telemetry-url 'ws://telemetry.polkadot.io:1024 0' \ --validator ``` diff --git a/client/cli/src/commands/runcmd.rs b/client/cli/src/commands/runcmd.rs index bdc57a38c3..30cefa5d0c 100644 --- a/client/cli/src/commands/runcmd.rs +++ b/client/cli/src/commands/runcmd.rs @@ -17,6 +17,7 @@ use std::path::PathBuf; use std::net::SocketAddr; use std::fs; +use std::fmt; use log::info; use structopt::{StructOpt, clap::arg_enum}; use names::{Generator, Name}; @@ -172,8 +173,8 @@ pub struct RunCmd { /// /// This flag can be passed multiple times as a means to specify multiple /// telemetry endpoints. Verbosity levels range from 0-9, with 0 denoting - /// the least verbosity. If no verbosity level is specified the default is - /// 0. + /// the least verbosity. + /// Expected format is 'URL VERBOSITY', e.g. `--telemetry-url 'wss://foo/bar 0'`. #[structopt(long = "telemetry-url", value_name = "URL VERBOSITY", parse(try_from_str = parse_telemetry_endpoints))] pub telemetry_endpoints: Vec<(String, u8)>, @@ -565,16 +566,30 @@ fn interface_str( } } -/// Default to verbosity level 0, if none is provided. -fn parse_telemetry_endpoints(s: &str) -> Result<(String, u8), Box> { +#[derive(Debug)] +enum TelemetryParsingError { + MissingVerbosity, + VerbosityParsingError(std::num::ParseIntError), +} + +impl std::error::Error for TelemetryParsingError {} + +impl fmt::Display for TelemetryParsingError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &*self { + TelemetryParsingError::MissingVerbosity => write!(f, "Verbosity level missing"), + TelemetryParsingError::VerbosityParsingError(e) => write!(f, "{}", e), + } + } +} + +fn parse_telemetry_endpoints(s: &str) -> Result<(String, u8), TelemetryParsingError> { let pos = s.find(' '); match pos { - None => { - Ok((s.to_owned(), 0)) - }, + None => Err(TelemetryParsingError::MissingVerbosity), Some(pos_) => { - let verbosity = s[pos_ + 1..].parse()?; - let url = s[..pos_].parse()?; + let url = s[..pos_].to_string(); + let verbosity = s[pos_ + 1..].parse().map_err(TelemetryParsingError::VerbosityParsingError)?; Ok((url, verbosity)) } } diff --git a/docs/README.adoc b/docs/README.adoc index 8d762fee05..51e7748b67 100644 --- a/docs/README.adoc +++ b/docs/README.adoc @@ -291,7 +291,7 @@ cargo run --release \-- \ --chain=local \ --alice \ --node-key 0000000000000000000000000000000000000000000000000000000000000001 \ - --telemetry-url ws://telemetry.polkadot.io:1024 \ + --telemetry-url 'ws://telemetry.polkadot.io:1024 0' \ --validator In the second terminal, we'll run the following to start Bob's Substrate node on a different TCP port of 30334, and with his chain database stored locally at `/tmp/bob`. We'll specify a value for the `--bootnodes` option that will connect his node to Alice's Bootnode ID on TCP port 30333: @@ -303,7 +303,7 @@ cargo run --release \-- \ --chain=local \ --bob \ --port 30334 \ - --telemetry-url ws://telemetry.polkadot.io:1024 \ + --telemetry-url 'ws://telemetry.polkadot.io:1024 0' \ --validator Additional Substrate CLI usage options are available and may be shown by running `cargo run \-- --help`. -- GitLab From f1d7d1d4d4f648536eefce6eefda6d0d2d1abb63 Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Mon, 6 Apr 2020 10:45:27 +0200 Subject: [PATCH 168/300] Revert "prepopulate CARGO_HOME caches (#5505)" (#5533) This reverts commit 25fb92ab97614c69e496f5fe628196ad910849d4. --- .gitlab-ci.yml | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1227153028..ddbd74d1bf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -63,24 +63,6 @@ variables: - rustup show - cargo --version - sccache -s - # if there is no directory for this $CI_COMMIT_REF_NAME/$CI_JOB_NAME - # create such directory and - # copy recursively all the files from the newest dir which has $CI_JOB_NAME, if it exists - - | - if [[ ! -d $CARGO_HOME ]]; then - mkdir -p /ci-cache/${CI_PROJECT_NAME}/cargo/${CI_COMMIT_REF_NAME}; - FRESH_CACHE=$(find /ci-cache/${CI_PROJECT_NAME}/cargo -mindepth 2 -maxdepth 2 \ - -type d -name ${CI_JOB_NAME} -exec stat --printf="%Y\t%n\n" {} \; |sort -n -r |head -1 |cut -f2); - if [[ -d $FRESH_CACHE ]]; then - echo "____Using" "$FRESH_CACHE" "to prepopulate the cache____"; - cp -r "${FRESH_CACHE}" "${CARGO_HOME}"; - touch ${CARGO_HOME}/config; - else - echo "_____No such cargo dir, proceeding from scratch_____"; - fi - else - echo "____No need to prepopulate the cache____"; - fi only: - master - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 @@ -96,7 +78,7 @@ variables: dependencies: [] interruptible: true tags: - - ci2 + - linux-docker .build-only: &build-only only: -- GitLab From 3f134a1af2462482b2868adf73a050a8da0d3934 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 6 Apr 2020 06:09:49 -0700 Subject: [PATCH 169/300] Update Externalities docs (#5537) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update externalities docs * Update primitives/externalities/src/lib.rs Co-Authored-By: Bastian Köcher * Update primitives/externalities/src/lib.rs Co-Authored-By: Bastian Köcher * Update primitives/externalities/src/lib.rs Co-Authored-By: Bastian Köcher * Update primitives/externalities/src/lib.rs Co-Authored-By: Bastian Köcher Co-authored-by: Bastian Köcher --- primitives/externalities/src/lib.rs | 30 ++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/primitives/externalities/src/lib.rs b/primitives/externalities/src/lib.rs index 6fbd239b89..6a7f943947 100644 --- a/primitives/externalities/src/lib.rs +++ b/primitives/externalities/src/lib.rs @@ -39,10 +39,14 @@ pub trait Externalities: ExtensionStore { /// Read runtime storage. fn storage(&self, key: &[u8]) -> Option>; - /// Get storage value hash. This may be optimized for large values. + /// Get storage value hash. + /// + /// This may be optimized for large values. fn storage_hash(&self, key: &[u8]) -> Option>; - /// Get child storage value hash. This may be optimized for large values. + /// Get child storage value hash. + /// + /// This may be optimized for large values. /// /// Returns an `Option` that holds the SCALE encoded hash. fn child_storage_hash( @@ -136,7 +140,7 @@ pub trait Externalities: ExtensionStore { /// Set or clear a storage entry (`key`) of current contract being called (effective immediately). fn place_storage(&mut self, key: Vec, value: Option>); - /// Set or clear a child storage entry. Return whether the operation succeeds. + /// Set or clear a child storage entry. fn place_child_storage( &mut self, storage_key: ChildStorageKey, @@ -148,16 +152,17 @@ pub trait Externalities: ExtensionStore { /// Get the identity of the chain. fn chain_id(&self) -> u64; - /// Get the trie root of the current storage map. This will also update all child storage keys - /// in the top-level storage map. + /// Get the trie root of the current storage map. /// - /// The hash is defined by the `Block`. + /// This will also update all child storage keys in the top-level storage map. /// - /// Returns the SCALE encoded hash. + /// The returned hash is defined by the `Block` and is SCALE encoded. fn storage_root(&mut self) -> Vec; - /// Get the trie root of a child storage map. This will also update the value of the child - /// storage keys in the top-level storage map. + /// Get the trie root of a child storage map. + /// + /// This will also update the value of the child storage keys in the top-level storage map. + /// /// If the storage root equals the default hash as defined by the trie, the key in the top-level /// storage map will be removed. fn child_storage_root( @@ -165,12 +170,11 @@ pub trait Externalities: ExtensionStore { storage_key: ChildStorageKey, ) -> Vec; - /// Get the change trie root of the current storage overlay at a block with given parent. - /// `parent` is expects a SCALE encoded hash. + /// Get the changes trie root of the current storage overlay at a block with given `parent`. /// - /// The hash is defined by the `Block`. + /// `parent` expects a SCALE encoded hash. /// - /// Returns the SCALE encoded hash. + /// The returned hash is defined by the `Block` and is SCALE encoded. fn storage_changes_root(&mut self, parent: &[u8]) -> Result>, ()>; /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -- GitLab From fc6ddaf82216c0aee9acd204c0d3e7d80c0f3aaa Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 6 Apr 2020 18:36:46 +0200 Subject: [PATCH 170/300] Prometheus Metrics: Turn notifications_total counter into notifications_sizes histogram (#5535) * Turn notifications_total into notifications_sizes * Address review --- client/network/src/service.rs | 28 ++++++++++++++++++---------- utils/prometheus/src/lib.rs | 1 + 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/client/network/src/service.rs b/client/network/src/service.rs index abe9231abf..4e9d8a7800 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -43,7 +43,7 @@ use libp2p::{kad::record, Multiaddr, PeerId}; use log::{error, info, trace, warn}; use parking_lot::Mutex; use prometheus_endpoint::{ - register, Counter, CounterVec, Gauge, GaugeVec, HistogramOpts, HistogramVec, Opts, PrometheusError, Registry, U64, + register, Counter, Gauge, GaugeVec, HistogramOpts, HistogramVec, Opts, PrometheusError, Registry, U64, }; use sc_peerset::PeersetHandle; use sp_consensus::import_queue::{BlockImportError, BlockImportResult, ImportQueue, Link}; @@ -824,7 +824,7 @@ struct Metrics { kbuckets_num_nodes: Gauge, network_per_sec_bytes: GaugeVec, notifications_queues_size: HistogramVec, - notifications_total: CounterVec, + notifications_sizes: HistogramVec, num_event_stream_channels: Gauge, opened_notification_streams: GaugeVec, peers_count: Gauge, @@ -879,11 +879,15 @@ impl Metrics { }, &["protocol"] )?, registry)?, - notifications_total: register(CounterVec::new( - Opts::new( - "sub_libp2p_notifications_total", - "Number of notification received from all nodes" - ), + notifications_sizes: register(HistogramVec::new( + HistogramOpts { + common_opts: Opts::new( + "sub_libp2p_notifications_sizes", + "Sizes of the notifications send to and received from all nodes" + ), + buckets: prometheus_endpoint::exponential_buckets(64.0, 4.0, 8) + .expect("parameters are always valid values; qed"), + }, &["direction", "protocol"] )?, registry)?, num_event_stream_channels: register(Gauge::new( @@ -921,8 +925,10 @@ impl Metrics { self.opened_notification_streams.with_label_values(&[&engine_id_to_string(&engine_id)]).dec(); }, Event::NotificationsReceived { messages, .. } => { - for (engine_id, _) in messages { - self.notifications_total.with_label_values(&["in", &engine_id_to_string(&engine_id)]).inc(); + for (engine_id, message) in messages { + self.notifications_sizes + .with_label_values(&["in", &engine_id_to_string(&engine_id)]) + .observe(message.len() as f64); } }, _ => {} @@ -983,7 +989,9 @@ impl Future for NetworkWorker { this.event_streams.push(sender), ServiceToWorkerMsg::WriteNotification { message, engine_id, target } => { if let Some(metrics) = this.metrics.as_ref() { - metrics.notifications_total.with_label_values(&["out", &engine_id_to_string(&engine_id)]).inc(); + metrics.notifications_sizes + .with_label_values(&["out", &engine_id_to_string(&engine_id)]) + .observe(message.len() as f64); } this.network_service.user_protocol_mut().write_notification(target, engine_id, message) }, diff --git a/utils/prometheus/src/lib.rs b/utils/prometheus/src/lib.rs index 00f0fb4f97..9030704cb7 100644 --- a/utils/prometheus/src/lib.rs +++ b/utils/prometheus/src/lib.rs @@ -19,6 +19,7 @@ pub use prometheus::{ self, Registry, Error as PrometheusError, Opts, Histogram, HistogramOpts, HistogramVec, + exponential_buckets, core::{ GenericGauge as Gauge, GenericCounter as Counter, GenericGaugeVec as GaugeVec, GenericCounterVec as CounterVec, -- GitLab From b14359cf5341a37028996a5002cf731a49312454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 6 Apr 2020 19:57:19 +0200 Subject: [PATCH 171/300] Remove myself. (#5544) --- docs/CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index d440434629..c20cdfa4f8 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -34,8 +34,8 @@ /primitives/core/src/sandbox.rs @pepyakin # Transaction pool -/client/transaction-pool/ @tomusdrw @NikVolf -/primitives/transaction-pool/ @tomusdrw @NikVolf +/client/transaction-pool/ @NikVolf +/primitives/transaction-pool/ @NikVolf # Offchain /client/offchain/ @tomusdrw -- GitLab From d579759a323e44101545816ea03f62d6efd02348 Mon Sep 17 00:00:00 2001 From: HackFisher Date: Tue, 7 Apr 2020 04:45:20 +0800 Subject: [PATCH 172/300] Add call hash as parameters of multisig related event (#5499) * Add call hash as parameters of multisig related event * update docs --- frame/utility/src/lib.rs | 31 ++++++++++++++++--------------- frame/utility/src/tests.rs | 4 ++-- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 49aea15a0f..3cd6d103cc 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -170,7 +170,8 @@ decl_event! { /// Events type. pub enum Event where AccountId = ::AccountId, - BlockNumber = ::BlockNumber + BlockNumber = ::BlockNumber, + CallHash = [u8; 32] { /// Batch of dispatches did not complete fully. Index of first failing dispatch given, as /// well as the error. @@ -178,17 +179,17 @@ decl_event! { /// Batch of dispatches completed fully with no error. BatchCompleted, /// A new multisig operation has begun. First param is the account that is approving, - /// second is the multisig account. - NewMultisig(AccountId, AccountId), + /// second is the multisig account, third is hash of the call. + NewMultisig(AccountId, AccountId, CallHash), /// A multisig operation has been approved by someone. First param is the account that is - /// approving, third is the multisig account. - MultisigApproval(AccountId, Timepoint, AccountId), + /// approving, third is the multisig account, fourth is hash of the call. + MultisigApproval(AccountId, Timepoint, AccountId, CallHash), /// A multisig operation has been executed. First param is the account that is - /// approving, third is the multisig account. - MultisigExecuted(AccountId, Timepoint, AccountId, DispatchResult), + /// approving, third is the multisig account, fourth is hash of the call to be executed. + MultisigExecuted(AccountId, Timepoint, AccountId, CallHash, DispatchResult), /// A multisig operation has been cancelled. First param is the account that is - /// cancelling, third is the multisig account. - MultisigCancelled(AccountId, Timepoint, AccountId), + /// cancelling, third is the multisig account, fourth is hash of the call. + MultisigCancelled(AccountId, Timepoint, AccountId, CallHash), } } @@ -347,7 +348,7 @@ decl_module! { if (m.approvals.len() as u16) < threshold - 1 { m.approvals.insert(pos, who.clone()); >::insert(&id, call_hash, m); - Self::deposit_event(RawEvent::MultisigApproval(who, timepoint, id)); + Self::deposit_event(RawEvent::MultisigApproval(who, timepoint, id, call_hash)); return Ok(()) } } else { @@ -360,7 +361,7 @@ decl_module! { let _ = T::Currency::unreserve(&m.depositor, m.deposit); >::remove(&id, call_hash); Self::deposit_event(RawEvent::MultisigExecuted( - who, timepoint, id, result.map(|_| ()).map_err(|e| e.error) + who, timepoint, id, call_hash, result.map(|_| ()).map_err(|e| e.error) )); } else { ensure!(maybe_timepoint.is_none(), Error::::UnexpectedTimepoint); @@ -374,7 +375,7 @@ decl_module! { depositor: who.clone(), approvals: vec![who.clone()], }); - Self::deposit_event(RawEvent::NewMultisig(who, id)); + Self::deposit_event(RawEvent::NewMultisig(who, id, call_hash)); } else { return call.dispatch(frame_system::RawOrigin::Signed(id).into()) .map(|_| ()).map_err(|e| e.error) @@ -444,7 +445,7 @@ decl_module! { if let Err(pos) = m.approvals.binary_search(&who) { m.approvals.insert(pos, who.clone()); >::insert(&id, call_hash, m); - Self::deposit_event(RawEvent::MultisigApproval(who, timepoint, id)); + Self::deposit_event(RawEvent::MultisigApproval(who, timepoint, id, call_hash)); } else { Err(Error::::AlreadyApproved)? } @@ -460,7 +461,7 @@ decl_module! { depositor: who.clone(), approvals: vec![who.clone()], }); - Self::deposit_event(RawEvent::NewMultisig(who, id)); + Self::deposit_event(RawEvent::NewMultisig(who, id, call_hash)); } else { Err(Error::::NoApprovalsNeeded)? } @@ -520,7 +521,7 @@ decl_module! { let _ = T::Currency::unreserve(&m.depositor, m.deposit); >::remove(&id, call_hash); - Self::deposit_event(RawEvent::MultisigCancelled(who, timepoint, id)); + Self::deposit_event(RawEvent::MultisigCancelled(who, timepoint, id, call_hash)); Ok(()) } } diff --git a/frame/utility/src/tests.rs b/frame/utility/src/tests.rs index 9fcd525020..9fcfe55b26 100644 --- a/frame/utility/src/tests.rs +++ b/frame/utility/src/tests.rs @@ -303,10 +303,10 @@ fn multisig_2_of_3_cannot_reissue_same_call() { assert_eq!(Balances::free_balance(multi), 5); assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call.clone())); - assert_ok!(Utility::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), call)); + assert_ok!(Utility::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), call.clone())); let err = DispatchError::from(BalancesError::::InsufficientBalance).stripped(); - expect_event(RawEvent::MultisigExecuted(3, now(), multi, Err(err))); + expect_event(RawEvent::MultisigExecuted(3, now(), multi, call.using_encoded(blake2_256), Err(err))); }); } -- GitLab From 8d985b06468990a8e3d282fa34b4c3846f8ff336 Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Tue, 7 Apr 2020 09:25:57 +0200 Subject: [PATCH 173/300] change (ci): merge check warnings into test linux job (#5546) * change (ci): merge check warnings into test linux job * change (ci): newline doesn't make sense here --- .gitlab-ci.yml | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ddbd74d1bf..b9f30dc8aa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -196,14 +196,14 @@ test-linux-stable: &test-linux - WASM_BUILD_NO_COLOR=1 time cargo test --all --release --verbose --locked |& tee output.log - sccache -s - after_script: - - echo "___Collecting warnings for check_warnings job___" + - echo "____Test job successful, checking for warnings____" - awk '/^warning:/,/^$/ { print }' output.log > ${CI_COMMIT_SHORT_SHA}_warnings.log - artifacts: - name: $CI_COMMIT_SHORT_SHA - expire_in: 3 days - paths: - - ${CI_COMMIT_SHORT_SHA}_warnings.log + - if [ -s ${CI_COMMIT_SHORT_SHA}_warnings.log ]; then + cat ${CI_COMMIT_SHORT_SHA}_warnings.log; + exit 1; + else + echo "___No warnings___"; + fi test-dependency-rules: stage: test @@ -417,26 +417,6 @@ build-rust-doc-release: - echo "" > ./crate-docs/index.html - sccache -s -check_warnings: - stage: build - <<: *docker-env - except: - variables: - - $DEPLOY_TAG - variables: - GIT_STRATEGY: none - needs: - - job: test-linux-stable - artifacts: true - script: - - if [ -s ${CI_COMMIT_SHORT_SHA}_warnings.log ]; then - cat ${CI_COMMIT_SHORT_SHA}_warnings.log; - exit 1; - else - echo "___No warnings___"; - fi - - check-polkadot-companion-status: stage: post-build-test image: parity/tools:latest -- GitLab From 545aa61537151bd56e249f35bdb17acda57f82e1 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 7 Apr 2020 11:35:00 +0200 Subject: [PATCH 174/300] Generate Unit Tests for Benchmarks (#5527) * Update to latest staking * generate tests for benchmarking * add tests, fix warnings * starting on democracy * impl_benchmark_tests * Way more readable * add test feature flag (does this work?) * Fix `successful_origin` impl * democracry benchmark tests * Fix example benchmarks, add tests * identity benchmark tests * Update im-online benchmark tests * try to add session benchmarking tests (problem with mock) * staking and timestamp * add test for treasury, issue with dynamic contains * utility * Vesting * test instead of check * hide until we figure out what is wrong * add docs * close code * Create custom mock for session-pallet-benchmarking * Use refcell pattern * make un-pub * test-linux-stable includes `runtime-benchmarks` feature * Revert "test-linux-stable includes `runtime-benchmarks` feature" This reverts commit a2dab38abd18ac3eb8a6220e4a00e687740bd38c. * run tests in `--release` * undo balance change * build wasm --- .gitlab-ci.yml | 2 +- Cargo.lock | 9 + frame/balances/src/benchmarking.rs | 42 ++++ frame/benchmarking/Cargo.toml | 1 + frame/benchmarking/src/lib.rs | 123 ++++++++++-- frame/benchmarking/src/tests.rs | 31 ++- frame/democracy/src/benchmarking.rs | 41 ++++ frame/democracy/src/tests.rs | 4 +- frame/example/src/lib.rs | 27 ++- frame/identity/src/benchmarking.rs | 24 +++ frame/identity/src/lib.rs | 2 +- frame/im-online/src/benchmarking.rs | 41 +--- frame/session/benchmarking/Cargo.toml | 11 ++ frame/session/benchmarking/src/lib.rs | 29 ++- frame/session/benchmarking/src/mock.rs | 184 ++++++++++++++++++ frame/session/src/mock.rs | 10 + frame/session/src/tests.rs | 16 +- frame/staking/src/benchmarking.rs | 58 ++++-- frame/support/src/lib.rs | 2 + frame/system/src/lib.rs | 9 +- frame/timestamp/src/benchmarking.rs | 14 ++ frame/timestamp/src/lib.rs | 14 +- frame/treasury/src/benchmarking.rs | 22 +++ frame/treasury/src/tests.rs | 22 ++- frame/utility/src/benchmarking.rs | 21 ++ frame/utility/src/tests.rs | 2 +- frame/vesting/src/benchmarking.rs | 18 ++ .../state-machine/src/in_memory_backend.rs | 4 + 28 files changed, 667 insertions(+), 116 deletions(-) create mode 100644 frame/session/benchmarking/src/mock.rs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b9f30dc8aa..2c141c51d1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -287,7 +287,7 @@ test-runtime-benchmarks: - $DEPLOY_TAG script: - cd bin/node/cli - - BUILD_DUMMY_WASM_BINARY=1 time cargo check --verbose --features runtime-benchmarks + - WASM_BUILD_NO_COLOR=1 time cargo test --release --verbose --features runtime-benchmarks - sccache -s test-linux-stable-int: diff --git a/Cargo.lock b/Cargo.lock index 6038064ab0..28cc98cabf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1436,6 +1436,7 @@ dependencies = [ "frame-system", "linregress", "parity-scale-codec", + "paste", "sp-api", "sp-io", "sp-runtime", @@ -4433,9 +4434,17 @@ name = "pallet-session-benchmarking" version = "2.0.0-alpha.5" dependencies = [ "frame-benchmarking", + "frame-support", "frame-system", + "pallet-balances", "pallet-session", "pallet-staking", + "pallet-staking-reward-curve", + "pallet-timestamp", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", "sp-runtime", "sp-std", ] diff --git a/frame/balances/src/benchmarking.rs b/frame/balances/src/benchmarking.rs index 161fdab96b..a6206cd84f 100644 --- a/frame/balances/src/benchmarking.rs +++ b/frame/balances/src/benchmarking.rs @@ -119,3 +119,45 @@ benchmarks! { let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); }: set_balance(RawOrigin::Root, user_lookup, 0.into(), 0.into()) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests_composite::{ExtBuilder, Test}; + use frame_support::assert_ok; + + #[test] + fn transfer() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(test_benchmark_transfer::()); + }); + } + + #[test] + fn transfer_best_case() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(test_benchmark_transfer_best_case::()); + }); + } + + #[test] + fn transfer_keep_alive() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(test_benchmark_transfer_keep_alive::()); + }); + } + + #[test] + fn transfer_set_balance() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(test_benchmark_set_balance::()); + }); + } + + #[test] + fn transfer_set_balance_killing() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(test_benchmark_set_balance_killing::()); + }); + } +} diff --git a/frame/benchmarking/Cargo.toml b/frame/benchmarking/Cargo.toml index 7ed6066419..3221c7a1d4 100644 --- a/frame/benchmarking/Cargo.toml +++ b/frame/benchmarking/Cargo.toml @@ -10,6 +10,7 @@ description = "Macro for benchmarking a FRAME runtime." [dependencies] linregress = "0.1" +paste = "0.1" codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api", default-features = false } sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../primitives/runtime-interface", default-features = false } diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index b1427b792d..49f398d59d 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -29,6 +29,7 @@ pub use analysis::Analysis; #[doc(hidden)] pub use sp_io::storage::root as storage_root; pub use sp_runtime::traits::Dispatchable; +pub use paste; /// Construct pallet benchmarks for weighing dispatchables. /// @@ -124,6 +125,26 @@ pub use sp_runtime::traits::Dispatchable; /// }: { m.into_iter().collect::() } /// } /// ``` +/// +/// Test functions are automatically generated for each benchmark and are accessible to you when you +/// run `cargo test`. All tests are named `test_benchmark_`, expect you to pass them +/// the Runtime Trait, and run them in a test externalities environment. The test function runs your +/// benchmark just like a regular benchmark, but only testing at the lowest and highest values for +/// each component. The function will return `Ok(())` if the benchmarks return no errors. +/// +/// You can construct benchmark tests like so: +/// +/// ```ignore +/// #[test] +/// fn test_benchmarks() { +/// new_test_ext().execute_with(|| { +/// assert_ok!(test_benchmark_dummy::()); +/// assert_err!(test_benchmark_other_name::(), "Bad origin"); +/// assert_ok!(test_benchmark_sort_vector::()); +/// assert_err!(test_benchmark_broken_benchmark::(), "You forgot to sort!"); +/// }); +/// } +/// ``` #[macro_export] macro_rules! benchmarks { ( @@ -134,9 +155,12 @@ macro_rules! benchmarks { } $( $rest:tt )* ) => { - $crate::benchmarks_iter!(NO_INSTANCE { - $( { $common , $common_from , $common_to , $common_instancer } )* - } ( ) $( $rest )* ); + $crate::benchmarks_iter!( + NO_INSTANCE + { $( { $common , $common_from , $common_to , $common_instancer } )* } + ( ) + $( $rest )* + ); } } @@ -150,9 +174,12 @@ macro_rules! benchmarks_instance { } $( $rest:tt )* ) => { - $crate::benchmarks_iter!(INSTANCE { - $( { $common , $common_from , $common_to , $common_instancer } )* - } ( ) $( $rest )* ); + $crate::benchmarks_iter!( + INSTANCE + { $( { $common , $common_from , $common_to , $common_instancer } )* } + ( ) + $( $rest )* + ); } } @@ -168,7 +195,11 @@ macro_rules! benchmarks_iter { $( $rest:tt )* ) => { $crate::benchmarks_iter! { - $instance { $( $common )* } ( $( $names )* ) $name { $( $code )* }: $name ( $origin $( , $arg )* ) $( $rest )* + $instance + { $( $common )* } + ( $( $names )* ) + $name { $( $code )* }: $name ( $origin $( , $arg )* ) + $( $rest )* } }; // no instance mutation arm: @@ -181,9 +212,12 @@ macro_rules! benchmarks_iter { ) => { $crate::benchmarks_iter! { NO_INSTANCE - { $( $common )* } ( $( $names )* ) $name { $( $code )* }: { + { $( $common )* } + ( $( $names )* ) + $name { $( $code )* }: { as $crate::Dispatchable>::dispatch(Call::::$dispatch($($arg),*), $origin.into())?; - } $( $rest )* + } + $( $rest )* } }; // instance mutation arm: @@ -196,9 +230,12 @@ macro_rules! benchmarks_iter { ) => { $crate::benchmarks_iter! { INSTANCE - { $( $common )* } ( $( $names )* ) $name { $( $code )* }: { + { $( $common )* } + ( $( $names )* ) + $name { $( $code )* }: { as $crate::Dispatchable>::dispatch(Call::::$dispatch($($arg),*), $origin.into())?; - } $( $rest )* + } + $( $rest )* } }; // iteration arm: @@ -210,14 +247,26 @@ macro_rules! benchmarks_iter { $( $rest:tt )* ) => { $crate::benchmark_backend! { - $instance $name { $( $common )* } { } { $eval } { $( $code )* } + $instance + $name + { $( $common )* } + { } + { $eval } + { $( $code )* } } - $crate::benchmarks_iter!( $instance { $( $common )* } ( $( $names )* $name ) $( $rest )* ); + $crate::benchmarks_iter!( + $instance + { $( $common )* } + ( $( $names )* $name ) + $( $rest )* + ); }; // iteration-exit arm ( $instance:ident { $( $common:tt )* } ( $( $names:ident )* ) ) => { $crate::selected_benchmark!( $instance $( $names ),* ); $crate::impl_benchmark!( $instance $( $names ),* ); + #[cfg(test)] + $crate::impl_benchmark_tests!( $( $names ),* ); } } @@ -703,6 +752,54 @@ macro_rules! impl_benchmark { } } +// This creates unit tests from the main benchmark macro. +// They run the benchmark using the `high` and `low` value for each component +// and ensure that everything completes successfully. +#[macro_export] +macro_rules! impl_benchmark_tests { + ( + $( $name:ident ),* + ) => { + $( + $crate::paste::item! { + fn [] () -> Result<(), &'static str> + where T: frame_system::Trait + { + let selected_benchmark = SelectedBenchmark::$name; + let components = >::components(&selected_benchmark); + + for (_, (name, low, high)) in components.iter().enumerate() { + // Test only the low and high value, assuming values in the middle won't break + for component_value in vec![low, high] { + // Select the max value for all the other components. + let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter() + .enumerate() + .map(|(_, (n, _, h))| + if n == name { + (*n, *component_value) + } else { + (*n, *h) + } + ) + .collect(); + + // Set the block number to 1 so events are deposited. + frame_system::Module::::set_block_number(1.into()); + // Set up the externalities environment for the setup we want to benchmark. + let closure_to_benchmark = >::instance(&selected_benchmark, &c)?; + // Run the benchmark + closure_to_benchmark()?; + // Reset the state + $crate::benchmarking::wipe_db(); + } + } + Ok(()) + } + } + )* + } +} + /// This macro adds pallet benchmarks to a `Vec` object. /// diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index b3537617c7..3e79ca3875 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -22,7 +22,9 @@ use super::*; use codec::Decode; use sp_std::prelude::*; use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::{H256, Header}}; -use frame_support::{dispatch::DispatchResult, decl_module, impl_outer_origin}; +use frame_support::{ + dispatch::DispatchResult, decl_module, impl_outer_origin, assert_ok, assert_err, ensure +}; use frame_system::{RawOrigin, ensure_signed, ensure_none}; decl_module! { @@ -107,13 +109,24 @@ benchmarks!{ }: other_dummy (RawOrigin::Signed(caller), b.into()) sort_vector { - let x in 0 .. 10000; + let x in 1 .. 10000; let mut m = Vec::::new(); - for i in 0..x { + for i in (0..x).rev() { m.push(i); } }: { m.sort(); + ensure!(m[0] == 0, "You forgot to sort!") + } + + broken_benchmark { + let x in 1 .. 10000; + let mut m = Vec::::new(); + for i in (0..x).rev() { + m.push(i); + } + }: { + ensure!(m[0] == 0, "You forgot to sort!") } } @@ -157,7 +170,7 @@ fn benchmarks_macro_works_for_non_dispatchable() { let selected_benchmark = SelectedBenchmark::sort_vector; let components = >::components(&selected_benchmark); - assert_eq!(components, vec![(BenchmarkParameter::x, 0, 10000)]); + assert_eq!(components, vec![(BenchmarkParameter::x, 1, 10000)]); let closure = >::instance( &selected_benchmark, @@ -166,3 +179,13 @@ fn benchmarks_macro_works_for_non_dispatchable() { assert_eq!(closure(), Ok(())); } + +#[test] +fn benchmarks_generate_unit_tests() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_dummy::()); + assert_err!(test_benchmark_other_name::(), "Bad origin"); + assert_ok!(test_benchmark_sort_vector::()); + assert_err!(test_benchmark_broken_benchmark::(), "You forgot to sort!"); + }); +} diff --git a/frame/democracy/src/benchmarking.rs b/frame/democracy/src/benchmarking.rs index 83f7ca795f..6165a4f897 100644 --- a/frame/democracy/src/benchmarking.rs +++ b/frame/democracy/src/benchmarking.rs @@ -445,3 +445,44 @@ benchmarks! { }: _(RawOrigin::Signed(proxy), referendum_index) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{new_test_ext, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_propose::()); + assert_ok!(test_benchmark_second::()); + assert_ok!(test_benchmark_vote::()); + assert_ok!(test_benchmark_proxy_vote::()); + assert_ok!(test_benchmark_emergency_cancel::()); + assert_ok!(test_benchmark_external_propose::()); + assert_ok!(test_benchmark_external_propose_majority::()); + assert_ok!(test_benchmark_external_propose_default::()); + assert_ok!(test_benchmark_fast_track::()); + assert_ok!(test_benchmark_veto_external::()); + assert_ok!(test_benchmark_cancel_referendum::()); + assert_ok!(test_benchmark_cancel_queued::()); + assert_ok!(test_benchmark_open_proxy::()); + assert_ok!(test_benchmark_activate_proxy::()); + assert_ok!(test_benchmark_close_proxy::()); + assert_ok!(test_benchmark_deactivate_proxy::()); + assert_ok!(test_benchmark_delegate::()); + assert_ok!(test_benchmark_undelegate::()); + assert_ok!(test_benchmark_clear_public_proposals::()); + assert_ok!(test_benchmark_note_preimage::()); + assert_ok!(test_benchmark_note_imminent_preimage::()); + assert_ok!(test_benchmark_reap_preimage::()); + assert_ok!(test_benchmark_unlock::()); + assert_ok!(test_benchmark_remove_vote::()); + assert_ok!(test_benchmark_remove_other_vote::()); + assert_ok!(test_benchmark_proxy_delegate::()); + assert_ok!(test_benchmark_proxy_undelegate::()); + assert_ok!(test_benchmark_proxy_remove_vote::()); + }); + } +} diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index 8fca8fa4cf..e7320da082 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -126,6 +126,8 @@ impl Contains for OneToFive { fn sorted_members() -> Vec { vec![1, 2, 3, 4, 5] } + #[cfg(feature = "runtime-benchmarks")] + fn add(_m: &u64) {} } thread_local! { static PREIMAGE_BYTE_DEPOSIT: RefCell = RefCell::new(0); @@ -162,7 +164,7 @@ impl super::Trait for Test { type Scheduler = Scheduler; } -fn new_test_ext() -> sp_io::TestExternalities { +pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); pallet_balances::GenesisConfig::{ balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index e8ce89a863..51062c47ec 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -671,26 +671,41 @@ mod benchmarking { // This will measure the execution time of `set_dummy` for b in [1..1000] range. set_dummy { let b in ...; - let caller = account("caller", 0, 0); - }: set_dummy (RawOrigin::Signed(caller), b.into()) + }: set_dummy (RawOrigin::Root, b.into()) // This will measure the execution time of `set_dummy` for b in [1..10] range. another_set_dummy { let b in 1 .. 10; - let caller = account("caller", 0, 0); - }: set_dummy (RawOrigin::Signed(caller), b.into()) + }: set_dummy (RawOrigin::Root, b.into()) // This will measure the execution time of sorting a vector. sort_vector { let x in 0 .. 10000; let mut m = Vec::::new(); - for i in 0..x { + for i in (0..x).rev() { m.push(i); } }: { m.sort(); } } + + #[cfg(test)] + mod tests { + use super::*; + use crate::tests::{new_test_ext, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_accumulate_dummy::()); + assert_ok!(test_benchmark_set_dummy::()); + assert_ok!(test_benchmark_another_set_dummy::()); + assert_ok!(test_benchmark_sort_vector::()); + }); + } + } } #[cfg(test)] @@ -764,7 +779,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> sp_io::TestExternalities { + pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. pallet_balances::GenesisConfig::::default().assimilate_storage(&mut t).unwrap(); diff --git a/frame/identity/src/benchmarking.rs b/frame/identity/src/benchmarking.rs index b5236e6219..fe99cd9907 100644 --- a/frame/identity/src/benchmarking.rs +++ b/frame/identity/src/benchmarking.rs @@ -280,3 +280,27 @@ benchmarks! { } }: _(RawOrigin::Root, caller_lookup) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{new_test_ext, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_add_registrar::()); + assert_ok!(test_benchmark_set_identity::()); + assert_ok!(test_benchmark_set_subs::()); + assert_ok!(test_benchmark_clear_identity::()); + assert_ok!(test_benchmark_request_judgement::()); + assert_ok!(test_benchmark_cancel_request::()); + assert_ok!(test_benchmark_set_fee::()); + assert_ok!(test_benchmark_set_account_id::()); + assert_ok!(test_benchmark_set_fields::()); + assert_ok!(test_benchmark_provide_judgement::()); + assert_ok!(test_benchmark_kill_identity::()); + }); + } +} diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index e18689001b..2a2d1c9cf8 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -977,7 +977,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> sp_io::TestExternalities { + pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. pallet_balances::GenesisConfig:: { diff --git a/frame/im-online/src/benchmarking.rs b/frame/im-online/src/benchmarking.rs index 973bd0c361..e0e74bccfa 100644 --- a/frame/im-online/src/benchmarking.rs +++ b/frame/im-online/src/benchmarking.rs @@ -79,46 +79,15 @@ benchmarks! { #[cfg(test)] mod tests { - use crate::*; - use super::SelectedBenchmark; - use crate::mock::*; + use super::*; + use crate::mock::{new_test_ext, Runtime}; use frame_support::assert_ok; #[test] - fn test_heartbeat_benchmark() { + fn test_benchmarks() { new_test_ext().execute_with(|| { - let k = 10; - - assert_eq!(ReceivedHeartbeats::iter_prefix(0).count(), 0); - - let selected_benchmark = SelectedBenchmark::heartbeat; - let c = vec![(frame_benchmarking::BenchmarkParameter::k, k)]; - let closure_to_benchmark = - >::instance( - &selected_benchmark, - &c - ).unwrap(); - - assert_ok!(closure_to_benchmark()); - - assert_eq!(ReceivedHeartbeats::iter_prefix(0).count(), 1); - }); - } - - #[test] - fn test_validate_unsigned_benchmark() { - new_test_ext().execute_with(|| { - let k = 10; - - let selected_benchmark = SelectedBenchmark::validate_unsigned; - let c = vec![(frame_benchmarking::BenchmarkParameter::k, k)]; - let closure_to_benchmark = - >::instance( - &selected_benchmark, - &c - ).unwrap(); - - assert_ok!(closure_to_benchmark()); + assert_ok!(test_benchmark_heartbeat::()); + assert_ok!(test_benchmark_validate_unsigned::()); }); } } diff --git a/frame/session/benchmarking/Cargo.toml b/frame/session/benchmarking/Cargo.toml index 181fb37bfd..140116c82c 100644 --- a/frame/session/benchmarking/Cargo.toml +++ b/frame/session/benchmarking/Cargo.toml @@ -13,9 +13,19 @@ sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../.. sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../../system" } frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../../benchmarking" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../support" } pallet-staking = { version = "2.0.0-alpha.5", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../../session" } +[dev-dependencies] +serde = { version = "1.0.101" } +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +pallet-staking-reward-curve = { version = "2.0.0-alpha.5", path = "../../staking/reward-curve" } +sp-io ={ path = "../../../primitives/io", version = "2.0.0-alpha.5"} +pallet-timestamp = { version = "2.0.0-alpha.5", path = "../../timestamp" } +pallet-balances = { version = "2.0.0-alpha.5", path = "../../balances" } + [features] default = ["std"] std = [ @@ -23,6 +33,7 @@ std = [ "sp-runtime/std", "frame-system/std", "frame-benchmarking/std", + "frame-support/std", "pallet-staking/std", "pallet-session/std", ] diff --git a/frame/session/benchmarking/src/lib.rs b/frame/session/benchmarking/src/lib.rs index db925bd72e..3b91c2fdc5 100644 --- a/frame/session/benchmarking/src/lib.rs +++ b/frame/session/benchmarking/src/lib.rs @@ -19,6 +19,8 @@ #![cfg_attr(not(feature = "std"), no_std)] +mod mock; + use sp_std::prelude::*; use sp_std::vec; @@ -42,16 +44,33 @@ benchmarks! { set_keys { let n in 1 .. MAX_NOMINATIONS as u32; - let validator = create_validator_with_nominators::(n, MAX_NOMINATIONS as u32)?; + let v_stash = create_validator_with_nominators::(n, MAX_NOMINATIONS as u32)?; + let v_controller = pallet_staking::Module::::bonded(&v_stash).ok_or("not stash")?; let keys = T::Keys::default(); let proof: Vec = vec![0,1,2,3]; - }: _(RawOrigin::Signed(validator), keys, proof) + }: _(RawOrigin::Signed(v_controller), keys, proof) purge_keys { let n in 1 .. MAX_NOMINATIONS as u32; - let validator = create_validator_with_nominators::(n, MAX_NOMINATIONS as u32)?; + let v_stash = create_validator_with_nominators::(n, MAX_NOMINATIONS as u32)?; + let v_controller = pallet_staking::Module::::bonded(&v_stash).ok_or("not stash")?; let keys = T::Keys::default(); let proof: Vec = vec![0,1,2,3]; - Session::::set_keys(RawOrigin::Signed(validator.clone()).into(), keys, proof)?; - }: _(RawOrigin::Signed(validator)) + Session::::set_keys(RawOrigin::Signed(v_controller.clone()).into(), keys, proof)?; + }: _(RawOrigin::Signed(v_controller)) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::mock::{new_test_ext, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_set_keys::()); + assert_ok!(test_benchmark_purge_keys::()); + }); + } } diff --git a/frame/session/benchmarking/src/mock.rs b/frame/session/benchmarking/src/mock.rs new file mode 100644 index 0000000000..219a1904e0 --- /dev/null +++ b/frame/session/benchmarking/src/mock.rs @@ -0,0 +1,184 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Mock file for staking fuzzing. + +#![cfg(test)] + +use sp_runtime::traits::{Convert, SaturatedConversion, IdentityLookup}; +use frame_support::{impl_outer_origin, impl_outer_dispatch, parameter_types}; + +type AccountId = u64; +type AccountIndex = u32; +type BlockNumber = u64; +type Balance = u64; + +type System = frame_system::Module; +type Balances = pallet_balances::Module; +type Staking = pallet_staking::Module; +type Session = pallet_session::Module; + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + pallet_staking::Staking, + } +} + +pub struct CurrencyToVoteHandler; +impl Convert for CurrencyToVoteHandler { + fn convert(x: u64) -> u64 { + x + } +} +impl Convert for CurrencyToVoteHandler { + fn convert(x: u128) -> u64 { + x.saturated_into() + } +} + +#[derive(Clone, Eq, PartialEq, Debug)] +pub struct Test; + +impl frame_system::Trait for Test { + type Origin = Origin; + type Index = AccountIndex; + type BlockNumber = BlockNumber; + type Call = Call; + type Hash = sp_core::H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = sp_runtime::testing::Header; + type Event = (); + type BlockHashCount = (); + type MaximumBlockWeight = (); + type AvailableBlockRatio = (); + type MaximumBlockLength = (); + type Version = (); + type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (Balances,); +} +parameter_types! { + pub const ExistentialDeposit: Balance = 10; +} +impl pallet_balances::Trait for Test { + type Balance = Balance; + type Event = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; +} + +parameter_types! { + pub const MinimumPeriod: u64 = 5; +} +impl pallet_timestamp::Trait for Test { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; +} +impl pallet_session::historical::Trait for Test { + type FullIdentification = pallet_staking::Exposure; + type FullIdentificationOf = pallet_staking::ExposureOf; +} + +sp_runtime::impl_opaque_keys! { + pub struct SessionKeys { + pub foo: sp_runtime::testing::UintAuthorityId, + } +} + +pub struct TestSessionHandler; +impl pallet_session::SessionHandler for TestSessionHandler { + const KEY_TYPE_IDS: &'static [sp_runtime::KeyTypeId] = &[]; + + fn on_genesis_session(_validators: &[(AccountId, Ks)]) {} + + fn on_new_session( + _: bool, + _: &[(AccountId, Ks)], + _: &[(AccountId, Ks)], + ) {} + + fn on_disabled(_: usize) {} +} + +impl pallet_session::Trait for Test { + type SessionManager = pallet_session::historical::NoteHistoricalRoot; + type Keys = SessionKeys; + type ShouldEndSession = pallet_session::PeriodicSessions<(), ()>; + type NextSessionRotation = pallet_session::PeriodicSessions<(), ()>; + type SessionHandler = TestSessionHandler; + type Event = (); + type ValidatorId = AccountId; + type ValidatorIdOf = pallet_staking::StashOf; + type DisabledValidatorsThreshold = (); +} +pallet_staking_reward_curve::build! { + const I_NPOS: sp_runtime::curve::PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); +} +parameter_types! { + pub const RewardCurve: &'static sp_runtime::curve::PiecewiseLinear<'static> = &I_NPOS; + pub const MaxNominatorRewardedPerValidator: u32 = 64; +} + +pub type Extrinsic = sp_runtime::testing::TestXt; +type SubmitTransaction = frame_system::offchain::TransactionSubmitter< + sp_runtime::testing::UintAuthorityId, + Test, + Extrinsic, +>; + +impl pallet_staking::Trait for Test { + type Currency = Balances; + type UnixTime = pallet_timestamp::Module; + type CurrencyToVote = CurrencyToVoteHandler; + type RewardRemainder = (); + type Event = (); + type Slash = (); + type Reward = (); + type SessionsPerEra = (); + type SlashDeferDuration = (); + type SlashCancelOrigin = frame_system::EnsureRoot; + type BondingDuration = (); + type SessionInterface = Self; + type RewardCurve = RewardCurve; + type NextNewSession = Session; + type ElectionLookahead = (); + type Call = Call; + type SubmitTransaction = SubmitTransaction; + type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; +} + +impl crate::Trait for Test {} + +pub fn new_test_ext() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + sp_io::TestExternalities::new(t) +} diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index dd28d35749..a888dcfb28 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -150,6 +150,16 @@ pub fn reset_before_session_end_called() { BEFORE_SESSION_END_CALLED.with(|b| *b.borrow_mut() = false); } +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + GenesisConfig:: { + keys: NEXT_VALIDATORS.with(|l| + l.borrow().iter().cloned().map(|i| (i, i, UintAuthorityId(i).into())).collect() + ), + }.assimilate_storage(&mut t).unwrap(); + sp_io::TestExternalities::new(t) +} + #[derive(Clone, Eq, PartialEq)] pub struct Test; diff --git a/frame/session/src/tests.rs b/frame/session/src/tests.rs index 4e95d91cc7..abfd9f738b 100644 --- a/frame/session/src/tests.rs +++ b/frame/session/src/tests.rs @@ -21,21 +21,11 @@ use frame_support::{traits::OnInitialize, assert_ok}; use sp_core::crypto::key_types::DUMMY; use sp_runtime::testing::UintAuthorityId; use mock::{ - NEXT_VALIDATORS, SESSION_CHANGED, TEST_SESSION_CHANGED, authorities, force_new_session, - set_next_validators, set_session_length, session_changed, Test, Origin, System, Session, - reset_before_session_end_called, before_session_end_called, + SESSION_CHANGED, TEST_SESSION_CHANGED, authorities, force_new_session, + set_next_validators, set_session_length, session_changed, Origin, System, Session, + reset_before_session_end_called, before_session_end_called, new_test_ext, }; -fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - GenesisConfig:: { - keys: NEXT_VALIDATORS.with(|l| - l.borrow().iter().cloned().map(|i| (i, i, UintAuthorityId(i).into())).collect() - ), - }.assimilate_storage(&mut t).unwrap(); - sp_io::TestExternalities::new(t) -} - fn initialize_block(block: u64) { SESSION_CHANGED.with(|l| *l.borrow_mut() = false); System::set_block_number(block); diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index 60d0c13237..2686623aa1 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -98,8 +98,8 @@ pub fn create_validators_with_nominators_for_era(v: u32, n: u32) -> Re Ok(()) } -// This function generates one validator being nominated by n nominators. -// It starts an era and creates pending payouts. +// This function generates one validator being nominated by n nominators, and returns +//the validator stash account. It also starts an era and creates pending payouts. pub fn create_validator_with_nominators(n: u32, upper_bound: u32) -> Result { let mut points_total = 0; let mut points_individual = Vec::new(); @@ -114,7 +114,7 @@ pub fn create_validator_with_nominators(n: u32, upper_bound: u32) -> R let stash_lookup: ::Source = T::Lookup::unlookup(v_stash.clone()); points_total += 10; - points_individual.push((v_stash, 10)); + points_individual.push((v_stash.clone(), 10)); // Give the validator n nominators, but keep total users in the system the same. for i in 0 .. upper_bound { @@ -144,7 +144,7 @@ pub fn create_validator_with_nominators(n: u32, upper_bound: u32) -> R let total_payout = T::Currency::minimum_balance() * 1000.into(); >::insert(current_era, total_payout); - Ok(v_controller) + Ok(v_stash) } benchmarks! { @@ -368,16 +368,10 @@ benchmarks! { #[cfg(test)] mod tests { - use crate::*; - use crate::mock::*; + use super::*; + use crate::mock::{ExtBuilder, Test, Balances, Staking, Origin}; use frame_support::assert_ok; - use crate::benchmarking::{ - create_validators_with_nominators_for_era, - create_validator_with_nominators, - SelectedBenchmark, - }; - #[test] fn create_validators_with_nominators_for_era_works() { ExtBuilder::default().has_stakers(false).build().execute_with(|| { @@ -399,19 +393,16 @@ mod tests { ExtBuilder::default().has_stakers(false).build().execute_with(|| { let n = 10; - let validator = create_validator_with_nominators::( + let validator_stash = create_validator_with_nominators::( n, MAX_NOMINATIONS as u32, ).unwrap(); let current_era = CurrentEra::get().unwrap(); - let controller = validator; - let ledger = Staking::ledger(&controller).unwrap(); - let stash = ledger.stash; - let original_free_balance = Balances::free_balance(&stash); - assert_ok!(Staking::payout_stakers(Origin::signed(1337), stash, current_era)); - let new_free_balance = Balances::free_balance(&stash); + let original_free_balance = Balances::free_balance(&validator_stash); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), validator_stash, current_era)); + let new_free_balance = Balances::free_balance(&validator_stash); assert!(original_free_balance < new_free_balance); }); @@ -434,4 +425,33 @@ mod tests { assert_ok!(closure_to_benchmark()); }); } + + #[test] + fn test_benchmarks() { + ExtBuilder::default().has_stakers(false).build().execute_with(|| { + assert_ok!(test_benchmark_bond::()); + assert_ok!(test_benchmark_bond_extra::()); + assert_ok!(test_benchmark_unbond::()); + assert_ok!(test_benchmark_withdraw_unbonded::()); + assert_ok!(test_benchmark_validate::()); + assert_ok!(test_benchmark_nominate::()); + assert_ok!(test_benchmark_chill::()); + assert_ok!(test_benchmark_set_payee::()); + assert_ok!(test_benchmark_set_controller::()); + assert_ok!(test_benchmark_set_validator_count::()); + assert_ok!(test_benchmark_force_no_eras::()); + assert_ok!(test_benchmark_force_new_era::()); + assert_ok!(test_benchmark_force_new_era_always::()); + assert_ok!(test_benchmark_set_invulnerables::()); + assert_ok!(test_benchmark_force_unstake::()); + assert_ok!(test_benchmark_cancel_deferred_slash::()); + assert_ok!(test_benchmark_payout_stakers::()); + assert_ok!(test_benchmark_rebond::()); + assert_ok!(test_benchmark_set_history_depth::()); + assert_ok!(test_benchmark_reap_stash::()); + assert_ok!(test_benchmark_new_era::()); + assert_ok!(test_benchmark_do_slash::()); + assert_ok!(test_benchmark_payout_all::()); + }); + } } diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 81438ea1bd..d37a438fc6 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -140,6 +140,8 @@ macro_rules! ord_parameter_types { fn contains(t: &$type) -> bool { &$value == t } fn sorted_members() -> $crate::sp_std::prelude::Vec<$type> { vec![$value] } fn count() -> usize { 1 } + #[cfg(feature = "runtime-benchmarks")] + fn add(_: &$type) {} } } } diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 050ab2654b..38cd206a10 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -620,9 +620,12 @@ impl< #[cfg(feature = "runtime-benchmarks")] fn successful_origin() -> O { - let caller: AccountId = Default::default(); - // Who::add(&caller); - O::from(RawOrigin::Signed(caller)) + let members = Who::sorted_members(); + let first_member = match members.get(0) { + Some(account) => account.clone(), + None => Default::default(), + }; + O::from(RawOrigin::Signed(first_member.clone())) } } diff --git a/frame/timestamp/src/benchmarking.rs b/frame/timestamp/src/benchmarking.rs index 65b4dbf2b0..01a3d502a8 100644 --- a/frame/timestamp/src/benchmarking.rs +++ b/frame/timestamp/src/benchmarking.rs @@ -34,3 +34,17 @@ benchmarks! { let n in ...; }: _(RawOrigin::None, n.into()) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{new_test_ext, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_set::()); + }); + } +} diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 8ba756d683..6df8b46065 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -271,6 +271,11 @@ mod tests { use sp_core::H256; use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; + pub fn new_test_ext() -> TestExternalities { + let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + TestExternalities::new(t) + } + impl_outer_origin! { pub enum Origin for Test where system = frame_system {} } @@ -316,8 +321,7 @@ mod tests { #[test] fn timestamp_works() { - let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - TestExternalities::new(t).execute_with(|| { + new_test_ext().execute_with(|| { Timestamp::set_timestamp(42); assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); assert_eq!(Timestamp::now(), 69); @@ -327,8 +331,7 @@ mod tests { #[test] #[should_panic(expected = "Timestamp must be updated only once in the block")] fn double_timestamp_should_fail() { - let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - TestExternalities::new(t).execute_with(|| { + new_test_ext().execute_with(|| { Timestamp::set_timestamp(42); assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); let _ = Timestamp::dispatch(Call::set(70), Origin::NONE); @@ -338,8 +341,7 @@ mod tests { #[test] #[should_panic(expected = "Timestamp must increment by at least between sequential blocks")] fn block_period_minimum_enforced() { - let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - TestExternalities::new(t).execute_with(|| { + new_test_ext().execute_with(|| { Timestamp::set_timestamp(42); let _ = Timestamp::dispatch(Call::set(46), Origin::NONE); }); diff --git a/frame/treasury/src/benchmarking.rs b/frame/treasury/src/benchmarking.rs index 0f9582ebc4..f901576c95 100644 --- a/frame/treasury/src/benchmarking.rs +++ b/frame/treasury/src/benchmarking.rs @@ -217,3 +217,25 @@ benchmarks! { Treasury::::on_initialize(T::BlockNumber::zero()); } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{new_test_ext, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_propose_spend::()); + assert_ok!(test_benchmark_reject_proposal::()); + assert_ok!(test_benchmark_approve_proposal::()); + assert_ok!(test_benchmark_report_awesome::()); + assert_ok!(test_benchmark_retract_tip::()); + assert_ok!(test_benchmark_tip_new::()); + assert_ok!(test_benchmark_tip::()); + assert_ok!(test_benchmark_close_tip::()); + assert_ok!(test_benchmark_on_initialize::()); + }); + } +} diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index 1f6dbecef5..5ad78dcad7 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -19,7 +19,7 @@ #![cfg(test)] use super::*; - +use std::cell::RefCell; use frame_support::{ assert_noop, assert_ok, impl_outer_origin, parameter_types, weights::Weight, traits::{Contains, OnInitialize} @@ -74,16 +74,24 @@ impl pallet_balances::Trait for Test { type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; } +thread_local! { + static TEN_TO_FOURTEEN: RefCell> = RefCell::new(vec![10,11,12,13,14]); +} pub struct TenToFourteen; impl Contains for TenToFourteen { - fn contains(n: &u64) -> bool { - *n >= 10 && *n <= 14 - } fn sorted_members() -> Vec { - vec![10, 11, 12, 13, 14] + TEN_TO_FOURTEEN.with(|v| { + v.borrow().clone() + }) } #[cfg(feature = "runtime-benchmarks")] - fn add(_: &u64) { unimplemented!() } + fn add(new: &u64) { + TEN_TO_FOURTEEN.with(|v| { + let mut members = v.borrow_mut(); + members.push(*new); + members.sort(); + }) + } } parameter_types! { pub const ProposalBond: Permill = Permill::from_percent(5); @@ -115,7 +123,7 @@ type System = frame_system::Module; type Balances = pallet_balances::Module; type Treasury = Module; -fn new_test_ext() -> sp_io::TestExternalities { +pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); pallet_balances::GenesisConfig::{ // Total issuance will be 200 with treasury account initialized at ED. diff --git a/frame/utility/src/benchmarking.rs b/frame/utility/src/benchmarking.rs index f16754fad5..fc8783b49a 100644 --- a/frame/utility/src/benchmarking.rs +++ b/frame/utility/src/benchmarking.rs @@ -146,3 +146,24 @@ benchmarks! { Utility::::as_multi(RawOrigin::Signed(caller.clone()).into(), s as u16, signatories.clone(), None, call.clone())?; }: _(RawOrigin::Signed(caller), s as u16, signatories, timepoint, call_hash) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{new_test_ext, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_batch::()); + assert_ok!(test_benchmark_as_sub::()); + assert_ok!(test_benchmark_as_multi_create::()); + assert_ok!(test_benchmark_as_multi_approve::()); + assert_ok!(test_benchmark_as_multi_complete::()); + assert_ok!(test_benchmark_approve_as_multi_create::()); + assert_ok!(test_benchmark_approve_as_multi_approve::()); + assert_ok!(test_benchmark_cancel_as_multi::()); + }); + } +} diff --git a/frame/utility/src/tests.rs b/frame/utility/src/tests.rs index 9fcfe55b26..68bdabd6d9 100644 --- a/frame/utility/src/tests.rs +++ b/frame/utility/src/tests.rs @@ -109,7 +109,7 @@ type Utility = Module; use pallet_balances::Call as BalancesCall; use pallet_balances::Error as BalancesError; -fn new_test_ext() -> sp_io::TestExternalities { +pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 10)], diff --git a/frame/vesting/src/benchmarking.rs b/frame/vesting/src/benchmarking.rs index 2ef8ed9ef8..be2cb4cb2b 100644 --- a/frame/vesting/src/benchmarking.rs +++ b/frame/vesting/src/benchmarking.rs @@ -124,3 +124,21 @@ benchmarks! { }: _(RawOrigin::Signed(from), to_lookup, vesting_schedule) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{ExtBuilder, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + ExtBuilder::default().existential_deposit(256).build().execute_with(|| { + assert_ok!(test_benchmark_vest_locked::()); + assert_ok!(test_benchmark_vest_not_locked::()); + assert_ok!(test_benchmark_vest_other_locked::()); + assert_ok!(test_benchmark_vest_other_not_locked::()); + assert_ok!(test_benchmark_vested_transfer::()); + }); + } +} diff --git a/primitives/state-machine/src/in_memory_backend.rs b/primitives/state-machine/src/in_memory_backend.rs index 8cbed90e9a..ecd4532cf2 100644 --- a/primitives/state-machine/src/in_memory_backend.rs +++ b/primitives/state-machine/src/in_memory_backend.rs @@ -364,6 +364,10 @@ impl Backend for InMemory where H::Out: Codec { fn usage_info(&self) -> UsageInfo { UsageInfo::empty() } + + fn wipe(&self) -> Result<(), Self::Error> { + Ok(()) + } } #[cfg(test)] -- GitLab From 9f1bddf9f9a1e86022f3d6a759fdbbbc37e51e79 Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Tue, 7 Apr 2020 11:36:57 +0200 Subject: [PATCH 175/300] Benchmark Offences Pallet (#5411) * Add initial report_ofence bench. * Remove unused imports * Style nit * Add nominators * Remove logs. * Nits. * Add nominators param. * Reorg, comment. * Remove whitespaces. * Apply review suggestion: move benchmark to own crate. * Remove import. * Remove line. * Add feature flag. * Pass can_report. * Cleaning up. * More cleaning --- Cargo.lock | 404 +++++++++++++------------ bin/node/runtime/Cargo.toml | 2 + bin/node/runtime/src/lib.rs | 6 + frame/im-online/src/lib.rs | 6 +- frame/offences/Cargo.toml | 1 + frame/offences/benchmarking/Cargo.toml | 43 +++ frame/offences/benchmarking/src/lib.rs | 175 +++++++++++ frame/offences/src/lib.rs | 7 +- frame/scored-pool/src/lib.rs | 4 +- frame/staking/src/lib.rs | 20 +- 10 files changed, 463 insertions(+), 205 deletions(-) create mode 100644 frame/offences/benchmarking/Cargo.toml create mode 100644 frame/offences/benchmarking/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 28cc98cabf..5b2ce24399 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,12 +70,11 @@ dependencies = [ [[package]] name = "alga" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658f9468113d34781f6ca9d014d174c74b73de870f1e0e3ad32079bbab253b19" +checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2" dependencies = [ "approx", - "libm", "num-complex", "num-traits 0.2.11", ] @@ -100,9 +99,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" +checksum = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff" [[package]] name = "app_dirs" @@ -133,9 +132,9 @@ checksum = "75153c95fdedd7db9732dfbfc3702324a1627eec91ba56e37cd0ac78314ab2ed" [[package]] name = "arc-swap" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" +checksum = "d663a8e9a99154b5fb793032533f6328da35e23aac63d5c152279aa8ba356825" [[package]] name = "arrayref" @@ -174,7 +173,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" dependencies = [ "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -269,9 +268,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.45" +version = "0.3.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad235dabf00f36301792cfe82499880ba54c6486be094d1047b02bacb67c14e8" +checksum = "b1e692897359247cc6bb902933361652380af0f1b7651ae5c5013407f30e109e" dependencies = [ "backtrace-sys", "cfg-if", @@ -281,9 +280,9 @@ dependencies = [ [[package]] name = "backtrace-sys" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca797db0057bae1a7aa2eef3283a874695455cecf08a43bfb8507ee0ebc1ed69" +checksum = "7de8aba10a69c8e8d7622c5710229485ec32e9d55fdad160ea559c086fdcd118" dependencies = [ "cc", "libc", @@ -451,9 +450,9 @@ checksum = "b170cd256a3f9fa6b9edae3e44a7dfdfc77e8124dbc3e2612d75f9c3e2396dae" [[package]] name = "bstr" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502ae1441a0a5adb8fbd38a5955a6416b9493e92b465de5e4a9bde6a539c2c48" +checksum = "2889e6d50f394968c8bf4240dc3f2a7eb4680844d27308f798229ac9d4725f41" dependencies = [ "lazy_static", "memchr", @@ -604,9 +603,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "0.29.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92986241798376849e1a007827041fed9bb36195822c2049d18e174420e0534" +checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a" dependencies = [ "glob 0.3.0", "libc", @@ -1001,7 +1000,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47c5e5ac752e18207b12e16b10631ae5f7f68f8805f335f9b817ead83d9ffce1" dependencies = [ "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -1045,13 +1044,13 @@ checksum = "11c0346158a19b3627234e15596f5e465c360fcdb97d817bcb255e0510f5a788" [[package]] name = "derive_more" -version = "0.99.3" +version = "0.99.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a806e96c59a76a5ba6e18735b6cf833344671e61e7863f2edb5c518ea2cac95c" +checksum = "e2323f3f47db9a0e77ce7a300605d8d2098597fc451ed1a97bb1f6411bb550a7" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -1103,9 +1102,9 @@ dependencies = [ [[package]] name = "doc-comment" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "807e5847c39ad6a11eac66de492ed1406f76a260eb8656e8740cad9eabc69c27" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "ed25519-dalek" @@ -1153,7 +1152,7 @@ checksum = "ecf634c5213044b8d54a46dd282cf5dd1f86bb5cb53e92c409cb4680a7fb9894" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -1190,18 +1189,18 @@ checksum = "516aa8d7a71cb00a1c4146f0798549b93d083d4f189b3ced8f3de6b8f11ee6c4" [[package]] name = "erased-serde" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7d80305c9bd8cd78e3c753eb9fb110f83621e5211f1a3afffcc812b104daf9" +checksum = "d88b6d1705e16a4d62e05ea61cc0496c2bd190f4fa8e5c1f11ce747be6bcf3d1" dependencies = [ "serde", ] [[package]] name = "errno" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" +checksum = "b480f641ccf0faf324e20c1d3e53d81b7484c698b42ea677f6907ae4db195371" dependencies = [ "errno-dragonfly", "libc", @@ -1228,7 +1227,7 @@ dependencies = [ "fixed-hash", "impl-rlp", "impl-serde 0.3.0", - "tiny-keccak 2.0.1", + "tiny-keccak 2.0.2", ] [[package]] @@ -1334,7 +1333,7 @@ checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", "synstructure", ] @@ -1404,9 +1403,9 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" +checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" dependencies = [ "cfg-if", "crc32fast", @@ -1523,7 +1522,7 @@ dependencies = [ "frame-support-procedural-tools", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -1534,7 +1533,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -1543,7 +1542,7 @@ version = "2.0.0-alpha.5" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -1743,7 +1742,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -1896,9 +1895,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "globset" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" +checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120" dependencies = [ "aho-corasick", "bstr", @@ -1951,20 +1950,20 @@ dependencies = [ [[package]] name = "h2" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5c295d1c0c68e4e42003d75f908f5e16a1edd1cbe0b0d02e4dc2006a384f47" +checksum = "377038bf3c89d18d6ca1431e7a5027194fbd724ca10592b9487ede5e8e144f42" dependencies = [ "bytes 0.5.4", "fnv", "futures-core", "futures-sink", "futures-util", - "http 0.2.0", + "http 0.2.1", "indexmap", "log", "slab", - "tokio 0.2.13", + "tokio 0.2.16", "tokio-util", ] @@ -2004,9 +2003,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8" +checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e" dependencies = [ "libc", ] @@ -2081,9 +2080,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" +checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" dependencies = [ "bytes 0.5.4", "fnv", @@ -2109,7 +2108,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" dependencies = [ "bytes 0.5.4", - "http 0.2.0", + "http 0.2.1", ] [[package]] @@ -2159,16 +2158,16 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7b15203263d1faa615f9337d79c1d37959439dc46c2b4faab33286fadc2a1c5" +checksum = "ed6081100e960d9d74734659ffc9cc91daf1c0fc7aceb8eaa94ee1a3f5046f2e" dependencies = [ "bytes 0.5.4", "futures-channel", "futures-core", "futures-util", - "h2 0.2.2", - "http 0.2.0", + "h2 0.2.4", + "http 0.2.1", "http-body 0.3.1", "httparse", "itoa", @@ -2176,7 +2175,7 @@ dependencies = [ "net2", "pin-project", "time", - "tokio 0.2.13", + "tokio 0.2.16", "tower-service", "want 0.3.0", ] @@ -2190,11 +2189,11 @@ dependencies = [ "bytes 0.5.4", "ct-logs", "futures-util", - "hyper 0.13.3", + "hyper 0.13.4", "log", "rustls 0.17.0", "rustls-native-certs", - "tokio 0.2.13", + "tokio 0.2.16", "tokio-rustls", "webpki", ] @@ -2265,7 +2264,7 @@ checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -2310,9 +2309,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a859057dc563d1388c1e816f98a1892629075fc046ed06e845b883bb8b2916fb" +checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" [[package]] name = "itertools" @@ -2340,9 +2339,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cb931d43e71f560c81badb0191596562bafad2be06a3f9025b845c847c60df5" +checksum = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055" dependencies = [ "wasm-bindgen", ] @@ -2395,7 +2394,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -2568,9 +2567,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" [[package]] name = "libc" -version = "0.2.67" +version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" +checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" [[package]] name = "libflate" @@ -2596,9 +2595,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.1.4" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" +checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" @@ -2678,7 +2677,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d472e9d522f588805c77801de10b957be84e10f019ca5f869fa1825b15ea9b" dependencies = [ "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -3163,11 +3162,11 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" +checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" dependencies = [ - "rustc_version", + "autocfg 1.0.0", ] [[package]] @@ -3271,9 +3270,9 @@ checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" [[package]] name = "multimap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc" +checksum = "d8883adfde9756c1d30b0f519c9b8c502a94b41ac62f696453c37c7fc0a958ce" [[package]] name = "multistream-select" @@ -3564,6 +3563,7 @@ dependencies = [ "pallet-indices", "pallet-membership", "pallet-offences", + "pallet-offences-benchmarking", "pallet-randomness-collective-flip", "pallet-recovery", "pallet-scheduler", @@ -3789,9 +3789,9 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4dc79f9e6c81bef96148c8f6b8e72ad4541caa4a24373e900a36da07de03a3" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" dependencies = [ "autocfg 1.0.0", "num-bigint", @@ -3815,6 +3815,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" dependencies = [ "autocfg 1.0.0", + "libm", ] [[package]] @@ -4349,6 +4350,24 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-offences-benchmarking" +version = "2.0.0-alpha.5" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-im-online", + "pallet-offences", + "pallet-session", + "pallet-staking", + "parity-scale-codec", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", +] + [[package]] name = "pallet-randomness-collective-flip" version = "2.0.0-alpha.5" @@ -4505,7 +4524,7 @@ dependencies = [ "proc-macro2", "quote 1.0.3", "sp-runtime", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -4703,7 +4722,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -4737,7 +4756,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ "proc-macro2", - "syn 1.0.16", + "syn 1.0.17", "synstructure", ] @@ -4808,9 +4827,9 @@ dependencies = [ [[package]] name = "paste" -version = "0.1.7" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e1afe738d71b1ebab5f1207c055054015427dbfc7bbe9ee1266894156ec046" +checksum = "ab4fb1930692d1b6a9cfabdde3d06ea0a7d186518e2f4d67660d8970e2fa647a" dependencies = [ "paste-impl", "proc-macro-hack", @@ -4818,14 +4837,14 @@ dependencies = [ [[package]] name = "paste-impl" -version = "0.1.7" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d4dc4a7f6f743211c5aab239640a65091535d97d43d92a52bca435a640892bb" +checksum = "a62486e111e571b1e93b710b61e8f493c0013be39629b714cb166bdb06aa5a8a" dependencies = [ "proc-macro-hack", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -4889,7 +4908,7 @@ checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -4996,52 +5015,47 @@ dependencies = [ [[package]] name = "proc-macro-error" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7959c6467d962050d639361f7703b2051c43036d03493c36f01d440fdd3138a" +checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7" dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", "version_check", ] [[package]] name = "proc-macro-error-attr" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4002d9f55991d5e019fb940a90e1a95eb80c24e77cb2462dd4dc869604d543a" +checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", "syn-mid", "version_check", ] [[package]] name = "proc-macro-hack" -version = "0.5.11" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" -dependencies = [ - "proc-macro2", - "quote 1.0.3", - "syn 1.0.16", -] +checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" [[package]] name = "proc-macro-nested" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" +checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" [[package]] name = "proc-macro2" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" +checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" dependencies = [ "unicode-xid 0.2.0", ] @@ -5113,7 +5127,7 @@ dependencies = [ "itertools", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -5128,9 +5142,9 @@ dependencies = [ [[package]] name = "protobuf" -version = "2.10.2" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a5325d019a4d837d3abde0a836920f959e33d350f77b5f1e289e061e774942" +checksum = "71964f34fd51cf04882d7ae3325fa0794d4cad66a03d0003f38d8ae4f63ba126" [[package]] name = "pwasm-utils" @@ -5456,9 +5470,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.3.4" +version = "1.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" +checksum = "7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3" dependencies = [ "aho-corasick", "memchr", @@ -5477,9 +5491,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.16" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1132f845907680735a84409c3bebc64d1364a5683ffbce899550cd09d5eaefc1" +checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" [[package]] name = "region" @@ -5504,9 +5518,9 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.11" +version = "0.16.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "741ba1704ae21999c00942f9f5944f801e977f54302af346b596287599ad1862" +checksum = "1ba5a8ec64ee89a76c98c549af81ff14813df09c3e6dc4766c3856da48597a0c" dependencies = [ "cc", "lazy_static", @@ -5525,9 +5539,9 @@ checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" [[package]] name = "rlp" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a44d5ae8afcb238af8b75640907edc6c931efcfab2c854e81ed35fa080f84cd" +checksum = "4a7d3f9bed94764eac15b8f14af59fac420c236adaff743b7bcc88e265cb4345" dependencies = [ "rustc-hex", ] @@ -5637,7 +5651,7 @@ checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -5653,9 +5667,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" +checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76" [[package]] name = "safe-mix" @@ -5787,7 +5801,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -5828,7 +5842,7 @@ dependencies = [ "substrate-prometheus-endpoint", "tempfile", "time", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -6087,7 +6101,7 @@ dependencies = [ "substrate-test-runtime-client", "substrate-test-runtime-transaction-pool", "tempfile", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -6265,7 +6279,7 @@ dependencies = [ "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -6410,7 +6424,7 @@ dependencies = [ "fnv", "futures 0.3.4", "futures-timer 3.0.2", - "hyper 0.13.3", + "hyper 0.13.4", "hyper-rustls", "log", "num_cpus", @@ -6430,7 +6444,7 @@ dependencies = [ "sp-utils", "substrate-test-runtime-client", "threadpool", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -6711,9 +6725,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507a9e6e8ffe0a4e0ebb9a10293e62fdf7657c06f1b8bb07a8fcf697d2abf295" +checksum = "039c25b130bd8c1321ee2d7de7fde2659fa9c2744e4bb29711cfc852ea53cd19" dependencies = [ "lazy_static", "winapi 0.3.8", @@ -6766,7 +6780,7 @@ checksum = "f8584eea9b9ff42825b46faf46a8c24d2cff13ec152fa2a50df788b87c07ee28" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -6781,21 +6795,22 @@ dependencies = [ [[package]] name = "security-framework" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97bbedbe81904398b6ebb054b3e912f99d55807125790f3198ac990d98def5b0" +checksum = "572dfa3a0785509e7a44b5b4bebcf94d41ba34e9ed9eb9df722545c3b3c4144a" dependencies = [ "bitflags", "core-foundation", "core-foundation-sys", + "libc", "security-framework-sys", ] [[package]] name = "security-framework-sys" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06fd2f23e31ef68dd2328cc383bd493142e46107a3a0e24f7d734e3f3b80fe4c" +checksum = "8ddb15a5fec93b7021b8a9e96009c5d8d51c15673569f7c0f6b7204e5b7b404f" dependencies = [ "core-foundation-sys", "libc", @@ -6846,29 +6861,29 @@ checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" [[package]] name = "serde" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff" +checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" +checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] name = "serde_json" -version = "1.0.48" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25" +checksum = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9" dependencies = [ "itoa", "ryu", @@ -6991,7 +7006,7 @@ checksum = "a945ec7f7ce853e89ffa36be1e27dce9a43e82ff9093bf3461c30d5da74ed11b" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -7037,7 +7052,7 @@ dependencies = [ "bytes 0.5.4", "flate2", "futures 0.3.4", - "http 0.2.0", + "http 0.2.1", "httparse", "log", "rand 0.7.3", @@ -7081,7 +7096,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -7309,7 +7324,7 @@ dependencies = [ "sp-storage", "substrate-bip39", "tiny-bip39", - "tiny-keccak 2.0.1", + "tiny-keccak 2.0.2", "twox-hash", "wasmi", "zeroize", @@ -7321,7 +7336,7 @@ version = "2.0.0-alpha.5" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -7429,7 +7444,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -7489,7 +7504,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -7752,9 +7767,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe43617218c0805c6eb37160119dc3c548110a67786da7218d1c6555212f073" +checksum = "c8faa2719539bbe9d77869bfb15d4ee769f99525e707931452c97b693b3f159d" dependencies = [ "clap", "lazy_static", @@ -7763,15 +7778,15 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e79c80e0f4efd86ca960218d4e056249be189ff1c42824dcd9a7f51a56f0bd" +checksum = "3f88b8e18c69496aad6f9ddf4630dd7d585bcaf765786cb415b9aec2fe5a0430" dependencies = [ "heck", "proc-macro-error", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -7792,7 +7807,7 @@ dependencies = [ "heck", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -7878,7 +7893,7 @@ dependencies = [ "sc-rpc-api", "serde", "sp-storage", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -7911,10 +7926,10 @@ dependencies = [ "async-std", "derive_more", "futures-util", - "hyper 0.13.3", + "hyper 0.13.4", "log", "prometheus", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -8127,9 +8142,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" +checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" dependencies = [ "proc-macro2", "quote 1.0.3", @@ -8144,7 +8159,7 @@ checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -8164,7 +8179,7 @@ checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", "unicode-xid 0.2.0", ] @@ -8233,7 +8248,7 @@ dependencies = [ "lazy_static", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", "version_check", ] @@ -8248,22 +8263,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee14bf8e6767ab4c687c9e8bc003879e042a96fd67a3ba5934eadb6536bef4db" +checksum = "f0570dc61221295909abdb95c739f2e74325e14293b2026b0a7e195091ec54ae" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4" +checksum = "227362df41d566be41a28f64401e07a043157c21c14b9785a0d8e256f940a8fd" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -8297,9 +8312,9 @@ dependencies = [ [[package]] name = "tiny-bip39" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6848cd8f566953ce1e8faeba12ee23cbdbb0437754792cd857d44628b5685e3" +checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" dependencies = [ "failure", "hmac", @@ -8322,9 +8337,9 @@ dependencies = [ [[package]] name = "tiny-keccak" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2953ca5148619bc99695c1274cb54c5275bbb913c6adad87e72eaf8db9787f69" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" dependencies = [ "crunchy", ] @@ -8365,12 +8380,13 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa5e81d6bc4e67fe889d5783bd2a128ab2e0cfa487e0be16b6a8d177b101616" +checksum = "ee5a0dd887e37d37390c13ff8ac830f992307fe30a1fff0ab8427af67211ba28" dependencies = [ "bytes 0.5.4", "fnv", + "futures-core", "iovec", "lazy_static", "libc", @@ -8468,7 +8484,7 @@ checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -8498,7 +8514,7 @@ checksum = "4adb8b3e5f86b707f1b54e7c15b6de52617a823608ccda98a15d3a24222f265a" dependencies = [ "futures-core", "rustls 0.17.0", - "tokio 0.2.13", + "tokio 0.2.16", "webpki", ] @@ -8601,16 +8617,16 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" +checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" dependencies = [ "bytes 0.5.4", "futures-core", "futures-sink", "log", "pin-project-lite", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -8646,7 +8662,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fbad39da2f9af1cae3016339ad7f2c7a9e870f12e8fd04c4fd7ef35b30c0d2b" dependencies = [ "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -8915,9 +8931,9 @@ dependencies = [ [[package]] name = "wabt-sys" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af5d153dc96aad7dc13ab90835b892c69867948112d95299e522d370c4e13a08" +checksum = "23d7043ebb3e5d96fad7a8d3ca22ee9880748ff8c3e18092cfb2a49d3b8f9084" dependencies = [ "cc", "cmake", @@ -8973,9 +8989,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" -version = "0.2.59" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3557c397ab5a8e347d434782bcd31fc1483d927a6826804cec05cc792ee2519d" +checksum = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -8983,24 +8999,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.59" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0da9c9a19850d3af6df1cb9574970b566d617ecfaf36eb0b706b6f3ef9bd2f8" +checksum = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd" dependencies = [ "bumpalo", "lazy_static", "log", "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "457414a91863c0ec00090dba537f88ab955d93ca6555862c29b6d860990b8a8a" +checksum = "7add542ea1ac7fdaa9dc25e031a6af33b7d63376292bd24140c637d00d1c312a" dependencies = [ "cfg-if", "js-sys", @@ -9010,9 +9026,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.59" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f6fde1d36e75a714b5fe0cffbb78978f222ea6baebb726af13c78869fdb4205" +checksum = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4" dependencies = [ "quote 1.0.3", "wasm-bindgen-macro-support", @@ -9020,22 +9036,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.59" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bda4168030a6412ea8a047e27238cadf56f0e53516e1e83fec0a8b7c786f6d" +checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.59" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc9f36ad51f25b0219a3d4d13b90eb44cd075dff8b6280cca015775d7acaddd8" +checksum = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639" [[package]] name = "wasm-gc-api" @@ -9157,27 +9173,27 @@ dependencies = [ [[package]] name = "wast" -version = "10.0.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4efb62ecebf5cc9dbf2954309a20d816289c6550c0597a138b9e811cefc05007" +checksum = "5b20abd8b4a26f7e0d4dd5e357e90a3d555ec190e94472c9b2b27c5b9777f9ae" dependencies = [ "leb128", ] [[package]] name = "wat" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdea5e25273cc3a62f3ae3a1a4c7d7996625875b50c0b4475fee6698c2b069c" +checksum = "51a615830ee3e7200b505c441fec09aac2f114deae69df52f215cb828ba112c4" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721c6263e2c66fd44501cc5efbfa2b7dfa775d13e4ea38c46299646ed1f9c70a" +checksum = "2d6f51648d8c56c366144378a33290049eafdd784071077f6fe37dae64c1c4cb" dependencies = [ "js-sys", "wasm-bindgen", @@ -9250,9 +9266,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" +checksum = "fa515c5163a99cc82bab70fd3bfdd36d827be85de63737b40fcef2ce084a436e" dependencies = [ "winapi 0.3.8", ] @@ -9339,7 +9355,7 @@ checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" dependencies = [ "proc-macro2", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", "synstructure", ] diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 67e50e53f6..b8e5f70629 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -55,6 +55,7 @@ pallet-indices = { version = "2.0.0-alpha.5", default-features = false, path = " pallet-identity = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/identity" } pallet-membership = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/membership" } pallet-offences = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/offences" } +pallet-offences-benchmarking = { version = "2.0.0-alpha.5", path = "../../../frame/offences/benchmarking", default-features = false, optional = true } pallet-randomness-collective-flip = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/randomness-collective-flip" } pallet-recovery = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/recovery" } pallet-session = { version = "2.0.0-alpha.5", features = ["historical"], path = "../../../frame/session", default-features = false } @@ -150,6 +151,7 @@ runtime-benchmarks = [ "pallet-utility/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", "pallet-collective/runtime-benchmarks", + "pallet-offences-benchmarking", "pallet-session-benchmarking", ] diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 309f4ed024..483c8c6c97 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -887,10 +887,14 @@ impl_runtime_apis! { // To get around that, we separated the Session benchmarks into its own crate, which is why // we need these two lines below. use pallet_session_benchmarking::Module as SessionBench; + use pallet_offences_benchmarking::Module as OffencesBench; + impl pallet_session_benchmarking::Trait for Runtime {} + impl pallet_offences_benchmarking::Trait for Runtime {} let mut batches = Vec::::new(); let params = (&pallet, &benchmark, &lowest_range_values, &highest_range_values, &steps, repeat); + add_benchmark!(params, batches, b"balances", Balances); add_benchmark!(params, batches, b"collective", Council); add_benchmark!(params, batches, b"democracy", Democracy); @@ -902,6 +906,8 @@ impl_runtime_apis! { add_benchmark!(params, batches, b"treasury", Treasury); add_benchmark!(params, batches, b"utility", Utility); add_benchmark!(params, batches, b"vesting", Vesting); + add_benchmark!(params, batches, b"offences", OffencesBench::); + if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } Ok(batches) } diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index cbce3095b6..077471d354 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -679,11 +679,11 @@ pub struct UnresponsivenessOffence { /// /// It acts as a time measure for unresponsiveness reports and effectively will always point /// at the end of the session. - session_index: SessionIndex, + pub session_index: SessionIndex, /// The size of the validator set in current session/era. - validator_set_count: u32, + pub validator_set_count: u32, /// Authorities that were unresponsive during the current era. - offenders: Vec, + pub offenders: Vec, } impl Offence for UnresponsivenessOffence { diff --git a/frame/offences/Cargo.toml b/frame/offences/Cargo.toml index b858c03ba5..eab95dbd04 100644 --- a/frame/offences/Cargo.toml +++ b/frame/offences/Cargo.toml @@ -34,6 +34,7 @@ std = [ "frame-support/std", "frame-system/std", ] +runtime-benchmarks = [] [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/offences/benchmarking/Cargo.toml b/frame/offences/benchmarking/Cargo.toml new file mode 100644 index 0000000000..e343f1ff0c --- /dev/null +++ b/frame/offences/benchmarking/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "pallet-offences-benchmarking" +version = "2.0.0-alpha.5" +authors = ["Parity Technologies "] +edition = "2018" +license = "GPL-3.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "FRAME offences pallet benchmarking" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } + +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" } +sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/staking" } +sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../../benchmarking" } +frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../../system" } +frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../support" } +pallet-im-online = { version = "2.0.0-alpha.5", default-features = false, path = "../../im-online" } +pallet-offences = { version = "2.0.0-alpha.5", default-features = false, features = ["runtime-benchmarks"], path = "../../offences" } +pallet-staking = { version = "2.0.0-alpha.5", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } +pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../../session" } +sp-io = { path = "../../../primitives/io", default-features = false, version = "2.0.0-alpha.5"} + + +[features] +default = ["std"] +std = [ + "sp-runtime/std", + "sp-std/std", + "sp-staking/std", + "frame-benchmarking/std", + "frame-support/std", + "frame-system/std", + "pallet-offences/std", + "pallet-im-online/std", + "pallet-staking/std", + "pallet-session/std", +] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/offences/benchmarking/src/lib.rs b/frame/offences/benchmarking/src/lib.rs new file mode 100644 index 0000000000..a88714a89a --- /dev/null +++ b/frame/offences/benchmarking/src/lib.rs @@ -0,0 +1,175 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Offences pallet benchmarking. + +#![cfg_attr(not(feature = "std"), no_std)] + +use sp_std::prelude::*; +use sp_std::vec; + +use frame_system::RawOrigin; +use frame_benchmarking::{benchmarks, account}; +use frame_support::traits::{Currency, OnInitialize}; + +use sp_runtime::{Perbill, traits::{Convert, StaticLookup}}; +use sp_staking::offence::ReportOffence; + +use pallet_im_online::{Trait as ImOnlineTrait, Module as ImOnline, UnresponsivenessOffence}; +use pallet_offences::{Trait as OffencesTrait, Module as Offences}; +use pallet_staking::{ + Module as Staking, Trait as StakingTrait, RewardDestination, ValidatorPrefs, + Exposure, IndividualExposure, ElectionStatus +}; +use pallet_session::Trait as SessionTrait; +use pallet_session::historical::{Trait as HistoricalTrait, IdentificationTuple}; + +const SEED: u32 = 0; + +const MAX_USERS: u32 = 1000; +const MAX_REPORTERS: u32 = 100; +const MAX_OFFENDERS: u32 = 100; +const MAX_NOMINATORS: u32 = 100; +const MAX_DEFERRED_OFFENCES: u32 = 100; + +pub struct Module(Offences); + +pub trait Trait: SessionTrait + StakingTrait + OffencesTrait + ImOnlineTrait + HistoricalTrait {} + +fn create_offender(n: u32, nominators: u32) -> Result { + let stash: T::AccountId = account("stash", n, SEED); + let controller: T::AccountId = account("controller", n, SEED); + let controller_lookup: ::Source = T::Lookup::unlookup(controller.clone()); + let reward_destination = RewardDestination::Staked; + let amount = T::Currency::minimum_balance(); + + Staking::::bond( + RawOrigin::Signed(stash.clone()).into(), + controller_lookup.clone(), + amount.clone(), + reward_destination.clone(), + )?; + + let validator_prefs = ValidatorPrefs { + commission: Perbill::from_percent(50), + }; + Staking::::validate(RawOrigin::Signed(controller.clone()).into(), validator_prefs)?; + + let mut individual_exposures = vec![]; + + // Create n nominators + for i in 0 .. nominators { + let nominator_stash: T::AccountId = account("nominator stash", n * MAX_NOMINATORS + i, SEED); + let nominator_controller: T::AccountId = account("nominator controller", n * MAX_NOMINATORS + i, SEED); + let nominator_controller_lookup: ::Source = T::Lookup::unlookup(nominator_controller.clone()); + + Staking::::bond( + RawOrigin::Signed(nominator_stash.clone()).into(), + nominator_controller_lookup.clone(), + amount, + reward_destination, + )?; + + let selected_validators: Vec<::Source> = vec![controller_lookup.clone()]; + Staking::::nominate(RawOrigin::Signed(nominator_controller.clone()).into(), selected_validators)?; + + individual_exposures.push(IndividualExposure { + who: nominator_controller.clone(), + value: amount.clone(), + }); + } + + let exposure = Exposure { + total: amount.clone() * n.into(), + own: amount, + others: individual_exposures, + }; + let current_era = 0u32; + Staking::::add_era_stakers(current_era.into(), stash.clone().into(), exposure); + + Ok(controller) +} + +fn make_offenders(num_offenders: u32, num_nominators: u32) -> Result>, &'static str> { + let mut offenders: Vec = vec![]; + + for i in 0 .. num_offenders { + let offender = create_offender::(i, num_nominators)?; + offenders.push(offender); + } + + Ok(offenders.iter() + .map(|id| + ::ValidatorIdOf::convert(id.clone()) + .expect("failed to get validator id from account id")) + .map(|validator_id| + ::FullIdentificationOf::convert(validator_id.clone()) + .map(|full_id| (validator_id, full_id)) + .expect("failed to convert validator id to full identification")) + .collect::>>()) +} + +benchmarks! { + _ { + let u in 1 .. MAX_USERS => (); + let r in 1 .. MAX_REPORTERS => (); + let o in 1 .. MAX_OFFENDERS => (); + let n in 1 .. MAX_NOMINATORS => (); + let d in 1 .. MAX_DEFERRED_OFFENCES => (); + } + + report_offence { + let r in ...; + let o in ...; + let n in ...; + + let mut reporters = vec![]; + + for i in 0 .. r { + let reporter = account("reporter", i, SEED); + reporters.push(reporter); + } + + let offenders = make_offenders::(o, n).expect("failed to create offenders"); + let keys = ImOnline::::keys(); + + let offence = UnresponsivenessOffence { + session_index: 0, + validator_set_count: keys.len() as u32, + offenders, + }; + + }: { + let _ = ::ReportUnresponsiveness::report_offence(reporters, offence); + } + + on_initialize { + let d in ...; + + Staking::::put_election_status(ElectionStatus::Closed); + + let mut deferred_offences = vec![]; + + for i in 0 .. d { + deferred_offences.push((vec![], vec![], 0u32)); + } + + Offences::::set_deferred_offences(deferred_offences); + + }: { + Offences::::on_initialize(u.into()); + } +} diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index 0ba7cd87f2..40f39ab5f2 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -44,7 +44,7 @@ type OpaqueTimeSlot = Vec; type ReportIdOf = ::Hash; /// Type of data stored as a deferred offence -type DeferredOffenceOf = ( +pub type DeferredOffenceOf = ( Vec::AccountId, ::IdentificationTuple>>, Vec, SessionIndex, @@ -249,6 +249,11 @@ impl Module { None } } + + #[cfg(feature = "runtime-benchmarks")] + pub fn set_deferred_offences(offences: Vec>) { + >::put(offences); + } } struct TriageOutcome { diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index d162f42c3f..2602d38962 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -191,8 +191,8 @@ decl_storage! { >::insert(who, true); }); - /// Sorts the `Pool` by score in a descending order. Entities which - /// have a score of `None` are sorted to the beginning of the vec. + // Sorts the `Pool` by score in a descending order. Entities which + // have a score of `None` are sorted to the beginning of the vec. pool.sort_by_key(|(_, maybe_score)| Reverse(maybe_score.unwrap_or_default()) ); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index b566d616a8..9bdfa4738b 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -583,10 +583,10 @@ pub struct Nominations { #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, RuntimeDebug)] pub struct IndividualExposure { /// The stash account of the nominator in question. - who: AccountId, + pub who: AccountId, /// Amount of funds exposed. #[codec(compact)] - value: Balance, + pub value: Balance, } /// A snapshot of the stake backing a single validator in the system. @@ -1252,7 +1252,7 @@ decl_module! { /// unless the `origin` falls below _existential deposit_ and gets removed as dust. /// # #[weight = SimpleDispatchInfo::FixedNormal(500_000)] - fn bond(origin, + pub fn bond(origin, controller: ::Source, #[compact] value: BalanceOf, payee: RewardDestination, @@ -1446,7 +1446,7 @@ decl_module! { /// - Writes are limited to the `origin` account key. /// # #[weight = SimpleDispatchInfo::FixedNormal(750_000)] - fn validate(origin, prefs: ValidatorPrefs) { + pub fn validate(origin, prefs: ValidatorPrefs) { let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash = &ledger.stash; @@ -1466,7 +1466,7 @@ decl_module! { /// - Both the reads and writes follow a similar pattern. /// # #[weight = SimpleDispatchInfo::FixedNormal(750_000)] - fn nominate(origin, targets: Vec<::Source>) { + pub fn nominate(origin, targets: Vec<::Source>) { let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash = &ledger.stash; @@ -2878,6 +2878,16 @@ impl Module { _ => ForceEra::put(Forcing::ForceNew), } } + + #[cfg(feature = "runtime-benchmarks")] + pub fn add_era_stakers(current_era: EraIndex, controller: T::AccountId, exposure: Exposure>) { + >::insert(¤t_era, &controller, &exposure); + } + + #[cfg(feature = "runtime-benchmarks")] + pub fn put_election_status(status: ElectionStatus::) { + >::put(status); + } } /// In this implementation `new_session(session)` must be called before `end_session(session-1)` -- GitLab From b0efaa2cd7f4ff7f4b6b57502ee3a17193f13819 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Tue, 7 Apr 2020 11:38:07 +0200 Subject: [PATCH 176/300] CLI: refactoring: remove Options from sc_service::Configuration's fields (#5271) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * Rename IntoConfiguration to CliConfiguration * Renamed into_configuration to create_configuration * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * Move keystore params to its own module * Use in-memory keystore even for build-spec * Enforce proper value for node name * dev_key_seed * Telemetry endpoints * rustfmt * Converted all RunCmd * rustfmt * Added export-blocks * Missed something * Removed config_path in NetworkConfiguration (not used) * Fixed warnings * public_addresses is used but never set, keeping it * Merge Configuration.node and NetworkConfiguration.node_name ...because they are the same thing * Added: import-blocks * Adding a proc_macro to help impl SubstrateCli * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * Re-export spec_factory from sc_cli * Re-added all the commands * Refactored node_key_params * Fixed previous refucktoring * Clean-up and removed full_version() * Renamed get_is_dev to not confuse with Configuration field * Fixed sc-cli-derive example * Fixing tests * Fixing tests and removing some (will re-add later) * Fixing more tests * Removes the need of type parameter * Converting bin/node and simplifying API * Converting more * Converting last command * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * Fixing tests and added default for WasmExecutionMethod * Fixing stuff * Fixed something I broke oops * Update Cargo.lock * Moving things around * Convert everything to Result * Added new macros to simplify the impl of CliConfiguration * Added a macro to generate CliConfiguration automatically for subcommands * Revert... too many macros (this one is not really useful) This reverts commit 9c516dd38b40fbc420b02c1f8e61d5b2b1a4e434. * Renamed is_dev to get_is_dev Good enough for now * Fixed name roles (this is plural, not singular) * Clean-up * Re-export NodeKeyConfig and TelemetryEndpoints from sc_service * Improve styling/formatting * Added copyrights * Added doc and fixed warnings * Added myself to code owners * Yes it is needed according to the history * Revert formatting * Fixing conflict * Updated build.rs * Cargo.lock * Clean-up * Update client/cli-derive/Cargo.toml Co-Authored-By: Seun Lanlege * Fail if using proc_macro and build.rs is not set properly * Dropped all get_ in front of methods * Clean-up * Fixing proc macro missing env var * Get the configuration inside the Runtime (needed for polkadot) * Clean-up * Get is_dev from argument like the others * Get chain ID instead of chain spec from shared params * &self is passed to spec_factory/load_spec * Wrong text * Fix example * Officialize macro and made a cool doc * Renamed spec_factory to load_spec (substrate_cli_configuration) * Removed not so useful ChainSpec * Renamed SubstrateCLI to SubstrateCli * Added changelog for impl_version being full now * Renamed Runtime to Runner * Update changelog to show example * Removed option on database cache size * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * Fix on removal of option * typo * Clean-up imports * Added info in Cargo.toml * typo * remarks * Moved function for build.rs to substrate-build-script-utils * Fixed example & test of cli-derive * Moved function for build.rs to substrate-build-script-utils * Renamed substrate_cli_configuration to substrate_cli oops It implements SubstrateCli not CliConfiguration! * Added documentation and wrapper macro * Removed option on database cache size * Removed option on database cache size * Clean-up * Reduce risk of errors due to typos * Removed option on database cache size * Added NOTE as suggested * Added doc as suggested * Fixed test * typo * renamed runtime to runner * Fixed weird argument * More commas * Moved client/cli-derive to client/cli/derive * Added 7 tests for the macros * Improve error message * Upgrade assert_cmd * Fixing missing stuff * Fixed unused import * Improve SubstrateCli doc * Applied suggestions * Fix and clean-up imports * Started replacing macros WIP * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * Started removing substrate_cli * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * WIP Forked at: 2afecf81ee19b8a6edb364b419190ea47c4a4a31 Parent branch: origin/master * fixed bug introduced while refactoring * Renamed NetworkConfigurationParams to NetworkParams for consistency sake * Fixed test * Update client/cli/src/commands/runcmd.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/commands/runcmd.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/commands/export_blocks_cmd.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/commands/check_block_cmd.rs Co-Authored-By: Bastian Köcher * Update bin/node/cli/src/command.rs Co-Authored-By: Bastian Köcher * Update bin/node/cli/src/command.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/commands/export_blocks_cmd.rs Co-Authored-By: Bastian Köcher * Revert "Update client/cli/src/commands/export_blocks_cmd.rs" This reverts commit 5906776953392c02beac6bc0bf50f8cbe1a12a01. * Revert "Update client/cli/src/commands/check_block_cmd.rs" This reverts commit f705f42b7f3d732be001141afee210fe46a1ef47. * Revert "Update client/cli/src/commands/export_blocks_cmd.rs" This reverts commit 8d57c0550164449e6eb2d3bacb04c750c714fcea. * Revert "Update client/cli/src/commands/runcmd.rs" This reverts commit 93e74cf5d2e1c0dc49cdff8608d59fc40fc59338. * Revert "Update client/cli/src/commands/runcmd.rs" This reverts commit 11d527ba345c0d79f0d3b5b071933d95474d0614. * Update client/cli/src/commands/export_blocks_cmd.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/commands/import_blocks_cmd.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/commands/purge_chain_cmd.rs Co-Authored-By: Bastian Köcher * Changed ::sc_cli to $crate in the macro * fixed tests * fixed conflicts * Fixing test * Update client/cli/src/commands/purge_chain_cmd.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/params/pruning_params.rs Co-Authored-By: Bastian Köcher * Remove comment as suggested * Apply suggestion * Update client/cli/src/commands/purge_chain_cmd.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/commands/purge_chain_cmd.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/commands/purge_chain_cmd.rs Co-Authored-By: Bastian Köcher * Update utils/frame/benchmarking-cli/src/command.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/runner.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/runner.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/runner.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/params/pruning_params.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/params/node_key_params.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/params/network_params.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/lib.rs Co-Authored-By: Bastian Köcher * Update client/cli/src/config.rs Co-Authored-By: Bastian Köcher * Added doc * Fixed error introduced after applying suggestion * Revert "Update client/cli/src/params/pruning_params.rs" This reverts commit 0574d06a4f1efd86e94c1214420a12e7a4be0099. * Print error * Apply suggestions from code review * Remove useless Results * Fixed CI failing on polkadot approval Co-authored-by: Seun Lanlege Co-authored-by: Bastian Köcher --- .../gitlab/check_polkadot_companion_status.sh | 3 +- Cargo.lock | 30 +- bin/node-template/node/Cargo.toml | 4 +- bin/node-template/node/build.rs | 8 +- bin/node-template/node/src/chain_spec.rs | 142 ++--- bin/node-template/node/src/command.rs | 76 ++- bin/node-template/node/src/main.rs | 13 +- bin/node-template/node/src/service.rs | 2 +- bin/node/cli/Cargo.toml | 12 +- bin/node/cli/bin/main.rs | 13 +- bin/node/cli/build.rs | 8 +- bin/node/cli/src/browser.rs | 6 +- bin/node/cli/src/chain_spec.rs | 10 +- bin/node/cli/src/cli.rs | 11 +- bin/node/cli/src/command.rs | 192 +++--- bin/node/cli/src/lib.rs | 42 -- bin/node/cli/src/service.rs | 4 +- bin/node/cli/tests/version.rs | 83 +++ bin/node/inspect/src/command.rs | 184 +----- bin/node/inspect/src/lib.rs | 126 +++- bin/node/testing/src/bench.rs | 2 +- bin/utils/chain-spec-builder/src/main.rs | 4 +- client/cli/src/arg_enums.rs | 4 +- client/cli/src/commands/build_spec_cmd.rs | 45 +- client/cli/src/commands/check_block_cmd.rs | 60 +- client/cli/src/commands/export_blocks_cmd.rs | 55 +- client/cli/src/commands/import_blocks_cmd.rs | 51 +- client/cli/src/commands/mod.rs | 418 +++++++++--- client/cli/src/commands/purge_chain_cmd.rs | 37 +- client/cli/src/commands/revert_cmd.rs | 39 +- client/cli/src/commands/runcmd.rs | 599 +++++++----------- client/cli/src/config.rs | 462 ++++++++++++++ client/cli/src/lib.rs | 287 +++++---- client/cli/src/params/import_params.rs | 70 +- client/cli/src/params/keystore_params.rs | 92 +++ client/cli/src/params/mod.rs | 16 +- ...figuration_params.rs => network_params.rs} | 116 ++-- client/cli/src/params/node_key_params.rs | 114 ++-- client/cli/src/params/pruning_params.rs | 31 +- client/cli/src/params/shared_params.rs | 99 ++- .../cli/src/params/transaction_pool_params.rs | 21 +- client/cli/src/runner.rs | 237 +++++++ client/cli/src/runtime.rs | 149 ----- client/db/src/lib.rs | 4 +- client/db/src/light.rs | 90 +-- client/db/src/upgrade.rs | 2 +- client/db/src/utils.rs | 28 +- client/executor/src/wasm_runtime.rs | 6 + client/network/src/config.rs | 52 +- client/network/src/service.rs | 5 +- client/network/test/src/lib.rs | 30 +- client/service/Cargo.toml | 1 - client/service/src/builder.rs | 28 +- client/service/src/config.rs | 163 +---- client/service/src/lib.rs | 4 +- client/service/test/src/lib.rs | 61 +- client/src/client.rs | 4 +- docs/CHANGELOG.md | 6 +- docs/CODEOWNERS | 4 + utils/browser/src/lib.rs | 68 +- utils/build-script-utils/Cargo.toml | 1 + utils/build-script-utils/src/git.rs | 123 ++++ utils/build-script-utils/src/lib.rs | 29 +- utils/build-script-utils/src/version.rs | 59 ++ utils/frame/benchmarking-cli/src/command.rs | 141 +++++ utils/frame/benchmarking-cli/src/lib.rs | 142 +---- 66 files changed, 2894 insertions(+), 2134 deletions(-) create mode 100644 bin/node/cli/tests/version.rs create mode 100644 client/cli/src/config.rs create mode 100644 client/cli/src/params/keystore_params.rs rename client/cli/src/params/{network_configuration_params.rs => network_params.rs} (63%) create mode 100644 client/cli/src/runner.rs delete mode 100644 client/cli/src/runtime.rs create mode 100644 utils/build-script-utils/src/git.rs create mode 100644 utils/build-script-utils/src/version.rs create mode 100644 utils/frame/benchmarking-cli/src/command.rs diff --git a/.maintain/gitlab/check_polkadot_companion_status.sh b/.maintain/gitlab/check_polkadot_companion_status.sh index b54f457dc5..5387e68f25 100755 --- a/.maintain/gitlab/check_polkadot_companion_status.sh +++ b/.maintain/gitlab/check_polkadot_companion_status.sh @@ -87,7 +87,8 @@ fi curl -H "${github_header}" -sS -o companion_pr_reviews.json \ ${github_api_polkadot_pull_url}/${pr_companion}/reviews -if [ "$(jq -r -e '.[].state' < companion_pr_reviews.json | uniq)" != "APPROVED" ] +if [ -n "$(jq -r -e '.[].state | select(. == "CHANGES_REQUESTED")' < companion_pr_reviews.json)" ] && \ + [ -z "$(jq -r -e '.[].state | select(. == "APPROVED")' < companion_pr_reviews.json)" ] then boldprint "polkadot pr #${pr_companion} not APPROVED" exit 1 diff --git a/Cargo.lock b/Cargo.lock index 5b2ce24399..f0da8b5390 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3395,7 +3395,9 @@ dependencies = [ "pallet-timestamp", "pallet-transaction-payment", "parity-scale-codec", + "platforms", "rand 0.7.3", + "regex", "sc-authority-discovery", "sc-basic-authorship", "sc-chain-spec", @@ -3434,7 +3436,6 @@ dependencies = [ "substrate-build-script-utils", "tempfile", "tracing", - "vergen", "wasm-bindgen", "wasm-bindgen-futures", ] @@ -3625,7 +3626,6 @@ dependencies = [ "sp-transaction-pool", "structopt", "substrate-build-script-utils", - "vergen", ] [[package]] @@ -4935,6 +4935,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +[[package]] +name = "platforms" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feb3b2b1033b8a60b4da6ee470325f887758c95d5320f52f9ce0df055a55940e" + [[package]] name = "plotters" version = "0.2.12" @@ -6597,7 +6603,6 @@ dependencies = [ "substrate-prometheus-endpoint", "substrate-test-runtime-client", "sysinfo", - "target_info", "tracing", "wasm-timer", ] @@ -7879,6 +7884,9 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "2.0.0-alpha.5" +dependencies = [ + "platforms", +] [[package]] name = "substrate-frame-rpc-support" @@ -8210,12 +8218,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d" -[[package]] -name = "target_info" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" - [[package]] name = "tempfile" version = "3.1.0" @@ -8895,16 +8897,6 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -[[package]] -name = "vergen" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ce50d8996df1f85af15f2cd8d33daae6e479575123ef4314a51a70a230739cb" -dependencies = [ - "bitflags", - "chrono", -] - [[package]] name = "version_check" version = "0.9.1" diff --git a/bin/node-template/node/Cargo.toml b/bin/node-template/node/Cargo.toml index b312d31111..a2ccc4fa95 100644 --- a/bin/node-template/node/Cargo.toml +++ b/bin/node-template/node/Cargo.toml @@ -2,6 +2,7 @@ name = "node-template" version = "2.0.0-alpha.5" authors = ["Anonymous"] +description = "Substrate Node template" edition = "2018" license = "Unlicense" build = "build.rs" @@ -37,8 +38,7 @@ sc-basic-authorship = { path = "../../../client/basic-authorship", version = "0. node-template-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } [build-dependencies] -vergen = "3.0.4" -build-script-utils = { version = "2.0.0-alpha.5", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } +substrate-build-script-utils = { version = "2.0.0-alpha.5", path = "../../../utils/build-script-utils" } [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node-template/node/build.rs b/bin/node-template/node/build.rs index 222cbb4092..e3bfe3116b 100644 --- a/bin/node-template/node/build.rs +++ b/bin/node-template/node/build.rs @@ -1,9 +1,7 @@ -use vergen::{ConstantsFlags, generate_cargo_keys}; - -const ERROR_MSG: &str = "Failed to generate metadata files"; +use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed}; fn main() { - generate_cargo_keys(ConstantsFlags::SHA_SHORT).expect(ERROR_MSG); + generate_cargo_keys(); - build_script_utils::rerun_if_git_head_changed(); + rerun_if_git_head_changed(); } diff --git a/bin/node-template/node/src/chain_spec.rs b/bin/node-template/node/src/chain_spec.rs index b57000fed7..8ed91698eb 100644 --- a/bin/node-template/node/src/chain_spec.rs +++ b/bin/node-template/node/src/chain_spec.rs @@ -14,17 +14,6 @@ use sp_runtime::traits::{Verify, IdentifyAccount}; /// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type. pub type ChainSpec = sc_service::GenericChainSpec; -/// The chain specification option. This is expected to come in from the CLI and -/// is little more than one of a number of alternatives which can easily be converted -/// from a string (`--chain=...`) into a `ChainSpec`. -#[derive(Clone, Debug)] -pub enum Alternative { - /// Whatever the current runtime is, with just Alice as an auth. - Development, - /// Whatever the current runtime is, with simple Alice/Bob auths. - LocalTestnet, -} - /// Helper function to generate a crypto pair from seed pub fn get_from_seed(seed: &str) -> ::Public { TPublic::Pair::from_string(&format!("//{}", seed), None) @@ -42,80 +31,70 @@ pub fn get_account_id_from_seed(seed: &str) -> AccountId where } /// Helper function to generate an authority key for Aura -pub fn get_authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) { +pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) { ( get_from_seed::(s), get_from_seed::(s), ) } -impl Alternative { - /// Get an actual chain config from one of the alternatives. - pub(crate) fn load(self) -> Result { - Ok(match self { - Alternative::Development => ChainSpec::from_genesis( - "Development", - "dev", - || testnet_genesis( - vec![ - get_authority_keys_from_seed("Alice"), - ], - get_account_id_from_seed::("Alice"), - vec![ - get_account_id_from_seed::("Alice"), - get_account_id_from_seed::("Bob"), - get_account_id_from_seed::("Alice//stash"), - get_account_id_from_seed::("Bob//stash"), - ], - true, - ), - vec![], - None, - None, - None, - None - ), - Alternative::LocalTestnet => ChainSpec::from_genesis( - "Local Testnet", - "local_testnet", - || testnet_genesis( - vec![ - get_authority_keys_from_seed("Alice"), - get_authority_keys_from_seed("Bob"), - ], - get_account_id_from_seed::("Alice"), - vec![ - get_account_id_from_seed::("Alice"), - get_account_id_from_seed::("Bob"), - get_account_id_from_seed::("Charlie"), - get_account_id_from_seed::("Dave"), - get_account_id_from_seed::("Eve"), - get_account_id_from_seed::("Ferdie"), - get_account_id_from_seed::("Alice//stash"), - get_account_id_from_seed::("Bob//stash"), - get_account_id_from_seed::("Charlie//stash"), - get_account_id_from_seed::("Dave//stash"), - get_account_id_from_seed::("Eve//stash"), - get_account_id_from_seed::("Ferdie//stash"), - ], - true, - ), - vec![], - None, - None, - None, - None - ), - }) - } +pub fn development_config() -> ChainSpec { + ChainSpec::from_genesis( + "Development", + "dev", + || testnet_genesis( + vec![ + authority_keys_from_seed("Alice"), + ], + get_account_id_from_seed::("Alice"), + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + ], + true, + ), + vec![], + None, + None, + None, + None, + ) +} - pub(crate) fn from(s: &str) -> Option { - match s { - "dev" => Some(Alternative::Development), - "" | "local" => Some(Alternative::LocalTestnet), - _ => None, - } - } +pub fn local_testnet_config() -> ChainSpec { + ChainSpec::from_genesis( + "Local Testnet", + "local_testnet", + || testnet_genesis( + vec![ + authority_keys_from_seed("Alice"), + authority_keys_from_seed("Bob"), + ], + get_account_id_from_seed::("Alice"), + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + get_account_id_from_seed::("Charlie//stash"), + get_account_id_from_seed::("Dave//stash"), + get_account_id_from_seed::("Eve//stash"), + get_account_id_from_seed::("Ferdie//stash"), + ], + true, + ), + vec![], + None, + None, + None, + None, + ) } fn testnet_genesis(initial_authorities: Vec<(AuraId, GrandpaId)>, @@ -141,10 +120,3 @@ fn testnet_genesis(initial_authorities: Vec<(AuraId, GrandpaId)>, }), } } - -pub fn load_spec(id: &str) -> Result, String> { - Ok(match Alternative::from(id) { - Some(spec) => Box::new(spec.load()?), - None => Box::new(ChainSpec::from_json_file(std::path::PathBuf::from(id))?), - }) -} diff --git a/bin/node-template/node/src/command.rs b/bin/node-template/node/src/command.rs index 0f4c301dbf..75b88877aa 100644 --- a/bin/node-template/node/src/command.rs +++ b/bin/node-template/node/src/command.rs @@ -14,36 +14,64 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair}; -use sc_cli::VersionInfo; -use crate::service; use crate::chain_spec; use crate::cli::Cli; +use crate::service; +use sc_cli::SubstrateCli; +use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; -/// Parse and run command line arguments -pub fn run(version: VersionInfo) -> sc_cli::Result<()> { - let opt = sc_cli::from_args::(&version); +impl SubstrateCli for Cli { + fn impl_name() -> &'static str { + "Substrate Node" + } + + fn impl_version() -> &'static str { + env!("SUBSTRATE_CLI_IMPL_VERSION") + } + + fn description() -> &'static str { + env!("CARGO_PKG_DESCRIPTION") + } + + fn author() -> &'static str { + env!("CARGO_PKG_AUTHORS") + } - let mut config = sc_service::Configuration::from_version(&version); + fn support_url() -> &'static str { + "support.anonymous.an" + } + + fn copyright_start_year() -> i32 { + 2017 + } + + fn executable_name() -> &'static str { + env!("CARGO_PKG_NAME") + } + + fn load_spec(&self, id: &str) -> Result, String> { + Ok(match id { + "dev" => Box::new(chain_spec::development_config()), + "" | "local" => Box::new(chain_spec::local_testnet_config()), + path => Box::new(chain_spec::ChainSpec::from_json_file( + std::path::PathBuf::from(path), + )?), + }) + } +} + +/// Parse and run command line arguments +pub fn run() -> sc_cli::Result<()> { + let cli = Cli::from_args(); - match opt.subcommand { + match &cli.subcommand { Some(subcommand) => { - subcommand.init(&version)?; - subcommand.update_config(&mut config, chain_spec::load_spec, &version)?; - subcommand.run( - config, - |config: _| Ok(new_full_start!(config).0), - ) - }, + let runner = cli.create_runner(subcommand)?; + runner.run_subcommand(subcommand, |config| Ok(new_full_start!(config).0)) + } None => { - opt.run.init(&version)?; - opt.run.update_config(&mut config, chain_spec::load_spec, &version)?; - opt.run.run( - config, - service::new_light, - service::new_full, - &version, - ) - }, + let runner = cli.create_runner(&cli.run)?; + runner.run_node(service::new_light, service::new_full) + } } } diff --git a/bin/node-template/node/src/main.rs b/bin/node-template/node/src/main.rs index 91b2c257e0..369e6932a0 100644 --- a/bin/node-template/node/src/main.rs +++ b/bin/node-template/node/src/main.rs @@ -8,16 +8,5 @@ mod cli; mod command; fn main() -> sc_cli::Result<()> { - let version = sc_cli::VersionInfo { - name: "Substrate Node", - commit: env!("VERGEN_SHA_SHORT"), - version: env!("CARGO_PKG_VERSION"), - executable_name: "node-template", - author: "Anonymous", - description: "Template Node", - support_url: "support.anonymous.an", - copyright_start_year: 2017, - }; - - command::run(version) + command::run() } diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index b8c1b32b56..7c4a574f6b 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -74,7 +74,7 @@ pub fn new_full(config: Configuration) { let role = config.role.clone(); let force_authoring = config.force_authoring; - let name = config.name.clone(); + let name = config.network.node_name.clone(); let disable_grandpa = config.disable_grandpa; let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config); diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index c477471166..9842fd2ee4 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -2,7 +2,7 @@ name = "node-cli" version = "2.0.0-alpha.5" authors = ["Parity Technologies "] -description = "Substrate node implementation in Rust." +description = "Generic Substrate node implementation in Rust." build = "build.rs" edition = "2018" license = "GPL-3.0" @@ -116,13 +116,15 @@ tempfile = "3.1.0" assert_cmd = "1.0" nix = "0.17" serde_json = "1.0" +regex = "1" +platforms = "0.2.1" [build-dependencies] -build-script-utils = { version = "2.0.0-alpha.5", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } structopt = { version = "0.3.8", optional = true } node-transaction-factory = { version = "0.8.0-alpha.5", optional = true, path = "../transaction-factory" } node-inspect = { version = "0.8.0-alpha.5", optional = true, path = "../inspect" } frame-benchmarking-cli = { version = "2.0.0-alpha.5", optional = true, path = "../../../utils/frame/benchmarking-cli" } +substrate-build-script-utils = { version = "2.0.0-alpha.5", optional = true, path = "../../../utils/build-script-utils" } [build-dependencies.sc-cli] version = "0.8.0-alpha.5" @@ -130,10 +132,6 @@ package = "sc-cli" path = "../../../client/cli" optional = true -[build-dependencies.vergen] -version = "3.0.4" -optional = true - [features] default = [ "cli" ] browser = [ @@ -149,7 +147,7 @@ cli = [ "frame-benchmarking-cli", "sc-service/rocksdb", "structopt", - "vergen", + "substrate-build-script-utils", ] runtime-benchmarks = [ "node-runtime/runtime-benchmarks" ] diff --git a/bin/node/cli/bin/main.rs b/bin/node/cli/bin/main.rs index 8c4412667b..cfad84a4cb 100644 --- a/bin/node/cli/bin/main.rs +++ b/bin/node/cli/bin/main.rs @@ -19,16 +19,5 @@ #![warn(missing_docs)] fn main() -> sc_cli::Result<()> { - let version = sc_cli::VersionInfo { - name: "Substrate Node", - commit: env!("VERGEN_SHA_SHORT"), - version: env!("CARGO_PKG_VERSION"), - executable_name: "substrate", - author: "Parity Technologies ", - description: "Generic substrate node", - support_url: "https://github.com/paritytech/substrate/issues/new", - copyright_start_year: 2017, - }; - - node_cli::run(std::env::args(), version) + node_cli::run() } diff --git a/bin/node/cli/build.rs b/bin/node/cli/build.rs index e824b59be6..12e0cab58a 100644 --- a/bin/node/cli/build.rs +++ b/bin/node/cli/build.rs @@ -24,14 +24,14 @@ mod cli { include!("src/cli.rs"); use std::{fs, env, path::Path}; - use sc_cli::{structopt::clap::Shell}; - use vergen::{ConstantsFlags, generate_cargo_keys}; + use sc_cli::structopt::clap::Shell; + use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed}; pub fn main() { build_shell_completion(); - generate_cargo_keys(ConstantsFlags::all()).expect("Failed to generate metadata files"); + generate_cargo_keys(); - build_script_utils::rerun_if_git_head_changed(); + rerun_if_git_head_changed(); } /// Build shell completion scripts for all known shells diff --git a/bin/node/cli/src/browser.rs b/bin/node/cli/src/browser.rs index e7dd1e78b4..6cd98dfe8d 100644 --- a/bin/node/cli/src/browser.rs +++ b/bin/node/cli/src/browser.rs @@ -41,10 +41,10 @@ async fn start_inner(chain_spec: String, log_level: String) -> Result(seed: &str) -> AccountId where } /// Helper function to generate stash, controller and session key from seed -pub fn get_authority_keys_from_seed(seed: &str) -> ( +pub fn authority_keys_from_seed(seed: &str) -> ( AccountId, AccountId, GrandpaId, @@ -325,7 +325,7 @@ pub fn testnet_genesis( fn development_config_genesis() -> GenesisConfig { testnet_genesis( vec![ - get_authority_keys_from_seed("Alice"), + authority_keys_from_seed("Alice"), ], get_account_id_from_seed::("Alice"), None, @@ -350,8 +350,8 @@ pub fn development_config() -> ChainSpec { fn local_testnet_genesis() -> GenesisConfig { testnet_genesis( vec![ - get_authority_keys_from_seed("Alice"), - get_authority_keys_from_seed("Bob"), + authority_keys_from_seed("Alice"), + authority_keys_from_seed("Bob"), ], get_account_id_from_seed::("Alice"), None, @@ -383,7 +383,7 @@ pub(crate) mod tests { fn local_testnet_genesis_instant_single() -> GenesisConfig { testnet_genesis( vec![ - get_authority_keys_from_seed("Alice"), + authority_keys_from_seed("Alice"), ], get_account_id_from_seed::("Alice"), None, diff --git a/bin/node/cli/src/cli.rs b/bin/node/cli/src/cli.rs index b6db9c3deb..44b18fd716 100644 --- a/bin/node/cli/src/cli.rs +++ b/bin/node/cli/src/cli.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use sc_cli::{SharedParams, ImportParams, RunCmd}; +use sc_cli::{ImportParams, RunCmd, SharedParams}; use structopt::StructOpt; /// An overarching CLI command definition. @@ -50,10 +50,7 @@ pub enum Subcommand { Inspect(node_inspect::cli::InspectCmd), /// The custom benchmark subcommmand benchmarking runtime pallets. - #[structopt( - name = "benchmark", - about = "Benchmark runtime pallets." - )] + #[structopt(name = "benchmark", about = "Benchmark runtime pallets.")] Benchmark(frame_benchmarking_cli::BenchmarkCmd), } @@ -62,11 +59,11 @@ pub enum Subcommand { #[derive(Debug, StructOpt, Clone)] pub struct FactoryCmd { /// Number of blocks to generate. - #[structopt(long="blocks", default_value = "1")] + #[structopt(long = "blocks", default_value = "1")] pub blocks: u32, /// Number of transactions to push per block. - #[structopt(long="transactions", default_value = "8")] + #[structopt(long = "transactions", default_value = "8")] pub transactions: u32, #[allow(missing_docs)] diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index 84d680b6f8..37b77d3bb7 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -14,104 +14,126 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use sc_cli::VersionInfo; -use sc_service::{Role as ServiceRole}; +use crate::{chain_spec, factory_impl::FactoryState, service, Cli, FactoryCmd, Subcommand}; +use node_executor::Executor; +use node_runtime::{Block, RuntimeApi}; use node_transaction_factory::RuntimeAdapter; -use crate::{Cli, service, ChainSpec, load_spec, Subcommand, factory_impl::FactoryState}; +use sc_cli::{CliConfiguration, ImportParams, Result, SharedParams, SubstrateCli}; +use sc_service::Configuration; + +impl SubstrateCli for Cli { + fn impl_name() -> &'static str { + "Substrate Node" + } + + fn impl_version() -> &'static str { + env!("SUBSTRATE_CLI_IMPL_VERSION") + } + + fn description() -> &'static str { + env!("CARGO_PKG_DESCRIPTION") + } + + fn author() -> &'static str { + env!("CARGO_PKG_AUTHORS") + } + + fn support_url() -> &'static str { + "https://github.com/paritytech/substrate/issues/new" + } + + fn copyright_start_year() -> i32 { + 2017 + } + + fn executable_name() -> &'static str { + "substrate" + } + + fn load_spec(&self, id: &str) -> std::result::Result, String> { + Ok(match id { + "dev" => Box::new(chain_spec::development_config()), + "local" => Box::new(chain_spec::local_testnet_config()), + "" | "fir" | "flaming-fir" => Box::new(chain_spec::flaming_fir_config()?), + "staging" => Box::new(chain_spec::staging_testnet_config()), + path => Box::new(chain_spec::ChainSpec::from_json_file( + std::path::PathBuf::from(path), + )?), + }) + } +} /// Parse command line arguments into service configuration. -pub fn run(args: I, version: VersionInfo) -> sc_cli::Result<()> -where - I: Iterator, - T: Into + Clone, -{ +pub fn run() -> Result<()> { sc_cli::reset_signal_pipe_handler()?; - let args: Vec<_> = args.collect(); - let opt = sc_cli::from_iter::(args.clone(), &version); + let cli = Cli::from_args(); - let mut config = sc_service::Configuration::from_version(&version); - - match opt.subcommand { + match &cli.subcommand { None => { - opt.run.init(&version)?; - opt.run.update_config(&mut config, load_spec, &version)?; - opt.run.run( - config, - service::new_light, - service::new_full, - &version, - ) - }, + let runner = cli.create_runner(&cli.run)?; + runner.run_node(service::new_light, service::new_full) + } Some(Subcommand::Inspect(cmd)) => { - cmd.init(&version)?; - cmd.update_config(&mut config, load_spec, &version)?; - - let client = sc_service::new_full_client::< - node_runtime::Block, node_runtime::RuntimeApi, node_executor::Executor, - >(&config)?; - let inspect = node_inspect::Inspector::::new(client); + let runner = cli.create_runner(cmd)?; - cmd.run(inspect) - }, + runner.sync_run(|config| cmd.run::(config)) + } Some(Subcommand::Benchmark(cmd)) => { - cmd.init(&version)?; - cmd.update_config(&mut config, load_spec, &version)?; - - cmd.run::(config) - }, - Some(Subcommand::Factory(cli_args)) => { - cli_args.shared_params.init(&version)?; - cli_args.shared_params.update_config(&mut config, load_spec, &version)?; - cli_args.import_params.update_config( - &mut config, - &ServiceRole::Full, - cli_args.shared_params.dev, - )?; - - config.use_in_memory_keystore()?; - - match ChainSpec::from(config.expect_chain_spec().id()) { - Some(ref c) if c == &ChainSpec::Development || c == &ChainSpec::LocalTestnet => {}, - _ => return Err( - "Factory is only supported for development and local testnet.".into() - ), - } + let runner = cli.create_runner(cmd)?; - // Setup tracing. - if let Some(tracing_targets) = cli_args.import_params.tracing_targets.as_ref() { - let subscriber = sc_tracing::ProfilingSubscriber::new( - cli_args.import_params.tracing_receiver.into(), tracing_targets - ); - if let Err(e) = tracing::subscriber::set_global_default(subscriber) { - return Err( - format!("Unable to set global default subscriber {}", e).into() - ); - } - } + runner.sync_run(|config| cmd.run::(config)) + } + Some(Subcommand::Factory(cmd)) => { + let runner = cli.create_runner(cmd)?; - let factory_state = FactoryState::new( - cli_args.blocks, - cli_args.transactions, - ); + runner.sync_run(|config| cmd.run(config)) + } + Some(Subcommand::Base(subcommand)) => { + let runner = cli.create_runner(subcommand)?; + + runner.run_subcommand(subcommand, |config| Ok(new_full_start!(config).0)) + } + } +} - let service_builder = new_full_start!(config).0; - node_transaction_factory::factory( - factory_state, - service_builder.client(), - service_builder.select_chain() - .expect("The select_chain is always initialized by new_full_start!; QED") - ).map_err(|e| format!("Error in transaction factory: {}", e))?; +impl CliConfiguration for FactoryCmd { + fn shared_params(&self) -> &SharedParams { + &self.shared_params + } - Ok(()) - }, - Some(Subcommand::Base(subcommand)) => { - subcommand.init(&version)?; - subcommand.update_config(&mut config, load_spec, &version)?; - subcommand.run( - config, - |config: sc_service::Configuration| Ok(new_full_start!(config).0), - ) - }, + fn import_params(&self) -> Option<&ImportParams> { + Some(&self.import_params) + } +} + +impl FactoryCmd { + fn run(&self, config: Configuration) -> Result<()> { + match config.chain_spec.id() { + "dev" | "local" => {} + _ => return Err("Factory is only supported for development and local testnet.".into()), + } + + // Setup tracing. + if let Some(tracing_targets) = self.import_params.tracing_targets.as_ref() { + let subscriber = sc_tracing::ProfilingSubscriber::new( + self.import_params.tracing_receiver.into(), + tracing_targets, + ); + if let Err(e) = tracing::subscriber::set_global_default(subscriber) { + return Err(format!("Unable to set global default subscriber {}", e).into()); + } + } + + let factory_state = FactoryState::new(self.blocks, self.transactions); + + let service_builder = new_full_start!(config).0; + node_transaction_factory::factory( + factory_state, + service_builder.client(), + service_builder + .select_chain() + .expect("The select_chain is always initialized by new_full_start!; qed"), + ) } } diff --git a/bin/node/cli/src/lib.rs b/bin/node/cli/src/lib.rs index 6b3644856c..1e2c790bfa 100644 --- a/bin/node/cli/src/lib.rs +++ b/bin/node/cli/src/lib.rs @@ -47,45 +47,3 @@ pub use browser::*; pub use cli::*; #[cfg(feature = "cli")] pub use command::*; - -/// The chain specification option. -#[derive(Clone, Debug, PartialEq)] -pub enum ChainSpec { - /// Whatever the current runtime is, with just Alice as an auth. - Development, - /// Whatever the current runtime is, with simple Alice/Bob auths. - LocalTestnet, - /// The Flaming Fir testnet. - FlamingFir, - /// Whatever the current runtime is with the "global testnet" defaults. - StagingTestnet, -} - -/// Get a chain config from a spec setting. -impl ChainSpec { - pub(crate) fn load(self) -> Result { - Ok(match self { - ChainSpec::FlamingFir => chain_spec::flaming_fir_config()?, - ChainSpec::Development => chain_spec::development_config(), - ChainSpec::LocalTestnet => chain_spec::local_testnet_config(), - ChainSpec::StagingTestnet => chain_spec::staging_testnet_config(), - }) - } - - pub(crate) fn from(s: &str) -> Option { - match s { - "dev" => Some(ChainSpec::Development), - "local" => Some(ChainSpec::LocalTestnet), - "" | "fir" | "flaming-fir" => Some(ChainSpec::FlamingFir), - "staging" => Some(ChainSpec::StagingTestnet), - _ => None, - } - } -} - -fn load_spec(id: &str) -> Result, String> { - Ok(match ChainSpec::from(id) { - Some(spec) => Box::new(spec.load()?), - None => Box::new(chain_spec::ChainSpec::from_json_file(std::path::PathBuf::from(id))?), - }) -} diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 3e09802ccd..92d62364a2 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -88,7 +88,7 @@ macro_rules! new_full_start { import_setup = Some((block_import, grandpa_link, babe_link)); Ok(import_queue) })? - .with_rpc_extensions(|builder| -> Result { + .with_rpc_extensions(|builder| -> std::result::Result { let babe_link = import_setup.as_ref().map(|s| &s.2) .expect("BabeLink is present for full services or set up failed; qed."); let deps = node_rpc::FullDeps { @@ -127,7 +127,7 @@ macro_rules! new_full { ) = ( $config.role.clone(), $config.force_authoring, - $config.name.clone(), + $config.network.node_name.clone(), $config.disable_grandpa, ); diff --git a/bin/node/cli/tests/version.rs b/bin/node/cli/tests/version.rs new file mode 100644 index 0000000000..5555efd385 --- /dev/null +++ b/bin/node/cli/tests/version.rs @@ -0,0 +1,83 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use assert_cmd::cargo::cargo_bin; +use platforms::*; +use regex::Regex; +use std::process::Command; + +fn expected_regex() -> Regex { + Regex::new(r"^substrate (\d+\.\d+\.\d+(?:-.+?)?)-([a-f\d]+)-(.+?)-(.+?)(?:-(.+))?$").unwrap() +} + +#[test] +fn version_is_full() { + let expected = expected_regex(); + let output = Command::new(cargo_bin("substrate")) + .args(&["--version"]) + .output() + .unwrap(); + + assert!( + output.status.success(), + "command returned with non-success exit code" + ); + + let output = String::from_utf8_lossy(&output.stdout).trim().to_owned(); + let captures = expected + .captures(output.as_str()) + .expect("could not parse version in output"); + + assert_eq!(&captures[1], env!("CARGO_PKG_VERSION")); + assert_eq!(&captures[3], TARGET_ARCH.as_str()); + assert_eq!(&captures[4], TARGET_OS.as_str()); + assert_eq!( + captures.get(5).map(|x| x.as_str()), + TARGET_ENV.map(|x| x.as_str()) + ); +} + +#[test] +fn test_regex_matches_properly() { + let expected = expected_regex(); + + let captures = expected + .captures("substrate 2.0.0-da487d19d-x86_64-linux-gnu") + .unwrap(); + assert_eq!(&captures[1], "2.0.0"); + assert_eq!(&captures[2], "da487d19d"); + assert_eq!(&captures[3], "x86_64"); + assert_eq!(&captures[4], "linux"); + assert_eq!(captures.get(5).map(|x| x.as_str()), Some("gnu")); + + let captures = expected + .captures("substrate 2.0.0-alpha.5-da487d19d-x86_64-linux-gnu") + .unwrap(); + assert_eq!(&captures[1], "2.0.0-alpha.5"); + assert_eq!(&captures[2], "da487d19d"); + assert_eq!(&captures[3], "x86_64"); + assert_eq!(&captures[4], "linux"); + assert_eq!(captures.get(5).map(|x| x.as_str()), Some("gnu")); + + let captures = expected + .captures("substrate 2.0.0-alpha.5-da487d19d-x86_64-linux") + .unwrap(); + assert_eq!(&captures[1], "2.0.0-alpha.5"); + assert_eq!(&captures[2], "da487d19d"); + assert_eq!(&captures[3], "x86_64"); + assert_eq!(&captures[4], "linux"); + assert_eq!(captures.get(5).map(|x| x.as_str()), None); +} diff --git a/bin/node/inspect/src/command.rs b/bin/node/inspect/src/command.rs index 335b6c8531..2212907f76 100644 --- a/bin/node/inspect/src/command.rs +++ b/bin/node/inspect/src/command.rs @@ -16,186 +16,48 @@ //! Command ran by the CLI -use std::{ - fmt::Debug, - str::FromStr, -}; - use crate::cli::{InspectCmd, InspectSubCmd}; -use crate::{Inspector, PrettyPrinter}; +use crate::Inspector; +use sc_cli::{CliConfiguration, ImportParams, Result, SharedParams}; +use sc_service::{new_full_client, Configuration, NativeExecutionDispatch}; +use sp_runtime::traits::Block; +use std::str::FromStr; impl InspectCmd { - /// Initialize - pub fn init(&self, version: &sc_cli::VersionInfo) -> sc_cli::Result<()> { - self.shared_params.init(version) - } - - /// Parse CLI arguments and initialize given config. - pub fn update_config( - &self, - mut config: &mut sc_service::config::Configuration, - spec_factory: impl FnOnce(&str) -> Result, String>, - version: &sc_cli::VersionInfo, - ) -> sc_cli::Result<()> { - self.shared_params.update_config(config, spec_factory, version)?; - - // make sure to configure keystore - config.use_in_memory_keystore()?; - - // and all import params (especially pruning that has to match db meta) - self.import_params.update_config( - &mut config, - &sc_service::Role::Full, - self.shared_params.dev, - )?; - - Ok(()) - } - /// Run the inspect command, passing the inspector. - pub fn run( - self, - inspect: Inspector, - ) -> sc_cli::Result<()> where - B: sp_runtime::traits::Block, + pub fn run(&self, config: Configuration) -> Result<()> + where + B: Block, B::Hash: FromStr, - P: PrettyPrinter, + RA: Send + Sync + 'static, + EX: NativeExecutionDispatch + 'static, { - match self.command { + let client = new_full_client::(&config)?; + let inspect = Inspector::::new(client); + + match &self.command { InspectSubCmd::Block { input } => { let input = input.parse()?; - let res = inspect.block(input) - .map_err(|e| format!("{}", e))?; + let res = inspect.block(input).map_err(|e| format!("{}", e))?; println!("{}", res); Ok(()) - }, + } InspectSubCmd::Extrinsic { input } => { let input = input.parse()?; - let res = inspect.extrinsic(input) - .map_err(|e| format!("{}", e))?; + let res = inspect.extrinsic(input).map_err(|e| format!("{}", e))?; println!("{}", res); Ok(()) - }, - } - } -} - -/// A block to retrieve. -#[derive(Debug, Clone, PartialEq)] -pub enum BlockAddress { - /// Get block by hash. - Hash(Hash), - /// Get block by number. - Number(Number), - /// Raw SCALE-encoded bytes. - Bytes(Vec), -} - -impl FromStr for BlockAddress { - type Err = String; - - fn from_str(s: &str) -> Result { - // try to parse hash first - if let Ok(hash) = s.parse() { - return Ok(Self::Hash(hash)) - } - - // then number - if let Ok(number) = s.parse() { - return Ok(Self::Number(number)) + } } - - // then assume it's bytes (hex-encoded) - sp_core::bytes::from_hex(s) - .map(Self::Bytes) - .map_err(|e| format!( - "Given string does not look like hash or number. It could not be parsed as bytes either: {}", - e - )) - } -} - -/// An extrinsic address to decode and print out. -#[derive(Debug, Clone, PartialEq)] -pub enum ExtrinsicAddress { - /// Extrinsic as part of existing block. - Block(BlockAddress, usize), - /// Raw SCALE-encoded extrinsic bytes. - Bytes(Vec), -} - -impl FromStr for ExtrinsicAddress { - type Err = String; - - fn from_str(s: &str) -> Result { - // first try raw bytes - if let Ok(bytes) = sp_core::bytes::from_hex(s).map(Self::Bytes) { - return Ok(bytes) - } - - // split by a bunch of different characters - let mut it = s.split(|c| c == '.' || c == ':' || c == ' '); - let block = it.next() - .expect("First element of split iterator is never empty; qed") - .parse()?; - - let index = it.next() - .ok_or_else(|| format!("Extrinsic index missing: example \"5:0\""))? - .parse() - .map_err(|e| format!("Invalid index format: {}", e))?; - - Ok(Self::Block(block, index)) } } -#[cfg(test)] -mod tests { - use super::*; - use sp_core::hash::H160 as Hash; - - #[test] - fn should_parse_block_strings() { - type BlockAddress = super::BlockAddress; - - let b0 = BlockAddress::from_str("3BfC20f0B9aFcAcE800D73D2191166FF16540258"); - let b1 = BlockAddress::from_str("1234"); - let b2 = BlockAddress::from_str("0"); - let b3 = BlockAddress::from_str("0x0012345f"); - - - assert_eq!(b0, Ok(BlockAddress::Hash( - "3BfC20f0B9aFcAcE800D73D2191166FF16540258".parse().unwrap() - ))); - assert_eq!(b1, Ok(BlockAddress::Number(1234))); - assert_eq!(b2, Ok(BlockAddress::Number(0))); - assert_eq!(b3, Ok(BlockAddress::Bytes(vec![0, 0x12, 0x34, 0x5f]))); +impl CliConfiguration for InspectCmd { + fn shared_params(&self) -> &SharedParams { + &self.shared_params } - #[test] - fn should_parse_extrinsic_address() { - type BlockAddress = super::BlockAddress; - type ExtrinsicAddress = super::ExtrinsicAddress; - - let e0 = ExtrinsicAddress::from_str("1234"); - let b0 = ExtrinsicAddress::from_str("3BfC20f0B9aFcAcE800D73D2191166FF16540258:5"); - let b1 = ExtrinsicAddress::from_str("1234:0"); - let b2 = ExtrinsicAddress::from_str("0 0"); - let b3 = ExtrinsicAddress::from_str("0x0012345f"); - - - assert_eq!(e0, Err("Extrinsic index missing: example \"5:0\"".into())); - assert_eq!(b0, Ok(ExtrinsicAddress::Block( - BlockAddress::Hash("3BfC20f0B9aFcAcE800D73D2191166FF16540258".parse().unwrap()), - 5 - ))); - assert_eq!(b1, Ok(ExtrinsicAddress::Block( - BlockAddress::Number(1234), - 0 - ))); - assert_eq!(b2, Ok(ExtrinsicAddress::Block( - BlockAddress::Number(0), - 0 - ))); - assert_eq!(b3, Ok(ExtrinsicAddress::Bytes(vec![0, 0x12, 0x34, 0x5f]))); + fn import_params(&self) -> Option<&ImportParams> { + Some(&self.import_params) } } diff --git a/bin/node/inspect/src/lib.rs b/bin/node/inspect/src/lib.rs index c82682d602..b8101d98a3 100644 --- a/bin/node/inspect/src/lib.rs +++ b/bin/node/inspect/src/lib.rs @@ -27,7 +27,9 @@ pub mod command; use std::{ fmt, - marker::PhantomData + fmt::Debug, + marker::PhantomData, + str::FromStr, }; use codec::{Encode, Decode}; use sc_client_api::BlockBackend; @@ -38,8 +40,6 @@ use sp_runtime::{ traits::{Block, HashFor, NumberFor, Hash} }; -use command::{BlockAddress, ExtrinsicAddress}; - /// A helper type for a generic block input. pub type BlockAddressFor = BlockAddress< as Hash>::Output, @@ -205,3 +205,123 @@ impl> Inspector Ok(format!("{}", ExtrinsicPrinter(ext, &self.printer))) } } + +/// A block to retrieve. +#[derive(Debug, Clone, PartialEq)] +pub enum BlockAddress { + /// Get block by hash. + Hash(Hash), + /// Get block by number. + Number(Number), + /// Raw SCALE-encoded bytes. + Bytes(Vec), +} + +impl FromStr for BlockAddress { + type Err = String; + + fn from_str(s: &str) -> Result { + // try to parse hash first + if let Ok(hash) = s.parse() { + return Ok(Self::Hash(hash)) + } + + // then number + if let Ok(number) = s.parse() { + return Ok(Self::Number(number)) + } + + // then assume it's bytes (hex-encoded) + sp_core::bytes::from_hex(s) + .map(Self::Bytes) + .map_err(|e| format!( + "Given string does not look like hash or number. It could not be parsed as bytes either: {}", + e + )) + } +} + +/// An extrinsic address to decode and print out. +#[derive(Debug, Clone, PartialEq)] +pub enum ExtrinsicAddress { + /// Extrinsic as part of existing block. + Block(BlockAddress, usize), + /// Raw SCALE-encoded extrinsic bytes. + Bytes(Vec), +} + +impl FromStr for ExtrinsicAddress { + type Err = String; + + fn from_str(s: &str) -> Result { + // first try raw bytes + if let Ok(bytes) = sp_core::bytes::from_hex(s).map(Self::Bytes) { + return Ok(bytes) + } + + // split by a bunch of different characters + let mut it = s.split(|c| c == '.' || c == ':' || c == ' '); + let block = it.next() + .expect("First element of split iterator is never empty; qed") + .parse()?; + + let index = it.next() + .ok_or_else(|| format!("Extrinsic index missing: example \"5:0\""))? + .parse() + .map_err(|e| format!("Invalid index format: {}", e))?; + + Ok(Self::Block(block, index)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use sp_core::hash::H160 as Hash; + + #[test] + fn should_parse_block_strings() { + type BlockAddress = super::BlockAddress; + + let b0 = BlockAddress::from_str("3BfC20f0B9aFcAcE800D73D2191166FF16540258"); + let b1 = BlockAddress::from_str("1234"); + let b2 = BlockAddress::from_str("0"); + let b3 = BlockAddress::from_str("0x0012345f"); + + + assert_eq!(b0, Ok(BlockAddress::Hash( + "3BfC20f0B9aFcAcE800D73D2191166FF16540258".parse().unwrap() + ))); + assert_eq!(b1, Ok(BlockAddress::Number(1234))); + assert_eq!(b2, Ok(BlockAddress::Number(0))); + assert_eq!(b3, Ok(BlockAddress::Bytes(vec![0, 0x12, 0x34, 0x5f]))); + } + + #[test] + fn should_parse_extrinsic_address() { + type BlockAddress = super::BlockAddress; + type ExtrinsicAddress = super::ExtrinsicAddress; + + let e0 = ExtrinsicAddress::from_str("1234"); + let b0 = ExtrinsicAddress::from_str("3BfC20f0B9aFcAcE800D73D2191166FF16540258:5"); + let b1 = ExtrinsicAddress::from_str("1234:0"); + let b2 = ExtrinsicAddress::from_str("0 0"); + let b3 = ExtrinsicAddress::from_str("0x0012345f"); + + + assert_eq!(e0, Err("Extrinsic index missing: example \"5:0\"".into())); + assert_eq!(b0, Ok(ExtrinsicAddress::Block( + BlockAddress::Hash("3BfC20f0B9aFcAcE800D73D2191166FF16540258".parse().unwrap()), + 5 + ))); + assert_eq!(b1, Ok(ExtrinsicAddress::Block( + BlockAddress::Number(1234), + 0 + ))); + assert_eq!(b2, Ok(ExtrinsicAddress::Block( + BlockAddress::Number(0), + 0 + ))); + assert_eq!(b3, Ok(ExtrinsicAddress::Bytes(vec![0, 0x12, 0x34, 0x5f]))); + } +} diff --git a/bin/node/testing/src/bench.rs b/bin/node/testing/src/bench.rs index 3bc8d483ea..5dd0d012fb 100644 --- a/bin/node/testing/src/bench.rs +++ b/bin/node/testing/src/bench.rs @@ -186,7 +186,7 @@ impl BenchDb { pruning: PruningMode::ArchiveAll, source: sc_client_db::DatabaseSettingsSrc::Path { path: dir.into(), - cache_size: None, + cache_size: 128, }, }; diff --git a/bin/utils/chain-spec-builder/src/main.rs b/bin/utils/chain-spec-builder/src/main.rs index 3673909706..5aa7e7fff7 100644 --- a/bin/utils/chain-spec-builder/src/main.rs +++ b/bin/utils/chain-spec-builder/src/main.rs @@ -87,7 +87,7 @@ fn genesis_constructor( let authorities = authority_seeds .iter() .map(AsRef::as_ref) - .map(chain_spec::get_authority_keys_from_seed) + .map(chain_spec::authority_keys_from_seed) .collect::>(); let enable_println = true; @@ -142,7 +142,7 @@ fn generate_authority_keys_and_store( ).map_err(|err| err.to_string())?; let (_, _, grandpa, babe, im_online, authority_discovery) = - chain_spec::get_authority_keys_from_seed(seed); + chain_spec::authority_keys_from_seed(seed); let insert_key = |key_type, public| { keystore.write().insert_unknown( diff --git a/client/cli/src/arg_enums.rs b/client/cli/src/arg_enums.rs index 384087bec0..f09a8d8d47 100644 --- a/client/cli/src/arg_enums.rs +++ b/client/cli/src/arg_enums.rs @@ -45,7 +45,9 @@ impl WasmExecutionMethod { impl Into for WasmExecutionMethod { fn into(self) -> sc_service::config::WasmExecutionMethod { match self { - WasmExecutionMethod::Interpreted => sc_service::config::WasmExecutionMethod::Interpreted, + WasmExecutionMethod::Interpreted => { + sc_service::config::WasmExecutionMethod::Interpreted + } #[cfg(feature = "wasmtime")] WasmExecutionMethod::Compiled => sc_service::config::WasmExecutionMethod::Compiled, #[cfg(not(feature = "wasmtime"))] diff --git a/client/cli/src/commands/build_spec_cmd.rs b/client/cli/src/commands/build_spec_cmd.rs index 67aaf998fc..a01101fa79 100644 --- a/client/cli/src/commands/build_spec_cmd.rs +++ b/client/cli/src/commands/build_spec_cmd.rs @@ -14,15 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use structopt::StructOpt; -use log::info; -use sc_network::config::{build_multiaddr, MultiaddrWithPeerId}; -use sc_service::{Configuration, ChainSpec}; - use crate::error; -use crate::VersionInfo; -use crate::params::SharedParams; use crate::params::NodeKeyParams; +use crate::params::SharedParams; +use crate::CliConfiguration; +use log::info; +use sc_network::config::build_multiaddr; +use sc_service::{config::MultiaddrWithPeerId, Configuration}; +use structopt::StructOpt; /// The `build-spec` command used to build a specification. #[derive(Debug, StructOpt, Clone)] @@ -49,12 +48,9 @@ pub struct BuildSpecCmd { impl BuildSpecCmd { /// Run the build-spec command - pub fn run( - self, - config: Configuration, - ) -> error::Result<()> { + pub fn run(&self, config: Configuration) -> error::Result<()> { info!("Building chain spec"); - let mut spec = config.chain_spec.expect("`chain_spec` is set to `Some` in `update_config`"); + let mut spec = config.chain_spec; let raw_output = self.raw; if spec.boot_nodes().is_empty() && !self.disable_default_bootnode { @@ -73,25 +69,14 @@ impl BuildSpecCmd { Ok(()) } +} - /// Update and prepare a `Configuration` with command line parameters - pub fn update_config( - &self, - mut config: &mut Configuration, - spec_factory: F, - version: &VersionInfo, - ) -> error::Result<()> where - F: FnOnce(&str) -> Result, String>, - { - self.shared_params.update_config(&mut config, spec_factory, version)?; - - let net_config_path = config - .in_chain_config_dir(crate::commands::DEFAULT_NETWORK_CONFIG_PATH) - .expect("We provided a base_path"); - - self.node_key_params.update_config(&mut config, Some(&net_config_path))?; +impl CliConfiguration for BuildSpecCmd { + fn shared_params(&self) -> &SharedParams { + &self.shared_params + } - Ok(()) + fn node_key_params(&self) -> Option<&NodeKeyParams> { + Some(&self.node_key_params) } } - diff --git a/client/cli/src/commands/check_block_cmd.rs b/client/cli/src/commands/check_block_cmd.rs index ba267bbf4b..ac4fe63da9 100644 --- a/client/cli/src/commands/check_block_cmd.rs +++ b/client/cli/src/commands/check_block_cmd.rs @@ -14,20 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use crate::error; +use crate::params::ImportParams; +use crate::params::SharedParams; +use crate::CliConfiguration; +use sc_service::{Configuration, ServiceBuilderCommand}; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use std::fmt::Debug; use std::str::FromStr; use structopt::StructOpt; -use sc_service::{ - Configuration, ServiceBuilderCommand, Role, ChainSpec, -}; -use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; -use sp_runtime::generic::BlockId; - -use crate::error; -use crate::VersionInfo; -use crate::runtime::run_until_exit; -use crate::params::SharedParams; -use crate::params::ImportParams; /// The `check-block` command used to validate blocks. #[derive(Debug, StructOpt, Clone)] @@ -53,8 +49,8 @@ pub struct CheckBlockCmd { impl CheckBlockCmd { /// Run the check-block command - pub fn run( - self, + pub async fn run( + &self, config: Configuration, builder: B, ) -> error::Result<()> @@ -65,37 +61,37 @@ impl CheckBlockCmd { <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, ::Hash: std::str::FromStr, { - let input = if self.input.starts_with("0x") { &self.input[2..] } else { &self.input[..] }; + let input = if self.input.starts_with("0x") { + &self.input[2..] + } else { + &self.input[..] + }; let block_id = match FromStr::from_str(input) { Ok(hash) => BlockId::hash(hash), Err(_) => match self.input.parse::() { Ok(n) => BlockId::number((n as u32).into()), - Err(_) => return Err(error::Error::Input("Invalid hash or number specified".into())), - } + Err(_) => { + return Err(error::Error::Input( + "Invalid hash or number specified".into(), + )) + } + }, }; let start = std::time::Instant::now(); - run_until_exit(config, |config| { - Ok(builder(config)?.check_block(block_id)) - })?; + builder(config)?.check_block(block_id).await?; println!("Completed in {} ms.", start.elapsed().as_millis()); Ok(()) } +} - /// Update and prepare a `Configuration` with command line parameters - pub fn update_config( - &self, - mut config: &mut Configuration, - spec_factory: F, - version: &VersionInfo, - ) -> error::Result<()> where - F: FnOnce(&str) -> Result, String>, - { - self.shared_params.update_config(&mut config, spec_factory, version)?; - self.import_params.update_config(&mut config, &Role::Full, self.shared_params.dev)?; - config.use_in_memory_keystore()?; +impl CliConfiguration for CheckBlockCmd { + fn shared_params(&self) -> &SharedParams { + &self.shared_params + } - Ok(()) + fn import_params(&self) -> Option<&ImportParams> { + Some(&self.import_params) } } diff --git a/client/cli/src/commands/export_blocks_cmd.rs b/client/cli/src/commands/export_blocks_cmd.rs index 26cfcf61bf..48abd409d6 100644 --- a/client/cli/src/commands/export_blocks_cmd.rs +++ b/client/cli/src/commands/export_blocks_cmd.rs @@ -14,22 +14,19 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::io; -use std::fs; -use std::path::PathBuf; -use std::fmt::Debug; +use crate::error; +use crate::params::{BlockNumber, PruningParams, SharedParams}; +use crate::CliConfiguration; use log::info; -use structopt::StructOpt; use sc_service::{ - Configuration, ServiceBuilderCommand, ChainSpec, - config::DatabaseConfig, Role, + config::DatabaseConfig, Configuration, ServiceBuilderCommand, }; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; - -use crate::error; -use crate::VersionInfo; -use crate::runtime::run_until_exit; -use crate::params::{SharedParams, BlockNumber, PruningParams}; +use std::fmt::Debug; +use std::fs; +use std::io; +use std::path::PathBuf; +use structopt::StructOpt; /// The `export-blocks` command used to export blocks. #[derive(Debug, StructOpt, Clone)] @@ -65,8 +62,8 @@ pub struct ExportBlocksCmd { impl ExportBlocksCmd { /// Run the export-blocks command - pub fn run( - self, + pub async fn run( + &self, config: Configuration, builder: B, ) -> error::Result<()> @@ -77,9 +74,10 @@ impl ExportBlocksCmd { <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, ::Hash: std::str::FromStr, { - if let DatabaseConfig::Path { ref path, .. } = config.expect_database() { + if let DatabaseConfig::Path { ref path, .. } = &config.database { info!("DB path: {}", path.display()); } + let from = self.from.as_ref().and_then(|f| f.parse().ok()).unwrap_or(1); let to = self.to.as_ref().and_then(|t| t.parse().ok()); @@ -90,24 +88,19 @@ impl ExportBlocksCmd { None => Box::new(io::stdout()), }; - run_until_exit(config, |config| { - Ok(builder(config)?.export_blocks(file, from.into(), to, binary)) - }) + builder(config)? + .export_blocks(file, from.into(), to, binary) + .await + .map_err(Into::into) } +} - /// Update and prepare a `Configuration` with command line parameters - pub fn update_config( - &self, - mut config: &mut Configuration, - spec_factory: F, - version: &VersionInfo, - ) -> error::Result<()> where - F: FnOnce(&str) -> Result, String>, - { - self.shared_params.update_config(&mut config, spec_factory, version)?; - self.pruning_params.update_config(&mut config, &Role::Full, true)?; - config.use_in_memory_keystore()?; +impl CliConfiguration for ExportBlocksCmd { + fn shared_params(&self) -> &SharedParams { + &self.shared_params + } - Ok(()) + fn pruning_params(&self) -> Option<&PruningParams> { + Some(&self.pruning_params) } } diff --git a/client/cli/src/commands/import_blocks_cmd.rs b/client/cli/src/commands/import_blocks_cmd.rs index 5dc8debe06..ce95640f46 100644 --- a/client/cli/src/commands/import_blocks_cmd.rs +++ b/client/cli/src/commands/import_blocks_cmd.rs @@ -14,21 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use crate::error; +use crate::params::ImportParams; +use crate::params::SharedParams; +use crate::CliConfiguration; +use sc_service::{Configuration, ServiceBuilderCommand}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use std::fmt::Debug; -use std::io::{Read, Seek, self}; use std::fs; +use std::io::{self, Read, Seek}; use std::path::PathBuf; use structopt::StructOpt; -use sc_service::{ - Configuration, ServiceBuilderCommand, ChainSpec, Role, -}; -use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; - -use crate::error; -use crate::VersionInfo; -use crate::runtime::run_until_exit; -use crate::params::SharedParams; -use crate::params::ImportParams; /// The `import-blocks` command used to import blocks. #[derive(Debug, StructOpt, Clone)] @@ -59,8 +55,8 @@ impl ReadPlusSeek for T {} impl ImportBlocksCmd { /// Run the import-blocks command - pub fn run( - self, + pub async fn run( + &self, config: Configuration, builder: B, ) -> error::Result<()> @@ -77,27 +73,22 @@ impl ImportBlocksCmd { let mut buffer = Vec::new(); io::stdin().read_to_end(&mut buffer)?; Box::new(io::Cursor::new(buffer)) - }, + } }; - run_until_exit(config, |config| { - Ok(builder(config)?.import_blocks(file, false)) - }) + builder(config)? + .import_blocks(file, false) + .await + .map_err(Into::into) } +} - /// Update and prepare a `Configuration` with command line parameters - pub fn update_config( - &self, - mut config: &mut Configuration, - spec_factory: F, - version: &VersionInfo, - ) -> error::Result<()> where - F: FnOnce(&str) -> Result, String>, - { - self.shared_params.update_config(&mut config, spec_factory, version)?; - self.import_params.update_config(&mut config, &Role::Full, self.shared_params.dev)?; - config.use_in_memory_keystore()?; +impl CliConfiguration for ImportBlocksCmd { + fn shared_params(&self) -> &SharedParams { + &self.shared_params + } - Ok(()) + fn import_params(&self) -> Option<&ImportParams> { + Some(&self.import_params) } } diff --git a/client/cli/src/commands/mod.rs b/client/cli/src/commands/mod.rs index d87b08f7f4..d05a5464b2 100644 --- a/client/cli/src/commands/mod.rs +++ b/client/cli/src/commands/mod.rs @@ -14,34 +14,23 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -mod runcmd; -mod export_blocks_cmd; mod build_spec_cmd; -mod import_blocks_cmd; mod check_block_cmd; -mod revert_cmd; +mod export_blocks_cmd; +mod import_blocks_cmd; mod purge_chain_cmd; +mod revert_cmd; +mod runcmd; -use std::fmt::Debug; -use structopt::StructOpt; - -use sc_service::{ Configuration, ServiceBuilderCommand, ChainSpec }; -use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; - -use crate::error; -use crate::VersionInfo; -use crate::params::SharedParams; - -pub use crate::commands::runcmd::RunCmd; -pub use crate::commands::export_blocks_cmd::ExportBlocksCmd; pub use crate::commands::build_spec_cmd::BuildSpecCmd; -pub use crate::commands::import_blocks_cmd::ImportBlocksCmd; pub use crate::commands::check_block_cmd::CheckBlockCmd; -pub use crate::commands::revert_cmd::RevertCmd; +pub use crate::commands::export_blocks_cmd::ExportBlocksCmd; +pub use crate::commands::import_blocks_cmd::ImportBlocksCmd; pub use crate::commands::purge_chain_cmd::PurgeChainCmd; - -/// default sub directory to store network config -const DEFAULT_NETWORK_CONFIG_PATH : &'static str = "network"; +pub use crate::commands::revert_cmd::RevertCmd; +pub use crate::commands::runcmd::RunCmd; +use std::fmt::Debug; +use structopt::StructOpt; /// All core commands that are provided by default. /// @@ -51,89 +40,338 @@ const DEFAULT_NETWORK_CONFIG_PATH : &'static str = "network"; #[derive(Debug, Clone, StructOpt)] pub enum Subcommand { /// Build a spec.json file, outputs to stdout. - BuildSpec(build_spec_cmd::BuildSpecCmd), + BuildSpec(BuildSpecCmd), /// Export blocks to a file. - ExportBlocks(export_blocks_cmd::ExportBlocksCmd), + ExportBlocks(ExportBlocksCmd), /// Import blocks from file. - ImportBlocks(import_blocks_cmd::ImportBlocksCmd), + ImportBlocks(ImportBlocksCmd), /// Validate a single block. - CheckBlock(check_block_cmd::CheckBlockCmd), + CheckBlock(CheckBlockCmd), /// Revert chain to the previous state. - Revert(revert_cmd::RevertCmd), + Revert(RevertCmd), /// Remove the whole chain data. - PurgeChain(purge_chain_cmd::PurgeChainCmd), + PurgeChain(PurgeChainCmd), } -impl Subcommand { - /// Get the shared parameters of a `CoreParams` command. - pub fn get_shared_params(&self) -> &SharedParams { - use Subcommand::*; - - match self { - BuildSpec(params) => ¶ms.shared_params, - ExportBlocks(params) => ¶ms.shared_params, - ImportBlocks(params) => ¶ms.shared_params, - CheckBlock(params) => ¶ms.shared_params, - Revert(params) => ¶ms.shared_params, - PurgeChain(params) => ¶ms.shared_params, - } - } +// TODO: move to config.rs? +/// Macro that helps implement CliConfiguration on an enum of subcommand automatically +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate sc_cli; +/// +/// # struct EmptyVariant {} +/// +/// # impl sc_cli::CliConfiguration for EmptyVariant { +/// # fn shared_params(&self) -> &sc_cli::SharedParams { unimplemented!() } +/// # fn chain_id(&self, _: bool) -> sc_cli::Result { Ok("test-chain-id".to_string()) } +/// # } +/// +/// # fn main() { +/// enum Subcommand { +/// Variant1(EmptyVariant), +/// Variant2(EmptyVariant), +/// } +/// +/// substrate_cli_subcommands!( +/// Subcommand => Variant1, Variant2 +/// ); +/// +/// # use sc_cli::CliConfiguration; +/// # assert_eq!(Subcommand::Variant1(EmptyVariant {}).chain_id(false).unwrap(), "test-chain-id"); +/// +/// # } +/// ``` +/// +/// Which will expand to: +/// +/// ```ignore +/// impl CliConfiguration for Subcommand { +/// fn base_path(&self) -> Result> { +/// match self { +/// Subcommand::Variant1(cmd) => cmd.base_path(), +/// Subcommand::Variant2(cmd) => cmd.base_path(), +/// } +/// } +/// +/// fn is_dev(&self) -> Result { +/// match self { +/// Subcommand::Variant1(cmd) => cmd.is_dev(), +/// Subcommand::Variant2(cmd) => cmd.is_dev(), +/// } +/// } +/// +/// // ... +/// } +/// ``` +#[macro_export] +macro_rules! substrate_cli_subcommands { + ($enum:ident => $($variant:ident),*) => { + impl $crate::CliConfiguration for $enum { + fn shared_params(&self) -> &$crate::SharedParams { + match self { + $($enum::$variant(cmd) => cmd.shared_params()),* + } + } - /// Run any `CoreParams` command. - pub fn run( - self, - config: Configuration, - builder: B, - ) -> error::Result<()> - where - B: FnOnce(Configuration) -> Result, - BC: ServiceBuilderCommand + Unpin, - BB: sp_runtime::traits::Block + Debug, - <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, - ::Hash: std::str::FromStr, - { - match self { - Subcommand::BuildSpec(cmd) => cmd.run(config), - Subcommand::ExportBlocks(cmd) => cmd.run(config, builder), - Subcommand::ImportBlocks(cmd) => cmd.run(config, builder), - Subcommand::CheckBlock(cmd) => cmd.run(config, builder), - Subcommand::PurgeChain(cmd) => cmd.run(config), - Subcommand::Revert(cmd) => cmd.run(config, builder), - } - } + fn import_params(&self) -> Option<&$crate::ImportParams> { + match self { + $($enum::$variant(cmd) => cmd.import_params()),* + } + } - /// Update and prepare a `Configuration` with command line parameters. - pub fn update_config( - &self, - mut config: &mut Configuration, - spec_factory: F, - version: &VersionInfo, - ) -> error::Result<()> where - F: FnOnce(&str) -> Result, String>, - { - match self { - Subcommand::BuildSpec(cmd) => cmd.update_config(&mut config, spec_factory, version), - Subcommand::ExportBlocks(cmd) => cmd.update_config(&mut config, spec_factory, version), - Subcommand::ImportBlocks(cmd) => cmd.update_config(&mut config, spec_factory, version), - Subcommand::CheckBlock(cmd) => cmd.update_config(&mut config, spec_factory, version), - Subcommand::PurgeChain(cmd) => cmd.update_config(&mut config, spec_factory, version), - Subcommand::Revert(cmd) => cmd.update_config(&mut config, spec_factory, version), - } - } + fn pruning_params(&self) -> Option<&$crate::PruningParams> { + match self { + $($enum::$variant(cmd) => cmd.pruning_params()),* + } + } + + fn keystore_params(&self) -> Option<&$crate::KeystoreParams> { + match self { + $($enum::$variant(cmd) => cmd.keystore_params()),* + } + } + + fn network_params(&self) -> Option<&$crate::NetworkParams> { + match self { + $($enum::$variant(cmd) => cmd.network_params()),* + } + } + + fn base_path(&self) -> $crate::Result<::std::option::Option<::std::path::PathBuf>> { + match self { + $($enum::$variant(cmd) => cmd.base_path()),* + } + } + + fn is_dev(&self) -> $crate::Result { + match self { + $($enum::$variant(cmd) => cmd.is_dev()),* + } + } + + fn role(&self, is_dev: bool) -> $crate::Result<::sc_service::Role> { + match self { + $($enum::$variant(cmd) => cmd.role(is_dev)),* + } + } + + fn transaction_pool(&self) + -> $crate::Result<::sc_service::config::TransactionPoolOptions> { + match self { + $($enum::$variant(cmd) => cmd.transaction_pool()),* + } + } + + fn network_config( + &self, + chain_spec: &::std::boxed::Box, + is_dev: bool, + net_config_dir: &::std::path::PathBuf, + client_id: &str, + node_name: &str, + node_key: ::sc_service::config::NodeKeyConfig, + ) -> $crate::Result<::sc_service::config::NetworkConfiguration> { + match self { + $( + $enum::$variant(cmd) => cmd.network_config( + chain_spec, is_dev, net_config_dir, client_id, node_name, node_key + ) + ),* + } + } + + fn keystore_config(&self, base_path: &::std::path::PathBuf) + -> $crate::Result<::sc_service::config::KeystoreConfig> { + match self { + $($enum::$variant(cmd) => cmd.keystore_config(base_path)),* + } + } + + fn database_cache_size(&self) -> $crate::Result<::std::option::Option> { + match self { + $($enum::$variant(cmd) => cmd.database_cache_size()),* + } + } + + fn database_config( + &self, + base_path: &::std::path::PathBuf, + cache_size: usize, + ) -> $crate::Result<::sc_service::config::DatabaseConfig> { + match self { + $($enum::$variant(cmd) => cmd.database_config(base_path, cache_size)),* + } + } + + fn state_cache_size(&self) -> $crate::Result { + match self { + $($enum::$variant(cmd) => cmd.state_cache_size()),* + } + } + + fn state_cache_child_ratio(&self) -> $crate::Result<::std::option::Option> { + match self { + $($enum::$variant(cmd) => cmd.state_cache_child_ratio()),* + } + } + + fn pruning(&self, is_dev: bool, role: &::sc_service::Role) + -> $crate::Result<::sc_service::config::PruningMode> { + match self { + $($enum::$variant(cmd) => cmd.pruning(is_dev, role)),* + } + } + + fn chain_id(&self, is_dev: bool) -> $crate::Result { + match self { + $($enum::$variant(cmd) => cmd.chain_id(is_dev)),* + } + } + + fn init(&self) -> $crate::Result<()> { + match self { + $($enum::$variant(cmd) => cmd.init::()),* + } + } + + fn node_name(&self) -> $crate::Result { + match self { + $($enum::$variant(cmd) => cmd.node_name()),* + } + } + + fn wasm_method(&self) -> $crate::Result<::sc_service::config::WasmExecutionMethod> { + match self { + $($enum::$variant(cmd) => cmd.wasm_method()),* + } + } - /// Initialize substrate. This must be done only once. - /// - /// This method: - /// - /// 1. Set the panic handler - /// 2. Raise the FD limit - /// 3. Initialize the logger - pub fn init(&self, version: &VersionInfo) -> error::Result<()> { - self.get_shared_params().init(version) + fn execution_strategies(&self, is_dev: bool) + -> $crate::Result<::sc_service::config::ExecutionStrategies> { + match self { + $($enum::$variant(cmd) => cmd.execution_strategies(is_dev)),* + } + } + + fn rpc_http(&self) -> $crate::Result<::std::option::Option<::std::net::SocketAddr>> { + match self { + $($enum::$variant(cmd) => cmd.rpc_http()),* + } + } + + fn rpc_ws(&self) -> $crate::Result<::std::option::Option<::std::net::SocketAddr>> { + match self { + $($enum::$variant(cmd) => cmd.rpc_ws()),* + } + } + + fn rpc_ws_max_connections(&self) -> $crate::Result<::std::option::Option> { + match self { + $($enum::$variant(cmd) => cmd.rpc_ws_max_connections()),* + } + } + + fn rpc_cors(&self, is_dev: bool) + -> $crate::Result<::std::option::Option<::std::vec::Vec>> { + match self { + $($enum::$variant(cmd) => cmd.rpc_cors(is_dev)),* + } + } + + fn prometheus_config(&self) + -> $crate::Result<::std::option::Option<::sc_service::config::PrometheusConfig>> { + match self { + $($enum::$variant(cmd) => cmd.prometheus_config()),* + } + } + + fn telemetry_endpoints( + &self, + chain_spec: &Box, + ) -> $crate::Result<::std::option::Option<::sc_service::config::TelemetryEndpoints>> { + match self { + $($enum::$variant(cmd) => cmd.telemetry_endpoints(chain_spec)),* + } + } + + fn telemetry_external_transport(&self) + -> $crate::Result<::std::option::Option<::sc_service::config::ExtTransport>> { + match self { + $($enum::$variant(cmd) => cmd.telemetry_external_transport()),* + } + } + + fn default_heap_pages(&self) -> $crate::Result<::std::option::Option> { + match self { + $($enum::$variant(cmd) => cmd.default_heap_pages()),* + } + } + + fn offchain_worker(&self, role: &::sc_service::Role) -> $crate::Result { + match self { + $($enum::$variant(cmd) => cmd.offchain_worker(role)),* + } + } + + fn force_authoring(&self) -> $crate::Result { + match self { + $($enum::$variant(cmd) => cmd.force_authoring()),* + } + } + + fn disable_grandpa(&self) -> $crate::Result { + match self { + $($enum::$variant(cmd) => cmd.disable_grandpa()),* + } + } + + fn dev_key_seed(&self, is_dev: bool) -> $crate::Result<::std::option::Option> { + match self { + $($enum::$variant(cmd) => cmd.dev_key_seed(is_dev)),* + } + } + + fn tracing_targets(&self) -> $crate::Result<::std::option::Option> { + match self { + $($enum::$variant(cmd) => cmd.tracing_targets()),* + } + } + + fn tracing_receiver(&self) -> $crate::Result<::sc_service::TracingReceiver> { + match self { + $($enum::$variant(cmd) => cmd.tracing_receiver()),* + } + } + + fn node_key(&self, net_config_dir: &::std::path::PathBuf) + -> $crate::Result<::sc_service::config::NodeKeyConfig> { + match self { + $($enum::$variant(cmd) => cmd.node_key(net_config_dir)),* + } + } + + fn max_runtime_instances(&self) -> $crate::Result<::std::option::Option> { + match self { + $($enum::$variant(cmd) => cmd.max_runtime_instances()),* + } + } + + fn log_filters(&self) -> $crate::Result<::std::option::Option> { + match self { + $($enum::$variant(cmd) => cmd.log_filters()),* + } + } + } } } + +substrate_cli_subcommands!( + Subcommand => BuildSpec, ExportBlocks, ImportBlocks, CheckBlock, Revert, PurgeChain +); diff --git a/client/cli/src/commands/purge_chain_cmd.rs b/client/cli/src/commands/purge_chain_cmd.rs index e12a50bf24..845423695e 100644 --- a/client/cli/src/commands/purge_chain_cmd.rs +++ b/client/cli/src/commands/purge_chain_cmd.rs @@ -14,15 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use crate::error; +use crate::params::SharedParams; +use crate::CliConfiguration; +use sc_service::{config::DatabaseConfig, Configuration}; use std::fmt::Debug; -use std::io::{Write, self}; use std::fs; +use std::io::{self, Write}; use structopt::StructOpt; -use sc_service::{ Configuration, ChainSpec, config::{DatabaseConfig} }; - -use crate::error; -use crate::VersionInfo; -use crate::params::SharedParams; /// The `purge-chain` command used to remove the whole chain. #[derive(Debug, StructOpt, Clone)] @@ -38,11 +37,8 @@ pub struct PurgeChainCmd { impl PurgeChainCmd { /// Run the purge command - pub fn run( - self, - config: Configuration, - ) -> error::Result<()> { - let db_path = match config.expect_database() { + pub fn run(&self, config: Configuration) -> error::Result<()> { + let db_path = match &config.database { DatabaseConfig::Path { path, .. } => path, _ => { eprintln!("Cannot purge custom database implementation"); @@ -76,22 +72,13 @@ impl PurgeChainCmd { eprintln!("{:?} did not exist.", &db_path); Ok(()) }, - Err(err) => Result::Err(err.into()) + Err(err) => Result::Err(err.into()), } } +} - /// Update and prepare a `Configuration` with command line parameters - pub fn update_config( - &self, - mut config: &mut Configuration, - spec_factory: F, - version: &VersionInfo, - ) -> error::Result<()> where - F: FnOnce(&str) -> Result, String>, - { - self.shared_params.update_config(&mut config, spec_factory, version)?; - config.use_in_memory_keystore()?; - - Ok(()) +impl CliConfiguration for PurgeChainCmd { + fn shared_params(&self) -> &SharedParams { + &self.shared_params } } diff --git a/client/cli/src/commands/revert_cmd.rs b/client/cli/src/commands/revert_cmd.rs index 9617f8eda4..f7629ff2f6 100644 --- a/client/cli/src/commands/revert_cmd.rs +++ b/client/cli/src/commands/revert_cmd.rs @@ -14,16 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use crate::error; +use crate::params::{BlockNumber, PruningParams, SharedParams}; +use crate::CliConfiguration; +use sc_service::{Configuration, ServiceBuilderCommand}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use std::fmt::Debug; use structopt::StructOpt; -use sc_service::{ - Configuration, ServiceBuilderCommand, ChainSpec, Role, -}; -use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; - -use crate::error; -use crate::VersionInfo; -use crate::params::{BlockNumber, SharedParams, PruningParams}; /// The `revert` command used revert the chain to a previous state. #[derive(Debug, StructOpt, Clone)] @@ -43,11 +40,7 @@ pub struct RevertCmd { impl RevertCmd { /// Run the revert command - pub fn run( - self, - config: Configuration, - builder: B, - ) -> error::Result<()> + pub fn run(&self, config: Configuration, builder: B) -> error::Result<()> where B: FnOnce(Configuration) -> Result, BC: ServiceBuilderCommand + Unpin, @@ -60,20 +53,14 @@ impl RevertCmd { Ok(()) } +} - /// Update and prepare a `Configuration` with command line parameters - pub fn update_config( - &self, - mut config: &mut Configuration, - spec_factory: F, - version: &VersionInfo, - ) -> error::Result<()> where - F: FnOnce(&str) -> Result, String>, - { - self.shared_params.update_config(&mut config, spec_factory, version)?; - self.pruning_params.update_config(&mut config, &Role::Full, true)?; - config.use_in_memory_keystore()?; +impl CliConfiguration for RevertCmd { + fn shared_params(&self) -> &SharedParams { + &self.shared_params + } - Ok(()) + fn pruning_params(&self) -> Option<&PruningParams> { + Some(&self.pruning_params) } } diff --git a/client/cli/src/commands/runcmd.rs b/client/cli/src/commands/runcmd.rs index 30cefa5d0c..b3ce6ce6d1 100644 --- a/client/cli/src/commands/runcmd.rs +++ b/client/cli/src/commands/runcmd.rs @@ -14,34 +14,21 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::path::PathBuf; -use std::net::SocketAddr; -use std::fs; -use std::fmt; -use log::info; -use structopt::{StructOpt, clap::arg_enum}; -use names::{Generator, Name}; +use crate::error::{Error, Result}; +use crate::params::ImportParams; +use crate::params::KeystoreParams; +use crate::params::NetworkParams; +use crate::params::SharedParams; +use crate::params::TransactionPoolParams; +use crate::CliConfiguration; use regex::Regex; -use chrono::prelude::*; use sc_service::{ - AbstractService, Configuration, ChainSpec, Role, - config::{MultiaddrWithPeerId, KeystoreConfig, PrometheusConfig}, + config::{MultiaddrWithPeerId, PrometheusConfig, TransactionPoolOptions}, + ChainSpec, Role, }; use sc_telemetry::TelemetryEndpoints; - -use crate::VersionInfo; -use crate::error; -use crate::params::ImportParams; -use crate::params::SharedParams; -use crate::params::NetworkConfigurationParams; -use crate::params::TransactionPoolParams; -use crate::runtime::run_service_until_exit; - -/// The maximum number of characters for a node name. -const NODE_NAME_MAX_LENGTH: usize = 32; - -/// default sub directory for the key store -const DEFAULT_KEYSTORE_CONFIG_PATH : &'static str = "keystore"; +use std::net::SocketAddr; +use structopt::{clap::arg_enum, StructOpt}; arg_enum! { /// Whether off-chain workers are enabled. @@ -200,7 +187,7 @@ pub struct RunCmd { #[allow(missing_docs)] #[structopt(flatten)] - pub network_config: NetworkConfigurationParams, + pub network_params: NetworkParams, #[allow(missing_docs)] #[structopt(flatten)] @@ -242,38 +229,23 @@ pub struct RunCmd { #[structopt(long = "force-authoring")] pub force_authoring: bool, - /// Specify custom keystore path. - #[structopt(long = "keystore-path", value_name = "PATH", parse(from_os_str))] - pub keystore_path: Option, - - /// Use interactive shell for entering the password used by the keystore. - #[structopt( - long = "password-interactive", - conflicts_with_all = &[ "password", "password-filename" ] - )] - pub password_interactive: bool, - - /// Password used by the keystore. - #[structopt( - long = "password", - conflicts_with_all = &[ "password-interactive", "password-filename" ] - )] - pub password: Option, - - /// File that contains the password used by the keystore. - #[structopt( - long = "password-filename", - value_name = "PATH", - parse(from_os_str), - conflicts_with_all = &[ "password-interactive", "password" ] - )] - pub password_filename: Option, + #[allow(missing_docs)] + #[structopt(flatten)] + pub keystore_params: KeystoreParams, /// The size of the instances cache for each runtime. /// /// The default value is 8 and the values higher than 256 are ignored. - #[structopt(long = "max-runtime-instances", default_value = "8")] - pub max_runtime_instances: usize, + #[structopt(long)] + pub max_runtime_instances: Option, + + /// Specify a list of sentry node public addresses. + #[structopt( + long = "sentry-nodes", + value_name = "ADDR", + conflicts_with_all = &[ "sentry" ] + )] + pub sentry_nodes: Vec, } impl RunCmd { @@ -281,219 +253,203 @@ impl RunCmd { pub fn get_keyring(&self) -> Option { use sp_keyring::Sr25519Keyring::*; - if self.alice { Some(Alice) } - else if self.bob { Some(Bob) } - else if self.charlie { Some(Charlie) } - else if self.dave { Some(Dave) } - else if self.eve { Some(Eve) } - else if self.ferdie { Some(Ferdie) } - else if self.one { Some(One) } - else if self.two { Some(Two) } - else { None } - } - - /// Update and prepare a `Configuration` with command line parameters of `RunCmd` and `VersionInfo`. - pub fn update_config( - &self, - mut config: &mut Configuration, - spec_factory: F, - version: &VersionInfo, - ) -> error::Result<()> - where - F: FnOnce(&str) -> Result, String>, - { - self.shared_params.update_config(&mut config, spec_factory, version)?; - - let password = if self.password_interactive { - #[cfg(not(target_os = "unknown"))] - { - Some(input_keystore_password()?.into()) - } - #[cfg(target_os = "unknown")] - None - } else if let Some(ref file) = self.password_filename { - Some(fs::read_to_string(file).map_err(|e| format!("{}", e))?.into()) - } else if let Some(ref password) = self.password { - Some(password.clone().into()) + if self.alice { + Some(Alice) + } else if self.bob { + Some(Bob) + } else if self.charlie { + Some(Charlie) + } else if self.dave { + Some(Dave) + } else if self.eve { + Some(Eve) + } else if self.ferdie { + Some(Ferdie) + } else if self.one { + Some(One) + } else if self.two { + Some(Two) } else { None - }; + } + } +} - let path = self.keystore_path.clone().or( - config.in_chain_config_dir(DEFAULT_KEYSTORE_CONFIG_PATH) - ); +impl CliConfiguration for RunCmd { + fn shared_params(&self) -> &SharedParams { + &self.shared_params + } - config.keystore = KeystoreConfig::Path { - path: path.ok_or_else(|| "No `base_path` provided to create keystore path!".to_string())?, - password, - }; + fn import_params(&self) -> Option<&ImportParams> { + Some(&self.import_params) + } - let keyring = self.get_keyring(); - let is_dev = self.shared_params.dev; - let is_light = self.light; - let is_authority = (self.validator || is_dev || keyring.is_some()) - && !is_light; - let role = - if is_light { - sc_service::Role::Light - } else if is_authority { - sc_service::Role::Authority { sentry_nodes: self.network_config.sentry_nodes.clone() } - } else if !self.sentry.is_empty() { - sc_service::Role::Sentry { validators: self.sentry.clone() } - } else { - sc_service::Role::Full - }; + fn network_params(&self) -> Option<&NetworkParams> { + Some(&self.network_params) + } - self.import_params.update_config(&mut config, &role, is_dev)?; + fn keystore_params(&self) -> Option<&KeystoreParams> { + Some(&self.keystore_params) + } - config.name = match (self.name.as_ref(), keyring) { + fn node_name(&self) -> Result { + let name: String = match (self.name.as_ref(), self.get_keyring()) { (Some(name), _) => name.to_string(), (_, Some(keyring)) => keyring.to_string(), - (None, None) => generate_node_name(), + (None, None) => crate::generate_node_name(), }; - if let Err(msg) = is_node_name_valid(&config.name) { - return Err(error::Error::Input( - format!("Invalid node name '{}'. Reason: {}. If unsure, use none.", - config.name, - msg, - ) + + is_node_name_valid(&name).map_err(|msg| { + Error::Input(format!( + "Invalid node name '{}'. Reason: {}. If unsure, use none.", + name, msg )); - } + })?; - config.offchain_worker = match (&self.offchain_worker, &role) { - (OffchainWorkerEnabled::WhenValidating, sc_service::Role::Authority { .. }) => true, - (OffchainWorkerEnabled::Always, _) => true, - (OffchainWorkerEnabled::Never, _) => false, - (OffchainWorkerEnabled::WhenValidating, _) => false, - }; + Ok(name) + } - config.role = role; - config.disable_grandpa = self.no_grandpa; - - let client_id = config.client_id(); - let network_path = config - .in_chain_config_dir(crate::commands::DEFAULT_NETWORK_CONFIG_PATH) - .expect("We provided a basepath"); - self.network_config.update_config( - &mut config, - network_path, - client_id, - is_dev, - )?; - - self.pool_config.update_config(&mut config)?; - - config.dev_key_seed = keyring - .map(|a| format!("//{}", a)).or_else(|| { - if is_dev && !is_light { - Some("//Alice".into()) - } else { - None - } - }); + fn dev_key_seed(&self, is_dev: bool) -> Result> { + Ok(self.get_keyring().map(|a| format!("//{}", a)).or_else(|| { + if is_dev && !self.light { + Some("//Alice".into()) + } else { + None + } + })) + } - if config.rpc_http.is_none() || self.rpc_port.is_some() { - let rpc_interface: &str = interface_str(self.rpc_external, self.unsafe_rpc_external, self.validator)?; - config.rpc_http = Some(parse_address(&format!("{}:{}", rpc_interface, 9933), self.rpc_port)?); - } - if config.rpc_ws.is_none() || self.ws_port.is_some() { - let ws_interface: &str = interface_str(self.ws_external, self.unsafe_ws_external, self.validator)?; - config.rpc_ws = Some(parse_address(&format!("{}:{}", ws_interface, 9944), self.ws_port)?); - } + fn telemetry_endpoints( + &self, + chain_spec: &Box, + ) -> Result> { + Ok(if self.no_telemetry { + None + } else if !self.telemetry_endpoints.is_empty() { + Some( + TelemetryEndpoints::new(self.telemetry_endpoints.clone()) + .map_err(|e| e.to_string())?, + ) + } else { + chain_spec.telemetry_endpoints().clone() + }) + } + + fn role(&self, is_dev: bool) -> Result { + let keyring = self.get_keyring(); + let is_light = self.light; + let is_authority = (self.validator || is_dev || keyring.is_some()) && !is_light; - config.rpc_ws_max_connections = self.ws_max_connections; - config.rpc_cors = self.rpc_cors.clone().unwrap_or_else(|| if is_dev { - log::warn!("Running in --dev mode, RPC CORS has been disabled."); - Cors::All + Ok(if is_light { + sc_service::Role::Light + } else if is_authority { + sc_service::Role::Authority { + sentry_nodes: self.sentry_nodes.clone(), + } + } else if !self.sentry.is_empty() { + sc_service::Role::Sentry { + validators: self.sentry.clone(), + } } else { - Cors::List(vec![ - "http://localhost:*".into(), - "http://127.0.0.1:*".into(), - "https://localhost:*".into(), - "https://127.0.0.1:*".into(), - "https://polkadot.js.org".into(), - ]) - }).into(); - - // Override telemetry - if self.no_telemetry { - config.telemetry_endpoints = None; - } else if !self.telemetry_endpoints.is_empty() { - config.telemetry_endpoints = Some( - TelemetryEndpoints::new(self.telemetry_endpoints.clone()).map_err(|e| e.to_string())? - ); - } + sc_service::Role::Full + }) + } + + fn force_authoring(&self) -> Result { + // Imply forced authoring on --dev + Ok(self.shared_params.dev || self.force_authoring) + } - // Override prometheus + fn prometheus_config(&self) -> Result> { if self.no_prometheus { - config.prometheus_config = None; - } else if config.prometheus_config.is_none() { - let prometheus_interface: &str = if self.prometheus_external { "0.0.0.0" } else { "127.0.0.1" }; - config.prometheus_config = Some(PrometheusConfig::new_with_default_registry( - parse_address(&format!("{}:{}", prometheus_interface, 9615), self.prometheus_port)?, - )); + Ok(None) + } else { + let prometheus_interface: &str = if self.prometheus_external { + "0.0.0.0" + } else { + "127.0.0.1" + }; + + Ok(Some(PrometheusConfig::new_with_default_registry( + parse_address( + &format!("{}:{}", prometheus_interface, 9615), + self.prometheus_port, + )?, + ))) } + } - config.tracing_targets = self.import_params.tracing_targets.clone().into(); - config.tracing_receiver = self.import_params.tracing_receiver.clone().into(); + fn disable_grandpa(&self) -> Result { + Ok(self.no_grandpa) + } - // Imply forced authoring on --dev - config.force_authoring = self.shared_params.dev || self.force_authoring; - - config.max_runtime_instances = self.max_runtime_instances.min(256); - - Ok(()) - } - - /// Run the command that runs the node. - pub fn run( - self, - config: Configuration, - new_light: FNL, - new_full: FNF, - version: &VersionInfo, - ) -> error::Result<()> - where - FNL: FnOnce(Configuration) -> Result, - FNF: FnOnce(Configuration) -> Result, - SL: AbstractService + Unpin, - SF: AbstractService + Unpin, - { - info!("{}", version.name); - info!("✌️ version {}", config.full_version()); - info!("❤️ by {}, {}-{}", version.author, version.copyright_start_year, Local::today().year()); - info!("📋 Chain specification: {}", config.expect_chain_spec().name()); - info!("🏷 Node name: {}", config.name); - info!("👤 Role: {}", config.display_role()); - - match config.role { - Role::Light => run_service_until_exit( - config, - new_light, - ), - _ => run_service_until_exit( - config, - new_full, - ), - } + fn rpc_ws_max_connections(&self) -> Result> { + Ok(self.ws_max_connections) } - /// Initialize substrate. This must be done only once. - /// - /// This method: - /// - /// 1. Set the panic handler - /// 2. Raise the FD limit - /// 3. Initialize the logger - pub fn init(&self, version: &VersionInfo) -> error::Result<()> { - self.shared_params.init(version) + fn rpc_cors(&self, is_dev: bool) -> Result>> { + Ok(self + .rpc_cors + .clone() + .unwrap_or_else(|| { + if is_dev { + log::warn!("Running in --dev mode, RPC CORS has been disabled."); + Cors::All + } else { + Cors::List(vec![ + "http://localhost:*".into(), + "http://127.0.0.1:*".into(), + "https://localhost:*".into(), + "https://127.0.0.1:*".into(), + "https://polkadot.js.org".into(), + ]) + } + }) + .into()) + } + + fn rpc_http(&self) -> Result> { + let rpc_interface: &str = + interface_str(self.rpc_external, self.unsafe_rpc_external, self.validator)?; + + Ok(Some(parse_address( + &format!("{}:{}", rpc_interface, 9933), + self.rpc_port, + )?)) + } + + fn rpc_ws(&self) -> Result> { + let ws_interface: &str = + interface_str(self.ws_external, self.unsafe_ws_external, self.validator)?; + + Ok(Some(parse_address( + &format!("{}:{}", ws_interface, 9944), + self.ws_port, + )?)) + } + + fn offchain_worker(&self, role: &Role) -> Result { + Ok(match (&self.offchain_worker, role) { + (OffchainWorkerEnabled::WhenValidating, Role::Authority { .. }) => true, + (OffchainWorkerEnabled::Always, _) => true, + (OffchainWorkerEnabled::Never, _) => false, + (OffchainWorkerEnabled::WhenValidating, _) => false, + }) + } + + fn transaction_pool(&self) -> Result { + Ok(self.pool_config.transaction_pool()) + } + + fn max_runtime_instances(&self) -> Result> { + Ok(self.max_runtime_instances.map(|x| x.min(256))) } } /// Check whether a node name is considered as valid. -pub fn is_node_name_valid(_name: &str) -> Result<(), &str> { +pub fn is_node_name_valid(_name: &str) -> std::result::Result<(), &str> { let name = _name.to_string(); - if name.chars().count() >= NODE_NAME_MAX_LENGTH { + if name.chars().count() >= crate::NODE_NAME_MAX_LENGTH { return Err("Node name too long"); } @@ -512,32 +468,10 @@ pub fn is_node_name_valid(_name: &str) -> Result<(), &str> { Ok(()) } -#[cfg(not(target_os = "unknown"))] -fn input_keystore_password() -> Result { - rpassword::read_password_from_tty(Some("Keystore password: ")) - .map_err(|e| format!("{:?}", e)) -} - -fn generate_node_name() -> String { - let result = loop { - let node_name = Generator::with_naming(Name::Numbered).next().unwrap(); - let count = node_name.chars().count(); - - if count < NODE_NAME_MAX_LENGTH { - break node_name - } - }; - - result -} - -fn parse_address( - address: &str, - port: Option, -) -> Result { - let mut address: SocketAddr = address.parse().map_err( - |_| format!("Invalid address: {}", address) - )?; +fn parse_address(address: &str, port: Option) -> std::result::Result { + let mut address: SocketAddr = address + .parse() + .map_err(|_| format!("Invalid address: {}", address))?; if let Some(port) = port { address.set_port(port); } @@ -549,16 +483,21 @@ fn interface_str( is_external: bool, is_unsafe_external: bool, is_validator: bool, -) -> Result<&'static str, error::Error> { +) -> Result<&'static str> { if is_external && is_validator { - return Err(error::Error::Input("--rpc-external and --ws-external options shouldn't be \ + return Err(Error::Input( + "--rpc-external and --ws-external options shouldn't be \ used if the node is running as a validator. Use `--unsafe-rpc-external` if you understand \ - the risks. See the options description for more information.".to_owned())); + the risks. See the options description for more information." + .to_owned(), + )); } if is_external || is_unsafe_external { - log::warn!("It isn't safe to expose RPC publicly without a proxy server that filters \ - available set of RPC methods."); + log::warn!( + "It isn't safe to expose RPC publicly without a proxy server that filters \ + available set of RPC methods." + ); Ok("0.0.0.0") } else { @@ -574,8 +513,8 @@ enum TelemetryParsingError { impl std::error::Error for TelemetryParsingError {} -impl fmt::Display for TelemetryParsingError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +impl std::fmt::Display for TelemetryParsingError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match &*self { TelemetryParsingError::MissingVerbosity => write!(f, "Verbosity level missing"), TelemetryParsingError::VerbosityParsingError(e) => write!(f, "{}", e), @@ -583,13 +522,15 @@ impl fmt::Display for TelemetryParsingError { } } -fn parse_telemetry_endpoints(s: &str) -> Result<(String, u8), TelemetryParsingError> { +fn parse_telemetry_endpoints(s: &str) -> std::result::Result<(String, u8), TelemetryParsingError> { let pos = s.find(' '); match pos { None => Err(TelemetryParsingError::MissingVerbosity), Some(pos_) => { let url = s[..pos_].to_string(); - let verbosity = s[pos_ + 1..].parse().map_err(TelemetryParsingError::VerbosityParsingError)?; + let verbosity = s[pos_ + 1..] + .parse() + .map_err(TelemetryParsingError::VerbosityParsingError)?; Ok((url, verbosity)) } } @@ -617,7 +558,7 @@ impl From for Option> { } /// Parse cors origins. -fn parse_cors(s: &str) -> Result> { +fn parse_cors(s: &str) -> std::result::Result> { let mut is_all = false; let mut origins = Vec::new(); for part in s.split(',') { @@ -625,29 +566,21 @@ fn parse_cors(s: &str) -> Result> { "all" | "*" => { is_all = true; break; - }, + } other => origins.push(other.to_owned()), } } - Ok(if is_all { Cors::All } else { Cors::List(origins) }) + Ok(if is_all { + Cors::All + } else { + Cors::List(origins) + }) } #[cfg(test)] mod tests { use super::*; - use sc_service::{GenericChainSpec, config::DatabaseConfig}; - - const TEST_VERSION_INFO: &'static VersionInfo = &VersionInfo { - name: "node-test", - version: "0.1.0", - commit: "some_commit", - executable_name: "node-test", - description: "description", - author: "author", - support_url: "http://example.org", - copyright_start_year: 2020, - }; #[test] fn tests_node_name_good() { @@ -663,94 +596,4 @@ mod tests { assert!(is_node_name_valid("www.visit.me").is_err()); assert!(is_node_name_valid("email@domain").is_err()); } - - #[test] - fn keystore_path_is_generated_correctly() { - let chain_spec = GenericChainSpec::from_genesis( - "test", - "test-id", - || (), - Vec::new(), - None, - None, - None, - None::<()>, - ); - - for keystore_path in vec![None, Some("/keystore/path")] { - let args: Vec<&str> = vec![]; - let mut cli = RunCmd::from_iter(args); - cli.keystore_path = keystore_path.clone().map(PathBuf::from); - - let mut config = Configuration::default(); - config.config_dir = Some(PathBuf::from("/test/path")); - config.chain_spec = Some(Box::new(chain_spec.clone())); - let chain_spec = chain_spec.clone(); - cli.update_config(&mut config, move |_| Ok(Box::new(chain_spec)), TEST_VERSION_INFO).unwrap(); - - let expected_path = match keystore_path { - Some(path) => PathBuf::from(path), - None => PathBuf::from("/test/path/chains/test-id/keystore"), - }; - - assert_eq!(expected_path, config.keystore.path().unwrap().to_owned()); - } - } - - #[test] - fn ensure_load_spec_provide_defaults() { - let chain_spec = GenericChainSpec::from_genesis( - "test", - "test-id", - || (), - vec!["/ip4/127.0.0.1/tcp/30333/p2p/QmdSHZLmwEL5Axz5JvWNE2mmxU7qyd7xHBFpyUfktgAdg7".parse().unwrap()], - Some(TelemetryEndpoints::new(vec![("wss://foo/bar".to_string(), 42)]) - .expect("provided url should be valid")), - None, - None, - None::<()>, - ); - - let args: Vec<&str> = vec![]; - let cli = RunCmd::from_iter(args); - - let mut config = Configuration::from_version(TEST_VERSION_INFO); - cli.update_config(&mut config, |_| Ok(Box::new(chain_spec)), TEST_VERSION_INFO).unwrap(); - - assert!(config.chain_spec.is_some()); - assert!(!config.network.boot_nodes.is_empty()); - assert!(config.telemetry_endpoints.is_some()); - } - - #[test] - fn ensure_update_config_for_running_node_provides_defaults() { - let chain_spec = GenericChainSpec::from_genesis( - "test", - "test-id", - || (), - vec![], - None, - None, - None, - None::<()>, - ); - - let args: Vec<&str> = vec![]; - let cli = RunCmd::from_iter(args); - - let mut config = Configuration::from_version(TEST_VERSION_INFO); - cli.init(&TEST_VERSION_INFO).unwrap(); - cli.update_config(&mut config, |_| Ok(Box::new(chain_spec)), TEST_VERSION_INFO).unwrap(); - - assert!(config.config_dir.is_some()); - assert!(config.database.is_some()); - if let Some(DatabaseConfig::Path { ref cache_size, .. }) = config.database { - assert!(cache_size.is_some()); - } else { - panic!("invalid config.database variant"); - } - assert!(!config.name.is_empty()); - assert!(config.network.config_path.is_some()); - assert!(!config.network.listen_addresses.is_empty()); - } } diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs new file mode 100644 index 0000000000..6c4cc0e710 --- /dev/null +++ b/client/cli/src/config.rs @@ -0,0 +1,462 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Configuration trait for a CLI based on substrate + +use crate::error::Result; +use crate::{ + init_logger, ImportParams, KeystoreParams, NetworkParams, NodeKeyParams, + PruningParams, SharedParams, SubstrateCli, +}; +use app_dirs::{AppDataType, AppInfo}; +use names::{Generator, Name}; +use sc_service::config::{ + Configuration, DatabaseConfig, ExecutionStrategies, ExtTransport, KeystoreConfig, + NetworkConfiguration, NodeKeyConfig, PrometheusConfig, PruningMode, Role, TelemetryEndpoints, + TransactionPoolOptions, WasmExecutionMethod, +}; +use sc_service::{ChainSpec, TracingReceiver}; +use std::future::Future; +use std::net::SocketAddr; +use std::path::PathBuf; +use std::pin::Pin; +use std::sync::Arc; + +/// The maximum number of characters for a node name. +pub(crate) const NODE_NAME_MAX_LENGTH: usize = 32; + +/// default sub directory to store network config +pub(crate) const DEFAULT_NETWORK_CONFIG_PATH: &'static str = "network"; + +/// A trait that allows converting an object to a Configuration +pub trait CliConfiguration: Sized { + /// Get the SharedParams for this object + fn shared_params(&self) -> &SharedParams; + + /// Get the ImportParams for this object + fn import_params(&self) -> Option<&ImportParams> { + None + } + + /// Get the PruningParams for this object + fn pruning_params(&self) -> Option<&PruningParams> { + self.import_params().map(|x| &x.pruning_params) + } + + /// Get the KeystoreParams for this object + fn keystore_params(&self) -> Option<&KeystoreParams> { + None + } + + /// Get the NetworkParams for this object + fn network_params(&self) -> Option<&NetworkParams> { + None + } + + /// Get the NodeKeyParams for this object + fn node_key_params(&self) -> Option<&NodeKeyParams> { + self.network_params() + .map(|x| &x.node_key_params) + } + + /// Get the base path of the configuration (if any) + /// + /// By default this is retrieved from `SharedParams`. + fn base_path(&self) -> Result> { + Ok(self.shared_params().base_path()) + } + + /// Returns `true` if the node is for development or not + /// + /// By default this is retrieved from `SharedParams`. + fn is_dev(&self) -> Result { + Ok(self.shared_params().is_dev()) + } + + /// Gets the role + /// + /// By default this is `Role::Full`. + fn role(&self, _is_dev: bool) -> Result { + Ok(Role::Full) + } + + /// Get the transaction pool options + /// + /// By default this is `TransactionPoolOptions::default()`. + fn transaction_pool(&self) -> Result { + Ok(Default::default()) + } + + /// Get the network configuration + /// + /// By default this is retrieved from `NetworkParams` if it is available otherwise it creates + /// a default `NetworkConfiguration` based on `node_name`, `client_id`, `node_key` and + /// `net_config_dir`. + fn network_config( + &self, + chain_spec: &Box, + is_dev: bool, + net_config_dir: &PathBuf, + client_id: &str, + node_name: &str, + node_key: NodeKeyConfig, + ) -> Result { + Ok(if let Some(network_params) = self.network_params() { + network_params.network_config( + chain_spec, + is_dev, + net_config_dir, + client_id, + node_name, + node_key, + ) + } else { + NetworkConfiguration::new( + node_name, + client_id, + node_key, + net_config_dir, + ) + }) + } + + /// Get the keystore configuration. + /// + /// Bu default this is retrieved from `KeystoreParams` if it is available. Otherwise it uses + /// `KeystoreConfig::InMemory`. + fn keystore_config(&self, base_path: &PathBuf) -> Result { + self.keystore_params() + .map(|x| x.keystore_config(base_path)) + .unwrap_or(Ok(KeystoreConfig::InMemory)) + } + + /// Get the database cache size. + /// + /// By default this is retrieved from `ImportParams` if it is available. Otherwise its `None`. + fn database_cache_size(&self) -> Result> { + Ok(self.import_params() + .map(|x| x.database_cache_size()) + .unwrap_or(Default::default())) + } + + /// Get the database configuration. + /// + /// By default this is retrieved from `SharedParams` + fn database_config(&self, base_path: &PathBuf, cache_size: usize) -> Result { + Ok(self.shared_params().database_config(base_path, cache_size)) + } + + /// Get the state cache size. + /// + /// By default this is retrieved from `ImportParams` if it is available. Otherwise its `0`. + fn state_cache_size(&self) -> Result { + Ok(self.import_params() + .map(|x| x.state_cache_size()) + .unwrap_or(Default::default())) + } + + /// Get the state cache child ratio (if any). + /// + /// By default this is `None`. + fn state_cache_child_ratio(&self) -> Result> { + Ok(Default::default()) + } + + /// Get the pruning mode. + /// + /// By default this is retrieved from `PruningMode` if it is available. Otherwise its + /// `PruningMode::default()`. + fn pruning(&self, is_dev: bool, role: &Role) -> Result { + self.pruning_params() + .map(|x| x.pruning(is_dev, role)) + .unwrap_or(Ok(Default::default())) + } + + /// Get the chain ID (string). + /// + /// By default this is retrieved from `SharedParams`. + fn chain_id(&self, is_dev: bool) -> Result { + Ok(self.shared_params().chain_id(is_dev)) + } + + /// Get the name of the node. + /// + /// By default a random name is generated. + fn node_name(&self) -> Result { + Ok(generate_node_name()) + } + + /// Get the WASM execution method. + /// + /// By default this is retrieved from `ImportParams` if it is available. Otherwise its + /// `WasmExecutionMethod::default()`. + fn wasm_method(&self) -> Result { + Ok(self.import_params() + .map(|x| x.wasm_method()) + .unwrap_or(Default::default())) + } + + /// Get the execution strategies. + /// + /// By default this is retrieved from `ImportParams` if it is available. Otherwise its + /// `ExecutionStrategies::default()`. + fn execution_strategies(&self, is_dev: bool) -> Result { + Ok(self.import_params() + .map(|x| x.execution_strategies(is_dev)) + .unwrap_or(Default::default())) + } + + /// Get the RPC HTTP address (`None` if disabled). + /// + /// By default this is `None`. + fn rpc_http(&self) -> Result> { + Ok(Default::default()) + } + + /// Get the RPC websocket address (`None` if disabled). + /// + /// By default this is `None`. + fn rpc_ws(&self) -> Result> { + Ok(Default::default()) + } + + /// Get the RPC websockets maximum connections (`None` if unlimited). + /// + /// By default this is `None`. + fn rpc_ws_max_connections(&self) -> Result> { + Ok(Default::default()) + } + + /// Get the RPC cors (`None` if disabled) + /// + /// By default this is `None`. + fn rpc_cors(&self, _is_dev: bool) -> Result>> { + Ok(Some(Vec::new())) + } + + /// Get the prometheus configuration (`None` if disabled) + /// + /// By default this is `None`. + fn prometheus_config(&self) -> Result> { + Ok(Default::default()) + } + + /// Get the telemetry endpoints (if any) + /// + /// By default this is retrieved from the chain spec loaded by `load_spec`. + fn telemetry_endpoints( + &self, + chain_spec: &Box, + ) -> Result> { + Ok(chain_spec.telemetry_endpoints().clone()) + } + + /// Get the telemetry external transport + /// + /// By default this is `None`. + fn telemetry_external_transport(&self) -> Result> { + Ok(Default::default()) + } + + /// Get the default value for heap pages + /// + /// By default this is `None`. + fn default_heap_pages(&self) -> Result> { + Ok(Default::default()) + } + + /// Returns `Ok(true)` if offchain worker should be used + /// + /// By default this is `false`. + fn offchain_worker(&self, _role: &Role) -> Result { + Ok(Default::default()) + } + + /// Returns `Ok(true)` if authoring should be forced + /// + /// By default this is `false`. + fn force_authoring(&self) -> Result { + Ok(Default::default()) + } + + /// Returns `Ok(true)` if grandpa should be disabled + /// + /// By default this is `false`. + fn disable_grandpa(&self) -> Result { + Ok(Default::default()) + } + + /// Get the development key seed from the current object + /// + /// By default this is `None`. + fn dev_key_seed(&self, _is_dev: bool) -> Result> { + Ok(Default::default()) + } + + /// Get the tracing targets from the current object (if any) + /// + /// By default this is retrieved from `ImportParams` if it is available. Otherwise its + /// `None`. + fn tracing_targets(&self) -> Result> { + Ok(self.import_params() + .map(|x| x.tracing_targets()) + .unwrap_or(Default::default())) + } + + /// Get the TracingReceiver value from the current object + /// + /// By default this is retrieved from `ImportParams` if it is available. Otherwise its + /// `TracingReceiver::default()`. + fn tracing_receiver(&self) -> Result { + Ok(self.import_params() + .map(|x| x.tracing_receiver()) + .unwrap_or(Default::default())) + } + + /// Get the node key from the current object + /// + /// By default this is retrieved from `NodeKeyParams` if it is available. Otherwise its + /// `NodeKeyConfig::default()`. + fn node_key(&self, net_config_dir: &PathBuf) -> Result { + self.node_key_params() + .map(|x| x.node_key(net_config_dir)) + .unwrap_or(Ok(Default::default())) + } + + /// Get maximum runtime instances + /// + /// By default this is `None`. + fn max_runtime_instances(&self) -> Result> { + Ok(Default::default()) + } + + /// Activate or not the automatic announcing of blocks after import + /// + /// By default this is `false`. + fn announce_block(&self) -> Result { + Ok(true) + } + + /// Create a Configuration object from the current object + fn create_configuration( + &self, + cli: &C, + task_executor: Arc + Send>>) + Send + Sync>, + ) -> Result { + let is_dev = self.is_dev()?; + let chain_id = self.chain_id(is_dev)?; + let chain_spec = cli.load_spec(chain_id.as_str())?; + let config_dir = self + .base_path()? + .unwrap_or_else(|| { + app_dirs::get_app_root( + AppDataType::UserData, + &AppInfo { + name: C::executable_name(), + author: C::author(), + }, + ) + .expect("app directories exist on all supported platforms; qed") + }) + .join("chains") + .join(chain_spec.id()); + let net_config_dir = config_dir.join(DEFAULT_NETWORK_CONFIG_PATH); + let client_id = C::client_id(); + let database_cache_size = self.database_cache_size()?.unwrap_or(128); + let node_key = self.node_key(&net_config_dir)?; + let role = self.role(is_dev)?; + let max_runtime_instances = self.max_runtime_instances()?.unwrap_or(8); + + Ok(Configuration { + impl_name: C::impl_name(), + impl_version: C::impl_version(), + task_executor, + transaction_pool: self.transaction_pool()?, + network: self.network_config( + &chain_spec, + is_dev, + &net_config_dir, + client_id.as_str(), + self.node_name()?.as_str(), + node_key, + )?, + keystore: self.keystore_config(&config_dir)?, + database: self.database_config(&config_dir, database_cache_size)?, + state_cache_size: self.state_cache_size()?, + state_cache_child_ratio: self.state_cache_child_ratio()?, + pruning: self.pruning(is_dev, &role)?, + wasm_method: self.wasm_method()?, + execution_strategies: self.execution_strategies(is_dev)?, + rpc_http: self.rpc_http()?, + rpc_ws: self.rpc_ws()?, + rpc_ws_max_connections: self.rpc_ws_max_connections()?, + rpc_cors: self.rpc_cors(is_dev)?, + prometheus_config: self.prometheus_config()?, + telemetry_endpoints: self.telemetry_endpoints(&chain_spec)?, + telemetry_external_transport: self.telemetry_external_transport()?, + default_heap_pages: self.default_heap_pages()?, + offchain_worker: self.offchain_worker(&role)?, + force_authoring: self.force_authoring()?, + disable_grandpa: self.disable_grandpa()?, + dev_key_seed: self.dev_key_seed(is_dev)?, + tracing_targets: self.tracing_targets()?, + tracing_receiver: self.tracing_receiver()?, + chain_spec, + max_runtime_instances, + announce_block: self.announce_block()?, + role, + }) + } + + /// Get the filters for the logging. + /// + /// By default this is retrieved from `SharedParams`. + fn log_filters(&self) -> Result> { + Ok(self.shared_params().log_filters()) + } + + /// Initialize substrate. This must be done only once. + /// + /// This method: + /// + /// 1. Set the panic handler + /// 2. Raise the FD limit + /// 3. Initialize the logger + fn init(&self) -> Result<()> { + let logger_pattern = self.log_filters()?.unwrap_or_default(); + + sp_panic_handler::set(C::support_url(), C::impl_version()); + + fdlimit::raise_fd_limit(); + init_logger(logger_pattern.as_str()); + + Ok(()) + } +} + +/// Generate a valid random name for the node +pub fn generate_node_name() -> String { + loop { + let node_name = Generator::with_naming(Name::Numbered) + .next() + .expect("RNG is available on all supported platforms; qed"); + let count = node_name.chars().count(); + + if count < NODE_NAME_MAX_LENGTH { + return node_name; + } + }; +} diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index ba59b94c82..25b71059b1 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -19,137 +19,175 @@ #![warn(missing_docs)] #![warn(unused_extern_crates)] -mod params; mod arg_enums; -mod error; -mod runtime; mod commands; +mod config; +mod error; +mod params; +mod runner; -pub use sc_service::config::VersionInfo; - -use std::io::Write; - -use regex::Regex; -use structopt::{StructOpt, clap::{self, AppSettings}}; -pub use structopt; -pub use params::*; -pub use commands::*; pub use arg_enums::*; +pub use commands::*; +pub use config::*; pub use error::*; -use log::info; use lazy_static::lazy_static; -pub use crate::runtime::{run_until_exit, run_service_until_exit}; +use log::info; +pub use params::*; +use regex::Regex; +pub use runner::*; +use sc_service::{ChainSpec, Configuration}; +use std::future::Future; +use std::io::Write; +use std::pin::Pin; +use std::sync::Arc; +pub use structopt; +use structopt::{ + clap::{self, AppSettings}, + StructOpt, +}; -/// Helper function used to parse the command line arguments. This is the equivalent of -/// `structopt`'s `from_iter()` except that it takes a `VersionInfo` argument to provide the name of -/// the application, author, "about" and version. It will also set `AppSettings::GlobalVersion`. +/// Substrate client CLI /// -/// To allow running the node without subcommand, tt also sets a few more settings: -/// `AppSettings::ArgsNegateSubcommands` and `AppSettings::SubcommandsNegateReqs`. +/// This trait needs to be defined on the root structopt of the application. It will provide the +/// implementation name, version, executable name, description, author, support_url, copyright start +/// year and most importantly: how to load the chain spec. /// -/// Gets the struct from the command line arguments. Print the -/// error message and quit the program in case of failure. -pub fn from_args(version: &VersionInfo) -> T -where - T: StructOpt + Sized, -{ - from_iter::(&mut std::env::args_os(), version) -} +/// StructOpt must not be in scope to use from_args (or the similar methods). This trait provides +/// its own implementation that will fill the necessary field based on the trait's functions. +pub trait SubstrateCli: Sized { + /// Implementation name. + fn impl_name() -> &'static str; + + /// Implementation version. + /// + /// By default this will look like this: 2.0.0-b950f731c-x86_64-linux-gnu where the hash is the + /// short commit hash of the commit of in the Git repository. + fn impl_version() -> &'static str; + + /// Executable file name. + fn executable_name() -> &'static str; + + /// Executable file description. + fn description() -> &'static str; + + /// Executable file author. + fn author() -> &'static str; + + /// Support URL. + fn support_url() -> &'static str; + + /// Copyright starting year (x-current year) + fn copyright_start_year() -> i32; + + /// Chain spec factory + fn load_spec(&self, id: &str) -> std::result::Result, String>; + + /// Helper function used to parse the command line arguments. This is the equivalent of + /// `structopt`'s `from_iter()` except that it takes a `VersionInfo` argument to provide the name of + /// the application, author, "about" and version. It will also set `AppSettings::GlobalVersion`. + /// + /// To allow running the node without subcommand, tt also sets a few more settings: + /// `AppSettings::ArgsNegateSubcommands` and `AppSettings::SubcommandsNegateReqs`. + /// + /// Gets the struct from the command line arguments. Print the + /// error message and quit the program in case of failure. + fn from_args() -> Self + where + Self: StructOpt + Sized, + { + ::from_iter(&mut std::env::args_os()) + } -/// Helper function used to parse the command line arguments. This is the equivalent of -/// `structopt`'s `from_iter()` except that it takes a `VersionInfo` argument to provide the name of -/// the application, author, "about" and version. It will also set `AppSettings::GlobalVersion`. -/// -/// To allow running the node without subcommand, tt also sets a few more settings: -/// `AppSettings::ArgsNegateSubcommands` and `AppSettings::SubcommandsNegateReqs`. -/// -/// Gets the struct from any iterator such as a `Vec` of your making. -/// Print the error message and quit the program in case of failure. -pub fn from_iter(iter: I, version: &VersionInfo) -> T -where - T: StructOpt + Sized, - I: IntoIterator, - I::Item: Into + Clone, -{ - let app = T::clap(); - - let mut full_version = sc_service::config::full_version_from_strs( - version.version, - version.commit - ); - full_version.push_str("\n"); - - let app = app - .name(version.executable_name) - .author(version.author) - .about(version.description) - .version(full_version.as_str()) - .settings(&[ - AppSettings::GlobalVersion, - AppSettings::ArgsNegateSubcommands, - AppSettings::SubcommandsNegateReqs, - ]); - - T::from_clap(&app.get_matches_from(iter)) -} + /// Helper function used to parse the command line arguments. This is the equivalent of + /// `structopt`'s `from_iter()` except that it takes a `VersionInfo` argument to provide the name of + /// the application, author, "about" and version. It will also set `AppSettings::GlobalVersion`. + /// + /// To allow running the node without subcommand, it also sets a few more settings: + /// `AppSettings::ArgsNegateSubcommands` and `AppSettings::SubcommandsNegateReqs`. + /// + /// Gets the struct from any iterator such as a `Vec` of your making. + /// Print the error message and quit the program in case of failure. + fn from_iter(iter: I) -> Self + where + Self: StructOpt + Sized, + I: IntoIterator, + I::Item: Into + Clone, + { + let app = ::clap(); + + let mut full_version = Self::impl_version().to_string(); + full_version.push_str("\n"); + + let app = app + .name(Self::executable_name()) + .author(Self::author()) + .about(Self::description()) + .version(full_version.as_str()) + .settings(&[ + AppSettings::GlobalVersion, + AppSettings::ArgsNegateSubcommands, + AppSettings::SubcommandsNegateReqs, + ]); + + ::from_clap(&app.get_matches_from(iter)) + } -/// Helper function used to parse the command line arguments. This is the equivalent of -/// `structopt`'s `from_iter()` except that it takes a `VersionInfo` argument to provide the name of -/// the application, author, "about" and version. It will also set `AppSettings::GlobalVersion`. -/// -/// To allow running the node without subcommand, tt also sets a few more settings: -/// `AppSettings::ArgsNegateSubcommands` and `AppSettings::SubcommandsNegateReqs`. -/// -/// Gets the struct from any iterator such as a `Vec` of your making. -/// Print the error message and quit the program in case of failure. -/// -/// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are -/// used. It will return a [`clap::Error`], where the [`kind`] is a -/// [`ErrorKind::HelpDisplayed`] or [`ErrorKind::VersionDisplayed`] respectively. You must call -/// [`Error::exit`] or perform a [`std::process::exit`]. -pub fn try_from_iter(iter: I, version: &VersionInfo) -> clap::Result -where - T: StructOpt + Sized, - I: IntoIterator, - I::Item: Into + Clone, -{ - let app = T::clap(); - - let mut full_version = sc_service::config::full_version_from_strs( - version.version, - version.commit, - ); - full_version.push_str("\n"); - - let app = app - .name(version.executable_name) - .author(version.author) - .about(version.description) - .version(full_version.as_str()); - - let matches = app.get_matches_from_safe(iter)?; - - Ok(T::from_clap(&matches)) -} + /// Helper function used to parse the command line arguments. This is the equivalent of + /// `structopt`'s `from_iter()` except that it takes a `VersionInfo` argument to provide the name of + /// the application, author, "about" and version. It will also set `AppSettings::GlobalVersion`. + /// + /// To allow running the node without subcommand, it also sets a few more settings: + /// `AppSettings::ArgsNegateSubcommands` and `AppSettings::SubcommandsNegateReqs`. + /// + /// Gets the struct from any iterator such as a `Vec` of your making. + /// Print the error message and quit the program in case of failure. + /// + /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are + /// used. It will return a [`clap::Error`], where the [`kind`] is a + /// [`ErrorKind::HelpDisplayed`] or [`ErrorKind::VersionDisplayed`] respectively. You must call + /// [`Error::exit`] or perform a [`std::process::exit`]. + fn try_from_iter(iter: I) -> clap::Result + where + Self: StructOpt + Sized, + I: IntoIterator, + I::Item: Into + Clone, + { + let app = ::clap(); -/// Initialize substrate. This must be done only once. -/// -/// This method: -/// -/// 1. Set the panic handler -/// 2. Raise the FD limit -/// 3. Initialize the logger -pub fn init(logger_pattern: &str, version: &VersionInfo) -> error::Result<()> { - let full_version = sc_service::config::full_version_from_strs( - version.version, - version.commit - ); - sp_panic_handler::set(version.support_url, &full_version); - - fdlimit::raise_fd_limit(); - init_logger(logger_pattern); + let mut full_version = Self::impl_version().to_string(); + full_version.push_str("\n"); - Ok(()) + let app = app + .name(Self::executable_name()) + .author(Self::author()) + .about(Self::description()) + .version(full_version.as_str()); + + let matches = app.get_matches_from_safe(iter)?; + + Ok(::from_clap(&matches)) + } + + /// Returns the client ID: `{impl_name}/v{impl_version}` + fn client_id() -> String { + format!("{}/v{}", Self::impl_name(), Self::impl_version()) + } + + /// Only create a Configuration for the command provided in argument + fn create_configuration( + &self, + command: &T, + task_executor: Arc + Send>>) + Send + Sync>, + ) -> error::Result { + command.create_configuration(self, task_executor) + } + + /// Create a runner for the command provided in argument. This will create a Configuration and + /// a tokio runtime + fn create_runner(&self, command: &T) -> error::Result> { + command.init::()?; + Runner::new(self, command) + } } /// Initialize the logger @@ -177,15 +215,20 @@ pub fn init_logger(pattern: &str) { builder.format(move |buf, record| { let now = time::now(); let timestamp = - time::strftime("%Y-%m-%d %H:%M:%S", &now) - .expect("Error formatting log timestamp"); + time::strftime("%Y-%m-%d %H:%M:%S", &now).expect("Error formatting log timestamp"); let mut output = if log::max_level() <= log::LevelFilter::Info { - format!("{} {}", Colour::Black.bold().paint(timestamp), record.args()) + format!( + "{} {}", + Colour::Black.bold().paint(timestamp), + record.args(), + ) } else { let name = ::std::thread::current() .name() - .map_or_else(Default::default, |x| format!("{}", Colour::Blue.bold().paint(x))); + .map_or_else(Default::default, |x| { + format!("{}", Colour::Blue.bold().paint(x)) + }); let millis = (now.tm_nsec as f32 / 1000000.0).floor() as usize; let timestamp = format!("{}.{}", timestamp, millis); format!( diff --git a/client/cli/src/params/import_params.rs b/client/cli/src/params/import_params.rs index 8d34b706f5..08ca1c8f8f 100644 --- a/client/cli/src/params/import_params.rs +++ b/client/cli/src/params/import_params.rs @@ -14,16 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use structopt::StructOpt; -use sc_service::{Configuration, config::DatabaseConfig}; - -use crate::error; use crate::arg_enums::{ - WasmExecutionMethod, TracingReceiver, ExecutionStrategy, DEFAULT_EXECUTION_BLOCK_CONSTRUCTION, + ExecutionStrategy, TracingReceiver, WasmExecutionMethod, DEFAULT_EXECUTION_BLOCK_CONSTRUCTION, DEFAULT_EXECUTION_IMPORT_BLOCK, DEFAULT_EXECUTION_OFFCHAIN_WORKER, DEFAULT_EXECUTION_OTHER, - DEFAULT_EXECUTION_SYNCING + DEFAULT_EXECUTION_SYNCING, }; use crate::params::PruningParams; +use crate::Result; +use sc_client_api::execution_extensions::ExecutionStrategies; +use sc_service::{PruningMode, Role}; +use structopt::StructOpt; /// Parameters for block import. #[derive(Debug, StructOpt, Clone)] @@ -52,11 +52,11 @@ pub struct ImportParams { #[allow(missing_docs)] #[structopt(flatten)] - pub execution_strategies: ExecutionStrategies, + pub execution_strategies: ExecutionStrategiesParams, /// Limit the memory the database cache can use. - #[structopt(long = "db-cache", value_name = "MiB", default_value = "128")] - pub database_cache_size: u32, + #[structopt(long = "db-cache", value_name = "MiB")] + pub database_cache_size: Option, /// Specify the state cache size. #[structopt(long = "state-cache-size", value_name = "Bytes", default_value = "67108864")] @@ -78,25 +78,31 @@ pub struct ImportParams { } impl ImportParams { - /// Put block import CLI params into `config` object. - pub fn update_config( - &self, - mut config: &mut Configuration, - role: &sc_service::Role, - is_dev: bool, - ) -> error::Result<()> { - use sc_client_api::execution_extensions::ExecutionStrategies; - - if let Some(DatabaseConfig::Path { ref mut cache_size, .. }) = config.database { - *cache_size = Some(self.database_cache_size); - } + /// Receiver to process tracing messages. + pub fn tracing_receiver(&self) -> sc_service::TracingReceiver { + self.tracing_receiver.clone().into() + } - config.state_cache_size = self.state_cache_size; + /// Comma separated list of targets for tracing. + pub fn tracing_targets(&self) -> Option { + self.tracing_targets.clone() + } - self.pruning_params.update_config(&mut config, role, self.unsafe_pruning)?; + /// Specify the state cache size. + pub fn state_cache_size(&self) -> usize { + self.state_cache_size + } - config.wasm_method = self.wasm_method.into(); + /// Get the WASM execution method from the parameters + pub fn wasm_method(&self) -> sc_service::config::WasmExecutionMethod { + self.wasm_method.into() + } + /// Get execution strategies for the parameters + pub fn execution_strategies( + &self, + is_dev: bool, + ) -> ExecutionStrategies { let exec = &self.execution_strategies; let exec_all_or = |strat: ExecutionStrategy, default: ExecutionStrategy| { exec.execution.unwrap_or(if strat == default && is_dev { @@ -106,7 +112,7 @@ impl ImportParams { }).into() }; - config.execution_strategies = ExecutionStrategies { + ExecutionStrategies { syncing: exec_all_or(exec.execution_syncing, DEFAULT_EXECUTION_SYNCING), importing: exec_all_or(exec.execution_import_block, DEFAULT_EXECUTION_IMPORT_BLOCK), block_construction: @@ -114,15 +120,23 @@ impl ImportParams { offchain_worker: exec_all_or(exec.execution_offchain_worker, DEFAULT_EXECUTION_OFFCHAIN_WORKER), other: exec_all_or(exec.execution_other, DEFAULT_EXECUTION_OTHER), - }; + } + } - Ok(()) + /// Get the pruning mode from the parameters + pub fn pruning(&self, unsafe_pruning: bool, role: &Role) -> Result { + self.pruning_params.pruning(unsafe_pruning, role) + } + + /// Limit the memory the database cache can use. + pub fn database_cache_size(&self) -> Option { + self.database_cache_size } } /// Execution strategies parameters. #[derive(Debug, StructOpt, Clone)] -pub struct ExecutionStrategies { +pub struct ExecutionStrategiesParams { /// The means of execution used when calling into the runtime while syncing blocks. #[structopt( long = "execution-syncing", diff --git a/client/cli/src/params/keystore_params.rs b/client/cli/src/params/keystore_params.rs new file mode 100644 index 0000000000..c6131c2f64 --- /dev/null +++ b/client/cli/src/params/keystore_params.rs @@ -0,0 +1,92 @@ +// Copyright 2018-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use crate::error::Result; +use sc_service::config::KeystoreConfig; +use std::fs; +use std::path::PathBuf; +use structopt::StructOpt; + +/// default sub directory for the key store +const DEFAULT_KEYSTORE_CONFIG_PATH: &'static str = "keystore"; + +/// Parameters of the keystore +#[derive(Debug, StructOpt, Clone)] +pub struct KeystoreParams { + /// Specify custom keystore path. + #[structopt(long = "keystore-path", value_name = "PATH", parse(from_os_str))] + pub keystore_path: Option, + + /// Use interactive shell for entering the password used by the keystore. + #[structopt( + long = "password-interactive", + conflicts_with_all = &[ "password", "password-filename" ] + )] + pub password_interactive: bool, + + /// Password used by the keystore. + #[structopt( + long = "password", + conflicts_with_all = &[ "password-interactive", "password-filename" ] + )] + pub password: Option, + + /// File that contains the password used by the keystore. + #[structopt( + long = "password-filename", + value_name = "PATH", + parse(from_os_str), + conflicts_with_all = &[ "password-interactive", "password" ] + )] + pub password_filename: Option, +} + +impl KeystoreParams { + /// Get the keystore configuration for the parameters + pub fn keystore_config(&self, base_path: &PathBuf) -> Result { + let password = if self.password_interactive { + #[cfg(not(target_os = "unknown"))] + { + Some(input_keystore_password()?.into()) + } + #[cfg(target_os = "unknown")] + None + } else if let Some(ref file) = self.password_filename { + Some( + fs::read_to_string(file) + .map_err(|e| format!("{}", e))? + .into(), + ) + } else if let Some(ref password) = self.password { + Some(password.clone().into()) + } else { + None + }; + + let path = self + .keystore_path + .clone() + .unwrap_or(base_path.join(DEFAULT_KEYSTORE_CONFIG_PATH)); + + Ok(KeystoreConfig::Path { path, password }) + } +} + +#[cfg(not(target_os = "unknown"))] +fn input_keystore_password() -> Result { + rpassword::read_password_from_tty(Some("Keystore password: ")) + .map_err(|e| format!("{:?}", e).into()) +} diff --git a/client/cli/src/params/mod.rs b/client/cli/src/params/mod.rs index f684cab336..9097bf8589 100644 --- a/client/cli/src/params/mod.rs +++ b/client/cli/src/params/mod.rs @@ -15,21 +15,23 @@ // along with Substrate. If not, see . mod import_params; -mod transaction_pool_params; -mod shared_params; +mod keystore_params; +mod network_params; mod node_key_params; -mod network_configuration_params; mod pruning_params; +mod shared_params; +mod transaction_pool_params; -use std::str::FromStr; use std::fmt::Debug; +use std::str::FromStr; pub use crate::params::import_params::*; -pub use crate::params::transaction_pool_params::*; -pub use crate::params::shared_params::*; +pub use crate::params::keystore_params::*; +pub use crate::params::network_params::*; pub use crate::params::node_key_params::*; -pub use crate::params::network_configuration_params::*; pub use crate::params::pruning_params::*; +pub use crate::params::shared_params::*; +pub use crate::params::transaction_pool_params::*; /// Wrapper type of `String` that holds an unsigned integer of arbitrary size, formatted as a decimal. #[derive(Debug, Clone)] diff --git a/client/cli/src/params/network_configuration_params.rs b/client/cli/src/params/network_params.rs similarity index 63% rename from client/cli/src/params/network_configuration_params.rs rename to client/cli/src/params/network_params.rs index b01cdeeb1c..2c008e19d1 100644 --- a/client/cli/src/params/network_configuration_params.rs +++ b/client/cli/src/params/network_params.rs @@ -14,21 +14,20 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::path::PathBuf; +use crate::params::node_key_params::NodeKeyParams; +use sc_network::{ + config::{NetworkConfiguration, NodeKeyConfig, NonReservedPeerMode, TransportConfig}, + multiaddr::Protocol, +}; +use sc_service::{ChainSpec, config::{Multiaddr, MultiaddrWithPeerId}}; use std::iter; use std::net::Ipv4Addr; +use std::path::PathBuf; use structopt::StructOpt; -use sc_network::{ - config::{MultiaddrWithPeerId, NonReservedPeerMode, TransportConfig}, multiaddr::Protocol, Multiaddr, -}; -use sc_service::Configuration; - -use crate::error; -use crate::params::node_key_params::NodeKeyParams; /// Parameters used to create the network configuration. #[derive(Debug, StructOpt, Clone)] -pub struct NetworkConfigurationParams { +pub struct NetworkParams { /// Specify a list of bootnodes. #[structopt(long = "bootnodes", value_name = "ADDR")] pub bootnodes: Vec, @@ -44,14 +43,6 @@ pub struct NetworkConfigurationParams { #[structopt(long = "reserved-only")] pub reserved_only: bool, - /// Specify a list of sentry node public addresses. - #[structopt( - long = "sentry-nodes", - value_name = "ADDR", - conflicts_with_all = &[ "sentry" ] - )] - pub sentry_nodes: Vec, - /// Listen on this multiaddress. #[structopt(long = "listen-addr", value_name = "LISTEN_ADDR")] pub listen_addr: Vec, @@ -87,7 +78,11 @@ pub struct NetworkConfigurationParams { /// /// This allows downloading announced blocks from multiple peers. Decrease to save /// traffic and risk increased latency. - #[structopt(long = "max-parallel-downloads", value_name = "COUNT", default_value = "5")] + #[structopt( + long = "max-parallel-downloads", + value_name = "COUNT", + default_value = "5" + )] pub max_parallel_downloads: u32, #[allow(missing_docs)] @@ -99,53 +94,50 @@ pub struct NetworkConfigurationParams { pub use_yamux_flow_control: bool, } -impl NetworkConfigurationParams { +impl NetworkParams { /// Fill the given `NetworkConfiguration` by looking at the cli parameters. - pub fn update_config( + pub fn network_config( &self, - mut config: &mut Configuration, - config_path: PathBuf, - client_id: String, + chain_spec: &Box, is_dev: bool, - ) -> error::Result<()> { - config.network.boot_nodes.extend(self.bootnodes.clone()); - config.network.config_path = Some(config_path.clone()); - config.network.net_config_path = Some(config_path.clone()); - - config.network.reserved_nodes.extend(self.reserved_nodes.clone()); - if self.reserved_only { - config.network.non_reserved_mode = NonReservedPeerMode::Deny; - } - - config.network.listen_addresses.extend(self.listen_addr.iter().cloned()); - if config.network.listen_addresses.is_empty() { - let port = match self.port { - Some(port) => port, - None => 30333, - }; - - config.network.listen_addresses = vec![ - iter::once(Protocol::Ip4(Ipv4Addr::new(0, 0, 0, 0))) - .chain(iter::once(Protocol::Tcp(port))) - .collect() - ]; + net_config_path: &PathBuf, + client_id: &str, + node_name: &str, + node_key: NodeKeyConfig, + ) -> NetworkConfiguration { + let port = self.port.unwrap_or(30333); + let mut listen_addresses = vec![iter::once(Protocol::Ip4(Ipv4Addr::new(0, 0, 0, 0))) + .chain(iter::once(Protocol::Tcp(port))) + .collect()]; + + listen_addresses.extend(self.listen_addr.iter().cloned()); + + let mut boot_nodes = chain_spec.boot_nodes().to_vec(); + boot_nodes.extend(self.bootnodes.clone()); + + NetworkConfiguration { + boot_nodes, + net_config_path: net_config_path.clone(), + reserved_nodes: self.reserved_nodes.clone(), + non_reserved_mode: if self.reserved_only { + NonReservedPeerMode::Deny + } else { + NonReservedPeerMode::Accept + }, + listen_addresses, + public_addresses: Vec::new(), + node_key, + node_name: node_name.to_string(), + client_version: client_id.to_string(), + in_peers: self.in_peers, + out_peers: self.out_peers, + transport: TransportConfig::Normal { + enable_mdns: !is_dev && !self.no_mdns, + allow_private_ipv4: !self.no_private_ipv4, + wasm_external_transport: None, + use_yamux_flow_control: self.use_yamux_flow_control, + }, + max_parallel_downloads: self.max_parallel_downloads, } - - config.network.client_version = client_id; - self.node_key_params.update_config(&mut config, Some(&config_path))?; - - config.network.in_peers = self.in_peers; - config.network.out_peers = self.out_peers; - - config.network.transport = TransportConfig::Normal { - enable_mdns: !is_dev && !self.no_mdns, - allow_private_ipv4: !self.no_private_ipv4, - wasm_external_transport: None, - use_yamux_flow_control: self.use_yamux_flow_control, - }; - - config.network.max_parallel_downloads = self.max_parallel_downloads; - - Ok(()) } } diff --git a/client/cli/src/params/node_key_params.rs b/client/cli/src/params/node_key_params.rs index c55ec8ee69..2913ff2c10 100644 --- a/client/cli/src/params/node_key_params.rs +++ b/client/cli/src/params/node_key_params.rs @@ -14,14 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::{path::PathBuf, str::FromStr}; -use structopt::StructOpt; -use sc_service::Configuration; use sc_network::config::NodeKeyConfig; use sp_core::H256; +use std::{path::PathBuf, str::FromStr}; +use structopt::StructOpt; -use crate::error; use crate::arg_enums::NodeKeyType; +use crate::error; /// The file name of the node's Ed25519 secret key inside the chain-specific /// network config directory, if neither `--node-key` nor `--node-key-file` @@ -93,31 +92,23 @@ pub struct NodeKeyParams { impl NodeKeyParams { /// Create a `NodeKeyConfig` from the given `NodeKeyParams` in the context /// of an optional network config storage directory. - pub fn update_config<'a>( - &self, - mut config: &'a mut Configuration, - net_config_path: Option<&PathBuf>, - ) -> error::Result<&'a NodeKeyConfig> { - config.network.node_key = match self.node_key_type { + pub fn node_key(&self, net_config_dir: &PathBuf) -> error::Result { + Ok(match self.node_key_type { NodeKeyType::Ed25519 => { let secret = if let Some(node_key) = self.node_key.as_ref() { parse_ed25519_secret(node_key)? } else { - let path = self.node_key_file.clone() - .or_else(|| net_config_path.map(|d| d.join(NODE_KEY_ED25519_FILE))); + let path = self + .node_key_file + .clone() + .unwrap_or_else(|| net_config_dir.join(NODE_KEY_ED25519_FILE)); - if let Some(path) = path { - sc_network::config::Secret::File(path) - } else { - sc_network::config::Secret::New - } + sc_network::config::Secret::File(path) }; NodeKeyConfig::Ed25519(secret) } - }; - - Ok(&config.network.node_key) + }) } } @@ -128,114 +119,107 @@ fn invalid_node_key(e: impl std::fmt::Display) -> error::Error { /// Parse a Ed25519 secret key from a hex string into a `sc_network::Secret`. fn parse_ed25519_secret(hex: &str) -> error::Result { - H256::from_str(&hex).map_err(invalid_node_key).and_then(|bytes| - sc_network::config::identity::ed25519::SecretKey::from_bytes(bytes) - .map(sc_network::config::Secret::Input) - .map_err(invalid_node_key)) + H256::from_str(&hex) + .map_err(invalid_node_key) + .and_then(|bytes| { + sc_network::config::identity::ed25519::SecretKey::from_bytes(bytes) + .map(sc_network::config::Secret::Input) + .map_err(invalid_node_key) + }) } #[cfg(test)] mod tests { - use sc_network::config::identity::ed25519; use super::*; + use sc_network::config::identity::ed25519; #[test] fn test_node_key_config_input() { - fn secret_input(net_config_dir: Option<&PathBuf>) -> error::Result<()> { + fn secret_input(net_config_dir: &PathBuf) -> error::Result<()> { NodeKeyType::variants().iter().try_for_each(|t| { - let mut config = Configuration::default(); let node_key_type = NodeKeyType::from_str(t).unwrap(); let sk = match node_key_type { - NodeKeyType::Ed25519 => ed25519::SecretKey::generate().as_ref().to_vec() + NodeKeyType::Ed25519 => ed25519::SecretKey::generate().as_ref().to_vec(), }; let params = NodeKeyParams { node_key_type, node_key: Some(format!("{:x}", H256::from_slice(sk.as_ref()))), - node_key_file: None + node_key_file: None, }; - params.update_config(&mut config, net_config_dir).and_then(|c| match c { + params.node_key(net_config_dir).and_then(|c| match c { NodeKeyConfig::Ed25519(sc_network::config::Secret::Input(ref ski)) - if node_key_type == NodeKeyType::Ed25519 && - &sk[..] == ski.as_ref() => Ok(()), - _ => Err(error::Error::Input("Unexpected node key config".into())) + if node_key_type == NodeKeyType::Ed25519 && &sk[..] == ski.as_ref() => + { + Ok(()) + } + _ => Err(error::Error::Input("Unexpected node key config".into())), }) }) } - assert!(secret_input(None).is_ok()); - assert!(secret_input(Some(&PathBuf::from_str("x").unwrap())).is_ok()); + assert!(secret_input(&PathBuf::from_str("x").unwrap()).is_ok()); } #[test] fn test_node_key_config_file() { - fn secret_file(net_config_dir: Option<&PathBuf>) -> error::Result<()> { + fn secret_file(net_config_dir: &PathBuf) -> error::Result<()> { NodeKeyType::variants().iter().try_for_each(|t| { - let mut config = Configuration::default(); let node_key_type = NodeKeyType::from_str(t).unwrap(); let tmp = tempfile::Builder::new().prefix("alice").tempdir()?; let file = tmp.path().join(format!("{}_mysecret", t)).to_path_buf(); let params = NodeKeyParams { node_key_type, node_key: None, - node_key_file: Some(file.clone()) + node_key_file: Some(file.clone()), }; - params.update_config(&mut config, net_config_dir).and_then(|c| match c { + params.node_key(net_config_dir).and_then(|c| match c { NodeKeyConfig::Ed25519(sc_network::config::Secret::File(ref f)) - if node_key_type == NodeKeyType::Ed25519 && f == &file => Ok(()), - _ => Err(error::Error::Input("Unexpected node key config".into())) + if node_key_type == NodeKeyType::Ed25519 && f == &file => + { + Ok(()) + } + _ => Err(error::Error::Input("Unexpected node key config".into())), }) }) } - assert!(secret_file(None).is_ok()); - assert!(secret_file(Some(&PathBuf::from_str("x").unwrap())).is_ok()); + assert!(secret_file(&PathBuf::from_str("x").unwrap()).is_ok()); } #[test] fn test_node_key_config_default() { fn with_def_params(f: F) -> error::Result<()> where - F: Fn(NodeKeyParams) -> error::Result<()> + F: Fn(NodeKeyParams) -> error::Result<()>, { NodeKeyType::variants().iter().try_for_each(|t| { let node_key_type = NodeKeyType::from_str(t).unwrap(); f(NodeKeyParams { node_key_type, node_key: None, - node_key_file: None + node_key_file: None, }) }) } - fn no_config_dir() -> error::Result<()> { - with_def_params(|params| { - let mut config = Configuration::default(); - let typ = params.node_key_type; - params.update_config(&mut config, None) - .and_then(|c| match c { - NodeKeyConfig::Ed25519(sc_network::config::Secret::New) - if typ == NodeKeyType::Ed25519 => Ok(()), - _ => Err(error::Error::Input("Unexpected node key config".into())) - }) - }) - } - fn some_config_dir(net_config_dir: &PathBuf) -> error::Result<()> { with_def_params(|params| { - let mut config = Configuration::default(); let dir = PathBuf::from(net_config_dir.clone()); let typ = params.node_key_type; - params.update_config(&mut config, Some(net_config_dir)) + params + .node_key(net_config_dir) .and_then(move |c| match c { NodeKeyConfig::Ed25519(sc_network::config::Secret::File(ref f)) - if typ == NodeKeyType::Ed25519 && - f == &dir.join(NODE_KEY_ED25519_FILE) => Ok(()), - _ => Err(error::Error::Input("Unexpected node key config".into())) - }) + if typ == NodeKeyType::Ed25519 + && f == &dir.join(NODE_KEY_ED25519_FILE) => + { + Ok(()) + } + _ => Err(error::Error::Input("Unexpected node key config".into())), + }) }) } - assert!(no_config_dir().is_ok()); assert!(some_config_dir(&PathBuf::from_str("x").unwrap()).is_ok()); } } diff --git a/client/cli/src/params/pruning_params.rs b/client/cli/src/params/pruning_params.rs index 8d069a299f..ed8f7ab168 100644 --- a/client/cli/src/params/pruning_params.rs +++ b/client/cli/src/params/pruning_params.rs @@ -14,10 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use structopt::StructOpt; -use sc_service::{Configuration, PruningMode}; - use crate::error; +use sc_service::{PruningMode, Role}; +use structopt::StructOpt; /// Parameters to define the pruning mode #[derive(Debug, StructOpt, Clone)] @@ -32,18 +31,13 @@ pub struct PruningParams { } impl PruningParams { - /// Put block pruning CLI params into `config` object. - pub fn update_config( - &self, - mut config: &mut Configuration, - role: &sc_service::Role, - unsafe_pruning: bool, - ) -> error::Result<()> { + /// Get the pruning value from the parameters + pub fn pruning(&self, unsafe_pruning: bool, role: &Role) -> error::Result { // by default we disable pruning if the node is an authority (i.e. // `ArchiveAll`), otherwise we keep state for the last 256 blocks. if the // node is an authority and pruning is enabled explicitly, then we error // unless `unsafe_pruning` is set. - config.pruning = match &self.pruning { + Ok(match &self.pruning { Some(ref s) if s == "archive" => PruningMode::ArchiveAll, None if role.is_network_authority() => PruningMode::ArchiveAll, None => PruningMode::default(), @@ -51,16 +45,15 @@ impl PruningParams { if role.is_network_authority() && !unsafe_pruning { return Err(error::Error::Input( "Validators should run with state pruning disabled (i.e. archive). \ - You can ignore this check with `--unsafe-pruning`.".to_string() + You can ignore this check with `--unsafe-pruning`." + .to_string(), )); } - PruningMode::keep_blocks(s.parse() - .map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))? - ) - }, - }; - - Ok(()) + PruningMode::keep_blocks(s.parse().map_err(|_| { + error::Error::Input("Invalid pruning mode specified".to_string()) + })?) + } + }) } } diff --git a/client/cli/src/params/shared_params.rs b/client/cli/src/params/shared_params.rs index 41b9cce826..f7f9db102c 100644 --- a/client/cli/src/params/shared_params.rs +++ b/client/cli/src/params/shared_params.rs @@ -14,18 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use sc_service::config::DatabaseConfig; use std::path::PathBuf; use structopt::StructOpt; -use app_dirs::{AppInfo, AppDataType}; -use sc_service::{ - Configuration, config::DatabaseConfig, ChainSpec, -}; - -use crate::VersionInfo; -use crate::error; /// default sub directory to store database -const DEFAULT_DB_CONFIG_PATH : &'static str = "db"; +const DEFAULT_DB_CONFIG_PATH: &'static str = "db"; /// Shared parameters used by all `CoreParams`. #[derive(Debug, StructOpt, Clone)] @@ -39,7 +33,12 @@ pub struct SharedParams { pub dev: bool, /// Specify custom base path. - #[structopt(long = "base-path", short = "d", value_name = "PATH", parse(from_os_str))] + #[structopt( + long = "base-path", + short = "d", + value_name = "PATH", + parse(from_os_str) + )] pub base_path: Option, /// Sets a custom logging filter. Syntax is =, e.g. -lsync=debug. @@ -51,62 +50,44 @@ pub struct SharedParams { } impl SharedParams { - /// Load spec to `Configuration` from `SharedParams` and spec factory. - pub fn update_config<'a, F>( - &self, - mut config: &'a mut Configuration, - spec_factory: F, - version: &VersionInfo, - ) -> error::Result<&'a dyn ChainSpec> where - F: FnOnce(&str) -> Result, String>, - { - let chain_key = match self.chain { - Some(ref chain) => chain.clone(), - None => if self.dev { "dev".into() } else { "".into() } - }; - let spec = spec_factory(&chain_key)?; - config.network.boot_nodes = spec.boot_nodes().to_vec(); - config.telemetry_endpoints = spec.telemetry_endpoints().clone(); + /// Specify custom base path. + pub fn base_path(&self) -> Option { + self.base_path.clone() + } - config.chain_spec = Some(spec); + /// Specify the development chain. + pub fn is_dev(&self) -> bool { + self.dev + } - if config.config_dir.is_none() { - config.config_dir = Some(base_path(self, version)); + /// Get the chain spec for the parameters provided + pub fn chain_id(&self, is_dev: bool) -> String { + match self.chain { + Some(ref chain) => chain.clone(), + None => { + if is_dev { + "dev".into() + } else { + "".into() + } + } } + } - if config.database.is_none() { - config.database = Some(DatabaseConfig::Path { - path: config - .in_chain_config_dir(DEFAULT_DB_CONFIG_PATH) - .expect("We provided a base_path/config_dir."), - cache_size: None, - }); + /// Get the database configuration object for the parameters provided + pub fn database_config( + &self, + base_path: &PathBuf, + cache_size: usize, + ) -> DatabaseConfig { + DatabaseConfig::Path { + path: base_path.join(DEFAULT_DB_CONFIG_PATH), + cache_size, } - - Ok(config.expect_chain_spec()) } - /// Initialize substrate. This must be done only once. - /// - /// This method: - /// - /// 1. Set the panic handler - /// 2. Raise the FD limit - /// 3. Initialize the logger - pub fn init(&self, version: &VersionInfo) -> error::Result<()> { - crate::init(self.log.as_ref().map(|v| v.as_ref()).unwrap_or(""), version) + /// Get the filters for the logging + pub fn log_filters(&self) -> Option { + self.log.clone() } } - -fn base_path(cli: &SharedParams, version: &VersionInfo) -> PathBuf { - cli.base_path.clone() - .unwrap_or_else(|| - app_dirs::get_app_root( - AppDataType::UserData, - &AppInfo { - name: version.executable_name, - author: version.author - } - ).expect("app directories exist on all supported platforms; qed") - ) -} diff --git a/client/cli/src/params/transaction_pool_params.rs b/client/cli/src/params/transaction_pool_params.rs index 3468c12243..dfcdf9af70 100644 --- a/client/cli/src/params/transaction_pool_params.rs +++ b/client/cli/src/params/transaction_pool_params.rs @@ -14,9 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use sc_service::config::TransactionPoolOptions; use structopt::StructOpt; -use sc_service::Configuration; -use crate::error; /// Parameters used to create the pool configuration. #[derive(Debug, StructOpt, Clone)] @@ -24,6 +23,7 @@ pub struct TransactionPoolParams { /// Maximum number of transactions in the transaction pool. #[structopt(long = "pool-limit", value_name = "COUNT", default_value = "8192")] pub pool_limit: usize, + /// Maximum number of kilobytes of all transactions stored in the pool. #[structopt(long = "pool-kbytes", value_name = "COUNT", default_value = "20480")] pub pool_kbytes: usize, @@ -31,19 +31,18 @@ pub struct TransactionPoolParams { impl TransactionPoolParams { /// Fill the given `PoolConfiguration` by looking at the cli parameters. - pub fn update_config( - &self, - config: &mut Configuration, - ) -> error::Result<()> { + pub fn transaction_pool(&self) -> TransactionPoolOptions { + let mut opts = TransactionPoolOptions::default(); + // ready queue - config.transaction_pool.ready.count = self.pool_limit; - config.transaction_pool.ready.total_bytes = self.pool_kbytes * 1024; + opts.ready.count = self.pool_limit; + opts.ready.total_bytes = self.pool_kbytes * 1024; // future queue let factor = 10; - config.transaction_pool.future.count = self.pool_limit / factor; - config.transaction_pool.future.total_bytes = self.pool_kbytes * 1024 / factor; + opts.future.count = self.pool_limit / factor; + opts.future.total_bytes = self.pool_kbytes * 1024 / factor; - Ok(()) + opts } } diff --git a/client/cli/src/runner.rs b/client/cli/src/runner.rs new file mode 100644 index 0000000000..bd5dc7100e --- /dev/null +++ b/client/cli/src/runner.rs @@ -0,0 +1,237 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use crate::CliConfiguration; +use crate::Result; +use crate::SubstrateCli; +use crate::Subcommand; +use chrono::prelude::*; +use futures::pin_mut; +use futures::select; +use futures::{future, future::FutureExt, Future}; +use log::info; +use sc_service::{AbstractService, Configuration, Role, ServiceBuilderCommand}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; +use sp_utils::metrics::{TOKIO_THREADS_ALIVE, TOKIO_THREADS_TOTAL}; +use std::fmt::Debug; +use std::marker::PhantomData; +use std::sync::Arc; + +#[cfg(target_family = "unix")] +async fn main(func: F) -> std::result::Result<(), Box> +where + F: Future> + future::FusedFuture, + E: 'static + std::error::Error, +{ + use tokio::signal::unix::{signal, SignalKind}; + + let mut stream_int = signal(SignalKind::interrupt())?; + let mut stream_term = signal(SignalKind::terminate())?; + + let t1 = stream_int.recv().fuse(); + let t2 = stream_term.recv().fuse(); + let t3 = func; + + pin_mut!(t1, t2, t3); + + select! { + _ = t1 => {}, + _ = t2 => {}, + res = t3 => res?, + } + + Ok(()) +} + +#[cfg(not(unix))] +async fn main(func: F) -> std::result::Result<(), Box> +where + F: Future> + future::FusedFuture, + E: 'static + std::error::Error, +{ + use tokio::signal::ctrl_c; + + let t1 = ctrl_c().fuse(); + let t2 = func; + + pin_mut!(t1, t2); + + select! { + _ = t1 => {}, + res = t2 => res?, + } + + Ok(()) +} + +/// Build a tokio runtime with all features +pub fn build_runtime() -> std::result::Result { + tokio::runtime::Builder::new() + .thread_name("main-tokio-") + .threaded_scheduler() + .on_thread_start(||{ + TOKIO_THREADS_ALIVE.inc(); + TOKIO_THREADS_TOTAL.inc(); + }) + .on_thread_stop(||{ + TOKIO_THREADS_ALIVE.dec(); + }) + .enable_all() + .build() +} + +fn run_until_exit(mut tokio_runtime: tokio::runtime::Runtime, future: FUT) -> Result<()> +where + FUT: Future> + future::Future, + ERR: 'static + std::error::Error, +{ + let f = future.fuse(); + pin_mut!(f); + + tokio_runtime.block_on(main(f)).map_err(|e| e.to_string())?; + + Ok(()) +} + +/// A Substrate CLI runtime that can be used to run a node or a command +pub struct Runner { + config: Configuration, + tokio_runtime: tokio::runtime::Runtime, + phantom: PhantomData, +} + +impl Runner { + /// Create a new runtime with the command provided in argument + pub fn new(cli: &C, command: &T) -> Result> { + let tokio_runtime = build_runtime()?; + + let task_executor = { + let runtime_handle = tokio_runtime.handle().clone(); + Arc::new(move |fut| { + runtime_handle.spawn(fut); + }) + }; + + Ok(Runner { + config: command.create_configuration(cli, task_executor)?, + tokio_runtime, + phantom: PhantomData, + }) + } + + /// A helper function that runs an `AbstractService` with tokio and stops if the process receives + /// the signal `SIGTERM` or `SIGINT`. + pub fn run_node(self, new_light: FNL, new_full: FNF) -> Result<()> + where + FNL: FnOnce(Configuration) -> sc_service::error::Result, + FNF: FnOnce(Configuration) -> sc_service::error::Result, + SL: AbstractService + Unpin, + SF: AbstractService + Unpin, + { + info!("{}", C::impl_name()); + info!("✌️ version {}", C::impl_version()); + info!( + "❤️ by {}, {}-{}", + C::author(), + C::copyright_start_year(), + Local::today().year(), + ); + info!("📋 Chain specification: {}", self.config.chain_spec.name()); + info!("🏷 Node name: {}", self.config.network.node_name); + info!("👤 Role: {}", self.config.display_role()); + + match self.config.role { + Role::Light => self.run_service_until_exit(new_light), + _ => self.run_service_until_exit(new_full), + } + } + + /// A helper function that runs a future with tokio and stops if the process receives the signal + /// `SIGTERM` or `SIGINT`. + pub fn run_subcommand(self, subcommand: &Subcommand, builder: B) -> Result<()> + where + B: FnOnce(Configuration) -> sc_service::error::Result, + BC: ServiceBuilderCommand + Unpin, + BB: sp_runtime::traits::Block + Debug, + <<::Header as HeaderT>::Number as std::str::FromStr>::Err: Debug, + ::Hash: std::str::FromStr, + { + match subcommand { + Subcommand::BuildSpec(cmd) => cmd.run(self.config), + Subcommand::ExportBlocks(cmd) => { + run_until_exit(self.tokio_runtime, cmd.run(self.config, builder)) + } + Subcommand::ImportBlocks(cmd) => { + run_until_exit(self.tokio_runtime, cmd.run(self.config, builder)) + } + Subcommand::CheckBlock(cmd) => { + run_until_exit(self.tokio_runtime, cmd.run(self.config, builder)) + } + Subcommand::Revert(cmd) => cmd.run(self.config, builder), + Subcommand::PurgeChain(cmd) => cmd.run(self.config), + } + } + + fn run_service_until_exit(mut self, service_builder: F) -> Result<()> + where + F: FnOnce(Configuration) -> std::result::Result, + T: AbstractService + Unpin, + { + let service = service_builder(self.config)?; + + let informant_future = sc_informant::build(&service, sc_informant::OutputFormat::Coloured); + let _informant_handle = self.tokio_runtime.spawn(informant_future); + + // we eagerly drop the service so that the internal exit future is fired, + // but we need to keep holding a reference to the global telemetry guard + // and drop the runtime first. + let _telemetry = service.telemetry(); + + let f = service.fuse(); + pin_mut!(f); + + self.tokio_runtime + .block_on(main(f)) + .map_err(|e| e.to_string())?; + drop(self.tokio_runtime); + + Ok(()) + } + + /// A helper function that runs a command with the configuration of this node + pub fn sync_run(self, runner: impl FnOnce(Configuration) -> Result<()>) -> Result<()> { + runner(self.config) + } + + /// A helper function that runs a future with tokio and stops if the process receives + /// the signal SIGTERM or SIGINT + pub fn async_run(self, runner: impl FnOnce(Configuration) -> FUT) -> Result<()> + where + FUT: Future>, + { + run_until_exit(self.tokio_runtime, runner(self.config)) + } + + /// Get an immutable reference to the node Configuration + pub fn config(&self) -> &Configuration { + &self.config + } + + /// Get a mutable reference to the node Configuration + pub fn config_mut(&mut self) -> &Configuration { + &mut self.config + } +} diff --git a/client/cli/src/runtime.rs b/client/cli/src/runtime.rs deleted file mode 100644 index 5c9bc75088..0000000000 --- a/client/cli/src/runtime.rs +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -use std::sync::Arc; - -use futures::{Future, future, future::FutureExt}; -use futures::select; -use futures::pin_mut; -use sc_service::{AbstractService, Configuration}; -use sp_utils::metrics::{TOKIO_THREADS_ALIVE, TOKIO_THREADS_TOTAL}; -use crate::error; - -#[cfg(target_family = "unix")] -async fn main(func: F) -> Result<(), Box> -where - F: Future> + future::FusedFuture, - E: 'static + std::error::Error, -{ - use tokio::signal::unix::{signal, SignalKind}; - - let mut stream_int = signal(SignalKind::interrupt())?; - let mut stream_term = signal(SignalKind::terminate())?; - - let t1 = stream_int.recv().fuse(); - let t2 = stream_term.recv().fuse(); - let t3 = func; - - pin_mut!(t1, t2, t3); - - select! { - _ = t1 => {}, - _ = t2 => {}, - res = t3 => res?, - } - - Ok(()) -} - -#[cfg(not(unix))] -async fn main(func: F) -> Result<(), Box> -where - F: Future> + future::FusedFuture, - E: 'static + std::error::Error, -{ - use tokio::signal::ctrl_c; - - let t1 = ctrl_c().fuse(); - let t2 = func; - - pin_mut!(t1, t2); - - select! { - _ = t1 => {}, - res = t2 => res?, - } - - Ok(()) -} - -fn build_runtime() -> Result { - tokio::runtime::Builder::new() - .thread_name("main-tokio-") - .threaded_scheduler() - .on_thread_start(||{ - TOKIO_THREADS_ALIVE.inc(); - TOKIO_THREADS_TOTAL.inc(); - }) - .on_thread_stop(||{ - TOKIO_THREADS_ALIVE.dec(); - }) - .enable_all() - .build() -} - -/// A helper function that runs a future with tokio and stops if the process receives the signal -/// SIGTERM or SIGINT -pub fn run_until_exit( - mut config: Configuration, - future_builder: F, -) -> error::Result<()> -where - F: FnOnce(Configuration) -> error::Result, - FUT: Future> + future::Future, - ERR: 'static + std::error::Error, -{ - let mut runtime = build_runtime()?; - - config.task_executor = { - let runtime_handle = runtime.handle().clone(); - Some(Arc::new(move |fut| { runtime_handle.spawn(fut); })) - }; - - let f = future_builder(config)?; - let f = f.fuse(); - pin_mut!(f); - - runtime.block_on(main(f)).map_err(|e| e.to_string())?; - - Ok(()) -} - -/// A helper function that runs an `AbstractService` with tokio and stops if the process receives -/// the signal SIGTERM or SIGINT -pub fn run_service_until_exit( - mut config: Configuration, - service_builder: F, -) -> error::Result<()> -where - F: FnOnce(Configuration) -> Result, - T: AbstractService + Unpin, -{ - let mut runtime = build_runtime()?; - - config.task_executor = { - let runtime_handle = runtime.handle().clone(); - Some(Arc::new(move |fut| { runtime_handle.spawn(fut); })) - }; - - let service = service_builder(config)?; - - let informant_future = sc_informant::build(&service, sc_informant::OutputFormat::Coloured); - let _informant_handle = runtime.spawn(informant_future); - - // we eagerly drop the service so that the internal exit future is fired, - // but we need to keep holding a reference to the global telemetry guard - // and drop the runtime first. - let _telemetry = service.telemetry(); - - let f = service.fuse(); - pin_mut!(f); - - runtime.block_on(main(f)).map_err(|e| e.to_string())?; - drop(runtime); - - Ok(()) -} diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index f1cb5f9a79..e00d608a5f 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -284,8 +284,8 @@ pub enum DatabaseSettingsSrc { Path { /// Path to the database. path: PathBuf, - /// Cache size in bytes. If `None` default is used. - cache_size: Option, + /// Cache size in bytes. + cache_size: usize, }, /// Use a custom already-open database. diff --git a/client/db/src/light.rs b/client/db/src/light.rs index 808a209f52..e3dcdedd50 100644 --- a/client/db/src/light.rs +++ b/client/db/src/light.rs @@ -963,7 +963,7 @@ pub(crate) mod tests { fn run_checks(db: &LightStorage, max: u64, checks: &[(u64, Option>)]) { for (at, expected) in checks.iter().take_while(|(at, _)| *at <= max) { - let actual = get_authorities(db.cache(), BlockId::Number(*at)); + let actual = authorities(db.cache(), BlockId::Number(*at)); assert_eq!(*expected, actual); } } @@ -978,7 +978,7 @@ pub(crate) mod tests { map } - fn get_authorities(cache: &dyn BlockchainCache, at: BlockId) -> Option> { + fn authorities(cache: &dyn BlockchainCache, at: BlockId) -> Option> { cache.get_at(&well_known_cache_keys::AUTHORITIES, &at).unwrap_or(None) .and_then(|(_, _, val)| Decode::decode(&mut &val[..]).ok()) } @@ -1026,9 +1026,9 @@ pub(crate) mod tests { // ... -> B2(1) -> B2_1(1) -> B2_2(2) // => the cache ignores all writes before best finalized block let hash2_1 = insert_non_best_block(&db, make_authorities(vec![auth1()]), || default_header(&hash2, 3)); - assert_eq!(None, get_authorities(db.cache(), BlockId::Hash(hash2_1))); + assert_eq!(None, authorities(db.cache(), BlockId::Hash(hash2_1))); let hash2_2 = insert_non_best_block(&db, make_authorities(vec![auth1(), auth2()]), || default_header(&hash2_1, 4)); - assert_eq!(None, get_authorities(db.cache(), BlockId::Hash(hash2_2))); + assert_eq!(None, authorities(db.cache(), BlockId::Hash(hash2_2))); } let (hash7, hash8, hash6_1, hash6_2, hash6_1_1, hash6_1_2) = { @@ -1040,55 +1040,55 @@ pub(crate) mod tests { let hash7 = insert_block(&db, make_authorities(vec![auth3()]), || default_header(&hash6, 7)); assert_eq!( - get_authorities(db.cache(), BlockId::Hash(hash6)), + authorities(db.cache(), BlockId::Hash(hash6)), Some(vec![auth1(), auth2()]), ); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash7)), Some(vec![auth3()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash7)), Some(vec![auth3()])); let hash8 = insert_block(&db, make_authorities(vec![auth3()]), || default_header(&hash7, 8)); assert_eq!( - get_authorities(db.cache(), BlockId::Hash(hash6)), + authorities(db.cache(), BlockId::Hash(hash6)), Some(vec![auth1(), auth2()]), ); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash7)), Some(vec![auth3()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash8)), Some(vec![auth3()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash7)), Some(vec![auth3()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash8)), Some(vec![auth3()])); let hash6_1 = insert_block(&db, make_authorities(vec![auth4()]), || default_header(&hash6, 7)); assert_eq!( - get_authorities(db.cache(), BlockId::Hash(hash6)), + authorities(db.cache(), BlockId::Hash(hash6)), Some(vec![auth1(), auth2()]), ); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash7)), Some(vec![auth3()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash8)), Some(vec![auth3()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1)), Some(vec![auth4()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash7)), Some(vec![auth3()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash8)), Some(vec![auth3()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1)), Some(vec![auth4()])); let hash6_1_1 = insert_non_best_block(&db, make_authorities(vec![auth5()]), || default_header(&hash6_1, 8)); assert_eq!( - get_authorities(db.cache(), BlockId::Hash(hash6)), + authorities(db.cache(), BlockId::Hash(hash6)), Some(vec![auth1(), auth2()]), ); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash7)), Some(vec![auth3()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash8)), Some(vec![auth3()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1)), Some(vec![auth4()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1_1)), Some(vec![auth5()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash7)), Some(vec![auth3()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash8)), Some(vec![auth3()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1)), Some(vec![auth4()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1_1)), Some(vec![auth5()])); let hash6_1_2 = insert_non_best_block(&db, make_authorities(vec![auth6()]), || default_header(&hash6_1, 8)); assert_eq!( - get_authorities(db.cache(), BlockId::Hash(hash6)), + authorities(db.cache(), BlockId::Hash(hash6)), Some(vec![auth1(), auth2()]), ); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash7)), Some(vec![auth3()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash8)), Some(vec![auth3()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1)), Some(vec![auth4()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1_1)), Some(vec![auth5()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1_2)), Some(vec![auth6()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash7)), Some(vec![auth3()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash8)), Some(vec![auth3()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1)), Some(vec![auth4()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1_1)), Some(vec![auth5()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1_2)), Some(vec![auth6()])); let hash6_2 = insert_block(&db, make_authorities(vec![auth4()]), || default_header(&hash6_1, 8)); assert_eq!( - get_authorities(db.cache(), BlockId::Hash(hash6)), + authorities(db.cache(), BlockId::Hash(hash6)), Some(vec![auth1(), auth2()]), ); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash7)), Some(vec![auth3()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash8)), Some(vec![auth3()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1)), Some(vec![auth4()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1_1)), Some(vec![auth5()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1_2)), Some(vec![auth6()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_2)), Some(vec![auth4()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash7)), Some(vec![auth3()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash8)), Some(vec![auth3()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1)), Some(vec![auth4()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1_1)), Some(vec![auth5()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1_2)), Some(vec![auth6()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_2)), Some(vec![auth4()])); (hash7, hash8, hash6_1, hash6_2, hash6_1_1, hash6_1_2) }; @@ -1097,27 +1097,27 @@ pub(crate) mod tests { // finalize block hash6_1 db.finalize_header(BlockId::Hash(hash6_1)).unwrap(); assert_eq!( - get_authorities(db.cache(), BlockId::Hash(hash6)), + authorities(db.cache(), BlockId::Hash(hash6)), Some(vec![auth1(), auth2()]), ); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash7)), None); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash8)), None); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1)), Some(vec![auth4()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1_1)), Some(vec![auth5()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1_2)), Some(vec![auth6()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_2)), Some(vec![auth4()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash7)), None); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash8)), None); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1)), Some(vec![auth4()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1_1)), Some(vec![auth5()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1_2)), Some(vec![auth6()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_2)), Some(vec![auth4()])); // finalize block hash6_2 db.finalize_header(BlockId::Hash(hash6_2)).unwrap(); assert_eq!( - get_authorities(db.cache(), BlockId::Hash(hash6)), + authorities(db.cache(), BlockId::Hash(hash6)), Some(vec![auth1(), auth2()]), ); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash7)), None); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash8)), None); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1)), Some(vec![auth4()])); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1_1)), None); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_1_2)), None); - assert_eq!(get_authorities(db.cache(), BlockId::Hash(hash6_2)), Some(vec![auth4()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash7)), None); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash8)), None); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1)), Some(vec![auth4()])); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1_1)), None); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_1_2)), None); + assert_eq!(authorities(db.cache(), BlockId::Hash(hash6_2)), Some(vec![auth4()])); } } diff --git a/client/db/src/upgrade.rs b/client/db/src/upgrade.rs index 971acf8456..5e6794108e 100644 --- a/client/db/src/upgrade.rs +++ b/client/db/src/upgrade.rs @@ -166,7 +166,7 @@ mod tests { state_cache_size: 0, state_cache_child_ratio: None, pruning: PruningMode::ArchiveAll, - source: DatabaseSettingsSrc::Path { path: db_path.to_owned(), cache_size: None }, + source: DatabaseSettingsSrc::Path { path: db_path.to_owned(), cache_size: 128 }, }, DatabaseType::Full).map(|_| ()) } diff --git a/client/db/src/utils.rs b/client/db/src/utils.rs index f26714eb5a..e62c4f052b 100644 --- a/client/db/src/utils.rs +++ b/client/db/src/utils.rs @@ -227,24 +227,22 @@ pub fn open_database( // and now open database assuming that it has the latest version let mut db_config = DatabaseConfig::with_columns(NUM_COLUMNS); + let state_col_budget = (*cache_size as f64 * 0.9) as usize; + let other_col_budget = (cache_size - state_col_budget) / (NUM_COLUMNS as usize - 1); + let mut memory_budget = std::collections::HashMap::new(); + let path = path.to_str() + .ok_or_else(|| sp_blockchain::Error::Backend("Invalid database path".into()))?; - if let Some(cache_size) = cache_size { - let state_col_budget = (*cache_size as f64 * 0.9) as usize; - let other_col_budget = (cache_size - state_col_budget) / (NUM_COLUMNS as usize - 1); - - let mut memory_budget = std::collections::HashMap::new(); - for i in 0..NUM_COLUMNS { - if i == crate::columns::STATE { - memory_budget.insert(i, state_col_budget); - } else { - memory_budget.insert(i, other_col_budget); - } + for i in 0..NUM_COLUMNS { + if i == crate::columns::STATE { + memory_budget.insert(i, state_col_budget); + } else { + memory_budget.insert(i, other_col_budget); } - - db_config.memory_budget = memory_budget; } - let path = path.to_str() - .ok_or_else(|| sp_blockchain::Error::Backend("Invalid database path".into()))?; + + db_config.memory_budget = memory_budget; + Arc::new(Database::open(&db_config, &path).map_err(db_err)?) }, #[cfg(not(any(feature = "kvdb-rocksdb", test)))] diff --git a/client/executor/src/wasm_runtime.rs b/client/executor/src/wasm_runtime.rs index e6c16453f3..7a369cc470 100644 --- a/client/executor/src/wasm_runtime.rs +++ b/client/executor/src/wasm_runtime.rs @@ -40,6 +40,12 @@ pub enum WasmExecutionMethod { Compiled, } +impl Default for WasmExecutionMethod { + fn default() -> WasmExecutionMethod { + WasmExecutionMethod::Interpreted + } +} + /// A Wasm runtime object along with its cached runtime version. struct VersionedRuntime { /// Runtime code hash. diff --git a/client/network/src/config.rs b/client/network/src/config.rs index c9290927eb..9cd57a9d1d 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -307,10 +307,8 @@ impl From for ParseErr { /// Network service configuration. #[derive(Clone, Debug)] pub struct NetworkConfiguration { - /// Directory path to store general network configuration. None means nothing will be saved. - pub config_path: Option, /// Directory path to store network-specific configuration. None means nothing will be saved. - pub net_config_path: Option, + pub net_config_path: PathBuf, /// Multiaddresses to listen for incoming connections. pub listen_addresses: Vec, /// Multiaddresses to advertise. Detected automatically if empty. @@ -337,21 +335,26 @@ pub struct NetworkConfiguration { pub max_parallel_downloads: u32, } -impl Default for NetworkConfiguration { - fn default() -> Self { +impl NetworkConfiguration { + /// Create new default configuration + pub fn new, SV: Into>( + node_name: SN, + client_version: SV, + node_key: NodeKeyConfig, + net_config_path: &PathBuf, + ) -> Self { NetworkConfiguration { - config_path: None, - net_config_path: None, + net_config_path: net_config_path.clone(), listen_addresses: Vec::new(), public_addresses: Vec::new(), boot_nodes: Vec::new(), - node_key: NodeKeyConfig::Ed25519(Secret::New), + node_key, in_peers: 25, out_peers: 75, reserved_nodes: Vec::new(), non_reserved_mode: NonReservedPeerMode::Accept, - client_version: "unknown".into(), - node_name: "unknown".into(), + client_version: client_version.into(), + node_name: node_name.into(), transport: TransportConfig::Normal { enable_mdns: false, allow_private_ipv4: true, @@ -364,30 +367,39 @@ impl Default for NetworkConfiguration { } impl NetworkConfiguration { - /// Create a new instance of default settings. - pub fn new() -> Self { - Self::default() - } - /// Create new default configuration for localhost-only connection with random port (useful for testing) pub fn new_local() -> NetworkConfiguration { - let mut config = NetworkConfiguration::new(); + let mut config = NetworkConfiguration::new( + "test-node", + "test-client", + Default::default(), + &std::env::current_dir().expect("current directory must exist"), + ); + config.listen_addresses = vec![ iter::once(multiaddr::Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .chain(iter::once(multiaddr::Protocol::Tcp(0))) .collect() ]; + config } /// Create new default configuration for localhost-only connection with random port (useful for testing) pub fn new_memory() -> NetworkConfiguration { - let mut config = NetworkConfiguration::new(); + let mut config = NetworkConfiguration::new( + "test-node", + "test-client", + Default::default(), + &std::env::current_dir().expect("current directory must exist"), + ); + config.listen_addresses = vec![ iter::once(multiaddr::Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .chain(iter::once(multiaddr::Protocol::Tcp(0))) .collect() ]; + config } } @@ -452,6 +464,12 @@ pub enum NodeKeyConfig { Ed25519(Secret) } +impl Default for NodeKeyConfig { + fn default() -> NodeKeyConfig { + NodeKeyConfig::Ed25519(Secret::New) + } +} + /// The options for obtaining a Ed25519 secret key. pub type Ed25519Secret = Secret; diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 4e9d8a7800..d3a72a3ff6 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -56,7 +56,6 @@ use std::{ collections::{HashMap, HashSet}, fs, io, marker::PhantomData, - path::Path, pin::Pin, str, sync::{atomic::{AtomicBool, AtomicUsize, Ordering}, Arc}, @@ -175,9 +174,7 @@ impl NetworkWorker { pub fn new(params: Params) -> Result, Error> { let (to_worker, from_worker) = tracing_unbounded("mpsc_network_worker"); - if let Some(ref path) = params.network_config.net_config_path { - fs::create_dir_all(Path::new(path))?; - } + fs::create_dir_all(¶ms.network_config.net_config_path)?; // List of multiaddresses that we know in the network. let mut known_addresses = Vec::new(); diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index aa887bf5ca..56070f9888 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -600,14 +600,19 @@ pub trait TestNetFactory: Sized { let listen_addr = build_multiaddr![Memory(rand::random::())]; + let mut network_config = NetworkConfiguration::new( + "test-node", + "test-client", + Default::default(), + &std::env::current_dir().expect("current directory must exist"), + ); + network_config.transport = TransportConfig::MemoryOnly; + network_config.listen_addresses = vec![listen_addr.clone()]; + let network = NetworkWorker::new(sc_network::config::Params { role: Role::Full, executor: None, - network_config: NetworkConfiguration { - listen_addresses: vec![listen_addr.clone()], - transport: TransportConfig::MemoryOnly, - ..NetworkConfiguration::default() - }, + network_config, chain: client.clone(), finality_proof_provider: self.make_finality_proof_provider( PeersClient::Full(client.clone(), backend.clone()), @@ -671,14 +676,19 @@ pub trait TestNetFactory: Sized { let listen_addr = build_multiaddr![Memory(rand::random::())]; + let mut network_config = NetworkConfiguration::new( + "test-node", + "test-client", + Default::default(), + &std::env::current_dir().expect("current directory must exist"), + ); + network_config.transport = TransportConfig::MemoryOnly; + network_config.listen_addresses = vec![listen_addr.clone()]; + let network = NetworkWorker::new(sc_network::config::Params { role: Role::Light, executor: None, - network_config: NetworkConfiguration { - listen_addresses: vec![listen_addr.clone()], - transport: TransportConfig::MemoryOnly, - ..NetworkConfiguration::default() - }, + network_config, chain: client.clone(), finality_proof_provider: self.make_finality_proof_provider( PeersClient::Light(client.clone(), backend.clone()) diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 530142c745..634d774a31 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -32,7 +32,6 @@ exit-future = "0.2.0" serde = "1.0.101" serde_json = "1.0.41" sysinfo = "0.12.0" -target_info = "0.1.0" sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 205f877999..0586a61a89 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -168,7 +168,6 @@ fn new_full_parts( password.clone() )?, KeystoreConfig::InMemory => Keystore::new_in_memory(), - KeystoreConfig::None => return Err("No keystore config provided!".into()), }; let tasks_builder = TaskManagerBuilder::new(); @@ -179,7 +178,7 @@ fn new_full_parts( config.max_runtime_instances, ); - let chain_spec = config.expect_chain_spec(); + let chain_spec = &config.chain_spec; let fork_blocks = get_extension::>(chain_spec.extensions()) .cloned() .unwrap_or_default(); @@ -194,11 +193,11 @@ fn new_full_parts( state_cache_child_ratio: config.state_cache_child_ratio.map(|v| (v, 100)), pruning: config.pruning.clone(), - source: match config.expect_database() { + source: match &config.database { DatabaseConfig::Path { path, cache_size } => sc_client_db::DatabaseSettingsSrc::Path { path: path.clone(), - cache_size: cache_size.clone().map(|u| u as usize), + cache_size: *cache_size, }, DatabaseConfig::Custom(db) => sc_client_db::DatabaseSettingsSrc::Custom(db.clone()), @@ -213,7 +212,7 @@ fn new_full_parts( sc_client_db::new_client( db_config, executor, - config.expect_chain_spec().as_storage_builder(), + chain_spec.as_storage_builder(), fork_blocks, bad_blocks, extensions, @@ -289,7 +288,6 @@ impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { password.clone() )?, KeystoreConfig::InMemory => Keystore::new_in_memory(), - KeystoreConfig::None => return Err("No keystore config provided!".into()), }; let executor = NativeExecutor::::new( @@ -304,11 +302,11 @@ impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { state_cache_child_ratio: config.state_cache_child_ratio.map(|v| (v, 100)), pruning: config.pruning.clone(), - source: match config.expect_database() { + source: match &config.database { DatabaseConfig::Path { path, cache_size } => sc_client_db::DatabaseSettingsSrc::Path { path: path.clone(), - cache_size: cache_size.clone().map(|u| u as usize), + cache_size: *cache_size, }, DatabaseConfig::Custom(db) => sc_client_db::DatabaseSettingsSrc::Custom(db.clone()), @@ -329,7 +327,7 @@ impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { let remote_blockchain = backend.remote_blockchain(); let client = Arc::new(sc_client::light::new_light( backend.clone(), - config.expect_chain_spec().as_storage_builder(), + config.chain_spec.as_storage_builder(), executor, Box::new(tasks_builder.spawn_handle()), config.prometheus_config.as_ref().map(|config| config.registry.clone()), @@ -778,9 +776,9 @@ ServiceBuilder< let import_queue = Box::new(import_queue); let chain_info = client.chain_info(); - let chain_spec = config.expect_chain_spec(); + let chain_spec = &config.chain_spec; - let version = config.full_version(); + let version = config.impl_version; info!("📦 Highest known block at #{}", chain_info.best_number); telemetry!( SUBSTRATE_INFO; @@ -958,7 +956,7 @@ ServiceBuilder< }; let metrics = MetricsService::with_prometheus( ®istry, - &config.name, + &config.network.node_name, &config.impl_version, role_bits, )?; @@ -1097,10 +1095,10 @@ ServiceBuilder< let telemetry = config.telemetry_endpoints.clone().map(|endpoints| { let is_authority = config.role.is_authority(); let network_id = network.local_peer_id().to_base58(); - let name = config.name.clone(); + let name = config.network.node_name.clone(); let impl_name = config.impl_name.to_owned(); let version = version.clone(); - let chain_name = config.expect_chain_spec().name().to_owned(); + let chain_name = config.chain_spec.name().to_owned(); let telemetry_connection_sinks_ = telemetry_connection_sinks.clone(); let telemetry = sc_telemetry::init_telemetry(sc_telemetry::TelemetryConfig { endpoints, @@ -1152,7 +1150,7 @@ ServiceBuilder< Ok(Service { client, - task_manager: tasks_builder.into_task_manager(config.task_executor.ok_or(Error::TaskExecutorRequired)?), + task_manager: tasks_builder.into_task_manager(config.task_executor), network, network_status_sinks, select_chain, diff --git a/client/service/src/config.rs b/client/service/src/config.rs index 109ff1bfd5..0515a31c7c 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -18,60 +18,35 @@ pub use sc_client::ExecutionStrategies; pub use sc_client_db::{kvdb::KeyValueDB, PruningMode}; -pub use sc_network::{Multiaddr, config::{MultiaddrWithPeerId, ExtTransport, NetworkConfiguration, Role}}; +pub use sc_network::Multiaddr; +pub use sc_network::config::{ExtTransport, MultiaddrWithPeerId, NetworkConfiguration, Role, NodeKeyConfig}; pub use sc_executor::WasmExecutionMethod; use std::{future::Future, path::{PathBuf, Path}, pin::Pin, net::SocketAddr, sync::Arc}; pub use sc_transaction_pool::txpool::Options as TransactionPoolOptions; use sc_chain_spec::ChainSpec; use sp_core::crypto::Protected; -use target_info::Target; -use sc_telemetry::TelemetryEndpoints; +pub use sc_telemetry::TelemetryEndpoints; use prometheus_endpoint::Registry; -/// Executable version. Used to pass version information from the root crate. -#[derive(Clone)] -pub struct VersionInfo { - /// Implementation name. - pub name: &'static str, - /// Implementation version. - pub version: &'static str, - /// SCM Commit hash. - pub commit: &'static str, - /// Executable file name. - pub executable_name: &'static str, - /// Executable file description. - pub description: &'static str, - /// Executable file author. - pub author: &'static str, - /// Support URL. - pub support_url: &'static str, - /// Copyright starting year (x-current year) - pub copyright_start_year: i32, -} - /// Service configuration. pub struct Configuration { /// Implementation name pub impl_name: &'static str, - /// Implementation version + /// Implementation version (see sc-cli to see an example of format) pub impl_version: &'static str, - /// Git commit if any. - pub impl_commit: &'static str, /// Node role. pub role: Role, /// How to spawn background tasks. Mandatory, otherwise creating a `Service` will error. - pub task_executor: Option + Send>>) + Send + Sync>>, + pub task_executor: Arc + Send>>) + Send + Sync>, /// Extrinsic pool configuration. pub transaction_pool: TransactionPoolOptions, /// Network configuration. pub network: NetworkConfiguration, - /// Path to the base configuration directory. - pub config_dir: Option, /// Configuration for the keystore. pub keystore: KeystoreConfig, /// Configuration for the database. - pub database: Option, + pub database: DatabaseConfig, /// Size of internal state cache in Bytes pub state_cache_size: usize, /// Size in percent of cache size dedicated to child tries @@ -79,9 +54,7 @@ pub struct Configuration { /// Pruning settings. pub pruning: PruningMode, /// Chain configuration. - pub chain_spec: Option>, - /// Node name. - pub name: String, + pub chain_spec: Box, /// Wasm execution method. pub wasm_method: WasmExecutionMethod, /// Execution strategies. @@ -130,8 +103,6 @@ pub struct Configuration { /// Configuration of the client keystore. #[derive(Clone)] pub enum KeystoreConfig { - /// No config supplied. - None, /// Keystore at a path on-disk. Recommended for native nodes. Path { /// The path of the keystore. @@ -147,8 +118,8 @@ impl KeystoreConfig { /// Returns the path for the keystore. pub fn path(&self) -> Option<&Path> { match self { - Self::Path { path, .. } => Some(&path), - Self::None | Self::InMemory => None, + Self::Path { path, .. } => Some(path), + Self::InMemory => None, } } } @@ -161,7 +132,7 @@ pub enum DatabaseConfig { /// Path to the database. path: PathBuf, /// Cache Size for internal database in MiB - cache_size: Option, + cache_size: usize, }, /// A custom implementation of an already-open database. @@ -190,123 +161,9 @@ impl PrometheusConfig { } } -impl Default for Configuration { - /// Create a default config - fn default() -> Self { - Configuration { - impl_name: "parity-substrate", - impl_version: "0.0.0", - impl_commit: "", - chain_spec: None, - config_dir: None, - name: Default::default(), - role: Role::Full, - task_executor: None, - transaction_pool: Default::default(), - network: Default::default(), - keystore: KeystoreConfig::None, - database: None, - state_cache_size: Default::default(), - state_cache_child_ratio: Default::default(), - pruning: PruningMode::default(), - wasm_method: WasmExecutionMethod::Interpreted, - execution_strategies: Default::default(), - rpc_http: None, - rpc_ws: None, - rpc_ws_max_connections: None, - rpc_cors: Some(vec![]), - prometheus_config: None, - telemetry_endpoints: None, - telemetry_external_transport: None, - default_heap_pages: None, - offchain_worker: Default::default(), - force_authoring: false, - disable_grandpa: false, - dev_key_seed: None, - tracing_targets: Default::default(), - tracing_receiver: Default::default(), - max_runtime_instances: 8, - announce_block: true, - } - } -} - impl Configuration { - /// Create a default config using `VersionInfo` - pub fn from_version(version: &VersionInfo) -> Self { - let mut config = Configuration::default(); - config.impl_name = version.name; - config.impl_version = version.version; - config.impl_commit = version.commit; - - config - } - - /// Returns full version string of this configuration. - pub fn full_version(&self) -> String { - full_version_from_strs(self.impl_version, self.impl_commit) - } - - /// Implementation id and version. - pub fn client_id(&self) -> String { - format!("{}/v{}", self.impl_name, self.full_version()) - } - - /// Generate a PathBuf to sub in the chain configuration directory - /// if given - pub fn in_chain_config_dir(&self, sub: &str) -> Option { - self.config_dir.clone().map(|mut path| { - path.push("chains"); - path.push(self.expect_chain_spec().id()); - path.push(sub); - path - }) - } - - /// Return a reference to the `ChainSpec` of this `Configuration`. - /// - /// ### Panics - /// - /// This method panic if the `chain_spec` is `None` - pub fn expect_chain_spec(&self) -> &dyn ChainSpec { - &**self.chain_spec.as_ref().expect("chain_spec must be specified") - } - - /// Return a reference to the `DatabaseConfig` of this `Configuration`. - /// - /// ### Panics - /// - /// This method panic if the `database` is `None` - pub fn expect_database(&self) -> &DatabaseConfig { - self.database.as_ref().expect("database must be specified") - } - /// Returns a string displaying the node role. pub fn display_role(&self) -> String { self.role.to_string() } - - /// Use in memory keystore config when it is not required at all. - /// - /// This function returns an error if the keystore is already set to something different than - /// `KeystoreConfig::None`. - pub fn use_in_memory_keystore(&mut self) -> Result<(), String> { - match &mut self.keystore { - cfg @ KeystoreConfig::None => { *cfg = KeystoreConfig::InMemory; Ok(()) }, - _ => Err("Keystore config specified when it should not be!".into()), - } - } -} - -/// Returns platform info -pub fn platform() -> String { - let env = Target::env(); - let env_dash = if env.is_empty() { "" } else { "-" }; - format!("{}-{}{}{}", Target::arch(), Target::os(), env_dash, env) -} - -/// Returns full version string, using supplied version and commit. -pub fn full_version_from_strs(impl_version: &str, impl_commit: &str) -> String { - let commit_dash = if impl_commit.is_empty() { "" } else { "-" }; - format!("{}{}{}-{}", impl_version, commit_dash, impl_commit, platform()) } diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 0ceb310d07..16b1d0d718 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -61,7 +61,8 @@ pub use self::builder::{ }; pub use config::{Configuration, Role, PruningMode, DatabaseConfig}; pub use sc_chain_spec::{ - ChainSpec, GenericChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension + ChainSpec, GenericChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension, + NoExtension, }; pub use sp_transaction_pool::{TransactionPool, InPoolTransaction, error::IntoPoolError}; pub use sc_transaction_pool::txpool::Options as TransactionPoolOptions; @@ -72,6 +73,7 @@ pub use sc_executor::NativeExecutionDispatch; pub use std::{ops::Deref, result::Result, sync::Arc}; #[doc(hidden)] pub use sc_network::config::{FinalityProofProvider, OnDemand, BoxFinalityProofRequestBuilder}; +pub use sc_tracing::TracingReceiver; pub use task_manager::{TaskManagerBuilder, SpawnTaskHandle}; use task_manager::TaskManager; diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index d63fd4009e..bb5ef09562 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -38,7 +38,7 @@ use sc_service::{ Error, }; use sc_network::{multiaddr, Multiaddr, NetworkStateInfo}; -use sc_network::config::{NetworkConfiguration, TransportConfig, NodeKeyConfig, Secret, NonReservedPeerMode}; +use sc_network::config::{NetworkConfiguration, TransportConfig}; use sp_runtime::{generic::BlockId, traits::Block as BlockT}; use sp_transaction_pool::TransactionPool; @@ -143,57 +143,46 @@ fn node_config 2.0.0-alpha.5 Runtime @@ -51,4 +55,4 @@ API * client/authority-discovery: Instrument code with Prometheus (#5195) * Don't include `:code` by default in storage proofs (#5179) * client/network-gossip: Merge GossipEngine and GossipEngineInner (#5042) -* Introduce `on_runtime_upgrade` (#5058) \ No newline at end of file +* Introduce `on_runtime_upgrade` (#5058) diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index c20cdfa4f8..d1eb924d0d 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -90,3 +90,7 @@ # Prometheus endpoint /utils/prometheus/ @mxinden + +# CLI API +/client/cli @cecton +/client/cli-derive @cecton diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index 80dfa5e2d2..8bed06eee9 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -17,8 +17,10 @@ use futures01::sync::mpsc as mpsc01; use log::{debug, info}; use std::sync::Arc; +use sc_network::config::TransportConfig; use sc_service::{ - AbstractService, RpcSession, Role, Configuration, config::{DatabaseConfig, KeystoreConfig}, + AbstractService, RpcSession, Role, Configuration, + config::{DatabaseConfig, KeystoreConfig, NetworkConfiguration}, GenericChainSpec, RuntimeGenesis }; use wasm_bindgen::prelude::*; @@ -43,29 +45,57 @@ where let name = chain_spec.name().to_string(); let transport = ExtTransport::new(ffi::websocket_transport()); - let mut config = Configuration::default(); - config.network.boot_nodes = chain_spec.boot_nodes().to_vec(); - config.telemetry_endpoints = chain_spec.telemetry_endpoints().clone(); - config.chain_spec = Some(Box::new(chain_spec)); - config.network.transport = sc_network::config::TransportConfig::Normal { + let mut network = NetworkConfiguration::new( + format!("{} (Browser)", name), + "unknown", + Default::default(), + &std::env::current_dir().expect("current directory must exist"), + ); + network.boot_nodes = chain_spec.boot_nodes().to_vec(); + network.transport = TransportConfig::Normal { wasm_external_transport: Some(transport.clone()), allow_private_ipv4: true, enable_mdns: false, use_yamux_flow_control: true, }; - config.task_executor = Some(Arc::new(move |fut| { - wasm_bindgen_futures::spawn_local(fut) - })); - config.telemetry_external_transport = Some(transport); - config.role = Role::Light; - config.name = format!("{} (Browser)", name); - config.database = Some({ - info!("Opening Indexed DB database '{}'...", name); - let db = kvdb_web::Database::open(name, 10) - .await?; - DatabaseConfig::Custom(Arc::new(db)) - }); - config.keystore = KeystoreConfig::InMemory; + + let config = Configuration { + network, + telemetry_endpoints: chain_spec.telemetry_endpoints().clone(), + chain_spec: Box::new(chain_spec), + task_executor: Arc::new(move |fut| wasm_bindgen_futures::spawn_local(fut)), + telemetry_external_transport: Some(transport), + role: Role::Light, + database: { + info!("Opening Indexed DB database '{}'...", name); + let db = kvdb_web::Database::open(name, 10).await?; + + DatabaseConfig::Custom(Arc::new(db)) + }, + keystore: KeystoreConfig::InMemory, + default_heap_pages: Default::default(), + dev_key_seed: Default::default(), + disable_grandpa: Default::default(), + execution_strategies: Default::default(), + force_authoring: Default::default(), + impl_name: "parity-substrate", + impl_version: "0.0.0", + offchain_worker: Default::default(), + prometheus_config: Default::default(), + pruning: Default::default(), + rpc_cors: Default::default(), + rpc_http: Default::default(), + rpc_ws: Default::default(), + rpc_ws_max_connections: Default::default(), + state_cache_child_ratio: Default::default(), + state_cache_size: Default::default(), + tracing_receiver: Default::default(), + tracing_targets: Default::default(), + transaction_pool: Default::default(), + wasm_method: Default::default(), + max_runtime_instances: 8, + announce_block: true, + }; Ok(config) } diff --git a/utils/build-script-utils/Cargo.toml b/utils/build-script-utils/Cargo.toml index 3fe10f6a82..637d50d19d 100644 --- a/utils/build-script-utils/Cargo.toml +++ b/utils/build-script-utils/Cargo.toml @@ -9,6 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "Crate with utility functions for `build.rs` scripts." [dependencies] +platforms = "0.2.1" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/build-script-utils/src/git.rs b/utils/build-script-utils/src/git.rs new file mode 100644 index 0000000000..919c4813ab --- /dev/null +++ b/utils/build-script-utils/src/git.rs @@ -0,0 +1,123 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use std::{env, fs, fs::File, io, io::Read, path::PathBuf}; + +/// Make sure the calling `build.rs` script is rerun when `.git/HEAD` changed. +/// +/// The file is searched from the `CARGO_MANIFEST_DIR` upwards. If the file can not be found, +/// a warning is generated. +pub fn rerun_if_git_head_changed() { + let mut manifest_dir = PathBuf::from( + env::var("CARGO_MANIFEST_DIR").expect("`CARGO_MANIFEST_DIR` is always set by cargo."), + ); + let manifest_dir_copy = manifest_dir.clone(); + + while manifest_dir.parent().is_some() { + match get_git_paths(&manifest_dir) { + Err(err) => { + eprintln!("cargo:warning=Unable to read the Git repository: {}", err); + + return; + } + Ok(None) => {} + Ok(Some(paths)) => { + for p in paths { + println!("cargo:rerun-if-changed={}", p.display()); + } + + return; + } + } + + manifest_dir.pop(); + } + + println!( + "cargo:warning=Could not find `.git/HEAD` searching from `{}` upwards!", + manifest_dir_copy.display(), + ); +} + +// Code taken from https://github.com/rustyhorde/vergen/blob/8d522db8c8e16e26c0fc9ea8e6b0247cbf5cca84/src/output/envvar.rs +fn get_git_paths(path: &PathBuf) -> Result>, io::Error> { + let git_dir_or_file = path.join(".git"); + + if let Ok(metadata) = fs::metadata(&git_dir_or_file) { + if metadata.is_dir() { + // Echo the HEAD path + let git_head_path = git_dir_or_file.join("HEAD"); + + // Determine where HEAD points and echo that path also. + let mut f = File::open(&git_head_path)?; + let mut git_head_contents = String::new(); + let _ = f.read_to_string(&mut git_head_contents)?; + let ref_vec: Vec<&str> = git_head_contents.split(": ").collect(); + + if ref_vec.len() == 2 { + let current_head_file = ref_vec[1]; + let git_refs_path = PathBuf::from(".git").join(current_head_file); + + Ok(Some(vec![git_head_path, git_refs_path])) + } else { + Err(io::Error::new( + io::ErrorKind::Other, + "You are most likely in a detached HEAD state", + )) + } + } else if metadata.is_file() { + // We are in a worktree, so find out where the actual worktrees//HEAD file is. + let mut git_file = File::open(&git_dir_or_file)?; + let mut git_contents = String::new(); + let _ = git_file.read_to_string(&mut git_contents)?; + let dir_vec: Vec<&str> = git_contents.split(": ").collect(); + let git_path = dir_vec[1].trim(); + + // Echo the HEAD psth + let git_head_path = PathBuf::from(git_path).join("HEAD"); + + // Find out what the full path to the .git dir is. + let mut actual_git_dir = PathBuf::from(git_path); + actual_git_dir.pop(); + actual_git_dir.pop(); + + // Determine where HEAD points and echo that path also. + let mut f = File::open(&git_head_path)?; + let mut git_head_contents = String::new(); + let _ = f.read_to_string(&mut git_head_contents)?; + let ref_vec: Vec<&str> = git_head_contents.split(": ").collect(); + + if ref_vec.len() == 2 { + let current_head_file = ref_vec[1]; + let git_refs_path = actual_git_dir.join(current_head_file); + + Ok(Some(vec![git_head_path, git_refs_path])) + } else { + Err(io::Error::new( + io::ErrorKind::Other, + "You are most likely in a detached HEAD state", + )) + } + } else { + Err(io::Error::new( + io::ErrorKind::Other, + "Invalid .git format (Not a directory or a file)", + )) + } + } else { + Ok(None) + } +} diff --git a/utils/build-script-utils/src/lib.rs b/utils/build-script-utils/src/lib.rs index 1b915bdcaf..57a1e7c5cd 100644 --- a/utils/build-script-utils/src/lib.rs +++ b/utils/build-script-utils/src/lib.rs @@ -16,29 +16,8 @@ //! Crate with utility functions for `build.rs` scripts. -use std::{env, path::PathBuf}; +mod version; +mod git; -/// Make sure the calling `build.rs` script is rerun when `.git/HEAD` changed. -/// -/// The file is searched from the `CARGO_MANIFEST_DIR` upwards. If the file can not be found, -/// a warning is generated. -pub fn rerun_if_git_head_changed() { - let mut manifest_dir = PathBuf::from( - env::var("CARGO_MANIFEST_DIR").expect("`CARGO_MANIFEST_DIR` is always set by cargo.") - ); - let manifest_dir_copy = manifest_dir.clone(); - - while manifest_dir.parent().is_some() { - if manifest_dir.join(".git/HEAD").exists() { - println!("cargo:rerun-if-changed={}", manifest_dir.join(".git/HEAD").display()); - return - } - - manifest_dir.pop(); - } - - println!( - "cargo:warning=Could not find `.git/HEAD` searching from `{}` upwards!", - manifest_dir_copy.display(), - ); -} +pub use git::*; +pub use version::*; diff --git a/utils/build-script-utils/src/version.rs b/utils/build-script-utils/src/version.rs new file mode 100644 index 0000000000..d41538707c --- /dev/null +++ b/utils/build-script-utils/src/version.rs @@ -0,0 +1,59 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use platforms::*; +use std::process::Command; + +/// Generate the `cargo:` key output +pub fn generate_cargo_keys() { + let output = Command::new("git") + .args(&["rev-parse", "--short", "HEAD"]) + .output(); + + match output { + Ok(o) if o.status.success() => { + let sha = String::from_utf8_lossy(&o.stdout).trim().to_owned(); + + println!("cargo:rustc-env=SUBSTRATE_CLI_IMPL_VERSION={}", get_version(sha.as_str())) + } + Ok(o) => eprintln!("cargo:warning=Git command failed with status: {}", o.status), + Err(err) => eprintln!("cargo:warning=Failed to execute git command: {}", err), + } +} + +fn get_platform() -> String { + let env_dash = if TARGET_ENV.is_some() { "-" } else { "" }; + + format!( + "{}-{}{}{}", + TARGET_ARCH.as_str(), + TARGET_OS.as_str(), + env_dash, + TARGET_ENV.map(|x| x.as_str()).unwrap_or(""), + ) +} + +fn get_version(impl_commit: &str) -> String { + let commit_dash = if impl_commit.is_empty() { "" } else { "-" }; + + format!( + "{}{}{}-{}", + std::env::var("CARGO_PKG_VERSION").unwrap_or_default(), + commit_dash, + impl_commit, + get_platform(), + ) +} diff --git a/utils/frame/benchmarking-cli/src/command.rs b/utils/frame/benchmarking-cli/src/command.rs new file mode 100644 index 0000000000..5e35d57cda --- /dev/null +++ b/utils/frame/benchmarking-cli/src/command.rs @@ -0,0 +1,141 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use crate::BenchmarkCmd; +use codec::{Decode, Encode}; +use frame_benchmarking::{Analysis, BenchmarkBatch}; +use sc_cli::{SharedParams, CliConfiguration, ExecutionStrategy, Result}; +use sc_client::StateMachine; +use sc_client_db::BenchmarkingState; +use sc_executor::NativeExecutor; +use sp_externalities::Extensions; +use sc_service::{Configuration, NativeExecutionDispatch}; +use sp_runtime::{ + traits::{Block as BlockT, Header as HeaderT, NumberFor}, +}; +use sp_core::{tasks, testing::KeyStore, traits::KeystoreExt}; +use std::fmt::Debug; + +impl BenchmarkCmd { + /// Runs the command and benchmarks the chain. + pub fn run(&self, config: Configuration) -> Result<()> + where + BB: BlockT + Debug, + <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, + ::Hash: std::str::FromStr, + ExecDispatch: NativeExecutionDispatch + 'static, + { + let spec = config.chain_spec; + let wasm_method = self.wasm_method.into(); + let strategy = self.execution.unwrap_or(ExecutionStrategy::Native); + + let genesis_storage = spec.build_storage()?; + let mut changes = Default::default(); + let cache_size = Some(self.database_cache_size as usize); + let state = BenchmarkingState::::new(genesis_storage, cache_size)?; + let executor = NativeExecutor::::new( + wasm_method, + None, // heap pages + 2, // The runtime instances cache size. + ); + + let mut extensions = Extensions::default(); + extensions.register(KeystoreExt(KeyStore::new())); + + let result = StateMachine::<_, _, NumberFor, _>::new( + &state, + None, + &mut changes, + &executor, + "Benchmark_dispatch_benchmark", + &( + &self.pallet, + &self.extrinsic, + self.lowest_range_values.clone(), + self.highest_range_values.clone(), + self.steps.clone(), + self.repeat, + ).encode(), + extensions, + &sp_state_machine::backend::BackendRuntimeCode::new(&state).runtime_code()?, + tasks::executor(), + ) + .execute(strategy.into()) + .map_err(|e| format!("Error executing runtime benchmark: {:?}", e))?; + + let results = , String> as Decode>::decode(&mut &result[..]) + .map_err(|e| format!("Failed to decode benchmark results: {:?}", e))?; + + match results { + Ok(batches) => for batch in batches.into_iter() { + // Print benchmark metadata + println!( + "Pallet: {:?}, Extrinsic: {:?}, Lowest values: {:?}, Highest values: {:?}, Steps: {:?}, Repeat: {:?}", + String::from_utf8(batch.pallet).expect("Encoded from String; qed"), + String::from_utf8(batch.benchmark).expect("Encoded from String; qed"), + self.lowest_range_values, + self.highest_range_values, + self.steps, + self.repeat, + ); + + if self.raw_data { + // Print the table header + batch.results[0].0.iter().for_each(|param| print!("{:?},", param.0)); + + print!("extrinsic_time,storage_root_time\n"); + // Print the values + batch.results.iter().for_each(|result| { + let parameters = &result.0; + parameters.iter().for_each(|param| print!("{:?},", param.1)); + // Print extrinsic time and storage root time + print!("{:?},{:?}\n", result.1, result.2); + }); + + println!(); + } + + // Conduct analysis. + if !self.no_median_slopes { + if let Some(analysis) = Analysis::median_slopes(&batch.results) { + println!("Median Slopes Analysis\n========\n{}", analysis); + } + } + if !self.no_min_squares { + if let Some(analysis) = Analysis::min_squares_iqr(&batch.results) { + println!("Min Squares Analysis\n========\n{}", analysis); + } + } + }, + Err(error) => eprintln!("Error: {:?}", error), + } + + Ok(()) + } +} + +impl CliConfiguration for BenchmarkCmd { + fn shared_params(&self) -> &SharedParams { + &self.shared_params + } + + fn chain_id(&self, _is_dev: bool) -> Result { + Ok(match self.shared_params.chain { + Some(ref chain) => chain.clone(), + None => "dev".into(), + }) + } +} diff --git a/utils/frame/benchmarking-cli/src/lib.rs b/utils/frame/benchmarking-cli/src/lib.rs index 926d140e02..96204d1ae5 100644 --- a/utils/frame/benchmarking-cli/src/lib.rs +++ b/utils/frame/benchmarking-cli/src/lib.rs @@ -14,21 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +mod command; + +use sc_cli::{ExecutionStrategy, WasmExecutionMethod}; use std::fmt::Debug; -use sp_runtime::{traits::{Block as BlockT, Header as HeaderT, NumberFor}}; -use sc_client::StateMachine; -use sc_cli::{ExecutionStrategy, WasmExecutionMethod, VersionInfo}; -use sc_client_db::BenchmarkingState; -use sc_service::{Configuration, ChainSpec}; -use sc_executor::{NativeExecutor, NativeExecutionDispatch}; -use codec::{Encode, Decode}; -use frame_benchmarking::{BenchmarkBatch, Analysis}; -use sp_core::{ - tasks, - traits::KeystoreExt, - testing::KeyStore, -}; -use sp_externalities::Extensions; /// The `benchmark` command used to benchmark FRAME Pallets. #[derive(Debug, structopt::StructOpt, Clone)] @@ -96,128 +85,3 @@ pub struct BenchmarkCmd { #[structopt(long = "db-cache", value_name = "MiB", default_value = "128")] pub database_cache_size: u32, } - -impl BenchmarkCmd { - /// Initialize - pub fn init(&self, version: &sc_cli::VersionInfo) -> sc_cli::Result<()> { - self.shared_params.init(version) - } - - /// Runs the command and benchmarks the chain. - pub fn run( - self, - config: Configuration, - ) -> sc_cli::Result<()> - where - BB: BlockT + Debug, - <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, - ::Hash: std::str::FromStr, - ExecDispatch: NativeExecutionDispatch + 'static, - { - let spec = config.chain_spec.expect("chain_spec is always Some"); - let wasm_method = self.wasm_method.into(); - let strategy = self.execution.unwrap_or(ExecutionStrategy::Native); - - let genesis_storage = spec.build_storage()?; - let mut changes = Default::default(); - let cache_size = Some(self.database_cache_size as usize); - let state = BenchmarkingState::::new(genesis_storage, cache_size)?; - let executor = NativeExecutor::::new( - wasm_method, - None, // heap pages - 2, // The runtime instances cache size. - ); - - let mut extensions = Extensions::default(); - extensions.register(KeystoreExt(KeyStore::new())); - - let result = StateMachine::<_, _, NumberFor, _>::new( - &state, - None, - &mut changes, - &executor, - "Benchmark_dispatch_benchmark", - &( - &self.pallet, - &self.extrinsic, - self.lowest_range_values.clone(), - self.highest_range_values.clone(), - self.steps.clone(), - self.repeat, - ).encode(), - extensions, - &sp_state_machine::backend::BackendRuntimeCode::new(&state).runtime_code()?, - tasks::executor(), - ) - .execute(strategy.into()) - .map_err(|e| format!("Error executing runtime benchmark: {:?}", e))?; - - let results = , String> as Decode>::decode(&mut &result[..]) - .map_err(|e| format!("Failed to decode benchmark results: {:?}", e))?; - - match results { - Ok(batches) => for batch in batches.into_iter() { - // Print benchmark metadata - println!( - "Pallet: {:?}, Extrinsic: {:?}, Lowest values: {:?}, Highest values: {:?}, Steps: {:?}, Repeat: {:?}", - String::from_utf8(batch.pallet).expect("Encoded from String; qed"), - String::from_utf8(batch.benchmark).expect("Encoded from String; qed"), - self.lowest_range_values, - self.highest_range_values, - self.steps, - self.repeat, - ); - - if self.raw_data { - // Print the table header - batch.results[0].0.iter().for_each(|param| print!("{:?},", param.0)); - - print!("extrinsic_time,storage_root_time\n"); - // Print the values - batch.results.iter().for_each(|result| { - let parameters = &result.0; - parameters.iter().for_each(|param| print!("{:?},", param.1)); - // Print extrinsic time and storage root time - print!("{:?},{:?}\n", result.1, result.2); - }); - - print!("\n"); - } - - // Conduct analysis. - if !self.no_median_slopes { - if let Some(analysis) = Analysis::median_slopes(&batch.results) { - println!("Median Slopes Analysis\n========\n{}", analysis); - } - } - if !self.no_min_squares { - if let Some(analysis) = Analysis::min_squares_iqr(&batch.results) { - println!("Min Squares Analysis\n========\n{}", analysis); - } - } - }, - Err(error) => eprintln!("Error: {:?}", error), - } - - Ok(()) - } - - /// Update and prepare a `Configuration` with command line parameters - pub fn update_config( - &self, - mut config: &mut Configuration, - spec_factory: impl FnOnce(&str) -> Result, String>, - _version: &VersionInfo, - ) -> sc_cli::Result<()> - { - // Configure chain spec. - let chain_key = self.shared_params.chain.clone().unwrap_or("dev".into()); - let spec = spec_factory(&chain_key)?; - config.chain_spec = Some(spec); - - // Make sure to configure keystore. - config.use_in_memory_keystore()?; - - Ok(()) - } -} -- GitLab From 028a71594f93edc1c105c85f425760943a362f8e Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Tue, 7 Apr 2020 12:55:46 +0200 Subject: [PATCH 177/300] More emoji (#5556) --- client/consensus/babe/src/aux_schema.rs | 2 +- client/consensus/slots/src/lib.rs | 2 +- client/finality-grandpa/src/aux_schema.rs | 2 +- client/network/src/service.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/consensus/babe/src/aux_schema.rs b/client/consensus/babe/src/aux_schema.rs index 6f69e65940..e014c8975a 100644 --- a/client/consensus/babe/src/aux_schema.rs +++ b/client/consensus/babe/src/aux_schema.rs @@ -74,7 +74,7 @@ pub(crate) fn load_epoch_changes( let epoch_changes = Arc::new(Mutex::new(maybe_epoch_changes.unwrap_or_else(|| { info!(target: "babe", - "Creating empty BABE epoch changes on what appears to be first startup." + "👶 Creating empty BABE epoch changes on what appears to be first startup." ); EpochChangesFor::::default() }))); diff --git a/client/consensus/slots/src/lib.rs b/client/consensus/slots/src/lib.rs index d0f1f6ec4b..5952856bda 100644 --- a/client/consensus/slots/src/lib.rs +++ b/client/consensus/slots/src/lib.rs @@ -466,7 +466,7 @@ impl SlotDuration { cb(client.runtime_api(), &BlockId::number(Zero::zero()))?; info!( - "Loaded block-time = {:?} milliseconds from genesis on first-launch", + "⏱ Loaded block-time = {:?} milliseconds from genesis on first-launch", genesis_slot_duration ); diff --git a/client/finality-grandpa/src/aux_schema.rs b/client/finality-grandpa/src/aux_schema.rs index 525a4a99ba..fe652f52fe 100644 --- a/client/finality-grandpa/src/aux_schema.rs +++ b/client/finality-grandpa/src/aux_schema.rs @@ -330,7 +330,7 @@ pub(crate) fn load_persistent( } // genesis. - info!(target: "afg", "Loading GRANDPA authority set \ + info!(target: "afg", "👴 Loading GRANDPA authority set \ from genesis on what appears to be first startup."); let genesis_authorities = genesis_authorities()?; diff --git a/client/network/src/service.rs b/client/network/src/service.rs index d3a72a3ff6..ef2aa0aa23 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -1069,7 +1069,7 @@ impl Future for NetworkWorker { && error.contains("Peer ID mismatch") { error!( - "Connecting to bootnode with peer id `{}` and address `{}` failed \ + "💔 Connecting to bootnode with peer id `{}` and address `{}` failed \ because it returned a different peer id!", peer_id, address, -- GitLab From 7ab4ba1f7f39f453dda4903574f1f6bf8f6bbc9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 7 Apr 2020 19:31:45 +0200 Subject: [PATCH 178/300] Make `application-crypto` `std` feature internal (#5558) * Make `application-crypto` `std` feature internal The macros should not generate code that requires that the calling crate has a feature with the name `std` defined. * Use a proper panic! --- primitives/application-crypto/src/lib.rs | 134 +++++++++++++++-------- primitives/phragmen/src/reduce.rs | 2 +- 2 files changed, 89 insertions(+), 47 deletions(-) diff --git a/primitives/application-crypto/src/lib.rs b/primitives/application-crypto/src/lib.rs index 07e2b45106..79572eb49d 100644 --- a/primitives/application-crypto/src/lib.rs +++ b/primitives/application-crypto/src/lib.rs @@ -103,17 +103,8 @@ macro_rules! app_crypto_pair { type Signature = Signature; type DeriveError = <$pair as $crate::Pair>::DeriveError; - #[cfg(feature = "std")] - fn generate_with_phrase(password: Option<&str>) -> (Self, String, Self::Seed) { - let r = <$pair>::generate_with_phrase(password); - (Self(r.0), r.1, r.2) - } - #[cfg(feature = "std")] - fn from_phrase(phrase: &str, password: Option<&str>) - -> Result<(Self, Self::Seed), $crate::SecretStringError> - { - <$pair>::from_phrase(phrase, password).map(|r| (Self(r.0), r.1)) - } + $crate::app_crypto_pair_functions_if_std!($pair); + fn derive< Iter: Iterator >(&self, path: Iter, seed: Option) -> Result<(Self, Option), Self::DeriveError> { @@ -158,10 +149,38 @@ macro_rules! app_crypto_pair { }; } +/// Implements functions for the `Pair` trait when `feature = "std"` is enabled. +#[doc(hidden)] +#[cfg(feature = "std")] +#[macro_export] +macro_rules! app_crypto_pair_functions_if_std { + ($pair:ty) => { + fn generate_with_phrase(password: Option<&str>) -> (Self, String, Self::Seed) { + let r = <$pair>::generate_with_phrase(password); + (Self(r.0), r.1, r.2) + } + + fn from_phrase(phrase: &str, password: Option<&str>) + -> Result<(Self, Self::Seed), $crate::SecretStringError> + { + <$pair>::from_phrase(phrase, password).map(|r| (Self(r.0), r.1)) + } + } +} + +#[doc(hidden)] +#[cfg(not(feature = "std"))] +#[macro_export] +macro_rules! app_crypto_pair_functions_if_std { + ($pair:ty) => {} +} + + /// Declares Public type which is functionally equivalent to `$public`, but is new /// Application-specific type whose identifier is `$key_type`. /// can only be used together with `full_crypto` feature /// For full functionality, app_crypto_public_common! must be called too. +#[doc(hidden)] #[macro_export] macro_rules! app_crypto_public_full_crypto { ($public:ty, $key_type:expr) => { @@ -195,6 +214,7 @@ macro_rules! app_crypto_public_full_crypto { /// Application-specific type whose identifier is `$key_type`. /// can only be used without `full_crypto` feature /// For full functionality, app_crypto_public_common! must be called too. +#[doc(hidden)] #[macro_export] macro_rules! app_crypto_public_not_full_crypto { ($public:ty, $key_type:expr) => { @@ -223,44 +243,11 @@ macro_rules! app_crypto_public_not_full_crypto { /// Declares Public type which is functionally equivalent to `$public`, but is new /// Application-specific type whose identifier is `$key_type`. /// For full functionality, app_crypto_public_(not)_full_crypto! must be called too. +#[doc(hidden)] #[macro_export] macro_rules! app_crypto_public_common { ($public:ty, $sig:ty, $key_type:expr) => { - impl $crate::Derive for Public { - #[cfg(feature = "std")] - fn derive>(&self, - path: Iter - ) -> Option { - self.0.derive(path).map(Self) - } - } - - #[cfg(feature = "std")] - impl std::fmt::Display for Public { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - use $crate::Ss58Codec; - write!(f, "{}", self.0.to_ss58check()) - } - } - #[cfg(feature = "std")] - impl $crate::serde::Serialize for Public { - fn serialize(&self, serializer: S) -> std::result::Result where - S: $crate::serde::Serializer - { - use $crate::Ss58Codec; - serializer.serialize_str(&self.to_ss58check()) - } - } - #[cfg(feature = "std")] - impl<'de> $crate::serde::Deserialize<'de> for Public { - fn deserialize(deserializer: D) -> std::result::Result where - D: $crate::serde::Deserializer<'de> - { - use $crate::Ss58Codec; - Public::from_ss58check(&String::deserialize(deserializer)?) - .map_err(|e| $crate::serde::de::Error::custom(format!("{:?}", e))) - } - } + $crate::app_crypto_public_common_if_std!(); impl AsRef<[u8]> for Public { fn as_ref(&self) -> &[u8] { self.0.as_ref() } @@ -309,10 +296,63 @@ macro_rules! app_crypto_public_common { } } +/// Implements traits for the public key type if `feature = "std"` is enabled. +#[cfg(feature = "std")] +#[doc(hidden)] +#[macro_export] +macro_rules! app_crypto_public_common_if_std { + () => { + impl $crate::Derive for Public { + fn derive>(&self, + path: Iter + ) -> Option { + self.0.derive(path).map(Self) + } + } + + impl std::fmt::Display for Public { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + use $crate::Ss58Codec; + write!(f, "{}", self.0.to_ss58check()) + } + } + + impl $crate::serde::Serialize for Public { + fn serialize(&self, serializer: S) -> std::result::Result where + S: $crate::serde::Serializer + { + use $crate::Ss58Codec; + serializer.serialize_str(&self.to_ss58check()) + } + } + + impl<'de> $crate::serde::Deserialize<'de> for Public { + fn deserialize(deserializer: D) -> std::result::Result where + D: $crate::serde::Deserializer<'de> + { + use $crate::Ss58Codec; + Public::from_ss58check(&String::deserialize(deserializer)?) + .map_err(|e| $crate::serde::de::Error::custom(format!("{:?}", e))) + } + } + } +} + +#[cfg(not(feature = "std"))] +#[doc(hidden)] +#[macro_export] +macro_rules! app_crypto_public_common_if_std { + () => { + impl $crate::Derive for Public {} + } +} + + /// Declares Signature type which is functionally equivalent to `$sig`, but is new /// Application-specific type whose identifier is `$key_type`. /// can only be used together with `full_crypto` feature /// For full functionality, app_crypto_public_common! must be called too. +#[doc(hidden)] #[macro_export] macro_rules! app_crypto_signature_full_crypto { ($sig:ty, $key_type:expr) => { @@ -345,6 +385,7 @@ macro_rules! app_crypto_signature_full_crypto { /// Application-specific type whose identifier is `$key_type`. /// can only be used without `full_crypto` feature /// For full functionality, app_crypto_public_common! must be called too. +#[doc(hidden)] #[macro_export] macro_rules! app_crypto_signature_not_full_crypto { ($sig:ty, $key_type:expr) => { @@ -372,6 +413,7 @@ macro_rules! app_crypto_signature_not_full_crypto { /// Declares Signature type which is functionally equivalent to `$sig`, but is new /// Application-specific type whose identifier is `$key_type`. /// For full functionality, app_crypto_public_(not)_full_crypto! must be called too. +#[doc(hidden)] #[macro_export] macro_rules! app_crypto_signature_common { ($sig:ty, $key_type:expr) => { diff --git a/primitives/phragmen/src/reduce.rs b/primitives/phragmen/src/reduce.rs index 54a71a7ff2..1f6f6c3b99 100644 --- a/primitives/phragmen/src/reduce.rs +++ b/primitives/phragmen/src/reduce.rs @@ -305,7 +305,7 @@ fn reduce_4(assignments: &mut Vec>) -> u32 { } (false, false) => { // Neither of the edges was removed? impossible. - debug_assert!(false, "Duplicate voter (or other corrupt input)."); + panic!("Duplicate voter (or other corrupt input)."); } } } -- GitLab From 0dc25937f756dec51e176a3b942f5e884c0fc58b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 7 Apr 2020 19:32:21 +0200 Subject: [PATCH 179/300] Fix compilation of service metrics on Windows (#5548) * Fix compilation of service metrics on Windows * Fix browser node * Ahh * Remove duplicate code... --- client/service/src/metrics.rs | 85 ++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/client/service/src/metrics.rs b/client/service/src/metrics.rs index 740a795eda..6b7c32c2d0 100644 --- a/client/service/src/metrics.rs +++ b/client/service/src/metrics.rs @@ -14,23 +14,22 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use std::convert::TryFrom; + use crate::NetworkStatus; use prometheus_endpoint::{register, Gauge, U64, F64, Registry, PrometheusError, Opts, GaugeVec}; use sc_client::ClientInfo; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; -use std::convert::TryFrom; use sp_runtime::traits::{NumberFor, Block, SaturatedConversion, UniqueSaturatedInto}; use sp_transaction_pool::PoolStatus; use sp_utils::metrics::register_globals; -#[cfg(any(windows, unix))] use sysinfo::{self, ProcessExt, SystemExt}; -#[cfg(any(unix, windows))] -use netstat2::{TcpState, ProtocolSocketInfo, iterate_sockets_info, AddressFamilyFlags, ProtocolFlags}; - -#[cfg(target_os = "linux")] -use procfs; +#[cfg(not(target_os = "unknown"))] +use netstat2::{ + TcpState, ProtocolSocketInfo, iterate_sockets_info, AddressFamilyFlags, ProtocolFlags, +}; struct PrometheusMetrics { // system @@ -42,7 +41,7 @@ struct PrometheusMetrics { memory_usage_bytes: Gauge, threads: Gauge, open_files: GaugeVec, - + #[cfg(any(unix, windows))] netstat: GaugeVec, @@ -71,13 +70,13 @@ impl PrometheusMetrics { .const_label("name", name) .const_label("version", version) )?, ®istry)?.set(1); - + register(Gauge::::new( "node_roles", "The roles the node is running as", )?, ®istry)?.set(roles); register_globals(registry)?; - + Ok(Self { // system #[cfg(any(unix, windows))] @@ -113,7 +112,6 @@ impl PrometheusMetrics { // --- internal // generic internals - block_height: register(GaugeVec::new( Opts::new("block_height", "Block height info of the chain"), &["status"] @@ -128,7 +126,6 @@ impl PrometheusMetrics { )?, registry)?, // I/ O - network_per_sec_bytes: register(GaugeVec::new( Opts::new("network_per_sec_bytes", "Networking bytes per second"), &["direction"] @@ -179,9 +176,9 @@ struct ProcessInfo { pub struct MetricsService { metrics: Option, - #[cfg(any(windows, unix))] + #[cfg(not(target_os = "unknown"))] system: sysinfo::System, - pid: Option, + pid: Option, } #[cfg(target_os = "linux")] @@ -196,12 +193,14 @@ impl MetricsService { pid: Some(process.pid), } } + fn process_info(&mut self) -> ProcessInfo { let pid = self.pid.clone().expect("unix always has a pid. qed"); - let mut info = self._process_info_for(&pid); + let mut info = self.process_info_for(&pid); let process = procfs::process::Process::new(pid).expect("Our process exists. qed."); info.threads = process.stat().ok().map(|s| - u64::try_from(s.num_threads).expect("There are no negative thread counts. qed")); + u64::try_from(s.num_threads).expect("There are no negative thread counts. qed"), + ); info.open_fd = process.fd().ok().map(|i| i.into_iter().fold(FdCounter::default(), |mut f, info| { match info.target { @@ -218,7 +217,6 @@ impl MetricsService { ); info } - } #[cfg(all(any(unix, windows), not(target_os = "linux")))] @@ -227,24 +225,25 @@ impl MetricsService { Self { metrics, system: sysinfo::System::new(), - pid: sysinfo::get_current_pid().ok() + pid: sysinfo::get_current_pid().ok(), } } - + fn process_info(&mut self) -> ProcessInfo { - self.pid.map(|pid| self._process_info_for(&pid)).unwrap_or_else(ProcessInfo::default) + self.pid.map(|pid| self.process_info_for(&pid)).unwrap_or_default() } } -#[cfg(not(any(unix, windows)))] + +#[cfg(target_os = "unknown")] impl MetricsService { fn inner_new(metrics: Option) -> Self { Self { metrics, - pid: None + pid: None, } } - + fn process_info(&mut self) -> ProcessInfo { ProcessInfo::default() } @@ -252,7 +251,6 @@ impl MetricsService { impl MetricsService { - pub fn with_prometheus(registry: &Registry, name: &str, version: &str, roles: u64) -> Result { @@ -265,8 +263,8 @@ impl MetricsService { Self::inner_new(None) } - #[cfg(any(windows, unix))] - fn _process_info_for(&mut self, pid: &i32) -> ProcessInfo { + #[cfg(not(target_os = "unknown"))] + fn process_info_for(&mut self, pid: &sysinfo::Pid) -> ProcessInfo { let mut info = ProcessInfo::default(); if self.system.refresh_process(*pid) { let prc = self.system.get_process(*pid) @@ -277,7 +275,7 @@ impl MetricsService { info } - #[cfg(any(unix, windows))] + #[cfg(not(target_os = "unknown"))] fn connections_info(&self) -> Option { self.pid.as_ref().and_then(|pid| { let af_flags = AddressFamilyFlags::IPV4 | AddressFamilyFlags::IPV6; @@ -285,15 +283,12 @@ impl MetricsService { let netstat_pid = *pid as u32; iterate_sockets_info(af_flags, proto_flags).ok().map(|iter| - iter.filter_map(|r| + iter.filter_map(|r| r.ok().and_then(|s| { - if s.associated_pids.contains(&netstat_pid) { - match s.protocol_socket_info { - ProtocolSocketInfo::Tcp(info) => Some(info.state), - _ => None - } - } else { - None + match s.protocol_socket_info { + ProtocolSocketInfo::Tcp(info) + if s.associated_pids.contains(&netstat_pid) => Some(info.state), + _ => None } }) ).fold(ConnectionsCount::default(), |mut counter, socket_state| { @@ -317,7 +312,7 @@ impl MetricsService { &mut self, info: &ClientInfo, txpool_status: &PoolStatus, - net_status: &NetworkStatus + net_status: &NetworkStatus, ) { let best_number = info.chain.best_number.saturated_into::(); @@ -377,8 +372,12 @@ impl MetricsService { } - metrics.network_per_sec_bytes.with_label_values(&["download"]).set(net_status.average_download_per_sec); - metrics.network_per_sec_bytes.with_label_values(&["upload"]).set(net_status.average_upload_per_sec); + metrics.network_per_sec_bytes.with_label_values(&["download"]).set( + net_status.average_download_per_sec, + ); + metrics.network_per_sec_bytes.with_label_values(&["upload"]).set( + net_status.average_upload_per_sec, + ); metrics.block_height.with_label_values(&["finalized"]).set(finalized_number); metrics.block_height.with_label_values(&["best"]).set(best_number); @@ -396,14 +395,18 @@ impl MetricsService { metrics.database_cache.set(info.memory.database_cache.as_bytes() as u64); metrics.state_cache.set(info.memory.state_cache.as_bytes() as u64); - metrics.state_db.with_label_values(&["non_canonical"]).set(info.memory.state_db.non_canonical.as_bytes() as u64); + metrics.state_db.with_label_values(&["non_canonical"]).set( + info.memory.state_db.non_canonical.as_bytes() as u64, + ); if let Some(pruning) = info.memory.state_db.pruning { metrics.state_db.with_label_values(&["pruning"]).set(pruning.as_bytes() as u64); } - metrics.state_db.with_label_values(&["pinned"]).set(info.memory.state_db.pinned.as_bytes() as u64); + metrics.state_db.with_label_values(&["pinned"]).set( + info.memory.state_db.pinned.as_bytes() as u64, + ); } - #[cfg(any(unix, windows))] + #[cfg(not(target_os = "unknown"))] { let load = self.system.get_load_average(); metrics.load_avg.with_label_values(&["1min"]).set(load.one); -- GitLab From 2af2ab98ea06d80dd24f56cb987d8956692d7d6d Mon Sep 17 00:00:00 2001 From: Seun Lanlege Date: Tue, 7 Apr 2020 19:08:54 +0100 Subject: [PATCH 180/300] sc-consensus-manual-seal uses Finalizer trait for finalization instead of Backend. (#5469) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * manual-seal uses Finalizer trait for finalization instead of Backend * fix tests * use Transaction type * refactor import_queue * ugh * line-width * Update client/consensus/manual-seal/src/lib.rs Co-Authored-By: Joshy Orndorff * fix tests * update docs * Update client/consensus/manual-seal/src/seal_new_block.rs Co-Authored-By: André Silva <123550+andresilva@users.noreply.github.com> * Don't auto-finalize on verification * Explicity don't finalize on import. Co-authored-by: Joshy Orndorff Co-authored-by: Joshy Orndorff Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> --- .../manual-seal/src/finalize_block.rs | 19 ++- client/consensus/manual-seal/src/lib.rs | 148 +++++++----------- .../manual-seal/src/seal_new_block.rs | 19 ++- 3 files changed, 80 insertions(+), 106 deletions(-) diff --git a/client/consensus/manual-seal/src/finalize_block.rs b/client/consensus/manual-seal/src/finalize_block.rs index b3b60e2238..5780a25f97 100644 --- a/client/consensus/manual-seal/src/finalize_block.rs +++ b/client/consensus/manual-seal/src/finalize_block.rs @@ -23,35 +23,40 @@ use sp_runtime::{ generic::BlockId, }; use std::sync::Arc; -use sc_client_api::backend::Backend as ClientBackend; +use sc_client_api::backend::{Backend as ClientBackend, Finalizer}; +use std::marker::PhantomData; /// params for block finalization. -pub struct FinalizeBlockParams { +pub struct FinalizeBlockParams { /// hash of the block pub hash: ::Hash, /// sender to report errors/success to the rpc. pub sender: rpc::Sender<()>, /// finalization justification pub justification: Option, - /// client backend - pub backend: Arc, + /// Finalizer trait object. + pub finalizer: Arc, + /// phantom type to pin the Backend type + pub _phantom: PhantomData, } + /// finalizes a block in the backend with the given params. -pub async fn finalize_block(params: FinalizeBlockParams) +pub async fn finalize_block(params: FinalizeBlockParams) where B: BlockT, + F: Finalizer, CB: ClientBackend, { let FinalizeBlockParams { hash, mut sender, justification, - backend: back_end, + finalizer, .. } = params; - match back_end.finalize_block(BlockId::Hash(hash), justification) { + match finalizer.finalize_block(BlockId::Hash(hash), justification, true) { Err(e) => { log::warn!("Failed to finalize block {:?}", e); rpc::send_result(&mut sender, Err(e.into())) diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs index f3a0ca887f..8294ae049f 100644 --- a/client/consensus/manual-seal/src/lib.rs +++ b/client/consensus/manual-seal/src/lib.rs @@ -17,66 +17,32 @@ //! A manual sealing engine: the engine listens for rpc calls to seal blocks and create forks. //! This is suitable for a testing environment. +use futures::prelude::*; use sp_consensus::{ - self, BlockImport, Environment, Proposer, BlockCheckParams, - ForkChoiceStrategy, BlockImportParams, BlockOrigin, - ImportResult, SelectChain, - import_queue::{ - BasicQueue, - CacheKeyId, - Verifier, - BoxBlockImport, - }, + Environment, Proposer, ForkChoiceStrategy, BlockImportParams, BlockOrigin, SelectChain, + import_queue::{BasicQueue, CacheKeyId, Verifier, BoxBlockImport}, }; +use sp_blockchain::HeaderBackend; use sp_inherents::InherentDataProviders; use sp_runtime::{traits::Block as BlockT, Justification}; -use sc_client_api::backend::Backend as ClientBackend; -use futures::prelude::*; +use sc_client_api::backend::{Backend as ClientBackend, Finalizer}; use sc_transaction_pool::txpool; -use std::collections::HashMap; -use std::sync::Arc; +use std::{sync::Arc, marker::PhantomData}; -pub mod rpc; mod error; mod finalize_block; mod seal_new_block; -use finalize_block::{finalize_block, FinalizeBlockParams}; -use seal_new_block::{seal_new_block, SealBlockParams}; -pub use error::Error; -pub use rpc::{EngineCommand, CreatedBlock}; - -/// The synchronous block-import worker of the engine. -pub struct ManualSealBlockImport { - inner: I, -} - -impl From for ManualSealBlockImport { - fn from(i: I) -> Self { - ManualSealBlockImport { inner: i } - } -} - -impl BlockImport for ManualSealBlockImport - where - B: BlockT, - I: BlockImport, -{ - type Error = I::Error; - type Transaction = (); - - fn check_block(&mut self, block: BlockCheckParams) -> Result - { - self.inner.check_block(block) - } +pub mod rpc; - fn import_block( - &mut self, - block: BlockImportParams, - cache: HashMap>, - ) -> Result { - self.inner.import_block(block, cache) - } -} +use self::{ + finalize_block::{finalize_block, FinalizeBlockParams}, + seal_new_block::{seal_new_block, SealBlockParams}, +}; +pub use self::{ + error::Error, + rpc::{EngineCommand, CreatedBlock}, +}; +use sc_client_api::{TransactionFor, Backend}; /// The verifier for the manual seal engine; instantly finalizes. struct ManualSealVerifier; @@ -92,7 +58,7 @@ impl Verifier for ManualSealVerifier { let mut import_params = BlockImportParams::new(origin, header); import_params.justification = justification; import_params.body = body; - import_params.finalized = true; + import_params.finalized = false; import_params.fork_choice = Some(ForkChoiceStrategy::LongestChain); Ok((import_params, None)) @@ -100,37 +66,43 @@ impl Verifier for ManualSealVerifier { } /// Instantiate the import queue for the manual seal consensus engine. -pub fn import_queue(block_import: BoxBlockImport) -> BasicQueue +pub fn import_queue( + block_import: BoxBlockImport> +) -> BasicQueue> + where + Block: BlockT, + B: Backend + 'static, { BasicQueue::new( ManualSealVerifier, - block_import, + Box::new(block_import), None, None, ) } /// Creates the background authorship task for the manual seal engine. -pub async fn run_manual_seal( +pub async fn run_manual_seal( mut block_import: BoxBlockImport, mut env: E, - backend: Arc, + client: Arc, pool: Arc>, - mut seal_block_channel: S, - select_chain: C, + mut commands_stream: S, + select_chain: SC, inherent_data_providers: InherentDataProviders, ) where + A: txpool::ChainApi::Hash> + 'static, B: BlockT + 'static, + C: HeaderBackend + Finalizer + 'static, CB: ClientBackend + 'static, E: Environment + 'static, E::Error: std::fmt::Display, >::Error: std::fmt::Display, - A: txpool::ChainApi::Hash> + 'static, S: Stream::Hash>> + Unpin + 'static, - C: SelectChain + 'static, + SC: SelectChain + 'static, { - while let Some(command) = seal_block_channel.next().await { + while let Some(command) = commands_stream.next().await { match command { EngineCommand::SealNewBlock { create_empty, @@ -149,7 +121,7 @@ pub async fn run_manual_seal( block_import: &mut block_import, inherent_data_provider: &inherent_data_providers, pool: pool.clone(), - backend: backend.clone(), + client: client.clone(), } ).await; } @@ -159,7 +131,8 @@ pub async fn run_manual_seal( hash, sender, justification, - backend: backend.clone(), + finalizer: client.clone(), + _phantom: PhantomData, } ).await } @@ -170,26 +143,28 @@ pub async fn run_manual_seal( /// runs the background authorship task for the instant seal engine. /// instant-seal creates a new block for every transaction imported into /// the transaction pool. -pub async fn run_instant_seal( +pub async fn run_instant_seal( block_import: BoxBlockImport, env: E, - backend: Arc, + client: Arc, pool: Arc>, - select_chain: C, + select_chain: SC, inherent_data_providers: InherentDataProviders, ) where A: txpool::ChainApi::Hash> + 'static, B: BlockT + 'static, + C: HeaderBackend + Finalizer + 'static, CB: ClientBackend + 'static, E: Environment + 'static, E::Error: std::fmt::Display, >::Error: std::fmt::Display, - C: SelectChain + 'static + SC: SelectChain + 'static { // instant-seal creates blocks as soon as transactions are imported // into the transaction pool. - let seal_block_channel = pool.validated_pool().import_notification_stream() + let commands_stream = pool.validated_pool() + .import_notification_stream() .map(|_| { EngineCommand::SealNewBlock { create_empty: false, @@ -202,9 +177,9 @@ pub async fn run_instant_seal( run_manual_seal( block_import, env, - backend, + client, pool, - seal_block_channel, + commands_stream, select_chain, inherent_data_providers, ).await @@ -226,9 +201,7 @@ mod tests { use substrate_test_runtime_transaction_pool::{TestApi, uxt}; use sp_transaction_pool::{TransactionPool, MaintainedTransactionPool, TransactionSource}; use sp_runtime::generic::BlockId; - use sp_blockchain::HeaderBackend; use sp_consensus::ImportedAux; - use sc_client::LongestChain; use sp_inherents::InherentDataProviders; use sc_basic_authorship::ProposerFactory; @@ -241,9 +214,8 @@ mod tests { #[tokio::test] async fn instant_seal() { let builder = TestClientBuilder::new(); - let backend = builder.backend(); - let client = Arc::new(builder.build()); - let select_chain = LongestChain::new(backend.clone()); + let (client, select_chain) = builder.build_with_longest_chain(); + let client = Arc::new(client); let inherent_data_providers = InherentDataProviders::new(); let pool = Arc::new(BasicPool::new(Options::default(), api()).0); let env = ProposerFactory::new( @@ -268,7 +240,7 @@ mod tests { let future = run_manual_seal( Box::new(client.clone()), env, - backend.clone(), + client.clone(), pool.pool().clone(), stream, select_chain, @@ -300,15 +272,14 @@ mod tests { } ); // assert that there's a new block in the db. - assert!(backend.blockchain().header(BlockId::Number(1)).unwrap().is_some()) + assert!(client.header(&BlockId::Number(1)).unwrap().is_some()) } #[tokio::test] async fn manual_seal_and_finalization() { let builder = TestClientBuilder::new(); - let backend = builder.backend(); - let client = Arc::new(builder.build()); - let select_chain = LongestChain::new(backend.clone()); + let (client, select_chain) = builder.build_with_longest_chain(); + let client = Arc::new(client); let inherent_data_providers = InherentDataProviders::new(); let pool = Arc::new(BasicPool::new(Options::default(), api()).0); let env = ProposerFactory::new( @@ -320,7 +291,7 @@ mod tests { let future = run_manual_seal( Box::new(client.clone()), env, - backend.clone(), + client.clone(), pool.pool().clone(), stream, select_chain, @@ -360,7 +331,7 @@ mod tests { } ); // assert that there's a new block in the db. - let header = backend.blockchain().header(BlockId::Number(1)).unwrap().unwrap(); + let header = client.header(&BlockId::Number(1)).unwrap().unwrap(); let (tx, rx) = futures::channel::oneshot::channel(); sink.send(EngineCommand::FinalizeBlock { sender: Some(tx), @@ -374,9 +345,8 @@ mod tests { #[tokio::test] async fn manual_seal_fork_blocks() { let builder = TestClientBuilder::new(); - let backend = builder.backend(); - let client = Arc::new(builder.build()); - let select_chain = LongestChain::new(backend.clone()); + let (client, select_chain) = builder.build_with_longest_chain(); + let client = Arc::new(client); let inherent_data_providers = InherentDataProviders::new(); let pool_api = api(); let pool = Arc::new(BasicPool::new(Options::default(), pool_api.clone()).0); @@ -389,7 +359,7 @@ mod tests { let future = run_manual_seal( Box::new(client.clone()), env, - backend.clone(), + client.clone(), pool.pool().clone(), stream, select_chain, @@ -431,12 +401,12 @@ mod tests { } ); // assert that there's a new block in the db. - assert!(backend.blockchain().header(BlockId::Number(0)).unwrap().is_some()); + assert!(client.header(&BlockId::Number(0)).unwrap().is_some()); assert!(pool.submit_one(&BlockId::Number(1), SOURCE, uxt(Alice, 1)).await.is_ok()); pool.maintain(sp_transaction_pool::ChainEvent::NewBlock { id: BlockId::Number(1), - header: backend.blockchain().header(BlockId::Number(1)).expect("db error").expect("imported above"), + header: client.header(&BlockId::Number(1)).expect("db error").expect("imported above"), is_new_best: true, retracted: vec![], }).await; @@ -452,7 +422,7 @@ mod tests { rx1.await.expect("should be no error receiving"), Ok(_) ); - assert!(backend.blockchain().header(BlockId::Number(1)).unwrap().is_some()); + assert!(client.header(&BlockId::Number(1)).unwrap().is_some()); pool_api.increment_nonce(Alice.into()); assert!(pool.submit_one(&BlockId::Number(2), SOURCE, uxt(Alice, 2)).await.is_ok()); @@ -465,6 +435,6 @@ mod tests { }).await.is_ok()); let imported = rx2.await.unwrap().unwrap(); // assert that fork block is in the db - assert!(backend.blockchain().header(BlockId::Hash(imported.hash)).unwrap().is_some()) + assert!(client.header(&BlockId::Hash(imported.hash)).unwrap().is_some()) } } diff --git a/client/consensus/manual-seal/src/seal_new_block.rs b/client/consensus/manual-seal/src/seal_new_block.rs index 39d73e16ab..88b58ef4cc 100644 --- a/client/consensus/manual-seal/src/seal_new_block.rs +++ b/client/consensus/manual-seal/src/seal_new_block.rs @@ -33,7 +33,6 @@ use sp_consensus::{ import_queue::BoxBlockImport, }; use sp_blockchain::HeaderBackend; -use sc_client_api::backend::Backend as ClientBackend; use std::collections::HashMap; use std::time::Duration; use sp_inherents::InherentDataProviders; @@ -42,7 +41,7 @@ use sp_inherents::InherentDataProviders; const MAX_PROPOSAL_DURATION: u64 = 10; /// params for sealing a new block -pub struct SealBlockParams<'a, B: BlockT, C, CB, E, T, P: txpool::ChainApi> { +pub struct SealBlockParams<'a, B: BlockT, SC, HB, E, T, P: txpool::ChainApi> { /// if true, empty blocks(without extrinsics) will be created. /// otherwise, will return Error::EmptyTransactionPool. pub create_empty: bool, @@ -54,12 +53,12 @@ pub struct SealBlockParams<'a, B: BlockT, C, CB, E, T, P: txpool::ChainApi> { pub sender: rpc::Sender::Hash>>, /// transaction pool pub pool: Arc>, - /// client backend - pub backend: Arc, + /// header backend + pub client: Arc, /// Environment trait object for creating a proposer pub env: &'a mut E, /// SelectChain object - pub select_chain: &'a C, + pub select_chain: &'a SC, /// block import object pub block_import: &'a mut BoxBlockImport, /// inherent data provider @@ -67,24 +66,24 @@ pub struct SealBlockParams<'a, B: BlockT, C, CB, E, T, P: txpool::ChainApi> { } /// seals a new block with the given params -pub async fn seal_new_block( +pub async fn seal_new_block( SealBlockParams { create_empty, finalize, pool, parent_hash, - backend: back_end, + client, select_chain, block_import, env, inherent_data_provider, mut sender, .. - }: SealBlockParams<'_, B, SC, CB, E, T, P> + }: SealBlockParams<'_, B, SC, HB, E, T, P> ) where B: BlockT, - CB: ClientBackend, + HB: HeaderBackend, E: Environment, >::Error: std::fmt::Display, >::Error: std::fmt::Display, @@ -101,7 +100,7 @@ pub async fn seal_new_block( // or fetch the best_block. let header = match parent_hash { Some(hash) => { - match back_end.blockchain().header(BlockId::Hash(hash))? { + match client.header(BlockId::Hash(hash))? { Some(header) => header, None => return Err(Error::BlockNotFound(format!("{}", hash))), } -- GitLab From 8c1858048148c1c717123b0e4d360f8ad1be5bf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Tue, 7 Apr 2020 21:11:22 +0100 Subject: [PATCH 181/300] babe, grandpa: restrict info logging during initial sync (#5564) * babe: restrict info logging during initial sync * grandpa: restrict info logging during initial sync * grandpa: fix test compilation * grandpa: remove afg_log macro mod --- client/consensus/babe/src/lib.rs | 40 +++++----- client/finality-grandpa/src/authorities.rs | 86 ++++++++++++++++------ client/finality-grandpa/src/environment.rs | 15 +++- client/finality-grandpa/src/import.rs | 41 +++++++++-- client/finality-grandpa/src/lib.rs | 17 +++++ client/finality-grandpa/src/observer.rs | 1 + 6 files changed, 147 insertions(+), 53 deletions(-) diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index 5365aae2aa..092bf8153b 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -101,7 +101,7 @@ use sc_client_api::{ use sp_block_builder::BlockBuilder as BlockBuilderApi; use futures::prelude::*; -use log::{warn, debug, info, trace}; +use log::{debug, info, log, trace, warn}; use sc_consensus_slots::{ SlotWorker, SlotInfo, SlotCompatible, StorageChanges, CheckedHeader, check_equivocation, }; @@ -222,16 +222,6 @@ fn babe_err(error: Error) -> Error { error } -macro_rules! babe_info { - ($($i: expr),+) => { - { - info!(target: "babe", $($i),+); - format!($($i),+) - } - }; -} - - /// Intermediate value passed to block importer. pub struct BabeIntermediate { /// The epoch descriptor. @@ -368,7 +358,7 @@ pub fn start_babe(BabeParams { &inherent_data_providers, )?; - babe_info!("👶 Starting BABE Authorship worker"); + info!(target: "babe", "👶 Starting BABE Authorship worker"); Ok(sc_consensus_slots::start_slot_worker( config.0, select_chain, @@ -1010,15 +1000,29 @@ impl BlockImport for BabeBlockImport::FetchEpoch(parent_hash).into()) })?; - babe_info!("👶 New epoch {} launching at block {} (block slot {} >= start slot {}).", - viable_epoch.as_ref().epoch_index, - hash, - slot_number, - viable_epoch.as_ref().start_slot); + // restrict info logging during initial sync to avoid spam + let log_level = if block.origin == BlockOrigin::NetworkInitialSync { + log::Level::Debug + } else { + log::Level::Info + }; + + log!(target: "babe", + log_level, + "👶 New epoch {} launching at block {} (block slot {} >= start slot {}).", + viable_epoch.as_ref().epoch_index, + hash, + slot_number, + viable_epoch.as_ref().start_slot, + ); let next_epoch = viable_epoch.increment(next_epoch_descriptor); - babe_info!("👶 Next epoch starts at slot {}", next_epoch.as_ref().start_slot); + log!(target: "babe", + log_level, + "👶 Next epoch starts at slot {}", + next_epoch.as_ref().start_slot, + ); // prune the tree of epochs not part of the finalized chain or // that are not live anymore, and then track the given epoch change diff --git a/client/finality-grandpa/src/authorities.rs b/client/finality-grandpa/src/authorities.rs index 4709216ebe..fe3f2dd19e 100644 --- a/client/finality-grandpa/src/authorities.rs +++ b/client/finality-grandpa/src/authorities.rs @@ -20,7 +20,7 @@ use fork_tree::ForkTree; use parking_lot::RwLock; use finality_grandpa::voter_set::VoterSet; use parity_scale_codec::{Encode, Decode}; -use log::{debug, info}; +use log::debug; use sc_telemetry::{telemetry, CONSENSUS_INFO}; use sp_finality_grandpa::{AuthorityId, AuthorityList}; @@ -250,6 +250,7 @@ where best_hash: H, best_number: N, is_descendent_of: &F, + initial_sync: bool, ) -> Result, E> where F: Fn(&H, &H) -> Result, { @@ -262,8 +263,10 @@ where // check if the given best block is in the same branch as the block that signaled the change. if is_descendent_of(&change.canon_hash, &best_hash)? { // apply this change: make the set canonical - info!(target: "afg", "👴 Applying authority set change forced at block #{:?}", - change.canon_height); + afg_log!(initial_sync, + "👴 Applying authority set change forced at block #{:?}", + change.canon_height, + ); telemetry!(CONSENSUS_INFO; "afg.applying_forced_authority_set_change"; "block" => ?change.canon_height ); @@ -305,6 +308,7 @@ where finalized_hash: H, finalized_number: N, is_descendent_of: &F, + initial_sync: bool, ) -> Result, fork_tree::Error> where F: Fn(&H, &H) -> Result, E: std::error::Error, @@ -328,8 +332,10 @@ where self.pending_forced_changes.clear(); if let Some(change) = change { - info!(target: "afg", "👴 Applying authority set change scheduled at block #{:?}", - change.canon_height); + afg_log!(initial_sync, + "👴 Applying authority set change scheduled at block #{:?}", + change.canon_height, + ); telemetry!(CONSENSUS_INFO; "afg.applying_scheduled_authority_set_change"; "block" => ?change.canon_height ); @@ -599,11 +605,16 @@ mod tests { ); // finalizing "hash_c" won't enact the change signaled at "hash_a" but it will prune out "hash_b" - let status = authorities.apply_standard_changes("hash_c", 11, &is_descendent_of(|base, hash| match (*base, *hash) { - ("hash_a", "hash_c") => true, - ("hash_b", "hash_c") => false, - _ => unreachable!(), - })).unwrap(); + let status = authorities.apply_standard_changes( + "hash_c", + 11, + &is_descendent_of(|base, hash| match (*base, *hash) { + ("hash_a", "hash_c") => true, + ("hash_b", "hash_c") => false, + _ => unreachable!(), + }), + false, + ).unwrap(); assert!(status.changed); assert_eq!(status.new_set_block, None); @@ -613,10 +624,15 @@ mod tests { ); // finalizing "hash_d" will enact the change signaled at "hash_a" - let status = authorities.apply_standard_changes("hash_d", 15, &is_descendent_of(|base, hash| match (*base, *hash) { - ("hash_a", "hash_d") => true, - _ => unreachable!(), - })).unwrap(); + let status = authorities.apply_standard_changes( + "hash_d", + 15, + &is_descendent_of(|base, hash| match (*base, *hash) { + ("hash_a", "hash_d") => true, + _ => unreachable!(), + }), + false, + ).unwrap(); assert!(status.changed); assert_eq!(status.new_set_block, Some(("hash_d", 15))); @@ -671,12 +687,18 @@ mod tests { }); // trying to finalize past `change_c` without finalizing `change_a` first - match authorities.apply_standard_changes("hash_d", 40, &is_descendent_of) { - Err(fork_tree::Error::UnfinalizedAncestor) => {}, - _ => unreachable!(), - } + assert!(matches!( + authorities.apply_standard_changes("hash_d", 40, &is_descendent_of, false), + Err(fork_tree::Error::UnfinalizedAncestor) + )); + + let status = authorities.apply_standard_changes( + "hash_b", + 15, + &is_descendent_of, + false, + ).unwrap(); - let status = authorities.apply_standard_changes("hash_b", 15, &is_descendent_of).unwrap(); assert!(status.changed); assert_eq!(status.new_set_block, Some(("hash_b", 15))); @@ -684,7 +706,13 @@ mod tests { assert_eq!(authorities.set_id, 1); // after finalizing `change_a` it should be possible to finalize `change_c` - let status = authorities.apply_standard_changes("hash_d", 40, &is_descendent_of).unwrap(); + let status = authorities.apply_standard_changes( + "hash_d", + 40, + &is_descendent_of, + false, + ).unwrap(); + assert!(status.changed); assert_eq!(status.new_set_block, Some(("hash_d", 40))); @@ -817,20 +845,30 @@ mod tests { assert!(authorities.add_pending_change(change_c, &is_descendent_of_a).is_err()); // too early. - assert!(authorities.apply_forced_changes("hash_a10", 10, &static_is_descendent_of(true)).unwrap().is_none()); + assert!( + authorities.apply_forced_changes("hash_a10", 10, &static_is_descendent_of(true), false) + .unwrap() + .is_none() + ); // too late. - assert!(authorities.apply_forced_changes("hash_a16", 16, &static_is_descendent_of(true)).unwrap().is_none()); + assert!( + authorities.apply_forced_changes("hash_a16", 16, &static_is_descendent_of(true), false) + .unwrap() + .is_none() + ); // on time -- chooses the right change. assert_eq!( - authorities.apply_forced_changes("hash_a15", 15, &is_descendent_of_a).unwrap().unwrap(), + authorities.apply_forced_changes("hash_a15", 15, &is_descendent_of_a, false) + .unwrap() + .unwrap(), (42, AuthoritySet { current_authorities: set_a, set_id: 1, pending_standard_changes: ForkTree::new(), pending_forced_changes: Vec::new(), - }) + }), ); } } diff --git a/client/finality-grandpa/src/environment.rs b/client/finality-grandpa/src/environment.rs index dec9492482..d3bbc1adb3 100644 --- a/client/finality-grandpa/src/environment.rs +++ b/client/finality-grandpa/src/environment.rs @@ -20,7 +20,7 @@ use std::pin::Pin; use std::sync::Arc; use std::time::Duration; -use log::{debug, warn, info}; +use log::{debug, warn}; use parity_scale_codec::{Decode, Encode}; use futures::prelude::*; use futures_timer::Delay; @@ -911,6 +911,7 @@ where hash, number, (round, commit).into(), + false, ) } @@ -970,6 +971,7 @@ pub(crate) fn finalize_block( hash: Block::Hash, number: NumberFor, justification_or_commit: JustificationOrCommit, + initial_sync: bool, ) -> Result<(), CommandOrError>> where Block: BlockT, BE: Backend, @@ -1011,6 +1013,7 @@ pub(crate) fn finalize_block( hash, number, &is_descendent_of::(&*client, None), + initial_sync, ).map_err(|e| Error::Safety(e.to_string()))?; // check if this is this is the first finalization of some consensus changes @@ -1091,9 +1094,15 @@ pub(crate) fn finalize_block( let (new_id, set_ref) = authority_set.current(); if set_ref.len() > 16 { - info!("👴 Applying GRANDPA set change to new set with {} authorities", set_ref.len()); + afg_log!(initial_sync, + "👴 Applying GRANDPA set change to new set with {} authorities", + set_ref.len(), + ); } else { - info!("👴 Applying GRANDPA set change to new set {:?}", set_ref); + afg_log!(initial_sync, + "👴 Applying GRANDPA set change to new set {:?}", + set_ref, + ); } telemetry!(CONSENSUS_INFO; "afg.generating_new_authority_set"; diff --git a/client/finality-grandpa/src/import.rs b/client/finality-grandpa/src/import.rs index faf3193641..c1e32dfa6c 100644 --- a/client/finality-grandpa/src/import.rs +++ b/client/finality-grandpa/src/import.rs @@ -16,7 +16,7 @@ use std::{sync::Arc, collections::HashMap}; -use log::{debug, trace, info}; +use log::{debug, trace}; use parity_scale_codec::Encode; use parking_lot::RwLockWriteGuard; @@ -27,7 +27,7 @@ use sp_api::{TransactionFor}; use sp_consensus::{ BlockImport, Error as ConsensusError, - BlockCheckParams, BlockImportParams, ImportResult, JustificationImport, + BlockCheckParams, BlockImportParams, BlockOrigin, ImportResult, JustificationImport, SelectChain, }; use sp_finality_grandpa::{ConsensusLog, ScheduledChange, SetId, GRANDPA_ENGINE_ID}; @@ -128,7 +128,12 @@ impl JustificationImport number: NumberFor, justification: Justification, ) -> Result<(), Self::Error> { - GrandpaBlockImport::import_justification(self, hash, number, justification, false) + // this justification was requested by the sync service, therefore we + // are not sure if it should enact a change or not. it could have been a + // request made as part of initial sync but that means the justification + // wasn't part of the block and was requested asynchronously, probably + // makes sense to log in that case. + GrandpaBlockImport::import_justification(self, hash, number, justification, false, false) } } @@ -250,6 +255,7 @@ where &self, block: &mut BlockImportParams>, hash: Block::Hash, + initial_sync: bool, ) -> Result, ConsensusError> { // when we update the authorities, we need to hold the lock // until the block is written to prevent a race if we need to restore @@ -324,7 +330,9 @@ where } let applied_changes = { - let forced_change_set = guard.as_mut().apply_forced_changes(hash, number, &is_descendent_of) + let forced_change_set = guard + .as_mut() + .apply_forced_changes(hash, number, &is_descendent_of, initial_sync) .map_err(|e| ConsensusError::ClientImport(e.to_string())) .map_err(ConsensusError::from)?; @@ -419,7 +427,10 @@ impl BlockImport Err(e) => return Err(ConsensusError::ClientImport(e.to_string()).into()), } - let pending_changes = self.make_authorities_changes(&mut block, hash)?; + // on initial sync we will restrict logging under info to avoid spam. + let initial_sync = block.origin == BlockOrigin::NetworkInitialSync; + + let pending_changes = self.make_authorities_changes(&mut block, hash, initial_sync)?; // we don't want to finalize on `inner.import_block` let mut justification = block.justification.take(); @@ -492,7 +503,15 @@ impl BlockImport match justification { Some(justification) => { - self.import_justification(hash, number, justification, needs_justification).unwrap_or_else(|err| { + let import_res = self.import_justification( + hash, + number, + justification, + needs_justification, + initial_sync, + ); + + import_res.unwrap_or_else(|err| { if needs_justification || enacts_consensus_change { debug!(target: "afg", "Imported block #{} that enacts authority set change with \ invalid justification: {:?}, requesting justification from peers.", number, err); @@ -604,6 +623,7 @@ where number: NumberFor, justification: Justification, enacts_change: bool, + initial_sync: bool, ) -> Result<(), ConsensusError> { let justification = GrandpaJustification::decode_and_verify_finalizes( &justification, @@ -625,12 +645,17 @@ where hash, number, justification.into(), + initial_sync, ); match result { Err(CommandOrError::VoterCommand(command)) => { - info!(target: "afg", "👴 Imported justification for block #{} that triggers \ - command {}, signaling voter.", number, command); + afg_log!(initial_sync, + "👴 Imported justification for block #{} that triggers \ + command {}, signaling voter.", + number, + command, + ); // send the command to the voter let _ = self.send_voter_commands.unbounded_send(command); diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index 800fe3442e..6fab89ac68 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -84,6 +84,23 @@ use std::time::Duration; use std::pin::Pin; use std::task::{Poll, Context}; +// utility logging macro that takes as first argument a conditional to +// decide whether to log under debug or info level (useful to restrict +// logging under initial sync). +macro_rules! afg_log { + ($condition:expr, $($msg: expr),+ $(,)?) => { + { + let log_level = if $condition { + log::Level::Debug + } else { + log::Level::Info + }; + + log::log!(target: "afg", log_level, $($msg),+); + } + }; +} + mod authorities; mod aux_schema; mod communication; diff --git a/client/finality-grandpa/src/observer.rs b/client/finality-grandpa/src/observer.rs index fbe19a0716..1e6c8ddf18 100644 --- a/client/finality-grandpa/src/observer.rs +++ b/client/finality-grandpa/src/observer.rs @@ -124,6 +124,7 @@ fn grandpa_observer( finalized_hash, finalized_number, (round, commit).into(), + false, ) { Ok(_) => {}, Err(e) => return future::err(e), -- GitLab From 27d371ee0199eef5f8bc753bfae52a707bbb0250 Mon Sep 17 00:00:00 2001 From: Roman Borschel Date: Wed, 8 Apr 2020 09:23:21 +0200 Subject: [PATCH 182/300] libp2p-next (#5278) * Adapt to rust-libp2p#1440. * Further adapt to libp2p/master. * Update to libp2p-0.17 * Finishing touches. * Remove stray TODO. * Incorporate review feedback. * Remove unused import. --- Cargo.lock | 217 +++-- Cargo.toml | 1 + bin/utils/subkey/Cargo.toml | 2 +- client/authority-discovery/Cargo.toml | 2 +- client/authority-discovery/src/lib.rs | 14 +- client/authority-discovery/src/tests.rs | 2 +- client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 7 +- client/network/src/debug_info.rs | 108 +-- client/network/src/discovery.rs | 50 +- client/network/src/lib.rs | 9 + client/network/src/protocol.rs | 41 +- client/network/src/protocol/block_requests.rs | 17 +- .../src/protocol/generic_proto/behaviour.rs | 760 +++++++++++------- .../protocol/generic_proto/handler/group.rs | 23 +- .../protocol/generic_proto/handler/legacy.rs | 25 +- .../generic_proto/handler/notif_in.rs | 2 +- .../generic_proto/handler/notif_out.rs | 24 +- .../src/protocol/generic_proto/tests.rs | 31 +- .../src/protocol/light_client_handler.rs | 319 +++++--- client/network/src/service.rs | 56 +- client/network/test/Cargo.toml | 2 +- client/peerset/Cargo.toml | 2 +- client/telemetry/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- utils/browser/Cargo.toml | 2 +- 26 files changed, 1045 insertions(+), 677 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0da8b5390..de2b174826 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -398,6 +398,17 @@ dependencies = [ "constant_time_eq", ] +[[package]] +name = "blake2s_simd" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab9e07352b829279624ceb7c64adb4f585dacdb81d35cafae81139ccd617cf44" +dependencies = [ + "arrayref", + "arrayvec 0.5.1", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.7.3" @@ -1227,7 +1238,7 @@ dependencies = [ "fixed-hash", "impl-rlp", "impl-serde 0.3.0", - "tiny-keccak 2.0.2", + "tiny-keccak 2.0.1", ] [[package]] @@ -1791,7 +1802,6 @@ dependencies = [ "proc-macro-hack", "proc-macro-nested", "slab", - "tokio-io", ] [[package]] @@ -1963,7 +1973,7 @@ dependencies = [ "indexmap", "log", "slab", - "tokio 0.2.16", + "tokio 0.2.13", "tokio-util", ] @@ -2175,7 +2185,7 @@ dependencies = [ "net2", "pin-project", "time", - "tokio 0.2.16", + "tokio 0.2.13", "tower-service", "want 0.3.0", ] @@ -2193,7 +2203,7 @@ dependencies = [ "log", "rustls 0.17.0", "rustls-native-certs", - "tokio 0.2.16", + "tokio 0.2.13", "tokio-rustls", "webpki", ] @@ -2601,9 +2611,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.16.2" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bba17ee9cac4bb89de5812159877d9b4f0a993bf41697a5a875940cd1eb71f24" +checksum = "8a261244b8d7ff58f5d62ffa33589eb1ba7733a1dfee0902ad9fdfe62ada7009" dependencies = [ "bytes 0.5.4", "futures 0.3.4", @@ -2629,8 +2639,8 @@ dependencies = [ "libp2p-wasm-ext", "libp2p-websocket", "libp2p-yamux", - "parity-multiaddr", - "parity-multihash", + "multihash", + "parity-multiaddr 0.8.0", "parking_lot 0.10.0", "pin-project", "smallvec 1.2.0", @@ -2639,22 +2649,23 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.16.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b874594c4b29de1a29f27871feba8e6cd13aa54a8a1e8f8c7cf3dfac5ca287c" +checksum = "1cfe1412f2afe1366a2661abd211bb1a27ee6a664d799071282f4fba997c6858" dependencies = [ "asn1_der", "bs58", "ed25519-dalek", + "either", "fnv", "futures 0.3.4", "futures-timer 3.0.2", "lazy_static", "libsecp256k1", "log", + "multihash", "multistream-select", - "parity-multiaddr", - "parity-multihash", + "parity-multiaddr 0.8.0", "parking_lot 0.10.0", "pin-project", "prost", @@ -2672,9 +2683,9 @@ dependencies = [ [[package]] name = "libp2p-core-derive" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d472e9d522f588805c77801de10b957be84e10f019ca5f869fa1825b15ea9b" +checksum = "a0eeb25d5f152a826eac57c7d1cc3de10d72dc4051e90fe4c0cd139f07a069a3" dependencies = [ "quote 1.0.3", "syn 1.0.17", @@ -2682,9 +2693,9 @@ dependencies = [ [[package]] name = "libp2p-deflate" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e25004d4d9837b44b22c5f1a69be1724a5168fef6cff1716b5176a972c3aa62" +checksum = "136fcef31e3247f51946c3ebefb94d0798c4c8aae78bc59cb7431b220b5330cf" dependencies = [ "flate2", "futures 0.3.4", @@ -2693,9 +2704,9 @@ dependencies = [ [[package]] name = "libp2p-dns" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b99e552f9939b606eb4b59f7f64d9b01e3f96752f47e350fc3c5fc646ed3f649" +checksum = "647178f8683bf868f7f14d5e5718dbdc2445b9f6b24ce99da96cecd7c5d2d1a6" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2704,9 +2715,9 @@ dependencies = [ [[package]] name = "libp2p-floodsub" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3234f12e44f9a50351a9807b97fe7de11eb9ae4482370392ba10da6dc90722" +checksum = "34c8dee172fd1630caf91a427d601d6a8d24c8cfcbcf7d5c09c9a1f3b4bbebc2" dependencies = [ "cuckoofilter", "fnv", @@ -2721,9 +2732,9 @@ dependencies = [ [[package]] name = "libp2p-gossipsub" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d46cb3e0841bd951cbf4feae56cdc081e6347836a644fb260c3ec554149b4006" +checksum = "0042a2156fb6264bda9def93070e411dfaddf8c57c4b2d63634190d296458c76" dependencies = [ "base64 0.11.0", "byteorder 1.3.4", @@ -2746,9 +2757,9 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfeb935a9bd41263e4f3a24b988e9f4a044f3ae89ac284e83c17fe2f84e0d66b" +checksum = "04efa011cda5232648b5aa50bd80be7ba0a695d682b01aa46b65e5be5ece0605" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2762,9 +2773,9 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.16.2" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464dc8412978d40f0286be72ed9ab5e0e1386a4a06e7f174526739b5c3c1f041" +checksum = "97f4722d83af8fc0065cee7589a000b629961c1c11d90ba09f6685b3e123b9ae" dependencies = [ "arrayvec 0.5.1", "bytes 0.5.4", @@ -2775,7 +2786,7 @@ dependencies = [ "libp2p-core", "libp2p-swarm", "log", - "parity-multihash", + "multihash", "prost", "prost-build", "rand 0.7.3", @@ -2789,9 +2800,9 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881fcfb360c2822db9f0e6bb6f89529621556ed9a8b038313414eda5107334de" +checksum = "b752276b3bea2fca1c291f43cefc8082d8a639bb8f9052cf5adc6accfcd7b44e" dependencies = [ "async-std", "data-encoding", @@ -2811,9 +2822,9 @@ dependencies = [ [[package]] name = "libp2p-mplex" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8507b37ad0eed275efcde67a023c3d85af6c80768b193845b9288e848e1af95" +checksum = "0f317db8c062beecde87a8765ca03784e6f1a55daa5b9868bf60ebf9b9a2b92f" dependencies = [ "bytes 0.5.4", "fnv", @@ -2827,9 +2838,9 @@ dependencies = [ [[package]] name = "libp2p-noise" -version = "0.16.2" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15a8a3d71f898beb6f854c8aae27aa1d198e0d1f2e49412261c2d90ef39675a" +checksum = "98d3845f54288ff134dd78c131517bad8bc03965def6e6517efef03291d9b4d7" dependencies = [ "curve25519-dalek", "futures 0.3.4", @@ -2848,9 +2859,9 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d22f2f228b3a828dca1cb8aa9fa331e0bc9c36510cb2c1916956e20dc85e8c" +checksum = "aa1cb80ccbedb91d9b980aafc6bf39dc7e4616a7e37c631a4e6ef62629567a13" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2863,9 +2874,9 @@ dependencies = [ [[package]] name = "libp2p-plaintext" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56126a204d7b3382bac163143ff4125a14570b3ba76ba979103d1ae1abed1923" +checksum = "da16d35e3990cc5dc22c8d7ea4a2aa1c18f518491bb29c0c3498fb9a2d8e486e" dependencies = [ "bytes 0.5.4", "futures 0.3.4", @@ -2881,9 +2892,9 @@ dependencies = [ [[package]] name = "libp2p-pnet" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b916938a8868f75180aeeffcc6a516a922d165e8fa2a90b57bad989d1ccbb57a" +checksum = "45d11e8c6d83e294ef3d7ff3a9f5a7aa5aa0c39c2d4991f2905c23c438c84526" dependencies = [ "futures 0.3.4", "log", @@ -2895,9 +2906,9 @@ dependencies = [ [[package]] name = "libp2p-secio" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1219e9ecb4945d7331a05f5ffe96a1f6e28051bfa1223d4c60353c251de0354e" +checksum = "74130fa95effb780850ec790b7af777b893108d9b5983ab994b61d93d2eb0336" dependencies = [ "aes-ctr", "ctr", @@ -2925,13 +2936,14 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "275471e7c0e88ae004660866cd54f603bd8bd1f4caef541a27f50dd8640c4d4c" +checksum = "a4ec53df8978a5d6d9dac243fb1e3adf004f8b8d28f72e6f2160df34d5f39564" dependencies = [ "futures 0.3.4", "libp2p-core", "log", + "rand 0.7.3", "smallvec 1.2.0", "void", "wasm-timer", @@ -2939,9 +2951,9 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e80ad4e3535345f3d666554ce347d3100453775611c05c60786bf9a1747a10" +checksum = "e25c9d9c5448c189bba7ecdd1ca23800516281476e82810eff711ef04abaf9eb" dependencies = [ "async-std", "futures 0.3.4", @@ -2954,9 +2966,9 @@ dependencies = [ [[package]] name = "libp2p-uds" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d329564a43da9d0e055a5b938633c4a8ceab1f59cec133fbc4647917c07341" +checksum = "d8dbcbe6567ea1b3c98ba4df5fd9d1b7c2bebbf50d46ceb0c2ce735c55af3f8d" dependencies = [ "async-std", "futures 0.3.4", @@ -2966,9 +2978,9 @@ dependencies = [ [[package]] name = "libp2p-wasm-ext" -version = "0.16.2" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "923581c055bc4b8c5f42d4ce5ef43e52fe5216f1ea4bc26476cb8a966ce6220b" +checksum = "076446cabb23b0d79d2375661d837a43cbda6719d88787f234e7661c33ef9554" dependencies = [ "futures 0.3.4", "js-sys", @@ -2980,9 +2992,9 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5351ca9eea122081c1c0f9323164d2918cac29b5a6bfe5054d4ba8ec9447cf42" +checksum = "a0117ed6a6f60114c107c1232a0890a8fe997013c7e1920b6f0c811e05d2fae7" dependencies = [ "async-tls", "bytes 0.5.4", @@ -3001,9 +3013,9 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.16.2" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dac30de24ccde0e67f363d71a125c587bbe6589503f664947e9b084b68a34f1" +checksum = "ee12c49426527908f81ffb6551b95f57149a8ea64f386bb7da3b123cdb9c01ba" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -3268,6 +3280,21 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" +[[package]] +name = "multihash" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47fbc227f7e2b1cb701f95404579ecb2668abbdd3c7ef7a6cbb3cc0d3b236869" +dependencies = [ + "blake2b_simd", + "blake2s_simd", + "digest", + "sha-1", + "sha2", + "sha3", + "unsigned-varint", +] + [[package]] name = "multimap" version = "0.8.1" @@ -3276,15 +3303,15 @@ checksum = "d8883adfde9756c1d30b0f519c9b8c502a94b41ac62f696453c37c7fc0a958ce" [[package]] name = "multistream-select" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f938ffe420493e77c8b6cbcc3f282283f68fc889c5dcbc8e51668d5f3a01ad94" +checksum = "74cdcf7cfb3402881e15a1f95116cb033d69b33c83d481e1234777f5ef0c3d2c" dependencies = [ "bytes 0.5.4", - "futures 0.1.29", + "futures 0.3.4", "log", + "pin-project", "smallvec 1.2.0", - "tokio-io", "unsigned-varint", ] @@ -4685,6 +4712,24 @@ dependencies = [ "url 2.1.1", ] +[[package]] +name = "parity-multiaddr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4db35e222f783ef4e6661873f6c165c4eb7b65e0c408349818517d5705c2d7d3" +dependencies = [ + "arrayref", + "bs58", + "byteorder 1.3.4", + "data-encoding", + "multihash", + "percent-encoding 2.1.0", + "serde", + "static_assertions", + "unsigned-varint", + "url 2.1.1", +] + [[package]] name = "parity-multihash" version = "0.2.3" @@ -4827,9 +4872,9 @@ dependencies = [ [[package]] name = "paste" -version = "0.1.10" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4fb1930692d1b6a9cfabdde3d06ea0a7d186518e2f4d67660d8970e2fa647a" +checksum = "092d791bf7847f70bbd49085489fba25fc2c193571752bff9e36e74e72403932" dependencies = [ "paste-impl", "proc-macro-hack", @@ -4837,9 +4882,9 @@ dependencies = [ [[package]] name = "paste-impl" -version = "0.1.10" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62486e111e571b1e93b710b61e8f493c0013be39629b714cb166bdb06aa5a8a" +checksum = "406c23fb4c45cc6f68a9bbabb8ec7bd6f8cfcbd17e9e8f72c2460282f8325729" dependencies = [ "proc-macro-hack", "proc-macro2", @@ -5848,7 +5893,7 @@ dependencies = [ "substrate-prometheus-endpoint", "tempfile", "time", - "tokio 0.2.16", + "tokio 0.2.13", ] [[package]] @@ -6107,7 +6152,7 @@ dependencies = [ "substrate-test-runtime-client", "substrate-test-runtime-transaction-pool", "tempfile", - "tokio 0.2.16", + "tokio 0.2.13", ] [[package]] @@ -6285,7 +6330,7 @@ dependencies = [ "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", - "tokio 0.2.16", + "tokio 0.2.13", ] [[package]] @@ -6450,7 +6495,7 @@ dependencies = [ "sp-utils", "substrate-test-runtime-client", "threadpool", - "tokio 0.2.16", + "tokio 0.2.13", ] [[package]] @@ -6566,7 +6611,7 @@ dependencies = [ "lazy_static", "log", "netstat2", - "parity-multiaddr", + "parity-multiaddr 0.7.3", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.0", @@ -6866,18 +6911,18 @@ checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" [[package]] name = "serde" -version = "1.0.106" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" +checksum = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.106" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" +checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" dependencies = [ "proc-macro2", "quote 1.0.3", @@ -6886,9 +6931,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.51" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9" +checksum = "78a7a12c167809363ec3bd7329fc0a3369056996de43c4b37ef3cd54a6ce4867" dependencies = [ "itoa", "ryu", @@ -7329,7 +7374,7 @@ dependencies = [ "sp-storage", "substrate-bip39", "tiny-bip39", - "tiny-keccak 2.0.2", + "tiny-keccak 2.0.1", "twox-hash", "wasmi", "zeroize", @@ -7901,7 +7946,7 @@ dependencies = [ "sc-rpc-api", "serde", "sp-storage", - "tokio 0.2.16", + "tokio 0.2.13", ] [[package]] @@ -7937,7 +7982,7 @@ dependencies = [ "hyper 0.13.4", "log", "prometheus", - "tokio 0.2.16", + "tokio 0.2.13", ] [[package]] @@ -8339,9 +8384,9 @@ dependencies = [ [[package]] name = "tiny-keccak" -version = "2.0.2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +checksum = "2953ca5148619bc99695c1274cb54c5275bbb913c6adad87e72eaf8db9787f69" dependencies = [ "crunchy", ] @@ -8382,9 +8427,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.16" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee5a0dd887e37d37390c13ff8ac830f992307fe30a1fff0ab8427af67211ba28" +checksum = "0fa5e81d6bc4e67fe889d5783bd2a128ab2e0cfa487e0be16b6a8d177b101616" dependencies = [ "bytes 0.5.4", "fnv", @@ -8516,7 +8561,7 @@ checksum = "4adb8b3e5f86b707f1b54e7c15b6de52617a823608ccda98a15d3a24222f265a" dependencies = [ "futures-core", "rustls 0.17.0", - "tokio 0.2.16", + "tokio 0.2.13", "webpki", ] @@ -8628,7 +8673,7 @@ dependencies = [ "futures-sink", "log", "pin-project-lite", - "tokio 0.2.16", + "tokio 0.2.13", ] [[package]] @@ -9165,18 +9210,18 @@ dependencies = [ [[package]] name = "wast" -version = "13.0.0" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b20abd8b4a26f7e0d4dd5e357e90a3d555ec190e94472c9b2b27c5b9777f9ae" +checksum = "0615ba420811bcda39cf80e8a1bd75997aec09222bda35165920a07ef15cc695" dependencies = [ "leb128", ] [[package]] name = "wat" -version = "1.0.14" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51a615830ee3e7200b505c441fec09aac2f114deae69df52f215cb828ba112c4" +checksum = "095f615fbfcae695e3a4cea7d9f02f70561c81274c0142f45a12bf1e154d08bd" dependencies = [ "wast", ] diff --git a/Cargo.toml b/Cargo.toml index b582907385..035ae7bc37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -175,3 +175,4 @@ members = [ [profile.release] # Substrate runtime requires unwinding. panic = "unwind" + diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index 9bf20146a9..672f25275c 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -29,7 +29,7 @@ derive_more = { version = "0.99.2" } sc-rpc = { version = "2.0.0-alpha.5", path = "../../../client/rpc" } jsonrpc-core-client = { version = "14.0.3", features = ["http"] } hyper = "0.12.35" -libp2p = "0.16.2" +libp2p = "0.17.0" serde_json = "1.0" [features] diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 3fe4de13e3..7521101ae6 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -18,7 +18,7 @@ codec = { package = "parity-scale-codec", default-features = false, version = "1 derive_more = "0.99.2" futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.16.2", default-features = false, features = ["secp256k1", "libp2p-websocket"] } +libp2p = { version = "0.17.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } log = "0.4.8" prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.5"} prost = "0.6.1" diff --git a/client/authority-discovery/src/lib.rs b/client/authority-discovery/src/lib.rs index 176e8b2e81..45f05e1039 100644 --- a/client/authority-discovery/src/lib.rs +++ b/client/authority-discovery/src/lib.rs @@ -300,7 +300,7 @@ where .map_err(Error::EncodingProto)?; self.network.put_value( - hash_authority_id(key.1.as_ref())?, + hash_authority_id(key.1.as_ref()), signed_addresses, ); } @@ -323,7 +323,7 @@ where for authority_id in authorities.iter() { self.network - .get_value(&hash_authority_id(authority_id.as_ref())?); + .get_value(&hash_authority_id(authority_id.as_ref())); } Ok(()) @@ -408,8 +408,8 @@ where self.addr_cache.retain_ids(&authorities); authorities .into_iter() - .map(|id| hash_authority_id(id.as_ref()).map(|h| (h, id))) - .collect::>>()? + .map(|id| (hash_authority_id(id.as_ref()), id)) + .collect::>() }; // Check if the event origins from an authority in the current authority set. @@ -586,10 +586,8 @@ where } } -fn hash_authority_id(id: &[u8]) -> Result { - libp2p::multihash::encode(libp2p::multihash::Hash::SHA2256, id) - .map(|k| libp2p::kad::record::Key::new(&k)) - .map_err(Error::HashingAuthorityId) +fn hash_authority_id(id: &[u8]) -> libp2p::kad::record::Key { + libp2p::kad::record::Key::new(&libp2p::multihash::Sha2_256::digest(id)) } fn interval_at(start: Instant, duration: Duration) -> Interval { diff --git a/client/authority-discovery/src/tests.rs b/client/authority-discovery/src/tests.rs index d23836d6fa..358376e5db 100644 --- a/client/authority-discovery/src/tests.rs +++ b/client/authority-discovery/src/tests.rs @@ -304,7 +304,7 @@ fn handle_dht_events_with_value_found_should_call_set_priority_group() { // Create sample dht event. - let authority_id_1 = hash_authority_id(key_pair.public().as_ref()).unwrap(); + let authority_id_1 = hash_authority_id(key_pair.public().as_ref()); let address_1: Multiaddr = "/ip6/2001:db8::".parse().unwrap(); let mut serialized_addresses = vec![]; diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index ad2eb2ae0e..c2887ed719 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/sc-network-gossip" [dependencies] futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.16.2", default-features = false, features = ["libp2p-websocket"] } +libp2p = { version = "0.17.0", default-features = false, features = ["websocket"] } log = "0.4.8" lru = "0.4.3" sc-network = { version = "0.8.0-alpha.5", path = "../network" } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 8d67a15c35..5b4813e80a 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -26,7 +26,6 @@ futures = "0.3.4" futures_codec = "0.3.3" futures-timer = "3.0.1" wasm-timer = "0.2" -libp2p = { version = "0.16.2", default-features = false, features = ["libp2p-websocket"] } linked-hash-map = "0.5.2" linked_hash_set = "0.1.3" log = "0.4.8" @@ -59,10 +58,16 @@ unsigned-varint = { version = "0.3.1", features = ["futures", "futures-codec"] } void = "1.0.2" zeroize = "1.0.0" +[dependencies.libp2p] +version = "0.17.0" +default-features = false +features = ["websocket", "kad", "mdns", "ping", "identify", "mplex", "yamux", "noise"] + [dev-dependencies] async-std = "1.5" assert_matches = "1.3" env_logger = "0.7.0" +libp2p = { version = "0.17.0", default-features = false, features = ["secio"] } quickcheck = "0.9.0" rand = "0.7.2" sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } diff --git a/client/network/src/debug_info.rs b/client/network/src/debug_info.rs index 17fb622f7c..e2803cde35 100644 --- a/client/network/src/debug_info.rs +++ b/client/network/src/debug_info.rs @@ -17,14 +17,15 @@ use fnv::FnvHashMap; use futures::prelude::*; use libp2p::Multiaddr; -use libp2p::core::nodes::listeners::ListenerId; +use libp2p::core::connection::{ConnectionId, ListenerId}; use libp2p::core::{ConnectedPoint, either::EitherOutput, PeerId, PublicKey}; use libp2p::swarm::{IntoProtocolsHandler, IntoProtocolsHandlerSelect, ProtocolsHandler}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use libp2p::identify::{Identify, IdentifyEvent, IdentifyInfo}; use libp2p::ping::{Ping, PingConfig, PingEvent, PingSuccess}; use log::{debug, trace, error}; -use std::error; +use smallvec::SmallVec; +use std::{error, io}; use std::collections::hash_map::Entry; use std::pin::Pin; use std::task::{Context, Poll}; @@ -56,14 +57,27 @@ struct NodeInfo { /// When we will remove the entry about this node from the list, or `None` if we're connected /// to the node. info_expire: Option, - /// How we're connected to the node. - endpoint: ConnectedPoint, + /// Non-empty list of connected endpoints, one per connection. + endpoints: SmallVec<[ConnectedPoint; crate::MAX_CONNECTIONS_PER_PEER]>, /// Version reported by the remote, or `None` if unknown. client_version: Option, /// Latest ping time with this node. latest_ping: Option, } +impl NodeInfo { + fn new(endpoint: ConnectedPoint) -> Self { + let mut endpoints = SmallVec::new(); + endpoints.push(endpoint); + NodeInfo { + info_expire: None, + endpoints, + client_version: None, + latest_ping: None, + } + } +} + impl DebugInfoBehaviour { /// Builds a new `DebugInfoBehaviour`. pub fn new( @@ -121,9 +135,9 @@ impl DebugInfoBehaviour { pub struct Node<'a>(&'a NodeInfo); impl<'a> Node<'a> { - /// Returns the endpoint we are connected to or were last connected to. + /// Returns the endpoint of an established connection to the peer. pub fn endpoint(&self) -> &'a ConnectedPoint { - &self.0.endpoint + &self.0.endpoints[0] // `endpoints` are non-empty by definition } /// Returns the latest version information we know of. @@ -168,18 +182,17 @@ impl NetworkBehaviour for DebugInfoBehaviour { list } - fn inject_connected(&mut self, peer_id: PeerId, endpoint: ConnectedPoint) { - self.ping.inject_connected(peer_id.clone(), endpoint.clone()); - self.identify.inject_connected(peer_id.clone(), endpoint.clone()); + fn inject_connected(&mut self, peer_id: &PeerId) { + self.ping.inject_connected(peer_id); + self.identify.inject_connected(peer_id); + } - match self.nodes_info.entry(peer_id) { + fn inject_connection_established(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { + self.ping.inject_connection_established(peer_id, conn, endpoint); + self.identify.inject_connection_established(peer_id, conn, endpoint); + match self.nodes_info.entry(peer_id.clone()) { Entry::Vacant(e) => { - e.insert(NodeInfo { - info_expire: None, - endpoint, - client_version: None, - latest_ping: None, - }); + e.insert(NodeInfo::new(endpoint.clone())); } Entry::Occupied(e) => { let e = e.into_mut(); @@ -188,14 +201,26 @@ impl NetworkBehaviour for DebugInfoBehaviour { e.latest_ping = None; } e.info_expire = None; - e.endpoint = endpoint; + e.endpoints.push(endpoint.clone()); } } } - fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint) { - self.ping.inject_disconnected(peer_id, endpoint.clone()); - self.identify.inject_disconnected(peer_id, endpoint); + fn inject_connection_closed(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { + self.ping.inject_connection_closed(peer_id, conn, endpoint); + self.identify.inject_connection_closed(peer_id, conn, endpoint); + + if let Some(entry) = self.nodes_info.get_mut(peer_id) { + entry.endpoints.retain(|ep| ep != endpoint) + } else { + error!(target: "sub-libp2p", + "Unknown connection to {:?} closed: {:?}", peer_id, endpoint); + } + } + + fn inject_disconnected(&mut self, peer_id: &PeerId) { + self.ping.inject_disconnected(peer_id); + self.identify.inject_disconnected(peer_id); if let Some(entry) = self.nodes_info.get_mut(peer_id) { entry.info_expire = Some(Instant::now() + CACHE_EXPIRE); @@ -205,26 +230,15 @@ impl NetworkBehaviour for DebugInfoBehaviour { } } - fn inject_node_event( + fn inject_event( &mut self, peer_id: PeerId, + connection: ConnectionId, event: <::Handler as ProtocolsHandler>::OutEvent ) { match event { - EitherOutput::First(event) => self.ping.inject_node_event(peer_id, event), - EitherOutput::Second(event) => self.identify.inject_node_event(peer_id, event), - } - } - - fn inject_replaced(&mut self, peer_id: PeerId, closed_endpoint: ConnectedPoint, new_endpoint: ConnectedPoint) { - self.ping.inject_replaced(peer_id.clone(), closed_endpoint.clone(), new_endpoint.clone()); - self.identify.inject_replaced(peer_id.clone(), closed_endpoint, new_endpoint.clone()); - - if let Some(entry) = self.nodes_info.get_mut(&peer_id) { - entry.endpoint = new_endpoint; - } else { - error!(target: "sub-libp2p", - "Disconnected from node we were not connected to {:?}", peer_id); + EitherOutput::First(event) => self.ping.inject_event(peer_id, connection, event), + EitherOutput::Second(event) => self.identify.inject_event(peer_id, connection, event), } } @@ -258,9 +272,9 @@ impl NetworkBehaviour for DebugInfoBehaviour { self.identify.inject_listener_error(id, err); } - fn inject_listener_closed(&mut self, id: ListenerId) { - self.ping.inject_listener_closed(id); - self.identify.inject_listener_closed(id); + fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &io::Error>) { + self.ping.inject_listener_closed(id, reason); + self.identify.inject_listener_closed(id, reason); } fn poll( @@ -283,11 +297,12 @@ impl NetworkBehaviour for DebugInfoBehaviour { }, Poll::Ready(NetworkBehaviourAction::DialAddress { address }) => return Poll::Ready(NetworkBehaviourAction::DialAddress { address }), - Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id }) => - return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id }), - Poll::Ready(NetworkBehaviourAction::SendEvent { peer_id, event }) => - return Poll::Ready(NetworkBehaviourAction::SendEvent { + Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }) => + return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }), + Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, handler, event }) => + return Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, + handler, event: EitherOutput::First(event) }), Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }) => @@ -312,11 +327,12 @@ impl NetworkBehaviour for DebugInfoBehaviour { }, Poll::Ready(NetworkBehaviourAction::DialAddress { address }) => return Poll::Ready(NetworkBehaviourAction::DialAddress { address }), - Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id }) => - return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id }), - Poll::Ready(NetworkBehaviourAction::SendEvent { peer_id, event }) => - return Poll::Ready(NetworkBehaviourAction::SendEvent { + Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }) => + return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }), + Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, handler, event }) => + return Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, + handler, event: EitherOutput::Second(event) }), Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }) => diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index ed5016642b..a72c3cce65 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -47,7 +47,7 @@ use futures::prelude::*; use futures_timer::Delay; -use libp2p::core::{nodes::listeners::ListenerId, ConnectedPoint, Multiaddr, PeerId, PublicKey}; +use libp2p::core::{connection::{ConnectionId, ListenerId}, ConnectedPoint, Multiaddr, PeerId, PublicKey}; use libp2p::swarm::{ProtocolsHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use libp2p::kad::{Kademlia, KademliaEvent, Quorum, Record}; use libp2p::kad::GetClosestPeersError; @@ -58,7 +58,7 @@ use libp2p::{swarm::toggle::Toggle}; use libp2p::mdns::{Mdns, MdnsEvent}; use libp2p::multiaddr::Protocol; use log::{debug, info, trace, warn, error}; -use std::{cmp, collections::VecDeque, time::Duration}; +use std::{cmp, collections::VecDeque, io, time::Duration}; use std::task::{Context, Poll}; use sp_core::hexdisplay::HexDisplay; @@ -149,6 +149,7 @@ impl DiscoveryBehaviour { /// If we didn't know this address before, also generates a `Discovered` event. pub fn add_known_address(&mut self, peer_id: PeerId, addr: Multiaddr) { if self.user_defined.iter().all(|(p, a)| *p != peer_id && *a != addr) { + self.kademlia.add_address(&peer_id, addr.clone()); self.discoveries.push_back(peer_id.clone()); self.user_defined.push((peer_id, addr)); } @@ -259,18 +260,22 @@ impl NetworkBehaviour for DiscoveryBehaviour { list } - fn inject_connected(&mut self, peer_id: PeerId, endpoint: ConnectedPoint) { + fn inject_connection_established(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { self.num_connections += 1; - NetworkBehaviour::inject_connected(&mut self.kademlia, peer_id, endpoint) + NetworkBehaviour::inject_connection_established(&mut self.kademlia, peer_id, conn, endpoint) } - fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint) { + fn inject_connected(&mut self, peer_id: &PeerId) { + NetworkBehaviour::inject_connected(&mut self.kademlia, peer_id) + } + + fn inject_connection_closed(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { self.num_connections -= 1; - NetworkBehaviour::inject_disconnected(&mut self.kademlia, peer_id, endpoint) + NetworkBehaviour::inject_connection_closed(&mut self.kademlia, peer_id, conn, endpoint) } - fn inject_replaced(&mut self, peer_id: PeerId, closed: ConnectedPoint, opened: ConnectedPoint) { - NetworkBehaviour::inject_replaced(&mut self.kademlia, peer_id, closed, opened) + fn inject_disconnected(&mut self, peer_id: &PeerId) { + NetworkBehaviour::inject_disconnected(&mut self.kademlia, peer_id) } fn inject_addr_reach_failure( @@ -282,12 +287,13 @@ impl NetworkBehaviour for DiscoveryBehaviour { NetworkBehaviour::inject_addr_reach_failure(&mut self.kademlia, peer_id, addr, error) } - fn inject_node_event( + fn inject_event( &mut self, peer_id: PeerId, + connection: ConnectionId, event: ::OutEvent, ) { - NetworkBehaviour::inject_node_event(&mut self.kademlia, peer_id, event) + NetworkBehaviour::inject_event(&mut self.kademlia, peer_id, connection, event) } fn inject_new_external_addr(&mut self, addr: &Multiaddr) { @@ -315,9 +321,8 @@ impl NetworkBehaviour for DiscoveryBehaviour { NetworkBehaviour::inject_listener_error(&mut self.kademlia, id, err); } - fn inject_listener_closed(&mut self, id: ListenerId) { - error!(target: "sub-libp2p", "Libp2p listener {:?} closed", id); - NetworkBehaviour::inject_listener_closed(&mut self.kademlia, id); + fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &io::Error>) { + NetworkBehaviour::inject_listener_closed(&mut self.kademlia, id, reason); } fn poll( @@ -340,8 +345,9 @@ impl NetworkBehaviour for DiscoveryBehaviour { while let Poll::Ready(_) = self.next_kad_random_query.poll_unpin(cx) { let actually_started = if self.num_connections < self.discovery_only_if_under_num { let random_peer_id = PeerId::random(); - debug!(target: "sub-libp2p", "Libp2p <= Starting random Kademlia request for \ - {:?}", random_peer_id); + debug!(target: "sub-libp2p", + "Libp2p <= Starting random Kademlia request for {:?}", + random_peer_id); self.kademlia.get_closest_peers(random_peer_id); true @@ -451,10 +457,10 @@ impl NetworkBehaviour for DiscoveryBehaviour { }, NetworkBehaviourAction::DialAddress { address } => return Poll::Ready(NetworkBehaviourAction::DialAddress { address }), - NetworkBehaviourAction::DialPeer { peer_id } => - return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id }), - NetworkBehaviourAction::SendEvent { peer_id, event } => - return Poll::Ready(NetworkBehaviourAction::SendEvent { peer_id, event }), + NetworkBehaviourAction::DialPeer { peer_id, condition } => + return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }), + NetworkBehaviourAction::NotifyHandler { peer_id, handler, event } => + return Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, handler, event }), NetworkBehaviourAction::ReportObservedAddr { address } => return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }), } @@ -482,9 +488,9 @@ impl NetworkBehaviour for DiscoveryBehaviour { }, NetworkBehaviourAction::DialAddress { address } => return Poll::Ready(NetworkBehaviourAction::DialAddress { address }), - NetworkBehaviourAction::DialPeer { peer_id } => - return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id }), - NetworkBehaviourAction::SendEvent { event, .. } => + NetworkBehaviourAction::DialPeer { peer_id, condition } => + return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }), + NetworkBehaviourAction::NotifyHandler { event, .. } => match event {}, // `event` is an enum with no variant NetworkBehaviourAction::ReportObservedAddr { address } => return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }), diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index b425a7763b..d8afa1f153 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -255,3 +255,12 @@ pub use libp2p::{Multiaddr, PeerId}; pub use libp2p::multiaddr; pub use sc_peerset::ReputationChange; + +/// The maximum allowed number of established connections per peer. +/// +/// Typically, and by design of the network behaviours in this crate, +/// there is a single established connection per peer. However, to +/// avoid unnecessary and nondeterministic connection closure in +/// case of (possibly repeated) simultaneous dialing attempts between +/// two peers, the per-peer connection limit is not set to 1 but 2. +const MAX_CONNECTIONS_PER_PEER: usize = 2; diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index bfe8226c8d..365cbcbc52 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -20,7 +20,7 @@ use bytes::{Bytes, BytesMut}; use futures::prelude::*; use generic_proto::{GenericProto, GenericProtoOut}; use libp2p::{Multiaddr, PeerId}; -use libp2p::core::{ConnectedPoint, nodes::listeners::ListenerId}; +use libp2p::core::{ConnectedPoint, connection::{ConnectionId, ListenerId}}; use libp2p::swarm::{ProtocolsHandler, IntoProtocolsHandler}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use sp_core::{ @@ -48,7 +48,7 @@ use std::borrow::Cow; use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; use std::sync::Arc; use std::fmt::Write; -use std::{cmp, num::NonZeroUsize, pin::Pin, task::Poll, time}; +use std::{cmp, io, num::NonZeroUsize, pin::Pin, task::Poll, time}; use log::{log, Level, trace, debug, warn, error}; use crate::chain::{Client, FinalityProofProvider}; use sc_client_api::{ChangesProof, StorageProof}; @@ -1830,20 +1830,29 @@ impl NetworkBehaviour for Protocol { self.behaviour.addresses_of_peer(peer_id) } - fn inject_connected(&mut self, peer_id: PeerId, endpoint: ConnectedPoint) { - self.behaviour.inject_connected(peer_id, endpoint) + fn inject_connection_established(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { + self.behaviour.inject_connection_established(peer_id, conn, endpoint) } - fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint) { - self.behaviour.inject_disconnected(peer_id, endpoint) + fn inject_connection_closed(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { + self.behaviour.inject_connection_closed(peer_id, conn, endpoint) } - fn inject_node_event( + fn inject_connected(&mut self, peer_id: &PeerId) { + self.behaviour.inject_connected(peer_id) + } + + fn inject_disconnected(&mut self, peer_id: &PeerId) { + self.behaviour.inject_disconnected(peer_id) + } + + fn inject_event( &mut self, peer_id: PeerId, + connection: ConnectionId, event: <::Handler as ProtocolsHandler>::OutEvent, ) { - self.behaviour.inject_node_event(peer_id, event) + self.behaviour.inject_event(peer_id, connection, event) } fn poll( @@ -1900,10 +1909,10 @@ impl NetworkBehaviour for Protocol { Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)) => ev, Poll::Ready(NetworkBehaviourAction::DialAddress { address }) => return Poll::Ready(NetworkBehaviourAction::DialAddress { address }), - Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id }) => - return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id }), - Poll::Ready(NetworkBehaviourAction::SendEvent { peer_id, event }) => - return Poll::Ready(NetworkBehaviourAction::SendEvent { peer_id, event }), + Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }) => + return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }), + Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, handler, event }) => + return Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, handler, event }), Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }) => return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }), }; @@ -1967,10 +1976,6 @@ impl NetworkBehaviour for Protocol { } } - fn inject_replaced(&mut self, peer_id: PeerId, closed_endpoint: ConnectedPoint, new_endpoint: ConnectedPoint) { - self.behaviour.inject_replaced(peer_id, closed_endpoint, new_endpoint) - } - fn inject_addr_reach_failure( &mut self, peer_id: Option<&PeerId>, @@ -2000,8 +2005,8 @@ impl NetworkBehaviour for Protocol { self.behaviour.inject_listener_error(id, err); } - fn inject_listener_closed(&mut self, id: ListenerId) { - self.behaviour.inject_listener_closed(id); + fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &io::Error>) { + self.behaviour.inject_listener_closed(id, reason); } } diff --git a/client/network/src/protocol/block_requests.rs b/client/network/src/protocol/block_requests.rs index 5a947c0b6b..6af5023d39 100644 --- a/client/network/src/protocol/block_requests.rs +++ b/client/network/src/protocol/block_requests.rs @@ -35,6 +35,7 @@ use libp2p::{ ConnectedPoint, Multiaddr, PeerId, + connection::ConnectionId, upgrade::{InboundUpgrade, ReadOneError, UpgradeInfo, Negotiated}, upgrade::{DeniedUpgrade, read_one, write_one} }, @@ -43,6 +44,7 @@ use libp2p::{ NetworkBehaviour, NetworkBehaviourAction, OneShotHandler, + OneShotHandlerConfig, PollParameters, SubstreamProtocol } @@ -257,20 +259,27 @@ where max_request_len: self.config.max_request_len, protocol: self.config.protocol.clone(), }; - OneShotHandler::new(SubstreamProtocol::new(p), self.config.inactivity_timeout) + let mut cfg = OneShotHandlerConfig::default(); + cfg.inactive_timeout = self.config.inactivity_timeout; + OneShotHandler::new(SubstreamProtocol::new(p), cfg) } fn addresses_of_peer(&mut self, _: &PeerId) -> Vec { Vec::new() } - fn inject_connected(&mut self, _peer: PeerId, _info: ConnectedPoint) { + fn inject_connected(&mut self, _peer: &PeerId) { } - fn inject_disconnected(&mut self, _peer: &PeerId, _info: ConnectedPoint) { + fn inject_disconnected(&mut self, _peer: &PeerId) { } - fn inject_node_event(&mut self, peer: PeerId, Request(request, mut stream): Request) { + fn inject_event( + &mut self, + peer: PeerId, + connection: ConnectionId, + Request(request, mut stream): Request + ) { match self.on_block_request(&peer, &request) { Ok(res) => { log::trace!("enqueueing block response for peer {} with {} blocks", peer, res.blocks.len()); diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index c398f6df2d..b38a97cb8f 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -21,8 +21,14 @@ use crate::protocol::generic_proto::upgrade::RegisteredProtocol; use bytes::BytesMut; use fnv::FnvHashMap; use futures::prelude::*; -use libp2p::core::{ConnectedPoint, Multiaddr, PeerId}; -use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; +use libp2p::core::{ConnectedPoint, Multiaddr, PeerId, connection::ConnectionId}; +use libp2p::swarm::{ + DialPeerCondition, + NetworkBehaviour, + NetworkBehaviourAction, + NotifyHandler, + PollParameters +}; use log::{debug, error, trace, warn}; use prometheus_endpoint::HistogramVec; use rand::distributions::{Distribution as _, Uniform}; @@ -32,15 +38,16 @@ use std::{borrow::Cow, cmp, collections::hash_map::Entry}; use std::{error, mem, pin::Pin, str, time::Duration}; use wasm_timer::Instant; -/// Network behaviour that handles opening substreams for custom protocols with other nodes. +/// Network behaviour that handles opening substreams for custom protocols with other peers. /// /// ## Legacy vs new protocol /// /// The `GenericProto` behaves as following: /// -/// - Whenever a connection is established, we open a single substream (called "legay protocol" in -/// the source code). This substream name depends on the `protocol_id` and `versions` passed at -/// initialization. If the remote refuses this substream, we close the connection. +/// - Whenever a connection is established, we open a single substream (called "legacy protocol" in +/// the source code) on that connection. This substream name depends on the `protocol_id` and +/// `versions` passed at initialization. If the remote refuses this substream, we close the +/// connection. /// /// - For each registered protocol, we also open an additional substream for this protocol. If the /// remote refuses this substream, then it's fine. @@ -55,27 +62,51 @@ use wasm_timer::Instant; /// /// - The libp2p swarm that opens new connections and reports disconnects. /// - The connection handler (see `handler.rs`) that handles individual connections. -/// - The peerset manager (PSM) that requests links to nodes to be established or broken. +/// - The peerset manager (PSM) that requests links to peers to be established or broken. /// - The external API, that requires knowledge of the links that have been established. /// /// Each connection handler can be in four different states: Enabled+Open, Enabled+Closed, /// Disabled+Open, or Disabled+Closed. The Enabled/Disabled component must be in sync with the /// peerset manager. For example, if the peerset manager requires a disconnection, we disable the -/// existing handler. The Open/Closed component must be in sync with the external API. +/// connection handlers of that peer. The Open/Closed component must be in sync with the external +/// API. /// -/// However a connection handler only exists if we are actually connected to a node. What this -/// means is that there are six possible states for each node: Disconnected, Dialing (trying to -/// reach it), Enabled+Open, Enabled+Closed, Disabled+open, Disabled+Closed. Most notably, the -/// Dialing state must correspond to a "link established" state in the peerset manager. In other -/// words, the peerset manager doesn't differentiate whether we are dialing a node or connected -/// to it. +/// However, a connection handler for a peer only exists if we are actually connected to that peer. +/// What this means is that there are six possible states for each peer: Disconnected, Dialing +/// (trying to connect), Enabled+Open, Enabled+Closed, Disabled+Open, Disabled+Closed. +/// Most notably, the Dialing state must correspond to a "link established" state in the peerset +/// manager. In other words, the peerset manager doesn't differentiate whether we are dialing a +/// peer or connected to it. /// -/// Additionally, there also exists a "banning" system. If we fail to dial a node, we "ban" it for -/// a few seconds. If the PSM requests a node that is in the "banned" state, then we delay the -/// actual dialing attempt until after the ban expires, but the PSM will still consider the link -/// to be established. -/// Note that this "banning" system is not an actual ban. If a "banned" node tries to connect to -/// us, we accept the connection. The "banning" system is only about delaying dialing attempts. +/// There may be multiple connections to a peer. However, the status of a peer on +/// the API of this behaviour and towards the peerset manager is aggregated in +/// the following way: +/// +/// 1. The enabled/disabled status is the same across all connections, as +/// decided by the peerset manager. +/// 2. `send_packet` and `write_notification` always send all data over +/// the same connection to preserve the ordering provided by the transport, +/// as long as that connection is open. If it closes, a second open +/// connection may take over, if one exists, but that case should be no +/// different than a single connection failing and being re-established +/// in terms of potential reordering and dropped messages. Messages can +/// be received on any connection. +/// 3. The behaviour reports `GenericProtoOut::CustomProtocolOpen` when the +/// first connection reports `NotifsHandlerOut::Open`. +/// 4. The behaviour reports `GenericProtoOut::CustomProtocolClosed` when the +/// last connection reports `NotifsHandlerOut::Closed`. +/// +/// In this way, the number of actual established connections to the peer is +/// an implementation detail of this behaviour. Note that, in practice and at +/// the time of this writing, there may be at most two connections to a peer +/// and only as a result of simultaneous dialing. However, the implementation +/// accommodates for any number of connections. +/// +/// Additionally, there also exists a "banning" system. If we fail to dial a peer, we "ban" it for +/// a few seconds. If the PSM requests connecting to a peer that is currently "banned", the next +/// dialing attempt is delayed until after the ban expires. However, the PSM will still consider +/// the peer to be connected. This "ban" is thus not a ban in a strict sense: If a "banned" peer +/// tries to connect, the connection is accepted. A ban only delays dialing attempts. /// pub struct GenericProto { /// Legacy protocol to open with peers. Never modified. @@ -113,14 +144,14 @@ enum PeerState { /// the state machine code. Poisoned, - /// The peer misbehaved. If the PSM wants us to connect to this node, we will add an artificial + /// The peer misbehaved. If the PSM wants us to connect to this peer, we will add an artificial /// delay to the connection. Banned { - /// Until when the node is banned. + /// Until when the peer is banned. until: Instant, }, - /// The peerset requested that we connect to this peer. We are not connected to this node. + /// The peerset requested that we connect to this peer. We are currently not connected. PendingRequest { /// When to actually start dialing. timer: futures_timer::Delay, @@ -131,16 +162,13 @@ enum PeerState { /// The peerset requested that we connect to this peer. We are currently dialing this peer. Requested, - /// We are connected to this peer but the peerset refused it. This peer can still perform - /// Kademlia queries and such, but should get disconnected in a few seconds. + /// We are connected to this peer but the peerset refused it. + /// + /// We may still have ongoing traffic with that peer, but it should cease shortly. Disabled { - /// How we are connected to this peer. - connected_point: ConnectedPoint, - /// If true, we still have a custom protocol open with it. It will likely get closed in - /// a short amount of time, but we need to keep the information in order to not have a - /// state mismatch. - open: bool, - /// If `Some`, the node is banned until the given `Instant`. + /// The connections that are currently open for custom protocol traffic. + open: SmallVec<[ConnectionId; crate::MAX_CONNECTIONS_PER_PEER]>, + /// If `Some`, any dial attempts to this peer are delayed until the given `Instant`. banned_until: Option, }, @@ -148,12 +176,8 @@ enum PeerState { /// will be enabled when `timer` fires. This peer can still perform Kademlia queries and such, /// but should get disconnected in a few seconds. DisabledPendingEnable { - /// How we are connected to this peer. - connected_point: ConnectedPoint, - /// If true, we still have a custom protocol open with it. It will likely get closed in - /// a short amount of time, but we need to keep the information in order to not have a - /// state mismatch. - open: bool, + /// The connections that are currently open for custom protocol traffic. + open: SmallVec<[ConnectionId; crate::MAX_CONNECTIONS_PER_PEER]>, /// When to enable this remote. timer: futures_timer::Delay, /// When the `timer` will trigger. @@ -163,33 +187,41 @@ enum PeerState { /// We are connected to this peer and the peerset has accepted it. The handler is in the /// enabled state. Enabled { - /// How we are connected to this peer. - connected_point: ConnectedPoint, - /// If true, we have a custom protocol open with this peer. - open: bool, + /// The connections that are currently open for custom protocol traffic. + open: SmallVec<[ConnectionId; crate::MAX_CONNECTIONS_PER_PEER]>, }, - /// We are connected to this peer, and we sent an incoming message to the peerset. The handler - /// is in initialization mode. We are waiting for the Accept or Reject from the peerset. There - /// is a corresponding entry in `incoming`. - Incoming { - /// How we are connected to this peer. - connected_point: ConnectedPoint, - }, + /// We received an incoming connection from this peer and forwarded that + /// connection request to the peerset. The connection handlers are waiting + /// for initialisation, i.e. to be enabled or disabled based on whether + /// the peerset accepts or rejects the peer. + Incoming, } impl PeerState { - /// True if we have an open channel with that node. + /// True if there exists an established connection to tbe peer + /// that is open for custom protocol traffic. fn is_open(&self) -> bool { + self.get_open().is_some() + } + + /// Returns the connection ID of the first established connection + /// that is open for custom protocol traffic. + fn get_open(&self) -> Option { match self { - PeerState::Poisoned => false, - PeerState::Banned { .. } => false, - PeerState::PendingRequest { .. } => false, - PeerState::Requested => false, - PeerState::Disabled { open, .. } => *open, - PeerState::DisabledPendingEnable { open, .. } => *open, - PeerState::Enabled { open, .. } => *open, - PeerState::Incoming { .. } => false, + PeerState::Disabled { open, .. } | + PeerState::DisabledPendingEnable { open, .. } | + PeerState::Enabled { open, .. } => + if !open.is_empty() { + Some(open[0]) + } else { + None + } + PeerState::Poisoned => None, + PeerState::Banned { .. } => None, + PeerState::PendingRequest { .. } => None, + PeerState::Requested => None, + PeerState::Incoming { .. } => None, } } @@ -211,7 +243,7 @@ impl PeerState { /// State of an "incoming" message sent to the peer set manager. #[derive(Debug)] struct IncomingPeer { - /// Id of the node that is concerned. + /// Id of the remote peer of the incoming connection. peer_id: PeerId, /// If true, this "incoming" still corresponds to an actual connection. If false, then the /// connection corresponding to it has been closed or replaced already. @@ -225,10 +257,8 @@ struct IncomingPeer { pub enum GenericProtoOut { /// Opened a custom protocol with the remote. CustomProtocolOpen { - /// Id of the node we have opened a connection with. + /// Id of the peer we are connected to. peer_id: PeerId, - /// Endpoint used for this custom protocol. - endpoint: ConnectedPoint, }, /// Closed a custom protocol with the remote. @@ -316,7 +346,7 @@ impl GenericProto { self.peers.iter().filter(|(_, state)| state.is_open()).map(|(id, _)| id) } - /// Returns true if we have a channel open with this node. + /// Returns true if we have an open connection to the given peer. pub fn is_open(&self, peer_id: &PeerId) -> bool { self.peers.get(peer_id).map(|p| p.is_open()).unwrap_or(false) } @@ -327,8 +357,8 @@ impl GenericProto { self.disconnect_peer_inner(peer_id, None); } - /// Inner implementation of `disconnect_peer`. If `ban` is `Some`, we ban the node for the - /// specific duration. + /// Inner implementation of `disconnect_peer`. If `ban` is `Some`, we ban the peer + /// for the specific duration. fn disconnect_peer_inner(&mut self, peer_id: &PeerId, ban: Option) { let mut entry = if let Entry::Occupied(entry) = self.peers.entry(peer_id.clone()) { entry @@ -344,7 +374,11 @@ impl GenericProto { st @ PeerState::Banned { .. } => *entry.into_mut() = st, // DisabledPendingEnable => Disabled. - PeerState::DisabledPendingEnable { open, connected_point, timer_deadline, .. } => { + PeerState::DisabledPendingEnable { + open, + timer_deadline, + timer: _ + } => { debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", peer_id); self.peerset.dropped(peer_id.clone()); let banned_until = Some(if let Some(ban) = ban { @@ -352,24 +386,31 @@ impl GenericProto { } else { timer_deadline }); - *entry.into_mut() = PeerState::Disabled { open, connected_point, banned_until } + *entry.into_mut() = PeerState::Disabled { + open, + banned_until + } }, // Enabled => Disabled. - PeerState::Enabled { open, connected_point } => { + PeerState::Enabled { open } => { debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", peer_id); self.peerset.dropped(peer_id.clone()); debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", peer_id); - self.events.push(NetworkBehaviourAction::SendEvent { + self.events.push(NetworkBehaviourAction::NotifyHandler { peer_id: peer_id.clone(), + handler: NotifyHandler::All, event: NotifsHandlerIn::Disable, }); let banned_until = ban.map(|dur| Instant::now() + dur); - *entry.into_mut() = PeerState::Disabled { open, connected_point, banned_until } + *entry.into_mut() = PeerState::Disabled { + open, + banned_until + } }, // Incoming => Disabled. - PeerState::Incoming { connected_point, .. } => { + PeerState::Incoming => { let inc = if let Some(inc) = self.incoming.iter_mut() .find(|i| i.peer_id == *entry.key() && i.alive) { inc @@ -381,12 +422,16 @@ impl GenericProto { inc.alive = false; debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", peer_id); - self.events.push(NetworkBehaviourAction::SendEvent { + self.events.push(NetworkBehaviourAction::NotifyHandler { peer_id: peer_id.clone(), + handler: NotifyHandler::All, event: NotifsHandlerIn::Disable, }); let banned_until = ban.map(|dur| Instant::now() + dur); - *entry.into_mut() = PeerState::Disabled { open: false, connected_point, banned_until } + *entry.into_mut() = PeerState::Disabled { + open: SmallVec::new(), + banned_until + } }, PeerState::Poisoned => @@ -441,9 +486,15 @@ impl GenericProto { message: impl Into>, encoded_fallback_message: Vec, ) { - if !self.is_open(target) { - return; - } + let conn = match self.peers.get(target).and_then(|p| p.get_open()) { + None => { + debug!(target: "sub-libp2p", + "Tried to sent notification to {:?} without an open channel.", + target); + return + }, + Some(conn) => conn + }; trace!( target: "sub-libp2p", @@ -453,8 +504,9 @@ impl GenericProto { ); trace!(target: "sub-libp2p", "Handler({:?}) <= Packet", target); - self.events.push(NetworkBehaviourAction::SendEvent { + self.events.push(NetworkBehaviourAction::NotifyHandler { peer_id: target.clone(), + handler: NotifyHandler::One(conn), event: NotifsHandlerIn::SendNotification { message: message.into(), encoded_fallback_message, @@ -470,14 +522,21 @@ impl GenericProto { /// Also note that even we have a valid open substream, it may in fact be already closed /// without us knowing, in which case the packet will not be received. pub fn send_packet(&mut self, target: &PeerId, message: Vec) { - if !self.is_open(target) { - return; - } + let conn = match self.peers.get(target).and_then(|p| p.get_open()) { + None => { + debug!(target: "sub-libp2p", + "Tried to sent packet to {:?} without an open channel.", + target); + return + } + Some(conn) => conn + }; trace!(target: "sub-libp2p", "External API => Packet for {:?}", target); trace!(target: "sub-libp2p", "Handler({:?}) <= Packet", target); - self.events.push(NetworkBehaviourAction::SendEvent { + self.events.push(NetworkBehaviourAction::NotifyHandler { peer_id: target.clone(), + handler: NotifyHandler::One(conn), event: NotifsHandlerIn::SendLegacy { message, } @@ -489,7 +548,7 @@ impl GenericProto { self.peerset.debug_info() } - /// Function that is called when the peerset wants us to connect to a node. + /// Function that is called when the peerset wants us to connect to a peer. fn peerset_report_connect(&mut self, peer_id: PeerId) { let mut occ_entry = match self.peers.entry(peer_id) { Entry::Occupied(entry) => entry, @@ -497,7 +556,10 @@ impl GenericProto { // If there's no entry in `self.peers`, start dialing. debug!(target: "sub-libp2p", "PSM => Connect({:?}): Starting to connect", entry.key()); debug!(target: "sub-libp2p", "Libp2p <= Dial {:?}", entry.key()); - self.events.push(NetworkBehaviourAction::DialPeer { peer_id: entry.key().clone() }); + self.events.push(NetworkBehaviourAction::DialPeer { + peer_id: entry.key().clone(), + condition: DialPeerCondition::Disconnected + }); entry.insert(PeerState::Requested); return; } @@ -518,36 +580,41 @@ impl GenericProto { PeerState::Banned { .. } => { debug!(target: "sub-libp2p", "PSM => Connect({:?}): Starting to connect", occ_entry.key()); debug!(target: "sub-libp2p", "Libp2p <= Dial {:?}", occ_entry.key()); - self.events.push(NetworkBehaviourAction::DialPeer { peer_id: occ_entry.key().clone() }); + self.events.push(NetworkBehaviourAction::DialPeer { + peer_id: occ_entry.key().clone(), + condition: DialPeerCondition::Disconnected + }); *occ_entry.into_mut() = PeerState::Requested; }, - PeerState::Disabled { open, ref connected_point, banned_until: Some(ref banned) } - if *banned > now => { - debug!(target: "sub-libp2p", "PSM => Connect({:?}): Has idle connection through \ - {:?} but node is banned until {:?}", occ_entry.key(), connected_point, banned); + PeerState::Disabled { + open, + banned_until: Some(ref banned) + } if *banned > now => { + debug!(target: "sub-libp2p", "PSM => Connect({:?}): But peer is banned until {:?}", + occ_entry.key(), banned); *occ_entry.into_mut() = PeerState::DisabledPendingEnable { - connected_point: connected_point.clone(), open, timer: futures_timer::Delay::new(banned.clone() - now), timer_deadline: banned.clone(), }; }, - PeerState::Disabled { open, connected_point, banned_until: _ } => { - debug!(target: "sub-libp2p", "PSM => Connect({:?}): Enabling previously-idle \ - connection through {:?}", occ_entry.key(), connected_point); + PeerState::Disabled { open, banned_until: _ } => { + debug!(target: "sub-libp2p", "PSM => Connect({:?}): Enabling connections.", + occ_entry.key()); debug!(target: "sub-libp2p", "Handler({:?}) <= Enable", occ_entry.key()); - self.events.push(NetworkBehaviourAction::SendEvent { + self.events.push(NetworkBehaviourAction::NotifyHandler { peer_id: occ_entry.key().clone(), + handler: NotifyHandler::All, event: NotifsHandlerIn::Enable, }); - *occ_entry.into_mut() = PeerState::Enabled { connected_point, open }; + *occ_entry.into_mut() = PeerState::Enabled { open }; }, - PeerState::Incoming { connected_point, .. } => { - debug!(target: "sub-libp2p", "PSM => Connect({:?}): Enabling incoming \ - connection through {:?}", occ_entry.key(), connected_point); + PeerState::Incoming => { + debug!(target: "sub-libp2p", "PSM => Connect({:?}): Enabling connections.", + occ_entry.key()); if let Some(inc) = self.incoming.iter_mut() .find(|i| i.peer_id == *occ_entry.key() && i.alive) { inc.alive = false; @@ -556,26 +623,30 @@ impl GenericProto { incoming for incoming peer") } debug!(target: "sub-libp2p", "Handler({:?}) <= Enable", occ_entry.key()); - self.events.push(NetworkBehaviourAction::SendEvent { + self.events.push(NetworkBehaviourAction::NotifyHandler { peer_id: occ_entry.key().clone(), + handler: NotifyHandler::All, event: NotifsHandlerIn::Enable, }); - *occ_entry.into_mut() = PeerState::Enabled { connected_point, open: false }; + *occ_entry.into_mut() = PeerState::Enabled { open: SmallVec::new() }; }, st @ PeerState::Enabled { .. } => { - warn!(target: "sub-libp2p", "PSM => Connect({:?}): Already connected to this \ - peer", occ_entry.key()); + warn!(target: "sub-libp2p", + "PSM => Connect({:?}): Already connected.", + occ_entry.key()); *occ_entry.into_mut() = st; }, st @ PeerState::DisabledPendingEnable { .. } => { - warn!(target: "sub-libp2p", "PSM => Connect({:?}): Already have an idle \ - connection to this peer and waiting to enable it", occ_entry.key()); + warn!(target: "sub-libp2p", + "PSM => Connect({:?}): Already pending enabling.", + occ_entry.key()); *occ_entry.into_mut() = st; }, st @ PeerState::Requested { .. } | st @ PeerState::PendingRequest { .. } => { - warn!(target: "sub-libp2p", "PSM => Connect({:?}): Received a previous \ - request for that peer", occ_entry.key()); + warn!(target: "sub-libp2p", + "PSM => Connect({:?}): Duplicate request.", + occ_entry.key()); *occ_entry.into_mut() = st; }, @@ -584,55 +655,63 @@ impl GenericProto { } } - /// Function that is called when the peerset wants us to disconnect from a node. + /// Function that is called when the peerset wants us to disconnect from a peer. fn peerset_report_disconnect(&mut self, peer_id: PeerId) { let mut entry = match self.peers.entry(peer_id) { Entry::Occupied(entry) => entry, Entry::Vacant(entry) => { - debug!(target: "sub-libp2p", "PSM => Drop({:?}): Node already disabled", entry.key()); + debug!(target: "sub-libp2p", "PSM => Drop({:?}): Already disabled.", entry.key()); return } }; match mem::replace(entry.get_mut(), PeerState::Poisoned) { st @ PeerState::Disabled { .. } | st @ PeerState::Banned { .. } => { - debug!(target: "sub-libp2p", "PSM => Drop({:?}): Node already disabled", entry.key()); + debug!(target: "sub-libp2p", "PSM => Drop({:?}): Already disabled.", entry.key()); *entry.into_mut() = st; }, - PeerState::DisabledPendingEnable { open, connected_point, timer_deadline, .. } => { - debug!(target: "sub-libp2p", "PSM => Drop({:?}): Interrupting pending \ - enable", entry.key()); + PeerState::DisabledPendingEnable { + open, + timer_deadline, + timer: _ + } => { + debug!(target: "sub-libp2p", + "PSM => Drop({:?}): Interrupting pending enabling.", + entry.key()); *entry.into_mut() = PeerState::Disabled { open, - connected_point, banned_until: Some(timer_deadline), }; }, - PeerState::Enabled { open, connected_point } => { - debug!(target: "sub-libp2p", "PSM => Drop({:?}): Disabling connection", entry.key()); + PeerState::Enabled { open } => { + debug!(target: "sub-libp2p", "PSM => Drop({:?}): Disabling connections.", entry.key()); debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", entry.key()); - self.events.push(NetworkBehaviourAction::SendEvent { + self.events.push(NetworkBehaviourAction::NotifyHandler { peer_id: entry.key().clone(), + handler: NotifyHandler::All, event: NotifsHandlerIn::Disable, }); - *entry.into_mut() = PeerState::Disabled { open, connected_point, banned_until: None } + *entry.into_mut() = PeerState::Disabled { + open, + banned_until: None + } }, - st @ PeerState::Incoming { .. } => { - error!(target: "sub-libp2p", "PSM => Drop({:?}): Was in incoming mode", + st @ PeerState::Incoming => { + error!(target: "sub-libp2p", "PSM => Drop({:?}): Not enabled (Incoming).", entry.key()); *entry.into_mut() = st; }, PeerState::Requested => { // We don't cancel dialing. Libp2p doesn't expose that on purpose, as other - // sub-systems (such as the discovery mechanism) may require dialing this node as + // sub-systems (such as the discovery mechanism) may require dialing this peer as // well at the same time. - debug!(target: "sub-libp2p", "PSM => Drop({:?}): Was not yet connected", entry.key()); + debug!(target: "sub-libp2p", "PSM => Drop({:?}): Not yet connected.", entry.key()); entry.remove(); }, PeerState::PendingRequest { timer_deadline, .. } => { - debug!(target: "sub-libp2p", "PSM => Drop({:?}): Was not yet connected", entry.key()); + debug!(target: "sub-libp2p", "PSM => Drop({:?}): Not yet connected", entry.key()); *entry.into_mut() = PeerState::Banned { until: timer_deadline } }, @@ -641,7 +720,8 @@ impl GenericProto { } } - /// Function that is called when the peerset wants us to accept an incoming node. + /// Function that is called when the peerset wants us to accept a connection + /// request from a peer. fn peerset_report_accept(&mut self, index: sc_peerset::IncomingIndex) { let incoming = if let Some(pos) = self.incoming.iter().position(|i| i.incoming_id == index) { self.incoming.remove(pos) @@ -658,34 +738,25 @@ impl GenericProto { return } - let state = if let Some(state) = self.peers.get_mut(&incoming.peer_id) { - state - } else { - error!(target: "sub-libp2p", "State mismatch in libp2p: no entry in peers \ - corresponding to an alive incoming"); - return - }; - - let connected_point = if let PeerState::Incoming { connected_point } = state { - connected_point.clone() - } else { - error!(target: "sub-libp2p", "State mismatch in libp2p: entry in peers corresponding \ - to an alive incoming is not in incoming state"); - return - }; - - debug!(target: "sub-libp2p", "PSM => Accept({:?}, {:?}): Enabling connection \ - through {:?}", index, incoming.peer_id, connected_point); - debug!(target: "sub-libp2p", "Handler({:?}) <= Enable", incoming.peer_id); - self.events.push(NetworkBehaviourAction::SendEvent { - peer_id: incoming.peer_id, - event: NotifsHandlerIn::Enable, - }); - - *state = PeerState::Enabled { open: false, connected_point }; + match self.peers.get_mut(&incoming.peer_id) { + Some(state @ PeerState::Incoming) => { + debug!(target: "sub-libp2p", "PSM => Accept({:?}, {:?}): Enabling connections.", + index, incoming.peer_id); + debug!(target: "sub-libp2p", "Handler({:?}) <= Enable", incoming.peer_id); + self.events.push(NetworkBehaviourAction::NotifyHandler { + peer_id: incoming.peer_id, + handler: NotifyHandler::All, + event: NotifsHandlerIn::Enable, + }); + *state = PeerState::Enabled { open: SmallVec::new() }; + } + peer => error!(target: "sub-libp2p", + "State mismatch in libp2p: Expected alive incoming. Got {:?}.", + peer) + } } - /// Function that is called when the peerset wants us to reject an incoming node. + /// Function that is called when the peerset wants us to reject an incoming peer. fn peerset_report_reject(&mut self, index: sc_peerset::IncomingIndex) { let incoming = if let Some(pos) = self.incoming.iter().position(|i| i.incoming_id == index) { self.incoming.remove(pos) @@ -700,30 +771,25 @@ impl GenericProto { return } - let state = if let Some(state) = self.peers.get_mut(&incoming.peer_id) { - state - } else { - error!(target: "sub-libp2p", "State mismatch in libp2p: no entry in peers \ - corresponding to an alive incoming"); - return - }; - - let connected_point = if let PeerState::Incoming { connected_point } = state { - connected_point.clone() - } else { - error!(target: "sub-libp2p", "State mismatch in libp2p: entry in peers corresponding \ - to an alive incoming is not in incoming state"); - return - }; - - debug!(target: "sub-libp2p", "PSM => Reject({:?}, {:?}): Rejecting connection through \ - {:?}", index, incoming.peer_id, connected_point); - debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", incoming.peer_id); - self.events.push(NetworkBehaviourAction::SendEvent { - peer_id: incoming.peer_id, - event: NotifsHandlerIn::Disable, - }); - *state = PeerState::Disabled { open: false, connected_point, banned_until: None }; + match self.peers.get_mut(&incoming.peer_id) { + Some(state @ PeerState::Incoming) => { + debug!(target: "sub-libp2p", "PSM => Reject({:?}, {:?}): Rejecting connections.", + index, incoming.peer_id); + debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", incoming.peer_id); + self.events.push(NetworkBehaviourAction::NotifyHandler { + peer_id: incoming.peer_id, + handler: NotifyHandler::All, + event: NotifsHandlerIn::Disable, + }); + *state = PeerState::Disabled { + open: SmallVec::new(), + banned_until: None + }; + } + peer => error!(target: "sub-libp2p", + "State mismatch in libp2p: Expected alive incoming. Got {:?}.", + peer) + } } } @@ -743,26 +809,32 @@ impl NetworkBehaviour for GenericProto { Vec::new() } - fn inject_connected(&mut self, peer_id: PeerId, connected_point: ConnectedPoint) { - match (self.peers.entry(peer_id.clone()).or_insert(PeerState::Poisoned), connected_point) { - (st @ &mut PeerState::Requested, connected_point) | - (st @ &mut PeerState::PendingRequest { .. }, connected_point) => { - debug!(target: "sub-libp2p", "Libp2p => Connected({:?}): Connection \ - requested by PSM (through {:?})", peer_id, connected_point + fn inject_connected(&mut self, _: &PeerId) { + } + + fn inject_connection_established(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { + debug!(target: "sub-libp2p", "Libp2p => Connection ({:?},{:?}) to {} established.", + conn, endpoint, peer_id); + match (self.peers.entry(peer_id.clone()).or_insert(PeerState::Poisoned), endpoint) { + (st @ &mut PeerState::Requested, endpoint) | + (st @ &mut PeerState::PendingRequest { .. }, endpoint) => { + debug!(target: "sub-libp2p", + "Libp2p => Connected({}, {:?}): Connection was requested by PSM.", + peer_id, endpoint ); - debug!(target: "sub-libp2p", "Handler({:?}) <= Enable", peer_id); - self.events.push(NetworkBehaviourAction::SendEvent { + *st = PeerState::Enabled { open: SmallVec::new() }; + self.events.push(NetworkBehaviourAction::NotifyHandler { peer_id: peer_id.clone(), - event: NotifsHandlerIn::Enable, + handler: NotifyHandler::One(*conn), + event: NotifsHandlerIn::Enable }); - *st = PeerState::Enabled { open: false, connected_point }; } - // Note: it may seem weird that "Banned" nodes get treated as if there were absent. + // Note: it may seem weird that "Banned" peers get treated as if they were absent. // This is because the word "Banned" means "temporarily prevent outgoing connections to - // this node", and not "banned" in the sense that we would refuse the node altogether. - (st @ &mut PeerState::Poisoned, connected_point @ ConnectedPoint::Listener { .. }) | - (st @ &mut PeerState::Banned { .. }, connected_point @ ConnectedPoint::Listener { .. }) => { + // this peer", and not "banned" in the sense that we would refuse the peer altogether. + (st @ &mut PeerState::Poisoned, endpoint @ ConnectedPoint::Listener { .. }) | + (st @ &mut PeerState::Banned { .. }, endpoint @ ConnectedPoint::Listener { .. }) => { let incoming_id = self.next_incoming_index.clone(); self.next_incoming_index.0 = match self.next_incoming_index.0.checked_add(1) { Some(v) => v, @@ -771,61 +843,79 @@ impl NetworkBehaviour for GenericProto { return } }; - debug!(target: "sub-libp2p", "Libp2p => Connected({:?}): Incoming connection", - peer_id); - debug!(target: "sub-libp2p", "PSM <= Incoming({:?}, {:?}): Through {:?}", - incoming_id, peer_id, connected_point); + debug!(target: "sub-libp2p", "Libp2p => Connected({}, {:?}): Incoming connection", + peer_id, endpoint); + debug!(target: "sub-libp2p", "PSM <= Incoming({}, {:?}).", + peer_id, incoming_id); self.peerset.incoming(peer_id.clone(), incoming_id); self.incoming.push(IncomingPeer { peer_id: peer_id.clone(), alive: true, incoming_id, }); - *st = PeerState::Incoming { connected_point }; + *st = PeerState::Incoming { }; } - (st @ &mut PeerState::Poisoned, connected_point) | - (st @ &mut PeerState::Banned { .. }, connected_point) => { + (st @ &mut PeerState::Poisoned, endpoint) | + (st @ &mut PeerState::Banned { .. }, endpoint) => { let banned_until = if let PeerState::Banned { until } = st { Some(*until) } else { None }; - debug!(target: "sub-libp2p", "Libp2p => Connected({:?}): Requested by something \ - else than PSM, disabling", peer_id); - debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", peer_id); - self.events.push(NetworkBehaviourAction::SendEvent { + debug!(target: "sub-libp2p", + "Libp2p => Connected({},{:?}): Not requested by PSM, disabling.", + peer_id, endpoint); + *st = PeerState::Disabled { open: SmallVec::new(), banned_until }; + self.events.push(NetworkBehaviourAction::NotifyHandler { peer_id: peer_id.clone(), - event: NotifsHandlerIn::Disable, + handler: NotifyHandler::One(*conn), + event: NotifsHandlerIn::Disable }); - *st = PeerState::Disabled { open: false, connected_point, banned_until }; } - st => { - // This is a serious bug either in this state machine or in libp2p. - error!(target: "sub-libp2p", "Received inject_connected for \ - already-connected node; state is {:?}", st - ); + (PeerState::Incoming { .. }, _) => { + debug!(target: "sub-libp2p", + "Secondary connection {:?} to {} waiting for PSM decision.", + conn, peer_id); + }, + + (PeerState::Enabled { .. }, _) => { + debug!(target: "sub-libp2p", "Handler({},{:?}) <= Enable secondary connection", + peer_id, conn); + self.events.push(NetworkBehaviourAction::NotifyHandler { + peer_id: peer_id.clone(), + handler: NotifyHandler::One(*conn), + event: NotifsHandlerIn::Enable + }); + } + + (PeerState::Disabled { .. }, _) | (PeerState::DisabledPendingEnable { .. }, _) => { + debug!(target: "sub-libp2p", "Handler({},{:?}) <= Disable secondary connection", + peer_id, conn); + self.events.push(NetworkBehaviourAction::NotifyHandler { + peer_id: peer_id.clone(), + handler: NotifyHandler::One(*conn), + event: NotifsHandlerIn::Disable + }); } } } - fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint) { - match self.peers.remove(peer_id) { - None | Some(PeerState::Requested) | Some(PeerState::PendingRequest { .. }) | - Some(PeerState::Banned { .. }) => - // This is a serious bug either in this state machine or in libp2p. - error!(target: "sub-libp2p", "Received inject_disconnected for non-connected \ - node {:?}", peer_id), - - Some(PeerState::Disabled { open, banned_until, .. }) => { - debug!(target: "sub-libp2p", "Libp2p => Disconnected({:?}): Was disabled \ - (through {:?})", peer_id, endpoint); - if let Some(until) = banned_until { - self.peers.insert(peer_id.clone(), PeerState::Banned { until }); - } - if open { - debug!(target: "sub-libp2p", "External API <= Closed({:?})", peer_id); + fn inject_connection_closed(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { + debug!(target: "sub-libp2p", "Libp2p => Connection ({:?},{:?}) to {} closed.", + conn, endpoint, peer_id); + match self.peers.get_mut(peer_id) { + Some(PeerState::Disabled { open, .. }) | + Some(PeerState::DisabledPendingEnable { open, .. }) | + Some(PeerState::Enabled { open, .. }) => { + // Check if the "link" to the peer is already considered closed, + // i.e. there is no connection that is open for custom protocols, + // in which case `CustomProtocolClosed` was already emitted. + let closed = open.is_empty(); + open.retain(|c| c != conn); + if !closed { + debug!(target: "sub-libp2p", "External API <= Closed({})", peer_id); let event = GenericProtoOut::CustomProtocolClosed { peer_id: peer_id.clone(), reason: "Disconnected by libp2p".into(), @@ -834,52 +924,52 @@ impl NetworkBehaviour for GenericProto { self.events.push(NetworkBehaviourAction::GenerateEvent(event)); } } + _ => {} + } + } - Some(PeerState::DisabledPendingEnable { open, timer_deadline, .. }) => { - debug!(target: "sub-libp2p", "Libp2p => Disconnected({:?}): Was disabled \ - (through {:?}) but pending enable", peer_id, endpoint); - debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", peer_id); - self.peerset.dropped(peer_id.clone()); - self.peers.insert(peer_id.clone(), PeerState::Banned { until: timer_deadline }); - if open { - debug!(target: "sub-libp2p", "External API <= Closed({:?})", peer_id); - let event = GenericProtoOut::CustomProtocolClosed { - peer_id: peer_id.clone(), - reason: "Disconnected by libp2p".into(), - }; + fn inject_disconnected(&mut self, peer_id: &PeerId) { + match self.peers.remove(peer_id) { + None | Some(PeerState::Requested) | Some(PeerState::PendingRequest { .. }) | + Some(PeerState::Banned { .. }) => + // This is a serious bug either in this state machine or in libp2p. + error!(target: "sub-libp2p", + "`inject_disconnected` called for unknown peer {}", + peer_id), - self.events.push(NetworkBehaviourAction::GenerateEvent(event)); + Some(PeerState::Disabled { banned_until, .. }) => { + debug!(target: "sub-libp2p", "Libp2p => Disconnected({}): Was disabled.", peer_id); + if let Some(until) = banned_until { + self.peers.insert(peer_id.clone(), PeerState::Banned { until }); } } - Some(PeerState::Enabled { open, .. }) => { - debug!(target: "sub-libp2p", "Libp2p => Disconnected({:?}): Was enabled \ - (through {:?})", peer_id, endpoint); - debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", peer_id); + Some(PeerState::DisabledPendingEnable { timer_deadline, .. }) => { + debug!(target: "sub-libp2p", + "Libp2p => Disconnected({}): Was disabled but pending enable.", + peer_id); + debug!(target: "sub-libp2p", "PSM <= Dropped({})", peer_id); self.peerset.dropped(peer_id.clone()); + self.peers.insert(peer_id.clone(), PeerState::Banned { until: timer_deadline }); + } + Some(PeerState::Enabled { .. }) => { + debug!(target: "sub-libp2p", "Libp2p => Disconnected({}): Was enabled.", peer_id); + debug!(target: "sub-libp2p", "PSM <= Dropped({})", peer_id); + self.peerset.dropped(peer_id.clone()); let ban_dur = Uniform::new(5, 10).sample(&mut rand::thread_rng()); self.peers.insert(peer_id.clone(), PeerState::Banned { until: Instant::now() + Duration::from_secs(ban_dur) }); - - if open { - debug!(target: "sub-libp2p", "External API <= Closed({:?})", peer_id); - let event = GenericProtoOut::CustomProtocolClosed { - peer_id: peer_id.clone(), - reason: "Disconnected by libp2p".into(), - }; - - self.events.push(NetworkBehaviourAction::GenerateEvent(event)); - } } // In the incoming state, we don't report "Dropped". Instead we will just ignore the // corresponding Accept/Reject. - Some(PeerState::Incoming { .. }) => { + Some(PeerState::Incoming { }) => { if let Some(state) = self.incoming.iter_mut().find(|i| i.peer_id == *peer_id) { - debug!(target: "sub-libp2p", "Libp2p => Disconnected({:?}): Was in incoming \ - mode (id {:?}, through {:?})", peer_id, state.incoming_id, endpoint); + debug!(target: "sub-libp2p", + "Libp2p => Disconnected({}): Was in incoming mode with id {:?}.", + peer_id, state.incoming_id); state.alive = false; } else { error!(target: "sub-libp2p", "State mismatch in libp2p: no entry in incoming \ @@ -888,7 +978,7 @@ impl NetworkBehaviour for GenericProto { } Some(PeerState::Poisoned) => - error!(target: "sub-libp2p", "State of {:?} is poisoned", peer_id), + error!(target: "sub-libp2p", "State of peer {} is poisoned", peer_id), } } @@ -899,13 +989,13 @@ impl NetworkBehaviour for GenericProto { fn inject_dial_failure(&mut self, peer_id: &PeerId) { if let Entry::Occupied(mut entry) = self.peers.entry(peer_id.clone()) { match mem::replace(entry.get_mut(), PeerState::Poisoned) { - // The node is not in our list. + // The peer is not in our list. st @ PeerState::Banned { .. } => { trace!(target: "sub-libp2p", "Libp2p => Dial failure for {:?}", peer_id); *entry.into_mut() = st; }, - // "Basic" situation: we failed to reach a node that the peerset requested. + // "Basic" situation: we failed to reach a peer that the peerset requested. PeerState::Requested | PeerState::PendingRequest { .. } => { debug!(target: "sub-libp2p", "Libp2p => Dial failure for {:?}", peer_id); *entry.into_mut() = PeerState::Banned { @@ -915,7 +1005,7 @@ impl NetworkBehaviour for GenericProto { self.peerset.dropped(peer_id.clone()) }, - // We can still get dial failures even if we are already connected to the node, + // We can still get dial failures even if we are already connected to the peer, // as an extra diagnostic for an earlier attempt. st @ PeerState::Disabled { .. } | st @ PeerState::Enabled { .. } | st @ PeerState::DisabledPendingEnable { .. } | st @ PeerState::Incoming { .. } => { @@ -928,92 +1018,130 @@ impl NetworkBehaviour for GenericProto { } } else { - // The node is not in our list. + // The peer is not in our list. trace!(target: "sub-libp2p", "Libp2p => Dial failure for {:?}", peer_id); } } - fn inject_node_event( + fn inject_event( &mut self, source: PeerId, + connection: ConnectionId, event: NotifsHandlerOut, ) { match event { - NotifsHandlerOut::Closed { reason } => { - debug!(target: "sub-libp2p", "Handler({:?}) => Closed: {}", source, reason); + NotifsHandlerOut::Closed { endpoint, reason } => { + debug!(target: "sub-libp2p", + "Handler({:?}) => Endpoint {:?} closed for custom protocols: {}", + source, endpoint, reason); let mut entry = if let Entry::Occupied(entry) = self.peers.entry(source.clone()) { entry } else { - error!(target: "sub-libp2p", "State mismatch in the custom protos handler"); + error!(target: "sub-libp2p", "Closed: State mismatch in the custom protos handler"); return }; - debug!(target: "sub-libp2p", "External API <= Closed({:?})", source); - let event = GenericProtoOut::CustomProtocolClosed { - reason, - peer_id: source.clone(), - }; - self.events.push(NetworkBehaviourAction::GenerateEvent(event)); - - match mem::replace(entry.get_mut(), PeerState::Poisoned) { - PeerState::Enabled { open, connected_point } => { - debug_assert!(open); - - debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", source); - self.peerset.dropped(source.clone()); + let last = match mem::replace(entry.get_mut(), PeerState::Poisoned) { + PeerState::Enabled { mut open } => { + debug_assert!(open.iter().any(|c| c == &connection)); + open.retain(|c| c != &connection); debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", source); - self.events.push(NetworkBehaviourAction::SendEvent { + self.events.push(NetworkBehaviourAction::NotifyHandler { peer_id: source.clone(), + handler: NotifyHandler::One(connection), event: NotifsHandlerIn::Disable, }); + let last = open.is_empty(); + + if last { + debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", source); + self.peerset.dropped(source.clone()); + *entry.into_mut() = PeerState::Disabled { + open, + banned_until: None + }; + } else { + *entry.into_mut() = PeerState::Enabled { open }; + } + + last + }, + PeerState::Disabled { mut open, banned_until } => { + debug_assert!(open.iter().any(|c| c == &connection)); + open.retain(|c| c != &connection); + let last = open.is_empty(); *entry.into_mut() = PeerState::Disabled { - open: false, - connected_point, - banned_until: None + open, + banned_until }; + last }, - PeerState::Disabled { open, connected_point, banned_until } => { - debug_assert!(open); - *entry.into_mut() = PeerState::Disabled { open: false, connected_point, banned_until }; - }, - PeerState::DisabledPendingEnable { open, connected_point, timer, timer_deadline } => { - debug_assert!(open); + PeerState::DisabledPendingEnable { + mut open, + timer, + timer_deadline + } => { + debug_assert!(open.iter().any(|c| c == &connection)); + open.retain(|c| c != &connection); + let last = open.is_empty(); *entry.into_mut() = PeerState::DisabledPendingEnable { - open: false, - connected_point, + open, timer, timer_deadline }; + last }, - _ => error!(target: "sub-libp2p", "State mismatch in the custom protos handler"), + state => { + error!(target: "sub-libp2p", + "Unexpected state in the custom protos handler: {:?}", + state); + return + } + }; + + if last { + debug!(target: "sub-libp2p", "External API <= Closed({:?})", source); + let event = GenericProtoOut::CustomProtocolClosed { + reason, + peer_id: source.clone(), + }; + self.events.push(NetworkBehaviourAction::GenerateEvent(event)); + } else { + debug!(target: "sub-libp2p", "Secondary connection closed custom protocol."); } } - NotifsHandlerOut::Open => { - debug!(target: "sub-libp2p", "Handler({:?}) => Open", source); - let endpoint = match self.peers.get_mut(&source) { - Some(PeerState::Enabled { ref mut open, ref connected_point }) | - Some(PeerState::DisabledPendingEnable { ref mut open, ref connected_point, .. }) | - Some(PeerState::Disabled { ref mut open, ref connected_point, .. }) if !*open => { - *open = true; - connected_point.clone() + NotifsHandlerOut::Open { endpoint } => { + debug!(target: "sub-libp2p", + "Handler({:?}) => Endpoint {:?} open for custom protocols.", + source, endpoint); + + let first = match self.peers.get_mut(&source) { + Some(PeerState::Enabled { ref mut open, .. }) | + Some(PeerState::DisabledPendingEnable { ref mut open, .. }) | + Some(PeerState::Disabled { ref mut open, .. }) => { + let first = open.is_empty(); + open.push(connection); + first } - _ => { - error!(target: "sub-libp2p", "State mismatch in the custom protos handler"); + state => { + error!(target: "sub-libp2p", + "Open: Unexpected state in the custom protos handler: {:?}", + state); return } }; - debug!(target: "sub-libp2p", "External API <= Open({:?})", source); - let event = GenericProtoOut::CustomProtocolOpen { - peer_id: source, - endpoint, - }; - - self.events.push(NetworkBehaviourAction::GenerateEvent(event)); + if first { + debug!(target: "sub-libp2p", "External API <= Open({:?})", source); + let event = GenericProtoOut::CustomProtocolOpen { peer_id: source }; + self.events.push(NetworkBehaviourAction::GenerateEvent(event)); + } else { + debug!(target: "sub-libp2p", "Secondary connection opened custom protocol."); + } } NotifsHandlerOut::CustomMessage { message } => { @@ -1065,11 +1193,12 @@ impl NetworkBehaviour for GenericProto { } NotifsHandlerOut::ProtocolError { error, .. } => { - debug!(target: "sub-libp2p", "Handler({:?}) => Severe protocol error: {:?}", + warn!(target: "sub-libp2p", + "Handler({:?}) => Severe protocol error: {:?}", source, error); - // A severe protocol error happens when we detect a "bad" node, such as a node on - // a different chain, or a node that doesn't speak the same protocol(s). We - // decrease the node's reputation, hence lowering the chances we try this node + // A severe protocol error happens when we detect a "bad" peer, such as a per on + // a different chain, or a peer that doesn't speak the same protocol(s). We + // decrease the peer's reputation, hence lowering the chances we try this peer // again in the short term. self.peerset.report_peer( source.clone(), @@ -1123,27 +1252,34 @@ impl NetworkBehaviour for GenericProto { } debug!(target: "sub-libp2p", "Libp2p <= Dial {:?} now that ban has expired", peer_id); - self.events.push(NetworkBehaviourAction::DialPeer { peer_id: peer_id.clone() }); + self.events.push(NetworkBehaviourAction::DialPeer { + peer_id: peer_id.clone(), + condition: DialPeerCondition::Disconnected + }); *peer_state = PeerState::Requested; } - PeerState::DisabledPendingEnable { mut timer, connected_point, open, timer_deadline } => { + PeerState::DisabledPendingEnable { + mut timer, + open, + timer_deadline + } => { if let Poll::Pending = Pin::new(&mut timer).poll(cx) { *peer_state = PeerState::DisabledPendingEnable { timer, - connected_point, open, timer_deadline }; continue; } - debug!(target: "sub-libp2p", "Handler({:?}) <= Enable now that ban has expired", peer_id); - self.events.push(NetworkBehaviourAction::SendEvent { + debug!(target: "sub-libp2p", "Handler({:?}) <= Enable (ban expired)", peer_id); + self.events.push(NetworkBehaviourAction::NotifyHandler { peer_id: peer_id.clone(), + handler: NotifyHandler::All, event: NotifsHandlerIn::Enable, }); - *peer_state = PeerState::Enabled { connected_point, open }; + *peer_state = PeerState::Enabled { open }; } st @ _ => *peer_state = st, diff --git a/client/network/src/protocol/generic_proto/handler/group.rs b/client/network/src/protocol/generic_proto/handler/group.rs index 21dc4091c0..7e597f1be6 100644 --- a/client/network/src/protocol/generic_proto/handler/group.rs +++ b/client/network/src/protocol/generic_proto/handler/group.rs @@ -143,7 +143,7 @@ impl IntoProtocolsHandler for NotifsHandlerProto { } /// Event that can be received by a `NotifsHandler`. -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum NotifsHandlerIn { /// The node should start using custom protocols. Enable, @@ -181,13 +181,18 @@ pub enum NotifsHandlerIn { /// Event that can be emitted by a `NotifsHandler`. #[derive(Debug)] pub enum NotifsHandlerOut { - /// Opened the substreams with the remote. - Open, + /// The connection is open for custom protocols. + Open { + /// The endpoint of the connection that is open for custom protocols. + endpoint: ConnectedPoint, + }, - /// Closed the substreams with the remote. + /// The connection is closed for custom protocols. Closed { - /// Reason why the substream closed, for diagnostic purposes. + /// The reason for closing, for diagnostic purposes. reason: Cow<'static, str>, + /// The endpoint of the connection that closed for custom protocols. + endpoint: ConnectedPoint, }, /// Received a non-gossiping message on the legacy substream. @@ -497,13 +502,13 @@ impl ProtocolsHandler for NotifsHandler { protocol: protocol.map_upgrade(EitherUpgrade::B), info: None, }), - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolOpen { .. }) => + ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolOpen { endpoint, .. }) => return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::Open + NotifsHandlerOut::Open { endpoint } )), - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolClosed { reason }) => + ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolClosed { endpoint, reason }) => return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::Closed { reason } + NotifsHandlerOut::Closed { endpoint, reason } )), ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomMessage { message }) => return Poll::Ready(ProtocolsHandlerEvent::Custom( diff --git a/client/network/src/protocol/generic_proto/handler/legacy.rs b/client/network/src/protocol/generic_proto/handler/legacy.rs index a2d2fc9246..bc84fd847c 100644 --- a/client/network/src/protocol/generic_proto/handler/legacy.rs +++ b/client/network/src/protocol/generic_proto/handler/legacy.rs @@ -40,9 +40,8 @@ use std::{pin::Pin, task::{Context, Poll}}; /// it is turned into a `LegacyProtoHandler`. It then handles all communications that are specific /// to Substrate on that single connection. /// -/// Note that there can be multiple instance of this struct simultaneously for same peer. However -/// if that happens, only one main instance can communicate with the outer layers of the code. In -/// other words, the outer layers of the code only ever see one handler. +/// Note that there can be multiple instance of this struct simultaneously for same peer, +/// if there are multiple established connections to the peer. /// /// ## State of the handler /// @@ -61,6 +60,7 @@ use std::{pin::Pin, task::{Context, Poll}}; /// these states. For example, if the handler reports a network misbehaviour, it will close the /// substreams but it is the role of the user to send a `Disabled` event if it wants the connection /// to close. Otherwise, the handler will try to reopen substreams. +/// /// The handler starts in the "Initializing" state and must be transitionned to Enabled or Disabled /// as soon as possible. /// @@ -111,7 +111,7 @@ impl IntoProtocolsHandler for LegacyProtoHandlerProto { fn into_handler(self, remote_peer_id: &PeerId, connected_point: &ConnectedPoint) -> Self::Handler { LegacyProtoHandler { protocol: self.protocol, - endpoint: connected_point.to_endpoint(), + endpoint: connected_point.clone(), remote_peer_id: remote_peer_id.clone(), state: ProtocolState::Init { substreams: SmallVec::new(), @@ -136,7 +136,7 @@ pub struct LegacyProtoHandler { /// Whether we are the connection dialer or listener. Used to determine who, between the local /// node and the remote node, has priority. - endpoint: Endpoint, + endpoint: ConnectedPoint, /// Queue of events to send to the outside. /// @@ -218,12 +218,16 @@ pub enum LegacyProtoHandlerOut { CustomProtocolOpen { /// Version of the protocol that has been opened. version: u8, + /// The connected endpoint. + endpoint: ConnectedPoint, }, /// Closed a custom protocol with the remote. CustomProtocolClosed { /// Reason why the substream closed, for diagnostic purposes. reason: Cow<'static, str>, + /// The connected endpoint. + endpoint: ConnectedPoint, }, /// Receives a message on a custom protocol substream. @@ -272,7 +276,7 @@ impl LegacyProtoHandler { ProtocolState::Init { substreams: incoming, .. } => { if incoming.is_empty() { - if let Endpoint::Dialer = self.endpoint { + if let ConnectedPoint::Dialer { .. } = self.endpoint { self.events_queue.push(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol: SubstreamProtocol::new(self.protocol.clone()), info: (), @@ -281,10 +285,10 @@ impl LegacyProtoHandler { ProtocolState::Opening { deadline: Delay::new(Duration::from_secs(60)) } - } else { let event = LegacyProtoHandlerOut::CustomProtocolOpen { - version: incoming[0].protocol_version() + version: incoming[0].protocol_version(), + endpoint: self.endpoint.clone() }; self.events_queue.push(ProtocolsHandlerEvent::Custom(event)); ProtocolState::Normal { @@ -404,6 +408,7 @@ impl LegacyProtoHandler { if substreams.is_empty() { let event = LegacyProtoHandlerOut::CustomProtocolClosed { reason: "All substreams have been closed by the remote".into(), + endpoint: self.endpoint.clone() }; self.state = ProtocolState::Disabled { shutdown: shutdown.into_iter().collect(), @@ -416,6 +421,7 @@ impl LegacyProtoHandler { if substreams.is_empty() { let event = LegacyProtoHandlerOut::CustomProtocolClosed { reason: format!("Error on the last substream: {:?}", err).into(), + endpoint: self.endpoint.clone() }; self.state = ProtocolState::Disabled { shutdown: shutdown.into_iter().collect(), @@ -479,7 +485,8 @@ impl LegacyProtoHandler { ProtocolState::Opening { .. } => { let event = LegacyProtoHandlerOut::CustomProtocolOpen { - version: substream.protocol_version() + version: substream.protocol_version(), + endpoint: self.endpoint.clone() }; self.events_queue.push(ProtocolsHandlerEvent::Custom(event)); ProtocolState::Normal { diff --git a/client/network/src/protocol/generic_proto/handler/notif_in.rs b/client/network/src/protocol/generic_proto/handler/notif_in.rs index 7558d1d361..83923154bd 100644 --- a/client/network/src/protocol/generic_proto/handler/notif_in.rs +++ b/client/network/src/protocol/generic_proto/handler/notif_in.rs @@ -72,7 +72,7 @@ pub struct NotifsInHandler { } /// Event that can be received by a `NotifsInHandler`. -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum NotifsInHandlerIn { /// Can be sent back as a response to an `OpenRequest`. Contains the status message to send /// to the remote. diff --git a/client/network/src/protocol/generic_proto/handler/notif_out.rs b/client/network/src/protocol/generic_proto/handler/notif_out.rs index dd38826496..b5d6cd61ad 100644 --- a/client/network/src/protocol/generic_proto/handler/notif_out.rs +++ b/client/network/src/protocol/generic_proto/handler/notif_out.rs @@ -33,7 +33,7 @@ use libp2p::swarm::{ SubstreamProtocol, NegotiatedSubstream, }; -use log::error; +use log::{debug, warn, error}; use prometheus_endpoint::Histogram; use smallvec::SmallVec; use std::{borrow::Cow, fmt, mem, pin::Pin, task::{Context, Poll}, time::Duration}; @@ -280,7 +280,7 @@ impl ProtocolsHandler for NotifsOutHandler { // be recovered. When in doubt, let's drop the existing substream and // open a new one. if sub.close().now_or_never().is_none() { - log::warn!( + warn!( target: "sub-libp2p", "📞 Improperly closed outbound notifications substream" ); @@ -293,16 +293,22 @@ impl ProtocolsHandler for NotifsOutHandler { }); self.state = State::Opening { initial_message }; }, - State::Opening { .. } | State::Refused | State::Open { .. } => - error!("☎️ Tried to enable notifications handler that was already enabled"), - State::Poisoned => error!("☎️ Notifications handler in a poisoned state"), + st @ State::Opening { .. } | st @ State::Refused | st @ State::Open { .. } => { + debug!(target: "sub-libp2p", + "Tried to enable notifications handler that was already enabled"); + self.state = st; + } + State::Poisoned => error!("Notifications handler in a poisoned state"), } } NotifsOutHandlerIn::Disable => { match mem::replace(&mut self.state, State::Poisoned) { - State::Disabled | State::DisabledOpen(_) | State::DisabledOpening => - error!("☎️ Tried to disable notifications handler that was already disabled"), + st @ State::Disabled | st @ State::DisabledOpen(_) | st @ State::DisabledOpening => { + debug!(target: "sub-libp2p", + "Tried to disable notifications handler that was already disabled"); + self.state = st; + } State::Opening { .. } => self.state = State::DisabledOpening, State::Refused => self.state = State::Disabled, State::Open { substream, .. } => self.state = State::DisabledOpen(substream), @@ -313,7 +319,7 @@ impl ProtocolsHandler for NotifsOutHandler { NotifsOutHandlerIn::Send(msg) => if let State::Open { substream, .. } = &mut self.state { if substream.push_message(msg).is_err() { - log::warn!( + warn!( target: "sub-libp2p", "📞 Notifications queue with peer {} is full, dropped message (protocol: {:?})", self.peer_id, @@ -325,7 +331,7 @@ impl ProtocolsHandler for NotifsOutHandler { } } else { // This is an API misuse. - log::warn!( + warn!( target: "sub-libp2p", "📞 Tried to send a notification on a disabled handler" ); diff --git a/client/network/src/protocol/generic_proto/tests.rs b/client/network/src/protocol/generic_proto/tests.rs index 4548859ac4..1bc6e745f8 100644 --- a/client/network/src/protocol/generic_proto/tests.rs +++ b/client/network/src/protocol/generic_proto/tests.rs @@ -18,7 +18,7 @@ use futures::{prelude::*, ready}; use codec::{Encode, Decode}; -use libp2p::core::nodes::listeners::ListenerId; +use libp2p::core::connection::{ConnectionId, ListenerId}; use libp2p::core::ConnectedPoint; use libp2p::swarm::{Swarm, ProtocolsHandler, IntoProtocolsHandler}; use libp2p::swarm::{PollParameters, NetworkBehaviour, NetworkBehaviourAction}; @@ -148,20 +148,29 @@ impl NetworkBehaviour for CustomProtoWithAddr { list } - fn inject_connected(&mut self, peer_id: PeerId, endpoint: ConnectedPoint) { - self.inner.inject_connected(peer_id, endpoint) + fn inject_connected(&mut self, peer_id: &PeerId) { + self.inner.inject_connected(peer_id) } - fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint) { - self.inner.inject_disconnected(peer_id, endpoint) + fn inject_disconnected(&mut self, peer_id: &PeerId) { + self.inner.inject_disconnected(peer_id) } - fn inject_node_event( + fn inject_connection_established(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { + self.inner.inject_connection_established(peer_id, conn, endpoint) + } + + fn inject_connection_closed(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { + self.inner.inject_connection_closed(peer_id, conn, endpoint) + } + + fn inject_event( &mut self, peer_id: PeerId, + connection: ConnectionId, event: <::Handler as ProtocolsHandler>::OutEvent ) { - self.inner.inject_node_event(peer_id, event) + self.inner.inject_event(peer_id, connection, event) } fn poll( @@ -177,10 +186,6 @@ impl NetworkBehaviour for CustomProtoWithAddr { self.inner.poll(cx, params) } - fn inject_replaced(&mut self, peer_id: PeerId, closed_endpoint: ConnectedPoint, new_endpoint: ConnectedPoint) { - self.inner.inject_replaced(peer_id, closed_endpoint, new_endpoint) - } - fn inject_addr_reach_failure(&mut self, peer_id: Option<&PeerId>, addr: &Multiaddr, error: &dyn std::error::Error) { self.inner.inject_addr_reach_failure(peer_id, addr, error) } @@ -205,8 +210,8 @@ impl NetworkBehaviour for CustomProtoWithAddr { self.inner.inject_listener_error(id, err); } - fn inject_listener_closed(&mut self, id: ListenerId) { - self.inner.inject_listener_closed(id); + fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &io::Error>) { + self.inner.inject_listener_closed(id, reason); } } diff --git a/client/network/src/protocol/light_client_handler.rs b/client/network/src/protocol/light_client_handler.rs index 88a9519149..85312b0803 100644 --- a/client/network/src/protocol/light_client_handler.rs +++ b/client/network/src/protocol/light_client_handler.rs @@ -37,6 +37,7 @@ use libp2p::{ ConnectedPoint, Multiaddr, PeerId, + connection::ConnectionId, upgrade::{InboundUpgrade, ReadOneError, UpgradeInfo, Negotiated}, upgrade::{OutboundUpgrade, read_one, write_one} }, @@ -44,9 +45,11 @@ use libp2p::{ NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, + NotifyHandler, OneShotHandler, + OneShotHandlerConfig, PollParameters, - SubstreamProtocol + SubstreamProtocol, } }; use nohash_hasher::IntMap; @@ -58,6 +61,7 @@ use sp_core::{ storage::{ChildInfo, StorageKey}, hexdisplay::HexDisplay, }; +use smallvec::SmallVec; use sp_blockchain::{Error as ClientError}; use sp_runtime::{ traits::{Block, Header, NumberFor, Zero}, @@ -237,25 +241,39 @@ struct RequestWrapper { retries: usize, /// The actual request. request: Request, - /// Peer information, e.g. `PeerId`. - peer: P + /// The peer to send the request to, e.g. `PeerId`. + peer: P, + /// The connection to use for sending the request. + connection: Option, } /// Information we have about some peer. #[derive(Debug)] struct PeerInfo { - address: Multiaddr, + connections: SmallVec<[(ConnectionId, Multiaddr); crate::MAX_CONNECTIONS_PER_PEER]>, best_block: Option>, status: PeerStatus, } +impl Default for PeerInfo { + fn default() -> Self { + PeerInfo { + connections: SmallVec::new(), + best_block: None, + status: PeerStatus::Idle, + } + } +} + +type RequestId = u64; + /// A peer is either idle or busy processing a request from us. #[derive(Debug, Clone, PartialEq, Eq)] enum PeerStatus { /// The peer is available. Idle, /// We wait for the peer to return us a response for the given request ID. - BusyWith(u64), + BusyWith(RequestId), } /// The light client handler behaviour. @@ -273,9 +291,9 @@ pub struct LightClientHandler { /// Pending (local) requests. pending_requests: VecDeque>, /// Requests on their way to remote peers. - outstanding: IntMap>, + outstanding: IntMap>, /// (Local) Request ID counter - next_request_id: u64, + next_request_id: RequestId, /// Handle to use for reporting misbehaviour of peers. peerset: sc_peerset::PeersetHandle, } @@ -323,35 +341,18 @@ where retries: retries(&req), request: req, peer: (), // we do not know the peer yet + connection: None, }; self.pending_requests.push_back(rw); Ok(()) } - fn next_request_id(&mut self) -> u64 { + fn next_request_id(&mut self) -> RequestId { let id = self.next_request_id; self.next_request_id += 1; id } - // Iterate over peers known to possess a certain block. - fn idle_peers_with_block(&mut self, num: NumberFor) -> impl Iterator + '_ { - self.peers.iter() - .filter(move |(_, info)| { - info.status == PeerStatus::Idle && info.best_block >= Some(num) - }) - .map(|(peer, _)| peer.clone()) - } - - // Iterate over peers without a known block. - fn idle_peers_with_unknown_block(&mut self) -> impl Iterator + '_ { - self.peers.iter() - .filter(|(_, info)| { - info.status == PeerStatus::Idle && info.best_block.is_none() - }) - .map(|(peer, _)| peer.clone()) - } - /// Remove the given peer. /// /// If we have a request to this peer in flight, we move it back to @@ -364,12 +365,50 @@ where retries: rw.retries, request: rw.request, peer: (), // need to find another peer + connection: None, }; self.pending_requests.push_back(rw); } self.peers.remove(peer); } + /// Prepares a request by selecting a suitable peer and connection to send it to. + /// + /// If there is currently no suitable peer for the request, the given request + /// is returned as `Err`. + fn prepare_request(&self, req: RequestWrapper) + -> Result<(PeerId, RequestWrapper), RequestWrapper> + { + let number = required_block(&req.request); + + let mut peer = None; + for (peer_id, peer_info) in self.peers.iter() { + if peer_info.status == PeerStatus::Idle { + match peer_info.best_block { + Some(n) => if n >= number { + peer = Some((peer_id, peer_info)); + break + }, + None => peer = Some((peer_id, peer_info)) + } + } + } + + if let Some((peer_id, peer_info)) = peer { + let connection = peer_info.connections.iter().next().map(|(id, _)| *id); + let rw = RequestWrapper { + timestamp: req.timestamp, + retries: req.retries, + request: req.request, + peer: peer_id.clone(), + connection, + }; + Ok((peer_id.clone(), rw)) + } else { + Err(req) + } + } + /// Process a local request's response from remote. /// /// If successful, this will give us the actual, checked data we should be @@ -723,38 +762,68 @@ where max_request_size: self.config.max_request_size, protocol: self.config.light_protocol.clone(), }; - OneShotHandler::new(SubstreamProtocol::new(p), self.config.inactivity_timeout) + let mut cfg = OneShotHandlerConfig::default(); + cfg.inactive_timeout = self.config.inactivity_timeout; + OneShotHandler::new(SubstreamProtocol::new(p), cfg) } fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec { self.peers.get(peer) - .map(|info| vec![info.address.clone()]) + .map(|info| info.connections.iter().map(|(_, a)| a.clone()).collect()) .unwrap_or_default() } - fn inject_connected(&mut self, peer: PeerId, info: ConnectedPoint) { + fn inject_connected(&mut self, peer: &PeerId) { + } + + fn inject_connection_established(&mut self, peer: &PeerId, conn: &ConnectionId, info: &ConnectedPoint) { let peer_address = match info { - ConnectedPoint::Listener { send_back_addr, .. } => send_back_addr, - ConnectedPoint::Dialer { address } => address + ConnectedPoint::Listener { send_back_addr, .. } => send_back_addr.clone(), + ConnectedPoint::Dialer { address } => address.clone() }; log::trace!("peer {} connected with address {}", peer, peer_address); - let info = PeerInfo { - address: peer_address, - best_block: None, - status: PeerStatus::Idle, - }; - - self.peers.insert(peer, info); + let entry = self.peers.entry(peer.clone()).or_default(); + entry.connections.push((*conn, peer_address)); } - fn inject_disconnected(&mut self, peer: &PeerId, _: ConnectedPoint) { + fn inject_disconnected(&mut self, peer: &PeerId) { log::trace!("peer {} disconnected", peer); self.remove_peer(peer) } - fn inject_node_event(&mut self, peer: PeerId, event: Event) { + fn inject_connection_closed(&mut self, peer: &PeerId, conn: &ConnectionId, info: &ConnectedPoint) { + let peer_address = match info { + ConnectedPoint::Listener { send_back_addr, .. } => send_back_addr, + ConnectedPoint::Dialer { address } => address + }; + + log::trace!("connection to peer {} closed: {}", peer, peer_address); + + if let Some(info) = self.peers.get_mut(peer) { + info.connections.retain(|(c, _)| c != conn) + } + + // Add any outstanding requests on the closed connection back to the + // pending requests. + if let Some(id) = self.outstanding.iter() + .find(|(_, rw)| &rw.peer == peer && rw.connection == Some(*conn)) // (*) + .map(|(id, _)| *id) + { + let rw = self.outstanding.remove(&id).expect("by (*)"); + let rw = RequestWrapper { + timestamp: rw.timestamp, + retries: rw.retries, + request: rw.request, + peer: (), // need to find another peer + connection: None, + }; + self.pending_requests.push_back(rw); + } + } + + fn inject_event(&mut self, peer: PeerId, conn: ConnectionId, event: Event) { match event { // An incoming request from remote has been received. Event::Request(request, mut stream) => { @@ -800,9 +869,10 @@ where // A response to one of our own requests has been received. Event::Response(id, response) => { if let Some(request) = self.outstanding.remove(&id) { - // We first just check if the response originates from the expected peer. + // We first just check if the response originates from the expected peer + // and connection. if request.peer != peer { - log::debug!("was expecting response from {} instead of {}", request.peer, peer); + log::debug!("Expected response from {} instead of {}.", request.peer, peer); self.outstanding.insert(id, request); self.remove_peer(&peer); self.peerset.report_peer(peer, ReputationChange::new_fatal("response from unexpected peer")); @@ -834,6 +904,7 @@ where retries: request.retries, request: request.request, peer: (), + connection: None, }; self.pending_requests.push_back(rw); } @@ -847,6 +918,7 @@ where retries: request.retries - 1, request: request.request, peer: (), + connection: None, }; self.pending_requests.push_back(rw) } else { @@ -886,54 +958,54 @@ where request.timestamp = Instant::now(); request.retries -= 1 } - let number = required_block(&request.request); - let available_peer = { - let p = self.idle_peers_with_block(number).next(); - if p.is_none() { - self.idle_peers_with_unknown_block().next() - } else { - p + + + match self.prepare_request(request) { + Err(request) => { + self.pending_requests.push_front(request); + log::debug!("no peer available to send request to"); + break } - }; - if let Some(peer) = available_peer { - let buf = match serialize_request(&request.request) { - Ok(b) => b, - Err(e) => { - log::debug!("failed to serialize request: {}", e); - send_reply(Err(ClientError::RemoteFetchFailed), request.request); - continue; - } - }; + Ok((peer, request)) => { + let request_bytes = match serialize_request(&request.request) { + Ok(bytes) => bytes, + Err(error) => { + log::debug!("failed to serialize request: {}", error); + send_reply(Err(ClientError::RemoteFetchFailed), request.request); + continue + } + }; - let id = self.next_request_id(); - log::trace!("sending request {} to peer {}", id, peer); - let protocol = OutboundProtocol { - request: buf, - request_id: id, - expected: match request.request { - Request::Body { .. } => ExpectedResponseTy::Block, - _ => ExpectedResponseTy::Light, - }, - max_response_size: self.config.max_response_size, - protocol: match request.request { - Request::Body { .. } => self.config.block_protocol.clone(), - _ => self.config.light_protocol.clone(), - }, - }; - self.peers.get_mut(&peer).map(|info| info.status = PeerStatus::BusyWith(id)); - let rw = RequestWrapper { - timestamp: request.timestamp, - retries: request.retries, - request: request.request, - peer: peer.clone(), - }; - self.outstanding.insert(id, rw); - return Poll::Ready(NetworkBehaviourAction::SendEvent { peer_id: peer, event: protocol }) + let (expected, protocol) = match request.request { + Request::Body { .. } => + (ExpectedResponseTy::Block, self.config.block_protocol.clone()), + _ => + (ExpectedResponseTy::Light, self.config.light_protocol.clone()), + }; - } else { - self.pending_requests.push_front(request); - log::debug!("no peer available to send request to"); - break + let peer_id = peer.clone(); + let handler = request.connection.map_or(NotifyHandler::Any, NotifyHandler::One); + + let request_id = self.next_request_id(); + self.peers.get_mut(&peer).map(|p| p.status = PeerStatus::BusyWith(request_id)); + self.outstanding.insert(request_id, request); + + let event = OutboundProtocol { + request_id, + request: request_bytes, + expected, + max_response_size: self.config.max_response_size, + protocol, + }; + + log::trace!("sending request {} to peer {}", request_id, peer_id); + + return Poll::Ready(NetworkBehaviourAction::NotifyHandler { + peer_id, + handler, + event, + }) + } } } @@ -959,6 +1031,7 @@ where retries: rw.retries - 1, request: rw.request, peer: (), + connection: None, }; self.pending_requests.push_back(rw) } @@ -1097,7 +1170,7 @@ pub enum Event { /// Incoming request from remote and substream to use for the response. Request(api::v1::light::Request, T), /// Incoming response from remote. - Response(u64, Response), + Response(RequestId, Response), } /// Incoming response from remote. @@ -1157,7 +1230,7 @@ pub struct OutboundProtocol { /// The serialized protobuf request. request: Vec, /// Local identifier for the request. Used to associate it with a response. - request_id: u64, + request_id: RequestId, /// Kind of response expected for this request. expected: ExpectedResponseTy, /// The max. response length in bytes. @@ -1244,6 +1317,7 @@ mod tests { Multiaddr, core::{ ConnectedPoint, + connection::ConnectionId, identity, muxing::{StreamMuxerBox, SubstreamRef}, transport::{Transport, boxed::Boxed, memory::MemoryTransport}, @@ -1457,10 +1531,12 @@ mod tests { let pset = peerset(); let mut behaviour = make_behaviour(true, pset.1, make_config()); - behaviour.inject_connected(peer.clone(), empty_dialer()); + behaviour.inject_connection_established(&peer, &ConnectionId::new(1), &empty_dialer()); + behaviour.inject_connected(&peer); assert_eq!(1, behaviour.peers.len()); - behaviour.inject_disconnected(&peer, empty_dialer()); + behaviour.inject_connection_closed(&peer, &ConnectionId::new(1), &empty_dialer()); + behaviour.inject_disconnected(&peer); assert_eq!(0, behaviour.peers.len()) } @@ -1471,8 +1547,10 @@ mod tests { let pset = peerset(); let mut behaviour = make_behaviour(true, pset.1, make_config()); - behaviour.inject_connected(peer0.clone(), empty_dialer()); - behaviour.inject_connected(peer1.clone(), empty_dialer()); + behaviour.inject_connection_established(&peer0, &ConnectionId::new(1), &empty_dialer()); + behaviour.inject_connected(&peer0); + behaviour.inject_connection_established(&peer1, &ConnectionId::new(2), &empty_dialer()); + behaviour.inject_connected(&peer1); // We now know about two peers. assert_eq!(HashSet::from_iter(&[peer0.clone(), peer1.clone()]), behaviour.peers.keys().collect::>()); @@ -1494,7 +1572,7 @@ mod tests { assert_eq!(1, behaviour.pending_requests.len()); // The behaviour should now attempt to send the request. - assert_matches!(poll(&mut behaviour), Poll::Ready(NetworkBehaviourAction::SendEvent { peer_id, .. }) => { + assert_matches!(poll(&mut behaviour), Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, .. }) => { assert!(peer_id == peer0 || peer_id == peer1) }); @@ -1534,7 +1612,9 @@ mod tests { let mut behaviour = make_behaviour(false, pset.1, make_config()); // ^--- Making sure the response data check fails. - behaviour.inject_connected(peer.clone(), empty_dialer()); + let conn = ConnectionId::new(1); + behaviour.inject_connection_established(&peer, &conn, &empty_dialer()); + behaviour.inject_connected(&peer); assert_eq!(1, behaviour.peers.len()); let chan = oneshot::channel(); @@ -1562,7 +1642,7 @@ mod tests { } }; - behaviour.inject_node_event(peer.clone(), Event::Response(request_id, Response::Light(response))); + behaviour.inject_event(peer.clone(), conn, Event::Response(request_id, Response::Light(response))); assert!(behaviour.peers.is_empty()); poll(&mut behaviour); // More progress @@ -1578,7 +1658,9 @@ mod tests { let pset = peerset(); let mut behaviour = make_behaviour(true, pset.1, make_config()); - behaviour.inject_connected(peer.clone(), empty_dialer()); + let conn = ConnectionId::new(1); + behaviour.inject_connection_established(&peer, &conn, &empty_dialer()); + behaviour.inject_connected(&peer); assert_eq!(1, behaviour.peers.len()); assert_eq!(0, behaviour.pending_requests.len()); assert_eq!(0, behaviour.outstanding.len()); @@ -1591,7 +1673,7 @@ mod tests { } }; - behaviour.inject_node_event(peer.clone(), Event::Response(2347895932, Response::Light(response))); + behaviour.inject_event(peer.clone(), conn, Event::Response(2347895932, Response::Light(response))); assert!(behaviour.peers.is_empty()); poll(&mut behaviour); @@ -1605,7 +1687,9 @@ mod tests { let pset = peerset(); let mut behaviour = make_behaviour(true, pset.1, make_config()); - behaviour.inject_connected(peer.clone(), empty_dialer()); + let conn = ConnectionId::new(1); + behaviour.inject_connection_established(&peer, &conn, &empty_dialer()); + behaviour.inject_connected(&peer); assert_eq!(1, behaviour.peers.len()); let chan = oneshot::channel(); @@ -1633,7 +1717,7 @@ mod tests { } }; - behaviour.inject_node_event(peer.clone(), Event::Response(request_id, Response::Light(response))); + behaviour.inject_event(peer.clone(), conn, Event::Response(request_id, Response::Light(response))); assert!(behaviour.peers.is_empty()); poll(&mut behaviour); // More progress @@ -1653,10 +1737,18 @@ mod tests { let mut behaviour = make_behaviour(false, pset.1, make_config()); // ^--- Making sure the response data check fails. - behaviour.inject_connected(peer1.clone(), empty_dialer()); - behaviour.inject_connected(peer2.clone(), empty_dialer()); - behaviour.inject_connected(peer3.clone(), empty_dialer()); - behaviour.inject_connected(peer4.clone(), empty_dialer()); + let conn1 = ConnectionId::new(1); + behaviour.inject_connection_established(&peer1, &conn1, &empty_dialer()); + behaviour.inject_connected(&peer1); + let conn2 = ConnectionId::new(2); + behaviour.inject_connection_established(&peer2, &conn2, &empty_dialer()); + behaviour.inject_connected(&peer2); + let conn3 = ConnectionId::new(3); + behaviour.inject_connection_established(&peer3, &conn3, &empty_dialer()); + behaviour.inject_connected(&peer3); + let conn4 = ConnectionId::new(3); + behaviour.inject_connection_established(&peer4, &conn4, &empty_dialer()); + behaviour.inject_connected(&peer4); assert_eq!(4, behaviour.peers.len()); let mut chan = oneshot::channel(); @@ -1671,11 +1763,11 @@ mod tests { assert_eq!(1, behaviour.pending_requests.len()); assert_eq!(0, behaviour.outstanding.len()); - assert_matches!(poll(&mut behaviour), Poll::Ready(NetworkBehaviourAction::SendEvent { .. })); + assert_matches!(poll(&mut behaviour), Poll::Ready(NetworkBehaviourAction::NotifyHandler { .. })); assert_eq!(0, behaviour.pending_requests.len()); assert_eq!(1, behaviour.outstanding.len()); - for _ in 0 .. 3 { + for i in 1 ..= 3 { // Construct an invalid response let request_id = *behaviour.outstanding.keys().next().unwrap(); let responding_peer = behaviour.outstanding.values().next().unwrap().peer.clone(); @@ -1685,8 +1777,9 @@ mod tests { response: Some(api::v1::light::response::Response::RemoteCallResponse(r)) } }; - behaviour.inject_node_event(responding_peer, Event::Response(request_id, Response::Light(response.clone()))); - assert_matches!(poll(&mut behaviour), Poll::Ready(NetworkBehaviourAction::SendEvent { .. })); + let conn = ConnectionId::new(i); + behaviour.inject_event(responding_peer, conn, Event::Response(request_id, Response::Light(response.clone()))); + assert_matches!(poll(&mut behaviour), Poll::Ready(NetworkBehaviourAction::NotifyHandler { .. })); assert_matches!(chan.1.try_recv(), Ok(None)) } // Final invalid response @@ -1698,7 +1791,7 @@ mod tests { response: Some(api::v1::light::response::Response::RemoteCallResponse(r)), } }; - behaviour.inject_node_event(responding_peer, Event::Response(request_id, Response::Light(response))); + behaviour.inject_event(responding_peer, conn4, Event::Response(request_id, Response::Light(response))); assert_matches!(poll(&mut behaviour), Poll::Pending); assert_matches!(chan.1.try_recv(), Ok(Some(Err(ClientError::RemoteFetchFailed)))) } @@ -1708,7 +1801,9 @@ mod tests { let pset = peerset(); let mut behaviour = make_behaviour(true, pset.1, make_config()); - behaviour.inject_connected(peer.clone(), empty_dialer()); + let conn = ConnectionId::new(1); + behaviour.inject_connection_established(&peer, &conn, &empty_dialer()); + behaviour.inject_connected(&peer); assert_eq!(1, behaviour.peers.len()); let response = match request { @@ -1757,12 +1852,12 @@ mod tests { assert_eq!(1, behaviour.pending_requests.len()); assert_eq!(0, behaviour.outstanding.len()); - assert_matches!(poll(&mut behaviour), Poll::Ready(NetworkBehaviourAction::SendEvent { .. })); + assert_matches!(poll(&mut behaviour), Poll::Ready(NetworkBehaviourAction::NotifyHandler { .. })); assert_eq!(0, behaviour.pending_requests.len()); assert_eq!(1, behaviour.outstanding.len()); assert_eq!(1, *behaviour.outstanding.keys().next().unwrap()); - behaviour.inject_node_event(peer.clone(), Event::Response(1, Response::Light(response))); + behaviour.inject_event(peer.clone(), conn, Event::Response(1, Response::Light(response))); poll(&mut behaviour); diff --git a/client/network/src/service.rs b/client/network/src/service.rs index ef2aa0aa23..fb33901dd0 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -37,9 +37,10 @@ use crate::{ transport, ReputationChange, }; use futures::prelude::*; -use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; +use libp2p::{PeerId, Multiaddr}; +use libp2p::core::{Executor, connection::PendingConnectionError}; +use libp2p::kad::record; use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent}; -use libp2p::{kad::record, Multiaddr, PeerId}; use log::{error, info, trace, warn}; use parking_lot::Mutex; use prometheus_endpoint::{ @@ -51,6 +52,7 @@ use sp_runtime::{ traits::{Block as BlockT, NumberFor}, ConsensusEngineId, }; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; use std::{ borrow::Cow, collections::{HashMap, HashSet}, @@ -322,9 +324,16 @@ impl NetworkWorker { }; transport::build_transport(local_identity, config_mem, config_wasm, flowctrl) }; - let mut builder = SwarmBuilder::new(transport, behaviour, local_peer_id.clone()); + let mut builder = SwarmBuilder::new(transport, behaviour, local_peer_id.clone()) + .peer_connection_limit(crate::MAX_CONNECTIONS_PER_PEER); if let Some(spawner) = params.executor { - builder = builder.executor_fn(spawner); + struct SpawnImpl(F); + impl + Send>>)> Executor for SpawnImpl { + fn exec(&self, f: Pin + Send>>) { + (self.0)(f) + } + } + builder = builder.executor(Box::new(SpawnImpl(spawner))); } (builder.build(), bandwidth) }; @@ -1038,13 +1047,13 @@ impl Future for NetworkWorker { metrics.update_with_network_event(&ev); } }, - Poll::Ready(SwarmEvent::Connected(peer_id)) => { + Poll::Ready(SwarmEvent::ConnectionEstablished { peer_id, .. }) => { trace!(target: "sub-libp2p", "Libp2p => Connected({:?})", peer_id); if let Some(metrics) = this.metrics.as_ref() { metrics.connections.inc(); } }, - Poll::Ready(SwarmEvent::Disconnected(peer_id)) => { + Poll::Ready(SwarmEvent::ConnectionClosed { peer_id, .. }) => { trace!(target: "sub-libp2p", "Libp2p => Disconnected({:?})", peer_id); if let Some(metrics) = this.metrics.as_ref() { metrics.connections.dec(); @@ -1054,9 +1063,7 @@ impl Future for NetworkWorker { trace!(target: "sub-libp2p", "Libp2p => NewListenAddr({})", addr), Poll::Ready(SwarmEvent::ExpiredListenAddr(addr)) => trace!(target: "sub-libp2p", "Libp2p => ExpiredListenAddr({})", addr), - Poll::Ready(SwarmEvent::UnreachableAddr { peer_id, address, error }) => { - let error = error.to_string(); - + Poll::Ready(SwarmEvent::UnreachableAddr { peer_id, address, error, .. }) => { trace!( target: "sub-libp2p", "Libp2p => Failed to reach {:?} through {:?}: {}", peer_id, @@ -1064,21 +1071,34 @@ impl Future for NetworkWorker { error, ); - if let Some(peer_id) = peer_id { - if this.boot_node_ids.contains(&peer_id) - && error.contains("Peer ID mismatch") - { + if this.boot_node_ids.contains(&peer_id) { + if let PendingConnectionError::InvalidPeerId = error { error!( - "💔 Connecting to bootnode with peer id `{}` and address `{}` failed \ - because it returned a different peer id!", + "💔 Invalid peer ID from bootnode, expected `{}` at address `{}`.", peer_id, address, ); } } - }, - Poll::Ready(SwarmEvent::StartConnect(peer_id)) => - trace!(target: "sub-libp2p", "Libp2p => StartConnect({:?})", peer_id), + } + Poll::Ready(SwarmEvent::Dialing(peer_id)) => + trace!(target: "sub-libp2p", "Libp2p => Dialing({:?})", peer_id), + Poll::Ready(SwarmEvent::IncomingConnection { local_addr, send_back_addr }) => + trace!(target: "sub-libp2p", "Libp2p => IncomingConnection({},{}))", + local_addr, send_back_addr), + Poll::Ready(SwarmEvent::IncomingConnectionError { local_addr, send_back_addr, error }) => + trace!(target: "sub-libp2p", "Libp2p => IncomingConnectionError({},{}): {}", + local_addr, send_back_addr, error), + Poll::Ready(SwarmEvent::BannedPeer { peer_id, endpoint }) => + trace!(target: "sub-libp2p", "Libp2p => BannedPeer({}). Connected via {:?}.", + peer_id, endpoint), + Poll::Ready(SwarmEvent::UnknownPeerUnreachableAddr { address, error }) => + trace!(target: "sub-libp2p", "Libp2p => UnknownPeerUnreachableAddr({}): {}", + address, error), + Poll::Ready(SwarmEvent::ListenerClosed { reason, addresses: _ }) => + warn!(target: "sub-libp2p", "Libp2p => ListenerClosed: {:?}", reason), + Poll::Ready(SwarmEvent::ListenerError { error }) => + trace!(target: "sub-libp2p", "Libp2p => ListenerError: {}", error), }; } diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index 769e0faca9..90202008eb 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -16,7 +16,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" rand = "0.7.2" -libp2p = { version = "0.16.2", default-features = false, features = ["libp2p-websocket"] } +libp2p = { version = "0.17.0", default-features = false, features = ["libp2p-websocket"] } sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } sc-client = { version = "0.8.0-alpha.5", path = "../../" } sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 78d488a989..e026c6063a 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.rs/sc-peerset" [dependencies] futures = "0.3.4" -libp2p = { version = "0.16.2", default-features = false } +libp2p = { version = "0.17.0", default-features = false } sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils"} log = "0.4.8" serde_json = "1.0.41" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index bb7e7e5103..dcf218e976 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -16,7 +16,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" wasm-timer = "0.2.0" -libp2p = { version = "0.16.2", default-features = false, features = ["libp2p-websocket"] } +libp2p = { version = "0.17.0", default-features = false, features = ["websocket", "wasm-ext", "tcp", "dns"] } log = "0.4.8" pin-project = "0.4.6" rand = "0.7.2" diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 112b9499a7..4734cde694 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.rs/sp-consensus/" [dependencies] derive_more = "0.99.2" -libp2p = { version = "0.16.2", default-features = false } +libp2p = { version = "0.17.0", default-features = false } log = "0.4.8" sp-core = { path= "../../core" , version = "2.0.0-alpha.5"} sp-inherents = { version = "2.0.0-alpha.5", path = "../../inherents" } diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 188f46bf19..5f6b18e001 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/paritytech/substrate/" futures = "0.3" futures01 = { package = "futures", version = "0.1.29" } log = "0.4.8" -libp2p-wasm-ext = { version = "0.16.2", features = ["websocket"] } +libp2p-wasm-ext = { version = "0.17.0", features = ["websocket"] } console_error_panic_hook = "0.1.6" console_log = "0.1.2" js-sys = "0.3.34" -- GitLab From 78cb165e3930824fdb4dc23848fece641c27c449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 8 Apr 2020 11:12:09 +0200 Subject: [PATCH 183/300] Refactor SignedExtension (#5540) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor SignedExtension * Move DispatchInfo Associated type to Dispatchable * Bound Call: Dispatchable * Pass PostDispatchInfo to post_dispatch * Pass DispatchInfo by reference to avoid clones * Whitespace fix Co-Authored-By: Tomasz Drwięga * Style changes from code review Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Only decalre in test mod to remove warning * Deduplicate Call definition * Bound frame_system::trait::Call by Dispatchable * Introduce DispatchInfoOf type alias * Whitespace fix from review Co-Authored-By: Bastian Köcher Co-authored-by: Tomasz Drwięga Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Bastian Köcher --- frame/balances/src/tests.rs | 23 +++- frame/balances/src/tests_composite.rs | 10 +- frame/balances/src/tests_local.rs | 10 +- frame/contracts/src/lib.rs | 9 +- frame/contracts/src/tests.rs | 4 +- frame/example/src/lib.rs | 16 +-- frame/executive/src/lib.rs | 12 +- frame/staking/src/lib.rs | 7 +- frame/staking/src/tests.rs | 2 +- frame/support/src/dispatch.rs | 4 +- frame/support/src/metadata.rs | 6 +- frame/system/src/lib.rs | 114 ++++++++++-------- frame/transaction-payment/src/lib.rs | 53 ++++---- .../runtime/src/generic/checked_extrinsic.rs | 30 ++--- .../src/generic/unchecked_extrinsic.rs | 1 - primitives/runtime/src/testing.rs | 12 +- primitives/runtime/src/traits.rs | 79 +++++++----- test-utils/runtime/src/lib.rs | 10 ++ 18 files changed, 235 insertions(+), 167 deletions(-) diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index 8055c2013e..14caf41c1e 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -18,6 +18,19 @@ #![cfg(test)] +#[derive(Debug)] +pub struct CallWithDispatchInfo; +impl sp_runtime::traits::Dispatchable for CallWithDispatchInfo { + type Origin = (); + type Trait = (); + type Info = frame_support::weights::DispatchInfo; + type PostInfo = frame_support::weights::PostDispatchInfo; + fn dispatch(self, _origin: Self::Origin) + -> sp_runtime::DispatchResultWithInfo { + panic!("Do not use dummy implementation for dispatch."); + } +} + #[macro_export] macro_rules! decl_tests { ($test:ty, $ext_builder:ty, $existential_deposit:expr) => { @@ -40,7 +53,7 @@ macro_rules! decl_tests { pub type System = frame_system::Module<$test>; pub type Balances = Module<$test>; - pub const CALL: &<$test as frame_system::Trait>::Call = &(); + pub const CALL: &<$test as frame_system::Trait>::Call = &$crate::tests::CallWithDispatchInfo; /// create a transaction info struct from weight. Handy to avoid building the whole struct. pub fn info_from_weight(w: Weight) -> DispatchInfo { @@ -154,14 +167,14 @@ macro_rules! decl_tests { ChargeTransactionPayment::from(1), &1, CALL, - info_from_weight(1), + &info_from_weight(1), 1, ).is_err()); assert!( as SignedExtension>::pre_dispatch( ChargeTransactionPayment::from(0), &1, CALL, - info_from_weight(1), + &info_from_weight(1), 1, ).is_ok()); @@ -172,14 +185,14 @@ macro_rules! decl_tests { ChargeTransactionPayment::from(1), &1, CALL, - info_from_weight(1), + &info_from_weight(1), 1, ).is_err()); assert!( as SignedExtension>::pre_dispatch( ChargeTransactionPayment::from(0), &1, CALL, - info_from_weight(1), + &info_from_weight(1), 1, ).is_err()); }); diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index 8935dc4c9a..59c520f4b5 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -18,14 +18,18 @@ #![cfg(test)] -use sp_runtime::{Perbill, traits::{ConvertInto, IdentityLookup}, testing::Header}; +use sp_runtime::{ + Perbill, + traits::{ConvertInto, IdentityLookup}, + testing::Header, +}; use sp_core::H256; use sp_io; use frame_support::{impl_outer_origin, parameter_types}; use frame_support::traits::Get; use frame_support::weights::{Weight, DispatchInfo}; use std::cell::RefCell; -use crate::{GenesisConfig, Module, Trait, decl_tests}; +use crate::{GenesisConfig, Module, Trait, decl_tests, tests::CallWithDispatchInfo}; use frame_system as system; impl_outer_origin!{ @@ -54,7 +58,7 @@ impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; - type Call = (); + type Call = CallWithDispatchInfo; type Hash = H256; type Hashing = ::sp_runtime::traits::BlakeTwo256; type AccountId = u64; diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index c8a4a298f5..3a9bfb30ce 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -18,14 +18,18 @@ #![cfg(test)] -use sp_runtime::{Perbill, traits::{ConvertInto, IdentityLookup}, testing::Header}; +use sp_runtime::{ + Perbill, + traits::{ConvertInto, IdentityLookup}, + testing::Header, +}; use sp_core::H256; use sp_io; use frame_support::{impl_outer_origin, parameter_types}; use frame_support::traits::{Get, StorageMapShim}; use frame_support::weights::{Weight, DispatchInfo}; use std::cell::RefCell; -use crate::{GenesisConfig, Module, Trait, decl_tests}; +use crate::{GenesisConfig, Module, Trait, decl_tests, tests::CallWithDispatchInfo}; use frame_system as system; impl_outer_origin!{ @@ -54,7 +58,7 @@ impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; - type Call = (); + type Call = CallWithDispatchInfo; type Hash = H256; type Hashing = ::sp_runtime::traits::BlakeTwo256; type AccountId = u64; diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 090b345099..10938bb7de 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -113,7 +113,10 @@ use sp_std::{prelude::*, marker::PhantomData, fmt::Debug}; use codec::{Codec, Encode, Decode}; use sp_io::hashing::blake2_256; use sp_runtime::{ - traits::{Hash, StaticLookup, Zero, MaybeSerializeDeserialize, Member, SignedExtension}, + traits::{ + Hash, StaticLookup, Zero, MaybeSerializeDeserialize, Member, SignedExtension, + DispatchInfoOf, + }, transaction_validity::{ ValidTransaction, InvalidTransaction, TransactionValidity, TransactionValidityError, }, @@ -123,7 +126,6 @@ use frame_support::dispatch::{DispatchResult, Dispatchable}; use frame_support::{ Parameter, decl_module, decl_event, decl_storage, decl_error, storage::child, parameter_types, IsSubType, - weights::DispatchInfo, }; use frame_support::traits::{OnUnbalanced, Currency, Get, Time, Randomness}; use frame_system::{self as system, ensure_signed, RawOrigin, ensure_root}; @@ -1091,7 +1093,6 @@ impl SignedExtension for CheckBlockGasLimit { type AccountId = T::AccountId; type Call = ::Call; type AdditionalSigned = (); - type DispatchInfo = DispatchInfo; type Pre = (); fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } @@ -1100,7 +1101,7 @@ impl SignedExtension for CheckBlockGasLimit { &self, _: &Self::AccountId, call: &Self::Call, - _: Self::DispatchInfo, + _: &DispatchInfoOf, _: usize, ) -> TransactionValidity { let call = match call.is_sub_type() { diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 04b9b1ee4c..f45b375476 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -2633,11 +2633,11 @@ fn check_block_gas_limit_works() { let call: Call = crate::Call::put_code(1000, vec![]).into(); assert_eq!( - check.validate(&0, &call, info, 0), InvalidTransaction::ExhaustsResources.into(), + check.validate(&0, &call, &info, 0), InvalidTransaction::ExhaustsResources.into(), ); let call: Call = crate::Call::update_schedule(Default::default()).into(); - assert_eq!(check.validate(&0, &call, info, 0), Ok(Default::default())); + assert_eq!(check.validate(&0, &call, &info, 0), Ok(Default::default())); }); } diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 51062c47ec..13985671c2 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -257,15 +257,16 @@ use sp_std::marker::PhantomData; use frame_support::{ dispatch::DispatchResult, decl_module, decl_storage, decl_event, weights::{ - SimpleDispatchInfo, DispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight, - PaysFee, + SimpleDispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee, }, }; use sp_std::prelude::*; use frame_system::{self as system, ensure_signed, ensure_root}; use codec::{Encode, Decode}; use sp_runtime::{ - traits::{SignedExtension, Bounded, SaturatedConversion}, + traits::{ + SignedExtension, Bounded, SaturatedConversion, DispatchInfoOf, + }, transaction_validity::{ ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity, }, @@ -619,7 +620,6 @@ impl SignedExtension for WatchDummy { // other pallets. type Call = Call; type AdditionalSigned = (); - type DispatchInfo = DispatchInfo; type Pre = (); fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } @@ -628,7 +628,7 @@ impl SignedExtension for WatchDummy { &self, _who: &Self::AccountId, call: &Self::Call, - _info: Self::DispatchInfo, + _info: &DispatchInfoOf, len: usize, ) -> TransactionValidity { // if the transaction is too big, just drop it. @@ -713,7 +713,7 @@ mod tests { use super::*; use frame_support::{ - assert_ok, impl_outer_origin, parameter_types, weights::GetDispatchInfo, + assert_ok, impl_outer_origin, parameter_types, weights::{DispatchInfo, GetDispatchInfo}, traits::{OnInitialize, OnFinalize} }; use sp_core::H256; @@ -829,13 +829,13 @@ mod tests { let info = DispatchInfo::default(); assert_eq!( - WatchDummy::(PhantomData).validate(&1, &call, info, 150) + WatchDummy::(PhantomData).validate(&1, &call, &info, 150) .unwrap() .priority, Bounded::max_value(), ); assert_eq!( - WatchDummy::(PhantomData).validate(&1, &call, info, 250), + WatchDummy::(PhantomData).validate(&1, &call, &info, 250), InvalidTransaction::ExhaustsResources.into(), ); }) diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index d30b66e083..f46fff1a33 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -120,9 +120,9 @@ impl< where Block::Extrinsic: Checkable + Codec, CheckedOf: - Applyable + + Applyable + GetDispatchInfo, - CallOf: Dispatchable, + CallOf: Dispatchable, OriginOf: From>, UnsignedValidator: ValidateUnsigned>, { @@ -145,9 +145,9 @@ impl< where Block::Extrinsic: Checkable + Codec, CheckedOf: - Applyable + + Applyable + GetDispatchInfo, - CallOf: Dispatchable, + CallOf: Dispatchable, OriginOf: From>, UnsignedValidator: ValidateUnsigned>, { @@ -307,7 +307,7 @@ where // Decode parameters and dispatch let dispatch_info = xt.get_dispatch_info(); - let r = Applyable::apply::(xt, dispatch_info, encoded_len)?; + let r = Applyable::apply::(xt, &dispatch_info, encoded_len)?; >::note_applied_extrinsic(&r, encoded_len as u32, dispatch_info); @@ -348,7 +348,7 @@ where let xt = uxt.check(&Default::default())?; let dispatch_info = xt.get_dispatch_info(); - xt.validate::(source, dispatch_info, encoded_len) + xt.validate::(source, &dispatch_info, encoded_len) } /// Start an offchain worker and generate extrinsics. diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 9bdfa4738b..b60e5c0e61 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -288,7 +288,7 @@ use sp_runtime::{ curve::PiecewiseLinear, traits::{ Convert, Zero, StaticLookup, CheckedSub, Saturating, SaturatedConversion, AtLeast32Bit, - SignedExtension, + SignedExtension, Dispatchable, DispatchInfoOf, }, transaction_validity::{ TransactionValidityError, TransactionValidity, ValidTransaction, InvalidTransaction, @@ -772,7 +772,7 @@ pub trait Trait: frame_system::Trait { type ElectionLookahead: Get; /// The overarching call type. - type Call: From> + IsSubType, Self> + Clone; + type Call: Dispatchable + From> + IsSubType, Self> + Clone; /// A transaction submitter. type SubmitTransaction: SubmitUnsignedTransaction::Call>; @@ -3135,7 +3135,6 @@ impl SignedExtension for LockStakingStatus { type AccountId = T::AccountId; type Call = ::Call; type AdditionalSigned = (); - type DispatchInfo = frame_support::weights::DispatchInfo; type Pre = (); fn additional_signed(&self) -> Result<(), TransactionValidityError> { Ok(()) } @@ -3144,7 +3143,7 @@ impl SignedExtension for LockStakingStatus { &self, _who: &Self::AccountId, call: &Self::Call, - _info: Self::DispatchInfo, + _info: &DispatchInfoOf, _len: usize, ) -> TransactionValidity { if let Some(inner_call) = call.is_sub_type() { diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 1777081769..9aaee23bc8 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -2939,7 +2939,7 @@ mod offchain_phragmen { let lock_staking: LockStakingStatus = Default::default(); assert_eq!( - lock_staking.validate(&10, &outer, Default::default(), Default::default(),), + lock_staking.validate(&10, &outer, &Default::default(), Default::default(),), TransactionValidity::Err(InvalidTransaction::Stale.into()), ) }) diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index 026b30d0f4..aadcec67a3 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -53,7 +53,7 @@ pub enum Never {} /// Serializable version of Dispatchable. /// This value can be used as a "function" in an extrinsic. pub trait Callable { - type Call: Dispatchable + Codec + Clone + PartialEq + Eq; + type Call: Dispatchable + Codec + Clone + PartialEq + Eq; } // dirty hack to work around serde_derive issue @@ -1593,6 +1593,7 @@ macro_rules! decl_module { { type Trait = $trait_instance; type Origin = $origin_type; + type Info = $crate::weights::DispatchInfo; type PostInfo = $crate::weights::PostDispatchInfo; fn dispatch(self, _origin: Self::Origin) -> $crate::dispatch::DispatchResultWithPostInfo { match self { @@ -1720,6 +1721,7 @@ macro_rules! impl_outer_dispatch { impl $crate::dispatch::Dispatchable for $call_type { type Origin = $origin; type Trait = $call_type; + type Info = $crate::weights::DispatchInfo; type PostInfo = $crate::weights::PostDispatchInfo; fn dispatch( self, diff --git a/frame/support/src/metadata.rs b/frame/support/src/metadata.rs index d9c8136d3c..3d99ddaa84 100644 --- a/frame/support/src/metadata.rs +++ b/frame/support/src/metadata.rs @@ -256,9 +256,8 @@ mod tests { struct TestExtension; impl sp_runtime::traits::SignedExtension for TestExtension { type AccountId = u32; - type Call = u32; + type Call = (); type AdditionalSigned = u32; - type DispatchInfo = (); type Pre = (); const IDENTIFIER: &'static str = "testextension"; fn additional_signed(&self) -> Result { @@ -270,9 +269,8 @@ mod tests { struct TestExtension2; impl sp_runtime::traits::SignedExtension for TestExtension2 { type AccountId = u32; - type Call = u32; + type Call = (); type AdditionalSigned = u32; - type DispatchInfo = (); type Pre = (); const IDENTIFIER: &'static str = "testextension2"; fn additional_signed(&self) -> Result { diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 38cd206a10..a38a8854c7 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -109,6 +109,7 @@ use sp_runtime::{ self, CheckEqual, AtLeast32Bit, Zero, SignedExtension, Lookup, LookupError, SimpleBitOps, Hash, Member, MaybeDisplay, BadOrigin, SaturatedConversion, MaybeSerialize, MaybeSerializeDeserialize, MaybeMallocSizeOf, StaticLookup, One, Bounded, + Dispatchable, DispatchInfoOf, PostDispatchInfoOf, }, }; @@ -146,7 +147,7 @@ pub trait Trait: 'static + Eq + Clone { + Clone; /// The aggregated `Call` type. - type Call: Debug; + type Call: Dispatchable + Debug; /// Account index (aka nonce) type. This stores the number of previous transactions associated /// with a sender account. @@ -1167,7 +1168,9 @@ pub fn split_inner(option: Option, splitter: impl FnOnce(T) -> (R, S #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct CheckWeight(PhantomData); -impl CheckWeight { +impl CheckWeight where + T::Call: Dispatchable +{ /// Get the quota ratio of each dispatch class type. This indicates that all operational /// dispatches can use the full capacity of any resource, while user-triggered ones can consume /// a portion. @@ -1183,7 +1186,7 @@ impl CheckWeight { /// /// Upon successes, it returns the new block weight as a `Result`. fn check_weight( - info: ::DispatchInfo, + info: &DispatchInfoOf, ) -> Result { let current_weight = Module::::all_extrinsics_weight(); let maximum_weight = T::MaximumBlockWeight::get(); @@ -1201,7 +1204,7 @@ impl CheckWeight { /// /// Upon successes, it returns the new block length as a `Result`. fn check_block_length( - info: ::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> Result { let current_len = Module::::all_extrinsics_len(); @@ -1217,7 +1220,7 @@ impl CheckWeight { } /// get the priority of an extrinsic denoted by `info`. - fn get_priority(info: ::DispatchInfo) -> TransactionPriority { + fn get_priority(info: &DispatchInfoOf) -> TransactionPriority { match info.class { DispatchClass::Normal => info.weight.into(), DispatchClass::Operational => Bounded::max_value(), @@ -1235,7 +1238,7 @@ impl CheckWeight { /// /// It checks and notes the new weight and length. fn do_pre_dispatch( - info: ::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> Result<(), TransactionValidityError> { let next_len = Self::check_block_length(info, len)?; @@ -1249,7 +1252,7 @@ impl CheckWeight { /// /// It only checks that the block weight and length limit will not exceed. fn do_validate( - info: ::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> TransactionValidity { // ignore the next weight and length. If they return `Ok`, then it is below the limit. @@ -1260,11 +1263,12 @@ impl CheckWeight { } } -impl SignedExtension for CheckWeight { +impl SignedExtension for CheckWeight where + T::Call: Dispatchable +{ type AccountId = T::AccountId; type Call = T::Call; type AdditionalSigned = (); - type DispatchInfo = DispatchInfo; type Pre = (); const IDENTIFIER: &'static str = "CheckWeight"; @@ -1274,7 +1278,7 @@ impl SignedExtension for CheckWeight { self, _who: &Self::AccountId, _call: &Self::Call, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> Result<(), TransactionValidityError> { if info.class == DispatchClass::Mandatory { @@ -1287,7 +1291,7 @@ impl SignedExtension for CheckWeight { &self, _who: &Self::AccountId, _call: &Self::Call, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> TransactionValidity { if info.class == DispatchClass::Mandatory { @@ -1298,7 +1302,7 @@ impl SignedExtension for CheckWeight { fn pre_dispatch_unsigned( _call: &Self::Call, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> Result<(), TransactionValidityError> { Self::do_pre_dispatch(info, len) @@ -1306,7 +1310,7 @@ impl SignedExtension for CheckWeight { fn validate_unsigned( _call: &Self::Call, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> TransactionValidity { Self::do_validate(info, len) @@ -1314,7 +1318,8 @@ impl SignedExtension for CheckWeight { fn post_dispatch( _pre: Self::Pre, - info: Self::DispatchInfo, + info: &DispatchInfoOf, + _post_info: &PostDispatchInfoOf, _len: usize, result: &DispatchResult, ) -> Result<(), TransactionValidityError> { @@ -1363,11 +1368,12 @@ impl Debug for CheckNonce { } } -impl SignedExtension for CheckNonce { +impl SignedExtension for CheckNonce where + T::Call: Dispatchable +{ type AccountId = T::AccountId; type Call = T::Call; type AdditionalSigned = (); - type DispatchInfo = DispatchInfo; type Pre = (); const IDENTIFIER: &'static str = "CheckNonce"; @@ -1377,7 +1383,7 @@ impl SignedExtension for CheckNonce { self, who: &Self::AccountId, _call: &Self::Call, - _info: Self::DispatchInfo, + _info: &DispatchInfoOf, _len: usize, ) -> Result<(), TransactionValidityError> { let mut account = Account::::get(who); @@ -1399,7 +1405,7 @@ impl SignedExtension for CheckNonce { &self, who: &Self::AccountId, _call: &Self::Call, - info: Self::DispatchInfo, + info: &DispatchInfoOf, _len: usize, ) -> TransactionValidity { // check index @@ -1458,7 +1464,6 @@ impl SignedExtension for CheckEra { type AccountId = T::AccountId; type Call = T::Call; type AdditionalSigned = T::Hash; - type DispatchInfo = DispatchInfo; type Pre = (); const IDENTIFIER: &'static str = "CheckEra"; @@ -1466,7 +1471,7 @@ impl SignedExtension for CheckEra { &self, _who: &Self::AccountId, _call: &Self::Call, - _info: Self::DispatchInfo, + _info: &DispatchInfoOf, _len: usize, ) -> TransactionValidity { let current_u64 = >::block_number().saturated_into::(); @@ -1515,7 +1520,6 @@ impl SignedExtension for CheckGenesis { type AccountId = T::AccountId; type Call = ::Call; type AdditionalSigned = T::Hash; - type DispatchInfo = DispatchInfo; type Pre = (); const IDENTIFIER: &'static str = "CheckGenesis"; @@ -1551,7 +1555,6 @@ impl SignedExtension for CheckVersion { type AccountId = T::AccountId; type Call = ::Call; type AdditionalSigned = u32; - type DispatchInfo = DispatchInfo; type Pre = (); const IDENTIFIER: &'static str = "CheckVersion"; @@ -1615,9 +1618,22 @@ mod tests { fn on_killed_account(who: &u64) { KILLED.with(|r| r.borrow_mut().push(*who)) } } + #[derive(Debug)] + pub struct Call {} + impl Dispatchable for Call { + type Origin = (); + type Trait = (); + type Info = DispatchInfo; + type PostInfo = (); + fn dispatch(self, _origin: Self::Origin) + -> sp_runtime::DispatchResultWithInfo { + panic!("Do not use dummy implementation for dispatch."); + } + } + impl Trait for Test { type Origin = Origin; - type Call = (); + type Call = Call; type Index = u64; type BlockNumber = u64; type Hash = H256; @@ -1650,7 +1666,7 @@ mod tests { type System = Module; - const CALL: &::Call = &(); + const CALL: &::Call = &Call {}; fn new_test_ext() -> sp_io::TestExternalities { GenesisConfig::default().build_storage::().unwrap().into() @@ -1851,14 +1867,14 @@ mod tests { let info = DispatchInfo::default(); let len = 0_usize; // stale - assert!(CheckNonce::(0).validate(&1, CALL, info, len).is_err()); - assert!(CheckNonce::(0).pre_dispatch(&1, CALL, info, len).is_err()); + assert!(CheckNonce::(0).validate(&1, CALL, &info, len).is_err()); + assert!(CheckNonce::(0).pre_dispatch(&1, CALL, &info, len).is_err()); // correct - assert!(CheckNonce::(1).validate(&1, CALL, info, len).is_ok()); - assert!(CheckNonce::(1).pre_dispatch(&1, CALL, info, len).is_ok()); + assert!(CheckNonce::(1).validate(&1, CALL, &info, len).is_ok()); + assert!(CheckNonce::(1).pre_dispatch(&1, CALL, &info, len).is_ok()); // future - assert!(CheckNonce::(5).validate(&1, CALL, info, len).is_ok()); - assert!(CheckNonce::(5).pre_dispatch(&1, CALL, info, len).is_err()); + assert!(CheckNonce::(5).validate(&1, CALL, &info, len).is_ok()); + assert!(CheckNonce::(5).pre_dispatch(&1, CALL, &info, len).is_err()); }) } @@ -1883,9 +1899,9 @@ mod tests { if f { assert!(r.is_err()) } else { assert!(r.is_ok()) } }; - reset_check_weight(small, false, 0); - reset_check_weight(medium, false, 0); - reset_check_weight(big, true, 1); + reset_check_weight(&small, false, 0); + reset_check_weight(&medium, false, 0); + reset_check_weight(&big, true, 1); }) } @@ -1896,7 +1912,7 @@ mod tests { let len = 0_usize; assert_eq!(System::all_extrinsics_weight(), 0); - let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, free, len); + let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &free, len); assert!(r.is_ok()); assert_eq!(System::all_extrinsics_weight(), 0); }) @@ -1910,7 +1926,7 @@ mod tests { let normal_limit = normal_weight_limit(); assert_eq!(System::all_extrinsics_weight(), 0); - let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, max, len); + let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &max, len); assert!(r.is_ok()); assert_eq!(System::all_extrinsics_weight(), normal_limit); }) @@ -1927,15 +1943,15 @@ mod tests { // given almost full block AllExtrinsicsWeight::put(normal_limit); // will not fit. - assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, normal, len).is_err()); + assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &normal, len).is_err()); // will fit. - assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, op, len).is_ok()); + assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &op, len).is_ok()); // likewise for length limit. let len = 100_usize; AllExtrinsicsLen::put(normal_length_limit()); - assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, normal, len).is_err()); - assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, op, len).is_ok()); + assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &normal, len).is_err()); + assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &op, len).is_ok()); }) } @@ -1947,13 +1963,13 @@ mod tests { let len = 0_usize; let priority = CheckWeight::(PhantomData) - .validate(&1, CALL, normal, len) + .validate(&1, CALL, &normal, len) .unwrap() .priority; assert_eq!(priority, 100); let priority = CheckWeight::(PhantomData) - .validate(&1, CALL, op, len) + .validate(&1, CALL, &op, len) .unwrap() .priority; assert_eq!(priority, u64::max_value()); @@ -1971,16 +1987,16 @@ mod tests { if f { assert!(r.is_err()) } else { assert!(r.is_ok()) } }; - reset_check_weight(normal, normal_limit - 1, false); - reset_check_weight(normal, normal_limit, false); - reset_check_weight(normal, normal_limit + 1, true); + reset_check_weight(&normal, normal_limit - 1, false); + reset_check_weight(&normal, normal_limit, false); + reset_check_weight(&normal, normal_limit + 1, true); // Operational ones don't have this limit. let op = DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: true }; - reset_check_weight(op, normal_limit, false); - reset_check_weight(op, normal_limit + 100, false); - reset_check_weight(op, 1024, false); - reset_check_weight(op, 1025, true); + reset_check_weight(&op, normal_limit, false); + reset_check_weight(&op, normal_limit + 100, false); + reset_check_weight(&op, 1024, false); + reset_check_weight(&op, 1025, true); }) } @@ -2012,7 +2028,7 @@ mod tests { System::set_block_number(17); >::insert(16, H256::repeat_byte(1)); - assert_eq!(ext.validate(&1, CALL, normal, len).unwrap().longevity, 15); + assert_eq!(ext.validate(&1, CALL, &normal, len).unwrap().longevity, 15); }) } diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 1078927747..7cf364d700 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -44,7 +44,10 @@ use sp_runtime::{ TransactionPriority, ValidTransaction, InvalidTransaction, TransactionValidityError, TransactionValidity, }, - traits::{Zero, Saturating, SignedExtension, SaturatedConversion, Convert}, + traits::{ + Zero, Saturating, SignedExtension, SaturatedConversion, Convert, Dispatchable, + DispatchInfoOf, + }, }; use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; @@ -98,7 +101,9 @@ decl_module! { } } -impl Module { +impl Module where + T::Call: Dispatchable, +{ /// Query the data that we know about the fee of a given `call`. /// /// As this module is not and cannot be aware of the internals of a signed extension, it only @@ -122,7 +127,7 @@ impl Module { let dispatch_info = ::get_dispatch_info(&unchecked_extrinsic); let partial_fee = - >::compute_fee(len, dispatch_info, 0u32.into()); + >::compute_fee(len, &dispatch_info, 0u32.into()); let DispatchInfo { weight, class, .. } = dispatch_info; RuntimeDispatchInfo { weight, class, partial_fee } @@ -134,7 +139,9 @@ impl Module { #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct ChargeTransactionPayment(#[codec(compact)] BalanceOf); -impl ChargeTransactionPayment { +impl ChargeTransactionPayment where + T::Call: Dispatchable, +{ /// utility constructor. Used only in client/factory code. pub fn from(fee: BalanceOf) -> Self { Self(fee) @@ -156,7 +163,7 @@ impl ChargeTransactionPayment { /// final_fee = base_fee + targeted_fee_adjustment(len_fee + weight_fee) + tip; pub fn compute_fee( len: u32, - info: ::DispatchInfo, + info: &DispatchInfoOf, tip: BalanceOf, ) -> BalanceOf where @@ -200,14 +207,14 @@ impl sp_std::fmt::Debug for ChargeTransactionPayment } } -impl SignedExtension for ChargeTransactionPayment - where BalanceOf: Send + Sync +impl SignedExtension for ChargeTransactionPayment where + BalanceOf: Send + Sync, + T::Call: Dispatchable, { const IDENTIFIER: &'static str = "ChargeTransactionPayment"; type AccountId = T::AccountId; type Call = T::Call; type AdditionalSigned = (); - type DispatchInfo = DispatchInfo; type Pre = (); fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } @@ -215,7 +222,7 @@ impl SignedExtension for ChargeTransactionPayment &self, who: &Self::AccountId, _call: &Self::Call, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> TransactionValidity { // pay any fees. @@ -438,14 +445,14 @@ mod tests { let len = 10; assert!( ChargeTransactionPayment::::from(0) - .pre_dispatch(&1, CALL, info_from_weight(5), len) + .pre_dispatch(&1, CALL, &info_from_weight(5), len) .is_ok() ); assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10); assert!( ChargeTransactionPayment::::from(5 /* tipped */) - .pre_dispatch(&2, CALL, info_from_weight(3), len) + .pre_dispatch(&2, CALL, &info_from_weight(3), len) .is_ok() ); assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 3 - 5); @@ -463,7 +470,7 @@ mod tests { // maximum weight possible assert!( ChargeTransactionPayment::::from(0) - .pre_dispatch(&1, CALL, info_from_weight(Weight::max_value()), 10) + .pre_dispatch(&1, CALL, &info_from_weight(Weight::max_value()), 10) .is_ok() ); // fee will be proportional to what is the actual maximum weight in the runtime. @@ -495,7 +502,7 @@ mod tests { }; assert!( ChargeTransactionPayment::::from(0) - .validate(&1, CALL, operational_transaction , len) + .validate(&1, CALL, &operational_transaction , len) .is_ok() ); @@ -507,7 +514,7 @@ mod tests { }; assert!( ChargeTransactionPayment::::from(0) - .validate(&1, CALL, free_transaction , len) + .validate(&1, CALL, &free_transaction , len) .is_err() ); }); @@ -527,7 +534,7 @@ mod tests { assert!( ChargeTransactionPayment::::from(10) // tipped - .pre_dispatch(&1, CALL, info_from_weight(3), len) + .pre_dispatch(&1, CALL, &info_from_weight(3), len) .is_ok() ); assert_eq!(Balances::free_balance(1), 100 - 10 - 5 - (10 + 3) * 3 / 2); @@ -587,25 +594,25 @@ mod tests { class: DispatchClass::Operational, pays_fee: false, }; - assert_eq!(ChargeTransactionPayment::::compute_fee(0, dispatch_info, 10), 10); + assert_eq!(ChargeTransactionPayment::::compute_fee(0, &dispatch_info, 10), 10); // No tip, only base fee works let dispatch_info = DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: true, }; - assert_eq!(ChargeTransactionPayment::::compute_fee(0, dispatch_info, 0), 100); + assert_eq!(ChargeTransactionPayment::::compute_fee(0, &dispatch_info, 0), 100); // Tip + base fee works - assert_eq!(ChargeTransactionPayment::::compute_fee(0, dispatch_info, 69), 169); + assert_eq!(ChargeTransactionPayment::::compute_fee(0, &dispatch_info, 69), 169); // Len (byte fee) + base fee works - assert_eq!(ChargeTransactionPayment::::compute_fee(42, dispatch_info, 0), 520); + assert_eq!(ChargeTransactionPayment::::compute_fee(42, &dispatch_info, 0), 520); // Weight fee + base fee works let dispatch_info = DispatchInfo { weight: 1000, class: DispatchClass::Operational, pays_fee: true, }; - assert_eq!(ChargeTransactionPayment::::compute_fee(0, dispatch_info, 0), 1100); + assert_eq!(ChargeTransactionPayment::::compute_fee(0, &dispatch_info, 0), 1100); }); } @@ -626,7 +633,7 @@ mod tests { class: DispatchClass::Operational, pays_fee: true, }; - assert_eq!(ChargeTransactionPayment::::compute_fee(0, dispatch_info, 0), 100); + assert_eq!(ChargeTransactionPayment::::compute_fee(0, &dispatch_info, 0), 100); // Everything works together :) let dispatch_info = DispatchInfo { @@ -638,7 +645,7 @@ mod tests { // adjustable fee = (123 * 1) + (456 * 10) = 4683 // adjusted fee = (4683 * .5) + 4683 = 7024.5 -> 7024 // final fee = 100 + 7024 + 789 tip = 7913 - assert_eq!(ChargeTransactionPayment::::compute_fee(456, dispatch_info, 789), 7913); + assert_eq!(ChargeTransactionPayment::::compute_fee(456, &dispatch_info, 789), 7913); }); } @@ -660,7 +667,7 @@ mod tests { assert_eq!( ChargeTransactionPayment::::compute_fee( ::max_value(), - dispatch_info, + &dispatch_info, ::max_value() ), ::max_value() diff --git a/primitives/runtime/src/generic/checked_extrinsic.rs b/primitives/runtime/src/generic/checked_extrinsic.rs index 673501bb91..a329f334c0 100644 --- a/primitives/runtime/src/generic/checked_extrinsic.rs +++ b/primitives/runtime/src/generic/checked_extrinsic.rs @@ -18,9 +18,8 @@ //! stage. use crate::traits::{ - self, Member, MaybeDisplay, SignedExtension, Dispatchable, + self, Member, MaybeDisplay, SignedExtension, Dispatchable, DispatchInfoOf, ValidateUnsigned, }; -use crate::traits::ValidateUnsigned; use crate::transaction_validity::{TransactionValidity, TransactionSource}; /// Definition of something that the external world might want to say; its @@ -36,28 +35,26 @@ pub struct CheckedExtrinsic { pub function: Call, } -impl traits::Applyable for +impl traits::Applyable for CheckedExtrinsic where AccountId: Member + MaybeDisplay, Call: Member + Dispatchable, - Extra: SignedExtension, + Extra: SignedExtension, Origin: From>, - Info: Clone, { type Call = Call; - type DispatchInfo = Info; fn validate>( &self, // TODO [#5006;ToDr] should source be passed to `SignedExtension`s? // Perhaps a change for 2.0 to avoid breaking too much APIs? source: TransactionSource, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> TransactionValidity { if let Some((ref id, ref extra)) = self.signed { - Extra::validate(extra, id, &self.function, info.clone(), len) + Extra::validate(extra, id, &self.function, info, len) } else { let valid = Extra::validate_unsigned(&self.function, info, len)?; let unsigned_validation = U::validate_unsigned(source, &self.function)?; @@ -67,21 +64,24 @@ where fn apply>( self, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> crate::ApplyExtrinsicResult { let (maybe_who, pre) = if let Some((id, extra)) = self.signed { - let pre = Extra::pre_dispatch(extra, &id, &self.function, info.clone(), len)?; + let pre = Extra::pre_dispatch(extra, &id, &self.function, info, len)?; (Some(id), pre) } else { - let pre = Extra::pre_dispatch_unsigned(&self.function, info.clone(), len)?; + let pre = Extra::pre_dispatch_unsigned(&self.function, info, len)?; U::pre_dispatch(&self.function)?; (None, pre) }; - let res = self.function.dispatch(Origin::from(maybe_who)) - .map(|_| ()) - .map_err(|e| e.error); - Extra::post_dispatch(pre, info.clone(), len, &res)?; + let res = self.function.dispatch(Origin::from(maybe_who)); + let post_info = match res { + Ok(info) => info, + Err(err) => err.post_info, + }; + let res = res.map(|_| ()).map_err(|e| e.error); + Extra::post_dispatch(pre, info, &post_info, len, &res)?; Ok(res) } } diff --git a/primitives/runtime/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs index a516bc1f7f..3e9e52ba8b 100644 --- a/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -357,7 +357,6 @@ mod tests { type AccountId = u64; type Call = (); type AdditionalSigned = (); - type DispatchInfo = (); type Pre = (); fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index f5fc35fe8e..1414a5f4f0 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -21,7 +21,7 @@ use std::{fmt::Debug, ops::Deref, fmt, cell::RefCell}; use crate::codec::{Codec, Encode, Decode}; use crate::traits::{ self, Checkable, Applyable, BlakeTwo256, OpaqueKeys, - SignedExtension, Dispatchable, + SignedExtension, Dispatchable, DispatchInfoOf, }; use crate::traits::ValidateUnsigned; use crate::{generic, KeyTypeId, ApplyExtrinsicResult}; @@ -345,20 +345,18 @@ impl traits::Extrinsic for TestXt } } -impl Applyable for TestXt where +impl Applyable for TestXt where Call: 'static + Sized + Send + Sync + Clone + Eq + Codec + Debug + Dispatchable, - Extra: SignedExtension, + Extra: SignedExtension, Origin: From>, - Info: Clone, { type Call = Call; - type DispatchInfo = Info; /// Checks to see if this is a valid *transaction*. It returns information on it if so. fn validate>( &self, _source: TransactionSource, - _info: Self::DispatchInfo, + _info: &DispatchInfoOf, _len: usize, ) -> TransactionValidity { Ok(Default::default()) @@ -368,7 +366,7 @@ impl Applyable for TestXt where /// index and sender. fn apply>( self, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> ApplyExtrinsicResult { let maybe_who = if let Some((who, extra)) = self.signature { diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index da5d5c4a81..fdf1d6396d 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -625,6 +625,10 @@ pub trait Dispatchable { type Origin; /// ... type Trait; + /// An opaque set of information attached to the transaction. This could be constructed anywhere + /// down the line in a runtime. The current Substrate runtime uses a struct with the same name + /// to represent the dispatch class and weight. + type Info; /// Additional information that is returned by `dispatch`. Can be used to supply the caller /// with information about a `Dispatchable` that is ownly known post dispatch. type PostInfo: Eq + PartialEq + Clone + Copy + Encode + Decode + Printable; @@ -632,6 +636,21 @@ pub trait Dispatchable { fn dispatch(self, origin: Self::Origin) -> crate::DispatchResultWithInfo; } +/// Shortcut to reference the `Info` type of a `Dispatchable`. +pub type DispatchInfoOf = ::Info; +/// Shortcut to reference the `PostInfo` type of a `Dispatchable`. +pub type PostDispatchInfoOf = ::PostInfo; + +impl Dispatchable for () { + type Origin = (); + type Trait = (); + type Info = (); + type PostInfo = (); + fn dispatch(self, _origin: Self::Origin) -> crate::DispatchResultWithInfo { + panic!("This implemention should not be used for actual dispatch."); + } +} + /// Means by which a transaction may be extended. This type embodies both the data and the logic /// that should be additionally associated with the transaction. It should be plain old data. pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq { @@ -645,7 +664,7 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq type AccountId; /// The type which encodes the call to be dispatched. - type Call; + type Call: Dispatchable; /// Any additional data that will go into the signed payload. This may be created dynamically /// from the transaction using the `additional_signed` function. @@ -654,11 +673,6 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq /// The type that encodes information that can be passed from pre_dispatch to post-dispatch. type Pre: Default; - /// An opaque set of information attached to the transaction. This could be constructed anywhere - /// down the line in a runtime. The current Substrate runtime uses a struct with the same name - /// to represent the dispatch class and weight. - type DispatchInfo: Clone; - /// Construct any additional data that should be in the signed payload of the transaction. Can /// also perform any pre-signature-verification checks and return an error if needed. fn additional_signed(&self) -> Result; @@ -676,7 +690,7 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq &self, _who: &Self::AccountId, _call: &Self::Call, - _info: Self::DispatchInfo, + _info: &DispatchInfoOf, _len: usize, ) -> TransactionValidity { Ok(ValidTransaction::default()) @@ -694,7 +708,7 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq self, who: &Self::AccountId, call: &Self::Call, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> Result { self.validate(who, call, info.clone(), len) @@ -712,7 +726,7 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq /// Make sure to perform the same checks in `pre_dispatch_unsigned` function. fn validate_unsigned( _call: &Self::Call, - _info: Self::DispatchInfo, + _info: &DispatchInfoOf, _len: usize, ) -> TransactionValidity { Ok(ValidTransaction::default()) @@ -728,7 +742,7 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq /// perform the same validation as in `validate_unsigned`. fn pre_dispatch_unsigned( call: &Self::Call, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> Result { Self::validate_unsigned(call, info.clone(), len) @@ -751,7 +765,8 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq /// will come from either an offchain-worker or via `InherentData`. fn post_dispatch( _pre: Self::Pre, - _info: Self::DispatchInfo, + _info: &DispatchInfoOf, + _post_info: &PostDispatchInfoOf, _len: usize, _result: &DispatchResult, ) -> Result<(), TransactionValidityError> { @@ -771,11 +786,10 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq } #[impl_for_tuples(1, 12)] -impl SignedExtension for Tuple { - for_tuples!( where #( Tuple: SignedExtension )* ); +impl SignedExtension for Tuple { + for_tuples!( where #( Tuple: SignedExtension )* ); type AccountId = AccountId; type Call = Call; - type DispatchInfo = Info; const IDENTIFIER: &'static str = "You should call `identifier()`!"; for_tuples!( type AdditionalSigned = ( #( Tuple::AdditionalSigned ),* ); ); for_tuples!( type Pre = ( #( Tuple::Pre ),* ); ); @@ -788,45 +802,46 @@ impl SignedExtension for Tuple { &self, who: &Self::AccountId, call: &Self::Call, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> TransactionValidity { let valid = ValidTransaction::default(); - for_tuples!( #( let valid = valid.combine_with(Tuple.validate(who, call, info.clone(), len)?); )* ); + for_tuples!( #( let valid = valid.combine_with(Tuple.validate(who, call, info, len)?); )* ); Ok(valid) } - fn pre_dispatch(self, who: &Self::AccountId, call: &Self::Call, info: Self::DispatchInfo, len: usize) + fn pre_dispatch(self, who: &Self::AccountId, call: &Self::Call, info: &DispatchInfoOf, len: usize) -> Result { - Ok(for_tuples!( ( #( Tuple.pre_dispatch(who, call, info.clone(), len)? ),* ) )) + Ok(for_tuples!( ( #( Tuple.pre_dispatch(who, call, info, len)? ),* ) )) } fn validate_unsigned( call: &Self::Call, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> TransactionValidity { let valid = ValidTransaction::default(); - for_tuples!( #( let valid = valid.combine_with(Tuple::validate_unsigned(call, info.clone(), len)?); )* ); + for_tuples!( #( let valid = valid.combine_with(Tuple::validate_unsigned(call, info, len)?); )* ); Ok(valid) } fn pre_dispatch_unsigned( call: &Self::Call, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> Result { - Ok(for_tuples!( ( #( Tuple::pre_dispatch_unsigned(call, info.clone(), len)? ),* ) )) + Ok(for_tuples!( ( #( Tuple::pre_dispatch_unsigned(call, info, len)? ),* ) )) } fn post_dispatch( pre: Self::Pre, - info: Self::DispatchInfo, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, len: usize, result: &DispatchResult, ) -> Result<(), TransactionValidityError> { - for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info.clone(), len, result)?; )* ); + for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info, post_info, len, result)?; )* ); Ok(()) } @@ -844,7 +859,6 @@ impl SignedExtension for () { type AdditionalSigned = (); type Call = (); type Pre = (); - type DispatchInfo = (); const IDENTIFIER: &'static str = "UnitSignedExtension"; fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } } @@ -857,16 +871,13 @@ impl SignedExtension for () { /// each piece of attributable information to be disambiguated. pub trait Applyable: Sized + Send + Sync { /// Type by which we can dispatch. Restricts the `UnsignedValidator` type. - type Call; - - /// An opaque set of information attached to the transaction. - type DispatchInfo: Clone; + type Call: Dispatchable; /// Checks to see if this is a valid *transaction*. It returns information on it if so. fn validate>( &self, source: TransactionSource, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> TransactionValidity; @@ -874,7 +885,7 @@ pub trait Applyable: Sized + Send + Sync { /// index and sender. fn apply>( self, - info: Self::DispatchInfo, + info: &DispatchInfoOf, len: usize, ) -> crate::ApplyExtrinsicResult; } @@ -1273,6 +1284,12 @@ impl Printable for bool { } } +impl Printable for () { + fn print(&self) { + "()".print() + } +} + #[impl_for_tuples(1, 12)] impl Printable for Tuple { fn print(&self) { diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index f3efb4bea7..c0aea9a2ab 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -181,6 +181,16 @@ impl ExtrinsicT for Extrinsic { } } +impl sp_runtime::traits::Dispatchable for Extrinsic { + type Origin = (); + type Trait = (); + type Info = (); + type PostInfo = (); + fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo { + panic!("This implemention should not be used for actual dispatch."); + } +} + impl Extrinsic { pub fn transfer(&self) -> &Transfer { match self { -- GitLab From 967852f0dfc6d9cee376d3d83ba0110c2bfe41c7 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 8 Apr 2020 11:14:35 +0200 Subject: [PATCH 184/300] Add more Prometheus metrics (#5571) * Add more Prometheus metrics * Update client/network/src/service.rs Co-Authored-By: Max Inden * Update client/network/src/service.rs Co-Authored-By: Max Inden Co-authored-by: Gavin Wood Co-authored-by: Max Inden --- client/network/src/service.rs | 152 ++++++++++++++++++++++++++++------ 1 file changed, 127 insertions(+), 25 deletions(-) diff --git a/client/network/src/service.rs b/client/network/src/service.rs index fb33901dd0..48b5c30d3e 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -38,13 +38,13 @@ use crate::{ }; use futures::prelude::*; use libp2p::{PeerId, Multiaddr}; -use libp2p::core::{Executor, connection::PendingConnectionError}; +use libp2p::core::{ConnectedPoint, Executor, connection::{ConnectionError, PendingConnectionError}}; use libp2p::kad::record; -use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent}; +use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent, protocols_handler::NodeHandlerWrapperError}; use log::{error, info, trace, warn}; use parking_lot::Mutex; use prometheus_endpoint::{ - register, Counter, Gauge, GaugeVec, HistogramOpts, HistogramVec, Opts, PrometheusError, Registry, U64, + register, Counter, CounterVec, Gauge, GaugeVec, HistogramOpts, HistogramVec, Opts, PrometheusError, Registry, U64, }; use sc_peerset::PeersetHandle; use sp_consensus::import_queue::{BlockImportError, BlockImportResult, ImportQueue, Link}; @@ -821,13 +821,18 @@ pub struct NetworkWorker { struct Metrics { // This list is ordered alphabetically - connections: Gauge, + connections: GaugeVec, + connections_closed_total: CounterVec, import_queue_blocks_submitted: Counter, import_queue_finality_proofs_submitted: Counter, import_queue_justifications_submitted: Counter, + incoming_connections_errors_total: Counter, + incoming_connections_total: Counter, is_major_syncing: Gauge, issued_light_requests: Counter, kbuckets_num_nodes: Gauge, + listeners_local_addresses: Gauge, + listeners_errors_total: Counter, network_per_sec_bytes: GaugeVec, notifications_queues_size: HistogramVec, notifications_sizes: HistogramVec, @@ -836,6 +841,8 @@ struct Metrics { peers_count: Gauge, peerset_num_discovered: Gauge, peerset_num_requested: Gauge, + pending_connections: Gauge, + pending_connections_errors_total: CounterVec, random_kademalia_queries_total: Counter, } @@ -843,8 +850,19 @@ impl Metrics { fn register(registry: &Registry) -> Result { Ok(Self { // This list is ordered alphabetically - connections: register(Gauge::new( - "sub_libp2p_connections", "Number of libp2p connections" + connections: register(GaugeVec::new( + Opts::new( + "sub_libp2p_connections", + "Number of active libp2p connections" + ), + &["direction"] + )?, registry)?, + connections_closed_total: register(CounterVec::new( + Opts::new( + "sub_libp2p_connections_closed_total", + "Total number of connections closed, by reason" + ), + &["reason"] )?, registry)?, import_queue_blocks_submitted: register(Counter::new( "import_queue_blocks_submitted", @@ -858,6 +876,14 @@ impl Metrics { "import_queue_justifications_submitted", "Number of justifications submitted to the import queue.", )?, registry)?, + incoming_connections_errors_total: register(Counter::new( + "sub_libp2p_incoming_connections_handshake_errors_total", + "Total number of incoming connections that have failed during the initial handshake" + )?, registry)?, + incoming_connections_total: register(Counter::new( + "sub_libp2p_incoming_connections_total", + "Total number of incoming connections on the listening sockets" + )?, registry)?, is_major_syncing: register(Gauge::new( "sub_libp2p_is_major_syncing", "Whether the node is performing a major sync or not.", )?, registry)?, @@ -868,6 +894,13 @@ impl Metrics { kbuckets_num_nodes: register(Gauge::new( "sub_libp2p_kbuckets_num_nodes", "Number of nodes in the Kademlia k-buckets" )?, registry)?, + listeners_local_addresses: register(Gauge::new( + "sub_libp2p_listeners_local_addresses", "Number of local addresses we're listening on" + )?, registry)?, + listeners_errors_total: register(Counter::new( + "sub_libp2p_listeners_errors_total", + "Total number of non-fatal errors reported by a listener" + )?, registry)?, network_per_sec_bytes: register(GaugeVec::new( Opts::new( "sub_libp2p_network_per_sec_bytes", @@ -916,6 +949,17 @@ impl Metrics { peerset_num_requested: register(Gauge::new( "sub_libp2p_peerset_num_requested", "Number of nodes that the peerset manager wants us to be connected to", )?, registry)?, + pending_connections: register(Gauge::new( + "sub_libp2p_pending_connections", + "Number of connections in the process of being established", + )?, registry)?, + pending_connections_errors_total: register(CounterVec::new( + Opts::new( + "sub_libp2p_pending_connections_errors_total", + "Total number of node connection failures" + ), + &["reason"] + )?, registry)?, random_kademalia_queries_total: register(Counter::new( "sub_libp2p_random_kademalia_queries_total", "Number of random Kademlia queries started", )?, registry)?, @@ -1047,22 +1091,50 @@ impl Future for NetworkWorker { metrics.update_with_network_event(&ev); } }, - Poll::Ready(SwarmEvent::ConnectionEstablished { peer_id, .. }) => { + Poll::Ready(SwarmEvent::ConnectionEstablished { peer_id, endpoint, .. }) => { trace!(target: "sub-libp2p", "Libp2p => Connected({:?})", peer_id); if let Some(metrics) = this.metrics.as_ref() { - metrics.connections.inc(); + match endpoint { + ConnectedPoint::Dialer { .. } => + metrics.connections.with_label_values(&["out"]).inc(), + ConnectedPoint::Listener { .. } => + metrics.connections.with_label_values(&["in"]).inc(), + } + } + }, + Poll::Ready(SwarmEvent::ConnectionClosed { peer_id, cause, endpoint, .. }) => { + trace!(target: "sub-libp2p", "Libp2p => Disconnected({:?}, {:?})", peer_id, cause); + if let Some(metrics) = this.metrics.as_ref() { + match endpoint { + ConnectedPoint::Dialer { .. } => + metrics.connections.with_label_values(&["out"]).dec(), + ConnectedPoint::Listener { .. } => + metrics.connections.with_label_values(&["in"]).dec(), + } + match cause { + ConnectionError::IO(_) => + metrics.connections_closed_total.with_label_values(&["transport-error"]).inc(), + ConnectionError::ConnectionLimit(_) => + metrics.connections_closed_total.with_label_values(&["limit-reached"]).inc(), + ConnectionError::Handler(NodeHandlerWrapperError::Handler(_)) => + metrics.connections_closed_total.with_label_values(&["protocol-error"]).inc(), + ConnectionError::Handler(NodeHandlerWrapperError::KeepAliveTimeout) => + metrics.connections_closed_total.with_label_values(&["keep-alive-timeout"]).inc(), + } + } + }, + Poll::Ready(SwarmEvent::NewListenAddr(addr)) => { + trace!(target: "sub-libp2p", "Libp2p => NewListenAddr({})", addr); + if let Some(metrics) = this.metrics.as_ref() { + metrics.listeners_local_addresses.inc(); } }, - Poll::Ready(SwarmEvent::ConnectionClosed { peer_id, .. }) => { - trace!(target: "sub-libp2p", "Libp2p => Disconnected({:?})", peer_id); + Poll::Ready(SwarmEvent::ExpiredListenAddr(addr)) => { + trace!(target: "sub-libp2p", "Libp2p => ExpiredListenAddr({})", addr); if let Some(metrics) = this.metrics.as_ref() { - metrics.connections.dec(); + metrics.listeners_local_addresses.dec(); } }, - Poll::Ready(SwarmEvent::NewListenAddr(addr)) => - trace!(target: "sub-libp2p", "Libp2p => NewListenAddr({})", addr), - Poll::Ready(SwarmEvent::ExpiredListenAddr(addr)) => - trace!(target: "sub-libp2p", "Libp2p => ExpiredListenAddr({})", addr), Poll::Ready(SwarmEvent::UnreachableAddr { peer_id, address, error, .. }) => { trace!( target: "sub-libp2p", "Libp2p => Failed to reach {:?} through {:?}: {}", @@ -1080,25 +1152,54 @@ impl Future for NetworkWorker { ); } } + + if let Some(metrics) = this.metrics.as_ref() { + match error { + PendingConnectionError::InvalidPeerId => + metrics.pending_connections_errors_total.with_label_values(&["invalid-peer-id"]).inc(), + PendingConnectionError::Transport(_) | PendingConnectionError::IO(_) => + metrics.pending_connections_errors_total.with_label_values(&["transport-error"]).inc(), + } + } } Poll::Ready(SwarmEvent::Dialing(peer_id)) => trace!(target: "sub-libp2p", "Libp2p => Dialing({:?})", peer_id), - Poll::Ready(SwarmEvent::IncomingConnection { local_addr, send_back_addr }) => + Poll::Ready(SwarmEvent::IncomingConnection { local_addr, send_back_addr }) => { trace!(target: "sub-libp2p", "Libp2p => IncomingConnection({},{}))", - local_addr, send_back_addr), - Poll::Ready(SwarmEvent::IncomingConnectionError { local_addr, send_back_addr, error }) => + local_addr, send_back_addr); + if let Some(metrics) = this.metrics.as_ref() { + metrics.incoming_connections_total.inc(); + } + }, + Poll::Ready(SwarmEvent::IncomingConnectionError { local_addr, send_back_addr, error }) => { trace!(target: "sub-libp2p", "Libp2p => IncomingConnectionError({},{}): {}", - local_addr, send_back_addr, error), - Poll::Ready(SwarmEvent::BannedPeer { peer_id, endpoint }) => + local_addr, send_back_addr, error); + if let Some(metrics) = this.metrics.as_ref() { + metrics.incoming_connections_errors_total.inc(); + } + }, + Poll::Ready(SwarmEvent::BannedPeer { peer_id, endpoint }) => { trace!(target: "sub-libp2p", "Libp2p => BannedPeer({}). Connected via {:?}.", - peer_id, endpoint), + peer_id, endpoint); + if let Some(metrics) = this.metrics.as_ref() { + metrics.incoming_connections_errors_total.inc(); + } + }, Poll::Ready(SwarmEvent::UnknownPeerUnreachableAddr { address, error }) => trace!(target: "sub-libp2p", "Libp2p => UnknownPeerUnreachableAddr({}): {}", address, error), - Poll::Ready(SwarmEvent::ListenerClosed { reason, addresses: _ }) => - warn!(target: "sub-libp2p", "Libp2p => ListenerClosed: {:?}", reason), - Poll::Ready(SwarmEvent::ListenerError { error }) => - trace!(target: "sub-libp2p", "Libp2p => ListenerError: {}", error), + Poll::Ready(SwarmEvent::ListenerClosed { reason, addresses }) => { + warn!(target: "sub-libp2p", "Libp2p => ListenerClosed: {:?}", reason); + if let Some(metrics) = this.metrics.as_ref() { + metrics.listeners_local_addresses.sub(addresses.len() as u64); + } + }, + Poll::Ready(SwarmEvent::ListenerError { error }) => { + trace!(target: "sub-libp2p", "Libp2p => ListenerError: {}", error); + if let Some(metrics) = this.metrics.as_ref() { + metrics.listeners_errors_total.inc(); + } + }, }; } @@ -1127,6 +1228,7 @@ impl Future for NetworkWorker { metrics.peers_count.set(num_connected_peers as u64); metrics.peerset_num_discovered.set(this.network_service.user_protocol().num_discovered_peers() as u64); metrics.peerset_num_requested.set(this.network_service.user_protocol().requested_peers().count() as u64); + metrics.pending_connections.set(Swarm::network_info(&this.network_service).num_connections_pending as u64); } Poll::Pending -- GitLab From ae77b81388174764d24184c6948a77a7a06d0bbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 8 Apr 2020 11:17:21 +0200 Subject: [PATCH 185/300] Unsigned Validation best practices (#5563) * Configurable Unsigned Priority. * Use the new builder. * Fix tests. * Fix benches. * Remove unused import. * Rename for_pallet --- bin/node/runtime/src/lib.rs | 7 +- frame/example-offchain-worker/src/lib.rs | 24 ++-- frame/example-offchain-worker/src/tests.rs | 2 + frame/im-online/src/lib.rs | 21 ++- frame/im-online/src/mock.rs | 5 + frame/session/benchmarking/src/mock.rs | 2 + frame/staking/src/lib.rs | 24 ++-- frame/staking/src/mock.rs | 2 + frame/staking/src/tests.rs | 2 +- .../runtime/src/transaction_validity.rs | 131 ++++++++++++++++++ 10 files changed, 194 insertions(+), 26 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 483c8c6c97..3752ca4d8e 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -35,7 +35,7 @@ use sp_runtime::{ impl_opaque_keys, generic, create_runtime_str, }; use sp_runtime::curve::PiecewiseLinear; -use sp_runtime::transaction_validity::{TransactionValidity, TransactionSource}; +use sp_runtime::transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority}; use sp_runtime::traits::{ self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion, ConvertInto, OpaqueKeys, @@ -361,6 +361,7 @@ impl pallet_staking::Trait for Runtime { type Call = Call; type SubmitTransaction = TransactionSubmitterOf<()>; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; + type UnsignedPriority = StakingUnsignedPriority; } parameter_types! { @@ -540,6 +541,9 @@ impl pallet_sudo::Trait for Runtime { parameter_types! { pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_SLOTS as _; + pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); + /// We prioritize im-online heartbeats over phragmen solution submission. + pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2; } impl pallet_im_online::Trait for Runtime { @@ -549,6 +553,7 @@ impl pallet_im_online::Trait for Runtime { type SubmitTransaction = TransactionSubmitterOf; type SessionDuration = SessionDuration; type ReportUnresponsiveness = Offences; + type UnsignedPriority = ImOnlineUnsignedPriority; } impl pallet_offences::Trait for Runtime { diff --git a/frame/example-offchain-worker/src/lib.rs b/frame/example-offchain-worker/src/lib.rs index e64b3dfa77..ac9ac2d1ee 100644 --- a/frame/example-offchain-worker/src/lib.rs +++ b/frame/example-offchain-worker/src/lib.rs @@ -53,9 +53,10 @@ use sp_runtime::{ traits::Zero, transaction_validity::{ InvalidTransaction, ValidTransaction, TransactionValidity, TransactionSource, + TransactionPriority, }, }; -use sp_std::{vec, vec::Vec}; +use sp_std::vec::Vec; use lite_json::json::JsonValue; #[cfg(test)] @@ -106,6 +107,12 @@ pub trait Trait: frame_system::Trait { /// /// This ensures that we only accept unsigned transactions once, every `UnsignedInterval` blocks. type UnsignedInterval: Get; + + /// A configuration for base priority of unsigned transactions. + /// + /// This is exposed so that it can be tuned for particular runtime, when + /// multiple pallets send unsigned transactions. + type UnsignedPriority: Get; } decl_storage! { @@ -537,32 +544,33 @@ impl frame_support::unsigned::ValidateUnsigned for Module { .map(|price| if &price > new_price { price - new_price } else { new_price - price }) .unwrap_or(0); - Ok(ValidTransaction { + ValidTransaction::with_tag_prefix("ExampleOffchainWorker") // We set base priority to 2**20 to make sure it's included before any other // transactions in the pool. Next we tweak the priority depending on how much // it differs from the current average. (the more it differs the more priority it // has). - priority: (1 << 20) + avg_price as u64, + .priority(T::UnsignedPriority::get().saturating_add(avg_price as _)) // This transaction does not require anything else to go before into the pool. // In theory we could require `previous_unsigned_at` transaction to go first, // but it's not necessary in our case. - requires: vec![], + //.and_requires() + // We set the `provides` tag to be the same as `next_unsigned_at`. This makes // sure only one transaction produced after `next_unsigned_at` will ever // get to the transaction pool and will end up in the block. // We can still have multiple transactions compete for the same "spot", // and the one with higher priority will replace other one in the pool. - provides: vec![codec::Encode::encode(&(KEY_TYPE.0, next_unsigned_at))], + .and_provides(next_unsigned_at) // The transaction is only valid for next 5 blocks. After that it's // going to be revalidated by the pool. - longevity: 5, + .longevity(5) // It's fine to propagate that transaction to other peers, which means it can be // created even by nodes that don't produce blocks. // Note that sometimes it's better to keep it for yourself (if you are the block // producer), since for instance in some schemes others may copy your solution and // claim a reward. - propagate: true, - }) + .propagate(true) + .build() } else { InvalidTransaction::Call.into() } diff --git a/frame/example-offchain-worker/src/tests.rs b/frame/example-offchain-worker/src/tests.rs index f64503b0a9..727c4942f6 100644 --- a/frame/example-offchain-worker/src/tests.rs +++ b/frame/example-offchain-worker/src/tests.rs @@ -94,6 +94,7 @@ impl frame_system::offchain::CreateTransaction for Test { parameter_types! { pub const GracePeriod: u64 = 5; pub const UnsignedInterval: u64 = 128; + pub const UnsignedPriority: u64 = 1 << 20; } impl Trait for Test { @@ -103,6 +104,7 @@ impl Trait for Test { type SubmitUnsignedTransaction = SubmitTransaction; type GracePeriod = GracePeriod; type UnsignedInterval = UnsignedInterval; + type UnsignedPriority = UnsignedPriority; } type Example = Module; diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 077471d354..9c2b55a5c0 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -247,6 +247,12 @@ pub trait Trait: frame_system::Trait + pallet_session::historical::Trait { IdentificationTuple, UnresponsivenessOffence>, >; + + /// A configuration for base priority of unsigned transactions. + /// + /// This is exposed so that it can be tuned for particular runtime, when + /// multiple pallets send unsigned transactions. + type UnsignedPriority: Get; } decl_event!( @@ -658,13 +664,14 @@ impl frame_support::unsigned::ValidateUnsigned for Module { return InvalidTransaction::BadProof.into(); } - Ok(ValidTransaction { - priority: TransactionPriority::max_value(), - requires: vec![], - provides: vec![(current_session, authority_id).encode()], - longevity: TryInto::::try_into(T::SessionDuration::get() / 2.into()).unwrap_or(64_u64), - propagate: true, - }) + ValidTransaction::with_tag_prefix("ImOnline") + .priority(T::UnsignedPriority::get()) + .and_provides((current_session, authority_id)) + .longevity(TryInto::::try_into( + T::SessionDuration::get() / 2.into() + ).unwrap_or(64_u64)) + .propagate(true) + .build() } else { InvalidTransaction::Call.into() } diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 3dc0543d88..73ccaf3f70 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -160,6 +160,10 @@ impl pallet_authorship::Trait for Runtime { type EventHandler = ImOnline; } +parameter_types! { + pub const UnsignedPriority: u64 = 1 << 20; +} + impl Trait for Runtime { type AuthorityId = UintAuthorityId; type Event = (); @@ -167,6 +171,7 @@ impl Trait for Runtime { type SubmitTransaction = SubmitTransaction; type ReportUnresponsiveness = OffenceHandler; type SessionDuration = Period; + type UnsignedPriority = UnsignedPriority; } /// Im Online module. diff --git a/frame/session/benchmarking/src/mock.rs b/frame/session/benchmarking/src/mock.rs index 219a1904e0..ff7965efca 100644 --- a/frame/session/benchmarking/src/mock.rs +++ b/frame/session/benchmarking/src/mock.rs @@ -146,6 +146,7 @@ pallet_staking_reward_curve::build! { parameter_types! { pub const RewardCurve: &'static sp_runtime::curve::PiecewiseLinear<'static> = &I_NPOS; pub const MaxNominatorRewardedPerValidator: u32 = 64; + pub const UnsignedPriority: u64 = 1 << 20; } pub type Extrinsic = sp_runtime::testing::TestXt; @@ -174,6 +175,7 @@ impl pallet_staking::Trait for Test { type Call = Call; type SubmitTransaction = SubmitTransaction; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; + type UnsignedPriority = UnsignedPriority; } impl crate::Trait for Test {} diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index b60e5c0e61..86e76408a4 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -292,7 +292,7 @@ use sp_runtime::{ }, transaction_validity::{ TransactionValidityError, TransactionValidity, ValidTransaction, InvalidTransaction, - TransactionSource, + TransactionSource, TransactionPriority, }, }; use sp_staking::{ @@ -782,6 +782,12 @@ pub trait Trait: frame_system::Trait { /// For each validator only the `$MaxNominatorRewardedPerValidator` biggest stakers can claim /// their reward. This used to limit the i/o cost for the nominator payout. type MaxNominatorRewardedPerValidator: Get; + + /// A configuration for base priority of unsigned transactions. + /// + /// This is exposed so that it can be tuned for particular runtime, when + /// multiple pallets send unsigned transactions. + type UnsignedPriority: Get; } /// Mode of era-forcing. @@ -3224,24 +3230,24 @@ impl frame_support::unsigned::ValidateUnsigned for Module { era, ); - Ok(ValidTransaction { + ValidTransaction::with_tag_prefix("StakingOffchain") // The higher the score[0], the better a solution is. - priority: score[0].saturated_into(), - // no requires. - requires: vec![], + .priority(T::UnsignedPriority::get().saturating_add(score[0].saturated_into())) // Defensive only. A single solution can exist in the pool per era. Each validator // will run OCW at most once per era, hence there should never exist more than one // transaction anyhow. - provides: vec![("StakingOffchain", era).encode()], + .and_provides(era) // Note: this can be more accurate in the future. We do something like // `era_end_block - current_block` but that is not needed now as we eagerly run // offchain workers now and the above should be same as `T::ElectionLookahead` // without the need to query more storage in the validation phase. If we randomize // offchain worker, then we might re-consider this. - longevity: TryInto::::try_into(T::ElectionLookahead::get()).unwrap_or(DEFAULT_LONGEVITY), + .longevity(TryInto::::try_into( + T::ElectionLookahead::get()).unwrap_or(DEFAULT_LONGEVITY) + ) // We don't propagate this. This can never the validated at a remote node. - propagate: false, - }) + .propagate(false) + .build() } else { InvalidTransaction::Call.into() } diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index f812341653..6332486b65 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -272,6 +272,7 @@ parameter_types! { pub const BondingDuration: EraIndex = 3; pub const RewardCurve: &'static PiecewiseLinear<'static> = &I_NPOS; pub const MaxNominatorRewardedPerValidator: u32 = 64; + pub const UnsignedPriority: u64 = 1 << 20; } impl Trait for Test { @@ -293,6 +294,7 @@ impl Trait for Test { type Call = Call; type SubmitTransaction = SubmitTransaction; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; + type UnsignedPriority = UnsignedPriority; } pub type Extrinsic = TestXt; diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 9aaee23bc8..321fcb34ef 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -3165,7 +3165,7 @@ mod offchain_phragmen { &inner, ), TransactionValidity::Ok(ValidTransaction { - priority: 1125, // the proposed slot stake. + priority: (1 << 20) + 1125, // the proposed slot stake. requires: vec![], provides: vec![("StakingOffchain", active_era()).encode()], longevity: 3, diff --git a/primitives/runtime/src/transaction_validity.rs b/primitives/runtime/src/transaction_validity.rs index 94cf44384d..95903b4876 100644 --- a/primitives/runtime/src/transaction_validity.rs +++ b/primitives/runtime/src/transaction_validity.rs @@ -264,6 +264,17 @@ impl Default for ValidTransaction { } impl ValidTransaction { + /// Initiate `ValidTransaction` builder object with a particular prefix for tags. + /// + /// To avoid conflicts between different parts in runtime it's recommended to build `requires` + /// and `provides` tags with a unique prefix. + pub fn with_tag_prefix(prefix: &'static str) -> ValidTransactionBuilder { + ValidTransactionBuilder { + prefix: Some(prefix), + validity: Default::default(), + } + } + /// Combine two instances into one, as a best effort. This will take the superset of each of the /// `provides` and `requires` tags, it will sum the priorities, take the minimum longevity and /// the logic *And* of the propagate flags. @@ -278,6 +289,104 @@ impl ValidTransaction { } } +/// `ValidTransaction` builder. +/// +/// +/// Allows to easily construct `ValidTransaction` and most importantly takes care of +/// prefixing `requires` and `provides` tags to avoid conflicts. +#[derive(Default, Clone, RuntimeDebug)] +pub struct ValidTransactionBuilder { + prefix: Option<&'static str>, + validity: ValidTransaction, +} + +impl ValidTransactionBuilder { + /// Set the priority of a transaction. + /// + /// Note that the final priority for `FRAME` is combined from all `SignedExtension`s. + /// Most likely for unsigned transactions you want the priority to be higher + /// than for regular transactions. We recommend exposing a base priority for unsigned + /// transactions as a runtime module parameter, so that the runtime can tune inter-module + /// priorities. + pub fn priority(mut self, priority: TransactionPriority) -> Self { + self.validity.priority = priority; + self + } + + /// Set the longevity of a transaction. + /// + /// By default the transaction will be considered valid forever and will not be revalidated + /// by the transaction pool. It's recommended though to set the longevity to a finite value + /// though. If unsure, it's also reasonable to expose this parameter via module configuration + /// and let the runtime decide. + pub fn longevity(mut self, longevity: TransactionLongevity) -> Self { + self.validity.longevity = longevity; + self + } + + /// Set the propagate flag. + /// + /// Set to `false` if the transaction is not meant to be gossiped to peers. Combined with + /// `TransactionSource::Local` validation it can be used to have special kind of + /// transactions that are only produced and included by the validator nodes. + pub fn propagate(mut self, propagate: bool) -> Self { + self.validity.propagate = propagate; + self + } + + /// Add a `TransactionTag` to the set of required tags. + /// + /// The tag will be encoded and prefixed with module prefix (if any). + /// If you'd rather add a raw `require` tag, consider using `#combine_with` method. + pub fn and_requires(mut self, tag: impl Encode) -> Self { + self.validity.requires.push(match self.prefix.as_ref() { + Some(prefix) => (prefix, tag).encode(), + None => tag.encode(), + }); + self + } + + /// Add a `TransactionTag` to the set of provided tags. + /// + /// The tag will be encoded and prefixed with module prefix (if any). + /// If you'd rather add a raw `require` tag, consider using `#combine_with` method. + pub fn and_provides(mut self, tag: impl Encode) -> Self { + self.validity.provides.push(match self.prefix.as_ref() { + Some(prefix) => (prefix, tag).encode(), + None => tag.encode(), + }); + self + } + + /// Augment the builder with existing `ValidTransaction`. + /// + /// This method does add the prefix to `require` or `provides` tags. + pub fn combine_with(mut self, validity: ValidTransaction) -> Self { + self.validity = core::mem::take(&mut self.validity).combine_with(validity); + self + } + + /// Finalize the builder and produce `TransactionValidity`. + /// + /// Note the result will always be `Ok`. Use `Into` to produce `ValidTransaction`. + pub fn build(self) -> TransactionValidity { + self.into() + } +} + +impl From for TransactionValidity { + fn from(builder: ValidTransactionBuilder) -> Self { + Ok(builder.into()) + } +} + +impl From for ValidTransaction { + fn from(builder: ValidTransactionBuilder) -> Self { + builder.validity + } +} + + #[cfg(test)] mod tests { use super::*; @@ -301,4 +410,26 @@ mod tests { // decode back assert_eq!(TransactionValidity::decode(&mut &*encoded), Ok(v)); } + + #[test] + fn builder_should_prefix_the_tags() { + const PREFIX: &str = "test"; + let a: ValidTransaction = ValidTransaction::with_tag_prefix(PREFIX) + .and_requires(1) + .and_requires(2) + .and_provides(3) + .and_provides(4) + .propagate(false) + .longevity(5) + .priority(3) + .priority(6) + .into(); + assert_eq!(a, ValidTransaction { + propagate: false, + longevity: 5, + priority: 6, + requires: vec![(PREFIX, 1).encode(), (PREFIX, 2).encode()], + provides: vec![(PREFIX, 3).encode(), (PREFIX, 4).encode()], + }); + } } -- GitLab From f08bd50bb3ad9473784532daf8a2a77c1fb1a5bb Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Wed, 8 Apr 2020 02:49:32 -0700 Subject: [PATCH 186/300] remove flakiness (#5572) --- Cargo.lock | 4 ++-- client/transaction-pool/Cargo.toml | 2 +- client/transaction-pool/src/revalidation.rs | 13 +++++++++++-- client/transaction-pool/src/testing/pool.rs | 15 +++++++-------- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de2b174826..3eaf51f752 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2300,9 +2300,9 @@ checksum = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" [[package]] name = "intervalier" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14200459dc2319eb13708aed1c1efb8307e0e0e801e7282476939492e1492631" +checksum = "64fa110ec7b8f493f416eed552740d10e7030ad5f63b2308f82c9608ec2df275" dependencies = [ "futures 0.3.4", "futures-timer 2.0.2", diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 29b8069842..aeb20e9863 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -24,7 +24,7 @@ sc-transaction-graph = { version = "2.0.0-alpha.5", path = "./graph" } sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } -intervalier = "0.3.1" +intervalier = "0.4.0" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] diff --git a/client/transaction-pool/src/revalidation.rs b/client/transaction-pool/src/revalidation.rs index 9bcb2dac39..f203bf08a0 100644 --- a/client/transaction-pool/src/revalidation.rs +++ b/client/transaction-pool/src/revalidation.rs @@ -30,7 +30,7 @@ use std::time::Duration; #[cfg(not(test))] const BACKGROUND_REVALIDATION_INTERVAL: Duration = Duration::from_millis(200); #[cfg(test)] -pub const BACKGROUND_REVALIDATION_INTERVAL: Duration = Duration::from_millis(5); +pub const BACKGROUND_REVALIDATION_INTERVAL: Duration = Duration::from_millis(1); const BACKGROUND_REVALIDATION_BATCH_SIZE: usize = 20; @@ -214,12 +214,21 @@ impl RevalidationWorker { loop { futures::select! { - _ = interval.next() => { + _guard = interval.next() => { let next_batch = this.prepare_batch(); let batch_len = next_batch.len(); batch_revalidate(this.pool.clone(), this.api.clone(), this.best_block, next_batch).await; + #[cfg(test)] + { + use intervalier::Guard; + // only trigger test events if something was processed + if batch_len == 0 { + _guard.expect("Always some() in tests").skip(); + } + } + if batch_len > 0 || this.len() > 0 { log::debug!( target: "txpool", diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index c6c54d9720..e7021e8ea0 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -221,7 +221,7 @@ fn should_revalidate_during_maintenance() { block_on(pool.maintain(block_event(1))); assert_eq!(pool.status().ready, 1); - block_on(notifier.next_blocking()); + block_on(notifier.next()); // test that pool revalidated transaction that left ready and not included in the block assert_eq!(pool.api.validation_requests().len(), 3); @@ -264,8 +264,8 @@ fn should_not_retain_invalid_hashes_from_retracted() { block_on(pool.maintain(event)); // maintenance is in background - block_on(notifier.next_blocking()); - + block_on(notifier.next()); + assert_eq!(pool.status().ready, 0); } @@ -281,7 +281,6 @@ fn should_revalidate_transaction_multiple_times() { pool.api.push_block(1, vec![xt.clone()]); block_on(pool.maintain(block_event(1))); - block_on(notifier.next_blocking()); block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); @@ -290,7 +289,7 @@ fn should_revalidate_transaction_multiple_times() { pool.api.add_invalid(&xt); block_on(pool.maintain(block_event(2))); - block_on(notifier.next_blocking()); + block_on(notifier.next()); assert_eq!(pool.status().ready, 0); } @@ -309,14 +308,14 @@ fn should_revalidate_across_many_blocks() { pool.api.push_block(1, vec![]); block_on(pool.maintain(block_event(1))); - block_on(notifier.next_blocking()); + block_on(notifier.next()); block_on(pool.submit_one(&BlockId::number(2), SOURCE, xt3.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 3); pool.api.push_block(2, vec![xt1.clone()]); block_on(pool.maintain(block_event(2))); - block_on(notifier.next_blocking()); + block_on(notifier.next()); assert_eq!(pool.status().ready, 2); // xt1 and xt2 validated twice, then xt3 once, then xt2 and xt3 again @@ -361,7 +360,7 @@ fn should_push_watchers_during_maintaince() { // clear timer events if any block_on(pool.maintain(block_event(0))); - block_on(notifier.next_blocking()); + block_on(notifier.next()); // then // hash3 is now invalid -- GitLab From 06fbebf2cca9c5e91c1c9809f917c195b70e8a3c Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Wed, 8 Apr 2020 12:55:06 +0200 Subject: [PATCH 187/300] Add verify block to benchmark tests (#5551) * Add verify block to benchmarks macro. * Update all benchmarks. * Add tests, add params. * Should panic. * ups, add closures * Update tests.rs * update macro syntax * Revert benchmark syntax change * verify only in tests * Update tests.rs * Uncomment staking * Fix tests for benchmark instance * Add docs * Update frame/benchmarking/src/lib.rs * add trace logs to benchmarks * Verify returns closure Co-authored-by: Shawn Tabrizi --- frame/balances/src/benchmarking.rs | 7 +- frame/benchmarking/src/lib.rs | 255 +++++++++++++++++++++++---- frame/benchmarking/src/tests.rs | 63 +++++-- frame/benchmarking/src/utils.rs | 10 +- frame/collective/src/benchmarking.rs | 33 +++- frame/collective/src/lib.rs | 30 ++-- 6 files changed, 330 insertions(+), 68 deletions(-) diff --git a/frame/balances/src/benchmarking.rs b/frame/balances/src/benchmarking.rs index a6206cd84f..3c2067559f 100644 --- a/frame/balances/src/benchmarking.rs +++ b/frame/balances/src/benchmarking.rs @@ -51,10 +51,13 @@ benchmarks! { let _ = as Currency<_>>::make_free_balance_be(&caller, balance); // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, and reap this user. - let recipient = account("recipient", u, SEED); - let recipient_lookup: ::Source = T::Lookup::unlookup(recipient); + let recipient: T::AccountId = account("recipient", u, SEED); + let recipient_lookup: ::Source = T::Lookup::unlookup(recipient.clone()); let transfer_amount = existential_deposit.saturating_mul((e - 1).into()) + 1.into(); }: _(RawOrigin::Signed(caller), recipient_lookup, transfer_amount) + verify { + assert_eq!(Balances::::free_balance(&recipient), transfer_amount); + } // Benchmark `transfer` with the best possible condition: // * Both accounts exist and will continue to exist. diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index 49f398d59d..6bb10f3d97 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -28,7 +28,7 @@ pub use utils::*; pub use analysis::Analysis; #[doc(hidden)] pub use sp_io::storage::root as storage_root; -pub use sp_runtime::traits::Dispatchable; +pub use sp_runtime::traits::{Dispatchable, Zero}; pub use paste; /// Construct pallet benchmarks for weighing dispatchables. @@ -132,6 +132,25 @@ pub use paste; /// benchmark just like a regular benchmark, but only testing at the lowest and highest values for /// each component. The function will return `Ok(())` if the benchmarks return no errors. /// +/// You can optionally add a `verify` code block at the end of a benchmark to test any final state +/// of your benchmark in a unit test. For example: +/// +/// ```ignore +/// sort_vector { +/// let x in 1 .. 10000; +/// let mut m = Vec::::new(); +/// for i in (0..x).rev() { +/// m.push(i); +/// } +/// }: { +/// m.sort(); +/// } verify { +/// ensure!(m[0] == 0, "You forgot to sort!") +/// } +/// ``` +/// +/// These `verify` blocks will not execute when running your actual benchmarks! +/// /// You can construct benchmark tests like so: /// /// ```ignore @@ -192,6 +211,7 @@ macro_rules! benchmarks_iter { { $( $common:tt )* } ( $( $names:ident )* ) $name:ident { $( $code:tt )* }: _ ( $origin:expr $( , $arg:expr )* ) + verify $postcode:block $( $rest:tt )* ) => { $crate::benchmarks_iter! { @@ -199,6 +219,7 @@ macro_rules! benchmarks_iter { { $( $common )* } ( $( $names )* ) $name { $( $code )* }: $name ( $origin $( , $arg )* ) + verify $postcode $( $rest )* } }; @@ -208,6 +229,7 @@ macro_rules! benchmarks_iter { { $( $common:tt )* } ( $( $names:ident )* ) $name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* ) + verify $postcode:block $( $rest:tt )* ) => { $crate::benchmarks_iter! { @@ -217,6 +239,7 @@ macro_rules! benchmarks_iter { $name { $( $code )* }: { as $crate::Dispatchable>::dispatch(Call::::$dispatch($($arg),*), $origin.into())?; } + verify $postcode $( $rest )* } }; @@ -226,6 +249,7 @@ macro_rules! benchmarks_iter { { $( $common:tt )* } ( $( $names:ident )* ) $name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* ) + verify $postcode:block $( $rest:tt )* ) => { $crate::benchmarks_iter! { @@ -235,6 +259,7 @@ macro_rules! benchmarks_iter { $name { $( $code )* }: { as $crate::Dispatchable>::dispatch(Call::::$dispatch($($arg),*), $origin.into())?; } + verify $postcode $( $rest )* } }; @@ -244,6 +269,7 @@ macro_rules! benchmarks_iter { { $( $common:tt )* } ( $( $names:ident )* ) $name:ident { $( $code:tt )* }: $eval:block + verify $postcode:block $( $rest:tt )* ) => { $crate::benchmark_backend! { @@ -253,6 +279,7 @@ macro_rules! benchmarks_iter { { } { $eval } { $( $code )* } + $postcode } $crate::benchmarks_iter!( $instance @@ -266,8 +293,59 @@ macro_rules! benchmarks_iter { $crate::selected_benchmark!( $instance $( $names ),* ); $crate::impl_benchmark!( $instance $( $names ),* ); #[cfg(test)] - $crate::impl_benchmark_tests!( $( $names ),* ); - } + $crate::impl_benchmark_tests!( $instance $( $names ),* ); + }; + // add verify block to _() format + ( + $instance:ident + { $( $common:tt )* } + ( $( $names:ident )* ) + $name:ident { $( $code:tt )* }: _ ( $origin:expr $( , $arg:expr )* ) + $( $rest:tt )* + ) => { + $crate::benchmarks_iter! { + $instance + { $( $common )* } + ( $( $names )* ) + $name { $( $code )* }: _ ( $origin $( , $arg )* ) + verify { } + $( $rest )* + } + }; + // add verify block to name() format + ( + $instance:ident + { $( $common:tt )* } + ( $( $names:ident )* ) + $name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* ) + $( $rest:tt )* + ) => { + $crate::benchmarks_iter! { + $instance + { $( $common )* } + ( $( $names )* ) + $name { $( $code )* }: $dispatch ( $origin $( , $arg )* ) + verify { } + $( $rest )* + } + }; + // add verify block to {} format + ( + $instance:ident + { $( $common:tt )* } + ( $( $names:ident )* ) + $name:ident { $( $code:tt )* }: $eval:block + $( $rest:tt )* + ) => { + $crate::benchmarks_iter!( + $instance + { $( $common )* } + ( $( $names )* ) + $name { $( $code )* }: $eval + verify { } + $( $rest )* + ); + }; } #[macro_export] @@ -281,12 +359,12 @@ macro_rules! benchmark_backend { } { $eval:block } { let $pre_id:tt : $pre_ty:ty = $pre_ex:expr; $( $rest:tt )* - } ) => { + } $postcode:block) => { $crate::benchmark_backend! { $instance $name { $( $common )* } { $( PRE { $( $pre_parsed )* } )* PRE { $pre_id , $pre_ty , $pre_ex } - } { $eval } { $( $rest )* } + } { $eval } { $( $rest )* } $postcode } }; ($instance:ident $name:ident { @@ -296,12 +374,12 @@ macro_rules! benchmark_backend { } { $eval:block } { let $param:ident in ( $param_from:expr ) .. $param_to:expr => $param_instancer:expr; $( $rest:tt )* - }) => { + } $postcode:block) => { $crate::benchmark_backend! { $instance $name { $( $common )* } { $( $parsed )* PARAM { $param , $param_from , $param_to , $param_instancer } - } { $eval } { $( $rest )* } + } { $eval } { $( $rest )* } $postcode } }; // mutation arm to look after defaulting to a common param @@ -312,7 +390,7 @@ macro_rules! benchmark_backend { } { $eval:block } { let $param:ident in ...; $( $rest:tt )* - }) => { + } $postcode:block) => { $crate::benchmark_backend! { $instance $name { $( { $common , $common_from , $common_to , $common_instancer } )* @@ -324,7 +402,7 @@ macro_rules! benchmark_backend { .. ({ $( let $common = $common_to; )* $param }) => ({ $( let $common = || -> Result<(), &'static str> { $common_instancer ; Ok(()) }; )* $param()? }); $( $rest )* - } + } $postcode } }; // mutation arm to look after defaulting only the range to common param @@ -335,7 +413,7 @@ macro_rules! benchmark_backend { } { $eval:block } { let $param:ident in _ .. _ => $param_instancer:expr ; $( $rest:tt )* - }) => { + } $postcode:block) => { $crate::benchmark_backend! { $instance $name { $( { $common , $common_from , $common_to , $common_instancer } )* @@ -347,7 +425,7 @@ macro_rules! benchmark_backend { .. ({ $( let $common = $common_to; )* $param }) => $param_instancer ; $( $rest )* - } + } $postcode } }; // mutation arm to look after a single tt for param_from. @@ -358,12 +436,12 @@ macro_rules! benchmark_backend { } { $eval:block } { let $param:ident in $param_from:tt .. $param_to:expr => $param_instancer:expr ; $( $rest:tt )* - }) => { + } $postcode:block) => { $crate::benchmark_backend! { $instance $name { $( $common )* } { $( $parsed )* } { $eval } { let $param in ( $param_from ) .. $param_to => $param_instancer; $( $rest )* - } + } $postcode } }; // mutation arm to look after the default tail of `=> ()` @@ -374,12 +452,12 @@ macro_rules! benchmark_backend { } { $eval:block } { let $param:ident in $param_from:tt .. $param_to:expr; $( $rest:tt )* - }) => { + } $postcode:block) => { $crate::benchmark_backend! { $instance $name { $( $common )* } { $( $parsed )* } { $eval } { let $param in $param_from .. $param_to => (); $( $rest )* - } + } $postcode } }; // mutation arm to look after `let _ =` @@ -390,12 +468,12 @@ macro_rules! benchmark_backend { } { $eval:block } { let $pre_id:tt = $pre_ex:expr; $( $rest:tt )* - }) => { + } $postcode:block) => { $crate::benchmark_backend! { $instance $name { $( $common )* } { $( $parsed )* } { $eval } { let $pre_id : _ = $pre_ex; $( $rest )* - } + } $postcode } }; // no instance actioning arm @@ -404,7 +482,7 @@ macro_rules! benchmark_backend { } { $( PRE { $pre_id:tt , $pre_ty:ty , $pre_ex:expr } )* $( PARAM { $param:ident , $param_from:expr , $param_to:expr , $param_instancer:expr } )* - } { $eval:block } { $( $post:tt )* } ) => { + } { $eval:block } { $( $post:tt )* } $postcode:block) => { #[allow(non_camel_case_types)] struct $name; #[allow(unused_variables)] @@ -435,6 +513,25 @@ macro_rules! benchmark_backend { Ok(Box::new(move || -> Result<(), &'static str> { $eval; Ok(()) })) } + + fn verify(&self, components: &[($crate::BenchmarkParameter, u32)]) + -> Result Result<(), &'static str>>, &'static str> + { + $( + let $common = $common_from; + )* + $( + // Prepare instance + let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1; + )* + $( + let $pre_id : $pre_ty = $pre_ex; + )* + $( $param_instancer ; )* + $( $post )* + + Ok(Box::new(move || -> Result<(), &'static str> { $eval; $postcode; Ok(()) })) + } } }; // instance actioning arm @@ -443,7 +540,7 @@ macro_rules! benchmark_backend { } { $( PRE { $pre_id:tt , $pre_ty:ty , $pre_ex:expr } )* $( PARAM { $param:ident , $param_from:expr , $param_to:expr , $param_instancer:expr } )* - } { $eval:block } { $( $post:tt )* } ) => { + } { $eval:block } { $( $post:tt )* } $postcode:block) => { #[allow(non_camel_case_types)] struct $name; #[allow(unused_variables)] @@ -474,6 +571,25 @@ macro_rules! benchmark_backend { Ok(Box::new(move || -> Result<(), &'static str> { $eval; Ok(()) })) } + + fn verify(&self, components: &[($crate::BenchmarkParameter, u32)]) + -> Result Result<(), &'static str>>, &'static str> + { + $( + let $common = $common_from; + )* + $( + // Prepare instance + let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1; + )* + $( + let $pre_id : $pre_ty = $pre_ex; + )* + $( $param_instancer ; )* + $( $post )* + + Ok(Box::new(move || -> Result<(), &'static str> { $eval; $postcode; Ok(()) })) + } } } } @@ -518,6 +634,14 @@ macro_rules! selected_benchmark { $( Self::$bench => <$bench as $crate::BenchmarkingSetup>::instance(&$bench, components), )* } } + + fn verify(&self, components: &[($crate::BenchmarkParameter, u32)]) + -> Result Result<(), &'static str>>, &'static str> + { + match self { + $( Self::$bench => <$bench as $crate::BenchmarkingSetup>::verify(&$bench, components), )* + } + } } }; ( @@ -544,6 +668,14 @@ macro_rules! selected_benchmark { $( Self::$bench => <$bench as $crate::BenchmarkingSetupInstance>::instance(&$bench, components), )* } } + + fn verify(&self, components: &[($crate::BenchmarkParameter, u32)]) + -> Result Result<(), &'static str>>, &'static str> + { + match self { + $( Self::$bench => <$bench as $crate::BenchmarkingSetupInstance>::verify(&$bench, components), )* + } + } } } } @@ -618,20 +750,25 @@ macro_rules! impl_benchmark { // Run the benchmark `repeat` times. for _ in 0..repeat { - // Set the block number to 1 so events are deposited. - frame_system::Module::::set_block_number(1.into()); // Set up the externalities environment for the setup we want to benchmark. let closure_to_benchmark = >::instance(&selected_benchmark, &c)?; + // Set the block number to at least 1 so events are deposited. + if $crate::Zero::is_zero(&frame_system::Module::::block_number()) { + frame_system::Module::::set_block_number(1.into()); + } + // Commit the externalities to the database, flushing the DB cache. // This will enable worst case scenario for reading from the database. $crate::benchmarking::commit_db(); // Time the extrinsic logic. + frame_support::debug::trace!(target: "benchmark", "Start Benchmark: {:?} {:?}", name, component_value); let start_extrinsic = $crate::benchmarking::current_time(); closure_to_benchmark()?; let finish_extrinsic = $crate::benchmarking::current_time(); let elapsed_extrinsic = finish_extrinsic - start_extrinsic; + frame_support::debug::trace!(target: "benchmark", "End Benchmark: {} ns", elapsed_extrinsic); // Time the storage root recalculation. let start_storage_root = $crate::benchmarking::current_time(); @@ -718,20 +855,25 @@ macro_rules! impl_benchmark { // Run the benchmark `repeat` times. for _ in 0..repeat { - // Set the block number to 1 so events are deposited. - frame_system::Module::::set_block_number(1.into()); // Set up the externalities environment for the setup we want to benchmark. let closure_to_benchmark = >::instance(&selected_benchmark, &c)?; + // Set the block number to at least 1 so events are deposited. + if $crate::Zero::is_zero(&frame_system::Module::::block_number()) { + frame_system::Module::::set_block_number(1.into()); + } + // Commit the externalities to the database, flushing the DB cache. // This will enable worst case scenario for reading from the database. $crate::benchmarking::commit_db(); // Time the extrinsic logic. + frame_support::debug::trace!(target: "benchmark", "Start Benchmark: {:?} {:?}", name, component_value); let start_extrinsic = $crate::benchmarking::current_time(); closure_to_benchmark()?; let finish_extrinsic = $crate::benchmarking::current_time(); let elapsed_extrinsic = finish_extrinsic - start_extrinsic; + frame_support::debug::trace!(target: "benchmark", "End Benchmark: {} ns", elapsed_extrinsic); // Time the storage root recalculation. let start_storage_root = $crate::benchmarking::current_time(); @@ -758,6 +900,7 @@ macro_rules! impl_benchmark { #[macro_export] macro_rules! impl_benchmark_tests { ( + NO_INSTANCE $( $name:ident ),* ) => { $( @@ -783,12 +926,17 @@ macro_rules! impl_benchmark_tests { ) .collect(); - // Set the block number to 1 so events are deposited. - frame_system::Module::::set_block_number(1.into()); - // Set up the externalities environment for the setup we want to benchmark. - let closure_to_benchmark = >::instance(&selected_benchmark, &c)?; - // Run the benchmark - closure_to_benchmark()?; + // Set up the verification state + let closure_to_verify = >::verify(&selected_benchmark, &c)?; + + // Set the block number to at least 1 so events are deposited. + if $crate::Zero::is_zero(&frame_system::Module::::block_number()) { + frame_system::Module::::set_block_number(1.into()); + } + + // Run verification + closure_to_verify()?; + // Reset the state $crate::benchmarking::wipe_db(); } @@ -797,7 +945,54 @@ macro_rules! impl_benchmark_tests { } } )* - } + }; + ( + INSTANCE + $( $name:ident ),* + ) => { + $( + $crate::paste::item! { + fn [] () -> Result<(), &'static str> + where T: frame_system::Trait + { + let selected_benchmark = SelectedBenchmark::$name; + let components = >::components(&selected_benchmark); + + for (_, (name, low, high)) in components.iter().enumerate() { + // Test only the low and high value, assuming values in the middle won't break + for component_value in vec![low, high] { + // Select the max value for all the other components. + let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter() + .enumerate() + .map(|(_, (n, _, h))| + if n == name { + (*n, *component_value) + } else { + (*n, *h) + } + ) + .collect(); + + // Set up the verification state + let closure_to_verify = >::verify(&selected_benchmark, &c)?; + + // Set the block number to at least 1 so events are deposited. + if $crate::Zero::is_zero(&frame_system::Module::::block_number()) { + frame_system::Module::::set_block_number(1.into()); + } + + // Run verification + closure_to_verify()?; + + // Reset the state + $crate::benchmarking::wipe_db(); + } + } + Ok(()) + } + } + )* + }; } diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index 3e79ca3875..50a39d0fcf 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -23,20 +23,28 @@ use codec::Decode; use sp_std::prelude::*; use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::{H256, Header}}; use frame_support::{ - dispatch::DispatchResult, decl_module, impl_outer_origin, assert_ok, assert_err, ensure + dispatch::DispatchResult, decl_module, decl_storage, impl_outer_origin, + assert_ok, assert_err, ensure }; use frame_system::{RawOrigin, ensure_signed, ensure_none}; +decl_storage! { + trait Store for Module as Test { + Value get(fn value): Option; + } +} + decl_module! { pub struct Module for enum Call where origin: T::Origin { #[weight = frame_support::weights::SimpleDispatchInfo::default()] - fn dummy(origin, _n: u32) -> DispatchResult { + fn set_value(origin, n: u32) -> DispatchResult { let _sender = ensure_signed(origin)?; + Value::put(n); Ok(()) } #[weight = frame_support::weights::SimpleDispatchInfo::default()] - fn other_dummy(origin, _n: u32) -> DispatchResult { + fn dummy(origin, _n: u32) -> DispatchResult { let _sender = ensure_none(origin)?; Ok(()) } @@ -98,15 +106,17 @@ benchmarks!{ let b in 1 .. 1000 => (); } - dummy { + set_value { let b in ...; - let caller = account("caller", 0, 0); + let caller = account::("caller", 0, 0); }: _ (RawOrigin::Signed(caller), b.into()) + verify { + assert_eq!(Value::get(), Some(b)); + } other_name { let b in ...; - let caller = account("caller", 0, 0); - }: other_dummy (RawOrigin::Signed(caller), b.into()) + }: dummy (RawOrigin::None, b.into()) sort_vector { let x in 1 .. 10000; @@ -116,24 +126,31 @@ benchmarks!{ } }: { m.sort(); + } verify { ensure!(m[0] == 0, "You forgot to sort!") } - broken_benchmark { + bad_origin { + let b in ...; + let caller = account::("caller", 0, 0); + }: dummy (RawOrigin::Signed(caller), b.into()) + + bad_verify { let x in 1 .. 10000; let mut m = Vec::::new(); for i in (0..x).rev() { m.push(i); } - }: { + }: { } + verify { ensure!(m[0] == 0, "You forgot to sort!") } } #[test] fn benchmarks_macro_works() { - // Check benchmark creation for `dummy`. - let selected_benchmark = SelectedBenchmark::dummy; + // Check benchmark creation for `set_value`. + let selected_benchmark = SelectedBenchmark::set_value; let components = >::components(&selected_benchmark); assert_eq!(components, vec![(BenchmarkParameter::b, 1, 1000)]); @@ -161,7 +178,7 @@ fn benchmarks_macro_rename_works() { ).expect("failed to create closure"); new_test_ext().execute_with(|| { - assert_eq!(closure(), Err("Bad origin")); + assert_ok!(closure()); }); } @@ -180,12 +197,28 @@ fn benchmarks_macro_works_for_non_dispatchable() { assert_eq!(closure(), Ok(())); } +#[test] +fn benchmarks_macro_verify_works() { + // Check postcondition for benchmark `set_value` is valid. + let selected_benchmark = SelectedBenchmark::set_value; + + let closure = >::verify( + &selected_benchmark, + &[(BenchmarkParameter::b, 1)], + ).expect("failed to create closure"); + + new_test_ext().execute_with(|| { + assert_ok!(closure()); + }); +} + #[test] fn benchmarks_generate_unit_tests() { new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_dummy::()); - assert_err!(test_benchmark_other_name::(), "Bad origin"); + assert_ok!(test_benchmark_set_value::()); + assert_ok!(test_benchmark_other_name::()); assert_ok!(test_benchmark_sort_vector::()); - assert_err!(test_benchmark_broken_benchmark::(), "You forgot to sort!"); + assert_err!(test_benchmark_bad_origin::(), "Bad origin"); + assert_err!(test_benchmark_bad_verify::(), "You forgot to sort!"); }); } diff --git a/frame/benchmarking/src/utils.rs b/frame/benchmarking/src/utils.rs index a6f262eab9..41b968fbfc 100644 --- a/frame/benchmarking/src/utils.rs +++ b/frame/benchmarking/src/utils.rs @@ -113,8 +113,11 @@ pub trait BenchmarkingSetup { /// Return the components and their ranges which should be tested in this benchmark. fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)>; - /// Set up the storage, and prepare a closure to test in a single run of the benchmark. + /// Set up the storage, and prepare a closure to run the benchmark. fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result Result<(), &'static str>>, &'static str>; + + /// Set up the storage, and prepare a closure to test and verify the benchmark + fn verify(&self, components: &[(BenchmarkParameter, u32)]) -> Result Result<(), &'static str>>, &'static str>; } /// The required setup for creating a benchmark. @@ -122,8 +125,11 @@ pub trait BenchmarkingSetupInstance { /// Return the components and their ranges which should be tested in this benchmark. fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)>; - /// Set up the storage, and prepare a closure to test in a single run of the benchmark. + /// Set up the storage, and prepare a closure to run the benchmark. fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result Result<(), &'static str>>, &'static str>; + + /// Set up the storage, and prepare a closure to test and verify the benchmark + fn verify(&self, components: &[(BenchmarkParameter, u32)]) -> Result Result<(), &'static str>>, &'static str>; } /// Grab an account, seeded by a name and index. diff --git a/frame/collective/src/benchmarking.rs b/frame/collective/src/benchmarking.rs index 51db4ee109..edef5e2e24 100644 --- a/frame/collective/src/benchmarking.rs +++ b/frame/collective/src/benchmarking.rs @@ -50,7 +50,7 @@ benchmarks_instance! { new_members.push(member); } - // Set old members. + // Set old members. // We compute the difference of old and new members, so it should influence timing. let mut old_members = vec![]; for i in 0 .. n { @@ -62,7 +62,11 @@ benchmarks_instance! { Collective::::set_members(SystemOrigin::Root.into(), old_members, prime.clone())?; - }: _(SystemOrigin::Root, new_members, prime) + }: _(SystemOrigin::Root, new_members.clone(), prime) + verify { + new_members.sort(); + assert_eq!(Collective::::members(), new_members); + } execute { let u in ...; @@ -148,7 +152,7 @@ benchmarks_instance! { let caller1: T::AccountId = account("caller1", u, SEED); let caller2: T::AccountId = account("caller2", u, SEED); - + let proposal: Box = Box::new(Call::::close(Default::default(), Default::default()).into()); let proposal_hash = T::Hashing::hash_of(&proposal); @@ -167,7 +171,7 @@ benchmarks_instance! { let caller1: T::AccountId = account("caller1", u, SEED); let caller2: T::AccountId = account("caller2", u, SEED); - + let proposal: Box = Box::new(Call::::close(Default::default(), Default::default()).into()); let proposal_hash = T::Hashing::hash_of(&proposal); @@ -183,3 +187,24 @@ benchmarks_instance! { }: _(SystemOrigin::Signed(caller2), proposal_hash, index) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{new_test_ext, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_set_members::()); + assert_ok!(test_benchmark_execute::()); + assert_ok!(test_benchmark_propose::()); + assert_ok!(test_benchmark_propose_else_branch::()); + assert_ok!(test_benchmark_vote::()); + assert_ok!(test_benchmark_vote_not_approve::()); + assert_ok!(test_benchmark_vote_approved::()); + assert_ok!(test_benchmark_close::()); + }); + } +} diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 49c1bd3891..53e9853221 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -589,7 +589,7 @@ mod tests { } ); - fn make_ext() -> sp_io::TestExternalities { + pub fn new_test_ext() -> sp_io::TestExternalities { let mut ext: sp_io::TestExternalities = GenesisConfig { collective_Instance1: Some(collective::GenesisConfig { members: vec![1, 2, 3], @@ -603,7 +603,7 @@ mod tests { #[test] fn motions_basic_environment_works() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { assert_eq!(Collective::members(), vec![1, 2, 3]); assert_eq!(Collective::proposals(), Vec::::new()); }); @@ -615,7 +615,7 @@ mod tests { #[test] fn close_works() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); @@ -643,7 +643,7 @@ mod tests { #[test] fn close_with_prime_works() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(Collective::set_members(Origin::ROOT, vec![1, 2, 3], Some(3))); @@ -666,7 +666,7 @@ mod tests { #[test] fn close_with_voting_prime_works() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(Collective::set_members(Origin::ROOT, vec![1, 2, 3], Some(1))); @@ -690,7 +690,7 @@ mod tests { #[test] fn removal_of_old_voters_votes_works() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); let end = 4; @@ -724,7 +724,7 @@ mod tests { #[test] fn removal_of_old_voters_votes_works_with_set_members() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); let end = 4; @@ -758,7 +758,7 @@ mod tests { #[test] fn propose_works() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { let proposal = make_proposal(42); let hash = proposal.blake2_256().into(); let end = 4; @@ -787,7 +787,7 @@ mod tests { #[test] fn motions_ignoring_non_collective_proposals_works() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { let proposal = make_proposal(42); assert_noop!( Collective::propose(Origin::signed(42), 3, Box::new(proposal.clone())), @@ -798,7 +798,7 @@ mod tests { #[test] fn motions_ignoring_non_collective_votes_works() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); @@ -811,7 +811,7 @@ mod tests { #[test] fn motions_ignoring_bad_index_collective_vote_works() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { System::set_block_number(3); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); @@ -825,7 +825,7 @@ mod tests { #[test] fn motions_revoting_works() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); let end = 4; @@ -876,7 +876,7 @@ mod tests { #[test] fn motions_reproposing_disapproved_works() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); @@ -889,7 +889,7 @@ mod tests { #[test] fn motions_disapproval_works() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); @@ -931,7 +931,7 @@ mod tests { #[test] fn motions_approval_works() { - make_ext().execute_with(|| { + new_test_ext().execute_with(|| { let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); assert_ok!(Collective::propose(Origin::signed(1), 2, Box::new(proposal.clone()))); -- GitLab From 017b054a0f19f8ad79989e0468632cfe62e5f9e1 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 8 Apr 2020 13:32:22 +0200 Subject: [PATCH 188/300] Fix #5516 (#5560) * Add a failing test * Make test not freeze * Fix the bug * Fix spaces * Fix tests * Apply suggestions from code review Co-Authored-By: Toralf Wittner * Make sure test doesn't succeed if nothing happened * Fix build * Do the events change Co-authored-by: Toralf Wittner --- client/cli/src/params/network_params.rs | 1 + client/network/src/config.rs | 27 +- .../protocol/generic_proto/handler/group.rs | 64 ++--- client/network/src/service.rs | 32 ++- client/network/src/service/tests.rs | 270 ++++++++++++++++++ client/network/test/src/lib.rs | 8 +- client/service/test/src/lib.rs | 8 +- 7 files changed, 355 insertions(+), 55 deletions(-) create mode 100644 client/network/src/service/tests.rs diff --git a/client/cli/src/params/network_params.rs b/client/cli/src/params/network_params.rs index 2c008e19d1..21e44f9782 100644 --- a/client/cli/src/params/network_params.rs +++ b/client/cli/src/params/network_params.rs @@ -126,6 +126,7 @@ impl NetworkParams { }, listen_addresses, public_addresses: Vec::new(), + notifications_protocols: Vec::new(), node_key, node_name: node_name.to_string(), client_version: client_id.to_string(), diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 9cd57a9d1d..01acbe6875 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -31,16 +31,23 @@ pub use crate::protocol::ProtocolConfig; use crate::service::ExHashT; -use sp_consensus::{block_validation::BlockAnnounceValidator, import_queue::ImportQueue}; -use sp_runtime::traits::{Block as BlockT}; -use libp2p::identity::{Keypair, ed25519}; -use libp2p::wasm_ext; -use libp2p::{PeerId, Multiaddr, multiaddr}; use core::{fmt, iter}; -use std::{convert::TryFrom, future::Future, pin::Pin, str::FromStr}; -use std::{error::Error, fs, io::{self, Write}, net::Ipv4Addr, path::{Path, PathBuf}, sync::Arc}; -use zeroize::Zeroize; +use libp2p::identity::{ed25519, Keypair}; +use libp2p::wasm_ext; +use libp2p::{multiaddr, Multiaddr, PeerId}; use prometheus_endpoint::Registry; +use sp_consensus::{block_validation::BlockAnnounceValidator, import_queue::ImportQueue}; +use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; +use std::{borrow::Cow, convert::TryFrom, future::Future, pin::Pin, str::FromStr}; +use std::{ + error::Error, + fs, + io::{self, Write}, + net::Ipv4Addr, + path::{Path, PathBuf}, + sync::Arc, +}; +use zeroize::Zeroize; /// Network initialization parameters. pub struct Params { @@ -317,6 +324,9 @@ pub struct NetworkConfiguration { pub boot_nodes: Vec, /// The node key configuration, which determines the node's network identity keypair. pub node_key: NodeKeyConfig, + /// List of notifications protocols that the node supports. Must also include a + /// `ConsensusEngineId` for backwards-compatibility. + pub notifications_protocols: Vec<(ConsensusEngineId, Cow<'static, [u8]>)>, /// Maximum allowed number of incoming connections. pub in_peers: u32, /// Number of outgoing connections we're trying to maintain. @@ -349,6 +359,7 @@ impl NetworkConfiguration { public_addresses: Vec::new(), boot_nodes: Vec::new(), node_key, + notifications_protocols: Vec::new(), in_peers: 25, out_peers: 75, reserved_nodes: Vec::new(), diff --git a/client/network/src/protocol/generic_proto/handler/group.rs b/client/network/src/protocol/generic_proto/handler/group.rs index 7e597f1be6..46b759d458 100644 --- a/client/network/src/protocol/generic_proto/handler/group.rs +++ b/client/network/src/protocol/generic_proto/handler/group.rs @@ -442,6 +442,38 @@ impl ProtocolsHandler for NotifsHandler { ) -> Poll< ProtocolsHandlerEvent > { + while let Poll::Ready(ev) = self.legacy.poll(cx) { + match ev { + ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol, info: () } => + return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { + protocol: protocol.map_upgrade(EitherUpgrade::B), + info: None, + }), + ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolOpen { endpoint, .. }) => + return Poll::Ready(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::Open { endpoint } + )), + ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolClosed { endpoint, reason }) => + return Poll::Ready(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::Closed { endpoint, reason } + )), + ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomMessage { message }) => + return Poll::Ready(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::CustomMessage { message } + )), + ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::Clogged { messages }) => + return Poll::Ready(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::Clogged { messages } + )), + ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::ProtocolError { is_severe, error }) => + return Poll::Ready(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::ProtocolError { is_severe, error } + )), + ProtocolsHandlerEvent::Close(err) => + return Poll::Ready(ProtocolsHandlerEvent::Close(EitherError::B(err))), + } + } + for (handler_num, handler) in self.in_handlers.iter_mut().enumerate() { while let Poll::Ready(ev) = handler.poll(cx) { match ev { @@ -495,38 +527,6 @@ impl ProtocolsHandler for NotifsHandler { } } - while let Poll::Ready(ev) = self.legacy.poll(cx) { - match ev { - ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol, info: () } => - return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { - protocol: protocol.map_upgrade(EitherUpgrade::B), - info: None, - }), - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolOpen { endpoint, .. }) => - return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::Open { endpoint } - )), - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolClosed { endpoint, reason }) => - return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::Closed { endpoint, reason } - )), - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomMessage { message }) => - return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::CustomMessage { message } - )), - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::Clogged { messages }) => - return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::Clogged { messages } - )), - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::ProtocolError { is_severe, error }) => - return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::ProtocolError { is_severe, error } - )), - ProtocolsHandlerEvent::Close(err) => - return Poll::Ready(ProtocolsHandlerEvent::Close(EitherError::B(err))), - } - } - Poll::Pending } } diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 48b5c30d3e..581a1ab972 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -52,7 +52,7 @@ use sp_runtime::{ traits::{Block as BlockT, NumberFor}, ConsensusEngineId, }; -use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; use std::{ borrow::Cow, collections::{HashMap, HashSet}, @@ -60,15 +60,20 @@ use std::{ marker::PhantomData, pin::Pin, str, - sync::{atomic::{AtomicBool, AtomicUsize, Ordering}, Arc}, + sync::{ + atomic::{AtomicBool, AtomicUsize, Ordering}, + Arc, + }, task::Poll, }; +#[cfg(test)] +mod tests; + /// Minimum Requirements for a Hash within Networking pub trait ExHashT: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static {} -impl ExHashT for T where - T: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static +impl ExHashT for T where T: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static {} /// Transaction pool interface @@ -284,7 +289,7 @@ impl NetworkWorker { )?; // Build the swarm. - let (mut swarm, bandwidth): (Swarm::, _) = { + let (mut swarm, bandwidth): (Swarm, _) = { let user_agent = format!( "{} ({})", params.network_config.client_version, @@ -296,9 +301,14 @@ impl NetworkWorker { }; let light_client_handler = { let config = protocol::light_client_handler::Config::new(¶ms.protocol_id); - protocol::LightClientHandler::new(config, params.chain, checker, peerset_handle.clone()) + protocol::LightClientHandler::new( + config, + params.chain, + checker, + peerset_handle.clone(), + ) }; - let behaviour = futures::executor::block_on(Behaviour::new( + let mut behaviour = futures::executor::block_on(Behaviour::new( protocol, params.role, user_agent, @@ -316,6 +326,9 @@ impl NetworkWorker { block_requests, light_client_handler )); + for (engine_id, protocol_name) in ¶ms.network_config.notifications_protocols { + behaviour.register_notifications_protocol(*engine_id, protocol_name.clone()); + } let (transport, bandwidth) = { let (config_mem, config_wasm, flowctrl) = match params.network_config.transport { TransportConfig::MemoryOnly => (true, None, false), @@ -531,6 +544,11 @@ impl NetworkWorker { } impl NetworkService { + /// Returns the local `PeerId`. + pub fn local_peer_id(&self) -> &PeerId { + &self.local_peer_id + } + /// Writes a message on an open notifications channel. Has no effect if the notifications /// channel with this protocol name is closed. /// diff --git a/client/network/src/service/tests.rs b/client/network/src/service/tests.rs new file mode 100644 index 0000000000..0e097072e6 --- /dev/null +++ b/client/network/src/service/tests.rs @@ -0,0 +1,270 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use crate::{config, Event, NetworkService, NetworkWorker}; + +use futures::prelude::*; +use sp_runtime::traits::{Block as BlockT, Header as _}; +use std::{sync::Arc, time::Duration}; +use substrate_test_runtime_client::{TestClientBuilder, TestClientBuilderExt as _}; + +type TestNetworkService = NetworkService< + substrate_test_runtime_client::runtime::Block, + substrate_test_runtime_client::runtime::Hash, +>; + +/// Builds a full node to be used for testing. Returns the node service and its associated events +/// stream. +/// +/// > **Note**: We return the events stream in order to not possibly lose events between the +/// > construction of the service and the moment the events stream is grabbed. +fn build_test_full_node(config: config::NetworkConfiguration) + -> (Arc, impl Stream) +{ + let client = Arc::new( + TestClientBuilder::with_default_backend() + .build_with_longest_chain() + .0, + ); + + #[derive(Clone)] + struct PassThroughVerifier(bool); + impl sp_consensus::import_queue::Verifier for PassThroughVerifier { + fn verify( + &mut self, + origin: sp_consensus::BlockOrigin, + header: B::Header, + justification: Option, + body: Option>, + ) -> Result< + ( + sp_consensus::BlockImportParams, + Option)>>, + ), + String, + > { + let maybe_keys = header + .digest() + .log(|l| { + l.try_as_raw(sp_runtime::generic::OpaqueDigestItemId::Consensus(b"aura")) + .or_else(|| { + l.try_as_raw(sp_runtime::generic::OpaqueDigestItemId::Consensus(b"babe")) + }) + }) + .map(|blob| { + vec![( + sp_blockchain::well_known_cache_keys::AUTHORITIES, + blob.to_vec(), + )] + }); + + let mut import = sp_consensus::BlockImportParams::new(origin, header); + import.body = body; + import.finalized = self.0; + import.justification = justification; + import.fork_choice = Some(sp_consensus::ForkChoiceStrategy::LongestChain); + Ok((import, maybe_keys)) + } + } + + let import_queue = Box::new(sp_consensus::import_queue::BasicQueue::new( + PassThroughVerifier(false), + Box::new(client.clone()), + None, + None, + )); + + let worker = NetworkWorker::new(config::Params { + role: config::Role::Full, + executor: None, + network_config: config, + chain: client.clone(), + finality_proof_provider: None, + finality_proof_request_builder: None, + on_demand: None, + transaction_pool: Arc::new(crate::service::EmptyTransactionPool), + protocol_id: config::ProtocolId::from(&b"/test-protocol-name"[..]), + import_queue, + block_announce_validator: Box::new( + sp_consensus::block_validation::DefaultBlockAnnounceValidator::new(client.clone()), + ), + metrics_registry: None, + }) + .unwrap(); + + let service = worker.service().clone(); + let event_stream = service.event_stream(); + + async_std::task::spawn(async move { + futures::pin_mut!(worker); + let _ = worker.await; + }); + + (service, event_stream) +} + +const ENGINE_ID: sp_runtime::ConsensusEngineId = *b"foo\0"; + +/// Builds two nodes and their associated events stream. +/// The nodes are connected together and have the `ENGINE_ID` protocol registered. +fn build_nodes_one_proto() + -> (Arc, impl Stream, Arc, impl Stream) +{ + let listen_addr = config::build_multiaddr![Memory(rand::random::())]; + + let (node1, events_stream1) = build_test_full_node(config::NetworkConfiguration { + notifications_protocols: vec![(ENGINE_ID, From::from(&b"/foo"[..]))], + listen_addresses: vec![listen_addr.clone()], + transport: config::TransportConfig::MemoryOnly, + .. config::NetworkConfiguration::new_local() + }); + + let (node2, events_stream2) = build_test_full_node(config::NetworkConfiguration { + notifications_protocols: vec![(ENGINE_ID, From::from(&b"/foo"[..]))], + reserved_nodes: vec![config::MultiaddrWithPeerId { + multiaddr: listen_addr, + peer_id: node1.local_peer_id().clone(), + }], + transport: config::TransportConfig::MemoryOnly, + .. config::NetworkConfiguration::new_local() + }); + + (node1, events_stream1, node2, events_stream2) +} + +#[test] +fn notifications_state_consistent() { + // Runs two nodes and ensures that events are propagated out of the API in a consistent + // correct order, which means no notification received on a closed substream. + + let (node1, mut events_stream1, node2, mut events_stream2) = build_nodes_one_proto(); + + // Write some initial notifications that shouldn't get through. + for _ in 0..(rand::random::() % 5) { + node1.write_notification(node2.local_peer_id().clone(), ENGINE_ID, b"hello world".to_vec()); + } + for _ in 0..(rand::random::() % 5) { + node2.write_notification(node1.local_peer_id().clone(), ENGINE_ID, b"hello world".to_vec()); + } + + async_std::task::block_on(async move { + // True if we have an active substream from node1 to node2. + let mut node1_to_node2_open = false; + // True if we have an active substream from node2 to node1. + let mut node2_to_node1_open = false; + // We stop the test after a certain number of iterations. + let mut iterations = 0; + // Safe guard because we don't want the test to pass if no substream has been open. + let mut something_happened = false; + + loop { + iterations += 1; + if iterations >= 1_000 { + assert!(something_happened); + break; + } + + // Start by sending a notification from node1 to node2 and vice-versa. Part of the + // test consists in ensuring that notifications get ignored if the stream isn't open. + if rand::random::() % 5 >= 3 { + node1.write_notification(node2.local_peer_id().clone(), ENGINE_ID, b"hello world".to_vec()); + } + if rand::random::() % 5 >= 3 { + node2.write_notification(node1.local_peer_id().clone(), ENGINE_ID, b"hello world".to_vec()); + } + + // Also randomly disconnect the two nodes from time to time. + if rand::random::() % 20 == 0 { + node1.disconnect_peer(node2.local_peer_id().clone()); + } + if rand::random::() % 20 == 0 { + node2.disconnect_peer(node1.local_peer_id().clone()); + } + + // Grab next event from either `events_stream1` or `events_stream2`. + let next_event = { + let next1 = events_stream1.next(); + let next2 = events_stream2.next(); + // We also await on a small timer, otherwise it is possible for the test to wait + // forever while nothing at all happens on the network. + let continue_test = futures_timer::Delay::new(Duration::from_millis(20)); + match future::select(future::select(next1, next2), continue_test).await { + future::Either::Left((future::Either::Left((Some(ev), _)), _)) => + future::Either::Left(ev), + future::Either::Left((future::Either::Right((Some(ev), _)), _)) => + future::Either::Right(ev), + future::Either::Right(_) => continue, + _ => break, + } + }; + + match next_event { + future::Either::Left(Event::NotificationStreamOpened { remote, engine_id, .. }) => { + something_happened = true; + assert!(!node1_to_node2_open); + node1_to_node2_open = true; + assert_eq!(remote, *node2.local_peer_id()); + assert_eq!(engine_id, ENGINE_ID); + } + future::Either::Right(Event::NotificationStreamOpened { remote, engine_id, .. }) => { + something_happened = true; + assert!(!node2_to_node1_open); + node2_to_node1_open = true; + assert_eq!(remote, *node1.local_peer_id()); + assert_eq!(engine_id, ENGINE_ID); + } + future::Either::Left(Event::NotificationStreamClosed { remote, engine_id, .. }) => { + assert!(node1_to_node2_open); + node1_to_node2_open = false; + assert_eq!(remote, *node2.local_peer_id()); + assert_eq!(engine_id, ENGINE_ID); + } + future::Either::Right(Event::NotificationStreamClosed { remote, engine_id, .. }) => { + assert!(node2_to_node1_open); + node2_to_node1_open = false; + assert_eq!(remote, *node1.local_peer_id()); + assert_eq!(engine_id, ENGINE_ID); + } + future::Either::Left(Event::NotificationsReceived { remote, .. }) => { + assert!(node1_to_node2_open); + assert_eq!(remote, *node2.local_peer_id()); + if rand::random::() % 5 >= 4 { + node1.write_notification( + node2.local_peer_id().clone(), + ENGINE_ID, + b"hello world".to_vec() + ); + } + } + future::Either::Right(Event::NotificationsReceived { remote, .. }) => { + assert!(node2_to_node1_open); + assert_eq!(remote, *node1.local_peer_id()); + if rand::random::() % 5 >= 4 { + node2.write_notification( + node1.local_peer_id().clone(), + ENGINE_ID, + b"hello world".to_vec() + ); + } + } + + // Add new events here. + future::Either::Left(Event::Dht(_)) => {} + future::Either::Right(Event::Dht(_)) => {} + }; + } + }); +} diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 56070f9888..fec4f1317b 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -41,7 +41,7 @@ use sp_consensus::block_import::{BlockImport, ImportResult}; use sp_consensus::Error as ConsensusError; use sp_consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, BlockCheckParams, JustificationImport}; use futures::prelude::*; -use sc_network::{NetworkWorker, NetworkStateInfo, NetworkService, config::ProtocolId}; +use sc_network::{NetworkWorker, NetworkService, config::ProtocolId}; use sc_network::config::{NetworkConfiguration, TransportConfig, BoxFinalityProofRequestBuilder}; use libp2p::PeerId; use parking_lot::Mutex; @@ -189,7 +189,7 @@ pub struct Peer { impl Peer { /// Get this peer ID. pub fn id(&self) -> PeerId { - self.network.service().local_peer_id() + self.network.service().local_peer_id().clone() } /// Returns true if we're major syncing. @@ -628,7 +628,7 @@ pub trait TestNetFactory: Sized { self.mut_peers(|peers| { for peer in peers.iter_mut() { - peer.network.add_known_address(network.service().local_peer_id(), listen_addr.clone()); + peer.network.add_known_address(network.service().local_peer_id().clone(), listen_addr.clone()); } let imported_blocks_stream = Box::pin(client.import_notification_stream().fuse()); @@ -704,7 +704,7 @@ pub trait TestNetFactory: Sized { self.mut_peers(|peers| { for peer in peers.iter_mut() { - peer.network.add_known_address(network.service().local_peer_id(), listen_addr.clone()); + peer.network.add_known_address(network.service().local_peer_id().clone(), listen_addr.clone()); } let imported_blocks_stream = Box::pin(client.import_notification_stream().fuse()); diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index bb5ef09562..2811076ba3 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -37,7 +37,7 @@ use sc_service::{ Role, Error, }; -use sc_network::{multiaddr, Multiaddr, NetworkStateInfo}; +use sc_network::{multiaddr, Multiaddr}; use sc_network::config::{NetworkConfiguration, TransportConfig}; use sp_runtime::{generic::BlockId, traits::Block as BlockT}; use sp_transaction_pool::TransactionPool; @@ -265,7 +265,7 @@ impl TestNet where let service = SyncService::from(service); executor.spawn(service.clone().map_err(|_| ())); - let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().into())); + let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().clone().into())); self.authority_nodes.push((self.nodes, service, user_data, addr)); self.nodes += 1; } @@ -281,7 +281,7 @@ impl TestNet where let service = SyncService::from(service); executor.spawn(service.clone().map_err(|_| ())); - let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().into())); + let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().clone().into())); self.full_nodes.push((self.nodes, service, user_data, addr)); self.nodes += 1; } @@ -296,7 +296,7 @@ impl TestNet where let service = SyncService::from(light(node_config).expect("Error creating test node service")); executor.spawn(service.clone().map_err(|_| ())); - let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().into())); + let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().clone().into())); self.light_nodes.push((self.nodes, service, addr)); self.nodes += 1; } -- GitLab From 11493abe7d052c7465fa7760c57824fb455e0e68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 8 Apr 2020 15:05:29 +0200 Subject: [PATCH 189/300] Don't always recompile the node binary on `cargo run` (#5577) There was a bug in determining the correct git files that should be tracked. The ref extracted from `.git/HEAD` pointed to a relative path and thus could not be found by cargo and resulted in always recompiling the binary. --- utils/build-script-utils/src/git.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/utils/build-script-utils/src/git.rs b/utils/build-script-utils/src/git.rs index 919c4813ab..10f5446cb4 100644 --- a/utils/build-script-utils/src/git.rs +++ b/utils/build-script-utils/src/git.rs @@ -16,7 +16,8 @@ use std::{env, fs, fs::File, io, io::Read, path::PathBuf}; -/// Make sure the calling `build.rs` script is rerun when `.git/HEAD` changed. +/// Make sure the calling `build.rs` script is rerun when `.git/HEAD` or the ref of `.git/HEAD` +/// changed. /// /// The file is searched from the `CARGO_MANIFEST_DIR` upwards. If the file can not be found, /// a warning is generated. @@ -69,7 +70,7 @@ fn get_git_paths(path: &PathBuf) -> Result>, io::Error> { if ref_vec.len() == 2 { let current_head_file = ref_vec[1]; - let git_refs_path = PathBuf::from(".git").join(current_head_file); + let git_refs_path = git_dir_or_file.join(current_head_file); Ok(Some(vec![git_head_path, git_refs_path])) } else { -- GitLab From 5d05c9cf30a76ced8abc00f02429925237ae34c6 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Wed, 8 Apr 2020 18:45:25 +0200 Subject: [PATCH 190/300] Reuse wasmtime instances, the PR (#5567) * Preserve a single wasmtime instance. * Sketch of wasm instance reusing. * Refactor and docs. * Rename state_snapshot to util module. * Renaming. * Comments. * Error handling * More fixes. --- Cargo.lock | 6 +- client/executor/common/Cargo.toml | 1 + client/executor/common/src/lib.rs | 3 +- client/executor/common/src/util.rs | 138 +++++++++++++ client/executor/wasmi/Cargo.toml | 1 - client/executor/wasmi/src/lib.rs | 187 +++++++----------- client/executor/wasmtime/Cargo.toml | 4 + .../executor/wasmtime/src/instance_wrapper.rs | 62 +++++- .../src/instance_wrapper/globals_snapshot.rs | 130 ++++++++++++ client/executor/wasmtime/src/runtime.rs | 70 ++++--- 10 files changed, 446 insertions(+), 156 deletions(-) create mode 100644 client/executor/common/src/util.rs create mode 100644 client/executor/wasmtime/src/instance_wrapper/globals_snapshot.rs diff --git a/Cargo.lock b/Cargo.lock index 3eaf51f752..f9e4f913c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6250,6 +6250,7 @@ dependencies = [ "derive_more", "log", "parity-scale-codec", + "parity-wasm 0.41.0", "sp-allocator", "sp-core", "sp-runtime-interface", @@ -6264,7 +6265,6 @@ version = "0.8.0-alpha.5" dependencies = [ "log", "parity-scale-codec", - "parity-wasm 0.41.0", "sc-executor-common", "sp-allocator", "sp-core", @@ -6278,6 +6278,8 @@ name = "sc-executor-wasmtime" version = "0.8.0-alpha.5" dependencies = [ "assert_matches", + "cranelift-codegen", + "cranelift-wasm", "log", "parity-scale-codec", "parity-wasm 0.41.0", @@ -6288,6 +6290,8 @@ dependencies = [ "sp-runtime-interface", "sp-wasm-interface", "substrate-wasmtime", + "substrate-wasmtime-runtime", + "wasmtime-environ", ] [[package]] diff --git a/client/executor/common/Cargo.toml b/client/executor/common/Cargo.toml index 1f52b959d0..f9ce7d4e39 100644 --- a/client/executor/common/Cargo.toml +++ b/client/executor/common/Cargo.toml @@ -12,6 +12,7 @@ documentation = "https://docs.rs/sc-executor-common/" [dependencies] log = "0.4.8" derive_more = "0.99.2" +parity-wasm = "0.41.0" codec = { package = "parity-scale-codec", version = "1.3.0" } wasmi = "0.6.2" sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } diff --git a/client/executor/common/src/lib.rs b/client/executor/common/src/lib.rs index cc515dcf9d..7f3864e615 100644 --- a/client/executor/common/src/lib.rs +++ b/client/executor/common/src/lib.rs @@ -18,6 +18,7 @@ #![warn(missing_docs)] -pub mod sandbox; pub mod error; +pub mod sandbox; +pub mod util; pub mod wasm_runtime; diff --git a/client/executor/common/src/util.rs b/client/executor/common/src/util.rs new file mode 100644 index 0000000000..149db13bc0 --- /dev/null +++ b/client/executor/common/src/util.rs @@ -0,0 +1,138 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! A set of utilities for resetting a wasm instance to its initial state. + +use crate::error::{self, Error}; +use std::mem; +use parity_wasm::elements::{deserialize_buffer, DataSegment, Instruction, Module as RawModule}; + +/// A bunch of information collected from a WebAssembly module. +pub struct WasmModuleInfo { + raw_module: RawModule, +} + +impl WasmModuleInfo { + /// Create `WasmModuleInfo` from the given wasm code. + /// + /// Returns `None` if the wasm code cannot be deserialized. + pub fn new(wasm_code: &[u8]) -> Option { + let raw_module: RawModule = deserialize_buffer(wasm_code).ok()?; + Some(Self { raw_module }) + } + + /// Extract the data segments from the given wasm code. + /// + /// Returns `Err` if the given wasm code cannot be deserialized. + fn data_segments(&self) -> Vec { + self.raw_module + .data_section() + .map(|ds| ds.entries()) + .unwrap_or(&[]) + .to_vec() + } + + /// The number of globals defined in locally in this module. + pub fn declared_globals_count(&self) -> u32 { + self.raw_module + .global_section() + .map(|gs| gs.entries().len() as u32) + .unwrap_or(0) + } + + /// The number of imports of globals. + pub fn imported_globals_count(&self) -> u32 { + self.raw_module + .import_section() + .map(|is| is.globals() as u32) + .unwrap_or(0) + } +} + +/// This is a snapshot of data segments specialzied for a particular instantiation. +/// +/// Note that this assumes that no mutable globals are used. +#[derive(Clone)] +pub struct DataSegmentsSnapshot { + /// The list of data segments represented by (offset, contents). + data_segments: Vec<(u32, Vec)>, +} + +impl DataSegmentsSnapshot { + /// Create a snapshot from the data segments from the module. + pub fn take(module: &WasmModuleInfo) -> error::Result { + let data_segments = module + .data_segments() + .into_iter() + .map(|mut segment| { + // Just replace contents of the segment since the segments will be discarded later + // anyway. + let contents = mem::replace(segment.value_mut(), vec![]); + + let init_expr = match segment.offset() { + Some(offset) => offset.code(), + // Return if the segment is passive + None => return Err(Error::from("Shared memory is not supported".to_string())), + }; + + // [op, End] + if init_expr.len() != 2 { + return Err(Error::from( + "initializer expression can have only up to 2 expressions in wasm 1.0" + .to_string(), + )); + } + let offset = match &init_expr[0] { + Instruction::I32Const(v) => *v as u32, + Instruction::GetGlobal(_) => { + // In a valid wasm file, initializer expressions can only refer imported + // globals. + // + // At the moment of writing the Substrate Runtime Interface does not provide + // any globals. There is nothing that prevents us from supporting this + // if/when we gain those. + return Err(Error::from( + "Imported globals are not supported yet".to_string(), + )); + } + insn => { + return Err(Error::from(format!( + "{:?} is not supported as initializer expression in wasm 1.0", + insn + ))) + } + }; + + Ok((offset, contents)) + }) + .collect::>>()?; + + Ok(Self { data_segments }) + } + + /// Apply the given snapshot to a linear memory. + /// + /// Linear memory interface is represented by a closure `memory_set`. + pub fn apply( + &self, + mut memory_set: impl FnMut(u32, &[u8]) -> Result<(), E>, + ) -> Result<(), E> { + for (offset, contents) in &self.data_segments { + memory_set(*offset, contents)?; + } + Ok(()) + } +} diff --git a/client/executor/wasmi/Cargo.toml b/client/executor/wasmi/Cargo.toml index ea8637b9e2..fe5bd70d00 100644 --- a/client/executor/wasmi/Cargo.toml +++ b/client/executor/wasmi/Cargo.toml @@ -12,7 +12,6 @@ documentation = "https://docs.rs/sc-executor-wasmi" [dependencies] log = "0.4.8" wasmi = "0.6.2" -parity-wasm = "0.41.0" codec = { package = "parity-scale-codec", version = "1.3.0" } sc-executor-common = { version = "0.8.0-alpha.5", path = "../common" } sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/wasm-interface" } diff --git a/client/executor/wasmi/src/lib.rs b/client/executor/wasmi/src/lib.rs index 6348c24133..e4b4aca409 100644 --- a/client/executor/wasmi/src/lib.rs +++ b/client/executor/wasmi/src/lib.rs @@ -16,21 +16,25 @@ //! This crate provides an implementation of `WasmModule` that is baked by wasmi. -use sc_executor_common::{error::{Error, WasmError}, sandbox}; -use std::{str, mem, cell::RefCell, sync::Arc}; +use std::{str, cell::RefCell, sync::Arc}; use wasmi::{ Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder, ModuleRef, - memory_units::Pages, RuntimeValue::{I32, I64, self}, + memory_units::Pages, + RuntimeValue::{I32, I64, self}, }; use codec::{Encode, Decode}; use sp_core::sandbox as sandbox_primitives; use log::{error, trace, debug}; -use parity_wasm::elements::{deserialize_buffer, DataSegment, Instruction, Module as RawModule}; use sp_wasm_interface::{ FunctionContext, Pointer, WordSize, Sandbox, MemoryId, Result as WResult, Function, }; use sp_runtime_interface::unpack_ptr_and_len; use sc_executor_common::wasm_runtime::{WasmModule, WasmInstance}; +use sc_executor_common::{ + error::{Error, WasmError}, + sandbox, +}; +use sc_executor_common::util::{DataSegmentsSnapshot, WasmModuleInfo}; struct FunctionExecutor<'a> { sandbox_store: sandbox::Store, @@ -530,52 +534,14 @@ fn instantiate_module( /// /// It is used for restoring the state of the module after execution. #[derive(Clone)] -struct StateSnapshot { - /// The offset and the content of the memory segments that should be used to restore the snapshot - data_segments: Vec<(u32, Vec)>, +struct GlobalValsSnapshot { /// The list of all global mutable variables of the module in their sequential order. global_mut_values: Vec, } -impl StateSnapshot { +impl GlobalValsSnapshot { // Returns `None` if instance is not valid. - fn take( - module_instance: &ModuleRef, - data_segments: Vec, - ) -> Option { - let prepared_segments = data_segments - .into_iter() - .map(|mut segment| { - // Just replace contents of the segment since the segments will be discarded later - // anyway. - let contents = mem::replace(segment.value_mut(), vec![]); - - let init_expr = match segment.offset() { - Some(offset) => offset.code(), - // Return if the segment is passive - None => return None - }; - - // [op, End] - if init_expr.len() != 2 { - return None; - } - let offset = match init_expr[0] { - Instruction::I32Const(v) => v as u32, - Instruction::GetGlobal(idx) => { - let global_val = module_instance.globals().get(idx as usize)?.get(); - match global_val { - RuntimeValue::I32(v) => v as u32, - _ => return None, - } - } - _ => return None, - }; - - Some((offset, contents)) - }) - .collect::>>()?; - + fn take(module_instance: &ModuleRef) -> Self { // Collect all values of mutable globals. let global_mut_values = module_instance .globals() @@ -583,42 +549,27 @@ impl StateSnapshot { .filter(|g| g.is_mutable()) .map(|g| g.get()) .collect(); - - Some(Self { - data_segments: prepared_segments, - global_mut_values, - }) + Self { global_mut_values } } /// Reset the runtime instance to the initial version by restoring /// the preserved memory and globals. /// /// Returns `Err` if applying the snapshot is failed. - fn apply(&self, instance: &ModuleRef, memory: &MemoryRef) -> Result<(), WasmError> { - // First, erase the memory and copy the data segments into it. - memory - .erase() - .map_err(|e| WasmError::ErasingFailed(e.to_string()))?; - for (offset, contents) in &self.data_segments { - memory - .set(*offset, contents) - .map_err(|_| WasmError::ApplySnapshotFailed)?; - } - - // Second, restore the values of mutable globals. + fn apply(&self, instance: &ModuleRef) -> Result<(), WasmError> { for (global_ref, global_val) in instance .globals() .iter() .filter(|g| g.is_mutable()) .zip(self.global_mut_values.iter()) - { - // the instance should be the same as used for preserving and - // we iterate the same way it as we do it for preserving values that means that the - // types should be the same and all the values are mutable. So no error is expected/ - global_ref - .set(*global_val) - .map_err(|_| WasmError::ApplySnapshotFailed)?; - } + { + // the instance should be the same as used for preserving and + // we iterate the same way it as we do it for preserving values that means that the + // types should be the same and all the values are mutable. So no error is expected/ + global_ref + .set(*global_val) + .map_err(|_| WasmError::ApplySnapshotFailed)?; + } Ok(()) } } @@ -634,8 +585,9 @@ pub struct WasmiRuntime { allow_missing_func_imports: bool, /// Numer of heap pages this runtime uses. heap_pages: u64, - /// Data segments created for each new instance. - data_segments: Vec, + + global_vals_snapshot: GlobalValsSnapshot, + data_segments_snapshot: DataSegmentsSnapshot, } impl WasmModule for WasmiRuntime { @@ -648,19 +600,11 @@ impl WasmModule for WasmiRuntime { self.allow_missing_func_imports, ).map_err(|e| WasmError::Instantiation(e.to_string()))?; - // Take state snapshot before executing anything. - let state_snapshot = StateSnapshot::take(&instance, self.data_segments.clone()) - .expect( - "`take` returns `Err` if the module is not valid; - we already loaded module above, thus the `Module` is proven to be valid at this point; - qed - ", - ); - Ok(Box::new(WasmiInstance { instance, memory, - state_snapshot, + global_vals_snapshot: self.global_vals_snapshot.clone(), + data_segments_snapshot: self.data_segments_snapshot.clone(), host_functions: self.host_functions.clone(), allow_missing_func_imports: self.allow_missing_func_imports, missing_functions, @@ -682,10 +626,29 @@ pub fn create_runtime( // // A return of this error actually indicates that there is a problem in logic, since // we just loaded and validated the `module` above. - let data_segments = extract_data_segments(&code)?; + let (data_segments_snapshot, global_vals_snapshot) = { + let (instance, _, _) = instantiate_module( + heap_pages as usize, + &module, + &host_functions, + allow_missing_func_imports, + ) + .map_err(|e| WasmError::Instantiation(e.to_string()))?; + + let data_segments_snapshot = DataSegmentsSnapshot::take( + &WasmModuleInfo::new(code) + .ok_or_else(|| WasmError::Other("cannot deserialize module".to_string()))?, + ) + .map_err(|e| WasmError::Other(e.to_string()))?; + let global_vals_snapshot = GlobalValsSnapshot::take(&instance); + + (data_segments_snapshot, global_vals_snapshot) + }; + Ok(WasmiRuntime { module, - data_segments, + data_segments_snapshot, + global_vals_snapshot, host_functions: Arc::new(host_functions), allow_missing_func_imports, heap_pages, @@ -698,12 +661,14 @@ pub struct WasmiInstance { instance: ModuleRef, /// The memory instance of used by the wasm module. memory: MemoryRef, - /// The snapshot of the instance's state taken just after the instantiation. - state_snapshot: StateSnapshot, + /// The snapshot of global variable values just after instantiation. + global_vals_snapshot: GlobalValsSnapshot, + /// The snapshot of data segments. + data_segments_snapshot: DataSegmentsSnapshot, /// The host functions registered for this instance. host_functions: Arc>, /// Enable stub generation for functions that are not available in `host_functions`. - /// These stubs will error when the wasm blob tries to call them. + /// These stubs will error when the wasm blob trie to call them. allow_missing_func_imports: bool, /// List of missing functions detected during function resolution missing_functions: Vec, @@ -713,19 +678,26 @@ pub struct WasmiInstance { unsafe impl Send for WasmiInstance {} impl WasmInstance for WasmiInstance { - fn call( - &self, - method: &str, - data: &[u8], - ) -> Result, Error> { - self.state_snapshot.apply(&self.instance, &self.memory) - .map_err(|e| { - // Snapshot restoration failed. This is pretty unexpected since this can happen - // if some invariant is broken or if the system is under extreme memory pressure - // (so erasing fails). - error!(target: "wasm-executor", "snapshot restoration failed: {}", e); - e - })?; + fn call(&self, method: &str, data: &[u8]) -> Result, Error> { + // We reuse a single wasm instance for multiple calls and a previous call (if any) + // altered the state. Therefore, we need to restore the instance to original state. + + // First, zero initialize the linear memory. + self.memory.erase().map_err(|e| { + // Snapshot restoration failed. This is pretty unexpected since this can happen + // if some invariant is broken or if the system is under extreme memory pressure + // (so erasing fails). + error!(target: "wasm-executor", "snapshot restoration failed: {}", e); + WasmError::ErasingFailed(e.to_string()) + })?; + + // Second, reapply data segments into the linear memory. + self.data_segments_snapshot + .apply(|offset, contents| self.memory.set(offset, contents))?; + + // Third, restore the global variables to their initial values. + self.global_vals_snapshot.apply(&self.instance)?; + call_in_wasm_module( &self.instance, &self.memory, @@ -750,18 +722,3 @@ impl WasmInstance for WasmiInstance { } } } - -/// Extract the data segments from the given wasm code. -/// -/// Returns `Err` if the given wasm code cannot be deserialized. -fn extract_data_segments(wasm_code: &[u8]) -> Result, WasmError> { - let raw_module: RawModule = deserialize_buffer(wasm_code) - .map_err(|_| WasmError::CantDeserializeWasm)?; - - let segments = raw_module - .data_section() - .map(|ds| ds.entries()) - .unwrap_or(&[]) - .to_vec(); - Ok(segments) -} diff --git a/client/executor/wasmtime/Cargo.toml b/client/executor/wasmtime/Cargo.toml index 11f99e7876..fcedf20b7a 100644 --- a/client/executor/wasmtime/Cargo.toml +++ b/client/executor/wasmtime/Cargo.toml @@ -19,6 +19,10 @@ sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/ sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } sp-allocator = { version = "2.0.0-alpha.5", path = "../../../primitives/allocator" } wasmtime = { package = "substrate-wasmtime", version = "0.13.0-threadsafe.1" } +wasmtime_runtime = { package = "substrate-wasmtime-runtime", version = "0.13.0-threadsafe.1" } +wasmtime-environ = "0.12.0" +cranelift-wasm = "0.59.0" +cranelift-codegen = "0.59.0" [dev-dependencies] assert_matches = "1.3.0" diff --git a/client/executor/wasmtime/src/instance_wrapper.rs b/client/executor/wasmtime/src/instance_wrapper.rs index 159746801a..469668802f 100644 --- a/client/executor/wasmtime/src/instance_wrapper.rs +++ b/client/executor/wasmtime/src/instance_wrapper.rs @@ -20,11 +20,55 @@ use crate::util; use crate::imports::Imports; -use sc_executor_common::error::{Error, Result}; +use std::{slice, marker}; +use sc_executor_common::{ + error::{Error, Result}, + util::{WasmModuleInfo, DataSegmentsSnapshot}, +}; use sp_wasm_interface::{Pointer, WordSize, Value}; -use std::slice; -use std::marker; -use wasmtime::{Instance, Module, Memory, Table, Val}; +use wasmtime::{Store, Instance, Module, Memory, Table, Val}; + +mod globals_snapshot; + +pub use globals_snapshot::GlobalsSnapshot; + +pub struct ModuleWrapper { + imported_globals_count: u32, + globals_count: u32, + module: Module, + data_segments_snapshot: DataSegmentsSnapshot, +} + +impl ModuleWrapper { + pub fn new(store: &Store, code: &[u8]) -> Result { + let module = Module::new(&store, code) + .map_err(|e| Error::from(format!("cannot create module: {}", e)))?; + + let module_info = WasmModuleInfo::new(code) + .ok_or_else(|| Error::from("cannot deserialize module".to_string()))?; + let declared_globals_count = module_info.declared_globals_count(); + let imported_globals_count = module_info.imported_globals_count(); + let globals_count = imported_globals_count + declared_globals_count; + + let data_segments_snapshot = DataSegmentsSnapshot::take(&module_info) + .map_err(|e| Error::from(format!("cannot take data segments snapshot: {}", e)))?; + + Ok(Self { + module, + imported_globals_count, + globals_count, + data_segments_snapshot, + }) + } + + pub fn module(&self) -> &Module { + &self.module + } + + pub fn data_segments_snapshot(&self) -> &DataSegmentsSnapshot { + &self.data_segments_snapshot + } +} /// Wrap the given WebAssembly Instance of a wasm module with Substrate-runtime. /// @@ -32,6 +76,8 @@ use wasmtime::{Instance, Module, Memory, Table, Val}; /// routines. pub struct InstanceWrapper { instance: Instance, + globals_count: u32, + imported_globals_count: u32, // The memory instance of the `instance`. // // It is important to make sure that we don't make any copies of this to make it easier to proof @@ -44,8 +90,8 @@ pub struct InstanceWrapper { impl InstanceWrapper { /// Create a new instance wrapper from the given wasm module. - pub fn new(module: &Module, imports: &Imports, heap_pages: u32) -> Result { - let instance = Instance::new(module, &imports.externs) + pub fn new(module_wrapper: &ModuleWrapper, imports: &Imports, heap_pages: u32) -> Result { + let instance = Instance::new(&module_wrapper.module, &imports.externs) .map_err(|e| Error::from(format!("cannot instantiate: {}", e)))?; let memory = match imports.memory_import_index { @@ -66,8 +112,10 @@ impl InstanceWrapper { Ok(Self { table: get_table(&instance), - memory, instance, + globals_count: module_wrapper.globals_count, + imported_globals_count: module_wrapper.imported_globals_count, + memory, _not_send_nor_sync: marker::PhantomData, }) } diff --git a/client/executor/wasmtime/src/instance_wrapper/globals_snapshot.rs b/client/executor/wasmtime/src/instance_wrapper/globals_snapshot.rs new file mode 100644 index 0000000000..a6ab3fed60 --- /dev/null +++ b/client/executor/wasmtime/src/instance_wrapper/globals_snapshot.rs @@ -0,0 +1,130 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use super::InstanceWrapper; +use sc_executor_common::{ + error::{Error, Result}, +}; +use sp_wasm_interface::Value; +use cranelift_codegen::ir; +use cranelift_wasm::GlobalIndex; + +/// A snapshot of a global variables values. This snapshot can be used later for restoring the +/// values to the preserved state. +/// +/// Technically, a snapshot stores only values of mutable global variables. This is because +/// immutable global variables always have the same values. +pub struct GlobalsSnapshot { + handle: wasmtime_runtime::InstanceHandle, + preserved_mut_globals: Vec<(*mut wasmtime_runtime::VMGlobalDefinition, Value)>, +} + +impl GlobalsSnapshot { + /// Take a snapshot of global variables for a given instance. + pub fn take(instance_wrapper: &InstanceWrapper) -> Result { + // EVIL: + // Usage of an undocumented function. + let handle = instance_wrapper.instance.handle().clone(); + + let mut preserved_mut_globals = vec![]; + + for global_idx in instance_wrapper.imported_globals_count..instance_wrapper.globals_count { + let (def, global) = match handle.lookup_by_declaration( + &wasmtime_environ::Export::Global(GlobalIndex::from_u32(global_idx)), + ) { + wasmtime_runtime::Export::Global { + definition, global, .. + } => (definition, global), + _ => unreachable!("only globals can be returned for a global request"), + }; + + // skip immutable globals. + if !global.mutability { + continue; + } + + let value = unsafe { + // Safety of this function solely depends on the correctness of the reference and + // the type information of the global. + read_global(def, global.ty)? + }; + preserved_mut_globals.push((def, value)); + } + + Ok(Self { + preserved_mut_globals, + handle, + }) + } + + /// Apply the snapshot to the given instance. + /// + /// This instance must be the same that was used for creation of this snapshot. + pub fn apply(&self, instance_wrapper: &InstanceWrapper) -> Result<()> { + if instance_wrapper.instance.handle() != &self.handle { + return Err(Error::from("unexpected instance handle".to_string())); + } + + for (def, value) in &self.preserved_mut_globals { + unsafe { + // The following writes are safe if the precondition that this is the same instance + // this snapshot was created with: + // + // 1. These pointers must be still not-NULL and allocated. + // 2. The set of global variables is fixed for the lifetime of the same instance. + // 3. We obviously assume that the wasmtime references are correct in the first place. + // 4. We write the data with the same type it was read in the first place. + write_global(*def, *value)?; + } + } + Ok(()) + } +} + +unsafe fn read_global( + def: *const wasmtime_runtime::VMGlobalDefinition, + ty: ir::Type, +) -> Result { + let def = def + .as_ref() + .ok_or_else(|| Error::from("wasmtime global reference is null during read".to_string()))?; + let val = match ty { + ir::types::I32 => Value::I32(*def.as_i32()), + ir::types::I64 => Value::I64(*def.as_i64()), + ir::types::F32 => Value::F32(*def.as_u32()), + ir::types::F64 => Value::F64(*def.as_u64()), + _ => { + return Err(Error::from(format!( + "unsupported global variable type: {}", + ty + ))) + } + }; + Ok(val) +} + +unsafe fn write_global(def: *mut wasmtime_runtime::VMGlobalDefinition, value: Value) -> Result<()> { + let def = def + .as_mut() + .ok_or_else(|| Error::from("wasmtime global reference is null during write".to_string()))?; + match value { + Value::I32(v) => *def.as_i32_mut() = v, + Value::I64(v) => *def.as_i64_mut() = v, + Value::F32(v) => *def.as_u32_mut() = v, + Value::F64(v) => *def.as_u64_mut() = v, + } + Ok(()) +} diff --git a/client/executor/wasmtime/src/runtime.rs b/client/executor/wasmtime/src/runtime.rs index 02acd33e69..0289188ba1 100644 --- a/client/executor/wasmtime/src/runtime.rs +++ b/client/executor/wasmtime/src/runtime.rs @@ -15,14 +15,14 @@ // along with Substrate. If not, see . //! Defines the compiled Wasm runtime that uses Wasmtime internally. -use std::rc::Rc; -use std::sync::Arc; use crate::host::HostState; use crate::imports::{Imports, resolve_imports}; -use crate::instance_wrapper::InstanceWrapper; +use crate::instance_wrapper::{ModuleWrapper, InstanceWrapper, GlobalsSnapshot}; use crate::state_holder; +use std::rc::Rc; +use std::sync::Arc; use sc_executor_common::{ error::{Error, Result, WasmError}, wasm_runtime::{WasmModule, WasmInstance}, @@ -30,12 +30,12 @@ use sc_executor_common::{ use sp_allocator::FreeingBumpHeapAllocator; use sp_runtime_interface::unpack_ptr_and_len; use sp_wasm_interface::{Function, Pointer, WordSize, Value}; -use wasmtime::{Config, Engine, Module, Store}; +use wasmtime::{Config, Engine, Store}; /// A `WasmModule` implementation using wasmtime to compile the runtime module to machine code /// and execute the compiled code. pub struct WasmtimeRuntime { - module: Arc, + module_wrapper: Arc, heap_pages: u32, allow_missing_func_imports: bool, host_functions: Vec<&'static dyn Function>, @@ -46,16 +46,24 @@ impl WasmModule for WasmtimeRuntime { // Scan all imports, find the matching host functions, and create stubs that adapt arguments // and results. let imports = resolve_imports( - &self.module, + self.module_wrapper.module(), &self.host_functions, self.heap_pages, self.allow_missing_func_imports, )?; + let instance_wrapper = + InstanceWrapper::new(&self.module_wrapper, &imports, self.heap_pages)?; + let heap_base = instance_wrapper.extract_heap_base()?; + let globals_snapshot = GlobalsSnapshot::take(&instance_wrapper)?; + Ok(Box::new(WasmtimeInstance { - module: self.module.clone(), + instance_wrapper: Rc::new(instance_wrapper), + module_wrapper: Arc::clone(&self.module_wrapper), imports, + globals_snapshot, heap_pages: self.heap_pages, + heap_base, })) } } @@ -63,9 +71,12 @@ impl WasmModule for WasmtimeRuntime { /// A `WasmInstance` implementation that reuses compiled module and spawns instances /// to execute the compiled code. pub struct WasmtimeInstance { - module: Arc, + module_wrapper: Arc, + instance_wrapper: Rc, + globals_snapshot: GlobalsSnapshot, imports: Imports, heap_pages: u32, + heap_base: u32, } // This is safe because `WasmtimeInstance` does not leak reference to `self.imports` @@ -74,23 +85,32 @@ unsafe impl Send for WasmtimeInstance {} impl WasmInstance for WasmtimeInstance { fn call(&self, method: &str, data: &[u8]) -> Result> { - // TODO: reuse the instance and reset globals after call - // https://github.com/paritytech/substrate/issues/5141 - let instance = Rc::new(InstanceWrapper::new(&self.module, &self.imports, self.heap_pages)?); - call_method( - instance, - method, + let entrypoint = self.instance_wrapper.resolve_entrypoint(method)?; + let allocator = FreeingBumpHeapAllocator::new(self.heap_base); + + self.module_wrapper + .data_segments_snapshot() + .apply(|offset, contents| { + self.instance_wrapper + .write_memory_from(Pointer::new(offset), contents) + })?; + + self.globals_snapshot.apply(&*self.instance_wrapper)?; + + perform_call( data, + Rc::clone(&self.instance_wrapper), + entrypoint, + allocator, ) } fn get_global_const(&self, name: &str) -> Result> { - let instance = InstanceWrapper::new(&self.module, &self.imports, self.heap_pages)?; + let instance = InstanceWrapper::new(&self.module_wrapper, &self.imports, self.heap_pages)?; instance.get_global_val(name) } } - /// Create a new `WasmtimeRuntime` given the code. This function performs translation from Wasm to /// machine code, which can be computationally heavy. pub fn create_runtime( @@ -105,30 +125,18 @@ pub fn create_runtime( let engine = Engine::new(&config); let store = Store::new(&engine); - let module = Module::new(&store, code) + + let module_wrapper = ModuleWrapper::new(&store, code) .map_err(|e| WasmError::Other(format!("cannot create module: {}", e)))?; Ok(WasmtimeRuntime { - module: Arc::new(module), + module_wrapper: Arc::new(module_wrapper), heap_pages: heap_pages as u32, allow_missing_func_imports, host_functions, }) } -/// Call a function inside a precompiled Wasm module. -fn call_method( - instance_wrapper: Rc, - method: &str, - data: &[u8], -) -> Result> { - let entrypoint = instance_wrapper.resolve_entrypoint(method)?; - let heap_base = instance_wrapper.extract_heap_base()?; - let allocator = FreeingBumpHeapAllocator::new(heap_base); - - perform_call(data, instance_wrapper, entrypoint, allocator) -} - fn perform_call( data: &[u8], instance_wrapper: Rc, -- GitLab From 25bdec1bde7fbfe74e5c714bc41b71edee2a807d Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Wed, 8 Apr 2020 20:11:30 +0200 Subject: [PATCH 191/300] Update .editorconfig (#5578) --- .editorconfig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.editorconfig b/.editorconfig index 47fde53b69..2b40ec32fa 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,3 +14,9 @@ indent_style=space indent_size=2 tab_width=8 end_of_line=lf + +[*.sh] +indent_style=space +indent_size=2 +tab_width=8 +end_of_line=lf -- GitLab From 50cd50232e78169b6374e37bbf83892f2e27b427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 8 Apr 2020 20:41:51 +0200 Subject: [PATCH 192/300] Add new RPC method to get the chain type (#5576) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add new RPC method to get the chain type This adds a new RPC method to get the chain type of the running chain. The chain type needs to be specified in the chain spec. This should make it easier for tools/UI to display extra information without needing to rely on parsing the chain name. * Update client/rpc-api/src/system/mod.rs Co-Authored-By: Tomasz Drwięga * Primitive crate * Feedback Co-authored-by: Tomasz Drwięga --- Cargo.lock | 12 +++++++ Cargo.toml | 1 + bin/node-template/node/src/chain_spec.rs | 8 +++-- bin/node/cli/src/chain_spec.rs | 7 +++- bin/utils/chain-spec-builder/Cargo.toml | 1 + bin/utils/chain-spec-builder/src/main.rs | 1 + client/chain-spec/Cargo.toml | 1 + client/chain-spec/src/chain_spec.rs | 20 ++++++++--- client/chain-spec/src/lib.rs | 8 +++-- client/rpc-api/Cargo.toml | 1 + client/rpc-api/src/system/helpers.rs | 7 ++-- client/rpc-api/src/system/mod.rs | 10 ++++-- client/rpc/Cargo.toml | 1 + client/rpc/src/system/mod.rs | 8 +++-- client/rpc/src/system/tests.rs | 17 +++++++--- client/service/src/builder.rs | 1 + client/service/src/lib.rs | 2 +- primitives/chain-spec/Cargo.toml | 13 ++++++++ primitives/chain-spec/src/lib.rs | 42 ++++++++++++++++++++++++ 19 files changed, 135 insertions(+), 26 deletions(-) create mode 100644 primitives/chain-spec/Cargo.toml create mode 100644 primitives/chain-spec/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index f9e4f913c6..9395f4a6df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -594,6 +594,7 @@ dependencies = [ "ansi_term 0.12.1", "node-cli", "rand 0.7.3", + "sc-chain-spec", "sc-keystore", "sp-core", "structopt", @@ -5841,6 +5842,7 @@ dependencies = [ "sc-telemetry", "serde", "serde_json", + "sp-chain-spec", "sp-core", "sp-runtime", ] @@ -6539,6 +6541,7 @@ dependencies = [ "serde_json", "sp-api", "sp-blockchain", + "sp-chain-spec", "sp-core", "sp-io", "sp-offchain", @@ -6568,6 +6571,7 @@ dependencies = [ "parking_lot 0.10.0", "serde", "serde_json", + "sp-chain-spec", "sp-core", "sp-rpc", "sp-runtime", @@ -7267,6 +7271,14 @@ dependencies = [ "sp-state-machine", ] +[[package]] +name = "sp-chain-spec" +version = "2.0.0-alpha.5" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "sp-consensus" version = "0.8.0-alpha.5" diff --git a/Cargo.toml b/Cargo.toml index 035ae7bc37..ab19142da6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -122,6 +122,7 @@ members = [ "primitives/consensus/pow", "primitives/consensus/vrf", "primitives/core", + "primitives/chain-spec", "primitives/debug-derive", "primitives/storage", "primitives/externalities", diff --git a/bin/node-template/node/src/chain_spec.rs b/bin/node-template/node/src/chain_spec.rs index 8ed91698eb..fb53edd9a1 100644 --- a/bin/node-template/node/src/chain_spec.rs +++ b/bin/node-template/node/src/chain_spec.rs @@ -3,10 +3,10 @@ use node_template_runtime::{ AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, SudoConfig, SystemConfig, WASM_BINARY, Signature }; -use sp_consensus_aura::sr25519::{AuthorityId as AuraId}; -use sp_finality_grandpa::{AuthorityId as GrandpaId}; -use sc_service; +use sp_consensus_aura::sr25519::AuthorityId as AuraId; +use sp_finality_grandpa::AuthorityId as GrandpaId; use sp_runtime::traits::{Verify, IdentifyAccount}; +use sc_service::ChainType; // Note this is the URL for the telemetry server //const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; @@ -42,6 +42,7 @@ pub fn development_config() -> ChainSpec { ChainSpec::from_genesis( "Development", "dev", + ChainType::Development, || testnet_genesis( vec![ authority_keys_from_seed("Alice"), @@ -67,6 +68,7 @@ pub fn local_testnet_config() -> ChainSpec { ChainSpec::from_genesis( "Local Testnet", "local_testnet", + ChainType::Local, || testnet_genesis( vec![ authority_keys_from_seed("Alice"), diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index 087977daaf..6d67c61381 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -27,7 +27,7 @@ use node_runtime::{ }; use node_runtime::Block; use node_runtime::constants::currency::*; -use sc_service; +use sc_service::ChainType; use hex_literal::hex; use sc_telemetry::TelemetryEndpoints; use grandpa_primitives::{AuthorityId as GrandpaId}; @@ -158,6 +158,7 @@ pub fn staging_testnet_config() -> ChainSpec { ChainSpec::from_genesis( "Staging Testnet", "staging_testnet", + ChainType::Live, staging_testnet_config_genesis, boot_nodes, Some(TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)]) @@ -338,6 +339,7 @@ pub fn development_config() -> ChainSpec { ChainSpec::from_genesis( "Development", "dev", + ChainType::Development, development_config_genesis, vec![], None, @@ -364,6 +366,7 @@ pub fn local_testnet_config() -> ChainSpec { ChainSpec::from_genesis( "Local Testnet", "local_testnet", + ChainType::Local, local_testnet_genesis, vec![], None, @@ -396,6 +399,7 @@ pub(crate) mod tests { ChainSpec::from_genesis( "Integration Test", "test", + ChainType::Development, local_testnet_genesis_instant_single, vec![], None, @@ -410,6 +414,7 @@ pub(crate) mod tests { ChainSpec::from_genesis( "Integration Test", "test", + ChainType::Development, local_testnet_genesis, vec![], None, diff --git a/bin/utils/chain-spec-builder/Cargo.toml b/bin/utils/chain-spec-builder/Cargo.toml index 9b03dd17b7..bab393a86a 100644 --- a/bin/utils/chain-spec-builder/Cargo.toml +++ b/bin/utils/chain-spec-builder/Cargo.toml @@ -11,6 +11,7 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] ansi_term = "0.12.1" sc-keystore = { version = "2.0.0-alpha.5", path = "../../../client/keystore" } +sc-chain-spec = { version = "2.0.0-alpha.5", path = "../../../client/chain-spec" } node-cli = { version = "2.0.0-alpha.5", path = "../../node/cli" } sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } rand = "0.7.2" diff --git a/bin/utils/chain-spec-builder/src/main.rs b/bin/utils/chain-spec-builder/src/main.rs index 5aa7e7fff7..1440187014 100644 --- a/bin/utils/chain-spec-builder/src/main.rs +++ b/bin/utils/chain-spec-builder/src/main.rs @@ -120,6 +120,7 @@ fn generate_chain_spec( let chain_spec = chain_spec::ChainSpec::from_genesis( "Custom", "custom", + sc_chain_spec::ChainType::Live, move || genesis_constructor(&authority_seeds, &endowed_accounts, &sudo_account), vec![], None, diff --git a/client/chain-spec/Cargo.toml b/client/chain-spec/Cargo.toml index 5d65cbd842..cf30ad6063 100644 --- a/client/chain-spec/Cargo.toml +++ b/client/chain-spec/Cargo.toml @@ -16,6 +16,7 @@ sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-chain-spec = { version = "2.0.0-alpha.5", path = "../../primitives/chain-spec" } sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } [package.metadata.docs.rs] diff --git a/client/chain-spec/src/chain_spec.rs b/client/chain-spec/src/chain_spec.rs index a7cf1d8aac..9f3a10ee89 100644 --- a/client/chain-spec/src/chain_spec.rs +++ b/client/chain-spec/src/chain_spec.rs @@ -25,8 +25,7 @@ use serde::{Serialize, Deserialize}; use sp_core::storage::{StorageKey, StorageData, ChildInfo, Storage, StorageChild}; use sp_runtime::BuildStorage; use serde_json as json; -use crate::RuntimeGenesis; -use crate::extension::GetExtension; +use crate::{RuntimeGenesis, ChainType, extension::GetExtension, Properties}; use sc_network::config::MultiaddrWithPeerId; use sc_telemetry::TelemetryEndpoints; @@ -137,6 +136,8 @@ enum Genesis { struct ClientSpec { name: String, id: String, + #[serde(default)] + chain_type: ChainType, boot_nodes: Vec, telemetry_endpoints: Option, protocol_id: Option, @@ -149,9 +150,6 @@ struct ClientSpec { genesis: serde::de::IgnoredAny, } -/// Arbitrary properties defined in chain spec as a JSON object -pub type Properties = json::map::Map; - /// A type denoting empty extensions. /// /// We use `Option` here since `()` is not flattenable by serde. @@ -219,6 +217,7 @@ impl ChainSpec { pub fn from_genesis G + 'static + Send + Sync>( name: &str, id: &str, + chain_type: ChainType, constructor: F, boot_nodes: Vec, telemetry_endpoints: Option, @@ -229,6 +228,7 @@ impl ChainSpec { let client_spec = ClientSpec { name: name.to_owned(), id: id.to_owned(), + chain_type, boot_nodes, telemetry_endpoints, protocol_id: protocol_id.map(str::to_owned), @@ -243,6 +243,11 @@ impl ChainSpec { genesis: GenesisSource::Factory(Arc::new(constructor)), } } + + /// Type of the chain. + fn chain_type(&self) -> ChainType { + self.client_spec.chain_type.clone() + } } impl ChainSpec { @@ -332,6 +337,10 @@ where ChainSpec::id(self) } + fn chain_type(&self) -> ChainType { + ChainSpec::chain_type(self) + } + fn telemetry_endpoints(&self) -> &Option { ChainSpec::telemetry_endpoints(self) } @@ -392,6 +401,7 @@ mod tests { ).unwrap(); assert_eq!(spec1.as_json(false), spec2.as_json(false)); + assert_eq!(spec2.chain_type(), ChainType::Live) } #[derive(Debug, Serialize, Deserialize)] diff --git a/client/chain-spec/src/lib.rs b/client/chain-spec/src/lib.rs index b7875fdbb4..de83e170e0 100644 --- a/client/chain-spec/src/lib.rs +++ b/client/chain-spec/src/lib.rs @@ -107,13 +107,13 @@ //! pub type MyChainSpec = GenericChainSpec; //! ``` - mod chain_spec; mod extension; -pub use chain_spec::{ChainSpec as GenericChainSpec, Properties, NoExtension}; +pub use chain_spec::{ChainSpec as GenericChainSpec, NoExtension}; pub use extension::{Group, Fork, Forks, Extension, GetExtension, get_extension}; pub use sc_chain_spec_derive::{ChainSpecExtension, ChainSpecGroup}; +pub use sp_chain_spec::{Properties, ChainType}; use serde::{Serialize, de::DeserializeOwned}; use sp_runtime::BuildStorage; @@ -124,12 +124,14 @@ use sc_telemetry::TelemetryEndpoints; pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {} impl RuntimeGenesis for T {} -/// Common interface to `GenericChainSpec` +/// Common interface of a chain specification. pub trait ChainSpec: BuildStorage + Send { /// Spec name. fn name(&self) -> &str; /// Spec id. fn id(&self) -> &str; + /// Type of the chain. + fn chain_type(&self) -> ChainType; /// A list of bootnode addresses. fn boot_nodes(&self) -> &[MultiaddrWithPeerId]; /// Telemetry endpoints (if any) diff --git a/client/rpc-api/Cargo.toml b/client/rpc-api/Cargo.toml index c5043b5b07..10b4b1746e 100644 --- a/client/rpc-api/Cargo.toml +++ b/client/rpc-api/Cargo.toml @@ -21,6 +21,7 @@ parking_lot = "0.10.0" sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } sp-version = { version = "2.0.0-alpha.5", path = "../../primitives/version" } sp-runtime = { path = "../../primitives/runtime" , version = "2.0.0-alpha.5"} +sp-chain-spec = { path = "../../primitives/chain-spec" , version = "2.0.0-alpha.5"} serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } diff --git a/client/rpc-api/src/system/helpers.rs b/client/rpc-api/src/system/helpers.rs index 80718cf487..46461d6988 100644 --- a/client/rpc-api/src/system/helpers.rs +++ b/client/rpc-api/src/system/helpers.rs @@ -18,10 +18,7 @@ use std::fmt; use serde::{Serialize, Deserialize}; -use serde_json::{Value, map::Map}; - -/// Node properties -pub type Properties = Map; +use sp_chain_spec::{Properties, ChainType}; /// Running node's static details. #[derive(Clone, Debug)] @@ -34,6 +31,8 @@ pub struct SystemInfo { pub chain_name: String, /// A custom set of properties defined in the chain spec. pub properties: Properties, + /// The type of this chain. + pub chain_type: ChainType, } /// Health struct returned by the RPC diff --git a/client/rpc-api/src/system/mod.rs b/client/rpc-api/src/system/mod.rs index f12a11e0b3..25f147b694 100644 --- a/client/rpc-api/src/system/mod.rs +++ b/client/rpc-api/src/system/mod.rs @@ -25,7 +25,7 @@ use futures::{future::BoxFuture, compat::Compat}; use self::error::Result as SystemResult; -pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo, NodeRole}; +pub use self::helpers::{SystemInfo, Health, PeerInfo, NodeRole}; pub use self::gen_client::Client as SystemClient; /// Substrate system RPC API @@ -39,13 +39,17 @@ pub trait SystemApi { #[rpc(name = "system_version")] fn system_version(&self) -> SystemResult; - /// Get the chain's type. Given as a string identifier. + /// Get the chain's name. Given as a string identifier. #[rpc(name = "system_chain")] fn system_chain(&self) -> SystemResult; + /// Get the chain's type. + #[rpc(name = "system_chainType")] + fn system_type(&self) -> SystemResult; + /// Get a custom set of properties as a JSON object, defined in the chain spec. #[rpc(name = "system_properties")] - fn system_properties(&self) -> SystemResult; + fn system_properties(&self) -> SystemResult; /// Return health status of the node. /// diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index 7092959b83..f852c452d7 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -27,6 +27,7 @@ sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } sp-rpc = { version = "2.0.0-alpha.5", path = "../../primitives/rpc" } sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } +sp-chain-spec = { version = "2.0.0-alpha.5", path = "../../primitives/chain-spec" } sc-executor = { version = "0.8.0-alpha.5", path = "../executor" } sc-block-builder = { version = "0.8.0-alpha.5", path = "../../client/block-builder" } sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } diff --git a/client/rpc/src/system/mod.rs b/client/rpc/src/system/mod.rs index 9565992cf4..e18d4d09a1 100644 --- a/client/rpc/src/system/mod.rs +++ b/client/rpc/src/system/mod.rs @@ -28,7 +28,7 @@ use sp_runtime::traits::{self, Header as HeaderT}; use self::error::Result; pub use sc_rpc_api::system::*; -pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo, NodeRole}; +pub use self::helpers::{SystemInfo, Health, PeerInfo, NodeRole}; pub use self::gen_client::Client as SystemClient; /// System API implementation @@ -82,7 +82,11 @@ impl SystemApi::Number> for Sy Ok(self.info.chain_name.clone()) } - fn system_properties(&self) -> Result { + fn system_type(&self) -> Result { + Ok(self.info.chain_type.clone()) + } + + fn system_properties(&self) -> Result { Ok(self.info.properties.clone()) } diff --git a/client/rpc/src/system/tests.rs b/client/rpc/src/system/tests.rs index d45894743c..f0331f50ed 100644 --- a/client/rpc/src/system/tests.rs +++ b/client/rpc/src/system/tests.rs @@ -105,6 +105,7 @@ fn api>>(sync: T) -> System { impl_version: "0.2.0".into(), chain_name: "testchain".into(), properties: Default::default(), + chain_type: Default::default(), }, tx) } @@ -117,7 +118,7 @@ fn wait_receiver(rx: Receiver) -> T { fn system_name_works() { assert_eq!( api(None).system_name().unwrap(), - "testclient".to_owned() + "testclient".to_owned(), ); } @@ -125,7 +126,7 @@ fn system_name_works() { fn system_version_works() { assert_eq!( api(None).system_version().unwrap(), - "0.2.0".to_owned() + "0.2.0".to_owned(), ); } @@ -133,7 +134,7 @@ fn system_version_works() { fn system_chain_works() { assert_eq!( api(None).system_chain().unwrap(), - "testchain".to_owned() + "testchain".to_owned(), ); } @@ -141,7 +142,15 @@ fn system_chain_works() { fn system_properties_works() { assert_eq!( api(None).system_properties().unwrap(), - serde_json::map::Map::new() + serde_json::map::Map::new(), + ); +} + +#[test] +fn system_type_works() { + assert_eq!( + api(None).system_type().unwrap(), + Default::default(), ); } diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 0586a61a89..0eefbe730f 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -1016,6 +1016,7 @@ ServiceBuilder< impl_name: config.impl_name.into(), impl_version: config.impl_version.into(), properties: chain_spec.properties().clone(), + chain_type: chain_spec.chain_type().clone(), }; let subscriptions = sc_rpc::Subscriptions::new(Arc::new(tasks_builder.spawn_handle())); diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 16b1d0d718..d5db64ea46 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -62,7 +62,7 @@ pub use self::builder::{ pub use config::{Configuration, Role, PruningMode, DatabaseConfig}; pub use sc_chain_spec::{ ChainSpec, GenericChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension, - NoExtension, + NoExtension, ChainType, }; pub use sp_transaction_pool::{TransactionPool, InPoolTransaction, error::IntoPoolError}; pub use sc_transaction_pool::txpool::Options as TransactionPoolOptions; diff --git a/primitives/chain-spec/Cargo.toml b/primitives/chain-spec/Cargo.toml new file mode 100644 index 0000000000..62d64bf614 --- /dev/null +++ b/primitives/chain-spec/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "sp-chain-spec" +version = "2.0.0-alpha.5" +authors = ["Parity Technologies "] +edition = "2018" +license = "GPL-3.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "Substrate chain configurations types." + +[dependencies] +serde = { version = "1.0.101", features = ["derive"] } +serde_json = "1.0.41" diff --git a/primitives/chain-spec/src/lib.rs b/primitives/chain-spec/src/lib.rs new file mode 100644 index 0000000000..13ebc09b6c --- /dev/null +++ b/primitives/chain-spec/src/lib.rs @@ -0,0 +1,42 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Types and traits related to chain specifications. + +/// The type of a chain. +/// +/// This can be used by tools to determine the type of a chain for displaying +/// additional information or enabling additional features. +#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)] +pub enum ChainType { + /// A development chain that runs mainly on one node. + Development, + /// A local chain that runs locally on multiple nodes for testing purposes. + Local, + /// A live chain. + Live, + /// Some custom chain type. + Custom(String), +} + +impl Default for ChainType { + fn default() -> Self { + Self::Live + } +} + +/// Arbitrary properties defined in chain spec as a JSON object +pub type Properties = serde_json::map::Map; -- GitLab From 77fd258408abc0bc6cd0a786c8af004edbefc0a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 8 Apr 2020 22:20:47 +0200 Subject: [PATCH 193/300] Don't fail the build when no git is found (#5589) --- utils/build-script-utils/src/version.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/utils/build-script-utils/src/version.rs b/utils/build-script-utils/src/version.rs index d41538707c..01a97c6f38 100644 --- a/utils/build-script-utils/src/version.rs +++ b/utils/build-script-utils/src/version.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use platforms::*; -use std::process::Command; +use std::{borrow::Cow, process::Command}; /// Generate the `cargo:` key output pub fn generate_cargo_keys() { @@ -23,15 +23,22 @@ pub fn generate_cargo_keys() { .args(&["rev-parse", "--short", "HEAD"]) .output(); - match output { + let commit = match output { Ok(o) if o.status.success() => { let sha = String::from_utf8_lossy(&o.stdout).trim().to_owned(); - - println!("cargo:rustc-env=SUBSTRATE_CLI_IMPL_VERSION={}", get_version(sha.as_str())) + Cow::from(sha) } - Ok(o) => eprintln!("cargo:warning=Git command failed with status: {}", o.status), - Err(err) => eprintln!("cargo:warning=Failed to execute git command: {}", err), - } + Ok(o) => { + println!("cargo:warning=Git command failed with status: {}", o.status); + Cow::from("unknown-commit") + }, + Err(err) => { + println!("cargo:warning=Failed to execute git command: {}", err); + Cow::from("unknown-commit") + }, + }; + + println!("cargo:rustc-env=SUBSTRATE_CLI_IMPL_VERSION={}", get_version(&commit)) } fn get_platform() -> String { -- GitLab From b5e8592d43b574fcaa3d5121a11c696cf80ded79 Mon Sep 17 00:00:00 2001 From: Stanislav Tkach Date: Thu, 9 Apr 2020 01:16:49 +0300 Subject: [PATCH 194/300] Move contracts wasm test code into separate files (#5337) * Move contracts wasm test code into separate files * Move crypto_hashes into a separate file * Load wasm code at runtime * Move wasm files * Fix wasm formatting * Update crypto_hashes file --- frame/contracts/src/tests.rs | 1242 +---------------- frame/contracts/tests/caller_contract.wat | 275 ++++ .../tests/check_default_rent_allowance.wat | 47 + frame/contracts/tests/crypto_hashes.wat | 80 ++ .../contracts/tests/destroy_and_transfer.wat | 148 ++ frame/contracts/tests/dispatch_call.wat | 14 + .../tests/dispatch_call_then_trap.wat | 15 + frame/contracts/tests/drain.wat | 54 + frame/contracts/tests/get_runtime_storage.wat | 74 + frame/contracts/tests/restoration.wat | 56 + .../contracts/tests/return_from_start_fn.wat | 27 + frame/contracts/tests/return_with_data.wat | 39 + frame/contracts/tests/run_out_of_gas.wat | 7 + frame/contracts/tests/self_destruct.wat | 72 + .../tests/self_destructing_constructor.wat | 54 + frame/contracts/tests/set_rent.wat | 101 ++ frame/contracts/tests/storage_size.wat | 60 + 17 files changed, 1169 insertions(+), 1196 deletions(-) create mode 100644 frame/contracts/tests/caller_contract.wat create mode 100644 frame/contracts/tests/check_default_rent_allowance.wat create mode 100644 frame/contracts/tests/crypto_hashes.wat create mode 100644 frame/contracts/tests/destroy_and_transfer.wat create mode 100644 frame/contracts/tests/dispatch_call.wat create mode 100644 frame/contracts/tests/dispatch_call_then_trap.wat create mode 100644 frame/contracts/tests/drain.wat create mode 100644 frame/contracts/tests/get_runtime_storage.wat create mode 100644 frame/contracts/tests/restoration.wat create mode 100644 frame/contracts/tests/return_from_start_fn.wat create mode 100644 frame/contracts/tests/return_with_data.wat create mode 100644 frame/contracts/tests/run_out_of_gas.wat create mode 100644 frame/contracts/tests/self_destruct.wat create mode 100644 frame/contracts/tests/self_destructing_constructor.wat create mode 100644 frame/contracts/tests/set_rent.wat create mode 100644 frame/contracts/tests/storage_size.wat diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index f45b375476..1a5aa08454 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -382,39 +382,10 @@ fn account_removal_does_not_remove_storage() { }); } -const CODE_RETURN_FROM_START_FN: &str = r#" -(module - (import "env" "ext_return" (func $ext_return (param i32 i32))) - (import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (start $start) - (func $start - (call $ext_deposit_event - (i32.const 0) ;; The topics buffer - (i32.const 0) ;; The topics buffer's length - (i32.const 8) ;; The data buffer - (i32.const 4) ;; The data buffer's length - ) - (call $ext_return - (i32.const 8) - (i32.const 4) - ) - (unreachable) - ) - - (func (export "call") - (unreachable) - ) - (func (export "deploy")) - - (data (i32.const 8) "\01\02\03\04") -) -"#; - #[test] fn instantiate_and_call_and_deposit_event() { - let (wasm, code_hash) = compile_module::(CODE_RETURN_FROM_START_FN).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("return_from_start_fn.wat")) + .unwrap(); ExtBuilder::default().existential_deposit(100).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); @@ -480,23 +451,6 @@ fn instantiate_and_call_and_deposit_event() { }); } -const CODE_DISPATCH_CALL: &str = r#" -(module - (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "call") - (call $ext_dispatch_call - (i32.const 8) ;; Pointer to the start of encoded call buffer - (i32.const 11) ;; Length of the buffer - ) - ) - (func (export "deploy")) - - (data (i32.const 8) "\00\00\03\00\00\00\00\00\00\00\C8") -) -"#; - #[test] fn dispatch_call() { // This test can fail due to the encoding changes. In case it becomes too annoying @@ -504,7 +458,8 @@ fn dispatch_call() { let encoded = Encode::encode(&Call::Balances(pallet_balances::Call::transfer(CHARLIE, 50))); assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); - let (wasm, code_hash) = compile_module::(CODE_DISPATCH_CALL).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("dispatch_call.wat")) + .unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); @@ -617,24 +572,6 @@ fn dispatch_call() { }); } -const CODE_DISPATCH_CALL_THEN_TRAP: &str = r#" -(module - (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "call") - (call $ext_dispatch_call - (i32.const 8) ;; Pointer to the start of encoded call buffer - (i32.const 11) ;; Length of the buffer - ) - (unreachable) ;; trap so that the top level transaction fails - ) - (func (export "deploy")) - - (data (i32.const 8) "\00\00\03\00\00\00\00\00\00\00\C8") -) -"#; - #[test] fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { // This test can fail due to the encoding changes. In case it becomes too annoying @@ -642,7 +579,8 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { let encoded = Encode::encode(&Call::Balances(pallet_balances::Call::transfer(CHARLIE, 50))); assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); - let (wasm, code_hash) = compile_module::(CODE_DISPATCH_CALL_THEN_TRAP).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("dispatch_call_then_trap.wat")) + .unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); @@ -732,19 +670,10 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { }); } -const CODE_RUN_OUT_OF_GAS: &str = r#" -(module - (func (export "call") - (loop $inf (br $inf)) ;; just run out of gas - (unreachable) - ) - (func (export "deploy")) -) -"#; - #[test] fn run_out_of_gas() { - let (wasm, code_hash) = compile_module::(CODE_RUN_OUT_OF_GAS).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("run_out_of_gas.wat")) + .unwrap(); ExtBuilder::default() .existential_deposit(50) @@ -777,110 +706,6 @@ fn run_out_of_gas() { }); } -const CODE_SET_RENT: &str = r#" -(module - (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) - (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) - (import "env" "ext_clear_storage" (func $ext_clear_storage (param i32))) - (import "env" "ext_set_rent_allowance" (func $ext_set_rent_allowance (param i32 i32))) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; insert a value of 4 bytes into storage - (func $call_0 - (call $ext_set_storage - (i32.const 1) - (i32.const 0) - (i32.const 4) - ) - ) - - ;; remove the value inserted by call_1 - (func $call_1 - (call $ext_clear_storage - (i32.const 1) - ) - ) - - ;; transfer 50 to ALICE - (func $call_2 - (call $ext_dispatch_call - (i32.const 68) - (i32.const 11) - ) - ) - - ;; do nothing - (func $call_else) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - ;; Dispatch the call according to input size - (func (export "call") - (local $input_size i32) - (set_local $input_size - (call $ext_scratch_size) - ) - (block $IF_ELSE - (block $IF_2 - (block $IF_1 - (block $IF_0 - (br_table $IF_0 $IF_1 $IF_2 $IF_ELSE - (get_local $input_size) - ) - (unreachable) - ) - (call $call_0) - return - ) - (call $call_1) - return - ) - (call $call_2) - return - ) - (call $call_else) - ) - - ;; Set into storage a 4 bytes value - ;; Set call set_rent_allowance with input - (func (export "deploy") - (local $input_size i32) - (set_local $input_size - (call $ext_scratch_size) - ) - (call $ext_set_storage - (i32.const 0) - (i32.const 0) - (i32.const 4) - ) - (call $ext_scratch_read - (i32.const 0) - (i32.const 0) - (get_local $input_size) - ) - (call $ext_set_rent_allowance - (i32.const 0) - (get_local $input_size) - ) - ) - - ;; Encoding of 10 in balance - (data (i32.const 0) "\28") - - ;; Encoding of call transfer 50 to CHARLIE - (data (i32.const 68) "\00\00\03\00\00\00\00\00\00\00\C8") -) -"#; - /// Input data for each call in set_rent code mod call { pub fn set_storage_4_byte() -> Vec { vec![] } @@ -898,7 +723,7 @@ fn test_set_rent_code_and_hash() { let encoded = Encode::encode(&Call::Balances(pallet_balances::Call::transfer(CHARLIE, 50))); assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); - let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("set_rent.wat")).unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); @@ -928,7 +753,7 @@ fn test_set_rent_code_and_hash() { #[test] fn storage_size() { - let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("set_rent.wat")).unwrap(); // Storage size ExtBuilder::default().existential_deposit(50).build().execute_with(|| { @@ -966,7 +791,7 @@ fn initialize_block(number: u64) { #[test] fn deduct_blocks() { - let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("set_rent.wat")).unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create @@ -1060,7 +885,7 @@ fn claim_surcharge_malus() { /// Claim surcharge with the given trigger_call at the given blocks. /// If `removes` is true then assert that the contract is a tombstone. fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) { - let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("set_rent.wat")).unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create @@ -1092,7 +917,7 @@ fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) /// * if allowance is exceeded /// * if balance is reached and balance < subsistence threshold fn removals(trigger_call: impl Fn() -> bool) { - let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("set_rent.wat")).unwrap(); // Balance reached and superior to subsistence threshold ExtBuilder::default().existential_deposit(50).build().execute_with(|| { @@ -1207,7 +1032,7 @@ fn removals(trigger_call: impl Fn() -> bool) { #[test] fn call_removed_contract() { - let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("set_rent.wat")).unwrap(); // Balance reached and superior to subsistence threshold ExtBuilder::default().existential_deposit(50).build().execute_with(|| { @@ -1249,59 +1074,10 @@ fn call_removed_contract() { }) } -const CODE_CHECK_DEFAULT_RENT_ALLOWANCE: &str = r#" -(module - (import "env" "ext_rent_allowance" (func $ext_rent_allowance)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call")) - - (func (export "deploy") - ;; fill the scratch buffer with the rent allowance. - (call $ext_rent_allowance) - - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to >::max_value(). - (call $assert - (i64.eq - (i64.load - (i32.const 8) - ) - (i64.const 0xFFFFFFFFFFFFFFFF) - ) - ) - ) -) -"#; - #[test] fn default_rent_allowance_on_instantiate() { - let (wasm, code_hash) = compile_module::(CODE_CHECK_DEFAULT_RENT_ALLOWANCE).unwrap(); + let (wasm, code_hash) = compile_module::( + &load_wasm("check_default_rent_allowance.wat")).unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create @@ -1331,65 +1107,6 @@ fn default_rent_allowance_on_instantiate() { }); } -const CODE_RESTORATION: &str = r#" -(module - (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) - (import "env" "ext_restore_to" (func $ext_restore_to (param i32 i32 i32 i32 i32 i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "call") - (call $ext_restore_to - ;; Pointer and length of the encoded dest buffer. - (i32.const 256) - (i32.const 8) - ;; Pointer and length of the encoded code hash buffer - (i32.const 264) - (i32.const 32) - ;; Pointer and length of the encoded rent_allowance buffer - (i32.const 296) - (i32.const 8) - ;; Pointer and number of items in the delta buffer. - ;; This buffer specifies multiple keys for removal before restoration. - (i32.const 100) - (i32.const 1) - ) - ) - (func (export "deploy") - ;; Data to restore - (call $ext_set_storage - (i32.const 0) - (i32.const 0) - (i32.const 4) - ) - - ;; ACL - (call $ext_set_storage - (i32.const 100) - (i32.const 0) - (i32.const 4) - ) - ) - - ;; Data to restore - (data (i32.const 0) "\28") - - ;; Buffer that has ACL storage keys. - (data (i32.const 100) "\01") - - ;; Address of bob - (data (i32.const 256) "\02\00\00\00\00\00\00\00") - - ;; Code hash of SET_RENT - (data (i32.const 264) - "\c2\1c\41\10\a5\22\d8\59\1c\4c\77\35\dd\2d\bf\a1" - "\13\0b\50\93\76\9b\92\31\97\b7\c5\74\26\aa\38\2a" - ) - - ;; Rent allowance - (data (i32.const 296) "\32\00\00\00\00\00\00\00") -) -"#; - #[test] fn restorations_dirty_storage_and_different_storage() { restoration(true, true); @@ -1411,9 +1128,10 @@ fn restoration_success() { } fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: bool) { - let (set_rent_wasm, set_rent_code_hash) = compile_module::(CODE_SET_RENT).unwrap(); + let (set_rent_wasm, set_rent_code_hash) = + compile_module::(&load_wasm("set_rent.wat")).unwrap(); let (restoration_wasm, restoration_code_hash) = - compile_module::(CODE_RESTORATION).unwrap(); + compile_module::(&load_wasm("restoration.wat")).unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); @@ -1625,72 +1343,10 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: }); } -const CODE_STORAGE_SIZE: &str = r#" -(module - (import "env" "ext_get_storage" (func $ext_get_storage (param i32) (result i32))) - (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 16 16)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 4) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 32) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 4) ;; Count of bytes to copy. - ) - - ;; place a garbage value in storage, the size of which is specified by the call input. - (call $ext_set_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 0) ;; Pointer to value - (i32.load (i32.const 32)) ;; Size of value - ) - - (call $assert - (i32.eq - (call $ext_get_storage - (i32.const 0) ;; Pointer to storage key - ) - (i32.const 0) - ) - ) - - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.load (i32.const 32)) - ) - ) - ) - - (func (export "deploy")) - - (data (i32.const 0) "\01") ;; Storage key (32 B) -) -"#; - #[test] fn storage_max_value_limit() { - let (wasm, code_hash) = compile_module::(CODE_STORAGE_SIZE).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("storage_size.wat")) + .unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create @@ -1731,330 +1387,12 @@ fn storage_max_value_limit() { }); } -const CODE_RETURN_WITH_DATA: &str = r#" -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; Deploy routine is the same as call. - (func (export "deploy") (result i32) - (call $call) - ) - - ;; Call reads the first 4 bytes (LE) as the exit status and returns the rest as output data. - (func $call (export "call") (result i32) - (local $buf_size i32) - (local $exit_status i32) - - ;; Find out the size of the scratch buffer - (set_local $buf_size (call $ext_scratch_size)) - - ;; Copy scratch buffer into this contract memory. - (call $ext_scratch_read - (i32.const 0) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (get_local $buf_size) ;; Count of bytes to copy. - ) - - ;; Copy all but the first 4 bytes of the input data as the output data. - (call $ext_scratch_write - (i32.const 4) ;; Pointer to the data to return. - (i32.sub ;; Count of bytes to copy. - (get_local $buf_size) - (i32.const 4) - ) - ) - - ;; Return the first 4 bytes of the input data as the exit status. - (i32.load (i32.const 0)) - ) -) -"#; - -const CODE_CALLER_CONTRACT: &str = r#" -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_balance" (func $ext_balance)) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_println" (func $ext_println (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func $current_balance (param $sp i32) (result i64) - (call $ext_balance) - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 8)) - ) - (call $ext_scratch_read - (i32.sub (get_local $sp) (i32.const 8)) - (i32.const 0) - (i32.const 8) - ) - (i64.load (i32.sub (get_local $sp) (i32.const 8))) - ) - - (func (export "deploy")) - - (func (export "call") - (local $sp i32) - (local $exit_code i32) - (local $balance i64) - - ;; Input data is the code hash of the contract to be deployed. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 32) - ) - ) - - ;; Copy code hash from scratch buffer into this contract's memory. - (call $ext_scratch_read - (i32.const 24) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 32) ;; Count of bytes to copy. - ) - - ;; Read current balance into local variable. - (set_local $sp (i32.const 1024)) - (set_local $balance - (call $current_balance (get_local $sp)) - ) - - ;; Fail to deploy the contract since it returns a non-zero exit status. - (set_local $exit_code - (call $ext_instantiate - (i32.const 24) ;; Pointer to the code hash. - (i32.const 32) ;; Length of the code hash. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 9) ;; Pointer to input data buffer address - (i32.const 7) ;; Length of input data buffer - ) - ) - - ;; Check non-zero exit status. - (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x11)) - ) - - ;; Check that scratch buffer is empty since contract instantiation failed. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 0)) - ) - - ;; Check that balance has not changed. - (call $assert - (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) - ) - - ;; Fail to deploy the contract due to insufficient gas. - (set_local $exit_code - (call $ext_instantiate - (i32.const 24) ;; Pointer to the code hash. - (i32.const 32) ;; Length of the code hash. - (i64.const 200) ;; How much gas to devote for the execution. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - ) - ) - - ;; Check for special trap exit status. - (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x0100)) - ) - - ;; Check that scratch buffer is empty since contract instantiation failed. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 0)) - ) - - ;; Check that balance has not changed. - (call $assert - (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) - ) - - ;; Deploy the contract successfully. - (set_local $exit_code - (call $ext_instantiate - (i32.const 24) ;; Pointer to the code hash. - (i32.const 32) ;; Length of the code hash. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - ) - ) - - ;; Check for success exit status. - (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x00)) - ) - - ;; Check that scratch buffer contains the address of the new contract. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 8)) - ) - - ;; Copy contract address from scratch buffer into this contract's memory. - (call $ext_scratch_read - (i32.const 16) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; Check that balance has been deducted. - (set_local $balance - (i64.sub (get_local $balance) (i64.load (i32.const 0))) - ) - (call $assert - (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) - ) - - ;; Call the new contract and expect it to return failing exit code. - (set_local $exit_code - (call $ext_call - (i32.const 16) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 9) ;; Pointer to input data buffer address - (i32.const 7) ;; Length of input data buffer - ) - ) - - ;; Check non-zero exit status. - (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x11)) - ) - - ;; Check that scratch buffer contains the expected return data. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 3)) - ) - (i32.store - (i32.sub (get_local $sp) (i32.const 4)) - (i32.const 0) - ) - (call $ext_scratch_read - (i32.sub (get_local $sp) (i32.const 4)) - (i32.const 0) - (i32.const 3) - ) - (call $assert - (i32.eq - (i32.load (i32.sub (get_local $sp) (i32.const 4))) - (i32.const 0x00776655) - ) - ) - - ;; Check that balance has not changed. - (call $assert - (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) - ) - - ;; Fail to call the contract due to insufficient gas. - (set_local $exit_code - (call $ext_call - (i32.const 16) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. - (i64.const 100) ;; How much gas to devote for the execution. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - ) - ) - - ;; Check for special trap exit status. - (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x0100)) - ) - - ;; Check that scratch buffer is empty since call trapped. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 0)) - ) - - ;; Check that balance has not changed. - (call $assert - (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) - ) - - ;; Call the contract successfully. - (set_local $exit_code - (call $ext_call - (i32.const 16) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - ) - ) - - ;; Check for success exit status. - (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x00)) - ) - - ;; Check that scratch buffer contains the expected return data. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 4)) - ) - (i32.store - (i32.sub (get_local $sp) (i32.const 4)) - (i32.const 0) - ) - (call $ext_scratch_read - (i32.sub (get_local $sp) (i32.const 4)) - (i32.const 0) - (i32.const 4) - ) - (call $assert - (i32.eq - (i32.load (i32.sub (get_local $sp) (i32.const 4))) - (i32.const 0x77665544) - ) - ) - - ;; Check that balance has been deducted. - (set_local $balance - (i64.sub (get_local $balance) (i64.load (i32.const 0))) - ) - (call $assert - (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) - ) - ) - - (data (i32.const 0) "\00\80") ;; The value to transfer on instantiation and calls. - ;; Chosen to be greater than existential deposit. - (data (i32.const 8) "\00\11\22\33\44\55\66\77") ;; The input data to instantiations and calls. -) -"#; - #[test] fn deploy_and_call_other_contract() { - let (callee_wasm, callee_code_hash) = compile_module::(CODE_RETURN_WITH_DATA).unwrap(); - let (caller_wasm, caller_code_hash) = compile_module::(CODE_CALLER_CONTRACT).unwrap(); + let (callee_wasm, callee_code_hash) = + compile_module::(&load_wasm("return_with_data.wat")).unwrap(); + let (caller_wasm, caller_code_hash) = + compile_module::(&load_wasm("caller_contract.wat")).unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create @@ -2084,7 +1422,8 @@ fn deploy_and_call_other_contract() { #[test] fn deploy_works_without_gas_price() { - let (wasm, code_hash) = compile_module::(CODE_GET_RUNTIME_STORAGE).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("get_runtime_storage.wat")) + .unwrap(); ExtBuilder::default().existential_deposit(50).gas_price(0).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); @@ -2098,66 +1437,9 @@ fn deploy_works_without_gas_price() { }); } -const CODE_DRAIN: &str = r#" -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_balance" (func $ext_balance)) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - ;; Send entire remaining balance to the 0 address. - (call $ext_balance) - - ;; Balance should be encoded as a u64. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; Read balance into memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer to write balance to - (i32.const 0) ;; Offset into scratch buffer - (i32.const 8) ;; Length of encoded balance - ) - - ;; Self-destruct by sending full balance to the 0 address. - (call $assert - (i32.eq - (call $ext_call - (i32.const 0) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - ) -) -"#; - #[test] fn cannot_self_destruct_through_draning() { - let (wasm, code_hash) = compile_module::(CODE_DRAIN).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("drain.wat")).unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); @@ -2192,84 +1474,10 @@ fn cannot_self_destruct_through_draning() { }); } -const CODE_SELF_DESTRUCT: &str = r#" -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_address" (func $ext_address)) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_terminate" (func $ext_terminate (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - ;; If the input data is not empty, then recursively call self with empty input data. - ;; This should trap instead of self-destructing since a contract cannot be removed live in - ;; the execution stack cannot be removed. If the recursive call traps, then trap here as - ;; well. - (if (call $ext_scratch_size) - (then - (call $ext_address) - - ;; Expect address to be 8 bytes. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; Read own address into memory. - (call $ext_scratch_read - (i32.const 16) ;; Pointer to write address to - (i32.const 0) ;; Offset into scratch buffer - (i32.const 8) ;; Length of encoded address - ) - - ;; Recursively call self with empty input data. - (call $assert - (i32.eq - (call $ext_call - (i32.const 16) ;; Pointer to own address - (i32.const 8) ;; Length of own address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - ) - (else - ;; Try to terminate and give balance to django. - (call $ext_terminate - (i32.const 32) ;; Pointer to beneficiary address - (i32.const 8) ;; Length of beneficiary address - ) - (unreachable) ;; ext_terminate never returns - ) - ) - ) - ;; Address of django - (data (i32.const 32) "\04\00\00\00\00\00\00\00") -) -"#; - #[test] fn cannot_self_destruct_while_live() { - let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("self_destruct.wat")) + .unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); @@ -2312,7 +1520,8 @@ fn cannot_self_destruct_while_live() { #[test] fn self_destruct_works() { - let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("self_destruct.wat")) + .unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); @@ -2352,163 +1561,14 @@ fn self_destruct_works() { }); } -const CODE_DESTROY_AND_TRANSFER: &str = r#" -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_get_storage" (func $ext_get_storage (param i32) (result i32))) - (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "deploy") - ;; Input data is the code hash of the contract to be deployed. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 32) - ) - ) - - ;; Copy code hash from scratch buffer into this contract's memory. - (call $ext_scratch_read - (i32.const 48) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 32) ;; Count of bytes to copy. - ) - - ;; Deploy the contract with the provided code hash. - (call $assert - (i32.eq - (call $ext_instantiate - (i32.const 48) ;; Pointer to the code hash. - (i32.const 32) ;; Length of the code hash. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - - ;; Read the address of the instantiated contract into memory. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - (call $ext_scratch_read - (i32.const 80) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; Store the return address. - (call $ext_set_storage - (i32.const 16) ;; Pointer to the key - (i32.const 80) ;; Pointer to the value - (i32.const 8) ;; Length of the value - ) - ) - - (func (export "call") - ;; Read address of destination contract from storage. - (call $assert - (i32.eq - (call $ext_get_storage - (i32.const 16) ;; Pointer to the key - ) - (i32.const 0) - ) - ) - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - (call $ext_scratch_read - (i32.const 80) ;; The pointer where to store the contract address. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; Calling the destination contract with non-empty input data should fail. - (call $assert - (i32.eq - (call $ext_call - (i32.const 80) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 1) ;; Length of input data buffer - ) - (i32.const 0x0100) - ) - ) - - ;; Call the destination contract regularly, forcing it to self-destruct. - (call $assert - (i32.eq - (call $ext_call - (i32.const 80) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - - ;; Calling the destination address with non-empty input data should now work since the - ;; contract has been removed. Also transfer a balance to the address so we can ensure this - ;; does not keep the contract alive. - (call $assert - (i32.eq - (call $ext_call - (i32.const 80) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 1) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - ) - - (data (i32.const 0) "\00\00\01") ;; Endowment to send when creating contract. - (data (i32.const 8) "") ;; Value to send when calling contract. - (data (i32.const 16) "") ;; The key to store the contract address under. -) -"#; - // This tests that one contract cannot prevent another from self-destructing by sending it // additional funds after it has been drained. #[test] fn destroy_contract_and_transfer_funds() { - let (callee_wasm, callee_code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); - let (caller_wasm, caller_code_hash) = compile_module::(CODE_DESTROY_AND_TRANSFER).unwrap(); + let (callee_wasm, callee_code_hash) = + compile_module::(&load_wasm("self_destruct.wat")).unwrap(); + let (caller_wasm, caller_code_hash) = + compile_module::(&load_wasm("destroy_and_transfer.wat")).unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create @@ -2546,66 +1606,10 @@ fn destroy_contract_and_transfer_funds() { }); } -const CODE_SELF_DESTRUCTING_CONSTRUCTOR: &str = r#" -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_balance" (func $ext_balance)) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "deploy") - ;; Send entire remaining balance to the 0 address. - (call $ext_balance) - - ;; Balance should be encoded as a u64. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; Read balance into memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer to write balance to - (i32.const 0) ;; Offset into scratch buffer - (i32.const 8) ;; Length of encoded balance - ) - - ;; Self-destruct by sending full balance to the 0 address. - (call $assert - (i32.eq - (call $ext_call - (i32.const 0) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - ) - - (func (export "call")) -) -"#; - #[test] fn cannot_self_destruct_in_constructor() { - let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCTING_CONSTRUCTOR).unwrap(); + let (wasm, code_hash) = + compile_module::(&load_wasm("self_destructing_constructor.wat")).unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); @@ -2641,86 +1645,10 @@ fn check_block_gas_limit_works() { }); } -const CODE_GET_RUNTIME_STORAGE: &str = r#" -(module - (import "env" "ext_get_runtime_storage" - (func $ext_get_runtime_storage (param i32 i32) (result i32)) - ) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "deploy")) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func $call (export "call") - ;; Load runtime storage for the first key and assert that it exists. - (call $assert - (i32.eq - (call $ext_get_runtime_storage - (i32.const 16) - (i32.const 4) - ) - (i32.const 0) - ) - ) - - ;; assert $ext_scratch_size == 4 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 4) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 4) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 4) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i32 value of 0x14144020. - (call $assert - (i32.eq - (i32.load - (i32.const 4) - ) - (i32.const 0x14144020) - ) - ) - - ;; Load the second key and assert that it doesn't exist. - (call $assert - (i32.eq - (call $ext_get_runtime_storage - (i32.const 20) - (i32.const 4) - ) - (i32.const 1) - ) - ) - ) - - ;; The first key, 4 bytes long. - (data (i32.const 16) "\01\02\03\04") - ;; The second key, 4 bytes long. - (data (i32.const 20) "\02\03\04\05") -) -"#; - #[test] fn get_runtime_storage() { - let (wasm, code_hash) = compile_module::(CODE_GET_RUNTIME_STORAGE).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("get_runtime_storage.wat")) + .unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); @@ -2747,92 +1675,9 @@ fn get_runtime_storage() { }); } -const CODE_CRYPTO_HASHES: &str = r#" -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) - - (import "env" "ext_hash_sha2_256" (func $ext_hash_sha2_256 (param i32 i32 i32))) - (import "env" "ext_hash_keccak_256" (func $ext_hash_keccak_256 (param i32 i32 i32))) - (import "env" "ext_hash_blake2_256" (func $ext_hash_blake2_256 (param i32 i32 i32))) - (import "env" "ext_hash_blake2_128" (func $ext_hash_blake2_128 (param i32 i32 i32))) - - (import "env" "memory" (memory 1 1)) - - (type $hash_fn_sig (func (param i32 i32 i32))) - (table 8 funcref) - (elem (i32.const 1) - $ext_hash_sha2_256 - $ext_hash_keccak_256 - $ext_hash_blake2_256 - $ext_hash_blake2_128 - ) - (data (i32.const 1) "20202010201008") ;; Output sizes of the hashes in order in hex. - - ;; Not in use by the tests besides instantiating the contract. - (func (export "deploy")) - - ;; Called by the tests. - ;; - ;; The `call` function expects data in a certain format in the scratch - ;; buffer. - ;; - ;; 1. The first byte encodes an identifier for the crypto hash function - ;; under test. (*) - ;; 2. The rest encodes the input data that is directly fed into the - ;; crypto hash function chosen in 1. - ;; - ;; The `deploy` function then computes the chosen crypto hash function - ;; given the input and puts the result back into the scratch buffer. - ;; After contract execution the test driver then asserts that the returned - ;; values are equal to the expected bytes for the input and chosen hash - ;; function. - ;; - ;; (*) The possible value for the crypto hash identifiers can be found below: - ;; - ;; | value | Algorithm | Bit Width | - ;; |-------|-----------|-----------| - ;; | 0 | SHA2 | 256 | - ;; | 1 | KECCAK | 256 | - ;; | 2 | BLAKE2 | 256 | - ;; | 3 | BLAKE2 | 128 | - ;; --------------------------------- - (func (export "call") (result i32) - (local $chosen_hash_fn i32) - (local $input_ptr i32) - (local $input_len i32) - (local $output_ptr i32) - (local $output_len i32) - (local.set $input_ptr (i32.const 10)) - (call $ext_scratch_read (local.get $input_ptr) (i32.const 0) (call $ext_scratch_size)) - (local.set $chosen_hash_fn (i32.load8_u (local.get $input_ptr))) - (if (i32.gt_u (local.get $chosen_hash_fn) (i32.const 7)) - ;; We check that the chosen hash fn identifier is within bounds: [0,7] - (unreachable) - ) - (local.set $input_ptr (i32.add (local.get $input_ptr) (i32.const 1))) - (local.set $input_len (i32.sub (call $ext_scratch_size) (i32.const 1))) - (local.set $output_ptr (i32.const 100)) - (local.set $output_len (i32.load8_u (local.get $chosen_hash_fn))) - (call_indirect (type $hash_fn_sig) - (local.get $input_ptr) - (local.get $input_len) - (local.get $output_ptr) - (local.get $chosen_hash_fn) ;; Which crypto hash function to execute. - ) - (call $ext_scratch_write - (local.get $output_ptr) ;; Linear memory location of the output buffer. - (local.get $output_len) ;; Number of output buffer bytes. - ) - (i32.const 0) - ) -) -"#; - #[test] fn crypto_hashes() { - let (wasm, code_hash) = compile_module::(&CODE_CRYPTO_HASHES).unwrap(); + let (wasm, code_hash) = compile_module::(&load_wasm("crypto_hashes.wat")).unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); @@ -2880,3 +1725,8 @@ fn crypto_hashes() { } }) } + +fn load_wasm(file_name: &str) -> String { + let path = ["tests/", file_name].concat(); + std::fs::read_to_string(&path).expect(&format!("Unable to read {} file", path)) +} diff --git a/frame/contracts/tests/caller_contract.wat b/frame/contracts/tests/caller_contract.wat new file mode 100644 index 0000000000..4bc122c0b1 --- /dev/null +++ b/frame/contracts/tests/caller_contract.wat @@ -0,0 +1,275 @@ +(module + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "ext_balance" (func $ext_balance)) + (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "ext_println" (func $ext_println (param i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func $current_balance (param $sp i32) (result i64) + (call $ext_balance) + (call $assert + (i32.eq (call $ext_scratch_size) (i32.const 8)) + ) + (call $ext_scratch_read + (i32.sub (get_local $sp) (i32.const 8)) + (i32.const 0) + (i32.const 8) + ) + (i64.load (i32.sub (get_local $sp) (i32.const 8))) + ) + + (func (export "deploy")) + + (func (export "call") + (local $sp i32) + (local $exit_code i32) + (local $balance i64) + + ;; Input data is the code hash of the contract to be deployed. + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 32) + ) + ) + + ;; Copy code hash from scratch buffer into this contract's memory. + (call $ext_scratch_read + (i32.const 24) ;; The pointer where to store the scratch buffer contents, + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 32) ;; Count of bytes to copy. + ) + + ;; Read current balance into local variable. + (set_local $sp (i32.const 1024)) + (set_local $balance + (call $current_balance (get_local $sp)) + ) + + ;; Fail to deploy the contract since it returns a non-zero exit status. + (set_local $exit_code + (call $ext_instantiate + (i32.const 24) ;; Pointer to the code hash. + (i32.const 32) ;; Length of the code hash. + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 0) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer. + (i32.const 9) ;; Pointer to input data buffer address + (i32.const 7) ;; Length of input data buffer + ) + ) + + ;; Check non-zero exit status. + (call $assert + (i32.eq (get_local $exit_code) (i32.const 0x11)) + ) + + ;; Check that scratch buffer is empty since contract instantiation failed. + (call $assert + (i32.eq (call $ext_scratch_size) (i32.const 0)) + ) + + ;; Check that balance has not changed. + (call $assert + (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) + ) + + ;; Fail to deploy the contract due to insufficient gas. + (set_local $exit_code + (call $ext_instantiate + (i32.const 24) ;; Pointer to the code hash. + (i32.const 32) ;; Length of the code hash. + (i64.const 200) ;; How much gas to devote for the execution. + (i32.const 0) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer. + (i32.const 8) ;; Pointer to input data buffer address + (i32.const 8) ;; Length of input data buffer + ) + ) + + ;; Check for special trap exit status. + (call $assert + (i32.eq (get_local $exit_code) (i32.const 0x0100)) + ) + + ;; Check that scratch buffer is empty since contract instantiation failed. + (call $assert + (i32.eq (call $ext_scratch_size) (i32.const 0)) + ) + + ;; Check that balance has not changed. + (call $assert + (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) + ) + + ;; Deploy the contract successfully. + (set_local $exit_code + (call $ext_instantiate + (i32.const 24) ;; Pointer to the code hash. + (i32.const 32) ;; Length of the code hash. + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 0) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer. + (i32.const 8) ;; Pointer to input data buffer address + (i32.const 8) ;; Length of input data buffer + ) + ) + + ;; Check for success exit status. + (call $assert + (i32.eq (get_local $exit_code) (i32.const 0x00)) + ) + + ;; Check that scratch buffer contains the address of the new contract. + (call $assert + (i32.eq (call $ext_scratch_size) (i32.const 8)) + ) + + ;; Copy contract address from scratch buffer into this contract's memory. + (call $ext_scratch_read + (i32.const 16) ;; The pointer where to store the scratch buffer contents, + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 8) ;; Count of bytes to copy. + ) + + ;; Check that balance has been deducted. + (set_local $balance + (i64.sub (get_local $balance) (i64.load (i32.const 0))) + ) + (call $assert + (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) + ) + + ;; Call the new contract and expect it to return failing exit code. + (set_local $exit_code + (call $ext_call + (i32.const 16) ;; Pointer to "callee" address. + (i32.const 8) ;; Length of "callee" address. + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 0) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer. + (i32.const 9) ;; Pointer to input data buffer address + (i32.const 7) ;; Length of input data buffer + ) + ) + + ;; Check non-zero exit status. + (call $assert + (i32.eq (get_local $exit_code) (i32.const 0x11)) + ) + + ;; Check that scratch buffer contains the expected return data. + (call $assert + (i32.eq (call $ext_scratch_size) (i32.const 3)) + ) + (i32.store + (i32.sub (get_local $sp) (i32.const 4)) + (i32.const 0) + ) + (call $ext_scratch_read + (i32.sub (get_local $sp) (i32.const 4)) + (i32.const 0) + (i32.const 3) + ) + (call $assert + (i32.eq + (i32.load (i32.sub (get_local $sp) (i32.const 4))) + (i32.const 0x00776655) + ) + ) + + ;; Check that balance has not changed. + (call $assert + (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) + ) + + ;; Fail to call the contract due to insufficient gas. + (set_local $exit_code + (call $ext_call + (i32.const 16) ;; Pointer to "callee" address. + (i32.const 8) ;; Length of "callee" address. + (i64.const 100) ;; How much gas to devote for the execution. + (i32.const 0) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer. + (i32.const 8) ;; Pointer to input data buffer address + (i32.const 8) ;; Length of input data buffer + ) + ) + + ;; Check for special trap exit status. + (call $assert + (i32.eq (get_local $exit_code) (i32.const 0x0100)) + ) + + ;; Check that scratch buffer is empty since call trapped. + (call $assert + (i32.eq (call $ext_scratch_size) (i32.const 0)) + ) + + ;; Check that balance has not changed. + (call $assert + (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) + ) + + ;; Call the contract successfully. + (set_local $exit_code + (call $ext_call + (i32.const 16) ;; Pointer to "callee" address. + (i32.const 8) ;; Length of "callee" address. + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 0) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer. + (i32.const 8) ;; Pointer to input data buffer address + (i32.const 8) ;; Length of input data buffer + ) + ) + + ;; Check for success exit status. + (call $assert + (i32.eq (get_local $exit_code) (i32.const 0x00)) + ) + + ;; Check that scratch buffer contains the expected return data. + (call $assert + (i32.eq (call $ext_scratch_size) (i32.const 4)) + ) + (i32.store + (i32.sub (get_local $sp) (i32.const 4)) + (i32.const 0) + ) + (call $ext_scratch_read + (i32.sub (get_local $sp) (i32.const 4)) + (i32.const 0) + (i32.const 4) + ) + (call $assert + (i32.eq + (i32.load (i32.sub (get_local $sp) (i32.const 4))) + (i32.const 0x77665544) + ) + ) + + ;; Check that balance has been deducted. + (set_local $balance + (i64.sub (get_local $balance) (i64.load (i32.const 0))) + ) + (call $assert + (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) + ) + ) + + (data (i32.const 0) "\00\80") ;; The value to transfer on instantiation and calls. + ;; Chosen to be greater than existential deposit. + (data (i32.const 8) "\00\11\22\33\44\55\66\77") ;; The input data to instantiations and calls. +) diff --git a/frame/contracts/tests/check_default_rent_allowance.wat b/frame/contracts/tests/check_default_rent_allowance.wat new file mode 100644 index 0000000000..12b3004adf --- /dev/null +++ b/frame/contracts/tests/check_default_rent_allowance.wat @@ -0,0 +1,47 @@ +(module + (import "env" "ext_rent_allowance" (func $ext_rent_allowance)) + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "call")) + + (func (export "deploy") + ;; fill the scratch buffer with the rent allowance. + (call $ext_rent_allowance) + + ;; assert $ext_scratch_size == 8 + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + + ;; copy contents of the scratch buffer into the contract's memory. + (call $ext_scratch_read + (i32.const 8) ;; Pointer in memory to the place where to copy. + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 8) ;; Count of bytes to copy. + ) + + ;; assert that contents of the buffer is equal to >::max_value(). + (call $assert + (i64.eq + (i64.load + (i32.const 8) + ) + (i64.const 0xFFFFFFFFFFFFFFFF) + ) + ) + ) +) diff --git a/frame/contracts/tests/crypto_hashes.wat b/frame/contracts/tests/crypto_hashes.wat new file mode 100644 index 0000000000..6dbca33928 --- /dev/null +++ b/frame/contracts/tests/crypto_hashes.wat @@ -0,0 +1,80 @@ +(module + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) + + (import "env" "ext_hash_sha2_256" (func $ext_hash_sha2_256 (param i32 i32 i32))) + (import "env" "ext_hash_keccak_256" (func $ext_hash_keccak_256 (param i32 i32 i32))) + (import "env" "ext_hash_blake2_256" (func $ext_hash_blake2_256 (param i32 i32 i32))) + (import "env" "ext_hash_blake2_128" (func $ext_hash_blake2_128 (param i32 i32 i32))) + + (import "env" "memory" (memory 1 1)) + + (type $hash_fn_sig (func (param i32 i32 i32))) + (table 8 funcref) + (elem (i32.const 1) + $ext_hash_sha2_256 + $ext_hash_keccak_256 + $ext_hash_blake2_256 + $ext_hash_blake2_128 + ) + (data (i32.const 1) "20202010201008") ;; Output sizes of the hashes in order in hex. + + ;; Not in use by the tests besides instantiating the contract. + (func (export "deploy")) + + ;; Called by the tests. + ;; + ;; The `call` function expects data in a certain format in the scratch + ;; buffer. + ;; + ;; 1. The first byte encodes an identifier for the crypto hash function + ;; under test. (*) + ;; 2. The rest encodes the input data that is directly fed into the + ;; crypto hash function chosen in 1. + ;; + ;; The `deploy` function then computes the chosen crypto hash function + ;; given the input and puts the result back into the scratch buffer. + ;; After contract execution the test driver then asserts that the returned + ;; values are equal to the expected bytes for the input and chosen hash + ;; function. + ;; + ;; (*) The possible value for the crypto hash identifiers can be found below: + ;; + ;; | value | Algorithm | Bit Width | + ;; |-------|-----------|-----------| + ;; | 0 | SHA2 | 256 | + ;; | 1 | KECCAK | 256 | + ;; | 2 | BLAKE2 | 256 | + ;; | 3 | BLAKE2 | 128 | + ;; --------------------------------- + (func (export "call") (result i32) + (local $chosen_hash_fn i32) + (local $input_ptr i32) + (local $input_len i32) + (local $output_ptr i32) + (local $output_len i32) + (local.set $input_ptr (i32.const 10)) + (call $ext_scratch_read (local.get $input_ptr) (i32.const 0) (call $ext_scratch_size)) + (local.set $chosen_hash_fn (i32.load8_u (local.get $input_ptr))) + (if (i32.gt_u (local.get $chosen_hash_fn) (i32.const 7)) + ;; We check that the chosen hash fn identifier is within bounds: [0,7] + (unreachable) + ) + (local.set $input_ptr (i32.add (local.get $input_ptr) (i32.const 1))) + (local.set $input_len (i32.sub (call $ext_scratch_size) (i32.const 1))) + (local.set $output_ptr (i32.const 100)) + (local.set $output_len (i32.load8_u (local.get $chosen_hash_fn))) + (call_indirect (type $hash_fn_sig) + (local.get $input_ptr) + (local.get $input_len) + (local.get $output_ptr) + (local.get $chosen_hash_fn) ;; Which crypto hash function to execute. + ) + (call $ext_scratch_write + (local.get $output_ptr) ;; Linear memory location of the output buffer. + (local.get $output_len) ;; Number of output buffer bytes. + ) + (i32.const 0) + ) +) diff --git a/frame/contracts/tests/destroy_and_transfer.wat b/frame/contracts/tests/destroy_and_transfer.wat new file mode 100644 index 0000000000..c8cf7271d7 --- /dev/null +++ b/frame/contracts/tests/destroy_and_transfer.wat @@ -0,0 +1,148 @@ +(module + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "ext_get_storage" (func $ext_get_storage (param i32) (result i32))) + (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) + (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "deploy") + ;; Input data is the code hash of the contract to be deployed. + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 32) + ) + ) + + ;; Copy code hash from scratch buffer into this contract's memory. + (call $ext_scratch_read + (i32.const 48) ;; The pointer where to store the scratch buffer contents, + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 32) ;; Count of bytes to copy. + ) + + ;; Deploy the contract with the provided code hash. + (call $assert + (i32.eq + (call $ext_instantiate + (i32.const 48) ;; Pointer to the code hash. + (i32.const 32) ;; Length of the code hash. + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 0) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer. + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 0) ;; Length of input data buffer + ) + (i32.const 0) + ) + ) + + ;; Read the address of the instantiated contract into memory. + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + (call $ext_scratch_read + (i32.const 80) ;; The pointer where to store the scratch buffer contents, + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 8) ;; Count of bytes to copy. + ) + + ;; Store the return address. + (call $ext_set_storage + (i32.const 16) ;; Pointer to the key + (i32.const 80) ;; Pointer to the value + (i32.const 8) ;; Length of the value + ) + ) + + (func (export "call") + ;; Read address of destination contract from storage. + (call $assert + (i32.eq + (call $ext_get_storage + (i32.const 16) ;; Pointer to the key + ) + (i32.const 0) + ) + ) + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + (call $ext_scratch_read + (i32.const 80) ;; The pointer where to store the contract address. + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 8) ;; Count of bytes to copy. + ) + + ;; Calling the destination contract with non-empty input data should fail. + (call $assert + (i32.eq + (call $ext_call + (i32.const 80) ;; Pointer to destination address + (i32.const 8) ;; Length of destination address + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 0) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 1) ;; Length of input data buffer + ) + (i32.const 0x0100) + ) + ) + + ;; Call the destination contract regularly, forcing it to self-destruct. + (call $assert + (i32.eq + (call $ext_call + (i32.const 80) ;; Pointer to destination address + (i32.const 8) ;; Length of destination address + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 8) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 0) ;; Length of input data buffer + ) + (i32.const 0) + ) + ) + + ;; Calling the destination address with non-empty input data should now work since the + ;; contract has been removed. Also transfer a balance to the address so we can ensure this + ;; does not keep the contract alive. + (call $assert + (i32.eq + (call $ext_call + (i32.const 80) ;; Pointer to destination address + (i32.const 8) ;; Length of destination address + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 0) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 1) ;; Length of input data buffer + ) + (i32.const 0) + ) + ) + ) + + (data (i32.const 0) "\00\00\01") ;; Endowment to send when creating contract. + (data (i32.const 8) "") ;; Value to send when calling contract. + (data (i32.const 16) "") ;; The key to store the contract address under. +) diff --git a/frame/contracts/tests/dispatch_call.wat b/frame/contracts/tests/dispatch_call.wat new file mode 100644 index 0000000000..db0995bd6c --- /dev/null +++ b/frame/contracts/tests/dispatch_call.wat @@ -0,0 +1,14 @@ +(module + (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func (export "call") + (call $ext_dispatch_call + (i32.const 8) ;; Pointer to the start of encoded call buffer + (i32.const 11) ;; Length of the buffer + ) + ) + (func (export "deploy")) + + (data (i32.const 8) "\00\00\03\00\00\00\00\00\00\00\C8") +) diff --git a/frame/contracts/tests/dispatch_call_then_trap.wat b/frame/contracts/tests/dispatch_call_then_trap.wat new file mode 100644 index 0000000000..ce949d6823 --- /dev/null +++ b/frame/contracts/tests/dispatch_call_then_trap.wat @@ -0,0 +1,15 @@ +(module + (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func (export "call") + (call $ext_dispatch_call + (i32.const 8) ;; Pointer to the start of encoded call buffer + (i32.const 11) ;; Length of the buffer + ) + (unreachable) ;; trap so that the top level transaction fails + ) + (func (export "deploy")) + + (data (i32.const 8) "\00\00\03\00\00\00\00\00\00\00\C8") +) diff --git a/frame/contracts/tests/drain.wat b/frame/contracts/tests/drain.wat new file mode 100644 index 0000000000..d08e1dd0d2 --- /dev/null +++ b/frame/contracts/tests/drain.wat @@ -0,0 +1,54 @@ +(module + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "ext_balance" (func $ext_balance)) + (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "deploy")) + + (func (export "call") + ;; Send entire remaining balance to the 0 address. + (call $ext_balance) + + ;; Balance should be encoded as a u64. + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + + ;; Read balance into memory. + (call $ext_scratch_read + (i32.const 8) ;; Pointer to write balance to + (i32.const 0) ;; Offset into scratch buffer + (i32.const 8) ;; Length of encoded balance + ) + + ;; Self-destruct by sending full balance to the 0 address. + (call $assert + (i32.eq + (call $ext_call + (i32.const 0) ;; Pointer to destination address + (i32.const 8) ;; Length of destination address + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 8) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 0) ;; Length of input data buffer + ) + (i32.const 0) + ) + ) + ) +) diff --git a/frame/contracts/tests/get_runtime_storage.wat b/frame/contracts/tests/get_runtime_storage.wat new file mode 100644 index 0000000000..6148f1c408 --- /dev/null +++ b/frame/contracts/tests/get_runtime_storage.wat @@ -0,0 +1,74 @@ +(module + (import "env" "ext_get_runtime_storage" + (func $ext_get_runtime_storage (param i32 i32) (result i32)) + ) + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func (export "deploy")) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func $call (export "call") + ;; Load runtime storage for the first key and assert that it exists. + (call $assert + (i32.eq + (call $ext_get_runtime_storage + (i32.const 16) + (i32.const 4) + ) + (i32.const 0) + ) + ) + + ;; assert $ext_scratch_size == 4 + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 4) + ) + ) + + ;; copy contents of the scratch buffer into the contract's memory. + (call $ext_scratch_read + (i32.const 4) ;; Pointer in memory to the place where to copy. + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 4) ;; Count of bytes to copy. + ) + + ;; assert that contents of the buffer is equal to the i32 value of 0x14144020. + (call $assert + (i32.eq + (i32.load + (i32.const 4) + ) + (i32.const 0x14144020) + ) + ) + + ;; Load the second key and assert that it doesn't exist. + (call $assert + (i32.eq + (call $ext_get_runtime_storage + (i32.const 20) + (i32.const 4) + ) + (i32.const 1) + ) + ) + ) + + ;; The first key, 4 bytes long. + (data (i32.const 16) "\01\02\03\04") + ;; The second key, 4 bytes long. + (data (i32.const 20) "\02\03\04\05") +) diff --git a/frame/contracts/tests/restoration.wat b/frame/contracts/tests/restoration.wat new file mode 100644 index 0000000000..4e11f97d5a --- /dev/null +++ b/frame/contracts/tests/restoration.wat @@ -0,0 +1,56 @@ +(module + (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) + (import "env" "ext_restore_to" (func $ext_restore_to (param i32 i32 i32 i32 i32 i32 i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func (export "call") + (call $ext_restore_to + ;; Pointer and length of the encoded dest buffer. + (i32.const 256) + (i32.const 8) + ;; Pointer and length of the encoded code hash buffer + (i32.const 264) + (i32.const 32) + ;; Pointer and length of the encoded rent_allowance buffer + (i32.const 296) + (i32.const 8) + ;; Pointer and number of items in the delta buffer. + ;; This buffer specifies multiple keys for removal before restoration. + (i32.const 100) + (i32.const 1) + ) + ) + (func (export "deploy") + ;; Data to restore + (call $ext_set_storage + (i32.const 0) + (i32.const 0) + (i32.const 4) + ) + + ;; ACL + (call $ext_set_storage + (i32.const 100) + (i32.const 0) + (i32.const 4) + ) + ) + + ;; Data to restore + (data (i32.const 0) "\28") + + ;; Buffer that has ACL storage keys. + (data (i32.const 100) "\01") + + ;; Address of bob + (data (i32.const 256) "\02\00\00\00\00\00\00\00") + + ;; Code hash of SET_RENT + (data (i32.const 264) + "\c2\1c\41\10\a5\22\d8\59\1c\4c\77\35\dd\2d\bf\a1" + "\13\0b\50\93\76\9b\92\31\97\b7\c5\74\26\aa\38\2a" + ) + + ;; Rent allowance + (data (i32.const 296) "\32\00\00\00\00\00\00\00") +) diff --git a/frame/contracts/tests/return_from_start_fn.wat b/frame/contracts/tests/return_from_start_fn.wat new file mode 100644 index 0000000000..ac898d4d94 --- /dev/null +++ b/frame/contracts/tests/return_from_start_fn.wat @@ -0,0 +1,27 @@ +(module + (import "env" "ext_return" (func $ext_return (param i32 i32))) + (import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32))) + (import "env" "memory" (memory 1 1)) + + (start $start) + (func $start + (call $ext_deposit_event + (i32.const 0) ;; The topics buffer + (i32.const 0) ;; The topics buffer's length + (i32.const 8) ;; The data buffer + (i32.const 4) ;; The data buffer's length + ) + (call $ext_return + (i32.const 8) + (i32.const 4) + ) + (unreachable) + ) + + (func (export "call") + (unreachable) + ) + (func (export "deploy")) + + (data (i32.const 8) "\01\02\03\04") +) diff --git a/frame/contracts/tests/return_with_data.wat b/frame/contracts/tests/return_with_data.wat new file mode 100644 index 0000000000..8cc84006a0 --- /dev/null +++ b/frame/contracts/tests/return_with_data.wat @@ -0,0 +1,39 @@ +(module + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) + (import "env" "memory" (memory 1 1)) + + ;; Deploy routine is the same as call. + (func (export "deploy") (result i32) + (call $call) + ) + + ;; Call reads the first 4 bytes (LE) as the exit status and returns the rest as output data. + (func $call (export "call") (result i32) + (local $buf_size i32) + (local $exit_status i32) + + ;; Find out the size of the scratch buffer + (set_local $buf_size (call $ext_scratch_size)) + + ;; Copy scratch buffer into this contract memory. + (call $ext_scratch_read + (i32.const 0) ;; The pointer where to store the scratch buffer contents, + (i32.const 0) ;; Offset from the start of the scratch buffer. + (get_local $buf_size) ;; Count of bytes to copy. + ) + + ;; Copy all but the first 4 bytes of the input data as the output data. + (call $ext_scratch_write + (i32.const 4) ;; Pointer to the data to return. + (i32.sub ;; Count of bytes to copy. + (get_local $buf_size) + (i32.const 4) + ) + ) + + ;; Return the first 4 bytes of the input data as the exit status. + (i32.load (i32.const 0)) + ) +) diff --git a/frame/contracts/tests/run_out_of_gas.wat b/frame/contracts/tests/run_out_of_gas.wat new file mode 100644 index 0000000000..52ee92539f --- /dev/null +++ b/frame/contracts/tests/run_out_of_gas.wat @@ -0,0 +1,7 @@ +(module + (func (export "call") + (loop $inf (br $inf)) ;; just run out of gas + (unreachable) + ) + (func (export "deploy")) +) diff --git a/frame/contracts/tests/self_destruct.wat b/frame/contracts/tests/self_destruct.wat new file mode 100644 index 0000000000..464b5c663e --- /dev/null +++ b/frame/contracts/tests/self_destruct.wat @@ -0,0 +1,72 @@ +(module + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "ext_address" (func $ext_address)) + (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "ext_terminate" (func $ext_terminate (param i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "deploy")) + + (func (export "call") + ;; If the input data is not empty, then recursively call self with empty input data. + ;; This should trap instead of self-destructing since a contract cannot be removed live in + ;; the execution stack cannot be removed. If the recursive call traps, then trap here as + ;; well. + (if (call $ext_scratch_size) + (then + (call $ext_address) + + ;; Expect address to be 8 bytes. + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + + ;; Read own address into memory. + (call $ext_scratch_read + (i32.const 16) ;; Pointer to write address to + (i32.const 0) ;; Offset into scratch buffer + (i32.const 8) ;; Length of encoded address + ) + + ;; Recursively call self with empty input data. + (call $assert + (i32.eq + (call $ext_call + (i32.const 16) ;; Pointer to own address + (i32.const 8) ;; Length of own address + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 8) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 0) ;; Length of input data buffer + ) + (i32.const 0) + ) + ) + ) + (else + ;; Try to terminate and give balance to django. + (call $ext_terminate + (i32.const 32) ;; Pointer to beneficiary address + (i32.const 8) ;; Length of beneficiary address + ) + (unreachable) ;; ext_terminate never returns + ) + ) + ) + ;; Address of django + (data (i32.const 32) "\04\00\00\00\00\00\00\00") +) diff --git a/frame/contracts/tests/self_destructing_constructor.wat b/frame/contracts/tests/self_destructing_constructor.wat new file mode 100644 index 0000000000..b19d6e5b50 --- /dev/null +++ b/frame/contracts/tests/self_destructing_constructor.wat @@ -0,0 +1,54 @@ +(module + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "ext_balance" (func $ext_balance)) + (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "deploy") + ;; Send entire remaining balance to the 0 address. + (call $ext_balance) + + ;; Balance should be encoded as a u64. + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + + ;; Read balance into memory. + (call $ext_scratch_read + (i32.const 8) ;; Pointer to write balance to + (i32.const 0) ;; Offset into scratch buffer + (i32.const 8) ;; Length of encoded balance + ) + + ;; Self-destruct by sending full balance to the 0 address. + (call $assert + (i32.eq + (call $ext_call + (i32.const 0) ;; Pointer to destination address + (i32.const 8) ;; Length of destination address + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 8) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 0) ;; Length of input data buffer + ) + (i32.const 0) + ) + ) + ) + + (func (export "call")) +) diff --git a/frame/contracts/tests/set_rent.wat b/frame/contracts/tests/set_rent.wat new file mode 100644 index 0000000000..d1affa0d74 --- /dev/null +++ b/frame/contracts/tests/set_rent.wat @@ -0,0 +1,101 @@ +(module + (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) + (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) + (import "env" "ext_clear_storage" (func $ext_clear_storage (param i32))) + (import "env" "ext_set_rent_allowance" (func $ext_set_rent_allowance (param i32 i32))) + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "memory" (memory 1 1)) + + ;; insert a value of 4 bytes into storage + (func $call_0 + (call $ext_set_storage + (i32.const 1) + (i32.const 0) + (i32.const 4) + ) + ) + + ;; remove the value inserted by call_1 + (func $call_1 + (call $ext_clear_storage + (i32.const 1) + ) + ) + + ;; transfer 50 to ALICE + (func $call_2 + (call $ext_dispatch_call + (i32.const 68) + (i32.const 11) + ) + ) + + ;; do nothing + (func $call_else) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + ;; Dispatch the call according to input size + (func (export "call") + (local $input_size i32) + (set_local $input_size + (call $ext_scratch_size) + ) + (block $IF_ELSE + (block $IF_2 + (block $IF_1 + (block $IF_0 + (br_table $IF_0 $IF_1 $IF_2 $IF_ELSE + (get_local $input_size) + ) + (unreachable) + ) + (call $call_0) + return + ) + (call $call_1) + return + ) + (call $call_2) + return + ) + (call $call_else) + ) + + ;; Set into storage a 4 bytes value + ;; Set call set_rent_allowance with input + (func (export "deploy") + (local $input_size i32) + (set_local $input_size + (call $ext_scratch_size) + ) + (call $ext_set_storage + (i32.const 0) + (i32.const 0) + (i32.const 4) + ) + (call $ext_scratch_read + (i32.const 0) + (i32.const 0) + (get_local $input_size) + ) + (call $ext_set_rent_allowance + (i32.const 0) + (get_local $input_size) + ) + ) + + ;; Encoding of 10 in balance + (data (i32.const 0) "\28") + + ;; Encoding of call transfer 50 to CHARLIE + (data (i32.const 68) "\00\00\03\00\00\00\00\00\00\00\C8") +) diff --git a/frame/contracts/tests/storage_size.wat b/frame/contracts/tests/storage_size.wat new file mode 100644 index 0000000000..8de9f42ee9 --- /dev/null +++ b/frame/contracts/tests/storage_size.wat @@ -0,0 +1,60 @@ +(module + (import "env" "ext_get_storage" (func $ext_get_storage (param i32) (result i32))) + (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "memory" (memory 16 16)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "call") + ;; assert $ext_scratch_size == 8 + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 4) + ) + ) + + ;; copy contents of the scratch buffer into the contract's memory. + (call $ext_scratch_read + (i32.const 32) ;; Pointer in memory to the place where to copy. + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 4) ;; Count of bytes to copy. + ) + + ;; place a garbage value in storage, the size of which is specified by the call input. + (call $ext_set_storage + (i32.const 0) ;; Pointer to storage key + (i32.const 0) ;; Pointer to value + (i32.load (i32.const 32)) ;; Size of value + ) + + (call $assert + (i32.eq + (call $ext_get_storage + (i32.const 0) ;; Pointer to storage key + ) + (i32.const 0) + ) + ) + + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.load (i32.const 32)) + ) + ) + ) + + (func (export "deploy")) + + (data (i32.const 0) "\01") ;; Storage key (32 B) +) -- GitLab From 453ad11ed3e6201d8b17e9a0c88644351304abe6 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 9 Apr 2020 10:34:51 +0200 Subject: [PATCH 195/300] client/authority-discovery: Terminate when network does (#5562) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * client/authority-discovery: Add test ensure termination on network termi * client/authority-discovery: Terminate when network does When the dht event stream returns Poll::Ready(None) it is likely due to the network terminating. When the network terminates due to the node itself shutting down or due to a fatal error, there is no purpose in continuing to run the authority discovery module. * client/authority-discovery/src/lib: Apply suggestions Co-Authored-By: André Silva <123550+andresilva@users.noreply.github.com> Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> --- client/authority-discovery/src/error.rs | 9 ++++--- client/authority-discovery/src/lib.rs | 30 ++++++++++++++-------- client/authority-discovery/src/tests.rs | 34 +++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/client/authority-discovery/src/error.rs b/client/authority-discovery/src/error.rs index 216f8c26bf..751e3e76e9 100644 --- a/client/authority-discovery/src/error.rs +++ b/client/authority-discovery/src/error.rs @@ -40,17 +40,20 @@ pub enum Error { MatchingHashedAuthorityIdWithAuthorityId, /// Failed to set the authority discovery peerset priority group in the peerset module. SettingPeersetPriorityGroup(String), + /// The sender side of the dht event stream has been closed likely due to the network + /// terminating. + DhtEventStreamTerminated, /// Failed to encode a protobuf payload. EncodingProto(prost::EncodeError), /// Failed to decode a protobuf payload. DecodingProto(prost::DecodeError), - /// Failed to encode or decode scale payload + /// Failed to encode or decode scale payload. EncodingDecodingScale(codec::Error), /// Failed to parse a libp2p multi address. ParsingMultiaddress(libp2p::core::multiaddr::Error), - /// Failed to sign using a specific public key + /// Failed to sign using a specific public key. MissingSignature(CryptoTypePublicPair), - /// Failed to sign using all public keys + /// Failed to sign using all public keys. Signing, /// Failed to register Prometheus metric. Prometheus(prometheus_endpoint::PrometheusError), diff --git a/client/authority-discovery/src/lib.rs b/client/authority-discovery/src/lib.rs index 45f05e1039..1a8a5c9f40 100644 --- a/client/authority-discovery/src/lib.rs +++ b/client/authority-discovery/src/lib.rs @@ -330,9 +330,9 @@ where } fn handle_dht_events(&mut self, cx: &mut Context) -> Result<()> { - while let Poll::Ready(Some(event)) = self.dht_event_rx.poll_next_unpin(cx) { - match event { - DhtEvent::ValueFound(v) => { + loop { + match self.dht_event_rx.poll_next_unpin(cx) { + Poll::Ready(Some(DhtEvent::ValueFound(v))) => { if let Some(metrics) = &self.metrics { metrics.dht_event_received.with_label_values(&["value_found"]).inc(); } @@ -347,7 +347,7 @@ where self.handle_dht_value_found_event(v)?; } - DhtEvent::ValueNotFound(hash) => { + Poll::Ready(Some(DhtEvent::ValueNotFound(hash))) => { if let Some(metrics) = &self.metrics { metrics.dht_event_received.with_label_values(&["value_not_found"]).inc(); } @@ -357,7 +357,7 @@ where "Value for hash '{:?}' not found on Dht.", hash ) }, - DhtEvent::ValuePut(hash) => { + Poll::Ready(Some(DhtEvent::ValuePut(hash))) => { if let Some(metrics) = &self.metrics { metrics.dht_event_received.with_label_values(&["value_put"]).inc(); } @@ -367,7 +367,7 @@ where "Successfully put hash '{:?}' on Dht.", hash, ) }, - DhtEvent::ValuePutFailed(hash) => { + Poll::Ready(Some(DhtEvent::ValuePutFailed(hash))) => { if let Some(metrics) = &self.metrics { metrics.dht_event_received.with_label_values(&["value_put_failed"]).inc(); } @@ -377,10 +377,12 @@ where "Failed to put hash '{:?}' on Dht.", hash ) }, + // The sender side of the dht event stream has been closed, likely due to the + // network terminating. + Poll::Ready(None) => return Err(Error::DhtEventStreamTerminated), + Poll::Pending => return Ok(()), } } - - Ok(()) } fn handle_dht_value_found_event( @@ -483,7 +485,6 @@ where } /// Update the peer set 'authority' priority group. - // fn update_peer_set_priority_group(&self) -> Result<()> { let addresses = self.addr_cache.get_subset(); @@ -539,11 +540,18 @@ where match inner() { Ok(()) => {} + + // Handle fatal errors. + // + // Given that the network likely terminated authority discovery should do the same. + Err(Error::DhtEventStreamTerminated) => return Poll::Ready(()), + + // Handle non-fatal errors. Err(e) => error!(target: "sub-authority-discovery", "Poll failure: {:?}", e), }; - // Make sure to always return NotReady as this is a long running task with the same lifetime - // as the node itself. + // Return Poll::Pending as this is a long running task with the same lifetime as the node + // itself. Poll::Pending } } diff --git a/client/authority-discovery/src/tests.rs b/client/authority-discovery/src/tests.rs index 358376e5db..923b7ee0f2 100644 --- a/client/authority-discovery/src/tests.rs +++ b/client/authority-discovery/src/tests.rs @@ -19,6 +19,7 @@ use std::{iter::FromIterator, sync::{Arc, Mutex}}; use futures::channel::mpsc::channel; use futures::executor::block_on; use futures::future::poll_fn; +use futures::poll; use libp2p::{kad, PeerId}; use sp_api::{ProvideRuntimeApi, ApiRef}; @@ -346,3 +347,36 @@ fn handle_dht_events_with_value_found_should_call_set_priority_group() { let _ = block_on(poll_fn(f)); } + +#[test] +fn terminate_when_event_stream_terminates() { + let (dht_event_tx, dht_event_rx) = channel(1000); + let network: Arc = Arc::new(Default::default()); + let key_store = KeyStore::new(); + let test_api = Arc::new(TestApi { + authorities: vec![], + }); + + let mut authority_discovery = AuthorityDiscovery::new( + test_api, + network.clone(), + vec![], + key_store, + dht_event_rx.boxed(), + None, + ); + + block_on(async { + assert_eq!(Poll::Pending, poll!(&mut authority_discovery)); + + // Simulate termination of the network through dropping the sender side of the dht event + // channel. + drop(dht_event_tx); + + assert_eq!( + Poll::Ready(()), poll!(&mut authority_discovery), + "Expect the authority discovery module to terminate once the sending side of the dht \ + event channel is terminated.", + ); + }); +} -- GitLab From 10096782cfb9938594ca0e2178f8bae4280e5385 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Thu, 9 Apr 2020 01:37:26 -0700 Subject: [PATCH 196/300] Fix benchmarks: set cache_size to higher value (#5585) * 128 -> 1024 * add trace and set = 512 * fix doc comment --- bin/node/testing/src/bench.rs | 2 +- client/db/src/lib.rs | 2 +- client/db/src/utils.rs | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/bin/node/testing/src/bench.rs b/bin/node/testing/src/bench.rs index 5dd0d012fb..2ca6428bed 100644 --- a/bin/node/testing/src/bench.rs +++ b/bin/node/testing/src/bench.rs @@ -186,7 +186,7 @@ impl BenchDb { pruning: PruningMode::ArchiveAll, source: sc_client_db::DatabaseSettingsSrc::Path { path: dir.into(), - cache_size: 128, + cache_size: 512, }, }; diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index e00d608a5f..70f666aebf 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -284,7 +284,7 @@ pub enum DatabaseSettingsSrc { Path { /// Path to the database. path: PathBuf, - /// Cache size in bytes. + /// Cache size in MiB. cache_size: usize, }, diff --git a/client/db/src/utils.rs b/client/db/src/utils.rs index e62c4f052b..16239a82c2 100644 --- a/client/db/src/utils.rs +++ b/client/db/src/utils.rs @@ -243,6 +243,15 @@ pub fn open_database( db_config.memory_budget = memory_budget; + log::trace!( + target: "db", + "Open database at {}, state column budget: {} MiB, others({}) column cache: {} MiB", + path, + state_col_budget, + NUM_COLUMNS, + other_col_budget, + ); + Arc::new(Database::open(&db_config, &path).map_err(db_err)?) }, #[cfg(not(any(feature = "kvdb-rocksdb", test)))] -- GitLab From 8bcd5ba1551f5fa9b29248d405184a278f21de58 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 9 Apr 2020 11:24:01 +0200 Subject: [PATCH 197/300] Report local force-closing connections to Prometheus (#5575) * Report local force-closing connections to Prometheus * Also report ping timeouts separately * Address concerns of #5571 --- client/network/src/protocol.rs | 1 + client/network/src/protocol/generic_proto.rs | 1 + .../src/protocol/generic_proto/behaviour.rs | 4 ++-- .../network/src/protocol/generic_proto/handler.rs | 1 + client/network/src/service.rs | 15 +++++++++++---- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 365cbcbc52..49479aa2d4 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -77,6 +77,7 @@ pub mod sync; pub use block_requests::BlockRequests; pub use light_client_handler::LightClientHandler; +pub use generic_proto::LegacyConnectionKillError; const REQUEST_TIMEOUT_SEC: u64 = 40; /// Interval at which we perform time based maintenance diff --git a/client/network/src/protocol/generic_proto.rs b/client/network/src/protocol/generic_proto.rs index f703287f38..cf8434d8bc 100644 --- a/client/network/src/protocol/generic_proto.rs +++ b/client/network/src/protocol/generic_proto.rs @@ -21,6 +21,7 @@ //! network, then performs the Substrate protocol handling on top. pub use self::behaviour::{GenericProto, GenericProtoOut}; +pub use self::handler::LegacyConnectionKillError; mod behaviour; mod handler; diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index b38a97cb8f..49744a5d86 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -1193,10 +1193,10 @@ impl NetworkBehaviour for GenericProto { } NotifsHandlerOut::ProtocolError { error, .. } => { - warn!(target: "sub-libp2p", + debug!(target: "sub-libp2p", "Handler({:?}) => Severe protocol error: {:?}", source, error); - // A severe protocol error happens when we detect a "bad" peer, such as a per on + // A severe protocol error happens when we detect a "bad" peer, such as a peer on // a different chain, or a peer that doesn't speak the same protocol(s). We // decrease the peer's reputation, hence lowering the chances we try this peer // again in the short term. diff --git a/client/network/src/protocol/generic_proto/handler.rs b/client/network/src/protocol/generic_proto/handler.rs index e97176cfbb..f0e2fc4bb8 100644 --- a/client/network/src/protocol/generic_proto/handler.rs +++ b/client/network/src/protocol/generic_proto/handler.rs @@ -15,6 +15,7 @@ // along with Substrate. If not, see . pub use self::group::{NotifsHandlerProto, NotifsHandler, NotifsHandlerIn, NotifsHandlerOut}; +pub use self::legacy::ConnectionKillError as LegacyConnectionKillError; mod group; mod legacy; diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 581a1ab972..55e257c5ae 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -33,13 +33,14 @@ use crate::{ NetworkState, NotConnectedPeer as NetworkStateNotConnectedPeer, Peer as NetworkStatePeer, }, on_demand_layer::AlwaysBadChecker, - protocol::{self, event::Event, light_client_handler, sync::SyncState, PeerInfo, Protocol}, + protocol::{self, event::Event, light_client_handler, LegacyConnectionKillError, sync::SyncState, PeerInfo, Protocol}, transport, ReputationChange, }; use futures::prelude::*; use libp2p::{PeerId, Multiaddr}; -use libp2p::core::{ConnectedPoint, Executor, connection::{ConnectionError, PendingConnectionError}}; +use libp2p::core::{ConnectedPoint, Executor, connection::{ConnectionError, PendingConnectionError}, either::EitherError}; use libp2p::kad::record; +use libp2p::ping::handler::PingFailure; use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent, protocols_handler::NodeHandlerWrapperError}; use log::{error, info, trace, warn}; use parking_lot::Mutex; @@ -871,7 +872,7 @@ impl Metrics { connections: register(GaugeVec::new( Opts::new( "sub_libp2p_connections", - "Number of active libp2p connections" + "Number of established libp2p connections" ), &["direction"] )?, registry)?, @@ -974,7 +975,7 @@ impl Metrics { pending_connections_errors_total: register(CounterVec::new( Opts::new( "sub_libp2p_pending_connections_errors_total", - "Total number of node connection failures" + "Total number of pending connection errors" ), &["reason"] )?, registry)?, @@ -1134,6 +1135,12 @@ impl Future for NetworkWorker { metrics.connections_closed_total.with_label_values(&["transport-error"]).inc(), ConnectionError::ConnectionLimit(_) => metrics.connections_closed_total.with_label_values(&["limit-reached"]).inc(), + ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( + EitherError::A(EitherError::B(EitherError::A(PingFailure::Timeout))))))) => + metrics.connections_closed_total.with_label_values(&["ping-timeout"]).inc(), + ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( + EitherError::A(EitherError::A(EitherError::B(LegacyConnectionKillError))))))) => + metrics.connections_closed_total.with_label_values(&["force-closed"]).inc(), ConnectionError::Handler(NodeHandlerWrapperError::Handler(_)) => metrics.connections_closed_total.with_label_values(&["protocol-error"]).inc(), ConnectionError::Handler(NodeHandlerWrapperError::KeepAliveTimeout) => -- GitLab From a37db5e7a35ebb758a1d8be1e4a0124038996e4a Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Thu, 9 Apr 2020 11:27:39 +0200 Subject: [PATCH 198/300] Benchmarks now use in-memory db & cache (#5586) * in-mem state for benchmarks * Use caching state * Update Cargo.lock Co-authored-by: Shawn Tabrizi --- Cargo.lock | 67 +++++++++++++++++++++--------------------- client/db/Cargo.toml | 1 - client/db/src/bench.rs | 64 +++++++++++++--------------------------- 3 files changed, 53 insertions(+), 79 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9395f4a6df..31badd989f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1239,7 +1239,7 @@ dependencies = [ "fixed-hash", "impl-rlp", "impl-serde 0.3.0", - "tiny-keccak 2.0.1", + "tiny-keccak 2.0.2", ] [[package]] @@ -1974,7 +1974,7 @@ dependencies = [ "indexmap", "log", "slab", - "tokio 0.2.13", + "tokio 0.2.16", "tokio-util", ] @@ -2186,7 +2186,7 @@ dependencies = [ "net2", "pin-project", "time", - "tokio 0.2.13", + "tokio 0.2.16", "tower-service", "want 0.3.0", ] @@ -2204,7 +2204,7 @@ dependencies = [ "log", "rustls 0.17.0", "rustls-native-certs", - "tokio 0.2.13", + "tokio 0.2.16", "tokio-rustls", "webpki", ] @@ -4873,9 +4873,9 @@ dependencies = [ [[package]] name = "paste" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092d791bf7847f70bbd49085489fba25fc2c193571752bff9e36e74e72403932" +checksum = "ab4fb1930692d1b6a9cfabdde3d06ea0a7d186518e2f4d67660d8970e2fa647a" dependencies = [ "paste-impl", "proc-macro-hack", @@ -4883,9 +4883,9 @@ dependencies = [ [[package]] name = "paste-impl" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406c23fb4c45cc6f68a9bbabb8ec7bd6f8cfcbd17e9e8f72c2460282f8325729" +checksum = "a62486e111e571b1e93b710b61e8f493c0013be39629b714cb166bdb06aa5a8a" dependencies = [ "proc-macro-hack", "proc-macro2", @@ -5229,9 +5229,9 @@ dependencies = [ [[package]] name = "quicksink" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8461ef7445f61fd72d8dcd0629ce724b9131b3c2eb36e83a5d3d4161c127530" +checksum = "77de3c815e5a160b1539c6592796801df2043ae35e123b46d73380cfa57af858" dependencies = [ "futures-core", "futures-sink", @@ -5895,7 +5895,7 @@ dependencies = [ "substrate-prometheus-endpoint", "tempfile", "time", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -5986,7 +5986,6 @@ dependencies = [ "parity-util-mem", "parking_lot 0.10.0", "quickcheck", - "rand 0.7.3", "sc-client", "sc-client-api", "sc-executor", @@ -6154,7 +6153,7 @@ dependencies = [ "substrate-test-runtime-client", "substrate-test-runtime-transaction-pool", "tempfile", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -6336,7 +6335,7 @@ dependencies = [ "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -6501,7 +6500,7 @@ dependencies = [ "sp-utils", "substrate-test-runtime-client", "threadpool", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -6919,18 +6918,18 @@ checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" [[package]] name = "serde" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff" +checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" +checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" dependencies = [ "proc-macro2", "quote 1.0.3", @@ -6939,9 +6938,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78a7a12c167809363ec3bd7329fc0a3369056996de43c4b37ef3cd54a6ce4867" +checksum = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9" dependencies = [ "itoa", "ryu", @@ -7390,7 +7389,7 @@ dependencies = [ "sp-storage", "substrate-bip39", "tiny-bip39", - "tiny-keccak 2.0.1", + "tiny-keccak 2.0.2", "twox-hash", "wasmi", "zeroize", @@ -7962,7 +7961,7 @@ dependencies = [ "sc-rpc-api", "serde", "sp-storage", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -7998,7 +7997,7 @@ dependencies = [ "hyper 0.13.4", "log", "prometheus", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -8400,9 +8399,9 @@ dependencies = [ [[package]] name = "tiny-keccak" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2953ca5148619bc99695c1274cb54c5275bbb913c6adad87e72eaf8db9787f69" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" dependencies = [ "crunchy", ] @@ -8443,9 +8442,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa5e81d6bc4e67fe889d5783bd2a128ab2e0cfa487e0be16b6a8d177b101616" +checksum = "ee5a0dd887e37d37390c13ff8ac830f992307fe30a1fff0ab8427af67211ba28" dependencies = [ "bytes 0.5.4", "fnv", @@ -8577,7 +8576,7 @@ checksum = "4adb8b3e5f86b707f1b54e7c15b6de52617a823608ccda98a15d3a24222f265a" dependencies = [ "futures-core", "rustls 0.17.0", - "tokio 0.2.13", + "tokio 0.2.16", "webpki", ] @@ -8689,7 +8688,7 @@ dependencies = [ "futures-sink", "log", "pin-project-lite", - "tokio 0.2.13", + "tokio 0.2.16", ] [[package]] @@ -9226,18 +9225,18 @@ dependencies = [ [[package]] name = "wast" -version = "12.0.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0615ba420811bcda39cf80e8a1bd75997aec09222bda35165920a07ef15cc695" +checksum = "5b20abd8b4a26f7e0d4dd5e357e90a3d555ec190e94472c9b2b27c5b9777f9ae" dependencies = [ "leb128", ] [[package]] name = "wat" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "095f615fbfcae695e3a4cea7d9f02f70561c81274c0142f45a12bf1e154d08bd" +checksum = "51a615830ee3e7200b505c441fec09aac2f114deae69df52f215cb828ba112c4" dependencies = [ "wast", ] diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index 9308d4ee74..c791f253a9 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -11,7 +11,6 @@ description = "Client backend that uses RocksDB database as storage." [dependencies] parking_lot = "0.10.0" log = "0.4.8" -rand = "0.7" kvdb = "0.5.0" kvdb-rocksdb = { version = "0.7", optional = true } kvdb-memorydb = "0.5.0" diff --git a/client/db/src/bench.rs b/client/db/src/bench.rs index 02b30a085a..ddac2109d7 100644 --- a/client/db/src/bench.rs +++ b/client/db/src/bench.rs @@ -17,10 +17,8 @@ //! State backend that's useful for benchmarking use std::sync::Arc; -use std::path::PathBuf; use std::cell::{Cell, RefCell}; use std::collections::HashMap; -use rand::Rng; use hash_db::{Prefix, Hasher}; use sp_trie::{MemoryDB, prefixed_key}; @@ -29,12 +27,14 @@ use sp_runtime::traits::{Block as BlockT, HashFor}; use sp_runtime::Storage; use sp_state_machine::{DBValue, backend::Backend as StateBackend}; use kvdb::{KeyValueDB, DBTransaction}; -use kvdb_rocksdb::{Database, DatabaseConfig}; +use crate::storage_cache::{CachingState, SharedCache, new_shared_cache}; type DbState = sp_state_machine::TrieBackend< Arc>>, HashFor >; +type State = CachingState, B>; + struct StorageDb { db: Arc, _block: std::marker::PhantomData, @@ -50,37 +50,30 @@ impl sp_state_machine::Storage> for StorageDb { - path: PathBuf, root: Cell, genesis_root: B::Hash, - state: RefCell>>, + state: RefCell>>, db: Cell>>, genesis: HashMap, (Vec, i32)>, record: Cell>>, - cache_size_mb: Option, + shared_cache: SharedCache, // shared cache is always empty } impl BenchmarkingState { /// Create a new instance that creates a database in a temporary dir. - pub fn new(genesis: Storage, cache_size_mb: Option) -> Result { - let temp_dir = PathBuf::from(std::env::temp_dir()); - let name: String = rand::thread_rng().sample_iter(&rand::distributions::Alphanumeric).take(10).collect(); - let path = temp_dir.join(&name); - + pub fn new(genesis: Storage, _cache_size_mb: Option) -> Result { let mut root = B::Hash::default(); let mut mdb = MemoryDB::>::default(); sp_state_machine::TrieDBMut::>::new(&mut mdb, &mut root); - std::fs::create_dir(&path).map_err(|_| String::from("Error creating temp dir"))?; let mut state = BenchmarkingState { state: RefCell::new(None), db: Cell::new(None), - path, root: Cell::new(root), genesis: Default::default(), genesis_root: Default::default(), record: Default::default(), - cache_size_mb, + shared_cache: new_shared_cache(0, (1, 10)), }; state.reopen()?; @@ -96,41 +89,25 @@ impl BenchmarkingState { state.genesis = transaction.clone().drain(); state.genesis_root = root.clone(); state.commit(root, transaction)?; + state.record.take(); Ok(state) } fn reopen(&self) -> Result<(), String> { *self.state.borrow_mut() = None; - self.db.set(None); - let mut db_config = DatabaseConfig::with_columns(1); - if let Some(size) = &self.cache_size_mb { - db_config.memory_budget.insert(0, *size); - } - let path = self.path.to_str() - .ok_or_else(|| String::from("Invalid database path"))?; - let db = Arc::new(Database::open(&db_config, &path).map_err(|e| format!("Error opening database: {:?}", e))?); + let db = match self.db.take() { + Some(db) => db, + None => Arc::new(::kvdb_memorydb::create(1)), + }; self.db.set(Some(db.clone())); let storage_db = Arc::new(StorageDb:: { db, _block: Default::default() }); - *self.state.borrow_mut() = Some(DbState::::new(storage_db, self.root.get())); + *self.state.borrow_mut() = Some(State::new( + DbState::::new(storage_db, self.root.get()), + self.shared_cache.clone(), + None + )); Ok(()) } - - fn kill(&self) -> Result<(), String> { - self.db.set(None); - *self.state.borrow_mut() = None; - let mut root = B::Hash::default(); - let mut mdb = MemoryDB::>::default(); - sp_state_machine::TrieDBMut::>::new(&mut mdb, &mut root); - self.root.set(root); - - std::fs::remove_dir_all(&self.path).map_err(|_| "Error removing database dir".into()) - } -} - -impl Drop for BenchmarkingState { - fn drop(&mut self) { - self.kill().ok(); - } } fn state_err() -> String { @@ -278,6 +255,7 @@ impl StateBackend> for BenchmarkingState { self.record.set(keys); db.write(db_transaction).map_err(|_| String::from("Error committing transaction"))?; self.root.set(storage_root); + self.db.set(Some(db)) } else { return Err("Trying to commit to a closed db".into()) } @@ -296,11 +274,9 @@ impl StateBackend> for BenchmarkingState { } } db.write(db_transaction).map_err(|_| String::from("Error committing transaction"))?; + self.db.set(Some(db)); } - self.db.set(None); - *self.state.borrow_mut() = None; - self.root.set(self.genesis_root.clone()); self.reopen()?; Ok(()) @@ -317,6 +293,6 @@ impl StateBackend> for BenchmarkingState { impl std::fmt::Debug for BenchmarkingState { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "DB at {:?}", self.path) + write!(f, "Bench DB") } } -- GitLab From 54b616453cc771fee3d2dfaccc7ff2f61ed518e1 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 9 Apr 2020 11:29:11 +0200 Subject: [PATCH 199/300] Collection of enhancement for staking/phragmen. (#5534) * Collection of enhancement for staking phragmen. * Ditch signed extension * Fix build * Update frame/staking/src/lib.rs Co-Authored-By: thiolliere * Update frame/staking/src/tests.rs Co-Authored-By: thiolliere * Fix reward limits * Disallow payout_stakers * Remove unused import Co-authored-by: thiolliere --- bin/node/cli/src/factory_impl.rs | 3 +- bin/node/cli/src/service.rs | 3 +- bin/node/runtime/src/lib.rs | 4 +- bin/node/testing/src/keyring.rs | 1 - bin/utils/subkey/src/main.rs | 2 - frame/executive/src/lib.rs | 2 +- frame/staking/src/lib.rs | 240 ++++++++++------------------- frame/staking/src/testing_utils.rs | 2 +- frame/staking/src/tests.rs | 15 +- 9 files changed, 94 insertions(+), 178 deletions(-) diff --git a/bin/node/cli/src/factory_impl.rs b/bin/node/cli/src/factory_impl.rs index cd7e3022e0..1d1eabe29c 100644 --- a/bin/node/cli/src/factory_impl.rs +++ b/bin/node/cli/src/factory_impl.rs @@ -58,7 +58,6 @@ impl FactoryState { frame_system::CheckWeight::new(), pallet_transaction_payment::ChargeTransactionPayment::from(0), Default::default(), - Default::default(), ) } } @@ -123,7 +122,7 @@ impl RuntimeAdapter for FactoryState { (*amount).into() ) ) - }, key, (version, genesis_hash.clone(), prior_block_hash.clone(), (), (), (), (), ())) + }, key, (version, genesis_hash.clone(), prior_block_hash.clone(), (), (), (), ())) } fn inherent_extrinsics(&self) -> InherentData { diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 92d62364a2..257068cf14 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -617,12 +617,11 @@ mod tests { check_weight, payment, Default::default(), - Default::default(), ); let raw_payload = SignedPayload::from_raw( function, extra, - (version, genesis_hash, genesis_hash, (), (), (), (), ()) + (version, genesis_hash, genesis_hash, (), (), (), ()) ); let signature = raw_payload.using_encoded(|payload| { signer.sign(payload) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 3752ca4d8e..54e236db96 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -59,7 +59,7 @@ pub use pallet_timestamp::Call as TimestampCall; pub use pallet_balances::Call as BalancesCall; pub use pallet_contracts::Gas; pub use frame_support::StorageValue; -pub use pallet_staking::{StakerStatus, LockStakingStatus}; +pub use pallet_staking::StakerStatus; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; @@ -107,7 +107,6 @@ impl frame_system::offchain::CreateTransaction for frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), Default::default(), - Default::default(), ); let raw_payload = SignedPayload::new(call, extra).map_err(|e| { debug::warn!("Unable to create signed payload: {:?}", e); @@ -711,7 +710,6 @@ pub type SignedExtra = ( frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, pallet_contracts::CheckBlockGasLimit, - pallet_staking::LockStakingStatus, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; diff --git a/bin/node/testing/src/keyring.rs b/bin/node/testing/src/keyring.rs index 5fa1e48b03..6b0d06875d 100644 --- a/bin/node/testing/src/keyring.rs +++ b/bin/node/testing/src/keyring.rs @@ -75,7 +75,6 @@ pub fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra { frame_system::CheckWeight::new(), pallet_transaction_payment::ChargeTransactionPayment::from(extra_fee), Default::default(), - Default::default(), ) } diff --git a/bin/utils/subkey/src/main.rs b/bin/utils/subkey/src/main.rs index 237cc68df2..08a46f1190 100644 --- a/bin/utils/subkey/src/main.rs +++ b/bin/utils/subkey/src/main.rs @@ -690,7 +690,6 @@ fn create_extrinsic( frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(f), Default::default(), - Default::default(), ) }; let raw_payload = SignedPayload::from_raw( @@ -704,7 +703,6 @@ fn create_extrinsic( (), (), (), - (), ), ); let signature = raw_payload.using_encoded(|payload| signer.sign(payload)).into_runtime(); diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index f46fff1a33..20c79fe4a5 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -543,7 +543,7 @@ mod tests { frame_system::CheckEra, frame_system::CheckNonce, frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment + pallet_transaction_payment::ChargeTransactionPayment, ); type AllModules = (System, Balances, Custom); type TestXt = sp_runtime::testing::TestXt; diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 86e76408a4..da4752d248 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -288,7 +288,7 @@ use sp_runtime::{ curve::PiecewiseLinear, traits::{ Convert, Zero, StaticLookup, CheckedSub, Saturating, SaturatedConversion, AtLeast32Bit, - SignedExtension, Dispatchable, DispatchInfoOf, + Dispatchable, }, transaction_validity::{ TransactionValidityError, TransactionValidity, ValidTransaction, InvalidTransaction, @@ -315,6 +315,18 @@ const STAKING_ID: LockIdentifier = *b"staking "; pub const MAX_UNLOCKING_CHUNKS: usize = 32; pub const MAX_NOMINATIONS: usize = ::LIMIT; +// syntactic sugar for logging +#[cfg(feature = "std")] +const LOG_TARGET: &'static str = "staking"; +macro_rules! log { + ($level:tt, $patter:expr $(, $values:expr)* $(,)?) => { + debug::native::$level!( + target: LOG_TARGET, + $patter $(, $values)* + ) + }; +} + /// Data type used to index nominators in the compact type pub type NominatorIndex = u32; @@ -1128,6 +1140,8 @@ decl_error! { PhragmenBogusEdge, /// The claimed score does not match with the one computed from the data. PhragmenBogusScore, + /// The call is not allowed at the given time due to restrictions of election period. + CallNotAllowed, } } @@ -1164,26 +1178,15 @@ decl_module! { >::put( ElectionStatus::::Open(now) ); - debug::native::info!( - target: "staking", - "Election window is Open({:?}). Snapshot created", - now, - ); + log!(info, "💸 Election window is Open({:?}). Snapshot created", now); } else { - debug::native::warn!( - target: "staking", - "Failed to create snapshot at {:?}. Election window will remain closed.", - now, - ); + log!(warn, "💸 Failed to create snapshot at {:?}.", now); } } } } else { - debug::native::warn!( - target: "staking", - "estimate_next_new_session() failed to execute. Election status cannot be changed.", - ); + log!(warn, "💸 Estimating next session change failed."); } } @@ -1199,23 +1202,12 @@ decl_module! { if Self::era_election_status().is_open_at(now) { let offchain_status = set_check_offchain_execution_status::(now); if let Err(why) = offchain_status { - debug::native::warn!( - target: "staking", - "skipping offchain worker in open election window due to [{}]", - why, - ); + log!(debug, "skipping offchain worker in open election window due to [{}]", why); } else { if let Err(e) = compute_offchain_election::() { - debug::native::warn!( - target: "staking", - "Error in phragmen offchain worker: {:?}", - e, - ); + log!(warn, "💸 Error in phragmen offchain worker: {:?}", e); } else { - debug::native::debug!( - target: "staking", - "Executed offchain worker thread without errors. Transaction submitted to the pool.", - ); + log!(debug, "Executed offchain worker thread without errors."); } } } @@ -1311,7 +1303,8 @@ decl_module! { /// Unlike [`bond`] or [`unbond`] this function does not impose any limitation on the amount /// that can be added. /// - /// The dispatch origin for this call must be _Signed_ by the stash, not the controller. + /// The dispatch origin for this call must be _Signed_ by the stash, not the controller and + /// it can be only called when [`EraElectionStatus`] is `Closed`. /// /// Emits `Bonded`. /// @@ -1322,6 +1315,7 @@ decl_module! { /// # #[weight = SimpleDispatchInfo::FixedNormal(500_000)] fn bond_extra(origin, #[compact] max_additional: BalanceOf) { + ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let stash = ensure_signed(origin)?; let controller = Self::bonded(&stash).ok_or(Error::::NotStash)?; @@ -1350,6 +1344,7 @@ decl_module! { /// to be called first to remove some of the chunks (if possible). /// /// The dispatch origin for this call must be _Signed_ by the controller, not the stash. + /// And, it can be only called when [`EraElectionStatus`] is `Closed`. /// /// Emits `Unbonded`. /// @@ -1366,6 +1361,7 @@ decl_module! { /// #[weight = SimpleDispatchInfo::FixedNormal(400_000)] fn unbond(origin, #[compact] value: BalanceOf) { + ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; let mut ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; ensure!( @@ -1398,6 +1394,7 @@ decl_module! { /// whatever it wants. /// /// The dispatch origin for this call must be _Signed_ by the controller, not the stash. + /// And, it can be only called when [`EraElectionStatus`] is `Closed`. /// /// Emits `Withdrawn`. /// @@ -1412,6 +1409,7 @@ decl_module! { /// # #[weight = SimpleDispatchInfo::FixedNormal(400_000)] fn withdraw_unbonded(origin) { + ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; let mut ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let (stash, old_total) = (ledger.stash.clone(), ledger.total); @@ -1445,6 +1443,7 @@ decl_module! { /// Effects will be felt at the beginning of the next era. /// /// The dispatch origin for this call must be _Signed_ by the controller, not the stash. + /// And, it can be only called when [`EraElectionStatus`] is `Closed`. /// /// # /// - Independent of the arguments. Insignificant complexity. @@ -1453,6 +1452,7 @@ decl_module! { /// # #[weight = SimpleDispatchInfo::FixedNormal(750_000)] pub fn validate(origin, prefs: ValidatorPrefs) { + ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash = &ledger.stash; @@ -1462,9 +1462,11 @@ decl_module! { /// Declare the desire to nominate `targets` for the origin controller. /// - /// Effects will be felt at the beginning of the next era. + /// Effects will be felt at the beginning of the next era. This can only be called when + /// [`EraElectionStatus`] is `Closed`. /// /// The dispatch origin for this call must be _Signed_ by the controller, not the stash. + /// And, it can be only called when [`EraElectionStatus`] is `Closed`. /// /// # /// - The transaction's complexity is proportional to the size of `targets`, @@ -1473,6 +1475,7 @@ decl_module! { /// # #[weight = SimpleDispatchInfo::FixedNormal(750_000)] pub fn nominate(origin, targets: Vec<::Source>) { + ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash = &ledger.stash; @@ -1498,6 +1501,7 @@ decl_module! { /// Effects will be felt at the beginning of the next era. /// /// The dispatch origin for this call must be _Signed_ by the controller, not the stash. + /// And, it can be only called when [`EraElectionStatus`] is `Closed`. /// /// # /// - Independent of the arguments. Insignificant complexity. @@ -1506,6 +1510,7 @@ decl_module! { /// # #[weight = SimpleDispatchInfo::FixedNormal(500_000)] fn chill(origin) { + ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; Self::chill_stash(&ledger.stash); @@ -1557,8 +1562,6 @@ decl_module! { } } - // ----- Root calls. - /// The ideal number of validators. #[weight = SimpleDispatchInfo::FixedNormal(5_000)] fn set_validator_count(origin, #[compact] new: u32) { @@ -1681,8 +1684,8 @@ decl_module! { fn payout_nominator(origin, era: EraIndex, validators: Vec<(T::AccountId, u32)>) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::do_payout_nominator(who, era, validators) + let ctrl = ensure_signed(origin)?; + Self::do_payout_nominator(ctrl, era, validators) } /// **This extrinsic will be removed after `MigrationEra + HistoryDepth` has passed, giving @@ -1706,8 +1709,8 @@ decl_module! { /// # #[weight = SimpleDispatchInfo::FixedNormal(500_000)] fn payout_validator(origin, era: EraIndex) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::do_payout_validator(who, era) + let ctrl = ensure_signed(origin)?; + Self::do_payout_validator(ctrl, era) } /// Pay out all the stakers behind a single validator for a single era. @@ -1719,30 +1722,34 @@ decl_module! { /// The origin of this call must be _Signed_. Any account can call this function, even if /// it is not one of the stakers. /// + /// This can only be called when [`EraElectionStatus`] is `Closed`. + /// /// # /// - Time complexity: at most O(MaxNominatorRewardedPerValidator). /// - Contains a limited number of reads and writes. /// # #[weight = SimpleDispatchInfo::FixedNormal(500_000)] fn payout_stakers(origin, validator_stash: T::AccountId, era: EraIndex) -> DispatchResult { + ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); ensure_signed(origin)?; Self::do_payout_stakers(validator_stash, era) } /// Rebond a portion of the stash scheduled to be unlocked. /// + /// The dispatch origin must be signed by the controller, and it can be only called when + /// [`EraElectionStatus`] is `Closed`. + /// /// # /// - Time complexity: O(1). Bounded by `MAX_UNLOCKING_CHUNKS`. /// - Storage changes: Can't increase storage, only decrease it. /// # #[weight = SimpleDispatchInfo::FixedNormal(500_000)] fn rebond(origin, #[compact] value: BalanceOf) { + ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; - ensure!( - !ledger.unlocking.is_empty(), - Error::::NoUnlockChunk, - ); + ensure!(!ledger.unlocking.is_empty(), Error::::NoUnlockChunk); let ledger = ledger.rebond(value); Self::update_ledger(&controller, &ledger); @@ -1965,9 +1972,9 @@ impl Module { num_validators > MAX_VALIDATORS || num_nominators.saturating_add(num_validators) > MAX_NOMINATORS { - debug::native::warn!( - target: "staking", - "Snapshot size too big [{} <> {}][{} <> {}].", + log!( + warn, + "💸 Snapshot size too big [{} <> {}][{} <> {}].", num_validators, MAX_VALIDATORS, num_nominators, @@ -1990,7 +1997,7 @@ impl Module { >::kill(); } - fn do_payout_nominator(who: T::AccountId, era: EraIndex, validators: Vec<(T::AccountId, u32)>) + fn do_payout_nominator(ctrl: T::AccountId, era: EraIndex, validators: Vec<(T::AccountId, u32)>) -> DispatchResult { // validators len must not exceed `MAX_NOMINATIONS` to avoid querying more validator @@ -2013,7 +2020,12 @@ impl Module { let era_payout = >::get(&era) .ok_or_else(|| Error::::InvalidEraToReward)?; - let mut nominator_ledger = >::get(&who).ok_or_else(|| Error::::NotController)?; + let mut nominator_ledger = >::get(&ctrl).ok_or_else(|| Error::::NotController)?; + + ensure!( + Self::era_election_status().is_closed() || Self::payee(&nominator_ledger.stash) != RewardDestination::Staked, + Error::::CallNotAllowed, + ); nominator_ledger.claimed_rewards.retain(|&x| x >= current_era.saturating_sub(history_depth)); match nominator_ledger.claimed_rewards.binary_search(&era) { @@ -2021,7 +2033,7 @@ impl Module { Err(pos) => nominator_ledger.claimed_rewards.insert(pos, era), } - >::insert(&who, &nominator_ledger); + >::insert(&ctrl, &nominator_ledger); let mut reward = Perbill::zero(); let era_reward_points = >::get(&era); @@ -2057,13 +2069,13 @@ impl Module { } if let Some(imbalance) = Self::make_payout(&nominator_ledger.stash, reward * era_payout) { - Self::deposit_event(RawEvent::Reward(who, imbalance.peek())); + Self::deposit_event(RawEvent::Reward(ctrl, imbalance.peek())); } Ok(()) } - fn do_payout_validator(who: T::AccountId, era: EraIndex) -> DispatchResult { + fn do_payout_validator(ctrl: T::AccountId, era: EraIndex) -> DispatchResult { // If migrate_era is not populated, then you should use `payout_stakers` let migrate_era = MigrateEra::get().ok_or(Error::::InvalidEraToReward)?; // This payout mechanism will only work for eras before the migration. @@ -2079,7 +2091,12 @@ impl Module { let era_payout = >::get(&era) .ok_or_else(|| Error::::InvalidEraToReward)?; - let mut ledger = >::get(&who).ok_or_else(|| Error::::NotController)?; + let mut ledger = >::get(&ctrl).ok_or_else(|| Error::::NotController)?; + + ensure!( + Self::era_election_status().is_closed() || Self::payee(&ledger.stash) != RewardDestination::Staked, + Error::::CallNotAllowed, + ); ledger.claimed_rewards.retain(|&x| x >= current_era.saturating_sub(history_depth)); match ledger.claimed_rewards.binary_search(&era) { @@ -2087,7 +2104,7 @@ impl Module { Err(pos) => ledger.claimed_rewards.insert(pos, era), } - >::insert(&who, &ledger); + >::insert(&ctrl, &ledger); let era_reward_points = >::get(&era); let commission = Self::eras_validator_prefs(&era, &ledger.stash).commission; @@ -2111,7 +2128,7 @@ impl Module { ); if let Some(imbalance) = Self::make_payout(&ledger.stash, reward * era_payout) { - Self::deposit_event(RawEvent::Reward(who, imbalance.peek())); + Self::deposit_event(RawEvent::Reward(ctrl, imbalance.peek())); } Ok(()) @@ -2121,7 +2138,7 @@ impl Module { validator_stash: T::AccountId, era: EraIndex, ) -> DispatchResult { - /* Validate input data */ + // Validate input data let current_era = CurrentEra::get().ok_or(Error::::InvalidEraToReward)?; ensure!(era <= current_era, Error::::InvalidEraToReward); let history_depth = Self::history_depth(); @@ -2377,11 +2394,7 @@ impl Module { validator_at, ).map_err(|e| { // log the error since it is not propagated into the runtime error. - debug::native::warn!( - target: "staking", - "un-compacting solution failed due to {:?}", - e, - ); + log!(warn, "💸 un-compacting solution failed due to {:?}", e); Error::::PhragmenBogusCompact })?; @@ -2396,10 +2409,7 @@ impl Module { // all of the indices must map to either a validator or a nominator. If this is ever // not the case, then the locking system of staking is most likely faulty, or we // have bigger problems. - debug::native::error!( - target: "staking", - "detected an error in the staking locking and snapshot." - ); + log!(error, "💸 detected an error in the staking locking and snapshot."); // abort. return Err(Error::::PhragmenBogusNominator); } @@ -2463,9 +2473,9 @@ impl Module { // At last, alles Ok. Exposures and store the result. let exposures = Self::collect_exposure(supports); - debug::native::info!( - target: "staking", - "A better solution (with compute {:?}) has been validated and stored on chain.", + log!( + info, + "💸 A better solution (with compute {:?}) has been validated and stored on chain.", compute, ); @@ -2646,9 +2656,9 @@ impl Module { // emit event Self::deposit_event(RawEvent::StakingElection(compute)); - debug::native::info!( - target: "staking", - "new validator set of size {:?} has been elected via {:?} for era {:?}", + log!( + info, + "💸 new validator set of size {:?} has been elected via {:?} for era {:?}", elected_stashes.len(), compute, current_era, @@ -3112,81 +3122,9 @@ impl ReportOffence } } -/// Disallows any transactions that change the election result to be submitted after the election -/// window is open. -#[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct LockStakingStatus(sp_std::marker::PhantomData); - -impl sp_std::fmt::Debug for LockStakingStatus { - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - write!(f, "LockStakingStatus") - } -} - -impl LockStakingStatus { - /// Create new `LockStakingStatus`. - pub fn new() -> Self { - Self(sp_std::marker::PhantomData) - } -} - -impl Default for LockStakingStatus { - fn default() -> Self { - Self::new() - } -} - -impl SignedExtension for LockStakingStatus { - const IDENTIFIER: &'static str = "LockStakingStatus"; - type AccountId = T::AccountId; - type Call = ::Call; - type AdditionalSigned = (); - type Pre = (); - - fn additional_signed(&self) -> Result<(), TransactionValidityError> { Ok(()) } - - fn validate( - &self, - _who: &Self::AccountId, - call: &Self::Call, - _info: &DispatchInfoOf, - _len: usize, - ) -> TransactionValidity { - if let Some(inner_call) = call.is_sub_type() { - if let ElectionStatus::Open(_) = >::era_election_status() { - match inner_call { - Call::::set_payee(..) | - Call::::set_controller(..) | - Call::::set_validator_count(..) | - Call::::force_no_eras(..) | - Call::::force_new_era(..) | - Call::::set_invulnerables(..) | - Call::::force_unstake(..) | - Call::::force_new_era_always(..) | - Call::::cancel_deferred_slash(..) | - Call::::set_history_depth(..) | - Call::::reap_stash(..) | - Call::::submit_election_solution(..) | - Call::::submit_election_solution_unsigned(..) => { - // These calls are allowed. Nothing. - } - _ => { - return Err(InvalidTransaction::Stale.into()); - } - } - } - } - - Ok(Default::default()) - } -} - impl From> for InvalidTransaction { fn from(e: Error) -> Self { - match e { - >::PhragmenEarlySubmission => InvalidTransaction::Future, - _ => InvalidTransaction::Custom(e.as_u8()), - } + InvalidTransaction::Custom(e.as_u8()) } } @@ -3206,29 +3144,17 @@ impl frame_support::unsigned::ValidateUnsigned for Module { match source { TransactionSource::Local | TransactionSource::InBlock => { /* allowed */ } _ => { - debug::native::debug!( - target: "staking", - "rejecting unsigned transaction because it is not local/in-block." - ); + log!(debug, "rejecting unsigned transaction because it is not local/in-block."); return InvalidTransaction::Call.into(); } } if let Err(e) = Self::pre_dispatch_checks(*score, *era) { - debug::native::debug!( - target: "staking", - "validate unsigned failed due to {:?}.", - e, - ); - let invalid: InvalidTransaction = e.into(); - return invalid.into(); + log!(debug, "validate unsigned pre dispatch checks failed due to {:?}.", e); + return InvalidTransaction::from(e).into(); } - debug::native::debug!( - target: "staking", - "Validated an unsigned transaction from the local node for era {}.", - era, - ); + log!(debug, "validateUnsigned succeeded for a solution at era {}.", era); ValidTransaction::with_tag_prefix("StakingOffchain") // The higher the score[0], the better a solution is. diff --git a/frame/staking/src/testing_utils.rs b/frame/staking/src/testing_utils.rs index 29a395b89d..4c1ee66a75 100644 --- a/frame/staking/src/testing_utils.rs +++ b/frame/staking/src/testing_utils.rs @@ -18,7 +18,7 @@ //! //! Note that these helpers should NOT be used with the actual crate tests, but are rather designed //! for when the module is being externally tested (i.e. fuzzing, benchmarking, e2e tests). Enabling -//! this feature in the current crate's Cargo.toml will leak the all of this into a normal release +//! this feature in the current crate's Cargo.toml will leak all of this into a normal release //! build. Just don't do it. use crate::*; diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 321fcb34ef..da8180639c 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -2902,7 +2902,6 @@ mod offchain_phragmen { fn offchain_wont_work_if_snapshot_fails() { ExtBuilder::default() .offchain_phragmen_ext() - .election_lookahead(3) .build() .execute_with(|| { run_to_block(12); @@ -2932,16 +2931,14 @@ mod offchain_phragmen { .execute_with(|| { run_to_block(12); assert!(Staking::snapshot_validators().is_some()); + // given assert_eq!(Staking::era_election_status(), ElectionStatus::Open(12)); - let call = crate::Call::bond(999, 998, Default::default()); - let outer: mock::Call = call.into(); - - let lock_staking: LockStakingStatus = Default::default(); - assert_eq!( - lock_staking.validate(&10, &outer, &Default::default(), Default::default(),), - TransactionValidity::Err(InvalidTransaction::Stale.into()), - ) + // chill et. al. are now not allowed. + assert_noop!( + Staking::chill(Origin::signed(10)), + Error::::CallNotAllowed, + ); }) } -- GitLab From 79809a6a21cde2e9554f4948fa2fb0d48e17dee6 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 9 Apr 2020 11:30:33 +0200 Subject: [PATCH 200/300] =?UTF-8?q?Forcing-aware=20offchain=20Phragm=C3=A9?= =?UTF-8?q?n.=20(#5580)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Make it force-aware * Fix merge issues --- frame/staking/src/lib.rs | 13 +++++++++++-- frame/staking/src/tests.rs | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index da4752d248..da860bd63e 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -1010,7 +1010,8 @@ decl_storage! { /// solutions to be submitted. pub EraElectionStatus get(fn era_election_status): ElectionStatus; - /// True if the current planned session is final. + /// True if the current **planned** session is final. Note that this does not take era + /// forcing into account. pub IsCurrentSessionFinal get(fn is_current_session_final): bool = false; /// True if network has been upgraded to this version. @@ -1166,7 +1167,8 @@ decl_module! { if // if we don't have any ongoing offchain compute. Self::era_election_status().is_closed() && - Self::is_current_session_final() + // either current session final based on the plan, or we're forcing. + (Self::is_current_session_final() || Self::will_era_be_forced()) { if let Some(next_session_change) = T::NextNewSession::estimate_next_new_session(now){ if let Some(remaining) = next_session_change.checked_sub(&now) { @@ -2895,6 +2897,13 @@ impl Module { } } + fn will_era_be_forced() -> bool { + match ForceEra::get() { + Forcing::ForceAlways | Forcing::ForceNew => true, + Forcing::ForceNone | Forcing::NotForcing => false, + } + } + #[cfg(feature = "runtime-benchmarks")] pub fn add_era_stakers(current_era: EraIndex, controller: T::AccountId, exposure: Exposure>) { >::insert(¤t_era, &controller, &exposure); diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index da8180639c..75c4edae22 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -2872,6 +2872,27 @@ mod offchain_phragmen { }) } + #[test] + fn offchain_election_flag_is_triggered_when_forcing() { + ExtBuilder::default() + .session_per_era(5) + .session_length(10) + .election_lookahead(3) + .build() + .execute_with(|| { + run_to_block(7); + assert_session_era!(0, 0); + + run_to_block(12); + ForceEra::put(Forcing::ForceNew); + run_to_block(13); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + + run_to_block(17); // instead of 47 + assert_eq!(Staking::era_election_status(), ElectionStatus::Open(17)); + }) + } + #[test] fn election_on_chain_fallback_works() { ExtBuilder::default().build().execute_with(|| { -- GitLab From c960f109c5a539536ee21a0eedda60aceecfa42b Mon Sep 17 00:00:00 2001 From: Roman Borschel Date: Thu, 9 Apr 2020 12:41:34 +0200 Subject: [PATCH 201/300] Do not prematurely emit CustomProtocolClosed on connection close. (#5595) --- client/network/src/protocol/generic_proto/behaviour.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index 49744a5d86..e62edb3733 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -914,7 +914,7 @@ impl NetworkBehaviour for GenericProto { // in which case `CustomProtocolClosed` was already emitted. let closed = open.is_empty(); open.retain(|c| c != conn); - if !closed { + if open.is_empty() && !closed { debug!(target: "sub-libp2p", "External API <= Closed({})", peer_id); let event = GenericProtoOut::CustomProtocolClosed { peer_id: peer_id.clone(), -- GitLab From 3f0e44481a83949dfd8b76f5c866470ca32295e3 Mon Sep 17 00:00:00 2001 From: s3krit Date: Thu, 9 Apr 2020 12:58:28 +0200 Subject: [PATCH 202/300] CI: Release - monitor gitlab pipeline (#5460) * Initial commit of gitlab pipeline monitoring * increase max job time * Improve debug output * s/PR/issue/ Co-authored-by: Benjamin Kampmann --- .github/ISSUE_TEMPLATE/release.md | 9 +++++ .github/workflows/check-gitlab-pipeline.yml | 30 +++++++++++++++++ .maintain/github/check_gitlab_pipeline.sh | 37 +++++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/release.md create mode 100644 .github/workflows/check-gitlab-pipeline.yml create mode 100755 .maintain/github/check_gitlab_pipeline.sh diff --git a/.github/ISSUE_TEMPLATE/release.md b/.github/ISSUE_TEMPLATE/release.md new file mode 100644 index 0000000000..6067dbf12f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release.md @@ -0,0 +1,9 @@ +--- +title: Release failure for {{ ref }} +--- + +Pipeline for release {{ ref }} failed. Please investigate. + +If the pipeline has failed before pushing to crates.io, delete the release tag +and fix the release as necessary, retagging after complete. If the pipeline has +failed after pushing to crates.io, create a new tag incrementing the version. diff --git a/.github/workflows/check-gitlab-pipeline.yml b/.github/workflows/check-gitlab-pipeline.yml new file mode 100644 index 0000000000..c87f17c2f7 --- /dev/null +++ b/.github/workflows/check-gitlab-pipeline.yml @@ -0,0 +1,30 @@ +# A github action to track the status of the gitlab pipeline for tagged +# releases, and cancel the release/create a new issue if it fails + +name: Monitor gitlab pipeline status + +on: + push: + tags: + - v* + - ci-release-* + +jobs: + monitor: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Monitor pipeline + run: env; ./.maintain/github/check_gitlab_pipeline.sh + id: monitor_pipeline + env: + TAGGER: ${{ github.event.pusher.name }} + - name: Create Issue + if: failure() + uses: JasonEtco/create-an-issue@v2 + with: + filename: .github/ISSUE_TEMPLATE/release.md + assignees: ${{ github.event.pusher.name }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.maintain/github/check_gitlab_pipeline.sh b/.maintain/github/check_gitlab_pipeline.sh new file mode 100755 index 0000000000..e7aaff15bf --- /dev/null +++ b/.maintain/github/check_gitlab_pipeline.sh @@ -0,0 +1,37 @@ +#!/bin/bash +SUBSTRATE_API_BASEURL="https://gitlab.parity.io/api/v4/projects/145" + +TAG_NAME=$(echo "$GITHUB_REF" | sed -E 's_refs/tags/(.*)_\1_') +PIPELINE_ID=$(curl -s $SUBSTRATE_API_BASEURL/pipelines | jq -r "map(select(.ref==\"$TAG_NAME\")) | .[0] | .id") +if [ "$PIPELINE_ID" == "null" ]; then + echo "[!] Pipeline for $TAG_NAME not found. Exiting." + exit 1 +fi + +echo "[+] Pipeline path: https://gitlab.parity.io/parity/substrate/pipelines/$PIPELINE_ID" + +# 130 minute job max +for (( c=0; c < 130; c++ )); do + out=$(curl -s "$SUBSTRATE_API_BASEURL/pipelines/$PIPELINE_ID" | jq -r .status) + case $out in + "success") + echo "[+] Pipeline $PIPELINE_ID for $TAG_NAME succeeded!" + exit 0 + ;; + "failed") + echo "[!] Pipeline $PIPELINE_ID for $TAG_NAME failed. Cannot proceed. Check job output on gitlab!" + exit 1 + ;; + "cancelled") + echo "[!] Pipeline $PIPELINE_ID for $TAG_NAME was cancelled. Cannot proceed!" + exit 1 + ;; + "running") + echo "[-] Pipeline $PIPELINE_ID for $TAG_NAME still in progress..." + esac + sleep 60 +done +# If we reach here, we timed out after 30 minutes +echo "[!] Pipeline $PIPELINE_ID for $TAG_NAME timed out! Cannot proceed" +echo "::set-output name=pipeline_status::timedout" +exit 1 -- GitLab From 611ce978fbd3ad793e9886c85dd34300bff9c659 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 9 Apr 2020 18:41:21 +0200 Subject: [PATCH 203/300] Update to libp2p 0.18 (#5602) * Update to libp2p 0.18 * Update Cargo.lock * Also bump in browser-utils --- Cargo.lock | 144 +++++++++++-------------- bin/utils/subkey/Cargo.toml | 2 +- client/authority-discovery/Cargo.toml | 2 +- client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 4 +- client/network/src/service.rs | 4 +- client/network/test/Cargo.toml | 2 +- client/peerset/Cargo.toml | 2 +- client/telemetry/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 4 +- utils/browser/Cargo.toml | 2 +- 11 files changed, 74 insertions(+), 96 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 31badd989f..affa982bd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,14 +233,14 @@ dependencies = [ [[package]] name = "async-tls" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce6977f57fa68da77ffe5542950d47e9c23d65f5bc7cb0a9f8700996913eec7" +checksum = "95fd83426b89b034bf4e9ceb9c533c2f2386b813fd3dcae0a425ec6f1837d78a" dependencies = [ "futures 0.3.4", - "rustls 0.16.0", + "rustls", "webpki", - "webpki-roots 0.17.0", + "webpki-roots 0.19.0", ] [[package]] @@ -294,15 +294,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" -[[package]] -name = "base64" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -dependencies = [ - "byteorder 1.3.4", -] - [[package]] name = "base64" version = "0.11.0" @@ -2202,7 +2193,7 @@ dependencies = [ "futures-util", "hyper 0.13.4", "log", - "rustls 0.17.0", + "rustls", "rustls-native-certs", "tokio 0.2.16", "tokio-rustls", @@ -2612,9 +2603,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a261244b8d7ff58f5d62ffa33589eb1ba7733a1dfee0902ad9fdfe62ada7009" +checksum = "aa5aedb713f76577818529be8283e35ec5e8b3ecdccfe0231ba4d860687438ab" dependencies = [ "bytes 0.5.4", "futures 0.3.4", @@ -2650,9 +2641,9 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.17.1" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfe1412f2afe1366a2661abd211bb1a27ee6a664d799071282f4fba997c6858" +checksum = "a1d2c17158c4dca984a77a5927aac6f0862d7f50c013470a415f93be498b5739" dependencies = [ "asn1_der", "bs58", @@ -2684,9 +2675,9 @@ dependencies = [ [[package]] name = "libp2p-core-derive" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0eeb25d5f152a826eac57c7d1cc3de10d72dc4051e90fe4c0cd139f07a069a3" +checksum = "329127858e4728db5ab60c33d5ae352a999325fdf190ed022ec7d3a4685ae2e6" dependencies = [ "quote 1.0.3", "syn 1.0.17", @@ -2694,9 +2685,9 @@ dependencies = [ [[package]] name = "libp2p-deflate" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136fcef31e3247f51946c3ebefb94d0798c4c8aae78bc59cb7431b220b5330cf" +checksum = "4ad32b006ea922da8cc66e537cf2df4b0fad8ebaa467d2a8c63d7784ac252ec6" dependencies = [ "flate2", "futures 0.3.4", @@ -2705,9 +2696,9 @@ dependencies = [ [[package]] name = "libp2p-dns" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "647178f8683bf868f7f14d5e5718dbdc2445b9f6b24ce99da96cecd7c5d2d1a6" +checksum = "c0d0993481203d68e5ce2f787d033fb0cac6b850659ed6c784612db678977c71" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2716,9 +2707,9 @@ dependencies = [ [[package]] name = "libp2p-floodsub" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34c8dee172fd1630caf91a427d601d6a8d24c8cfcbcf7d5c09c9a1f3b4bbebc2" +checksum = "3673153ca967c179d745fadf047d069355d6669ecf7f261b450fbaebf1bffd3d" dependencies = [ "cuckoofilter", "fnv", @@ -2733,11 +2724,11 @@ dependencies = [ [[package]] name = "libp2p-gossipsub" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0042a2156fb6264bda9def93070e411dfaddf8c57c4b2d63634190d296458c76" +checksum = "3f7f3f79f060864db0317cc47641b7d35276dee52a0ffa91553fbd0c153863a3" dependencies = [ - "base64 0.11.0", + "base64", "byteorder 1.3.4", "bytes 0.5.4", "fnv", @@ -2758,9 +2749,9 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04efa011cda5232648b5aa50bd80be7ba0a695d682b01aa46b65e5be5ece0605" +checksum = "a38ca3eb807789e26f41c82ca7cd2b3843c66c5587b8b5f709a2f421f3061414" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2774,9 +2765,9 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97f4722d83af8fc0065cee7589a000b629961c1c11d90ba09f6685b3e123b9ae" +checksum = "a92cda1fb8149ea64d092a2b99d2bd7a2c309eee38ea322d02e4480bd6ee1759" dependencies = [ "arrayvec 0.5.1", "bytes 0.5.4", @@ -2801,9 +2792,9 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b752276b3bea2fca1c291f43cefc8082d8a639bb8f9052cf5adc6accfcd7b44e" +checksum = "41e908d2aaf8ff0ec6ad1f02fe1844fd777fb0b03a68a226423630750ab99471" dependencies = [ "async-std", "data-encoding", @@ -2823,9 +2814,9 @@ dependencies = [ [[package]] name = "libp2p-mplex" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f317db8c062beecde87a8765ca03784e6f1a55daa5b9868bf60ebf9b9a2b92f" +checksum = "0832882b06619b2e81d74e71447753ea3c068164a0bca67847d272e856a04a02" dependencies = [ "bytes 0.5.4", "fnv", @@ -2839,9 +2830,9 @@ dependencies = [ [[package]] name = "libp2p-noise" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98d3845f54288ff134dd78c131517bad8bc03965def6e6517efef03291d9b4d7" +checksum = "918e94a649e1139c24ee9f1f8c1f2adaba6d157b9471af787f2d9beac8c29c77" dependencies = [ "curve25519-dalek", "futures 0.3.4", @@ -2860,9 +2851,9 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa1cb80ccbedb91d9b980aafc6bf39dc7e4616a7e37c631a4e6ef62629567a13" +checksum = "f9bfbf87eebb492d040f9899c5c81c9738730465ac5e78d9b7a7d086d0f07230" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2875,9 +2866,9 @@ dependencies = [ [[package]] name = "libp2p-plaintext" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da16d35e3990cc5dc22c8d7ea4a2aa1c18f518491bb29c0c3498fb9a2d8e486e" +checksum = "fabb00553a49bf6d4a8ce362f6eefac410227a14d03c3acffbb8cc3f022ea019" dependencies = [ "bytes 0.5.4", "futures 0.3.4", @@ -2893,9 +2884,9 @@ dependencies = [ [[package]] name = "libp2p-pnet" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45d11e8c6d83e294ef3d7ff3a9f5a7aa5aa0c39c2d4991f2905c23c438c84526" +checksum = "9f81b8b37ff529e1f51c20c396dac657def2108da174c1d27e57e72c9fe2d411" dependencies = [ "futures 0.3.4", "log", @@ -2907,9 +2898,9 @@ dependencies = [ [[package]] name = "libp2p-secio" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74130fa95effb780850ec790b7af777b893108d9b5983ab994b61d93d2eb0336" +checksum = "a7a0509a7e47245259954fef58b85b81bf4d29ae33a4365e38d718a866698774" dependencies = [ "aes-ctr", "ctr", @@ -2937,9 +2928,9 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4ec53df8978a5d6d9dac243fb1e3adf004f8b8d28f72e6f2160df34d5f39564" +checksum = "622605817885e67b5572189c2507e514b786beb69ed85a120dbb245a7f15383d" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2952,9 +2943,9 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25c9d9c5448c189bba7ecdd1ca23800516281476e82810eff711ef04abaf9eb" +checksum = "b37ea44823d3ed223e4605da94b50177bc520f05ae2452286700549a32d81669" dependencies = [ "async-std", "futures 0.3.4", @@ -2967,9 +2958,9 @@ dependencies = [ [[package]] name = "libp2p-uds" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8dbcbe6567ea1b3c98ba4df5fd9d1b7c2bebbf50d46ceb0c2ce735c55af3f8d" +checksum = "281c18ea2faacb9c8a6ff76c4405df5918d9a263770e3847bf03f099abadc010" dependencies = [ "async-std", "futures 0.3.4", @@ -2979,9 +2970,9 @@ dependencies = [ [[package]] name = "libp2p-wasm-ext" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076446cabb23b0d79d2375661d837a43cbda6719d88787f234e7661c33ef9554" +checksum = "e3ac7dbde0f88cad191dcdfd073b8bae28d01823e8ca313f117b6ecb914160c3" dependencies = [ "futures 0.3.4", "js-sys", @@ -2993,9 +2984,9 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0117ed6a6f60114c107c1232a0890a8fe997013c7e1920b6f0c811e05d2fae7" +checksum = "6874c9069ce93d899df9dc7b29f129c706b2a0fdc048f11d878935352b580190" dependencies = [ "async-tls", "bytes 0.5.4", @@ -3004,7 +2995,7 @@ dependencies = [ "libp2p-core", "log", "quicksink", - "rustls 0.16.0", + "rustls", "rw-stream-sink", "soketto", "url 2.1.1", @@ -3014,9 +3005,9 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee12c49426527908f81ffb6551b95f57149a8ea64f386bb7da3b123cdb9c01ba" +checksum = "02f91aea50f6571e0bc6c058dc0e9b270afd41ec28dd94e9e4bf607e78b9ab87" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -5624,7 +5615,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" dependencies = [ - "base64 0.11.0", + "base64", "blake2b_simd", "constant_time_eq", "crossbeam-utils", @@ -5657,26 +5648,13 @@ dependencies = [ "semver 0.9.0", ] -[[package]] -name = "rustls" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e" -dependencies = [ - "base64 0.10.1", - "log", - "ring", - "sct", - "webpki", -] - [[package]] name = "rustls" version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1" dependencies = [ - "base64 0.11.0", + "base64", "log", "ring", "sct", @@ -5690,7 +5668,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75ffeb84a6bd9d014713119542ce415db3a3e4748f0bfce1e1416cd224a23a5" dependencies = [ "openssl-probe", - "rustls 0.17.0", + "rustls", "schannel", "security-framework", ] @@ -7105,7 +7083,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c9dab3f95c9ebdf3a88268c19af668f637a3c5039c2c56ff2d40b1b2d64a25b" dependencies = [ - "base64 0.11.0", + "base64", "bytes 0.5.4", "flate2", "futures 0.3.4", @@ -8575,7 +8553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4adb8b3e5f86b707f1b54e7c15b6de52617a823608ccda98a15d3a24222f265a" dependencies = [ "futures-core", - "rustls 0.17.0", + "rustls", "tokio 0.2.16", "webpki", ] @@ -9185,7 +9163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80f3dea0e60c076dd0da27fa10c821323903c9554c617ed32eaab8e7a7e36c89" dependencies = [ "anyhow", - "base64 0.11.0", + "base64", "bincode", "cranelift-codegen", "cranelift-entity", @@ -9263,18 +9241,18 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a262ae37dd9d60f60dd473d1158f9fbebf110ba7b6a5051c8160460f6043718b" +checksum = "91cd5736df7f12a964a5067a12c62fa38e1bd8080aff1f80bc29be7c80d19ab4" dependencies = [ "webpki", ] [[package]] name = "webpki-roots" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cd5736df7f12a964a5067a12c62fa38e1bd8080aff1f80bc29be7c80d19ab4" +checksum = "f8eff4b7516a57307f9349c64bf34caa34b940b66fed4b2fb3136cb7386e5739" dependencies = [ "webpki", ] diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index 672f25275c..688f066ef1 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -29,7 +29,7 @@ derive_more = { version = "0.99.2" } sc-rpc = { version = "2.0.0-alpha.5", path = "../../../client/rpc" } jsonrpc-core-client = { version = "14.0.3", features = ["http"] } hyper = "0.12.35" -libp2p = "0.17.0" +libp2p = "0.18.0" serde_json = "1.0" [features] diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 7521101ae6..0aa1e6a6dc 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -18,7 +18,7 @@ codec = { package = "parity-scale-codec", default-features = false, version = "1 derive_more = "0.99.2" futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.17.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } +libp2p = { version = "0.18.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } log = "0.4.8" prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.5"} prost = "0.6.1" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index c2887ed719..75fc6c56bd 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/sc-network-gossip" [dependencies] futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.17.0", default-features = false, features = ["websocket"] } +libp2p = { version = "0.18.0", default-features = false, features = ["websocket"] } log = "0.4.8" lru = "0.4.3" sc-network = { version = "0.8.0-alpha.5", path = "../network" } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 5b4813e80a..098fae6018 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -59,7 +59,7 @@ void = "1.0.2" zeroize = "1.0.0" [dependencies.libp2p] -version = "0.17.0" +version = "0.18.0" default-features = false features = ["websocket", "kad", "mdns", "ping", "identify", "mplex", "yamux", "noise"] @@ -67,7 +67,7 @@ features = ["websocket", "kad", "mdns", "ping", "identify", "mplex", "yamux", "n async-std = "1.5" assert_matches = "1.3" env_logger = "0.7.0" -libp2p = { version = "0.17.0", default-features = false, features = ["secio"] } +libp2p = { version = "0.18.0", default-features = false, features = ["secio"] } quickcheck = "0.9.0" rand = "0.7.2" sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 55e257c5ae..ba4cdcecdf 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -1133,8 +1133,6 @@ impl Future for NetworkWorker { match cause { ConnectionError::IO(_) => metrics.connections_closed_total.with_label_values(&["transport-error"]).inc(), - ConnectionError::ConnectionLimit(_) => - metrics.connections_closed_total.with_label_values(&["limit-reached"]).inc(), ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( EitherError::A(EitherError::B(EitherError::A(PingFailure::Timeout))))))) => metrics.connections_closed_total.with_label_values(&["ping-timeout"]).inc(), @@ -1180,6 +1178,8 @@ impl Future for NetworkWorker { if let Some(metrics) = this.metrics.as_ref() { match error { + PendingConnectionError::ConnectionLimit(_) => + metrics.pending_connections_errors_total.with_label_values(&["limit-reached"]).inc(), PendingConnectionError::InvalidPeerId => metrics.pending_connections_errors_total.with_label_values(&["invalid-peer-id"]).inc(), PendingConnectionError::Transport(_) | PendingConnectionError::IO(_) => diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index 90202008eb..bdba0cc205 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -16,7 +16,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" rand = "0.7.2" -libp2p = { version = "0.17.0", default-features = false, features = ["libp2p-websocket"] } +libp2p = { version = "0.18.0", default-features = false, features = ["libp2p-websocket"] } sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } sc-client = { version = "0.8.0-alpha.5", path = "../../" } sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index e026c6063a..9385e7487b 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.rs/sc-peerset" [dependencies] futures = "0.3.4" -libp2p = { version = "0.17.0", default-features = false } +libp2p = { version = "0.18.0", default-features = false } sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils"} log = "0.4.8" serde_json = "1.0.41" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index dcf218e976..5cdc4a870e 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -16,7 +16,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" wasm-timer = "0.2.0" -libp2p = { version = "0.17.0", default-features = false, features = ["websocket", "wasm-ext", "tcp", "dns"] } +libp2p = { version = "0.18.0", default-features = false, features = ["websocket", "wasm-ext", "tcp", "dns"] } log = "0.4.8" pin-project = "0.4.6" rand = "0.7.2" diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 4734cde694..8b769479d3 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -12,9 +12,9 @@ documentation = "https://docs.rs/sp-consensus/" [dependencies] derive_more = "0.99.2" -libp2p = { version = "0.17.0", default-features = false } +libp2p = { version = "0.18.0", default-features = false } log = "0.4.8" -sp-core = { path= "../../core" , version = "2.0.0-alpha.5"} +sp-core = { path= "../../core", version = "2.0.0-alpha.5"} sp-inherents = { version = "2.0.0-alpha.5", path = "../../inherents" } sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } futures = { version = "0.3.1", features = ["thread-pool"] } diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 5f6b18e001..427f067751 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/paritytech/substrate/" futures = "0.3" futures01 = { package = "futures", version = "0.1.29" } log = "0.4.8" -libp2p-wasm-ext = { version = "0.17.0", features = ["websocket"] } +libp2p-wasm-ext = { version = "0.18.0", features = ["websocket"] } console_error_panic_hook = "0.1.6" console_log = "0.1.2" js-sys = "0.3.34" -- GitLab From cb3e628610562318f0a955f26c9eff558a7ce237 Mon Sep 17 00:00:00 2001 From: Stanislav Tkach Date: Thu, 9 Apr 2020 19:50:47 +0300 Subject: [PATCH 204/300] Hide benchmarking CLI behind the feature flag (#5600) * Hide benchmarking CLI behind the feature flag * Add a message --- bin/node/cli/Cargo.toml | 5 ++++- bin/node/cli/src/command.rs | 12 +++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index 9842fd2ee4..c15769a98a 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -149,7 +149,10 @@ cli = [ "structopt", "substrate-build-script-utils", ] -runtime-benchmarks = [ "node-runtime/runtime-benchmarks" ] +runtime-benchmarks = [ + "node-runtime/runtime-benchmarks", + "frame-benchmarking-cli", +] [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index 37b77d3bb7..179a61cee8 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -80,9 +80,15 @@ pub fn run() -> Result<()> { runner.sync_run(|config| cmd.run::(config)) } Some(Subcommand::Benchmark(cmd)) => { - let runner = cli.create_runner(cmd)?; - - runner.sync_run(|config| cmd.run::(config)) + if cfg!(feature = "runtime-benchmarks") { + let runner = cli.create_runner(cmd)?; + + runner.sync_run(|config| cmd.run::(config)) + } else { + println!("Benchmarking wasn't enabled when building the node. \ + You can enable it with `--features runtime-benchmarks`."); + Ok(()) + } } Some(Subcommand::Factory(cmd)) => { let runner = cli.create_runner(cmd)?; -- GitLab From 7f12a9f50e65522302bed54cb872a033e4dd3c93 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 9 Apr 2020 20:30:34 +0200 Subject: [PATCH 205/300] Add metrics for the events in the network output channels (#5597) * Add metrics for the events in the network output channels * Documentation fixes * A couple fixes * Fix panic at destruction * Rework for direct Prometheus integration * Don't lock on the Receiver * Another review address * Address review * Update client/network/src/service/out_events.rs Co-Authored-By: Max Inden * Fix bad event name * Fix descriptions * Fix names * client/network/service/out_events: Apply remaining suggestions Co-authored-by: Max Inden --- client/network/src/service.rs | 17 +- client/network/src/service/out_events.rs | 269 +++++++++++++++++++++++ 2 files changed, 275 insertions(+), 11 deletions(-) create mode 100644 client/network/src/service/out_events.rs diff --git a/client/network/src/service.rs b/client/network/src/service.rs index ba4cdcecdf..f7075cf16b 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -68,6 +68,7 @@ use std::{ task::Poll, }; +mod out_events; #[cfg(test)] mod tests; @@ -386,7 +387,7 @@ impl NetworkWorker { import_queue: params.import_queue, from_worker, light_client_rqs: params.on_demand.and_then(|od| od.extract_receiver()), - event_streams: Vec::new(), + event_streams: out_events::OutChannels::new(params.metrics_registry.as_ref())?, metrics, boot_node_ids, }) @@ -576,7 +577,7 @@ impl NetworkService { /// The stream never ends (unless the `NetworkWorker` gets shut down). pub fn event_stream(&self) -> impl Stream { // Note: when transitioning to stable futures, remove the `Error` entirely - let (tx, rx) = tracing_unbounded("mpsc_network_event_stream"); + let (tx, rx) = out_events::channel(); let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::EventStream(tx)); rx } @@ -796,7 +797,7 @@ enum ServiceToWorkerMsg { PutValue(record::Key, Vec), AddKnownAddress(PeerId, Multiaddr), SyncFork(Vec, B::Hash, NumberFor), - EventStream(TracingUnboundedSender), + EventStream(out_events::Sender), WriteNotification { message: Vec, engine_id: ConsensusEngineId, @@ -831,7 +832,7 @@ pub struct NetworkWorker { /// Receiver for queries from the light client that must be processed. light_client_rqs: Option>>, /// Senders for events that happen on the network. - event_streams: Vec>, + event_streams: out_events::OutChannels, /// Prometheus network metrics. metrics: Option, /// The `PeerId`'s of all boot nodes. @@ -855,7 +856,6 @@ struct Metrics { network_per_sec_bytes: GaugeVec, notifications_queues_size: HistogramVec, notifications_sizes: HistogramVec, - num_event_stream_channels: Gauge, opened_notification_streams: GaugeVec, peers_count: Gauge, peerset_num_discovered: Gauge, @@ -948,10 +948,6 @@ impl Metrics { }, &["direction", "protocol"] )?, registry)?, - num_event_stream_channels: register(Gauge::new( - "sub_libp2p_num_event_stream_channels", - "Number of internal active channels that broadcast network events", - )?, registry)?, opened_notification_streams: register(GaugeVec::new( Opts::new( "sub_libp2p_opened_notification_streams", @@ -1105,10 +1101,10 @@ impl Future for NetworkWorker { } }, Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::Event(ev))) => { - this.event_streams.retain(|sender| sender.unbounded_send(ev.clone()).is_ok()); if let Some(metrics) = this.metrics.as_ref() { metrics.update_with_network_event(&ev); } + this.event_streams.send(ev); }, Poll::Ready(SwarmEvent::ConnectionEstablished { peer_id, endpoint, .. }) => { trace!(target: "sub-libp2p", "Libp2p => Connected({:?})", peer_id); @@ -1249,7 +1245,6 @@ impl Future for NetworkWorker { metrics.network_per_sec_bytes.with_label_values(&["out"]).set(this.service.bandwidth.average_upload_per_sec()); metrics.is_major_syncing.set(is_major_syncing as u64); metrics.kbuckets_num_nodes.set(this.network_service.num_kbuckets_entries() as u64); - metrics.num_event_stream_channels.set(this.event_streams.len() as u64); metrics.peers_count.set(num_connected_peers as u64); metrics.peerset_num_discovered.set(this.network_service.user_protocol().num_discovered_peers() as u64); metrics.peerset_num_requested.set(this.network_service.user_protocol().requested_peers().count() as u64); diff --git a/client/network/src/service/out_events.rs b/client/network/src/service/out_events.rs new file mode 100644 index 0000000000..10bb9b7e91 --- /dev/null +++ b/client/network/src/service/out_events.rs @@ -0,0 +1,269 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Registering events streams. +//! +//! This code holds the logic that is used for the network service to inform other parts of +//! Substrate about what is happening. +//! +//! # Usage +//! +//! - Create an instance of [`OutChannels`]. +//! - Create channels using the [`channel`] function. The receiving side implements the `Stream` +//! trait. +//! - You cannot directly send an event on a sender. Instead, you have to call +//! [`OutChannels::push`] to put the sender within a [`OutChannels`]. +//! - Send events by calling [`OutChannels::send`]. Events are cloned for each sender in the +//! collection. +//! + +use crate::Event; +use super::engine_id_to_string; + +use futures::{prelude::*, channel::mpsc, ready}; +use parking_lot::Mutex; +use prometheus_endpoint::{register, CounterVec, Gauge, Opts, PrometheusError, Registry, U64}; +use std::{ + convert::TryFrom as _, + fmt, pin::Pin, sync::Arc, + task::{Context, Poll} +}; + +/// Creates a new channel that can be associated to a [`OutChannels`]. +pub fn channel() -> (Sender, Receiver) { + let (tx, rx) = mpsc::unbounded(); + let metrics = Arc::new(Mutex::new(None)); + let tx = Sender { inner: tx, metrics: metrics.clone() }; + let rx = Receiver { inner: rx, metrics }; + (tx, rx) +} + +/// Sending side of a channel. +/// +/// Must be associated with an [`OutChannels`] before anything can be sent on it +/// +/// > **Note**: Contrary to regular channels, this `Sender` is purposefully designed to not +/// implement the `Clone` trait e.g. in Order to not complicate the logic keeping the metrics in +/// sync on drop. If someone adds a `#[derive(Clone)]` below, it is **wrong**. +pub struct Sender { + inner: mpsc::UnboundedSender, + /// Clone of [`Receiver::metrics`]. + metrics: Arc>>>>, +} + +impl fmt::Debug for Sender { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("Sender").finish() + } +} + +impl Drop for Sender { + fn drop(&mut self) { + let metrics = self.metrics.lock(); + if let Some(Some(metrics)) = metrics.as_ref().map(|m| &**m) { + metrics.num_channels.dec(); + } + } +} + +/// Receiving side of a channel. +pub struct Receiver { + inner: mpsc::UnboundedReceiver, + /// Initially contains `None`, and will be set to a value once the corresponding [`Sender`] + /// is assigned to an instance of [`OutChannels`]. + metrics: Arc>>>>, +} + +impl Stream for Receiver { + type Item = Event; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + if let Some(ev) = ready!(Pin::new(&mut self.inner).poll_next(cx)) { + let metrics = self.metrics.lock().clone(); + if let Some(Some(metrics)) = metrics.as_ref().map(|m| &**m) { + metrics.event_out(&ev); + } else { + log::warn!("Inconsistency in out_events: event happened before sender associated"); + } + Poll::Ready(Some(ev)) + } else { + Poll::Ready(None) + } + } +} + +impl fmt::Debug for Receiver { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("Receiver").finish() + } +} + +impl Drop for Receiver { + fn drop(&mut self) { + // Empty the list to properly decrease the metrics. + while let Some(Some(_)) = self.next().now_or_never() {} + } +} + +/// Collection of senders. +pub struct OutChannels { + event_streams: Vec, + /// The metrics we collect. A clone of this is sent to each [`Receiver`] associated with this + /// object. + metrics: Arc>, +} + +impl OutChannels { + /// Creates a new empty collection of senders. + pub fn new(registry: Option<&Registry>) -> Result { + let metrics = if let Some(registry) = registry { + Some(Metrics::register(registry)?) + } else { + None + }; + + Ok(OutChannels { + event_streams: Vec::new(), + metrics: Arc::new(metrics), + }) + } + + /// Adds a new [`Sender`] to the collection. + pub fn push(&mut self, sender: Sender) { + let mut metrics = sender.metrics.lock(); + debug_assert!(metrics.is_none()); + *metrics = Some(self.metrics.clone()); + drop(metrics); + self.event_streams.push(sender); + + if let Some(metrics) = &*self.metrics { + metrics.num_channels.inc(); + } + } + + /// Sends an event. + pub fn send(&mut self, event: Event) { + self.event_streams.retain(|sender| { + sender.inner.unbounded_send(event.clone()).is_ok() + }); + + if let Some(metrics) = &*self.metrics { + metrics.event_in(&event, self.event_streams.len() as u64); + } + } +} + +impl fmt::Debug for OutChannels { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("OutChannels") + .field("num_channels", &self.event_streams.len()) + .finish() + } +} + +struct Metrics { + // This list is ordered alphabetically + events_total: CounterVec, + notifications_sizes: CounterVec, + num_channels: Gauge, +} + +impl Metrics { + fn register(registry: &Registry) -> Result { + Ok(Self { + events_total: register(CounterVec::new( + Opts::new( + "sub_libp2p_out_events_events_total", + "Number of broadcast network events that have been sent or received across all \ + channels" + ), + &["event_name", "action"] + )?, registry)?, + notifications_sizes: register(CounterVec::new( + Opts::new( + "sub_libp2p_out_events_notifications_sizes", + "Size of notification events that have been sent or received across all \ + channels" + ), + &["protocol", "action"] + )?, registry)?, + num_channels: register(Gauge::new( + "sub_libp2p_out_events_num_channels", + "Number of internal active channels that broadcast network events", + )?, registry)?, + }) + } + + fn event_in(&self, event: &Event, num: u64) { + match event { + Event::Dht(_) => { + self.events_total + .with_label_values(&["dht", "sent"]) + .inc_by(num); + } + Event::NotificationStreamOpened { engine_id, .. } => { + self.events_total + .with_label_values(&[&format!("notif-open-{:?}", engine_id), "sent"]) + .inc_by(num); + }, + Event::NotificationStreamClosed { engine_id, .. } => { + self.events_total + .with_label_values(&[&format!("notif-closed-{:?}", engine_id), "sent"]) + .inc_by(num); + }, + Event::NotificationsReceived { messages, .. } => { + for (engine_id, message) in messages { + self.events_total + .with_label_values(&[&format!("notif-{:?}", engine_id), "sent"]) + .inc_by(num); + self.notifications_sizes + .with_label_values(&[&engine_id_to_string(engine_id), "sent"]) + .inc_by(num.saturating_mul(u64::try_from(message.len()).unwrap_or(u64::max_value()))); + } + }, + } + } + + fn event_out(&self, event: &Event) { + match event { + Event::Dht(_) => { + self.events_total + .with_label_values(&["dht", "received"]) + .inc(); + } + Event::NotificationStreamOpened { engine_id, .. } => { + self.events_total + .with_label_values(&[&format!("notif-open-{:?}", engine_id), "received"]) + .inc(); + }, + Event::NotificationStreamClosed { engine_id, .. } => { + self.events_total + .with_label_values(&[&format!("notif-closed-{:?}", engine_id), "received"]) + .inc(); + }, + Event::NotificationsReceived { messages, .. } => { + for (engine_id, message) in messages { + self.events_total + .with_label_values(&[&format!("notif-{:?}", engine_id), "received"]) + .inc(); + self.notifications_sizes + .with_label_values(&[&engine_id_to_string(engine_id), "received"]) + .inc_by(u64::try_from(message.len()).unwrap_or(u64::max_value())); + } + }, + } + } +} -- GitLab From 512f1c8836e5ac4386f6a5ece7f23e18c9e4d27f Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Sat, 11 Apr 2020 13:12:59 +0200 Subject: [PATCH 206/300] Post-condition checking for some pallets (#5591) * add pre/post condition check to elections * Tests for staking * Better intersection fn * Fix build --- frame/elections-phragmen/src/lib.rs | 166 +++++++++++------- frame/staking/src/lib.rs | 1 - frame/staking/src/mock.rs | 175 +++++++++++-------- frame/staking/src/tests.rs | 251 ++++++++++------------------ 4 files changed, 303 insertions(+), 290 deletions(-) diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 036a5f492c..f0d08f6164 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -1083,7 +1083,7 @@ mod tests { self.genesis_members = members; self } - pub fn build(self) -> sp_io::TestExternalities { + pub fn build_and_execute(self, test: impl FnOnce() -> ()) { VOTING_BOND.with(|v| *v.borrow_mut() = self.voter_bond); TERM_DURATION.with(|v| *v.borrow_mut() = self.term_duration); DESIRED_RUNNERS_UP.with(|v| *v.borrow_mut() = self.desired_runners_up); @@ -1103,8 +1103,9 @@ mod tests { members: self.genesis_members }), }.build_storage().unwrap().into(); - ext.execute_with(|| System::set_block_number(1)); - ext + ext.execute_with(pre_conditions); + ext.execute_with(test); + ext.execute_with(post_conditions) } } @@ -1122,9 +1123,55 @@ mod tests { lock.amount } + fn intersects(a: &[T], b: &[T]) -> bool { + a.iter().any(|e| b.contains(e)) + } + + fn ensure_members_sorted() { + let mut members = Elections::members().clone(); + members.sort(); + assert_eq!(Elections::members(), members); + } + + fn ensure_candidates_sorted() { + let mut candidates = Elections::candidates().clone(); + candidates.sort(); + assert_eq!(Elections::candidates(), candidates); + } + + fn ensure_members_has_approval_stake() { + // we filter members that have no approval state. This means that even we have more seats + // than candidates, we will never ever chose a member with no votes. + assert!( + Elections::members().iter().chain( + Elections::runners_up().iter() + ).all(|(_, s)| *s != Zero::zero()) + ); + } + + fn ensure_member_candidates_runners_up_disjoint() { + // members, candidates and runners-up must always be disjoint sets. + assert!(!intersects(&Elections::members_ids(), &Elections::candidates())); + assert!(!intersects(&Elections::members_ids(), &Elections::runners_up_ids())); + assert!(!intersects(&Elections::candidates(), &Elections::runners_up_ids())); + } + + fn pre_conditions() { + System::set_block_number(1); + ensure_members_sorted(); + ensure_candidates_sorted(); + } + + fn post_conditions() { + ensure_members_sorted(); + ensure_candidates_sorted(); + ensure_member_candidates_runners_up_disjoint(); + ensure_members_has_approval_stake(); + } + #[test] fn params_should_work() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(Elections::desired_members(), 2); assert_eq!(Elections::term_duration(), 5); assert_eq!(Elections::election_rounds(), 0); @@ -1143,7 +1190,7 @@ mod tests { #[test] fn genesis_members_should_work() { - ExtBuilder::default().genesis_members(vec![(1, 10), (2, 20)]).build().execute_with(|| { + ExtBuilder::default().genesis_members(vec![(1, 10), (2, 20)]).build_and_execute(|| { System::set_block_number(1); assert_eq!(Elections::members(), vec![(1, 10), (2, 20)]); @@ -1160,7 +1207,7 @@ mod tests { #[test] fn genesis_members_unsorted_should_work() { - ExtBuilder::default().genesis_members(vec![(2, 20), (1, 10)]).build().execute_with(|| { + ExtBuilder::default().genesis_members(vec![(2, 20), (1, 10)]).build_and_execute(|| { System::set_block_number(1); assert_eq!(Elections::members(), vec![(1, 10), (2, 20)]); @@ -1179,28 +1226,27 @@ mod tests { #[should_panic = "Genesis member does not have enough stake"] fn genesis_members_cannot_over_stake_0() { // 10 cannot lock 20 as their stake and extra genesis will panic. - ExtBuilder::default().genesis_members(vec![(1, 20), (2, 20)]).build(); + ExtBuilder::default().genesis_members(vec![(1, 20), (2, 20)]).build_and_execute(|| {}); } #[test] #[should_panic] fn genesis_members_cannot_over_stake_1() { // 10 cannot reserve 20 as voting bond and extra genesis will panic. - ExtBuilder::default().voter_bond(20).genesis_members(vec![(1, 10), (2, 20)]).build(); + ExtBuilder::default().voter_bond(20).genesis_members(vec![(1, 10), (2, 20)]).build_and_execute(|| {}); } #[test] #[should_panic = "Duplicate member in elections phragmen genesis: 2"] fn genesis_members_cannot_be_duplicate() { - ExtBuilder::default().genesis_members(vec![(1, 10), (2, 10), (2, 10)]).build(); + ExtBuilder::default().genesis_members(vec![(1, 10), (2, 10), (2, 10)]).build_and_execute(|| {}); } #[test] fn term_duration_zero_is_passive() { ExtBuilder::default() .term_duration(0) - .build() - .execute_with(|| + .build_and_execute(|| { assert_eq!(Elections::term_duration(), 0); assert_eq!(Elections::desired_members(), 2); @@ -1221,7 +1267,7 @@ mod tests { #[test] fn simple_candidate_submission_should_work() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert!(Elections::is_candidate(&1).is_err()); assert!(Elections::is_candidate(&2).is_err()); @@ -1248,7 +1294,7 @@ mod tests { #[test] fn simple_candidate_submission_with_no_votes_should_work() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert_ok!(Elections::submit_candidacy(Origin::signed(1))); @@ -1275,7 +1321,7 @@ mod tests { #[test] fn dupe_candidate_submission_should_not_work() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert_ok!(Elections::submit_candidacy(Origin::signed(1))); assert_eq!(Elections::candidates(), vec![1]); @@ -1289,7 +1335,7 @@ mod tests { #[test] fn member_candidacy_submission_should_not_work() { // critically important to make sure that outgoing candidates and losers are not mixed up. - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); @@ -1309,7 +1355,7 @@ mod tests { #[test] fn runner_candidate_submission_should_not_work() { - ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1332,7 +1378,7 @@ mod tests { #[test] fn poor_candidate_submission_should_not_work() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert_noop!( Elections::submit_candidacy(Origin::signed(7)), @@ -1343,7 +1389,7 @@ mod tests { #[test] fn simple_voting_should_work() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert_eq!(balances(&2), (20, 0)); @@ -1357,7 +1403,7 @@ mod tests { #[test] fn can_vote_with_custom_stake() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert_eq!(balances(&2), (20, 0)); @@ -1371,7 +1417,7 @@ mod tests { #[test] fn can_update_votes_and_stake() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(balances(&2), (20, 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(5))); @@ -1392,7 +1438,7 @@ mod tests { #[test] fn cannot_vote_for_no_candidate() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_noop!( Elections::vote(Origin::signed(2), vec![], 20), Error::::UnableToVote, @@ -1402,7 +1448,7 @@ mod tests { #[test] fn can_vote_for_old_members_even_when_no_new_candidates() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1420,7 +1466,7 @@ mod tests { #[test] fn prime_works() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(3))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(5))); @@ -1444,7 +1490,7 @@ mod tests { #[test] fn prime_votes_for_exiting_members_are_removed() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(3))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(5))); @@ -1469,7 +1515,7 @@ mod tests { #[test] fn cannot_vote_for_more_than_candidates() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1482,7 +1528,7 @@ mod tests { #[test] fn cannot_vote_for_less_than_ed() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1495,7 +1541,7 @@ mod tests { #[test] fn can_vote_for_more_than_total_balance_but_moot() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1508,7 +1554,7 @@ mod tests { #[test] fn remove_voter_should_work() { - ExtBuilder::default().voter_bond(8).build().execute_with(|| { + ExtBuilder::default().voter_bond(8).build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); @@ -1533,14 +1579,14 @@ mod tests { #[test] fn non_voter_remove_should_not_work() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_noop!(Elections::remove_voter(Origin::signed(3)), Error::::MustBeVoter); }); } #[test] fn dupe_remove_should_fail() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); @@ -1553,7 +1599,7 @@ mod tests { #[test] fn removed_voter_should_not_be_counted() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1573,7 +1619,7 @@ mod tests { #[test] fn reporter_must_be_voter() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_noop!( Elections::report_defunct_voter(Origin::signed(1), 2), Error::::MustBeVoter, @@ -1583,7 +1629,7 @@ mod tests { #[test] fn can_detect_defunct_voter() { - ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(6))); @@ -1622,7 +1668,7 @@ mod tests { #[test] fn report_voter_should_work_and_earn_reward() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1653,7 +1699,7 @@ mod tests { #[test] fn report_voter_should_slash_when_bad_report() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1682,7 +1728,7 @@ mod tests { #[test] fn simple_voting_rounds_should_work() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1717,7 +1763,7 @@ mod tests { #[test] fn defunct_voter_will_be_counted() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); // This guy's vote is pointless for this round. @@ -1745,7 +1791,7 @@ mod tests { #[test] fn only_desired_seats_are_chosen() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1766,7 +1812,7 @@ mod tests { #[test] fn phragmen_should_not_self_vote() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1781,7 +1827,7 @@ mod tests { #[test] fn runners_up_should_be_kept() { - ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1808,7 +1854,7 @@ mod tests { #[test] fn runners_up_should_be_next_candidates() { - ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1835,7 +1881,7 @@ mod tests { #[test] fn runners_up_lose_bond_once_outgoing() { - ExtBuilder::default().desired_runners_up(1).build().execute_with(|| { + ExtBuilder::default().desired_runners_up(1).build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(2))); @@ -1863,7 +1909,7 @@ mod tests { #[test] fn members_lose_bond_once_outgoing() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(balances(&5), (50, 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(5))); @@ -1889,7 +1935,7 @@ mod tests { #[test] fn losers_will_lose_the_bond() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1912,7 +1958,7 @@ mod tests { #[test] fn current_members_are_always_next_candidate() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1948,7 +1994,7 @@ mod tests { fn election_state_is_uninterrupted() { // what I mean by uninterrupted: // given no input or stimulants the same members are re-elected. - ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1981,7 +2027,7 @@ mod tests { #[test] fn remove_members_triggers_election() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -2007,7 +2053,7 @@ mod tests { #[test] fn seats_should_be_released_when_no_vote() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -2041,7 +2087,7 @@ mod tests { #[test] fn incoming_outgoing_are_reported() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(5))); @@ -2088,7 +2134,7 @@ mod tests { #[test] fn invalid_votes_are_moot() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -2106,7 +2152,7 @@ mod tests { #[test] fn members_are_sorted_based_on_id_runners_on_merit() { - ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -2128,7 +2174,7 @@ mod tests { #[test] fn candidates_are_sorted() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -2144,7 +2190,7 @@ mod tests { #[test] fn runner_up_replacement_maintains_members_order() { - ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(2))); @@ -2164,7 +2210,7 @@ mod tests { #[test] fn runner_up_replacement_works_when_out_of_order() { - ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -2185,7 +2231,7 @@ mod tests { #[test] fn can_renounce_candidacy_member_with_runners_bond_is_refunded() { - ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -2212,7 +2258,7 @@ mod tests { #[test] fn can_renounce_candidacy_member_without_runners_bond_is_refunded() { - ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -2244,7 +2290,7 @@ mod tests { #[test] fn can_renounce_candidacy_runner() { - ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -2271,7 +2317,7 @@ mod tests { #[test] fn can_renounce_candidacy_candidate() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_eq!(balances(&5), (47, 3)); assert_eq!(Elections::candidates(), vec![5]); @@ -2284,7 +2330,7 @@ mod tests { #[test] fn wrong_renounce_candidacy_should_fail() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_noop!( Elections::renounce_candidacy(Origin::signed(5)), Error::::InvalidOrigin, @@ -2294,7 +2340,7 @@ mod tests { #[test] fn behavior_with_dupe_candidate() { - ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { >::put(vec![1, 1, 2, 3, 4]); assert_ok!(Elections::vote(Origin::signed(5), vec![1], 50)); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index da860bd63e..bc2721bc9f 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -1184,7 +1184,6 @@ decl_module! { } else { log!(warn, "💸 Failed to create snapshot at {:?}.", now); } - } } } else { diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 6332486b65..8e2b583c5e 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -42,25 +42,25 @@ const INIT_TIMESTAMP: u64 = 30_000; pub(crate) type AccountId = u64; pub(crate) type AccountIndex = u64; pub(crate) type BlockNumber = u64; -pub(crate) type Balance = u64; +pub(crate) type Balance = u128; /// Simple structure that exposes how u64 currency can be represented as... u64. pub struct CurrencyToVoteHandler; -impl Convert for CurrencyToVoteHandler { - fn convert(x: u64) -> u64 { - x +impl Convert for CurrencyToVoteHandler { + fn convert(x: Balance) -> u64 { + x.saturated_into() } } -impl Convert for CurrencyToVoteHandler { - fn convert(x: u128) -> u64 { - x.saturated_into() +impl Convert for CurrencyToVoteHandler { + fn convert(x: u128) -> Balance { + x } } thread_local! { static SESSION: RefCell<(Vec, HashSet)> = RefCell::new(Default::default()); static SESSION_PER_ERA: RefCell = RefCell::new(3); - static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); + static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); static SLASH_DEFER_DURATION: RefCell = RefCell::new(0); static ELECTION_LOOKAHEAD: RefCell = RefCell::new(0); static PERIOD: RefCell = RefCell::new(1); @@ -104,8 +104,8 @@ pub fn is_disabled(controller: AccountId) -> bool { } pub struct ExistentialDeposit; -impl Get for ExistentialDeposit { - fn get() -> u64 { +impl Get for ExistentialDeposit { + fn get() -> Balance { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow()) } } @@ -172,8 +172,8 @@ impl_outer_event! { /// Author of block is always 11 pub struct Author11; -impl FindAuthor for Author11 { - fn find_author<'a, I>(_digests: I) -> Option +impl FindAuthor for Author11 { + fn find_author<'a, I>(_digests: I) -> Option where I: 'a + IntoIterator, { Some(11) @@ -207,7 +207,7 @@ impl frame_system::Trait for Test { type MaximumBlockLength = MaximumBlockLength; type Version = (); type ModuleToIndex = (); - type AccountData = pallet_balances::AccountData; + type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); } @@ -337,7 +337,7 @@ impl Default for ExtBuilder { } impl ExtBuilder { - pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { + pub fn existential_deposit(mut self, existential_deposit: Balance) -> Self { self.existential_deposit = existential_deposit; self } @@ -369,7 +369,7 @@ impl ExtBuilder { self.num_validators = Some(num_validators); self } - pub fn invulnerables(mut self, invulnerables: Vec) -> Self { + pub fn invulnerables(mut self, invulnerables: Vec) -> Self { self.invulnerables = invulnerables; self } @@ -415,7 +415,7 @@ impl ExtBuilder { let num_validators = self.num_validators.unwrap_or(self.validator_count); let validators = (0..num_validators) - .map(|x| ((x + 1) * 10 + 1) as u64) + .map(|x| ((x + 1) * 10 + 1) as AccountId) .collect::>(); let _ = pallet_balances::GenesisConfig:: { @@ -473,7 +473,7 @@ impl ExtBuilder { keys: validators.iter().map(|x| ( *x, *x, - SessionKeys { other: UintAuthorityId(*x) } + SessionKeys { other: UintAuthorityId(*x as u64) } )).collect(), }.assimilate_storage(&mut storage); @@ -493,6 +493,11 @@ impl ExtBuilder { ext } + pub fn build_and_execute(self, test: impl FnOnce() -> ()) { + let mut ext = self.build(); + ext.execute_with(test); + ext.execute_with(post_conditions); + } } pub type System = frame_system::Module; @@ -501,61 +506,88 @@ pub type Session = pallet_session::Module; pub type Timestamp = pallet_timestamp::Module; pub type Staking = Module; -pub fn active_era() -> EraIndex { - Staking::active_era().unwrap().index +fn post_conditions() { + check_nominators(); + check_exposures(); + check_ledgers(); } -pub fn check_exposure_all(era: EraIndex) { - ErasStakers::::iter_prefix(era).for_each(check_exposure) +pub(crate) fn active_era() -> EraIndex { + Staking::active_era().unwrap().index } -pub fn check_nominator_all(era: EraIndex) { - >::iter() - .for_each(|(acc, _)| check_nominator_exposure(era, acc)); +fn check_ledgers() { + // check the ledger of all stakers. + Bonded::::iter().for_each(|(_, ctrl)| assert_ledger_consistent(ctrl)) } -/// Check for each selected validator: expo.total = Sum(expo.other) + expo.own -pub fn check_exposure(expo: Exposure) { - assert_eq!( - expo.total as u128, - expo.own as u128 + expo.others.iter().map(|e| e.value as u128).sum::(), - "wrong total exposure", - ); +fn check_exposures() { + // a check per validator to ensure the exposure struct is always sane. + let era = active_era(); + ErasStakers::::iter_prefix(era).for_each(|expo| { + assert_eq!( + expo.total as u128, + expo.own as u128 + expo.others.iter().map(|e| e.value as u128).sum::(), + "wrong total exposure.", + ); + }) } -/// Check that for each nominator: slashable_balance > sum(used_balance) -/// Note: we might not consume all of a nominator's balance, but we MUST NOT over spend it. -pub fn check_nominator_exposure(era: EraIndex, stash: AccountId) { - assert_is_stash(stash); - let mut sum = 0; - Session::validators() - .iter() - .map(|v| Staking::eras_stakers(era, v)) - .for_each(|e| e.others.iter().filter(|i| i.who == stash).for_each(|i| sum += i.value)); - let nominator_stake = Staking::slashable_balance_of(&stash); - // a nominator cannot over-spend. - assert!( - nominator_stake >= sum, - "failed: Nominator({}) stake({}) >= sum divided({})", - stash, - nominator_stake, - sum, - ); +fn check_nominators() { + // a check per nominator to ensure their entire stake is correctly distributed. Will only kick- + // in if the nomination was submitted before the current era. + let era = active_era(); + >::iter() + .filter_map(|(nominator, nomination)| + if nomination.submitted_in > era { + Some(nominator) + } else { + None + }) + .for_each(|nominator| { + // must be bonded. + assert_is_stash(nominator); + let mut sum = 0; + Session::validators() + .iter() + .map(|v| Staking::eras_stakers(era, v)) + .for_each(|e| { + let individual = e.others.iter().filter(|e| e.who == nominator).collect::>(); + let len = individual.len(); + match len { + 0 => { /* not supporting this validator at all. */ }, + 1 => sum += individual[0].value, + _ => panic!("nominator cannot back a validator more than once."), + }; + }); + + let nominator_stake = Staking::slashable_balance_of(&nominator); + // a nominator cannot over-spend. + assert!( + nominator_stake >= sum, + "failed: Nominator({}) stake({}) >= sum divided({})", + nominator, + nominator_stake, + sum, + ); + + let diff = nominator_stake - sum; + assert!(diff < 100); + }); } -pub fn assert_is_stash(acc: AccountId) { +fn assert_is_stash(acc: AccountId) { assert!(Staking::bonded(&acc).is_some(), "Not a stash."); } -pub fn assert_ledger_consistent(stash: AccountId) { - assert_is_stash(stash); - let ledger = Staking::ledger(stash - 1).unwrap(); - +fn assert_ledger_consistent(ctrl: AccountId) { + // ensures ledger.total == ledger.active + sum(ledger.unlocking). + let ledger = Staking::ledger(ctrl).expect("Not a controller."); let real_total: Balance = ledger.unlocking.iter().fold(ledger.active, |a, c| a + c.value); assert_eq!(real_total, ledger.total); } -pub fn bond_validator(stash: u64, ctrl: u64, val: u64) { +pub(crate) fn bond_validator(stash: AccountId, ctrl: AccountId, val: Balance) { let _ = Balances::make_free_balance_be(&stash, val); let _ = Balances::make_free_balance_be(&ctrl, val); assert_ok!(Staking::bond( @@ -570,7 +602,12 @@ pub fn bond_validator(stash: u64, ctrl: u64, val: u64) { )); } -pub fn bond_nominator(stash: u64, ctrl: u64, val: u64, target: Vec) { +pub(crate) fn bond_nominator( + stash: AccountId, + ctrl: AccountId, + val: Balance, + target: Vec, +) { let _ = Balances::make_free_balance_be(&stash, val); let _ = Balances::make_free_balance_be(&ctrl, val); assert_ok!(Staking::bond( @@ -582,7 +619,7 @@ pub fn bond_nominator(stash: u64, ctrl: u64, val: u64, target: Vec) { assert_ok!(Staking::nominate(Origin::signed(ctrl), target)); } -pub fn run_to_block(n: BlockNumber) { +pub(crate) fn run_to_block(n: BlockNumber) { Staking::on_finalize(System::block_number()); for b in System::block_number() + 1..=n { System::set_block_number(b); @@ -594,12 +631,12 @@ pub fn run_to_block(n: BlockNumber) { } } -pub fn advance_session() { +pub(crate) fn advance_session() { let current_index = Session::current_index(); start_session(current_index + 1); } -pub fn start_session(session_index: SessionIndex) { +pub(crate) fn start_session(session_index: SessionIndex) { assert_eq!(>::get(), 1, "start_session can only be used with session length 1."); for i in Session::current_index()..session_index { Staking::on_finalize(System::block_number()); @@ -612,12 +649,12 @@ pub fn start_session(session_index: SessionIndex) { assert_eq!(Session::current_index(), session_index); } -pub fn start_era(era_index: EraIndex) { +pub(crate) fn start_era(era_index: EraIndex) { start_session((era_index * >::get()).into()); assert_eq!(Staking::current_era().unwrap(), era_index); } -pub fn current_total_payout_for_duration(duration: u64) -> u64 { +pub(crate) fn current_total_payout_for_duration(duration: u64) -> Balance { inflation::compute_total_payout( ::RewardCurve::get(), Staking::eras_total_stake(Staking::active_era().unwrap().index), @@ -626,7 +663,7 @@ pub fn current_total_payout_for_duration(duration: u64) -> u64 { ).0 } -pub fn reward_all_elected() { +pub(crate) fn reward_all_elected() { let rewards = ::SessionInterface::validators() .into_iter() .map(|v| (v, 1)); @@ -634,14 +671,14 @@ pub fn reward_all_elected() { >::reward_by_ids(rewards) } -pub fn validator_controllers() -> Vec { +pub(crate) fn validator_controllers() -> Vec { Session::validators() .into_iter() .map(|s| Staking::bonded(&s).expect("no controller for validator")) .collect() } -pub fn on_offence_in_era( +pub(crate) fn on_offence_in_era( offenders: &[OffenceDetails< AccountId, pallet_session::historical::IdentificationTuple, @@ -671,7 +708,7 @@ pub fn on_offence_in_era( } } -pub fn on_offence_now( +pub(crate) fn on_offence_now( offenders: &[OffenceDetails>], slash_fraction: &[Perbill], ) { @@ -681,7 +718,7 @@ pub fn on_offence_now( // winners will be chosen by simply their unweighted total backing stake. Nominator stake is // distributed evenly. -pub fn horrible_phragmen_with_post_processing( +pub(crate) fn horrible_phragmen_with_post_processing( do_reduce: bool, ) -> (CompactAssignments, Vec, PhragmenScore) { let mut backing_stake_of: BTreeMap = BTreeMap::new(); @@ -789,7 +826,7 @@ pub fn horrible_phragmen_with_post_processing( // Note: this should always logically reproduce [`offchain_election::prepare_submission`], yet we // cannot do it since we want to have `tweak` injected into the process. -pub fn prepare_submission_with( +pub(crate) fn prepare_submission_with( do_reduce: bool, tweak: impl FnOnce(&mut Vec>), ) -> (CompactAssignments, Vec, PhragmenScore) { @@ -865,7 +902,7 @@ pub fn prepare_submission_with( } /// Make all validator and nominator request their payment -pub fn make_all_reward_payment_before_migration(era: EraIndex) { +pub(crate) fn make_all_reward_payment_before_migration(era: EraIndex) { let validators_with_reward = ErasRewardPoints::::get(era).individual.keys() .cloned() .collect::>(); @@ -897,7 +934,7 @@ pub fn make_all_reward_payment_before_migration(era: EraIndex) { } /// Make all validator and nominator request their payment -pub fn make_all_reward_payment(era: EraIndex) { +pub(crate) fn make_all_reward_payment(era: EraIndex) { let validators_with_reward = ErasRewardPoints::::get(era).individual.keys() .cloned() .collect::>(); diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 75c4edae22..837b085d68 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -33,7 +33,7 @@ use crate::Store; #[test] fn force_unstake_works() { // Verifies initial conditions of mock - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { // Account 11 is stashed and locked, and account 10 is the controller assert_eq!(Staking::bonded(&11), Some(10)); // Cant transfer @@ -55,7 +55,7 @@ fn force_unstake_works() { #[test] fn basic_setup_works() { // Verifies initial conditions of mock - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { // Account 11 is stashed and locked, and account 10 is the controller assert_eq!(Staking::bonded(&11), Some(10)); // Account 21 is stashed and locked, and account 20 is the controller @@ -77,7 +77,7 @@ fn basic_setup_works() { assert_eq!(Staking::ledger(&1), None); // ValidatorPrefs are default - assert_eq!(>::iter().collect::>(), vec![ + assert_eq_uvec!(>::iter().collect::>(), vec![ (31, ValidatorPrefs::default()), (21, ValidatorPrefs::default()), (11, ValidatorPrefs::default()) @@ -105,7 +105,8 @@ fn basic_setup_works() { others: vec![ IndividualExposure { who: 101, value: 375 }] }, ); - // initial slot_stake + + // initial total stake = 1125 + 1375 assert_eq!(Staking::eras_total_stake(Staking::active_era().unwrap().index), 2500); @@ -121,16 +122,12 @@ fn basic_setup_works() { // New era is not being forced assert_eq!(Staking::force_era(), Forcing::NotForcing); - - // All exposures must be correct. - check_exposure_all(Staking::active_era().unwrap().index); - check_nominator_all(Staking::active_era().unwrap().index); }); } #[test] fn change_controller_works() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(Staking::bonded(&11), Some(10)); assert!(Session::validators().contains(&11)); @@ -156,7 +153,7 @@ fn rewards_should_work() { // * rewards get recorded per session // * rewards get paid per Era // * Check that nominators are also rewarded - ExtBuilder::default().nominate(true).build().execute_with(|| { + ExtBuilder::default().nominate(true).build_and_execute(|| { let init_balance_10 = Balances::total_balance(&10); let init_balance_11 = Balances::total_balance(&11); let init_balance_20 = Balances::total_balance(&20); @@ -346,8 +343,6 @@ fn less_than_needed_candidates_works() { ErasStakers::::iter_prefix(Staking::active_era().unwrap().index) .all(|exposure| exposure.others.is_empty()) ); - check_exposure_all(Staking::active_era().unwrap().index); - check_nominator_all(Staking::active_era().unwrap().index); }); } @@ -529,9 +524,6 @@ fn nominating_and_rewards_should_work() { initial_balance + 5 * payout_for_20 / 11, 1, ); - - check_exposure_all(Staking::active_era().unwrap().index); - check_nominator_all(Staking::active_era().unwrap().index); }); } @@ -542,7 +534,7 @@ fn nominators_also_get_slashed() { // 10 - is the controller of 11 // 11 - is the stash. // 2 - is the nominator of 20, 10 - ExtBuilder::default().nominate(false).build().execute_with(|| { + ExtBuilder::default().nominate(false).build_and_execute(|| { assert_eq!(Staking::validator_count(), 2); // Set payee to controller @@ -589,8 +581,7 @@ fn nominators_also_get_slashed() { // initial + first era reward + slash assert_eq!(Balances::total_balance(&11), initial_balance - validator_slash); assert_eq!(Balances::total_balance(&2), initial_balance - nominator_slash); - check_exposure_all(Staking::active_era().unwrap().index); - check_nominator_all(Staking::active_era().unwrap().index); + // Because slashing happened. assert!(is_disabled(10)); }); @@ -602,7 +593,7 @@ fn double_staking_should_fail() { // * an account already bonded as stash cannot be be stashed again. // * an account already bonded as stash cannot nominate. // * an account already bonded as controller can nominate. - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let arbitrary_value = 5; // 2 = controller, 1 stashed => ok assert_ok!( @@ -625,7 +616,7 @@ fn double_staking_should_fail() { fn double_controlling_should_fail() { // should test (in the same order): // * an account already bonded as controller CANNOT be reused as the controller of another account. - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let arbitrary_value = 5; // 2 = controller, 1 stashed => ok assert_ok!(Staking::bond( @@ -644,7 +635,7 @@ fn double_controlling_should_fail() { #[test] fn session_and_eras_work() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(Staking::active_era().unwrap().index, 0); assert_eq!(Session::current_index(), 0); @@ -682,7 +673,7 @@ fn session_and_eras_work() { #[test] fn forcing_new_era_works() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { // normal flow of session. assert_eq!(Staking::active_era().unwrap().index, 0); start_session(0); @@ -738,7 +729,7 @@ fn forcing_new_era_works() { #[test] fn cannot_transfer_staked_balance() { // Tests that a stash account cannot transfer funds - ExtBuilder::default().nominate(false).build().execute_with(|| { + ExtBuilder::default().nominate(false).build_and_execute(|| { // Confirm account 11 is stashed assert_eq!(Staking::bonded(&11), Some(10)); // Confirm account 11 has some free balance @@ -763,7 +754,7 @@ fn cannot_transfer_staked_balance_2() { // Tests that a stash account cannot transfer funds // Same test as above but with 20, and more accurate. // 21 has 2000 free balance but 1000 at stake - ExtBuilder::default().nominate(false).fair(true).build().execute_with(|| { + ExtBuilder::default().nominate(false).fair(true).build_and_execute(|| { // Confirm account 21 is stashed assert_eq!(Staking::bonded(&21), Some(20)); // Confirm account 21 has some free balance @@ -782,7 +773,7 @@ fn cannot_transfer_staked_balance_2() { #[test] fn cannot_reserve_staked_balance() { // Checks that a bonded account cannot reserve balance from free balance - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { // Confirm account 11 is stashed assert_eq!(Staking::bonded(&11), Some(10)); // Confirm account 11 has some free balance @@ -805,7 +796,7 @@ fn cannot_reserve_staked_balance() { #[test] fn reward_destination_works() { // Rewards go to the correct destination as determined in Payee - ExtBuilder::default().nominate(false).build().execute_with(|| { + ExtBuilder::default().nominate(false).build_and_execute(|| { // Check that account 11 is a validator assert!(Session::validators().contains(&11)); // Check the balance of the validator account @@ -904,7 +895,7 @@ fn validator_payment_prefs_work() { // Test that validator preferences are correctly honored // Note: unstake threshold is being directly tested in slashing tests. // This test will focus on validator payment. - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let commission = Perbill::from_percent(40); >::insert(&11, ValidatorPrefs { commission: commission.clone(), @@ -935,9 +926,6 @@ fn validator_payment_prefs_work() { let reward_of_100 = shared_cut * exposure_1.others[0].value / exposure_1.total; assert_eq_error_rate!(Balances::total_balance(&10), balance_era_1_10 + reward_of_10, 2); assert_eq_error_rate!(Balances::total_balance(&100), balance_era_1_100 + reward_of_100, 2); - - check_exposure_all(Staking::active_era().unwrap().index); - check_nominator_all(Staking::active_era().unwrap().index); }); } @@ -947,7 +935,7 @@ fn bond_extra_works() { // Tests that extra `free_balance` in the stash can be added to stake // NOTE: this tests only verifies `StakingLedger` for correct updates // See `bond_extra_and_withdraw_unbonded_works` for more details and updates on `Exposure`. - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { // Check that account 10 is a validator assert!(>::contains_key(11)); // Check that account 10 is bonded to account 11 @@ -976,7 +964,7 @@ fn bond_extra_works() { })); // Call the bond_extra function with a large number, should handle it - assert_ok!(Staking::bond_extra(Origin::signed(11), u64::max_value())); + assert_ok!(Staking::bond_extra(Origin::signed(11), Balance::max_value())); // The full amount of the funds should now be in the total and active assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, @@ -995,7 +983,7 @@ fn bond_extra_and_withdraw_unbonded_works() { // * It can add extra funds to the bonded account. // * it can unbond a portion of its funds from the stash account. // * Once the unbonding period is done, it can actually take the funds out of the stash. - ExtBuilder::default().nominate(false).build().execute_with(|| { + ExtBuilder::default().nominate(false).build_and_execute(|| { // Set payee to controller. avoids confusion assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); @@ -1081,7 +1069,7 @@ fn bond_extra_and_withdraw_unbonded_works() { #[test] fn too_many_unbond_calls_should_not_work() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { // locked at era 0 until 3 for _ in 0..MAX_UNLOCKING_CHUNKS-1 { assert_ok!(Staking::unbond(Origin::signed(10), 1)); @@ -1359,7 +1347,7 @@ fn rebond_is_fifo() { #[test] fn reward_to_stake_works() { - ExtBuilder::default().nominate(false).fair(false).build().execute_with(|| { + ExtBuilder::default().nominate(false).fair(false).build_and_execute(|| { // Confirm validator count is 2 assert_eq!(Staking::validator_count(), 2); // Confirm account 10 and 20 are validators @@ -1401,9 +1389,6 @@ fn reward_to_stake_works() { // -- new infos assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11).total, 1000 + total_payout_0 / 2); assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 21).total, 69 + total_payout_0 / 2); - - check_exposure_all(Staking::active_era().unwrap().index); - check_nominator_all(Staking::active_era().unwrap().index); }); } @@ -1411,7 +1396,7 @@ fn reward_to_stake_works() { fn on_free_balance_zero_stash_removes_validator() { // Tests that validator storage items are cleaned up when stash is empty // Tests that storage items are untouched when controller is empty - ExtBuilder::default().existential_deposit(10).build().execute_with(|| { + ExtBuilder::default().existential_deposit(10).build_and_execute(|| { // Check the balance of the validator account assert_eq!(Balances::free_balance(10), 256); // Check the balance of the stash account @@ -1430,7 +1415,7 @@ fn on_free_balance_zero_stash_removes_validator() { assert!(>::contains_key(&11)); // Reduce free_balance of controller to 0 - let _ = Balances::slash(&10, u64::max_value()); + let _ = Balances::slash(&10, Balance::max_value()); // Check the balance of the stash account has not been touched assert_eq!(Balances::free_balance(11), 256000); @@ -1444,7 +1429,7 @@ fn on_free_balance_zero_stash_removes_validator() { assert!(>::contains_key(&11)); // Reduce free_balance of stash to 0 - let _ = Balances::slash(&11, u64::max_value()); + let _ = Balances::slash(&11, Balance::max_value()); // Check total balance of stash assert_eq!(Balances::total_balance(&11), 0); @@ -1464,7 +1449,7 @@ fn on_free_balance_zero_stash_removes_validator() { fn on_free_balance_zero_stash_removes_nominator() { // Tests that nominator storage items are cleaned up when stash is empty // Tests that storage items are untouched when controller is empty - ExtBuilder::default().existential_deposit(10).build().execute_with(|| { + ExtBuilder::default().existential_deposit(10).build_and_execute(|| { // Make 10 a nominator assert_ok!(Staking::nominate(Origin::signed(10), vec![20])); // Check that account 10 is a nominator @@ -1484,7 +1469,7 @@ fn on_free_balance_zero_stash_removes_nominator() { assert!(>::contains_key(&11)); // Reduce free_balance of controller to 0 - let _ = Balances::slash(&10, u64::max_value()); + let _ = Balances::slash(&10, Balance::max_value()); // Check total balance of account 10 assert_eq!(Balances::total_balance(&10), 0); @@ -1500,7 +1485,7 @@ fn on_free_balance_zero_stash_removes_nominator() { assert!(>::contains_key(&11)); // Reduce free_balance of stash to 0 - let _ = Balances::slash(&11, u64::max_value()); + let _ = Balances::slash(&11, Balance::max_value()); // Check total balance of stash assert_eq!(Balances::total_balance(&11), 0); @@ -1520,7 +1505,7 @@ fn on_free_balance_zero_stash_removes_nominator() { #[test] fn switching_roles() { // Test that it should be possible to switch between roles (nominator, validator, idle) with minimal overhead. - ExtBuilder::default().nominate(false).build().execute_with(|| { + ExtBuilder::default().nominate(false).build_and_execute(|| { // Reset reward destination for i in &[10, 20] { assert_ok!(Staking::set_payee(Origin::signed(*i), RewardDestination::Controller)); } @@ -1557,15 +1542,12 @@ fn switching_roles() { mock::start_era(2); assert_eq_uvec!(validator_controllers(), vec![2, 20]); - - check_exposure_all(Staking::active_era().unwrap().index); - check_nominator_all(Staking::active_era().unwrap().index); }); } #[test] fn wrong_vote_is_null() { - ExtBuilder::default().nominate(false).validator_pool(true).build().execute_with(|| { + ExtBuilder::default().nominate(false).validator_pool(true).build_and_execute(|| { assert_eq_uvec!(validator_controllers(), vec![40, 30]); // put some money in account that we'll use. @@ -1687,8 +1669,6 @@ fn bond_with_little_staked_value_bounded() { Balances::free_balance(&10), init_balance_10 + total_payout_0 / 3 + total_payout_1 / 3, ); - check_exposure_all(Staking::active_era().unwrap().index); - check_nominator_all(Staking::active_era().unwrap().index); }); } @@ -1707,80 +1687,39 @@ fn new_era_elects_correct_number_of_validators() { Session::on_initialize(System::block_number()); assert_eq!(validator_controllers().len(), 1); - check_exposure_all(Staking::active_era().unwrap().index); - check_nominator_all(Staking::active_era().unwrap().index); }) } #[test] -fn phragmen_should_not_overflow_validators() { - ExtBuilder::default().nominate(false).build().execute_with(|| { - let _ = Staking::chill(Origin::signed(10)); - let _ = Staking::chill(Origin::signed(20)); - - bond_validator(3, 2, u64::max_value()); - bond_validator(5, 4, u64::max_value()); - - bond_nominator(7, 6, u64::max_value() / 2, vec![3, 5]); - bond_nominator(9, 8, u64::max_value() / 2, vec![3, 5]); - - mock::start_era(1); - - assert_eq_uvec!(validator_controllers(), vec![4, 2]); +fn phragmen_should_not_overflow() { + ExtBuilder::default().nominate(false).build_and_execute(|| { + // This is the maximum value that we can have as the outcome of CurrencyToVote. + type Votes = u64; - // This test will fail this. Will saturate. - // check_exposure_all(); - assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 3).total, u64::max_value()); - assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 5).total, u64::max_value()); - }) -} - -#[test] -fn phragmen_should_not_overflow_nominators() { - ExtBuilder::default().nominate(false).build().execute_with(|| { let _ = Staking::chill(Origin::signed(10)); let _ = Staking::chill(Origin::signed(20)); - bond_validator(3, 2, u64::max_value() / 2); - bond_validator(5, 4, u64::max_value() / 2); + bond_validator(3, 2, Votes::max_value() as Balance); + bond_validator(5, 4, Votes::max_value() as Balance); - bond_nominator(7, 6, u64::max_value(), vec![3, 5]); - bond_nominator(9, 8, u64::max_value(), vec![3, 5]); + bond_nominator(7, 6, Votes::max_value() as Balance, vec![3, 5]); + bond_nominator(9, 8, Votes::max_value() as Balance, vec![3, 5]); mock::start_era(1); assert_eq_uvec!(validator_controllers(), vec![4, 2]); - // Saturate. - assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 3).total, u64::max_value()); - assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 5).total, u64::max_value()); + // We can safely convert back to values within [u64, u128]. + assert!(Staking::eras_stakers(active_era(), 3).total > Votes::max_value() as Balance); + assert!(Staking::eras_stakers(active_era(), 5).total > Votes::max_value() as Balance); }) } #[test] -fn phragmen_should_not_overflow_ultimate() { - ExtBuilder::default().nominate(false).build().execute_with(|| { - bond_validator(3, 2, u64::max_value()); - bond_validator(5, 4, u64::max_value()); - - bond_nominator(7, 6, u64::max_value(), vec![3, 5]); - bond_nominator(9, 8, u64::max_value(), vec![3, 5]); - - mock::start_era(1); - - assert_eq_uvec!(validator_controllers(), vec![4, 2]); - - // Saturate. - assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 3).total, u64::max_value()); - assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 5).total, u64::max_value()); - }) -} - -#[test] -fn reward_validator_slashing_validator_doesnt_overflow() { - ExtBuilder::default().build().execute_with(|| { - let stake = u32::max_value() as u64 * 2; - let reward_slash = u32::max_value() as u64 * 2; +fn reward_validator_slashing_validator_does_not_overflow() { + ExtBuilder::default().build_and_execute(|| { + let stake = u64::max_value() as Balance * 2; + let reward_slash = u64::max_value() as Balance * 2; // Assert multiplication overflows in balance arithmetic. assert!(stake.checked_mul(reward_slash).is_none()); @@ -1834,7 +1773,7 @@ fn reward_validator_slashing_validator_doesnt_overflow() { #[test] fn reward_from_authorship_event_handler_works() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { use pallet_authorship::EventHandler; assert_eq!(>::author(), 11); @@ -1861,7 +1800,7 @@ fn reward_from_authorship_event_handler_works() { #[test] fn add_reward_points_fns_works() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { // Not mandatory but must be coherent with rewards assert_eq!(Session::validators(), vec![21, 11]); @@ -1889,7 +1828,7 @@ fn add_reward_points_fns_works() { #[test] fn unbonded_balance_is_not_slashable() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { // total amount staked is slashable. assert_eq!(Staking::slashable_balance_of(&11), 1000); @@ -1904,7 +1843,7 @@ fn unbonded_balance_is_not_slashable() { fn era_is_always_same_length() { // This ensures that the sessions is always of the same length if there is no forcing no // session changes. - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let session_per_era = >::get(); mock::start_era(1); @@ -1927,7 +1866,7 @@ fn era_is_always_same_length() { #[test] fn offence_forces_new_era() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { on_offence_now( &[OffenceDetails { offender: ( @@ -1945,7 +1884,7 @@ fn offence_forces_new_era() { #[test] fn offence_ensures_new_era_without_clobbering() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_ok!(Staking::force_new_era_always(Origin::ROOT)); assert_eq!(Staking::force_era(), Forcing::ForceAlways); @@ -1966,7 +1905,7 @@ fn offence_ensures_new_era_without_clobbering() { #[test] fn offence_deselects_validator_even_when_slash_is_zero() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert!(Session::validators().contains(&11)); assert!(>::contains_key(11)); @@ -1995,7 +1934,7 @@ fn offence_deselects_validator_even_when_slash_is_zero() { fn slashing_performed_according_exposure() { // This test checks that slashing is performed according the exposure (or more precisely, // historical exposure), not the current balance. - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11).own, 1000); // Handle an offence with a historical exposure. @@ -2021,7 +1960,7 @@ fn slashing_performed_according_exposure() { #[test] fn slash_in_old_span_does_not_deselect() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { mock::start_era(1); assert!(>::contains_key(11)); @@ -2087,7 +2026,6 @@ fn slash_in_old_span_does_not_deselect() { assert_eq!(Staking::force_era(), Forcing::NotForcing); assert!(>::contains_key(11)); assert!(Session::validators().contains(&11)); - assert_ledger_consistent(11); }); } @@ -2095,7 +2033,7 @@ fn slash_in_old_span_does_not_deselect() { fn reporters_receive_their_slice() { // This test verifies that the reporters of the offence receive their slice from the slashed // amount. - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { // The reporters' reward is calculated from the total exposure. let initial_balance = 1125; @@ -2118,7 +2056,6 @@ fn reporters_receive_their_slice() { let reward_each = reward / 2; // split into two pieces. assert_eq!(Balances::free_balance(1), 10 + reward_each); assert_eq!(Balances::free_balance(2), 20 + reward_each); - assert_ledger_consistent(11); }); } @@ -2126,7 +2063,7 @@ fn reporters_receive_their_slice() { fn subsequent_reports_in_same_span_pay_out_less() { // This test verifies that the reporters of the offence receive their slice from the slashed // amount, but less and less if they submit multiple reports in one span. - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { // The reporters' reward is calculated from the total exposure. let initial_balance = 1125; @@ -2165,14 +2102,13 @@ fn subsequent_reports_in_same_span_pay_out_less() { // 50% * (10% * (initial_balance / 2) - prior_payout) let reward = ((initial_balance / 20) - prior_payout) / 2; assert_eq!(Balances::free_balance(1), 10 + prior_payout + reward); - assert_ledger_consistent(11); }); } #[test] fn invulnerables_are_not_slashed() { // For invulnerable validators no slashing is performed. - ExtBuilder::default().invulnerables(vec![11]).build().execute_with(|| { + ExtBuilder::default().invulnerables(vec![11]).build_and_execute(|| { assert_eq!(Balances::free_balance(11), 1000); assert_eq!(Balances::free_balance(21), 2000); @@ -2208,15 +2144,13 @@ fn invulnerables_are_not_slashed() { initial_balance - (2 * other.value / 10), ); } - assert_ledger_consistent(11); - assert_ledger_consistent(21); }); } #[test] fn dont_slash_if_fraction_is_zero() { // Don't slash if the fraction is zero. - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(Balances::free_balance(11), 1000); on_offence_now( @@ -2233,8 +2167,6 @@ fn dont_slash_if_fraction_is_zero() { // The validator hasn't been slashed. The new era is not forced. assert_eq!(Balances::free_balance(11), 1000); assert_eq!(Staking::force_era(), Forcing::ForceNew); - - assert_ledger_consistent(11); }); } @@ -2242,7 +2174,7 @@ fn dont_slash_if_fraction_is_zero() { fn only_slash_for_max_in_era() { // multiple slashes within one era are only applied if it is more than any previous slash in the // same era. - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { assert_eq!(Balances::free_balance(11), 1000); on_offence_now( @@ -2284,14 +2216,13 @@ fn only_slash_for_max_in_era() { // The validator got slashed 10% more. assert_eq!(Balances::free_balance(11), 400); - assert_ledger_consistent(11); }) } #[test] fn garbage_collection_after_slashing() { // ensures that `SlashingSpans` and `SpanSlash` of an account is removed after reaping. - ExtBuilder::default().existential_deposit(2).build().execute_with(|| { + ExtBuilder::default().existential_deposit(2).build_and_execute(|| { assert_eq!(Balances::free_balance(11), 256_000); on_offence_now( @@ -2335,7 +2266,7 @@ fn garbage_collection_after_slashing() { fn garbage_collection_on_window_pruning() { // ensures that `ValidatorSlashInEra` and `NominatorSlashInEra` are cleared after // `BondingDuration`. - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { mock::start_era(1); assert_eq!(Balances::free_balance(11), 1000); @@ -2376,7 +2307,7 @@ fn garbage_collection_on_window_pruning() { #[test] fn slashing_nominators_by_span_max() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { mock::start_era(1); mock::start_era(2); mock::start_era(3); @@ -2474,7 +2405,7 @@ fn slashing_nominators_by_span_max() { #[test] fn slashes_are_summed_across_spans() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { mock::start_era(1); mock::start_era(2); mock::start_era(3); @@ -2532,7 +2463,7 @@ fn slashes_are_summed_across_spans() { #[test] fn deferred_slashes_are_deferred() { - ExtBuilder::default().slash_defer_duration(2).build().execute_with(|| { + ExtBuilder::default().slash_defer_duration(2).build_and_execute(|| { mock::start_era(1); assert_eq!(Balances::free_balance(11), 1000); @@ -2575,7 +2506,7 @@ fn deferred_slashes_are_deferred() { #[test] fn remove_deferred() { - ExtBuilder::default().slash_defer_duration(2).build().execute_with(|| { + ExtBuilder::default().slash_defer_duration(2).build_and_execute(|| { mock::start_era(1); assert_eq!(Balances::free_balance(11), 1000); @@ -2651,7 +2582,7 @@ fn remove_deferred() { #[test] fn remove_multi_deferred() { - ExtBuilder::default().slash_defer_duration(2).build().execute_with(|| { + ExtBuilder::default().slash_defer_duration(2).build_and_execute(|| { mock::start_era(1); assert_eq!(Balances::free_balance(11), 1000); @@ -2895,7 +2826,7 @@ mod offchain_phragmen { #[test] fn election_on_chain_fallback_works() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { start_session(1); start_session(2); assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); @@ -3814,7 +3745,7 @@ mod offchain_phragmen { #[test] fn slash_kicks_validators_not_nominators_and_disables_nominator_for_kicked_validator() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { mock::start_era(1); assert_eq_uvec!(Session::validators(), vec![11, 21]); @@ -3881,7 +3812,7 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { // * rewards get paid until history_depth for both validators and nominators // * an invalid era to claim doesn't update last_reward // * double claim of one era fails - ExtBuilder::default().nominate(true).build().execute_with(|| { + ExtBuilder::default().nominate(true).build_and_execute(|| { let init_balance_10 = Balances::total_balance(&10); let init_balance_100 = Balances::total_balance(&100); @@ -3961,7 +3892,7 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { #[test] fn zero_slash_keeps_nominators() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { mock::start_era(1); assert_eq!(Balances::free_balance(11), 1000); @@ -3999,7 +3930,7 @@ fn zero_slash_keeps_nominators() { #[test] fn six_session_delay() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { use pallet_session::SessionManager; let val_set = Session::validators(); @@ -4053,11 +3984,11 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( // * If nominator nomination is below the $MaxNominatorRewardedPerValidator other nominator // then the nominator can't claim its reward // * A nominator can't claim another nominator reward - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { for i in 0..=::MaxNominatorRewardedPerValidator::get() { - let stash = 10_000 + i as u64; - let controller = 20_000 + i as u64; - let balance = 10_000 + i as u64; + let stash = 10_000 + i as AccountId; + let controller = 20_000 + i as AccountId; + let balance = 10_000 + i as Balance; Balances::make_free_balance_be(&stash, balance); assert_ok!( Staking::bond( @@ -4081,8 +4012,8 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( // Assert only nominators from 1 to Max are rewarded for i in 0..=::MaxNominatorRewardedPerValidator::get() { - let stash = 10_000 + i as u64; - let balance = 10_000 + i as u64; + let stash = 10_000 + i as AccountId; + let balance = 10_000 + i as Balance; if stash == 10_000 { assert!(Balances::free_balance(&stash) == balance); } else { @@ -4094,7 +4025,7 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( #[test] fn set_history_depth_works() { - ExtBuilder::default().build().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { mock::start_era(10); Staking::set_history_depth(Origin::ROOT, 20).unwrap(); assert!(::ErasTotalStake::contains_key(10 - 4)); @@ -4115,14 +4046,14 @@ fn set_history_depth_works() { fn test_payout_stakers() { // Here we will test validator can set `max_nominators_payout` and it works. // We also test that `payout_extra_nominators` works. - ExtBuilder::default().has_stakers(false).build().execute_with(|| { + ExtBuilder::default().has_stakers(false).build_and_execute(|| { let balance = 1000; // Create three validators: bond_validator(11, 10, balance); // Default(64) // Create nominators, targeting stash of validators for i in 0..100 { - bond_nominator(1000 + i, 100 + i, balance + i, vec![11]); + bond_nominator(1000 + i, 100 + i, balance + i as Balance, vec![11]); } mock::start_era(1); @@ -4137,11 +4068,11 @@ fn test_payout_stakers() { // Validator payout goes to controller. assert!(Balances::free_balance(&10) > balance); for i in 36..100 { - assert!(Balances::free_balance(&(100 + i)) > balance + i); + assert!(Balances::free_balance(&(100 + i)) > balance + i as Balance); } // The bottom 36 do not for i in 0..36 { - assert_eq!(Balances::free_balance(&(100 + i)), balance + i); + assert_eq!(Balances::free_balance(&(100 + i)), balance + i as Balance); } // We track rewards in `claimed_rewards` vec @@ -4195,14 +4126,14 @@ fn test_payout_stakers() { #[test] fn payout_stakers_handles_basic_errors() { // Here we will test payouts handle all errors. - ExtBuilder::default().has_stakers(false).build().execute_with(|| { + ExtBuilder::default().has_stakers(false).build_and_execute(|| { // Same setup as the test above let balance = 1000; bond_validator(11, 10, balance); // Default(64) // Create nominators, targeting stash for i in 0..100 { - bond_nominator(1000 + i, 100 + i, balance + i, vec![11]); + bond_nominator(1000 + i, 100 + i, balance + i as Balance, vec![11]); } mock::start_era(1); @@ -4239,7 +4170,7 @@ fn payout_stakers_handles_basic_errors() { #[test] fn bond_during_era_correctly_populates_claimed_rewards() { - ExtBuilder::default().has_stakers(false).build().execute_with(|| { + ExtBuilder::default().has_stakers(false).build_and_execute(|| { // Era = None bond_validator(9, 8, 1000); assert_eq!( @@ -4361,7 +4292,7 @@ fn test_last_reward_migration() { sp_io::TestExternalities::new(s).execute_with(|| { HistoryDepth::put(84); CurrentEra::put(99); - let nominations = Nominations:: { + let nominations = Nominations:: { targets: vec![], submitted_in: 0, suppressed: false @@ -4422,7 +4353,7 @@ fn rewards_should_work_before_migration() { // * rewards get recorded per session // * rewards get paid per Era // * Check that nominators are also rewarded - ExtBuilder::default().nominate(true).build().execute_with(|| { + ExtBuilder::default().nominate(true).build_and_execute(|| { MigrateEra::put(10); let init_balance_10 = Balances::total_balance(&10); let init_balance_11 = Balances::total_balance(&11); @@ -4513,7 +4444,7 @@ fn migrate_era_should_work() { // * rewards get recorded per session // * rewards get paid per Era // * Check that nominators are also rewarded - ExtBuilder::default().nominate(true).build().execute_with(|| { + ExtBuilder::default().nominate(true).build_and_execute(|| { MigrateEra::put(1); let init_balance_10 = Balances::total_balance(&10); let init_balance_11 = Balances::total_balance(&11); @@ -4601,7 +4532,7 @@ fn migrate_era_should_work() { #[test] #[should_panic] fn migrate_era_should_handle_error() { - ExtBuilder::default().nominate(true).build().execute_with(|| { + ExtBuilder::default().nominate(true).build_and_execute(|| { MigrateEra::put(1); let init_balance_10 = Balances::total_balance(&10); let init_balance_11 = Balances::total_balance(&11); @@ -4653,7 +4584,7 @@ fn migrate_era_should_handle_errors_2() { // * rewards get recorded per session // * rewards get paid per Era // * Check that nominators are also rewarded - ExtBuilder::default().nominate(true).build().execute_with(|| { + ExtBuilder::default().nominate(true).build_and_execute(|| { MigrateEra::put(1); let init_balance_10 = Balances::total_balance(&10); let init_balance_11 = Balances::total_balance(&11); -- GitLab From 18f0be7c780568a046afab89404de72cd12b708d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Sat, 11 Apr 2020 13:56:29 +0200 Subject: [PATCH 207/300] Do a refund based on the actual weight (#5584) This refunds weight and the weight bases fee back to the sender of an extrinsic after the dispatch. --- bin/node/executor/tests/basic.rs | 30 +++---- frame/support/src/weights.rs | 15 ++++ frame/system/src/lib.rs | 18 ++-- frame/transaction-payment/src/lib.rs | 128 ++++++++++++++++++--------- 4 files changed, 131 insertions(+), 60 deletions(-) diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index fccf4a62cc..bab3dfa0ae 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -342,11 +342,6 @@ fn full_native_block_import_works() { )), topics: vec![], }, - EventRecord { - phase: Phase::ApplyExtrinsic(1), - event: Event::pallet_treasury(pallet_treasury::RawEvent::Deposit(fees * 8 / 10)), - topics: vec![], - }, EventRecord { phase: Phase::ApplyExtrinsic(1), event: Event::pallet_balances(pallet_balances::RawEvent::Transfer( @@ -356,6 +351,11 @@ fn full_native_block_import_works() { )), topics: vec![], }, + EventRecord { + phase: Phase::ApplyExtrinsic(1), + event: Event::pallet_treasury(pallet_treasury::RawEvent::Deposit(fees * 8 / 10)), + topics: vec![], + }, EventRecord { phase: Phase::ApplyExtrinsic(1), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( @@ -395,11 +395,6 @@ fn full_native_block_import_works() { )), topics: vec![], }, - EventRecord { - phase: Phase::ApplyExtrinsic(1), - event: Event::pallet_treasury(pallet_treasury::RawEvent::Deposit(fees * 8 / 10)), - topics: vec![], - }, EventRecord { phase: Phase::ApplyExtrinsic(1), event: Event::pallet_balances( @@ -413,14 +408,14 @@ fn full_native_block_import_works() { }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 1000000, class: DispatchClass::Normal, pays_fee: true } - )), + event: Event::pallet_treasury(pallet_treasury::RawEvent::Deposit(fees * 8 / 10)), topics: vec![], }, EventRecord { - phase: Phase::ApplyExtrinsic(2), - event: Event::pallet_treasury(pallet_treasury::RawEvent::Deposit(fees * 8 / 10)), + phase: Phase::ApplyExtrinsic(1), + event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( + DispatchInfo { weight: 1000000, class: DispatchClass::Normal, pays_fee: true } + )), topics: vec![], }, EventRecord { @@ -434,6 +429,11 @@ fn full_native_block_import_works() { ), topics: vec![], }, + EventRecord { + phase: Phase::ApplyExtrinsic(2), + event: Event::pallet_treasury(pallet_treasury::RawEvent::Deposit(fees * 8 / 10)), + topics: vec![], + }, EventRecord { phase: Phase::ApplyExtrinsic(2), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index ea3368550f..df9745bf30 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -139,6 +139,21 @@ pub struct PostDispatchInfo { pub actual_weight: Option, } +impl PostDispatchInfo { + /// Calculate how much (if any) weight was not used by the `Dispatchable`. + pub fn calc_unspent(&self, info: &DispatchInfo) -> Weight { + if let Some(actual_weight) = self.actual_weight { + if actual_weight >= info.weight { + 0 + } else { + info.weight - actual_weight + } + } else { + 0 + } + } +} + impl From> for PostDispatchInfo { fn from(actual_weight: Option) -> Self { Self { diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index a38a8854c7..24d5e724ce 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -120,7 +120,7 @@ use frame_support::{ Contains, Get, ModuleToIndex, OnNewAccount, OnKilledAccount, IsDeadAccount, Happened, StoredMap, EnsureOrigin, }, - weights::{Weight, DispatchInfo, DispatchClass, SimpleDispatchInfo, FunctionOf} + weights::{Weight, DispatchInfo, PostDispatchInfo, DispatchClass, SimpleDispatchInfo, FunctionOf} }; use codec::{Encode, Decode, FullCodec, EncodeLike}; @@ -1169,7 +1169,7 @@ pub fn split_inner(option: Option, splitter: impl FnOnce(T) -> (R, S pub struct CheckWeight(PhantomData); impl CheckWeight where - T::Call: Dispatchable + T::Call: Dispatchable { /// Get the quota ratio of each dispatch class type. This indicates that all operational /// dispatches can use the full capacity of any resource, while user-triggered ones can consume @@ -1264,7 +1264,7 @@ impl CheckWeight where } impl SignedExtension for CheckWeight where - T::Call: Dispatchable + T::Call: Dispatchable { type AccountId = T::AccountId; type Call = T::Call; @@ -1319,7 +1319,7 @@ impl SignedExtension for CheckWeight where fn post_dispatch( _pre: Self::Pre, info: &DispatchInfoOf, - _post_info: &PostDispatchInfoOf, + post_info: &PostDispatchInfoOf, _len: usize, result: &DispatchResult, ) -> Result<(), TransactionValidityError> { @@ -1329,6 +1329,14 @@ impl SignedExtension for CheckWeight where if info.class == DispatchClass::Mandatory && result.is_err() { Err(InvalidTransaction::BadMandatory)? } + + let unspent = post_info.calc_unspent(info); + if unspent > 0 { + AllExtrinsicsWeight::mutate(|weight| { + *weight = weight.map(|w| w.saturating_sub(unspent)); + }) + } + Ok(()) } } @@ -1624,7 +1632,7 @@ mod tests { type Origin = (); type Trait = (); type Info = DispatchInfo; - type PostInfo = (); + type PostInfo = PostDispatchInfo; fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo { panic!("Do not use dummy implementation for dispatch."); diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 7cf364d700..6c5f2a7480 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -36,7 +36,8 @@ use codec::{Encode, Decode}; use frame_support::{ decl_storage, decl_module, traits::{Currency, Get, OnUnbalanced, ExistenceRequirement, WithdrawReason, Imbalance}, - weights::{Weight, DispatchInfo, GetDispatchInfo}, + weights::{Weight, DispatchInfo, PostDispatchInfo, GetDispatchInfo}, + dispatch::DispatchResult, }; use sp_runtime::{ Fixed64, @@ -46,7 +47,7 @@ use sp_runtime::{ }, traits::{ Zero, Saturating, SignedExtension, SaturatedConversion, Convert, Dispatchable, - DispatchInfoOf, + DispatchInfoOf, PostDispatchInfoOf, }, }; use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; @@ -102,7 +103,7 @@ decl_module! { } impl Module where - T::Call: Dispatchable, + T::Call: Dispatchable, { /// Query the data that we know about the fee of a given `call`. /// @@ -140,7 +141,8 @@ impl Module where pub struct ChargeTransactionPayment(#[codec(compact)] BalanceOf); impl ChargeTransactionPayment where - T::Call: Dispatchable, + T::Call: Dispatchable, + BalanceOf: Send + Sync, { /// utility constructor. Used only in client/factory code. pub fn from(fee: BalanceOf) -> Self { @@ -165,22 +167,12 @@ impl ChargeTransactionPayment where len: u32, info: &DispatchInfoOf, tip: BalanceOf, - ) -> BalanceOf - where - BalanceOf: Sync + Send, - { + ) -> BalanceOf { if info.pays_fee { let len = >::from(len); let per_byte = T::TransactionByteFee::get(); let len_fee = per_byte.saturating_mul(len); - - let weight_fee = { - // cap the weight to the maximum defined in runtime, otherwise it will be the - // `Bounded` maximum of its data type, which is not desired. - let capped_weight = info.weight - .min(::MaximumBlockWeight::get()); - T::WeightToFee::convert(capped_weight) - }; + let weight_fee = Self::compute_weight_fee(info.weight); // the adjustable part of the fee let adjustable_fee = len_fee.saturating_add(weight_fee); @@ -194,6 +186,42 @@ impl ChargeTransactionPayment where tip } } + + fn compute_weight_fee(weight: Weight) -> BalanceOf { + // cap the weight to the maximum defined in runtime, otherwise it will be the + // `Bounded` maximum of its data type, which is not desired. + let capped_weight = weight.min(::MaximumBlockWeight::get()); + T::WeightToFee::convert(capped_weight) + } + + fn withdraw_fee( + &self, + who: &T::AccountId, + info: &DispatchInfoOf, + len: usize, + ) -> Result<(BalanceOf, Option>), TransactionValidityError> { + let tip = self.0; + let fee = Self::compute_fee(len as u32, info, tip); + + // Only mess with balances if fee is not zero. + if fee.is_zero() { + return Ok((fee, None)); + } + + match T::Currency::withdraw( + who, + fee, + if tip.is_zero() { + WithdrawReason::TransactionPayment.into() + } else { + WithdrawReason::TransactionPayment | WithdrawReason::Tip + }, + ExistenceRequirement::KeepAlive, + ) { + Ok(imbalance) => Ok((fee, Some(imbalance))), + Err(_) => Err(InvalidTransaction::Payment.into()), + } + } } impl sp_std::fmt::Debug for ChargeTransactionPayment { @@ -209,13 +237,13 @@ impl sp_std::fmt::Debug for ChargeTransactionPayment impl SignedExtension for ChargeTransactionPayment where BalanceOf: Send + Sync, - T::Call: Dispatchable, + T::Call: Dispatchable, { const IDENTIFIER: &'static str = "ChargeTransactionPayment"; type AccountId = T::AccountId; type Call = T::Call; type AdditionalSigned = (); - type Pre = (); + type Pre = (BalanceOf, Self::AccountId, Option>); fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } fn validate( @@ -225,28 +253,7 @@ impl SignedExtension for ChargeTransactionPayment whe info: &DispatchInfoOf, len: usize, ) -> TransactionValidity { - // pay any fees. - let tip = self.0; - let fee = Self::compute_fee(len as u32, info, tip); - // Only mess with balances if fee is not zero. - if !fee.is_zero() { - let imbalance = match T::Currency::withdraw( - who, - fee, - if tip.is_zero() { - WithdrawReason::TransactionPayment.into() - } else { - WithdrawReason::TransactionPayment | WithdrawReason::Tip - }, - ExistenceRequirement::KeepAlive, - ) { - Ok(imbalance) => imbalance, - Err(_) => return InvalidTransaction::Payment.into(), - }; - let imbalances = imbalance.split(tip); - T::OnTransactionPayment::on_unbalanceds(Some(imbalances.0).into_iter() - .chain(Some(imbalances.1))); - } + let (fee, _) = self.withdraw_fee(who, info, len)?; let mut r = ValidTransaction::default(); // NOTE: we probably want to maximize the _fee (of any type) per weight unit_ here, which @@ -254,6 +261,47 @@ impl SignedExtension for ChargeTransactionPayment whe r.priority = fee.saturated_into::(); Ok(r) } + + fn pre_dispatch( + self, + who: &Self::AccountId, + _call: &Self::Call, + info: &DispatchInfoOf, + len: usize + ) -> Result { + let (_, imbalance) = self.withdraw_fee(who, info, len)?; + Ok((self.0, who.clone(), imbalance)) + } + + fn post_dispatch( + pre: Self::Pre, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, + _len: usize, + _result: &DispatchResult, + ) -> Result<(), TransactionValidityError> { + let (tip, who, imbalance) = pre; + if let Some(payed) = imbalance { + let refund = Self::compute_weight_fee(post_info.calc_unspent(info)); + let actual_payment = match T::Currency::deposit_into_existing(&who, refund) { + Ok(refund_imbalance) => { + // The refund cannot be larger than the up front payed max weight. + // `PostDispatchInfo::calc_unspent` guards against such a case. + match payed.offset(refund_imbalance) { + Ok(actual_payment) => actual_payment, + Err(_) => return Err(InvalidTransaction::Payment.into()), + } + } + // We do not recreate the account using the refund. The up front payment + // is gone in that case. + Err(_) => payed, + }; + let imbalances = actual_payment.split(tip); + T::OnTransactionPayment::on_unbalanceds(Some(imbalances.0).into_iter() + .chain(Some(imbalances.1))); + } + Ok(()) + } } #[cfg(test)] -- GitLab From 4af60fd76e135143b515d4cec7b4424a1668d866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sat, 11 Apr 2020 22:12:38 +0200 Subject: [PATCH 208/300] Make sure we poll authority event stream until all events are processed (#5608) * Make sure we poll authority event stream until all events are processed * Add test --- client/authority-discovery/src/lib.rs | 24 ++++---- client/authority-discovery/src/tests.rs | 78 ++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 16 deletions(-) diff --git a/client/authority-discovery/src/lib.rs b/client/authority-discovery/src/lib.rs index 1a8a5c9f40..956e970f26 100644 --- a/client/authority-discovery/src/lib.rs +++ b/client/authority-discovery/src/lib.rs @@ -538,21 +538,19 @@ where Ok(()) }; - match inner() { - Ok(()) => {} - - // Handle fatal errors. - // - // Given that the network likely terminated authority discovery should do the same. - Err(Error::DhtEventStreamTerminated) => return Poll::Ready(()), + loop { + match inner() { + Ok(()) => return Poll::Pending, - // Handle non-fatal errors. - Err(e) => error!(target: "sub-authority-discovery", "Poll failure: {:?}", e), - }; + // Handle fatal errors. + // + // Given that the network likely terminated authority discovery should do the same. + Err(Error::DhtEventStreamTerminated) => return Poll::Ready(()), - // Return Poll::Pending as this is a long running task with the same lifetime as the node - // itself. - Poll::Pending + // Handle non-fatal errors. + Err(e) => error!(target: "sub-authority-discovery", "Poll failure: {:?}", e), + }; + } } } diff --git a/client/authority-discovery/src/tests.rs b/client/authority-discovery/src/tests.rs index 923b7ee0f2..78ff5f33c2 100644 --- a/client/authority-discovery/src/tests.rs +++ b/client/authority-discovery/src/tests.rs @@ -17,8 +17,10 @@ use std::{iter::FromIterator, sync::{Arc, Mutex}}; use futures::channel::mpsc::channel; -use futures::executor::block_on; -use futures::future::poll_fn; +use futures::executor::{block_on, LocalPool}; +use futures::future::{poll_fn, FutureExt}; +use futures::sink::SinkExt; +use futures::task::LocalSpawn; use futures::poll; use libp2p::{kad, PeerId}; @@ -319,7 +321,7 @@ fn handle_dht_events_with_value_found_should_call_set_priority_group() { let mut signed_addresses = vec![]; schema::SignedAuthorityAddresses { addresses: serialized_addresses, - signature: signature, + signature, } .encode(&mut signed_addresses) .unwrap(); @@ -380,3 +382,73 @@ fn terminate_when_event_stream_terminates() { ); }); } + +#[test] +fn dont_stop_polling_when_error_is_returned() { + #[derive(PartialEq, Debug)] + enum Event { + Processed, + End, + }; + + let (mut dht_event_tx, dht_event_rx) = channel(1000); + let (mut discovery_update_tx, mut discovery_update_rx) = channel(1000); + let network: Arc = Arc::new(Default::default()); + let key_store = KeyStore::new(); + let test_api = Arc::new(TestApi { + authorities: vec![], + }); + let mut pool = LocalPool::new(); + + let mut authority_discovery = AuthorityDiscovery::new( + test_api, + network.clone(), + vec![], + key_store, + dht_event_rx.boxed(), + None, + ); + + // Spawn the authority discovery to make sure it is polled independently. + // + // As this is a local pool, only one future at a time will have the CPU and + // can make progress until the future returns `Pending`. + pool.spawner().spawn_local_obj( + futures::future::poll_fn(move |ctx| { + match std::pin::Pin::new(&mut authority_discovery).poll(ctx) { + Poll::Ready(()) => {}, + Poll::Pending => { + discovery_update_tx.send(Event::Processed).now_or_never(); + return Poll::Pending; + }, + } + let _ = discovery_update_tx.send(Event::End).now_or_never().unwrap(); + Poll::Ready(()) + }).boxed_local().into(), + ).expect("Spawns authority discovery"); + + pool.run_until( + // The future that drives the event stream + async { + // Send an event that should generate an error + let _ = dht_event_tx.send(DhtEvent::ValueFound(Default::default())).now_or_never(); + // Send the same event again to make sure that the event stream needs to be polled twice + // to be woken up again. + let _ = dht_event_tx.send(DhtEvent::ValueFound(Default::default())).now_or_never(); + + // Now we call `await` and give the control to the authority discovery future. + assert_eq!(Some(Event::Processed), discovery_update_rx.next().await); + + // Drop the event rx to stop the authority discovery. If it was polled correctly, it should + // end properly. + drop(dht_event_tx); + + assert!( + discovery_update_rx.collect::>() + .await + .into_iter() + .any(|evt| evt == Event::End), "The authority should have ended", + ); + } + ); +} -- GitLab From f8305672a8f015d966f09c52ad3a69f7d4249a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sat, 11 Apr 2020 22:31:40 +0200 Subject: [PATCH 209/300] Disable `wasm-timer` in `no_std` (#5609) --- primitives/timestamp/Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/primitives/timestamp/Cargo.toml b/primitives/timestamp/Cargo.toml index 4a0851ccb1..3c2772077b 100644 --- a/primitives/timestamp/Cargo.toml +++ b/primitives/timestamp/Cargo.toml @@ -15,7 +15,7 @@ sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../r codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../inherents" } impl-trait-for-tuples = "0.1.3" -wasm-timer = "0.2" +wasm-timer = { version = "0.2", optional = true } [features] default = [ "std" ] @@ -25,6 +25,7 @@ std = [ "sp-runtime/std", "codec/std", "sp-inherents/std", + "wasm-timer", ] [package.metadata.docs.rs] -- GitLab From 293885eff6e6728781ba5551d43278ac074767c4 Mon Sep 17 00:00:00 2001 From: Ashley Date: Mon, 13 Apr 2020 00:26:52 +0200 Subject: [PATCH 210/300] Fix the browser node and update demo script (#5613) * Fix browser node * Fix readme --- bin/node/cli/browser-demo/README.md | 7 ++----- bin/node/cli/browser-demo/build.sh | 3 ++- utils/browser/src/lib.rs | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/bin/node/cli/browser-demo/README.md b/bin/node/cli/browser-demo/README.md index 2ff1cc54f5..d5a23485fa 100644 --- a/bin/node/cli/browser-demo/README.md +++ b/bin/node/cli/browser-demo/README.md @@ -1,9 +1,6 @@ # How to run this demo ```sh -cargo install wasm-pack # If necessary - -wasm-pack build --target web --out-dir ./browser-demo/pkg --no-typescript --release ./.. -- --no-default-features --features "browser" - -xdg-open index.html +cargo install wasm-bindgen # If necessary +./build.sh ``` diff --git a/bin/node/cli/browser-demo/build.sh b/bin/node/cli/browser-demo/build.sh index 059ed9fe42..be52b7a523 100755 --- a/bin/node/cli/browser-demo/build.sh +++ b/bin/node/cli/browser-demo/build.sh @@ -1,3 +1,4 @@ #!/usr/bin/env sh -wasm-pack build --target web --out-dir ./browser-demo/pkg --no-typescript --release ./.. -- --no-default-features --features "browser" +cargo +nightly build --release -p node-cli --target wasm32-unknown-unknown --no-default-features --features browser -Z features=itarget +wasm-bindgen ../../../../target/wasm32-unknown-unknown/release/node_cli.wasm --out-dir pkg --target web python -m http.server 8000 diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index 8bed06eee9..572ebcb464 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -49,7 +49,7 @@ where format!("{} (Browser)", name), "unknown", Default::default(), - &std::env::current_dir().expect("current directory must exist"), + &std::path::PathBuf::new(), ); network.boot_nodes = chain_spec.boot_nodes().to_vec(); network.transport = TransportConfig::Normal { -- GitLab From 48b8adb20cbcd241e54945e4403e367f1d9955a1 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 13 Apr 2020 09:27:51 +0200 Subject: [PATCH 211/300] Remove HashMap from consensus-gossip (#5553) --- client/network-gossip/src/bridge.rs | 20 +- client/network-gossip/src/state_machine.rs | 222 ++++++--------------- 2 files changed, 71 insertions(+), 171 deletions(-) diff --git a/client/network-gossip/src/bridge.rs b/client/network-gossip/src/bridge.rs index 6a00b3d5a1..b3bfe606ba 100644 --- a/client/network-gossip/src/bridge.rs +++ b/client/network-gossip/src/bridge.rs @@ -40,22 +40,18 @@ impl Unpin for GossipEngine {} impl GossipEngine { /// Create a new instance. pub fn new + Send + Clone + 'static>( - mut network: N, + network: N, engine_id: ConsensusEngineId, protocol_name: impl Into>, validator: Arc>, ) -> Self where B: 'static { - let mut state_machine = ConsensusGossip::new(); - // We grab the event stream before registering the notifications protocol, otherwise we // might miss events. let network_event_stream = network.event_stream(); - network.register_notifications_protocol(engine_id, protocol_name.into()); - state_machine.register_validator(&mut network, engine_id, validator); GossipEngine { - state_machine, + state_machine: ConsensusGossip::new(validator, engine_id), network: Box::new(network), periodic_maintenance_interval: futures_timer::Delay::new(PERIODIC_MAINTENANCE_INTERVAL), network_event_stream, @@ -77,7 +73,7 @@ impl GossipEngine { topic: B::Hash, message: Vec, ) { - self.state_machine.register_message(topic, self.engine_id, message); + self.state_machine.register_message(topic, message); } /// Broadcast all messages with given topic. @@ -89,7 +85,7 @@ impl GossipEngine { pub fn messages_for(&mut self, topic: B::Hash) -> TracingUnboundedReceiver { - self.state_machine.messages_for(self.engine_id, topic) + self.state_machine.messages_for(topic) } /// Send all messages with given topic to a peer. @@ -99,7 +95,7 @@ impl GossipEngine { topic: B::Hash, force: bool ) { - self.state_machine.send_topic(&mut *self.network, who, topic, self.engine_id, force) + self.state_machine.send_topic(&mut *self.network, who, topic, force) } /// Multicast a message to all peers. @@ -109,14 +105,14 @@ impl GossipEngine { message: Vec, force: bool, ) { - self.state_machine.multicast(&mut *self.network, topic, self.engine_id, message, force) + self.state_machine.multicast(&mut *self.network, topic, message, force) } /// Send addressed message to the given peers. The message is not kept or multicast /// later on. pub fn send_message(&mut self, who: Vec, data: Vec) { for who in &who { - self.state_machine.send_message(&mut *self.network, who, self.engine_id, data.clone()); + self.state_machine.send_message(&mut *self.network, who, data.clone()); } } @@ -157,7 +153,7 @@ impl Future for GossipEngine { remote, messages.into_iter() .filter_map(|(engine, data)| if engine == engine_id { - Some((engine, data.to_vec())) + Some(data.to_vec()) } else { None }) .collect() ); diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index c846534488..d93003fcfb 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -42,16 +42,12 @@ mod rep { pub const GOSSIP_SUCCESS: Rep = Rep::new(1 << 4, "Successfull gossip"); /// Reputation change when a peer sends us a gossip message that we already knew about. pub const DUPLICATE_GOSSIP: Rep = Rep::new(-(1 << 2), "Duplicate gossip"); - /// Reputation change when a peer sends us a gossip message for an unknown engine, whatever that - /// means. - pub const UNKNOWN_GOSSIP: Rep = Rep::new(-(1 << 6), "Unknown gossip message engine id"); /// Reputation change when a peer sends a message from a topic it isn't registered on. pub const UNREGISTERED_TOPIC: Rep = Rep::new(-(1 << 10), "Unregistered gossip message topic"); } struct PeerConsensus { known_messages: HashSet, - role: ObservedRole, } /// Topic stream message with sender. @@ -66,7 +62,6 @@ pub struct TopicNotification { struct MessageEntry { message_hash: B::Hash, topic: B::Hash, - engine_id: ConsensusEngineId, message: Vec, sender: Option, } @@ -75,7 +70,6 @@ struct MessageEntry { struct NetworkContext<'g, 'p, B: BlockT> { gossip: &'g mut ConsensusGossip, network: &'p mut dyn Network, - engine_id: ConsensusEngineId, } impl<'g, 'p, B: BlockT> ValidatorContext for NetworkContext<'g, 'p, B> { @@ -89,7 +83,6 @@ impl<'g, 'p, B: BlockT> ValidatorContext for NetworkContext<'g, 'p, B> { self.gossip.multicast( self.network, topic, - self.engine_id.clone(), message, force, ); @@ -97,40 +90,30 @@ impl<'g, 'p, B: BlockT> ValidatorContext for NetworkContext<'g, 'p, B> { /// Send addressed message to a peer. fn send_message(&mut self, who: &PeerId, message: Vec) { - self.network.write_notification(who.clone(), self.engine_id, message); + self.network.write_notification(who.clone(), self.gossip.engine_id, message); } /// Send all messages with given topic to a peer. fn send_topic(&mut self, who: &PeerId, topic: B::Hash, force: bool) { - self.gossip.send_topic(self.network, who, topic, self.engine_id, force); + self.gossip.send_topic(self.network, who, topic, force); } } fn propagate<'a, B: BlockT, I>( network: &mut dyn Network, + engine_id: ConsensusEngineId, messages: I, intent: MessageIntent, peers: &mut HashMap>, - validators: &HashMap>>, + validator: &Arc>, ) // (msg_hash, topic, message) - where I: Clone + IntoIterator)>, + where I: Clone + IntoIterator)>, { - let mut check_fns = HashMap::new(); - let mut message_allowed = move |who: &PeerId, intent: MessageIntent, topic: &B::Hash, engine_id: ConsensusEngineId, message: &Vec| { - let check_fn = match check_fns.entry(engine_id) { - Entry::Occupied(entry) => entry.into_mut(), - Entry::Vacant(vacant) => match validators.get(&engine_id) { - None => return false, // treat all messages with no validator as not allowed - Some(validator) => vacant.insert(validator.message_allowed()), - } - }; - - (check_fn)(who, intent, topic, &message) - }; + let mut message_allowed = validator.message_allowed(); for (id, ref mut peer) in peers.iter_mut() { - for (message_hash, topic, engine_id, message) in messages.clone() { + for (message_hash, topic, message) in messages.clone() { let intent = match intent { MessageIntent::Broadcast { .. } => if peer.known_messages.contains(&message_hash) { @@ -149,7 +132,7 @@ fn propagate<'a, B: BlockT, I>( other => other, }; - if !message_allowed(id, intent, &topic, engine_id, &message) { + if !message_allowed(id, intent, &topic, &message) { continue; } @@ -164,45 +147,28 @@ fn propagate<'a, B: BlockT, I>( /// Consensus network protocol handler. Manages statements and candidate requests. pub struct ConsensusGossip { peers: HashMap>, - live_message_sinks: HashMap<(ConsensusEngineId, B::Hash), Vec>>, + live_message_sinks: HashMap>>, messages: Vec>, known_messages: LruCache, - validators: HashMap>>, + engine_id: ConsensusEngineId, + validator: Arc>, next_broadcast: Instant, } impl ConsensusGossip { - /// Create a new instance. - pub fn new() -> Self { + /// Create a new instance using the given validator. + pub fn new(validator: Arc>, engine_id: ConsensusEngineId) -> Self { ConsensusGossip { peers: HashMap::new(), live_message_sinks: HashMap::new(), messages: Default::default(), known_messages: LruCache::new(KNOWN_MESSAGES_CACHE_SIZE), - validators: Default::default(), + engine_id, + validator, next_broadcast: Instant::now() + REBROADCAST_INTERVAL, } } - /// Register message validator for a message type. - pub fn register_validator( - &mut self, - network: &mut dyn Network, - engine_id: ConsensusEngineId, - validator: Arc> - ) { - self.register_validator_internal(engine_id, validator.clone()); - let peers: Vec<_> = self.peers.iter().map(|(id, peer)| (id.clone(), peer.role.clone())).collect(); - for (id, role) in peers { - let mut context = NetworkContext { gossip: self, network, engine_id: engine_id.clone() }; - validator.new_peer(&mut context, &id, role); - } - } - - fn register_validator_internal(&mut self, engine_id: ConsensusEngineId, validator: Arc>) { - self.validators.insert(engine_id, validator.clone()); - } - /// Handle new connected peer. pub fn new_peer(&mut self, network: &mut dyn Network, who: PeerId, role: ObservedRole) { // light nodes are not valid targets for consensus gossip messages @@ -213,19 +179,17 @@ impl ConsensusGossip { trace!(target:"gossip", "Registering {:?} {}", role, who); self.peers.insert(who.clone(), PeerConsensus { known_messages: HashSet::new(), - role: role.clone(), }); - for (engine_id, v) in self.validators.clone() { - let mut context = NetworkContext { gossip: self, network, engine_id: engine_id.clone() }; - v.new_peer(&mut context, &who, role.clone()); - } + + let validator = self.validator.clone(); + let mut context = NetworkContext { gossip: self, network }; + validator.new_peer(&mut context, &who, role.clone()); } fn register_message_hashed( &mut self, message_hash: B::Hash, topic: B::Hash, - engine_id: ConsensusEngineId, message: Vec, sender: Option, ) { @@ -233,7 +197,6 @@ impl ConsensusGossip { self.messages.push(MessageEntry { message_hash, topic, - engine_id, message, sender, }); @@ -248,19 +211,17 @@ impl ConsensusGossip { pub fn register_message( &mut self, topic: B::Hash, - engine_id: ConsensusEngineId, message: Vec, ) { let message_hash = HashFor::::hash(&message[..]); - self.register_message_hashed(message_hash, topic, engine_id, message, None); + self.register_message_hashed(message_hash, topic, message, None); } /// Call when a peer has been disconnected to stop tracking gossip status. pub fn peer_disconnected(&mut self, network: &mut dyn Network, who: PeerId) { - for (engine_id, v) in self.validators.clone() { - let mut context = NetworkContext { gossip: self, network, engine_id: engine_id.clone() }; - v.peer_disconnected(&mut context, &who); - } + let validator = self.validator.clone(); + let mut context = NetworkContext { gossip: self, network }; + validator.peer_disconnected(&mut context, &who); self.peers.remove(&who); } @@ -276,8 +237,8 @@ impl ConsensusGossip { /// Rebroadcast all messages to all peers. fn rebroadcast(&mut self, network: &mut dyn Network) { let messages = self.messages.iter() - .map(|entry| (&entry.message_hash, &entry.topic, entry.engine_id, &entry.message)); - propagate(network, messages, MessageIntent::PeriodicRebroadcast, &mut self.peers, &self.validators); + .map(|entry| (&entry.message_hash, &entry.topic, &entry.message)); + propagate(network, self.engine_id, messages, MessageIntent::PeriodicRebroadcast, &mut self.peers, &self.validator); } /// Broadcast all messages with given topic. @@ -285,11 +246,11 @@ impl ConsensusGossip { let messages = self.messages.iter() .filter_map(|entry| if entry.topic == topic { - Some((&entry.message_hash, &entry.topic, entry.engine_id, &entry.message)) + Some((&entry.message_hash, &entry.topic, &entry.message)) } else { None } ); let intent = if force { MessageIntent::ForcedBroadcast } else { MessageIntent::Broadcast }; - propagate(network, messages, intent, &mut self.peers, &self.validators); + propagate(network, self.engine_id, messages, intent, &mut self.peers, &self.validator); } /// Prune old or no longer relevant consensus messages. Provide a predicate @@ -302,23 +263,9 @@ impl ConsensusGossip { let known_messages = &mut self.known_messages; let before = self.messages.len(); - let validators = &self.validators; - - let mut check_fns = HashMap::new(); - let mut message_expired = move |entry: &MessageEntry| { - let engine_id = entry.engine_id; - let check_fn = match check_fns.entry(engine_id) { - Entry::Occupied(entry) => entry.into_mut(), - Entry::Vacant(vacant) => match validators.get(&engine_id) { - None => return true, // treat all messages with no validator as expired - Some(validator) => vacant.insert(validator.message_expired()), - } - }; - - (check_fn)(entry.topic, &entry.message) - }; - self.messages.retain(|entry| !message_expired(entry)); + let mut message_expired = self.validator.message_expired(); + self.messages.retain(|entry| !message_expired(entry.topic, &entry.message)); trace!(target: "gossip", "Cleaned up {} stale messages, {} left ({} known)", before - self.messages.len(), @@ -332,13 +279,11 @@ impl ConsensusGossip { } /// Get data of valid, incoming messages for a topic (but might have expired meanwhile) - pub fn messages_for(&mut self, engine_id: ConsensusEngineId, topic: B::Hash) + pub fn messages_for(&mut self, topic: B::Hash) -> TracingUnboundedReceiver { let (tx, rx) = tracing_unbounded("mpsc_gossip_messages_for"); - for entry in self.messages.iter_mut() - .filter(|e| e.topic == topic && e.engine_id == engine_id) - { + for entry in self.messages.iter_mut().filter(|e| e.topic == topic) { tx.unbounded_send(TopicNotification { message: entry.message.clone(), sender: entry.sender.clone(), @@ -346,7 +291,7 @@ impl ConsensusGossip { .expect("receiver known to be live; qed"); } - self.live_message_sinks.entry((engine_id, topic)).or_default().push(tx); + self.live_message_sinks.entry(topic).or_default().push(tx); rx } @@ -358,13 +303,13 @@ impl ConsensusGossip { &mut self, network: &mut dyn Network, who: PeerId, - messages: Vec<(ConsensusEngineId, Vec)>, + messages: Vec>, ) { if !messages.is_empty() { trace!(target: "gossip", "Received {} messages from peer {}", messages.len(), who); } - for (engine_id, message) in messages { + for message in messages { let message_hash = HashFor::::hash(&message[..]); if self.known_messages.contains(&message_hash) { @@ -374,30 +319,23 @@ impl ConsensusGossip { } // validate the message - let validation = self.validators.get(&engine_id) - .cloned() - .map(|v| { - let mut context = NetworkContext { gossip: self, network, engine_id }; - v.validate(&mut context, &who, &message) - }); + let validation = { + let validator = self.validator.clone(); + let mut context = NetworkContext { gossip: self, network }; + validator.validate(&mut context, &who, &message) + }; let validation_result = match validation { - Some(ValidationResult::ProcessAndKeep(topic)) => Some((topic, true)), - Some(ValidationResult::ProcessAndDiscard(topic)) => Some((topic, false)), - Some(ValidationResult::Discard) => None, - None => { - trace!(target:"gossip", "Unknown message engine id {:?} from {}", engine_id, who); - network.report_peer(who.clone(), rep::UNKNOWN_GOSSIP); - network.disconnect_peer(who.clone()); - continue; - } + ValidationResult::ProcessAndKeep(topic) => Some((topic, true)), + ValidationResult::ProcessAndDiscard(topic) => Some((topic, false)), + ValidationResult::Discard => None, }; if let Some((topic, keep)) = validation_result { network.report_peer(who.clone(), rep::GOSSIP_SUCCESS); if let Some(ref mut peer) = self.peers.get_mut(&who) { peer.known_messages.insert(message_hash); - if let Entry::Occupied(mut entry) = self.live_message_sinks.entry((engine_id, topic)) { + if let Entry::Occupied(mut entry) = self.live_message_sinks.entry(topic) { trace!(target: "gossip", "Pushing consensus message to sinks for {}.", topic); entry.get_mut().retain(|sink| { if let Err(e) = sink.unbounded_send(TopicNotification { @@ -413,7 +351,7 @@ impl ConsensusGossip { } } if keep { - self.register_message_hashed(message_hash, topic, engine_id, message, Some(who.clone())); + self.register_message_hashed(message_hash, topic, message, Some(who.clone())); } } else { trace!(target:"gossip", "Ignored statement from unregistered peer {}", who); @@ -431,17 +369,12 @@ impl ConsensusGossip { network: &mut dyn Network, who: &PeerId, topic: B::Hash, - engine_id: ConsensusEngineId, force: bool ) { - let validator = self.validators.get(&engine_id); - let mut message_allowed = match validator { - None => return, // treat all messages with no validator as not allowed - Some(validator) => validator.message_allowed(), - }; + let mut message_allowed = self.validator.message_allowed(); if let Some(ref mut peer) = self.peers.get_mut(who) { - for entry in self.messages.iter().filter(|m| m.topic == topic && m.engine_id == engine_id) { + for entry in self.messages.iter().filter(|m| m.topic == topic) { let intent = if force { MessageIntent::ForcedBroadcast } else { @@ -459,7 +392,7 @@ impl ConsensusGossip { peer.known_messages.insert(entry.message_hash.clone()); trace!(target: "gossip", "Sending topic message to {}: {:?}", who, entry.message); - network.write_notification(who.clone(), engine_id, entry.message.clone()); + network.write_notification(who.clone(), self.engine_id, entry.message.clone()); } } } @@ -469,14 +402,13 @@ impl ConsensusGossip { &mut self, network: &mut dyn Network, topic: B::Hash, - engine_id: ConsensusEngineId, message: Vec, force: bool, ) { let message_hash = HashFor::::hash(&message); - self.register_message_hashed(message_hash, topic, engine_id, message.clone(), None); + self.register_message_hashed(message_hash, topic, message.clone(), None); let intent = if force { MessageIntent::ForcedBroadcast } else { MessageIntent::Broadcast }; - propagate(network, iter::once((&message_hash, &topic, engine_id, &message)), intent, &mut self.peers, &self.validators); + propagate(network, self.engine_id, iter::once((&message_hash, &topic, &message)), intent, &mut self.peers, &self.validator); } /// Send addressed message to a peer. The message is not kept or multicast @@ -485,7 +417,6 @@ impl ConsensusGossip { &mut self, network: &mut dyn Network, who: &PeerId, - engine_id: ConsensusEngineId, message: Vec, ) { let peer = match self.peers.get_mut(who) { @@ -498,7 +429,7 @@ impl ConsensusGossip { trace!(target: "gossip", "Sending direct to {}: {:?}", who, message); peer.known_messages.insert(message_hash); - network.write_notification(who.clone(), engine_id, message); + network.write_notification(who.clone(), self.engine_id, message); } } @@ -518,7 +449,6 @@ mod tests { $consensus.messages.push(MessageEntry { message_hash: $hash, topic: $topic, - engine_id: [0, 0, 0, 0], message: $m, sender: None, }); @@ -562,7 +492,7 @@ mod tests { let prev_hash = H256::random(); let best_hash = H256::random(); - let mut consensus = ConsensusGossip::::new(); + let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), [0, 0, 0, 0]); let m1_hash = H256::random(); let m2_hash = H256::random(); let m1 = vec![1, 2, 3]; @@ -573,13 +503,11 @@ mod tests { consensus.known_messages.put(m1_hash, ()); consensus.known_messages.put(m2_hash, ()); - let test_engine_id = Default::default(); - consensus.register_validator_internal(test_engine_id, Arc::new(AllowAll)); consensus.collect_garbage(); assert_eq!(consensus.messages.len(), 2); assert_eq!(consensus.known_messages.len(), 2); - consensus.register_validator_internal(test_engine_id, Arc::new(AllowOne)); + consensus.validator = Arc::new(AllowOne); // m2 is expired consensus.collect_garbage(); @@ -591,70 +519,47 @@ mod tests { #[test] fn message_stream_include_those_sent_before_asking_for_stream() { - let mut consensus = ConsensusGossip::::new(); - consensus.register_validator_internal([0, 0, 0, 0], Arc::new(AllowAll)); + let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), [0, 0, 0, 0]); - let engine_id = [0, 0, 0, 0]; let message = vec![4, 5, 6]; let topic = HashFor::::hash(&[1,2,3]); - consensus.register_message(topic, engine_id, message.clone()); - let mut stream = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); + consensus.register_message(topic, message.clone()); + let mut stream = block_on_stream(consensus.messages_for(topic)); assert_eq!(stream.next(), Some(TopicNotification { message: message, sender: None })); } #[test] fn can_keep_multiple_messages_per_topic() { - let mut consensus = ConsensusGossip::::new(); + let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), [0, 0, 0, 0]); let topic = [1; 32].into(); let msg_a = vec![1, 2, 3]; let msg_b = vec![4, 5, 6]; - consensus.register_message(topic, [0, 0, 0, 0], msg_a); - consensus.register_message(topic, [0, 0, 0, 0], msg_b); + consensus.register_message(topic, msg_a); + consensus.register_message(topic, msg_b); assert_eq!(consensus.messages.len(), 2); } #[test] fn can_keep_multiple_subscribers_per_topic() { - let mut consensus = ConsensusGossip::::new(); - consensus.register_validator_internal([0, 0, 0, 0], Arc::new(AllowAll)); + let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), [0, 0, 0, 0]); let message = vec![4, 5, 6]; let topic = HashFor::::hash(&[1, 2, 3]); - consensus.register_message(topic, [0, 0, 0, 0], message.clone()); + consensus.register_message(topic, message.clone()); - let mut stream1 = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); - let mut stream2 = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); + let mut stream1 = block_on_stream(consensus.messages_for(topic)); + let mut stream2 = block_on_stream(consensus.messages_for(topic)); assert_eq!(stream1.next(), Some(TopicNotification { message: message.clone(), sender: None })); assert_eq!(stream2.next(), Some(TopicNotification { message, sender: None })); } - #[test] - fn topics_are_localized_to_engine_id() { - let mut consensus = ConsensusGossip::::new(); - consensus.register_validator_internal([0, 0, 0, 0], Arc::new(AllowAll)); - - let topic = [1; 32].into(); - let msg_a = vec![1, 2, 3]; - let msg_b = vec![4, 5, 6]; - - consensus.register_message(topic, [0, 0, 0, 0], msg_a); - consensus.register_message(topic, [0, 0, 0, 1], msg_b); - - let mut stream = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); - - assert_eq!(stream.next(), Some(TopicNotification { message: vec![1, 2, 3], sender: None })); - - let _ = consensus.live_message_sinks.remove(&([0, 0, 0, 0], topic)); - assert_eq!(stream.next(), None); - } - #[test] fn peer_is_removed_on_disconnect() { struct TestNetwork; @@ -690,8 +595,7 @@ mod tests { } } - let mut consensus = ConsensusGossip::::new(); - consensus.register_validator_internal([0, 0, 0, 0], Arc::new(AllowAll)); + let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), [0, 0, 0, 0]); let mut network = TestNetwork; -- GitLab From 469bb4b6fa852fb660009605a4dd22c06279607a Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Mon, 13 Apr 2020 19:06:48 +0200 Subject: [PATCH 212/300] Fix native version text on startup (#5618) * Native version text was borked. * Unfix benchmarking. --- Cargo.lock | 1 + bin/node-template/node/src/command.rs | 6 +++++- bin/node/cli/Cargo.toml | 2 +- bin/node/cli/src/command.rs | 6 +++++- client/cli/Cargo.toml | 1 + client/cli/src/runner.rs | 9 +++++++-- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index affa982bd3..b50575fa80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5869,6 +5869,7 @@ dependencies = [ "sp-runtime", "sp-state-machine", "sp-utils", + "sp-version", "structopt", "substrate-prometheus-endpoint", "tempfile", diff --git a/bin/node-template/node/src/command.rs b/bin/node-template/node/src/command.rs index 75b88877aa..7950df9a0b 100644 --- a/bin/node-template/node/src/command.rs +++ b/bin/node-template/node/src/command.rs @@ -71,7 +71,11 @@ pub fn run() -> sc_cli::Result<()> { } None => { let runner = cli.create_runner(&cli.run)?; - runner.run_node(service::new_light, service::new_full) + runner.run_node( + service::new_light, + service::new_full, + node_template_runtime::VERSION + ) } } } diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index c15769a98a..4643df6072 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -53,13 +53,13 @@ sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherent sp-keyring = { version = "2.0.0-alpha.5", path = "../../../primitives/keyring" } sp-io = { version = "2.0.0-alpha.5", path = "../../../primitives/io" } sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } +sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } # client dependencies sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } sc-chain-spec = { version = "2.0.0-alpha.5", path = "../../../client/chain-spec" } sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../client/transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } sc-network = { version = "0.8.0-alpha.5", path = "../../../client/network" } sc-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../client/consensus/babe" } grandpa = { version = "0.8.0-alpha.5", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index 179a61cee8..ab7d6ea65e 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -72,7 +72,11 @@ pub fn run() -> Result<()> { match &cli.subcommand { None => { let runner = cli.create_runner(&cli.run)?; - runner.run_node(service::new_light, service::new_full) + runner.run_node( + service::new_light, + service::new_full, + node_runtime::VERSION + ) } Some(Subcommand::Inspect(cmd)) => { let runner = cli.create_runner(cmd)?; diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 89247cf016..1043818f7c 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -30,6 +30,7 @@ sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain sc-network = { version = "0.8.0-alpha.5", path = "../network" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } +sp-version = { version = "2.0.0-alpha.5", path = "../../primitives/version" } sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../service" } sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } diff --git a/client/cli/src/runner.rs b/client/cli/src/runner.rs index bd5dc7100e..c2c4f9739d 100644 --- a/client/cli/src/runner.rs +++ b/client/cli/src/runner.rs @@ -134,8 +134,12 @@ impl Runner { /// A helper function that runs an `AbstractService` with tokio and stops if the process receives /// the signal `SIGTERM` or `SIGINT`. - pub fn run_node(self, new_light: FNL, new_full: FNF) -> Result<()> - where + pub fn run_node( + self, + new_light: FNL, + new_full: FNF, + runtime_version: sp_version::RuntimeVersion, + ) -> Result<()> where FNL: FnOnce(Configuration) -> sc_service::error::Result, FNF: FnOnce(Configuration) -> sc_service::error::Result, SL: AbstractService + Unpin, @@ -152,6 +156,7 @@ impl Runner { info!("📋 Chain specification: {}", self.config.chain_spec.name()); info!("🏷 Node name: {}", self.config.network.node_name); info!("👤 Role: {}", self.config.display_role()); + info!("⛓ Native runtime: {}", runtime_version); match self.config.role { Role::Light => self.run_service_until_exit(new_light), -- GitLab From 352cd78bd9c70e51fcc7fd911d422fbe21d70654 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Mon, 13 Apr 2020 19:09:43 +0200 Subject: [PATCH 213/300] More robust sync (#5604) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * More robust ancestry search * Punish peers for being on the wrong fork * Update client/network/src/protocol/sync.rs Co-Authored-By: Bastian Köcher Co-authored-by: Bastian Köcher --- client/network/src/protocol/sync.rs | 78 ++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 24 deletions(-) diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index 9feded784f..b480f3abb9 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -90,6 +90,9 @@ mod rep { /// Reputation change for peers which send us a known bad block. pub const BAD_BLOCK: Rep = Rep::new(-(1 << 29), "Bad block"); + /// Reputation change for peers which send us a known block. + pub const KNOWN_BLOCK: Rep = Rep::new(-(1 << 29), "Duplicate block"); + /// Reputation change for peers which send us a block with bad justifications. pub const BAD_JUSTIFICATION: Rep = Rep::new(-(1 << 16), "Bad justification"); @@ -184,7 +187,11 @@ pub enum PeerSyncState { /// Available for sync requests. Available, /// Searching for ancestors the Peer has in common with us. - AncestorSearch(NumberFor, AncestorSearchState), + AncestorSearch { + start: NumberFor, + current: NumberFor, + state: AncestorSearchState, + }, /// Actively downloading new blocks, starting from the given Number. DownloadingNew(NumberFor), /// Downloading a stale block with given Hash. Stale means that it is a @@ -432,10 +439,11 @@ impl ChainSync { common_number: Zero::zero(), best_hash, best_number, - state: PeerSyncState::AncestorSearch( - common_best, - AncestorSearchState::ExponentialBackoff(One::one()) - ), + state: PeerSyncState::AncestorSearch { + current: common_best, + start: self.best_queued_number, + state: AncestorSearchState::ExponentialBackoff(One::one()), + }, recently_announced: Default::default() }); self.is_idle = false; @@ -508,7 +516,7 @@ impl ChainSync { self.is_idle = false; for peer_id in &peers { if let Some(peer) = self.peers.get_mut(peer_id) { - if let PeerSyncState::AncestorSearch(_, _) = peer.state { + if let PeerSyncState::AncestorSearch {..} = peer.state { continue; } @@ -669,7 +677,7 @@ impl ChainSync { match &mut peer.state { PeerSyncState::DownloadingNew(start_block) => { self.blocks.clear_peer_download(&who); - self.blocks.insert(*start_block, blocks, who); + self.blocks.insert(*start_block, blocks, who.clone()); peer.state = PeerSyncState::Available; self.blocks .drain(self.best_queued_number + One::one()) @@ -700,10 +708,10 @@ impl ChainSync { } }).collect() } - PeerSyncState::AncestorSearch(num, state) => { - let matching_hash = match (blocks.get(0), self.client.hash(*num)) { + PeerSyncState::AncestorSearch { current, start, state } => { + let matching_hash = match (blocks.get(0), self.client.hash(*current)) { (Some(block), Ok(maybe_our_block_hash)) => { - trace!(target: "sync", "Got ancestry block #{} ({}) from peer {}", num, block.hash, who); + trace!(target: "sync", "Got ancestry block #{} ({}) from peer {}", current, block.hash, who); maybe_our_block_hash.filter(|x| x == &block.hash) }, (None, _) => { @@ -715,15 +723,27 @@ impl ChainSync { return Err(BadPeer(who, rep::BLOCKCHAIN_READ_ERROR)) } }; - if matching_hash.is_some() && peer.common_number < *num { - peer.common_number = *num; + if matching_hash.is_some() { + if *start < self.best_queued_number && self.best_queued_number <= peer.best_number { + // We've made progress on this chain since the search was started. + // Opportunistically set common number to updated number + // instead of the one that started the search. + peer.common_number = self.best_queued_number; + } + else if peer.common_number < *current { + peer.common_number = *current; + } } - if matching_hash.is_none() && num.is_zero() { + if matching_hash.is_none() && current.is_zero() { trace!(target:"sync", "Ancestry search: genesis mismatch for peer {}", who); return Err(BadPeer(who, rep::GENESIS_MISMATCH)) } - if let Some((next_state, next_num)) = handle_ancestor_search_state(state, *num, matching_hash.is_some()) { - peer.state = PeerSyncState::AncestorSearch(next_num, next_state); + if let Some((next_state, next_num)) = handle_ancestor_search_state(state, *current, matching_hash.is_some()) { + peer.state = PeerSyncState::AncestorSearch { + current: next_num, + start: *start, + state: next_state, + }; return Ok(OnBlockData::Request(who, ancestry_request::(next_num))) } else { // Ancestry search is complete. Check if peer is on a stale fork unknown to us and @@ -747,7 +767,7 @@ impl ChainSync { parent_hash: None, peers: Default::default(), }) - .peers.insert(who); + .peers.insert(who.clone()); } peer.state = PeerSyncState::Available; Vec::new() @@ -776,18 +796,28 @@ impl ChainSync { Vec::new() }; - let orig_len = new_blocks.len(); - new_blocks.retain(|b| !self.queue_blocks.contains(&b.hash)); - if new_blocks.len() != orig_len { - debug!(target: "sync", "Ignoring {} blocks that are already queued", orig_len - new_blocks.len()); - } - + // When doing initial sync we don't request blocks in parallel. + // So the only way this can happen is when peers lie about the + // common block. let is_recent = new_blocks.first() .map(|block| { self.peers.iter().any(|(_, peer)| peer.recently_announced.contains(&block.hash)) }) .unwrap_or(false); + if !is_recent && new_blocks.last().map_or(false, |b| self.is_known(&b.hash)) { + // When doing initial sync we don't request blocks in parallel. + // So the only way this can happen is when peers lie about the + // common block. + debug!(target: "sync", "Ignoring known blocks from {}", who); + return Err(BadPeer(who, rep::KNOWN_BLOCK)); + } + let orig_len = new_blocks.len(); + new_blocks.retain(|b| !self.queue_blocks.contains(&b.hash)); + if new_blocks.len() != orig_len { + debug!(target: "sync", "Ignoring {} blocks that are already queued", orig_len - new_blocks.len()); + } + let origin = if is_recent { BlockOrigin::NetworkBroadcast @@ -1043,7 +1073,7 @@ impl ChainSync { self.best_queued_hash = *hash; // Update common blocks for (n, peer) in self.peers.iter_mut() { - if let PeerSyncState::AncestorSearch(_, _) = peer.state { + if let PeerSyncState::AncestorSearch {..} = peer.state { // Wait for ancestry search to complete first. continue; } @@ -1103,7 +1133,7 @@ impl ChainSync { peer.best_number = number; peer.best_hash = hash; } - if let PeerSyncState::AncestorSearch(_, _) = peer.state { + if let PeerSyncState::AncestorSearch {..} = peer.state { return OnBlockAnnounce::Nothing } // If the announced block is the best they have and is not ahead of us, our common number -- GitLab From 0366301736cb7c121452e9a1c19a350923d40e87 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 13 Apr 2020 11:08:14 -0700 Subject: [PATCH 214/300] profile mode (#5617) --- bin/node/bench/src/core.rs | 26 +++++++++++++++++++++++--- bin/node/bench/src/import.rs | 8 ++++++-- bin/node/bench/src/main.rs | 13 +++++++++++-- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/bin/node/bench/src/core.rs b/bin/node/bench/src/core.rs index a8164db75a..32039ac891 100644 --- a/bin/node/bench/src/core.rs +++ b/bin/node/bench/src/core.rs @@ -48,7 +48,7 @@ pub trait BenchmarkDescription { } pub trait Benchmark { - fn run(&mut self) -> std::time::Duration; + fn run(&mut self, mode: Mode) -> std::time::Duration; } #[derive(Debug, Clone, Serialize)] @@ -84,6 +84,23 @@ impl fmt::Display for NsFormatter { } } +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Mode { + Regular, + Profile, +} + +impl std::str::FromStr for Mode { + type Err = &'static str; + fn from_str(day: &str) -> Result { + match day { + "regular" => Ok(Mode::Regular), + "profile" => Ok(Mode::Profile), + _ => Err("Could not parse mode"), + } + } +} + impl fmt::Display for BenchmarkOutput { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( @@ -96,13 +113,16 @@ impl fmt::Display for BenchmarkOutput { } } -pub fn run_benchmark(benchmark: Box) -> BenchmarkOutput { +pub fn run_benchmark( + benchmark: Box, + mode: Mode, +) -> BenchmarkOutput { let name = benchmark.name().to_owned(); let mut benchmark = benchmark.setup(); let mut durations: Vec = vec![]; for _ in 0..50 { - let duration = benchmark.run(); + let duration = benchmark.run(mode); durations.push(duration.as_nanos()); } diff --git a/bin/node/bench/src/import.rs b/bin/node/bench/src/import.rs index 20181bf4c7..2dea292ab0 100644 --- a/bin/node/bench/src/import.rs +++ b/bin/node/bench/src/import.rs @@ -35,7 +35,7 @@ use node_primitives::Block; use sc_client_api::backend::Backend; use sp_runtime::generic::BlockId; -use crate::core::{self, Path}; +use crate::core::{self, Path, Mode}; #[derive(Clone, Copy, Debug)] pub enum SizeType { Small, Medium, Large } @@ -106,7 +106,7 @@ impl core::BenchmarkDescription for ImportBenchmarkDescription { } impl core::Benchmark for ImportBenchmark { - fn run(&mut self) -> std::time::Duration { + fn run(&mut self, mode: Mode) -> std::time::Duration { let mut context = self.database.create_context(self.profile); let _ = context.client.runtime_version_at(&BlockId::Number(0)) @@ -117,6 +117,10 @@ impl core::Benchmark for ImportBenchmark { context.import_block(self.block.clone()); let elapsed = start.elapsed(); + if mode == Mode::Profile { + std::thread::park_timeout(std::time::Duration::from_secs(2)); + } + log::info!( target: "bench-logistics", "imported block with {} tx, took: {:#?}", diff --git a/bin/node/bench/src/main.rs b/bin/node/bench/src/main.rs index 8f04546526..0a95a785c9 100644 --- a/bin/node/bench/src/main.rs +++ b/bin/node/bench/src/main.rs @@ -17,7 +17,7 @@ #[macro_use] mod core; mod import; -use crate::core::run_benchmark; +use crate::core::{run_benchmark, Mode as BenchmarkMode}; use import::{ImportBenchmarkDescription, SizeType}; use node_testing::bench::{Profile, KeyTypes}; use structopt::StructOpt; @@ -41,6 +41,15 @@ struct Opt { /// /// Run with `--list` for the hint of what to filter. filter: Option, + + /// Mode + /// + /// "regular" for regular becnhmark + /// + /// "profile" mode adds pauses between measurable runs, + /// so that actual interval can be selected in the profiler of choice. + #[structopt(short, long, default_value = "regular")] + mode: BenchmarkMode, } fn main() { @@ -81,7 +90,7 @@ fn main() { for benchmark in benchmarks { if opt.filter.as_ref().map(|f| benchmark.path().has(f)).unwrap_or(true) { log::info!("Starting {}", benchmark.name()); - let result = run_benchmark(benchmark); + let result = run_benchmark(benchmark, opt.mode); log::info!("{}", result); results.push(result); -- GitLab From 8e658e72ded93c17c2148af3f289f7cc6a46d842 Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Tue, 14 Apr 2020 20:07:59 +1200 Subject: [PATCH 215/300] Introduce `Fixed128` from ORML to `sp_arithmetic` (#5614) * add fixed128 * fix build * re-export * fix test * saturating_pow * Update primitives/arithmetic/src/fixed128.rs Co-Authored-By: Shawn Tabrizi Co-authored-by: Shawn Tabrizi --- Cargo.lock | 1 + primitives/arithmetic/Cargo.toml | 4 +- primitives/arithmetic/src/fixed128.rs | 675 ++++++++++++++++++++++++ primitives/arithmetic/src/lib.rs | 2 + primitives/arithmetic/src/per_things.rs | 2 +- primitives/arithmetic/src/traits.rs | 2 +- primitives/runtime/src/lib.rs | 2 +- 7 files changed, 684 insertions(+), 4 deletions(-) create mode 100644 primitives/arithmetic/src/fixed128.rs diff --git a/Cargo.lock b/Cargo.lock index b50575fa80..068a68de2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7187,6 +7187,7 @@ dependencies = [ "primitive-types", "rand 0.7.3", "serde", + "serde_json", "sp-debug-derive", "sp-std", ] diff --git a/primitives/arithmetic/Cargo.toml b/primitives/arithmetic/Cargo.toml index 208525f6c1..b8eaa721d6 100644 --- a/primitives/arithmetic/Cargo.toml +++ b/primitives/arithmetic/Cargo.toml @@ -17,11 +17,12 @@ num-traits = { version = "0.2.8", default-features = false } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-debug-derive = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/debug-derive" } +primitive-types = { version = "0.7.0", default-features = false } [dev-dependencies] -primitive-types = "0.7.0" rand = "0.7.2" criterion = "0.3" +serde_json = "1.0" [features] default = ["std"] @@ -31,6 +32,7 @@ std = [ "sp-std/std", "serde", "sp-debug-derive/std", + "primitive-types/std", ] [[bench]] diff --git a/primitives/arithmetic/src/fixed128.rs b/primitives/arithmetic/src/fixed128.rs new file mode 100644 index 0000000000..d9d55910eb --- /dev/null +++ b/primitives/arithmetic/src/fixed128.rs @@ -0,0 +1,675 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use codec::{Decode, Encode}; +use primitive_types::U256; +use crate::{ + traits::{Bounded, Saturating, UniqueSaturatedInto, SaturatedConversion}, + PerThing, +}; +use sp_std::{ + convert::{Into, TryFrom, TryInto}, + fmt, + num::NonZeroI128, +}; + +#[cfg(feature = "std")] +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; + +/// A signed fixed-point number. +/// Can hold any value in the range [-170_141_183_460_469_231_731, 170_141_183_460_469_231_731] +/// with fixed-point accuracy of 10 ** 18. +#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct Fixed128(i128); + +const DIV: i128 = 1_000_000_000_000_000_000; + +impl Fixed128 { + /// Create self from a natural number. + /// + /// Note that this might be lossy. + pub fn from_natural(int: i128) -> Self { + Self(int.saturating_mul(DIV)) + } + + /// Accuracy of `Fixed128`. + pub const fn accuracy() -> i128 { + DIV + } + + /// Raw constructor. Equal to `parts / DIV`. + pub const fn from_parts(parts: i128) -> Self { + Self(parts) + } + + /// Creates self from a rational number. Equal to `n/d`. + /// + /// Note that this might be lossy. + pub fn from_rational>(n: N, d: NonZeroI128) -> Self { + let n = n.unique_saturated_into(); + Self(n.saturating_mul(DIV.into()) / d.get()) + } + + /// Consume self and return the inner raw `i128` value. + /// + /// Note this is a low level function, as the returned value is represented with accuracy. + pub fn deconstruct(self) -> i128 { + self.0 + } + + /// Takes the reciprocal(inverse) of Fixed128, 1/x + pub fn recip(&self) -> Option { + Self::from_natural(1i128).checked_div(self) + } + + /// Checked add. Same semantic to `num_traits::CheckedAdd`. + pub fn checked_add(&self, rhs: &Self) -> Option { + self.0.checked_add(rhs.0).map(Self) + } + + /// Checked sub. Same semantic to `num_traits::CheckedSub`. + pub fn checked_sub(&self, rhs: &Self) -> Option { + self.0.checked_sub(rhs.0).map(Self) + } + + /// Checked mul. Same semantic to `num_traits::CheckedMul`. + pub fn checked_mul(&self, rhs: &Self) -> Option { + let signum = self.0.signum() * rhs.0.signum(); + let mut lhs = self.0; + if lhs.is_negative() { + lhs = lhs.saturating_mul(-1); + } + let mut rhs: i128 = rhs.0.saturated_into(); + if rhs.is_negative() { + rhs = rhs.saturating_mul(-1); + } + + U256::from(lhs) + .checked_mul(U256::from(rhs)) + .and_then(|n| n.checked_div(U256::from(DIV))) + .and_then(|n| TryInto::::try_into(n).ok()) + .map(|n| Self(n * signum)) + } + + /// Checked div. Same semantic to `num_traits::CheckedDiv`. + pub fn checked_div(&self, rhs: &Self) -> Option { + if rhs.0.signum() == 0 { + return None; + } + if self.0 == 0 { + return Some(*self); + } + + let signum = self.0.signum() / rhs.0.signum(); + let mut lhs: i128 = self.0; + if lhs.is_negative() { + lhs = lhs.saturating_mul(-1); + } + let mut rhs: i128 = rhs.0.saturated_into(); + if rhs.is_negative() { + rhs = rhs.saturating_mul(-1); + } + + U256::from(lhs) + .checked_mul(U256::from(DIV)) + .and_then(|n| n.checked_div(U256::from(rhs))) + .and_then(|n| TryInto::::try_into(n).ok()) + .map(|n| Self(n * signum)) + } + + /// Checked mul for int type `N`. + pub fn checked_mul_int(&self, other: &N) -> Option + where + N: Copy + TryFrom + TryInto, + { + N::try_into(*other).ok().and_then(|rhs| { + let mut lhs = self.0; + if lhs.is_negative() { + lhs = lhs.saturating_mul(-1); + } + let mut rhs: i128 = rhs.saturated_into(); + let signum = self.0.signum() * rhs.signum(); + if rhs.is_negative() { + rhs = rhs.saturating_mul(-1); + } + + U256::from(lhs) + .checked_mul(U256::from(rhs)) + .and_then(|n| n.checked_div(U256::from(DIV))) + .and_then(|n| TryInto::::try_into(n).ok()) + .and_then(|n| TryInto::::try_into(n * signum).ok()) + }) + } + + /// Checked mul for int type `N`. + pub fn saturating_mul_int(&self, other: &N) -> N + where + N: Copy + TryFrom + TryInto + Bounded, + { + self.checked_mul_int(other).unwrap_or_else(|| { + N::try_into(*other) + .map(|n| n.signum()) + .map(|n| n * self.0.signum()) + .map(|signum| { + if signum.is_negative() { + Bounded::min_value() + } else { + Bounded::max_value() + } + }) + .unwrap_or(Bounded::max_value()) + }) + } + + /// Checked div for int type `N`. + pub fn checked_div_int(&self, other: &N) -> Option + where + N: Copy + TryFrom + TryInto, + { + N::try_into(*other) + .ok() + .and_then(|n| self.0.checked_div(n)) + .and_then(|n| n.checked_div(DIV)) + .and_then(|n| TryInto::::try_into(n).ok()) + } + + pub fn zero() -> Self { + Self(0) + } + + pub fn is_zero(&self) -> bool { + self.0 == 0 + } + + /// Saturating absolute value. Returning MAX if `parts` == i128::MIN instead of overflowing. + pub fn saturating_abs(&self) -> Self { + if self.0 == i128::min_value() { + return Fixed128::max_value(); + } + + if self.0.is_negative() { + Fixed128::from_parts(self.0 * -1) + } else { + *self + } + } + + pub fn is_positive(&self) -> bool { + self.0.is_positive() + } + + pub fn is_negative(&self) -> bool { + self.0.is_negative() + } +} + +impl Saturating for Fixed128 { + fn saturating_add(self, rhs: Self) -> Self { + Self(self.0.saturating_add(rhs.0)) + } + + fn saturating_sub(self, rhs: Self) -> Self { + Self(self.0.saturating_sub(rhs.0)) + } + + fn saturating_mul(self, rhs: Self) -> Self { + self.checked_mul(&rhs).unwrap_or_else(|| { + if (self.0.signum() * rhs.0.signum()).is_negative() { + Bounded::min_value() + } else { + Bounded::max_value() + } + }) + } + + fn saturating_pow(self, exp: usize) -> Self { + if exp == 0 { + return Self::from_natural(1); + } + + let exp = exp as u64; + let msb_pos = 64 - exp.leading_zeros(); + + let mut result = Self::from_natural(1); + let mut pow_val = self; + for i in 0..msb_pos { + if ((1 << i) & exp) > 0 { + result = result.saturating_mul(pow_val); + } + pow_val = pow_val.saturating_mul(pow_val); + } + result + } +} + +impl Bounded for Fixed128 { + fn min_value() -> Self { + Self(Bounded::min_value()) + } + + fn max_value() -> Self { + Self(Bounded::max_value()) + } +} + +impl fmt::Debug for Fixed128 { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let integral = { + let int = self.0 / DIV; + let signum_for_zero = if int == 0 && self.is_negative() { "-" } else { "" }; + format!("{}{}", signum_for_zero, int) + }; + let fractional = format!("{:0>18}", (self.0 % DIV).abs()); + write!(f, "Fixed128({}.{})", integral, fractional) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + Ok(()) + } +} + +impl From

for Fixed128 { + fn from(val: P) -> Self { + let accuracy = P::ACCURACY.saturated_into().max(1) as i128; + let value = val.deconstruct().saturated_into() as i128; + Fixed128::from_rational(value, NonZeroI128::new(accuracy).unwrap()) + } +} + +#[cfg(feature = "std")] +impl Fixed128 { + fn i128_str(&self) -> String { + format!("{}", &self.0) + } + + fn try_from_i128_str(s: &str) -> Result { + let parts: i128 = s.parse().map_err(|_| "invalid string input")?; + Ok(Self::from_parts(parts)) + } +} + +// Manual impl `Serialize` as serde_json does not support i128. +// TODO: remove impl if issue https://github.com/serde-rs/json/issues/548 fixed. +#[cfg(feature = "std")] +impl Serialize for Fixed128 { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&self.i128_str()) + } +} + +// Manual impl `Serialize` as serde_json does not support i128. +// TODO: remove impl if issue https://github.com/serde-rs/json/issues/548 fixed. +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for Fixed128 { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + Fixed128::try_from_i128_str(&s).map_err(|err_str| de::Error::custom(err_str)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{Perbill, Percent, Permill, Perquintill}; + + fn max() -> Fixed128 { + Fixed128::max_value() + } + + fn min() -> Fixed128 { + Fixed128::min_value() + } + + #[test] + fn fixed128_semantics() { + let a = Fixed128::from_rational(5, NonZeroI128::new(2).unwrap()); + let b = Fixed128::from_rational(10, NonZeroI128::new(4).unwrap()); + assert_eq!(a.0, 5 * DIV / 2); + assert_eq!(a, b); + + let a = Fixed128::from_rational(-5, NonZeroI128::new(1).unwrap()); + assert_eq!(a, Fixed128::from_natural(-5)); + + let a = Fixed128::from_rational(5, NonZeroI128::new(-1).unwrap()); + assert_eq!(a, Fixed128::from_natural(-5)); + + // biggest value that can be created. + assert_ne!(max(), Fixed128::from_natural(170_141_183_460_469_231_731)); + assert_eq!(max(), Fixed128::from_natural(170_141_183_460_469_231_732)); + + // the smallest value that can be created. + assert_ne!(min(), Fixed128::from_natural(-170_141_183_460_469_231_731)); + assert_eq!(min(), Fixed128::from_natural(-170_141_183_460_469_231_732)); + } + + #[test] + fn fixed128_operation() { + let a = Fixed128::from_natural(2); + let b = Fixed128::from_natural(1); + assert_eq!(a.checked_add(&b), Some(Fixed128::from_natural(1 + 2))); + assert_eq!(a.checked_sub(&b), Some(Fixed128::from_natural(2 - 1))); + assert_eq!(a.checked_mul(&b), Some(Fixed128::from_natural(1 * 2))); + assert_eq!( + a.checked_div(&b), + Some(Fixed128::from_rational(2, NonZeroI128::new(1).unwrap())) + ); + + let a = Fixed128::from_rational(5, NonZeroI128::new(2).unwrap()); + let b = Fixed128::from_rational(3, NonZeroI128::new(2).unwrap()); + assert_eq!( + a.checked_add(&b), + Some(Fixed128::from_rational(8, NonZeroI128::new(2).unwrap())) + ); + assert_eq!( + a.checked_sub(&b), + Some(Fixed128::from_rational(2, NonZeroI128::new(2).unwrap())) + ); + assert_eq!( + a.checked_mul(&b), + Some(Fixed128::from_rational(15, NonZeroI128::new(4).unwrap())) + ); + assert_eq!( + a.checked_div(&b), + Some(Fixed128::from_rational(10, NonZeroI128::new(6).unwrap())) + ); + + let a = Fixed128::from_natural(120); + assert_eq!(a.checked_div_int(&2i32), Some(60)); + + let a = Fixed128::from_rational(20, NonZeroI128::new(1).unwrap()); + assert_eq!(a.checked_div_int(&2i32), Some(10)); + + let a = Fixed128::from_natural(120); + assert_eq!(a.checked_mul_int(&2i32), Some(240)); + + let a = Fixed128::from_rational(1, NonZeroI128::new(2).unwrap()); + assert_eq!(a.checked_mul_int(&20i32), Some(10)); + + let a = Fixed128::from_rational(-1, NonZeroI128::new(2).unwrap()); + assert_eq!(a.checked_mul_int(&20i32), Some(-10)); + } + + #[test] + fn saturating_mul_should_work() { + let a = Fixed128::from_natural(-1); + assert_eq!(min().saturating_mul(a), max()); + + assert_eq!(Fixed128::from_natural(125).saturating_mul(a).deconstruct(), -125 * DIV); + + let a = Fixed128::from_rational(1, NonZeroI128::new(5).unwrap()); + assert_eq!(Fixed128::from_natural(125).saturating_mul(a).deconstruct(), 25 * DIV); + } + + #[test] + fn saturating_mul_int_works() { + let a = Fixed128::from_rational(10, NonZeroI128::new(1).unwrap()); + assert_eq!(a.saturating_mul_int(&i32::max_value()), i32::max_value()); + + let a = Fixed128::from_rational(-10, NonZeroI128::new(1).unwrap()); + assert_eq!(a.saturating_mul_int(&i32::max_value()), i32::min_value()); + + let a = Fixed128::from_rational(3, NonZeroI128::new(1).unwrap()); + assert_eq!(a.saturating_mul_int(&100i8), i8::max_value()); + + let a = Fixed128::from_rational(10, NonZeroI128::new(1).unwrap()); + assert_eq!(a.saturating_mul_int(&123i128), 1230); + + let a = Fixed128::from_rational(-10, NonZeroI128::new(1).unwrap()); + assert_eq!(a.saturating_mul_int(&123i128), -1230); + + assert_eq!(max().saturating_mul_int(&2i128), 340_282_366_920_938_463_463); + + assert_eq!(max().saturating_mul_int(&i128::min_value()), i128::min_value()); + + assert_eq!(min().saturating_mul_int(&i128::max_value()), i128::min_value()); + + assert_eq!(min().saturating_mul_int(&i128::min_value()), i128::max_value()); + } + + #[test] + fn zero_works() { + assert_eq!(Fixed128::zero(), Fixed128::from_natural(0)); + } + + #[test] + fn is_zero_works() { + assert!(Fixed128::zero().is_zero()); + assert!(!Fixed128::from_natural(1).is_zero()); + } + + #[test] + fn checked_div_with_zero_should_be_none() { + let a = Fixed128::from_natural(1); + let b = Fixed128::from_natural(0); + assert_eq!(a.checked_div(&b), None); + assert_eq!(b.checked_div(&a), Some(b)); + } + + #[test] + fn checked_div_int_with_zero_should_be_none() { + let a = Fixed128::from_natural(1); + assert_eq!(a.checked_div_int(&0i32), None); + let a = Fixed128::from_natural(0); + assert_eq!(a.checked_div_int(&1i32), Some(0)); + } + + #[test] + fn checked_div_with_zero_dividend_should_be_zero() { + let a = Fixed128::zero(); + let b = Fixed128::from_parts(1); + + assert_eq!(a.checked_div(&b), Some(Fixed128::zero())); + } + + #[test] + fn under_flow_should_be_none() { + let b = Fixed128::from_natural(1); + assert_eq!(min().checked_sub(&b), None); + } + + #[test] + fn over_flow_should_be_none() { + let a = Fixed128::from_parts(i128::max_value() - 1); + let b = Fixed128::from_parts(2); + assert_eq!(a.checked_add(&b), None); + + let a = Fixed128::max_value(); + let b = Fixed128::from_rational(2, NonZeroI128::new(1).unwrap()); + assert_eq!(a.checked_mul(&b), None); + + let a = Fixed128::from_natural(255); + let b = 2u8; + assert_eq!(a.checked_mul_int(&b), None); + + let a = Fixed128::from_natural(256); + let b = 1u8; + assert_eq!(a.checked_div_int(&b), None); + + let a = Fixed128::from_natural(256); + let b = -1i8; + assert_eq!(a.checked_div_int(&b), None); + } + + #[test] + fn checked_div_int_should_work() { + // 256 / 10 = 25 (25.6 as int = 25) + let a = Fixed128::from_natural(256); + let result = a.checked_div_int(&10i128).unwrap(); + assert_eq!(result, 25); + + // 256 / 100 = 2 (2.56 as int = 2) + let a = Fixed128::from_natural(256); + let result = a.checked_div_int(&100i128).unwrap(); + assert_eq!(result, 2); + + // 256 / 1000 = 0 (0.256 as int = 0) + let a = Fixed128::from_natural(256); + let result = a.checked_div_int(&1000i128).unwrap(); + assert_eq!(result, 0); + + // 256 / -1 = -256 + let a = Fixed128::from_natural(256); + let result = a.checked_div_int(&-1i128).unwrap(); + assert_eq!(result, -256); + + // -256 / -1 = 256 + let a = Fixed128::from_natural(-256); + let result = a.checked_div_int(&-1i128).unwrap(); + assert_eq!(result, 256); + + // 10 / -5 = -2 + let a = Fixed128::from_rational(20, NonZeroI128::new(2).unwrap()); + let result = a.checked_div_int(&-5i128).unwrap(); + assert_eq!(result, -2); + + // -170_141_183_460_469_231_731 / -2 = 85_070_591_730_234_615_865 + let result = min().checked_div_int(&-2i128).unwrap(); + assert_eq!(result, 85_070_591_730_234_615_865); + + // 85_070_591_730_234_615_865 * -2 = -170_141_183_460_469_231_730 + let result = Fixed128::from_natural(result).checked_mul_int(&-2i128).unwrap(); + assert_eq!(result, -170_141_183_460_469_231_730); + } + + #[test] + fn perthing_into_fixed_i128() { + let ten_percent_percent: Fixed128 = Percent::from_percent(10).into(); + assert_eq!(ten_percent_percent.deconstruct(), DIV / 10); + + let ten_percent_permill: Fixed128 = Permill::from_percent(10).into(); + assert_eq!(ten_percent_permill.deconstruct(), DIV / 10); + + let ten_percent_perbill: Fixed128 = Perbill::from_percent(10).into(); + assert_eq!(ten_percent_perbill.deconstruct(), DIV / 10); + + let ten_percent_perquintill: Fixed128 = Perquintill::from_percent(10).into(); + assert_eq!(ten_percent_perquintill.deconstruct(), DIV / 10); + } + + #[test] + fn recip_should_work() { + let a = Fixed128::from_natural(2); + assert_eq!( + a.recip(), + Some(Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())) + ); + + let a = Fixed128::from_natural(2); + assert_eq!(a.recip().unwrap().checked_mul_int(&4i32), Some(2i32)); + + let a = Fixed128::from_rational(100, NonZeroI128::new(121).unwrap()); + assert_eq!( + a.recip(), + Some(Fixed128::from_rational(121, NonZeroI128::new(100).unwrap())) + ); + + let a = Fixed128::from_rational(1, NonZeroI128::new(2).unwrap()); + assert_eq!(a.recip().unwrap().checked_mul(&a), Some(Fixed128::from_natural(1))); + + let a = Fixed128::from_natural(0); + assert_eq!(a.recip(), None); + + let a = Fixed128::from_rational(-1, NonZeroI128::new(2).unwrap()); + assert_eq!(a.recip(), Some(Fixed128::from_natural(-2))); + } + + #[test] + fn serialize_deserialize_should_work() { + let two_point_five = Fixed128::from_rational(5, NonZeroI128::new(2).unwrap()); + let serialized = serde_json::to_string(&two_point_five).unwrap(); + assert_eq!(serialized, "\"2500000000000000000\""); + let deserialized: Fixed128 = serde_json::from_str(&serialized).unwrap(); + assert_eq!(deserialized, two_point_five); + + let minus_two_point_five = Fixed128::from_rational(-5, NonZeroI128::new(2).unwrap()); + let serialized = serde_json::to_string(&minus_two_point_five).unwrap(); + assert_eq!(serialized, "\"-2500000000000000000\""); + let deserialized: Fixed128 = serde_json::from_str(&serialized).unwrap(); + assert_eq!(deserialized, minus_two_point_five); + } + + #[test] + fn saturating_abs_should_work() { + // normal + assert_eq!(Fixed128::from_parts(1).saturating_abs(), Fixed128::from_parts(1)); + assert_eq!(Fixed128::from_parts(-1).saturating_abs(), Fixed128::from_parts(1)); + + // saturating + assert_eq!(Fixed128::min_value().saturating_abs(), Fixed128::max_value()); + } + + #[test] + fn is_positive_negative_should_work() { + let positive = Fixed128::from_parts(1); + assert!(positive.is_positive()); + assert!(!positive.is_negative()); + + let negative = Fixed128::from_parts(-1); + assert!(!negative.is_positive()); + assert!(negative.is_negative()); + + let zero = Fixed128::zero(); + assert!(!zero.is_positive()); + assert!(!zero.is_negative()); + } + + #[test] + fn fmt_should_work() { + let positive = Fixed128::from_parts(1000000000000000001); + assert_eq!(format!("{:?}", positive), "Fixed128(1.000000000000000001)"); + let negative = Fixed128::from_parts(-1000000000000000001); + assert_eq!(format!("{:?}", negative), "Fixed128(-1.000000000000000001)"); + + let positive_fractional = Fixed128::from_parts(1); + assert_eq!(format!("{:?}", positive_fractional), "Fixed128(0.000000000000000001)"); + let negative_fractional = Fixed128::from_parts(-1); + assert_eq!(format!("{:?}", negative_fractional), "Fixed128(-0.000000000000000001)"); + + let zero = Fixed128::zero(); + assert_eq!(format!("{:?}", zero), "Fixed128(0.000000000000000000)"); + } + + #[test] + fn saturating_pow_should_work() { + assert_eq!(Fixed128::from_natural(2).saturating_pow(0), Fixed128::from_natural(1)); + assert_eq!(Fixed128::from_natural(2).saturating_pow(1), Fixed128::from_natural(2)); + assert_eq!(Fixed128::from_natural(2).saturating_pow(2), Fixed128::from_natural(4)); + assert_eq!(Fixed128::from_natural(2).saturating_pow(3), Fixed128::from_natural(8)); + assert_eq!(Fixed128::from_natural(2).saturating_pow(50), Fixed128::from_natural(1125899906842624)); + + assert_eq!(Fixed128::from_natural(1).saturating_pow(1000), Fixed128::from_natural(1)); + assert_eq!(Fixed128::from_natural(-1).saturating_pow(1000), Fixed128::from_natural(1)); + assert_eq!(Fixed128::from_natural(-1).saturating_pow(1001), Fixed128::from_natural(-1)); + assert_eq!(Fixed128::from_natural(1).saturating_pow(usize::max_value()), Fixed128::from_natural(1)); + assert_eq!(Fixed128::from_natural(-1).saturating_pow(usize::max_value()), Fixed128::from_natural(-1)); + assert_eq!(Fixed128::from_natural(-1).saturating_pow(usize::max_value() - 1), Fixed128::from_natural(1)); + + assert_eq!(Fixed128::from_natural(114209).saturating_pow(4), Fixed128::from_natural(170137997018538053761)); + assert_eq!(Fixed128::from_natural(114209).saturating_pow(5), Fixed128::max_value()); + + assert_eq!(Fixed128::from_natural(1).saturating_pow(usize::max_value()), Fixed128::from_natural(1)); + assert_eq!(Fixed128::from_natural(0).saturating_pow(usize::max_value()), Fixed128::from_natural(0)); + assert_eq!(Fixed128::from_natural(2).saturating_pow(usize::max_value()), Fixed128::max_value()); + } +} diff --git a/primitives/arithmetic/src/lib.rs b/primitives/arithmetic/src/lib.rs index f6d8b53e34..fb70b13a15 100644 --- a/primitives/arithmetic/src/lib.rs +++ b/primitives/arithmetic/src/lib.rs @@ -37,9 +37,11 @@ pub mod helpers_128bit; pub mod traits; mod per_things; mod fixed64; +mod fixed128; mod rational128; pub use fixed64::Fixed64; +pub use fixed128::Fixed128; pub use per_things::{PerThing, Percent, PerU16, Permill, Perbill, Perquintill}; pub use rational128::Rational128; diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index ad529fbf32..56fc562cd1 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -1096,7 +1096,7 @@ macro_rules! implement_per_thing { <$type>::max_value(), super::Rounding::Nearest, ), - (<$type>::max_value() - 1).into(), + <$upper_type>::from((<$type>::max_value() - 1)), ); // (max % 2) * max / 2 == max / 2 assert_eq!( diff --git a/primitives/arithmetic/src/traits.rs b/primitives/arithmetic/src/traits.rs index 23f8f23f0b..6b5e324464 100644 --- a/primitives/arithmetic/src/traits.rs +++ b/primitives/arithmetic/src/traits.rs @@ -117,7 +117,7 @@ pub trait Saturating { /// Saturating multiply. Compute `self * rhs`, saturating at the numeric bounds instead of /// overflowing. fn saturating_mul(self, rhs: Self) -> Self; - + /// Saturating exponentiation. Compute `self.pow(exp)`, saturating at the numeric bounds /// instead of overflowing. fn saturating_pow(self, exp: usize) -> Self; diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index c80971b576..4e0a2728a9 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -69,7 +69,7 @@ pub use sp_core::RuntimeDebug; /// Re-export top-level arithmetic stuff. pub use sp_arithmetic::{ - Perquintill, Perbill, Permill, Percent, PerU16, Rational128, Fixed64, PerThing, + Perquintill, Perbill, Permill, Percent, PerU16, Rational128, Fixed64, Fixed128, PerThing, traits::SaturatedConversion, }; /// Re-export 128 bit helpers. -- GitLab From 226f7cd879a95744662a8978d9693c54170eccc5 Mon Sep 17 00:00:00 2001 From: cheme Date: Tue, 14 Apr 2020 10:25:20 +0200 Subject: [PATCH 216/300] name of children in chain spec change. --- bin/node/cli/res/flaming-fir.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/cli/res/flaming-fir.json b/bin/node/cli/res/flaming-fir.json index 7ed98239b5..3612d7284f 100644 --- a/bin/node/cli/res/flaming-fir.json +++ b/bin/node/cli/res/flaming-fir.json @@ -134,7 +134,7 @@ "0x5f3e4907f716ac89b6347d15ececedca0b6a45321efae92aea15e0740ec7afe7": "0x00000000", "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade98e54094c2d5af8ae10b91e1288f4f59f2946d7738f2c509b7effd909e5e9ba0ad": "0x00" }, - "children": {} + "childrenDefault": {} } } } -- GitLab From 482f4886661b39d74b8e51f7dd20f04c2d2cb370 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Tue, 14 Apr 2020 14:46:33 +0200 Subject: [PATCH 217/300] Bump trie-db (#5627) * Bump trie-db * Bumped version in Cargo.toml --- Cargo.lock | 4 ++-- primitives/state-machine/Cargo.toml | 2 +- primitives/trie/Cargo.toml | 2 +- test-utils/runtime/Cargo.toml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 068a68de2a..a696744bf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8740,9 +8740,9 @@ dependencies = [ [[package]] name = "trie-db" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de9222c50cc325855621271157c973da27a0dcd26fa06f8edf81020bd2333df0" +checksum = "bcc309f34008563989045a4c4dbcc5770467f3a3785ee80a9b5cc0d83362475f" dependencies = [ "hash-db", "hashbrown", diff --git a/primitives/state-machine/Cargo.toml b/primitives/state-machine/Cargo.toml index 548f3f4308..1e0e224b60 100644 --- a/primitives/state-machine/Cargo.toml +++ b/primitives/state-machine/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/sp-state-machine" log = "0.4.8" parking_lot = "0.10.0" hash-db = "0.15.2" -trie-db = "0.20.0" +trie-db = "0.20.1" trie-root = "0.16.0" sp-trie = { version = "2.0.0-alpha.5", path = "../trie" } sp-core = { version = "2.0.0-alpha.5", path = "../core" } diff --git a/primitives/trie/Cargo.toml b/primitives/trie/Cargo.toml index 3876f46526..bc475745a5 100644 --- a/primitives/trie/Cargo.toml +++ b/primitives/trie/Cargo.toml @@ -17,7 +17,7 @@ harness = false codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } hash-db = { version = "0.15.2", default-features = false } -trie-db = { version = "0.20.0", default-features = false } +trie-db = { version = "0.20.1", default-features = false } trie-root = { version = "0.16.0", default-features = false } memory-db = { version = "0.20.0", default-features = false } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index be22747ea6..4c3b92db70 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -39,7 +39,7 @@ pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = sc-client = { version = "0.8.0-alpha.5", optional = true, path = "../../client" } sp-trie = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/trie" } sp-transaction-pool = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/transaction-pool" } -trie-db = { version = "0.20.0", default-features = false } +trie-db = { version = "0.20.1", default-features = false } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] -- GitLab From 0132d522dbbdaef4e11a772fe5987801b59964aa Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 14 Apr 2020 14:49:41 +0200 Subject: [PATCH 218/300] Give names to channels (#5626) * Give names to channels * Fix * A couple more changes * More minor tweaks * Fix test --- bin/node/cli/src/service.rs | 2 +- client/network-gossip/src/lib.rs | 2 +- client/network/src/service.rs | 8 +++-- client/network/src/service/out_events.rs | 44 ++++++++++++++---------- client/network/src/service/tests.rs | 2 +- 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 257068cf14..757022655d 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -176,7 +176,7 @@ macro_rules! new_full { service.spawn_essential_task("babe-proposer", babe); let network = service.network(); - let dht_event_stream = network.event_stream().filter_map(|e| async move { match e { + let dht_event_stream = network.event_stream("authority-discovery").filter_map(|e| async move { match e { Event::Dht(e) => Some(e), _ => None, }}).boxed(); diff --git a/client/network-gossip/src/lib.rs b/client/network-gossip/src/lib.rs index 4e4d32366f..42aeca86cb 100644 --- a/client/network-gossip/src/lib.rs +++ b/client/network-gossip/src/lib.rs @@ -99,7 +99,7 @@ pub trait Network { impl Network for Arc> { fn event_stream(&self) -> Pin + Send>> { - Box::pin(NetworkService::event_stream(self)) + Box::pin(NetworkService::event_stream(self, "network-gossip")) } fn report_peer(&self, peer_id: PeerId, reputation: ReputationChange) { diff --git a/client/network/src/service.rs b/client/network/src/service.rs index f7075cf16b..b099a5dabf 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -575,9 +575,13 @@ impl NetworkService { /// If this method is called multiple times, the events are duplicated. /// /// The stream never ends (unless the `NetworkWorker` gets shut down). - pub fn event_stream(&self) -> impl Stream { + /// + /// The name passed is used to identify the channel in the Prometheus metrics. Note that the + /// parameter is a `&'static str`, and not a `String`, in order to avoid accidentally having + /// an unbounded set of Prometheus metrics, which would be quite bad in terms of memory + pub fn event_stream(&self, name: &'static str) -> impl Stream { // Note: when transitioning to stable futures, remove the `Error` entirely - let (tx, rx) = out_events::channel(); + let (tx, rx) = out_events::channel(name); let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::EventStream(tx)); rx } diff --git a/client/network/src/service/out_events.rs b/client/network/src/service/out_events.rs index 10bb9b7e91..b279be3c22 100644 --- a/client/network/src/service/out_events.rs +++ b/client/network/src/service/out_events.rs @@ -43,11 +43,13 @@ use std::{ }; /// Creates a new channel that can be associated to a [`OutChannels`]. -pub fn channel() -> (Sender, Receiver) { +/// +/// The name is used in Prometheus reports. +pub fn channel(name: &'static str) -> (Sender, Receiver) { let (tx, rx) = mpsc::unbounded(); let metrics = Arc::new(Mutex::new(None)); - let tx = Sender { inner: tx, metrics: metrics.clone() }; - let rx = Receiver { inner: rx, metrics }; + let tx = Sender { inner: tx, name, metrics: metrics.clone() }; + let rx = Receiver { inner: rx, name, metrics }; (tx, rx) } @@ -60,6 +62,7 @@ pub fn channel() -> (Sender, Receiver) { /// sync on drop. If someone adds a `#[derive(Clone)]` below, it is **wrong**. pub struct Sender { inner: mpsc::UnboundedSender, + name: &'static str, /// Clone of [`Receiver::metrics`]. metrics: Arc>>>>, } @@ -82,6 +85,7 @@ impl Drop for Sender { /// Receiving side of a channel. pub struct Receiver { inner: mpsc::UnboundedReceiver, + name: &'static str, /// Initially contains `None`, and will be set to a value once the corresponding [`Sender`] /// is assigned to an instance of [`OutChannels`]. metrics: Arc>>>>, @@ -94,7 +98,7 @@ impl Stream for Receiver { if let Some(ev) = ready!(Pin::new(&mut self.inner).poll_next(cx)) { let metrics = self.metrics.lock().clone(); if let Some(Some(metrics)) = metrics.as_ref().map(|m| &**m) { - metrics.event_out(&ev); + metrics.event_out(&ev, self.name); } else { log::warn!("Inconsistency in out_events: event happened before sender associated"); } @@ -161,7 +165,9 @@ impl OutChannels { }); if let Some(metrics) = &*self.metrics { - metrics.event_in(&event, self.event_streams.len() as u64); + for ev in &self.event_streams { + metrics.event_in(&event, 1, ev.name); + } } } } @@ -190,7 +196,7 @@ impl Metrics { "Number of broadcast network events that have been sent or received across all \ channels" ), - &["event_name", "action"] + &["event_name", "action", "name"] )?, registry)?, notifications_sizes: register(CounterVec::new( Opts::new( @@ -198,7 +204,7 @@ impl Metrics { "Size of notification events that have been sent or received across all \ channels" ), - &["protocol", "action"] + &["protocol", "action", "name"] )?, registry)?, num_channels: register(Gauge::new( "sub_libp2p_out_events_num_channels", @@ -207,60 +213,60 @@ impl Metrics { }) } - fn event_in(&self, event: &Event, num: u64) { + fn event_in(&self, event: &Event, num: u64, name: &str) { match event { Event::Dht(_) => { self.events_total - .with_label_values(&["dht", "sent"]) + .with_label_values(&["dht", "sent", name]) .inc_by(num); } Event::NotificationStreamOpened { engine_id, .. } => { self.events_total - .with_label_values(&[&format!("notif-open-{:?}", engine_id), "sent"]) + .with_label_values(&[&format!("notif-open-{:?}", engine_id), "sent", name]) .inc_by(num); }, Event::NotificationStreamClosed { engine_id, .. } => { self.events_total - .with_label_values(&[&format!("notif-closed-{:?}", engine_id), "sent"]) + .with_label_values(&[&format!("notif-closed-{:?}", engine_id), "sent", name]) .inc_by(num); }, Event::NotificationsReceived { messages, .. } => { for (engine_id, message) in messages { self.events_total - .with_label_values(&[&format!("notif-{:?}", engine_id), "sent"]) + .with_label_values(&[&format!("notif-{:?}", engine_id), "sent", name]) .inc_by(num); self.notifications_sizes - .with_label_values(&[&engine_id_to_string(engine_id), "sent"]) + .with_label_values(&[&engine_id_to_string(engine_id), "sent", name]) .inc_by(num.saturating_mul(u64::try_from(message.len()).unwrap_or(u64::max_value()))); } }, } } - fn event_out(&self, event: &Event) { + fn event_out(&self, event: &Event, name: &str) { match event { Event::Dht(_) => { self.events_total - .with_label_values(&["dht", "received"]) + .with_label_values(&["dht", "received", name]) .inc(); } Event::NotificationStreamOpened { engine_id, .. } => { self.events_total - .with_label_values(&[&format!("notif-open-{:?}", engine_id), "received"]) + .with_label_values(&[&format!("notif-open-{:?}", engine_id), "received", name]) .inc(); }, Event::NotificationStreamClosed { engine_id, .. } => { self.events_total - .with_label_values(&[&format!("notif-closed-{:?}", engine_id), "received"]) + .with_label_values(&[&format!("notif-closed-{:?}", engine_id), "received", name]) .inc(); }, Event::NotificationsReceived { messages, .. } => { for (engine_id, message) in messages { self.events_total - .with_label_values(&[&format!("notif-{:?}", engine_id), "received"]) + .with_label_values(&[&format!("notif-{:?}", engine_id), "received", name]) .inc(); self.notifications_sizes - .with_label_values(&[&engine_id_to_string(engine_id), "received"]) + .with_label_values(&[&engine_id_to_string(engine_id), "received", name]) .inc_by(u64::try_from(message.len()).unwrap_or(u64::max_value())); } }, diff --git a/client/network/src/service/tests.rs b/client/network/src/service/tests.rs index 0e097072e6..a60b32efb4 100644 --- a/client/network/src/service/tests.rs +++ b/client/network/src/service/tests.rs @@ -106,7 +106,7 @@ fn build_test_full_node(config: config::NetworkConfiguration) .unwrap(); let service = worker.service().clone(); - let event_stream = service.event_stream(); + let event_stream = service.event_stream("test"); async_std::task::spawn(async move { futures::pin_mut!(worker); -- GitLab From ae62c56e0b8110fc05cf00903e248e349f08b69b Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 14 Apr 2020 16:04:25 +0200 Subject: [PATCH 219/300] =?UTF-8?q?Phragmen=20solution=20should=20submit?= =?UTF-8?q?=20for=20current=20era=20and=20be=20checked=E2=80=A6=20(#5583)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * submit solution for current era * add test * address comment * fix tests --- frame/staking/src/lib.rs | 2 +- frame/staking/src/mock.rs | 8 +++ frame/staking/src/offchain_election.rs | 6 +-- frame/staking/src/tests.rs | 70 +++++++++++++------------- 4 files changed, 47 insertions(+), 39 deletions(-) diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index bc2721bc9f..ddf05f6ffd 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -2327,7 +2327,7 @@ impl Module { ); // check current era. - if let Some(current_era) = Self::active_era().map(|e| e.index) { + if let Some(current_era) = Self::current_era() { ensure!( current_era == era, Error::::PhragmenEarlySubmission, diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 8e2b583c5e..f649c530c1 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -506,6 +506,10 @@ pub type Session = pallet_session::Module; pub type Timestamp = pallet_timestamp::Module; pub type Staking = Module; +pub(crate) fn current_era() -> EraIndex { + Staking::current_era().unwrap() +} + fn post_conditions() { check_nominators(); check_exposures(); @@ -649,9 +653,13 @@ pub(crate) fn start_session(session_index: SessionIndex) { assert_eq!(Session::current_index(), session_index); } +// This start and activate the era given. +// Because the mock use pallet-session which delays session by one, this will be one session after +// the election happened, not the first session after the election has happened. pub(crate) fn start_era(era_index: EraIndex) { start_session((era_index * >::get()).into()); assert_eq!(Staking::current_era().unwrap(), era_index); + assert_eq!(Staking::active_era().unwrap().index, era_index); } pub(crate) fn current_total_payout_for_duration(duration: u64) -> Balance { diff --git a/frame/staking/src/offchain_election.rs b/frame/staking/src/offchain_election.rs index 0d4cf49f10..19196e917f 100644 --- a/frame/staking/src/offchain_election.rs +++ b/frame/staking/src/offchain_election.rs @@ -113,15 +113,15 @@ pub(crate) fn compute_offchain_election() -> Result<(), OffchainElecti // process and prepare it for submission. let (winners, compact, score) = prepare_submission::(assignments, winners, true)?; - // defensive-only: active era can never be none except genesis. - let era = >::active_era().map(|e| e.index).unwrap_or_default(); + // defensive-only: current era can never be none except genesis. + let current_era = >::current_era().unwrap_or_default(); // send it. let call: ::Call = Call::submit_election_solution_unsigned( winners, compact, score, - era, + current_era, ).into(); T::SubmitTransaction::submit_unsigned(call) diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 837b085d68..dd00fdcd3c 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -1847,20 +1847,20 @@ fn era_is_always_same_length() { let session_per_era = >::get(); mock::start_era(1); - assert_eq!(Staking::eras_start_session_index(active_era()).unwrap(), session_per_era); + assert_eq!(Staking::eras_start_session_index(current_era()).unwrap(), session_per_era); mock::start_era(2); - assert_eq!(Staking::eras_start_session_index(active_era()).unwrap(), session_per_era * 2u32); + assert_eq!(Staking::eras_start_session_index(current_era()).unwrap(), session_per_era * 2u32); let session = Session::current_index(); ForceEra::put(Forcing::ForceNew); advance_session(); advance_session(); - assert_eq!(Staking::active_era().unwrap().index, 3); - assert_eq!(Staking::eras_start_session_index(active_era()).unwrap(), session + 2); + assert_eq!(current_era(), 3); + assert_eq!(Staking::eras_start_session_index(current_era()).unwrap(), session + 2); mock::start_era(4); - assert_eq!(Staking::eras_start_session_index(active_era()).unwrap(), session + 2u32 + session_per_era); + assert_eq!(Staking::eras_start_session_index(current_era()).unwrap(), session + 2u32 + session_per_era); }); } @@ -2912,7 +2912,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), )); let queued_result = Staking::queued_elected().unwrap(); @@ -2955,7 +2955,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), )); let queued_result = Staking::queued_elected().unwrap(); @@ -3005,7 +3005,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenEarlySubmission, ); @@ -3031,7 +3031,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), )); // a bad solution @@ -3042,7 +3042,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenWeakSubmission, ); @@ -3068,7 +3068,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), )); // a better solution @@ -3078,7 +3078,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), )); }) } @@ -3116,7 +3116,7 @@ mod offchain_phragmen { TransactionValidity::Ok(ValidTransaction { priority: (1 << 20) + 1125, // the proposed slot stake. requires: vec![], - provides: vec![("StakingOffchain", active_era()).encode()], + provides: vec![("StakingOffchain", current_era()).encode()], longevity: 3, propagate: false, }) @@ -3140,7 +3140,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ),); // now run the offchain worker in the same chain state. @@ -3191,7 +3191,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenBogusWinnerCount, ); @@ -3222,7 +3222,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenBogusWinnerCount, ); @@ -3251,7 +3251,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ),); }) } @@ -3282,7 +3282,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenBogusCompact, ); @@ -3315,7 +3315,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenBogusCompact, ); @@ -3347,7 +3347,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenBogusWinner, ); @@ -3383,7 +3383,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenBogusEdge, ); @@ -3419,7 +3419,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenBogusSelfVote, ); @@ -3455,7 +3455,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenBogusSelfVote, ); @@ -3490,7 +3490,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenBogusCompact, ); @@ -3532,7 +3532,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenBogusNomination, ); @@ -3560,7 +3560,7 @@ mod offchain_phragmen { run_to_block(20); // slash 10. This must happen outside of the election window. - let offender_expo = Staking::eras_stakers(active_era(), 11); + let offender_expo = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); on_offence_now( &[OffenceDetails { offender: (11, offender_expo.clone()), @@ -3595,7 +3595,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), )); // a wrong solution. @@ -3614,7 +3614,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenSlashedNomination, ); @@ -3642,7 +3642,7 @@ mod offchain_phragmen { winners, compact, score, - active_era(), + current_era(), ), Error::::PhragmenBogusScore, ); @@ -3729,7 +3729,7 @@ mod offchain_phragmen { run_to_block(12); assert_eq!(Staking::era_election_status(), ElectionStatus::Open(12)); - let offender_expo = Staking::eras_stakers(active_era(), 10); + let offender_expo = Staking::eras_stakers(Staking::active_era().unwrap().index, 10); // panic from the impl in mock on_offence_now( @@ -3754,8 +3754,8 @@ fn slash_kicks_validators_not_nominators_and_disables_nominator_for_kicked_valid assert_eq!(Balances::free_balance(101), 2000); // 11 and 21 both have the support of 100 - let exposure_11 = Staking::eras_stakers(active_era(), &11); - let exposure_21 = Staking::eras_stakers(active_era(), &21); + let exposure_11 = Staking::eras_stakers(Staking::active_era().unwrap().index, &11); + let exposure_21 = Staking::eras_stakers(Staking::active_era().unwrap().index, &21); assert_eq!(exposure_11.total, 1000 + 125); assert_eq!(exposure_21.total, 1000 + 375); @@ -3795,8 +3795,8 @@ fn slash_kicks_validators_not_nominators_and_disables_nominator_for_kicked_valid assert_ok!(Staking::validate(Origin::signed(10), Default::default())); mock::start_era(2); - let exposure_11 = Staking::eras_stakers(active_era(), &11); - let exposure_21 = Staking::eras_stakers(active_era(), &21); + let exposure_11 = Staking::eras_stakers(Staking::active_era().unwrap().index, &11); + let exposure_21 = Staking::eras_stakers(Staking::active_era().unwrap().index, &21); // 10 is re-elected, but without the support of 100 assert_eq!(exposure_11.total, 900); @@ -3897,7 +3897,7 @@ fn zero_slash_keeps_nominators() { assert_eq!(Balances::free_balance(11), 1000); - let exposure = Staking::eras_stakers(active_era(), 11); + let exposure = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); assert_eq!(Balances::free_balance(101), 2000); on_offence_now( -- GitLab From 2cb699a28524f9bbc0f21a7f8ca09c2091cb2687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Tue, 14 Apr 2020 16:05:11 +0200 Subject: [PATCH 220/300] Add tests for weight refund (#5624) * Add tests for weight refund * Update frame/system/src/lib.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Fixed formatting * Format fixes Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/system/src/lib.rs | 40 ++++++++++++++ frame/transaction-payment/src/lib.rs | 80 +++++++++++++++++++++++++--- 2 files changed, 114 insertions(+), 6 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 24d5e724ce..70e4f96e9f 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -1913,6 +1913,46 @@ mod tests { }) } + #[test] + fn signed_ext_check_weight_refund_works() { + new_test_ext().execute_with(|| { + let info = DispatchInfo { weight: 512, ..Default::default() }; + let post_info = PostDispatchInfo { actual_weight: Some(128), }; + let len = 0_usize; + + AllExtrinsicsWeight::put(256); + + let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); + assert_eq!(AllExtrinsicsWeight::get().unwrap(), info.weight + 256); + + assert!( + CheckWeight::::post_dispatch(pre, &info, &post_info, len, &Ok(())) + .is_ok() + ); + assert_eq!(AllExtrinsicsWeight::get().unwrap(), post_info.actual_weight.unwrap() + 256); + }) + } + + #[test] + fn signed_ext_check_weight_actual_weight_higher_than_max_is_capped() { + new_test_ext().execute_with(|| { + let info = DispatchInfo { weight: 512, ..Default::default() }; + let post_info = PostDispatchInfo { actual_weight: Some(700), }; + let len = 0_usize; + + AllExtrinsicsWeight::put(128); + + let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); + assert_eq!(AllExtrinsicsWeight::get().unwrap(), info.weight + 128); + + assert!( + CheckWeight::::post_dispatch(pre, &info, &post_info, len, &Ok(())) + .is_ok() + ); + assert_eq!(AllExtrinsicsWeight::get().unwrap(), info.weight + 128); + }) + } + #[test] fn signed_ext_check_weight_fee_works() { new_test_ext().execute_with(|| { diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 6c5f2a7480..0136bcc85a 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -310,7 +310,7 @@ mod tests { use codec::Encode; use frame_support::{ impl_outer_dispatch, impl_outer_origin, parameter_types, - weights::{DispatchClass, DispatchInfo, GetDispatchInfo, Weight}, + weights::{DispatchClass, DispatchInfo, PostDispatchInfo, GetDispatchInfo, Weight}, }; use pallet_balances::Call as BalancesCall; use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; @@ -482,6 +482,14 @@ mod tests { DispatchInfo { weight: w, pays_fee: true, ..Default::default() } } + fn post_info_from_weight(w: Weight) -> PostDispatchInfo { + PostDispatchInfo { actual_weight: Some(w), } + } + + fn default_post_info() -> PostDispatchInfo { + PostDispatchInfo { actual_weight: None, } + } + #[test] fn signed_extension_transaction_payment_work() { ExtBuilder::default() @@ -491,19 +499,29 @@ mod tests { .execute_with(|| { let len = 10; + let pre = ChargeTransactionPayment::::from(0) + .pre_dispatch(&1, CALL, &info_from_weight(5), len) + .unwrap(); + assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10); + assert!( - ChargeTransactionPayment::::from(0) - .pre_dispatch(&1, CALL, &info_from_weight(5), len) + ChargeTransactionPayment:: + ::post_dispatch(pre, &info_from_weight(5), &default_post_info(), len, &Ok(())) .is_ok() ); assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10); + let pre = ChargeTransactionPayment::::from(5 /* tipped */) + .pre_dispatch(&2, CALL, &info_from_weight(100), len) + .unwrap(); + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); + assert!( - ChargeTransactionPayment::::from(5 /* tipped */) - .pre_dispatch(&2, CALL, &info_from_weight(3), len) + ChargeTransactionPayment:: + ::post_dispatch(pre, &info_from_weight(100), &post_info_from_weight(50), len, &Ok(())) .is_ok() ); - assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 3 - 5); + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 50 - 5); }); } @@ -722,4 +740,54 @@ mod tests { ); }); } + + #[test] + fn refund_does_not_recreate_account() { + ExtBuilder::default() + .balance_factor(10) + .base_fee(5) + .build() + .execute_with(|| + { + let len = 10; + let pre = ChargeTransactionPayment::::from(5 /* tipped */) + .pre_dispatch(&2, CALL, &info_from_weight(100), len) + .unwrap(); + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); + + // kill the account between pre and post dispatch + assert!(Balances::transfer(Some(2).into(), 3, Balances::free_balance(2)).is_ok()); + assert_eq!(Balances::free_balance(2), 0); + + assert!( + ChargeTransactionPayment:: + ::post_dispatch(pre, &info_from_weight(100), &post_info_from_weight(50), len, &Ok(())) + .is_ok() + ); + assert_eq!(Balances::free_balance(2), 0); + }); + } + + #[test] + fn actual_weight_higher_than_max_refunds_nothing() { + ExtBuilder::default() + .balance_factor(10) + .base_fee(5) + .build() + .execute_with(|| + { + let len = 10; + let pre = ChargeTransactionPayment::::from(5 /* tipped */) + .pre_dispatch(&2, CALL, &info_from_weight(100), len) + .unwrap(); + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); + + assert!( + ChargeTransactionPayment:: + ::post_dispatch(pre, &info_from_weight(100), &post_info_from_weight(101), len, &Ok(())) + .is_ok() + ); + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); + }); + } } -- GitLab From fa34cd474cb764599501192df43fa3ec9d797d27 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 14 Apr 2020 16:08:09 +0200 Subject: [PATCH 221/300] .maintain/sentry-node: Add monitoring to docker-compose stack (#5321) * Substrate Dashboard example * Improve README * Update README_dashboard.md * Add screenshots * Minor fix * Minor fix, image link * .maintain/sentry-node: Add monitoring to docker-compose stack With this patch a user can run the following fully configured and monitored setup with a single command: `docker-compose -f .maintain/sentry-node/docker-compose.yml up` - 2 validators in two different network namespaces, connected via one sentry node. - Polkadot-js/apps to connect to one of the nodes above. - Prometheus scraping the 3 Substrate nodes. - Grafana displaying data from Prometheus with community dashboards * .maintain/monitoring/grafana: Change default datasource name * .maintain/monitoring/grafana: Add metric namespace option * .maintain/monitoring/grafana: Remove `host` metric from most metrics * .maintain/monitoring/grafana: Remove underscore from metric_namespace * .maintain/monitoring: Use `instance` label instead of `hostname` To identify a scrape target, one should use `instance` and not `hostname` as multiple targets might run on the same node. See https://prometheus.io/docs/concepts/jobs_instances/ for details. * .maintain/monitoring: Introduce instance variable * .maintain/monitoring/grafana: Rename substrate_block_height_number * .maitain/monitoring/grafana: Use instance instead of host in legend * .maintain/monitoring: Remove node exporter dependency * .maintain/sentry-node/prometheus: Simplify configuration * .maintain/monitoring/grafana: Update README and remove images * .maintain/sentry-node: Improve docs * .maintain/monitoring/grafana: Use metric_namespace template variable * Use --sentry from v0.7.29 instead of a reserved-node * .maintain/sentry-node: Revert sentry-a using validator-b as bootnode Co-authored-by: DerFredy - @derfredy:matrix.org Co-authored-by: david --- .../grafana-dashboards/README_dashboard.md | 14 + .../substrate-dashboard.json | 1650 +++++++++++++++++ .maintain/sentry-node/docker-compose.yml | 37 +- .../provisioning/dashboards/dashboards.yml | 11 + .../provisioning/datasources/datasource.yml | 50 + .../sentry-node/prometheus/prometheus.yml | 15 + 6 files changed, 1776 insertions(+), 1 deletion(-) create mode 100644 .maintain/monitoring/grafana-dashboards/README_dashboard.md create mode 100644 .maintain/monitoring/grafana-dashboards/substrate-dashboard.json create mode 100644 .maintain/sentry-node/grafana/provisioning/dashboards/dashboards.yml create mode 100644 .maintain/sentry-node/grafana/provisioning/datasources/datasource.yml create mode 100644 .maintain/sentry-node/prometheus/prometheus.yml diff --git a/.maintain/monitoring/grafana-dashboards/README_dashboard.md b/.maintain/monitoring/grafana-dashboards/README_dashboard.md new file mode 100644 index 0000000000..37bebc6f8e --- /dev/null +++ b/.maintain/monitoring/grafana-dashboards/README_dashboard.md @@ -0,0 +1,14 @@ +## Substrate Dashboard + +Shared templated Grafana dashboards. + +To import the dashboards follow the [Grafana +documentation](https://grafana.com/docs/grafana/latest/reference/export_import/). +You can see an example setup [here](../../../.maintain/sentry-node). + +#### Required labels on Prometheus metrics + +- `instance` referring to a single scrape target (see [Prometheus docs for + details](https://prometheus.io/docs/concepts/jobs_instances/)). + +- `network` referring to the Blockchain network e.g. Kusama. diff --git a/.maintain/monitoring/grafana-dashboards/substrate-dashboard.json b/.maintain/monitoring/grafana-dashboards/substrate-dashboard.json new file mode 100644 index 0000000000..629b22617b --- /dev/null +++ b/.maintain/monitoring/grafana-dashboards/substrate-dashboard.json @@ -0,0 +1,1650 @@ +{ + "annotations": { + "list": [ + { + "$$hashKey": "object:15", + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1586424254170, + "links": [ + { + "icon": "external link", + "tags": [], + "targetBlank": true, + "title": "With love from ColmenaLabs", + "tooltip": "", + "type": "link", + "url": "https://colmenalabs.org" + }, + { + "icon": "external link", + "tags": [], + "targetBlank": true, + "title": "Polkastats.io", + "tooltip": "", + "type": "link", + "url": "https://polkastats.io" + } + ], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate([[metric_namespace]]_block_height{status=\"finalized\",instance=\"[[instance]]\",network=\"[[network]]\"}[10m])/rate([[metric_namespace]]_block_height{status=\"finalized\",instance=\"[[instance]]\",network=\"[[network]]\"}[1m])", + "intervalFactor": 1, + "legendFormat": "rate[10m] / rate[1m]", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Relative Block Production Speed", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 0 + }, + "hiddenSeries": false, + "id": 15, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "[[metric_namespace]]_sub_libp2p_peers_count{instance=\"[[instance]]\",network=\"[[network]]\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Peers count", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 0 + }, + "hiddenSeries": false, + "id": 17, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pluginVersion": "6.4.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "scalar([[metric_namespace]]_block_height{status=\"best\",instance=\"[[instance]]\",network=\"[[network]]\"})-scalar([[metric_namespace]]_block_height{status=\"finalized\",instance=\"[[instance]]\",network=\"[[network]]\"})", + "intervalFactor": 2, + "legendFormat": "[[hostname]]", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Diff -> ( Best Block - Finalized )", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 0 + }, + "hiddenSeries": false, + "id": 18, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate([[metric_namespace]]_block_height{status=\"finalized\",instance=\"[[instance]]\",network=\"[[network]]\"}[10m])*60", + "intervalFactor": 10, + "legendFormat": "{{instance}} Blocks / minute", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Block rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 6 + }, + "hiddenSeries": false, + "id": 10, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "increase([[metric_namespace]]_block_height{instance=\"[[instance]]\",network=\"[[network]]\",status=~\"finalized|sync_target\"}[1m])", + "intervalFactor": 5, + "legendFormat": "{{status}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Blocks Av per min", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 6 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "[[metric_namespace]]_block_height{instance=\"[[instance]]\",network=\"[[network]]\",status=~\"finalized|sync_target\"}", + "legendFormat": "{{instance}} {{status}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Block Finalized", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 6 + }, + "hiddenSeries": false, + "id": 13, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "[[metric_namespace]]_block_height{status=\"best\",instance=\"[[instance]]\",network=\"[[network]]\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Block height", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 6 + }, + "hiddenSeries": false, + "id": 20, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "data": "", + "expr": "[[metric_namespace]]_ready_transactions_number{instance=\"[[instance]]\",network=\"[[network]]\"}", + "hide": false, + "legendFormat": "{{instance}}", + "refId": "A", + "target": "txcount", + "type": "timeseries" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "TXs Count", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 12 + }, + "hiddenSeries": false, + "id": 23, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "[[metric_namespace]]_sync_extra_finality_proofs_active{instance=\"[[instance]]\",network=\"[[network]]\"}", + "legendFormat": "{{instance}} active", + "refId": "A" + }, + { + "expr": "[[metric_namespace]]_sync_extra_finality_proofs_failed{instance=\"[[instance]]\",network=\"[[network]]\"}", + "legendFormat": "{{instance}} failed", + "refId": "B" + }, + { + "expr": "[[metric_namespace]]_sync_extra_finality_proofs_importing{instance=\"[[instance]]\",network=\"[[network]]\"}", + "legendFormat": "{{instance}} importing", + "refId": "C" + }, + { + "expr": "[[metric_namespace]]_sync_extra_finality_proofs_pending{instance=\"[[instance]]\",network=\"[[network]]\"}", + "legendFormat": "{{instance}} pending", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Sync Proof", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 12 + }, + "hiddenSeries": false, + "id": 22, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "[[metric_namespace]]_sync_extra_justifications_active{instance=\"[[instance]]\",network=\"[[network]]\"}", + "legendFormat": "{{instance}} active", + "refId": "A" + }, + { + "expr": "[[metric_namespace]]_sync_extra_justifications_failed{instance=\"[[instance]]\",network=\"[[network]]\"}", + "legendFormat": "{{instance}} failed", + "refId": "B" + }, + { + "expr": "[[metric_namespace]]_sync_extra_justifications_importing{instance=\"[[instance]]\",network=\"[[network]]\"}", + "legendFormat": "{{instance}} importing", + "refId": "C" + }, + { + "expr": "[[metric_namespace]]_sync_extra_justifications_pending{instance=\"[[instance]]\",network=\"[[network]]\"}", + "legendFormat": "{{instance}} pending", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Sync justifications", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 12 + }, + "hiddenSeries": false, + "id": 24, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "[[metric_namespace]]_sub_libp2p_connections{instance=\"[[instance]]\",network=\"[[network]]\"}", + "hide": false, + "legendFormat": "{{instance}} connections", + "refId": "A" + }, + { + "expr": "[[metric_namespace]]_sub_libp2p_is_major_syncing{instance=\"[[instance]]\",network=\"[[network]]\"}", + "hide": false, + "legendFormat": "{{instance}} syncing", + "refId": "B" + }, + { + "expr": "[[metric_namespace]]_sub_libp2p_kbuckets_num_nodes{instance=\"[[instance]]\",network=\"[[network]]\"}", + "hide": false, + "legendFormat": "{{instance}} num_nodes", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "sub_libp2p", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 12 + }, + "hiddenSeries": false, + "id": 26, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "[[metric_namespace]]_sub_libp2p_notifications_total{instance=\"[[instance]]\",network=\"[[network]]\",protocol=\"FRNK\",direction=\"in\"}", + "hide": false, + "legendFormat": "{{instance}} FRNK in", + "refId": "A" + }, + { + "expr": "[[metric_namespace]]_sub_libp2p_notifications_total{instance=\"[[instance]]\",network=\"[[network]]\",protocol=\"FRNK\",direction=\"out\"}", + "hide": false, + "legendFormat": "{{instance}} FRNK out", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "libp2p_notifications", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 18 + }, + "hiddenSeries": false, + "id": 28, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "[[metric_namespace]]_cpu_usage_percentage{instance=\"[[instance]]\",network=\"[[network]]\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU usage %", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 18 + }, + "hiddenSeries": false, + "id": 27, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "[[metric_namespace]]_memory_usage_bytes{instance=\"[[instance]]\",network=\"[[network]]\"}", + "legendFormat": "{{instance}} Mem bytes", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 2, + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 18 + }, + "hiddenSeries": false, + "id": 25, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "[[metric_namespace]]_sub_libp2p_network_per_sec_bytes", + "hide": false, + "legendFormat": "{{instance}}", + "refId": "A" + }, + { + "expr": "[[metric_namespace]]_sub_libp2p_notifications_total", + "hide": true, + "legendFormat": "{{instance}}", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "libp2p_network_per_sec_bytes", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 18 + }, + "hiddenSeries": false, + "id": 29, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pluginVersion": "6.5.2", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "[[metric_namespace]]_sub_libp2p_notifications_total{instance=\"[[instance]]\",network=\"[[network]]\",protocol=\"dot1\",direction=\"in\"}", + "hide": false, + "legendFormat": "{{instance}} dot1 in", + "refId": "B" + }, + { + "expr": "[[metric_namespace]]_sub_libp2p_notifications_total{instance=\"[[instance]]\",network=\"[[network]]\",protocol=\"dot2\",direction=\"in\"}", + "hide": false, + "legendFormat": "{{instance}} dot2 in", + "refId": "C" + }, + { + "expr": "[[metric_namespace]]_sub_libp2p_notifications_total{instance=\"[[instance]]\",network=\"[[network]]\",protocol=\"dot2\",direction=\"out\"}", + "hide": false, + "legendFormat": "{{instance}} dot2 out", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "libp2p_notifications", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 22, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": null, + "current": { + "selected": true, + "text": "substrate", + "value": "substrate" + }, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "metric_namespace", + "options": [ + { + "selected": true, + "text": "substrate", + "value": "substrate" + }, + { + "selected": false, + "text": "polkadot", + "value": "polkadot" + } + ], + "query": "substrate, polkadot", + "skipUrlSync": false, + "type": "custom" + }, + { + "allValue": null, + "current": { + "selected": true, + "text": "dev", + "value": "dev" + }, + "datasource": "Prometheus", + "definition": "label_values(network)", + "hide": 0, + "includeAll": false, + "index": -1, + "label": null, + "multi": false, + "name": "network", + "options": [], + "query": "label_values(network)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "selected": false, + "text": "validator-a:9615", + "value": "validator-a:9615" + }, + "datasource": "Prometheus", + "definition": "label_values(instance)", + "hide": 0, + "includeAll": false, + "index": -1, + "label": null, + "multi": false, + "name": "instance", + "options": [], + "query": "label_values(instance)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Substrate Dashboard", + "uid": "ColmenaLabs", + "variables": { + "list": [] + }, + "version": 2 +} diff --git a/.maintain/sentry-node/docker-compose.yml b/.maintain/sentry-node/docker-compose.yml index db835b0579..225fc74f98 100644 --- a/.maintain/sentry-node/docker-compose.yml +++ b/.maintain/sentry-node/docker-compose.yml @@ -19,6 +19,9 @@ # - validator-a: localhost:9944 # - validator-b: localhost:9945 # - sentry-a: localhost:9946 +# - grafana: localhost:3001 +# - prometheus: localhost:9090 + version: "3.7" services: @@ -80,7 +83,7 @@ services: - "--port" - "30333" - "--charlie" - - "--bootnodes" + - "--sentry" - "/dns4/validator-a/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR" - "--bootnodes" - "/dns4/validator-b/tcp/30333/p2p/QmSVnNf9HwVMT1Y4cK1P6aoJcEZjmoTXpjKBmAABLMnZEk" @@ -95,6 +98,7 @@ services: - "--log" - "sub-authority-discovery=trace" - "--sentry" + - "--prometheus-external" validator-b: image: parity/substrate @@ -127,12 +131,43 @@ services: - "--unsafe-rpc-external" - "--log" - "sub-authority-discovery=trace" + - "--prometheus-external" ui: image: polkadot-js/apps ports: - "3000:80" + prometheus: + image: prom/prometheus + networks: + - network-a + - internet + ports: + - "9090:9090" + links: + - validator-a:validator-a + - sentry-a:sentry-a + - validator-b:validator-b + volumes: + - ./prometheus/:/etc/prometheus/ + restart: always + + grafana: + image: grafana/grafana + user: "104" + depends_on: + - prometheus + networks: + - network-a + - internet + ports: + - 3001:3000 + volumes: + - ./grafana/provisioning/:/etc/grafana/provisioning + - ../monitoring/grafana-dashboards/:/etc/grafana/provisioning/dashboard-definitions + restart: always + networks: network-a: internet: diff --git a/.maintain/sentry-node/grafana/provisioning/dashboards/dashboards.yml b/.maintain/sentry-node/grafana/provisioning/dashboards/dashboards.yml new file mode 100644 index 0000000000..ad9164fd8e --- /dev/null +++ b/.maintain/sentry-node/grafana/provisioning/dashboards/dashboards.yml @@ -0,0 +1,11 @@ +apiVersion: 1 + +providers: +- name: 'Prometheus' + orgId: 1 + folder: '' + type: file + disableDeletion: false + editable: false + options: + path: /etc/grafana/provisioning/dashboard-definitions diff --git a/.maintain/sentry-node/grafana/provisioning/datasources/datasource.yml b/.maintain/sentry-node/grafana/provisioning/datasources/datasource.yml new file mode 100644 index 0000000000..c02bb38b3d --- /dev/null +++ b/.maintain/sentry-node/grafana/provisioning/datasources/datasource.yml @@ -0,0 +1,50 @@ +# config file version +apiVersion: 1 + +# list of datasources that should be deleted from the database +deleteDatasources: + - name: Prometheus + orgId: 1 + +# list of datasources to insert/update depending +# whats available in the database +datasources: + # name of the datasource. Required +- name: Prometheus + # datasource type. Required + type: prometheus + # access mode. direct or proxy. Required + access: proxy + # org id. will default to orgId 1 if not specified + orgId: 1 + # url + url: http://prometheus:9090 + # database password, if used + password: + # database user, if used + user: + # database name, if used + database: + # enable/disable basic auth + basicAuth: false + # basic auth username, if used + basicAuthUser: + # basic auth password, if used + basicAuthPassword: + # enable/disable with credentials headers + withCredentials: + # mark as default datasource. Max one per org + isDefault: true + # fields that will be converted to json and stored in json_data + jsonData: + graphiteVersion: "1.1" + tlsAuth: false + tlsAuthWithCACert: false + # json object of data that will be encrypted. + secureJsonData: + tlsCACert: "..." + tlsClientCert: "..." + tlsClientKey: "..." + version: 1 + # allow users to edit datasources from the UI. + editable: true diff --git a/.maintain/sentry-node/prometheus/prometheus.yml b/.maintain/sentry-node/prometheus/prometheus.yml new file mode 100644 index 0000000000..831b84ba0b --- /dev/null +++ b/.maintain/sentry-node/prometheus/prometheus.yml @@ -0,0 +1,15 @@ +global: + scrape_interval: 15s + +scrape_configs: + - job_name: 'substrate_validator-a' + static_configs: + - targets: ['validator-a:9615'] + labels: + network: dev + - targets: ['sentry-a:9615'] + labels: + network: dev + - targets: ['validator-b:9615'] + labels: + network: dev -- GitLab From 292b5586582ac16aa587632cc0861ac058c5ad18 Mon Sep 17 00:00:00 2001 From: Fredrik Harrysson Date: Tue, 14 Apr 2020 18:30:33 +0200 Subject: [PATCH 222/300] Adding Process.toml for processbot (#5634) --- Process.toml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Process.toml diff --git a/Process.toml b/Process.toml new file mode 100644 index 0000000000..a81a6495bd --- /dev/null +++ b/Process.toml @@ -0,0 +1,24 @@ +[Networking] +owner = "tomaka" +whitelist = [] +matrix_room_id = "#libp2p:matrix.parity.io" + +[Client] +owner = "gnunicorn" +whitelist = [] +matrix_room_id = "#substrate:matrix.parity.io" + +[Runtime] +owner = "gavofyork" +whitelist = [] +matrix_room_id = "#substrate-frame:matrix.parity.io" + +[Consensus] +owner = "andresilva" +whitelist = [] +matrix_room_id = "#consensus-team:matrix.parity.io" + +[Smart Contracts] +owner = "pepyakin" +whitelist = [] +matrix_room_id = "#substrate-frame:matrix.parity.io" -- GitLab From 67f354f57e738fa575775f7fa0fb903e8972182b Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Tue, 14 Apr 2020 21:41:49 +0200 Subject: [PATCH 223/300] Prepping release of alpha.6 (#5629) * bumping version * cargo update * adding changelog --- Cargo.lock | 574 +++++++++--------- bin/node-template/node/Cargo.toml | 46 +- bin/node-template/pallets/template/Cargo.toml | 18 +- bin/node-template/runtime/Cargo.toml | 54 +- bin/node/bench/Cargo.toml | 14 +- bin/node/cli/Cargo.toml | 122 ++-- bin/node/executor/Cargo.toml | 54 +- bin/node/inspect/Cargo.toml | 20 +- bin/node/primitives/Cargo.toml | 14 +- bin/node/rpc-client/Cargo.toml | 12 +- bin/node/rpc/Cargo.toml | 40 +- bin/node/runtime/Cargo.toml | 116 ++-- bin/node/testing/Cargo.toml | 74 +-- bin/node/transaction-factory/Cargo.toml | 30 +- bin/utils/chain-spec-builder/Cargo.toml | 16 +- bin/utils/subkey/Cargo.toml | 24 +- client/Cargo.toml | 46 +- client/api/Cargo.toml | 42 +- client/authority-discovery/Cargo.toml | 28 +- client/basic-authorship/Cargo.toml | 30 +- client/block-builder/Cargo.toml | 26 +- client/chain-spec/Cargo.toml | 20 +- client/chain-spec/derive/Cargo.toml | 8 +- client/cli/Cargo.toml | 38 +- client/consensus/aura/Cargo.toml | 52 +- client/consensus/babe/Cargo.toml | 60 +- client/consensus/babe/rpc/Cargo.toml | 30 +- client/consensus/epochs/Cargo.toml | 16 +- client/consensus/manual-seal/Cargo.toml | 26 +- client/consensus/pow/Cargo.toml | 28 +- client/consensus/slots/Cargo.toml | 26 +- client/consensus/uncles/Cargo.toml | 20 +- client/db/Cargo.toml | 32 +- client/executor/Cargo.toml | 36 +- client/executor/common/Cargo.toml | 18 +- client/executor/runtime-test/Cargo.toml | 18 +- client/executor/wasmi/Cargo.toml | 18 +- client/executor/wasmtime/Cargo.toml | 18 +- client/finality-grandpa/Cargo.toml | 56 +- client/informant/Cargo.toml | 18 +- client/keystore/Cargo.toml | 12 +- client/network-gossip/Cargo.toml | 14 +- client/network/Cargo.toml | 38 +- client/network/test/Cargo.toml | 24 +- client/offchain/Cargo.toml | 30 +- client/peerset/Cargo.toml | 10 +- client/rpc-api/Cargo.toml | 20 +- client/rpc-servers/Cargo.toml | 10 +- client/rpc/Cargo.toml | 50 +- client/service/Cargo.toml | 62 +- client/service/test/Cargo.toml | 20 +- client/state-db/Cargo.toml | 12 +- client/telemetry/Cargo.toml | 8 +- client/tracing/Cargo.toml | 10 +- client/transaction-pool/Cargo.toml | 26 +- client/transaction-pool/graph/Cargo.toml | 18 +- docs/CHANGELOG.md | 38 +- frame/assets/Cargo.toml | 20 +- frame/aura/Cargo.toml | 32 +- frame/authority-discovery/Cargo.toml | 28 +- frame/authorship/Cargo.toml | 24 +- frame/babe/Cargo.toml | 34 +- frame/balances/Cargo.toml | 24 +- frame/benchmark/Cargo.toml | 20 +- frame/benchmarking/Cargo.toml | 22 +- frame/collective/Cargo.toml | 24 +- frame/contracts/Cargo.toml | 30 +- frame/contracts/common/Cargo.toml | 12 +- frame/contracts/rpc/Cargo.toml | 22 +- frame/contracts/rpc/runtime-api/Cargo.toml | 16 +- frame/democracy/Cargo.toml | 28 +- frame/elections-phragmen/Cargo.toml | 28 +- frame/elections/Cargo.toml | 22 +- frame/evm/Cargo.toml | 24 +- frame/example-offchain-worker/Cargo.toml | 20 +- frame/example/Cargo.toml | 24 +- frame/executive/Cargo.toml | 28 +- frame/finality-tracker/Cargo.toml | 24 +- frame/generic-asset/Cargo.toml | 20 +- frame/grandpa/Cargo.toml | 28 +- frame/identity/Cargo.toml | 24 +- frame/im-online/Cargo.toml | 30 +- frame/indices/Cargo.toml | 24 +- frame/membership/Cargo.toml | 20 +- frame/metadata/Cargo.toml | 12 +- frame/nicks/Cargo.toml | 22 +- frame/offences/Cargo.toml | 24 +- frame/offences/benchmarking/Cargo.toml | 30 +- frame/randomness-collective-flip/Cargo.toml | 20 +- frame/recovery/Cargo.toml | 22 +- frame/scheduler/Cargo.toml | 16 +- frame/scored-pool/Cargo.toml | 22 +- frame/session/Cargo.toml | 28 +- frame/session/benchmarking/Cargo.toml | 32 +- frame/society/Cargo.toml | 22 +- frame/staking/Cargo.toml | 48 +- frame/staking/reward-curve/Cargo.toml | 10 +- frame/sudo/Cargo.toml | 20 +- frame/support/Cargo.toml | 28 +- frame/support/procedural/Cargo.toml | 10 +- frame/support/procedural/tools/Cargo.toml | 10 +- .../procedural/tools/derive/Cargo.toml | 8 +- frame/support/test/Cargo.toml | 18 +- frame/system/Cargo.toml | 22 +- frame/system/rpc/runtime-api/Cargo.toml | 10 +- frame/timestamp/Cargo.toml | 28 +- frame/transaction-payment/Cargo.toml | 24 +- frame/transaction-payment/rpc/Cargo.toml | 20 +- .../rpc/runtime-api/Cargo.toml | 16 +- frame/treasury/Cargo.toml | 24 +- frame/utility/Cargo.toml | 26 +- frame/vesting/Cargo.toml | 26 +- primitives/allocator/Cargo.toml | 14 +- primitives/api/Cargo.toml | 20 +- primitives/api/proc-macro/Cargo.toml | 8 +- primitives/api/test/Cargo.toml | 22 +- primitives/application-crypto/Cargo.toml | 14 +- primitives/application-crypto/test/Cargo.toml | 14 +- primitives/arithmetic/Cargo.toml | 12 +- primitives/arithmetic/fuzzer/Cargo.toml | 10 +- primitives/authority-discovery/Cargo.toml | 16 +- primitives/authorship/Cargo.toml | 14 +- primitives/block-builder/Cargo.toml | 16 +- primitives/blockchain/Cargo.toml | 16 +- primitives/chain-spec/Cargo.toml | 2 +- primitives/consensus/aura/Cargo.toml | 20 +- primitives/consensus/babe/Cargo.toml | 24 +- primitives/consensus/common/Cargo.toml | 22 +- primitives/consensus/pow/Cargo.toml | 16 +- primitives/consensus/vrf/Cargo.toml | 14 +- primitives/core/Cargo.toml | 20 +- primitives/debug-derive/Cargo.toml | 10 +- primitives/externalities/Cargo.toml | 12 +- primitives/finality-grandpa/Cargo.toml | 16 +- primitives/finality-tracker/Cargo.toml | 12 +- primitives/inherents/Cargo.toml | 12 +- primitives/io/Cargo.toml | 22 +- primitives/keyring/Cargo.toml | 12 +- primitives/offchain/Cargo.toml | 12 +- primitives/panic-handler/Cargo.toml | 8 +- primitives/phragmen/Cargo.toml | 18 +- primitives/phragmen/compact/Cargo.toml | 8 +- primitives/rpc/Cargo.toml | 10 +- primitives/runtime-interface/Cargo.toml | 22 +- .../runtime-interface/proc-macro/Cargo.toml | 8 +- .../test-wasm-deprecated/Cargo.toml | 14 +- .../runtime-interface/test-wasm/Cargo.toml | 14 +- primitives/runtime-interface/test/Cargo.toml | 16 +- primitives/runtime/Cargo.toml | 20 +- primitives/sandbox/Cargo.toml | 16 +- primitives/serializer/Cargo.toml | 8 +- primitives/session/Cargo.toml | 16 +- primitives/staking/Cargo.toml | 12 +- primitives/state-machine/Cargo.toml | 18 +- primitives/std/Cargo.toml | 8 +- primitives/storage/Cargo.toml | 12 +- primitives/test-primitives/Cargo.toml | 12 +- primitives/timestamp/Cargo.toml | 16 +- primitives/transaction-pool/Cargo.toml | 14 +- primitives/trie/Cargo.toml | 14 +- primitives/utils/Cargo.toml | 2 +- primitives/version/Cargo.toml | 12 +- primitives/wasm-interface/Cargo.toml | 10 +- test-utils/Cargo.toml | 2 +- test-utils/client/Cargo.toml | 26 +- test-utils/runtime/Cargo.toml | 60 +- test-utils/runtime/client/Cargo.toml | 20 +- .../runtime/transaction-pool/Cargo.toml | 14 +- utils/browser/Cargo.toml | 16 +- utils/build-script-utils/Cargo.toml | 8 +- utils/fork-tree/Cargo.toml | 8 +- utils/frame/benchmarking-cli/Cargo.toml | 28 +- utils/frame/rpc/support/Cargo.toml | 16 +- utils/frame/rpc/system/Cargo.toml | 24 +- utils/prometheus/Cargo.toml | 8 +- utils/wasm-builder-runner/Cargo.toml | 4 +- utils/wasm-builder/Cargo.toml | 6 +- 177 files changed, 2288 insertions(+), 2252 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a696744bf2..c8e7de7761 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -440,7 +440,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "slab", ] @@ -580,7 +580,7 @@ dependencies = [ [[package]] name = "chain-spec-builder" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "ansi_term 0.12.1", "node-cli", @@ -742,7 +742,7 @@ dependencies = [ "gimli", "log", "serde", - "smallvec 1.2.0", + "smallvec 1.3.0", "target-lexicon", "thiserror", ] @@ -780,7 +780,7 @@ checksum = "518344698fa6c976d853319218415fdfb4f1bc6b42d0b2e2df652e55dff1f778" dependencies = [ "cranelift-codegen", "log", - "smallvec 1.2.0", + "smallvec 1.3.0", "target-lexicon", ] @@ -1140,18 +1140,18 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33121c8782ba948ba332dab29311b026a8716dc65a1599e5b88f392d38496af8" +checksum = "a80e524ebf194285b57e5e7944018721c7fffc673253f5183f7accd88a2a3b0c" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecf634c5213044b8d54a46dd282cf5dd1f86bb5cb53e92c409cb4680a7fb9894" +checksum = "2ed9afacaea0301eefb738c9deea725e6d53938004597cdc518a8cf9a7aa2f03" dependencies = [ "proc-macro2", "quote 1.0.3", @@ -1425,14 +1425,14 @@ checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" [[package]] name = "fork-tree" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "parity-scale-codec", ] [[package]] name = "frame-benchmarking" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -1448,7 +1448,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "parity-scale-codec", @@ -1466,7 +1466,7 @@ dependencies = [ [[package]] name = "frame-executive" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -1485,7 +1485,7 @@ dependencies = [ [[package]] name = "frame-metadata" -version = "11.0.0-alpha.5" +version = "11.0.0-alpha.6" dependencies = [ "parity-scale-codec", "serde", @@ -1495,7 +1495,7 @@ dependencies = [ [[package]] name = "frame-support" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "bitmask", "frame-metadata", @@ -1520,7 +1520,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support-procedural-tools", "proc-macro2", @@ -1530,7 +1530,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -1541,7 +1541,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "proc-macro2", "quote 1.0.3", @@ -1566,7 +1566,7 @@ dependencies = [ [[package]] name = "frame-system" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "criterion 0.2.11", "frame-support", @@ -1584,7 +1584,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "parity-scale-codec", "sp-api", @@ -1879,7 +1879,7 @@ dependencies = [ "byteorder 1.3.4", "fallible-iterator", "indexmap", - "smallvec 1.2.0", + "smallvec 1.3.0", "stable_deref_trait", ] @@ -1965,7 +1965,7 @@ dependencies = [ "indexmap", "log", "slab", - "tokio 0.2.16", + "tokio 0.2.18", "tokio-util", ] @@ -2177,7 +2177,7 @@ dependencies = [ "net2", "pin-project", "time", - "tokio 0.2.16", + "tokio 0.2.18", "tower-service", "want 0.3.0", ] @@ -2195,7 +2195,7 @@ dependencies = [ "log", "rustls", "rustls-native-certs", - "tokio 0.2.16", + "tokio 0.2.18", "tokio-rustls", "webpki", ] @@ -2350,9 +2350,9 @@ dependencies = [ [[package]] name = "jsonrpc-client-transports" -version = "14.0.5" +version = "14.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a9ae166c4d1f702d297cd76d4b55758ace80272ffc6dbb139fdc1bf810de40b" +checksum = "2307a7e78cf969759e390a8a2151ea12e783849a45bb00aa871b468ba58ea79e" dependencies = [ "failure", "futures 0.1.29", @@ -2367,9 +2367,9 @@ dependencies = [ [[package]] name = "jsonrpc-core" -version = "14.0.5" +version = "14.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3b688648f1ef5d5072229e2d672ecb92cbff7d1c79bcf3fd5898f3f3df0970" +checksum = "25525f6002338fb4debb5167a89a0b47f727a5a48418417545ad3429758b7fec" dependencies = [ "futures 0.1.29", "log", @@ -2380,9 +2380,9 @@ dependencies = [ [[package]] name = "jsonrpc-core-client" -version = "14.0.5" +version = "14.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080dc110be17701097df238fad3c816d4a478a1899dfbcf8ec8957dd40ec7304" +checksum = "87f9382e831a6d630c658df103aac3f971da096deb57c136ea2b760d3b4e3f9f" dependencies = [ "jsonrpc-client-transports", ] @@ -2401,36 +2401,36 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" -version = "14.0.6" +version = "14.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816d63997ea45d3634608edbef83ddb35e661f7c0b27b5b72f237e321f0e9807" +checksum = "d52860f0549694aa4abb12766856f56952ab46d3fb9f0815131b2db3d9cc2f29" dependencies = [ "hyper 0.12.35", "jsonrpc-core", "jsonrpc-server-utils", "log", "net2", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "unicase", ] [[package]] name = "jsonrpc-pubsub" -version = "14.0.6" +version = "14.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b31c9b90731276fdd24d896f31bb10aecf2e5151733364ae81123186643d939" +checksum = "c4ca5e391d6c6a2261d4adca029f427fe63ea546ad6cef2957c654c08495ec16" dependencies = [ "jsonrpc-core", "log", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "serde", ] [[package]] name = "jsonrpc-server-utils" -version = "14.0.5" +version = "14.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b7635e618a0edbbe0d2a2bbbc69874277c49383fcf6c3c0414491cfb517d22" +checksum = "1f06add502b48351e05dd95814835327fb115e4e9f834ca42fd522d3b769d4d2" dependencies = [ "bytes 0.4.12", "globset", @@ -2444,14 +2444,14 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" -version = "14.0.6" +version = "14.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94e5773b2ae66e0e02c80775ce6bbba6f15d5bb47c14ec36a36fcf94f8df851" +checksum = "017a7dd5083d9ed62c5e1dd3e317975c33c3115dac5447f4480fe05a8c354754" dependencies = [ "jsonrpc-core", "jsonrpc-server-utils", "log", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "slab", "ws", ] @@ -2499,7 +2499,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cad096c6849b2ef027fabe35c4aed356d0e3d3f586d0a8361e5e17f1e50a7ce5" dependencies = [ "parity-util-mem", - "smallvec 1.2.0", + "smallvec 1.3.0", ] [[package]] @@ -2510,7 +2510,7 @@ checksum = "4aa954d12cfac958822dfd77aab34f3eec71f103b918c4ab79ab59a36ee594ea" dependencies = [ "kvdb", "parity-util-mem", - "parking_lot 0.10.0", + "parking_lot 0.10.2", ] [[package]] @@ -2526,10 +2526,10 @@ dependencies = [ "num_cpus", "owning_ref", "parity-util-mem", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "regex", "rocksdb", - "smallvec 1.2.0", + "smallvec 1.3.0", ] [[package]] @@ -2569,9 +2569,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" [[package]] name = "libc" -version = "0.2.68" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" +checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" [[package]] name = "libflate" @@ -2633,9 +2633,9 @@ dependencies = [ "libp2p-yamux", "multihash", "parity-multiaddr 0.8.0", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "pin-project", - "smallvec 1.2.0", + "smallvec 1.3.0", "wasm-timer", ] @@ -2658,7 +2658,7 @@ dependencies = [ "multihash", "multistream-select", "parity-multiaddr 0.8.0", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "pin-project", "prost", "prost-build", @@ -2666,7 +2666,7 @@ dependencies = [ "ring", "rw-stream-sink", "sha2", - "smallvec 1.2.0", + "smallvec 1.3.0", "thiserror", "unsigned-varint", "void", @@ -2719,7 +2719,7 @@ dependencies = [ "prost", "prost-build", "rand 0.7.3", - "smallvec 1.2.0", + "smallvec 1.3.0", ] [[package]] @@ -2742,7 +2742,7 @@ dependencies = [ "prost-build", "rand 0.7.3", "sha2", - "smallvec 1.2.0", + "smallvec 1.3.0", "unsigned-varint", "wasm-timer", ] @@ -2759,7 +2759,7 @@ dependencies = [ "log", "prost", "prost-build", - "smallvec 1.2.0", + "smallvec 1.3.0", "wasm-timer", ] @@ -2783,7 +2783,7 @@ dependencies = [ "prost-build", "rand 0.7.3", "sha2", - "smallvec 1.2.0", + "smallvec 1.3.0", "uint", "unsigned-varint", "void", @@ -2807,7 +2807,7 @@ dependencies = [ "log", "net2", "rand 0.7.3", - "smallvec 1.2.0", + "smallvec 1.3.0", "void", "wasm-timer", ] @@ -2824,7 +2824,7 @@ dependencies = [ "futures_codec", "libp2p-core", "log", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "unsigned-varint", ] @@ -2936,7 +2936,7 @@ dependencies = [ "libp2p-core", "log", "rand 0.7.3", - "smallvec 1.2.0", + "smallvec 1.3.0", "void", "wasm-timer", ] @@ -3011,7 +3011,7 @@ checksum = "02f91aea50f6571e0bc6c058dc0e9b270afd41ec28dd94e9e4bf607e78b9ab87" dependencies = [ "futures 0.3.4", "libp2p-core", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "thiserror", "yamux", ] @@ -3093,9 +3093,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" dependencies = [ "scopeguard", ] @@ -3175,9 +3175,9 @@ dependencies = [ [[package]] name = "memory-db" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f58381b20ebe2c578e75dececd9da411414903415349548ccc46aac3209cdfbc" +checksum = "be512cb2ccb4ecbdca937fdd4a62ea5f09f8e7195466a85e4632b3d5bcce82e6" dependencies = [ "ahash", "hash-db", @@ -3303,7 +3303,7 @@ dependencies = [ "futures 0.3.4", "log", "pin-project", - "smallvec 1.2.0", + "smallvec 1.3.0", "unsigned-varint", ] @@ -3373,7 +3373,7 @@ dependencies = [ [[package]] name = "node-bench" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "log", "node-primitives", @@ -3388,7 +3388,7 @@ dependencies = [ [[package]] name = "node-cli" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "assert_cmd", "frame-benchmarking-cli", @@ -3461,7 +3461,7 @@ dependencies = [ [[package]] name = "node-executor" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "criterion 0.3.1", "frame-benchmarking", @@ -3495,7 +3495,7 @@ dependencies = [ [[package]] name = "node-inspect" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "derive_more", "log", @@ -3511,7 +3511,7 @@ dependencies = [ [[package]] name = "node-primitives" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "pretty_assertions", "sp-core", @@ -3521,7 +3521,7 @@ dependencies = [ [[package]] name = "node-rpc" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "jsonrpc-core", "node-primitives", @@ -3544,7 +3544,7 @@ dependencies = [ [[package]] name = "node-rpc-client" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "env_logger 0.7.1", "futures 0.1.29", @@ -3557,7 +3557,7 @@ dependencies = [ [[package]] name = "node-runtime" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "frame-executive", @@ -3621,7 +3621,7 @@ dependencies = [ [[package]] name = "node-template" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "futures 0.3.4", "log", @@ -3649,7 +3649,7 @@ dependencies = [ [[package]] name = "node-template-runtime" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-executive", "frame-support", @@ -3681,7 +3681,7 @@ dependencies = [ [[package]] name = "node-testing" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "criterion 0.3.1", "frame-support", @@ -3727,7 +3727,7 @@ dependencies = [ [[package]] name = "node-transaction-factory" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "log", "parity-scale-codec", @@ -3918,7 +3918,7 @@ dependencies = [ [[package]] name = "pallet-assets" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -3932,7 +3932,7 @@ dependencies = [ [[package]] name = "pallet-aura" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -3940,7 +3940,7 @@ dependencies = [ "pallet-session", "pallet-timestamp", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "serde", "sp-application-crypto", "sp-consensus-aura", @@ -3954,7 +3954,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -3972,7 +3972,7 @@ dependencies = [ [[package]] name = "pallet-authorship" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -3988,7 +3988,7 @@ dependencies = [ [[package]] name = "pallet-babe" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4009,7 +4009,7 @@ dependencies = [ [[package]] name = "pallet-balances" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4025,7 +4025,7 @@ dependencies = [ [[package]] name = "pallet-benchmark" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4039,7 +4039,7 @@ dependencies = [ [[package]] name = "pallet-collective" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4056,7 +4056,7 @@ dependencies = [ [[package]] name = "pallet-contracts" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "assert_matches", "frame-support", @@ -4081,7 +4081,7 @@ dependencies = [ [[package]] name = "pallet-contracts-primitives" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -4090,7 +4090,7 @@ dependencies = [ [[package]] name = "pallet-contracts-rpc" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4109,7 +4109,7 @@ dependencies = [ [[package]] name = "pallet-contracts-rpc-runtime-api" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "pallet-contracts-primitives", "parity-scale-codec", @@ -4120,7 +4120,7 @@ dependencies = [ [[package]] name = "pallet-democracy" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4139,7 +4139,7 @@ dependencies = [ [[package]] name = "pallet-elections" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4155,7 +4155,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4174,7 +4174,7 @@ dependencies = [ [[package]] name = "pallet-evm" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "evm", "frame-support", @@ -4194,7 +4194,7 @@ dependencies = [ [[package]] name = "pallet-example" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4210,7 +4210,7 @@ dependencies = [ [[package]] name = "pallet-example-offchain-worker" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4225,7 +4225,7 @@ dependencies = [ [[package]] name = "pallet-finality-tracker" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4242,7 +4242,7 @@ dependencies = [ [[package]] name = "pallet-generic-asset" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4256,7 +4256,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4274,7 +4274,7 @@ dependencies = [ [[package]] name = "pallet-identity" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "enumflags2", "frame-benchmarking", @@ -4291,7 +4291,7 @@ dependencies = [ [[package]] name = "pallet-im-online" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4310,7 +4310,7 @@ dependencies = [ [[package]] name = "pallet-indices" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4326,7 +4326,7 @@ dependencies = [ [[package]] name = "pallet-membership" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4340,7 +4340,7 @@ dependencies = [ [[package]] name = "pallet-nicks" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4355,7 +4355,7 @@ dependencies = [ [[package]] name = "pallet-offences" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4371,7 +4371,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4389,7 +4389,7 @@ dependencies = [ [[package]] name = "pallet-randomness-collective-flip" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4403,7 +4403,7 @@ dependencies = [ [[package]] name = "pallet-recovery" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "enumflags2", "frame-support", @@ -4419,7 +4419,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4434,7 +4434,7 @@ dependencies = [ [[package]] name = "pallet-scored-pool" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4449,7 +4449,7 @@ dependencies = [ [[package]] name = "pallet-session" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4469,7 +4469,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4489,7 +4489,7 @@ dependencies = [ [[package]] name = "pallet-society" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4505,7 +4505,7 @@ dependencies = [ [[package]] name = "pallet-staking" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "env_logger 0.7.1", "frame-benchmarking", @@ -4519,7 +4519,7 @@ dependencies = [ "pallet-staking-reward-curve", "pallet-timestamp", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "rand 0.7.3", "rand_chacha 0.2.2", "serde", @@ -4537,7 +4537,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -4548,7 +4548,7 @@ dependencies = [ [[package]] name = "pallet-sudo" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4562,7 +4562,7 @@ dependencies = [ [[package]] name = "pallet-template" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4574,7 +4574,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4592,7 +4592,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -4607,7 +4607,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4624,7 +4624,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "parity-scale-codec", @@ -4637,7 +4637,7 @@ dependencies = [ [[package]] name = "pallet-treasury" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4653,7 +4653,7 @@ dependencies = [ [[package]] name = "pallet-utility" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4669,7 +4669,7 @@ dependencies = [ [[package]] name = "pallet-vesting" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "enumflags2", "frame-benchmarking", @@ -4780,9 +4780,9 @@ dependencies = [ "impl-trait-for-tuples", "lru", "parity-util-mem-derive", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "primitive-types", - "smallvec 1.2.0", + "smallvec 1.3.0", "winapi 0.3.8", ] @@ -4825,12 +4825,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" +checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" dependencies = [ "lock_api", - "parking_lot_core 0.7.0", + "parking_lot_core 0.7.1", ] [[package]] @@ -4850,15 +4850,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" +checksum = "0e136c1904604defe99ce5fd71a28d473fa60a12255d511aa78a9ddf11237aeb" dependencies = [ "cfg-if", "cloudabi", "libc", "redox_syscall", - "smallvec 1.2.0", + "smallvec 1.3.0", "winapi 0.3.8", ] @@ -5058,9 +5058,9 @@ dependencies = [ [[package]] name = "proc-macro-error" -version = "0.4.12" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7" +checksum = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678" dependencies = [ "proc-macro-error-attr", "proc-macro2", @@ -5071,9 +5071,9 @@ dependencies = [ [[package]] name = "proc-macro-error-attr" -version = "0.4.12" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de" +checksum = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53" dependencies = [ "proc-macro2", "quote 1.0.3", @@ -5185,9 +5185,9 @@ dependencies = [ [[package]] name = "protobuf" -version = "2.12.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71964f34fd51cf04882d7ae3325fa0794d4cad66a03d0003f38d8ae4f63ba126" +checksum = "8e86d370532557ae7573551a1ec8235a0f8d6cb276c7c9e6aa490b511c447485" [[package]] name = "pwasm-utils" @@ -5741,7 +5741,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "bytes 0.5.4", "derive_more", @@ -5771,13 +5771,13 @@ dependencies = [ [[package]] name = "sc-basic-authorship" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", "log", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sc-block-builder", "sc-client-api", "sc-telemetry", @@ -5795,7 +5795,7 @@ dependencies = [ [[package]] name = "sc-block-builder" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -5812,7 +5812,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "impl-trait-for-tuples", "sc-chain-spec-derive", @@ -5827,7 +5827,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5837,7 +5837,7 @@ dependencies = [ [[package]] name = "sc-cli" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "ansi_term 0.12.1", "app_dirs", @@ -5874,12 +5874,12 @@ dependencies = [ "substrate-prometheus-endpoint", "tempfile", "time", - "tokio 0.2.16", + "tokio 0.2.18", ] [[package]] name = "sc-client" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "derive_more", "env_logger 0.7.1", @@ -5891,7 +5891,7 @@ dependencies = [ "kvdb-memorydb", "log", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sc-block-builder", "sc-client-api", "sc-executor", @@ -5918,7 +5918,7 @@ dependencies = [ [[package]] name = "sc-client-api" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "derive_more", "fnv", @@ -5929,7 +5929,7 @@ dependencies = [ "lazy_static", "log", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sc-executor", "sc-telemetry", "sp-api", @@ -5952,7 +5952,7 @@ dependencies = [ [[package]] name = "sc-client-db" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "env_logger 0.7.1", "hash-db", @@ -5963,7 +5963,7 @@ dependencies = [ "log", "parity-scale-codec", "parity-util-mem", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "quickcheck", "sc-client", "sc-client-api", @@ -5983,7 +5983,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "derive_more", "env_logger 0.7.1", @@ -5991,7 +5991,7 @@ dependencies = [ "futures-timer 3.0.2", "log", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sc-block-builder", "sc-client", "sc-client-api", @@ -6021,7 +6021,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "derive_more", "env_logger 0.7.1", @@ -6034,7 +6034,7 @@ dependencies = [ "num-rational", "num-traits 0.2.11", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "pdqselect", "rand 0.7.3", "sc-block-builder", @@ -6071,7 +6071,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "derive_more", "futures 0.3.4", @@ -6096,11 +6096,11 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "fork-tree", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sc-client-api", "sp-blockchain", "sp-runtime", @@ -6108,7 +6108,7 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "assert_matches", "derive_more", @@ -6118,7 +6118,7 @@ dependencies = [ "jsonrpc-core-client", "jsonrpc-derive", "log", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sc-basic-authorship", "sc-client", "sc-client-api", @@ -6132,12 +6132,12 @@ dependencies = [ "substrate-test-runtime-client", "substrate-test-runtime-transaction-pool", "tempfile", - "tokio 0.2.16", + "tokio 0.2.18", ] [[package]] name = "sc-consensus-pow" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "derive_more", "futures 0.3.4", @@ -6157,13 +6157,13 @@ dependencies = [ [[package]] name = "sc-consensus-slots" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", "log", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sc-client-api", "sc-telemetry", "sp-api", @@ -6178,7 +6178,7 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "log", "sc-client-api", @@ -6191,7 +6191,7 @@ dependencies = [ [[package]] name = "sc-executor" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "assert_matches", "derive_more", @@ -6201,7 +6201,7 @@ dependencies = [ "log", "parity-scale-codec", "parity-wasm 0.41.0", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sc-executor-common", "sc-executor-wasmi", "sc-executor-wasmtime", @@ -6225,7 +6225,7 @@ dependencies = [ [[package]] name = "sc-executor-common" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "derive_more", "log", @@ -6241,7 +6241,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "log", "parity-scale-codec", @@ -6255,7 +6255,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "assert_matches", "cranelift-codegen", @@ -6276,7 +6276,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "assert_matches", "env_logger 0.7.1", @@ -6286,7 +6286,7 @@ dependencies = [ "futures-timer 3.0.2", "log", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "pin-project", "rand 0.7.3", "sc-block-builder", @@ -6314,12 +6314,12 @@ dependencies = [ "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", - "tokio 0.2.16", + "tokio 0.2.18", ] [[package]] name = "sc-informant" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "ansi_term 0.12.1", "futures 0.3.4", @@ -6335,11 +6335,11 @@ dependencies = [ [[package]] name = "sc-keystore" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "derive_more", "hex", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "rand 0.7.3", "serde_json", "sp-application-crypto", @@ -6350,7 +6350,7 @@ dependencies = [ [[package]] name = "sc-network" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "assert_matches", "async-std", @@ -6373,7 +6373,7 @@ dependencies = [ "lru", "nohash-hasher", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "pin-project", "prost", "prost-build", @@ -6410,7 +6410,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", @@ -6433,7 +6433,7 @@ dependencies = [ "futures-timer 3.0.2", "libp2p", "log", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "rand 0.7.3", "sc-block-builder", "sc-client", @@ -6451,7 +6451,7 @@ dependencies = [ [[package]] name = "sc-offchain" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "bytes 0.5.4", "env_logger 0.7.1", @@ -6464,7 +6464,7 @@ dependencies = [ "log", "num_cpus", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "rand 0.7.3", "sc-client-api", "sc-client-db", @@ -6479,12 +6479,12 @@ dependencies = [ "sp-utils", "substrate-test-runtime-client", "threadpool", - "tokio 0.2.16", + "tokio 0.2.18", ] [[package]] name = "sc-peerset" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "futures 0.3.4", "libp2p", @@ -6497,7 +6497,7 @@ dependencies = [ [[package]] name = "sc-rpc" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "assert_matches", "futures 0.1.29", @@ -6507,7 +6507,7 @@ dependencies = [ "jsonrpc-pubsub", "log", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sc-block-builder", "sc-client", "sc-client-api", @@ -6536,7 +6536,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "derive_more", "futures 0.3.4", @@ -6546,7 +6546,7 @@ dependencies = [ "jsonrpc-pubsub", "log", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "serde", "serde_json", "sp-chain-spec", @@ -6559,7 +6559,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "jsonrpc-core", "jsonrpc-http-server", @@ -6586,7 +6586,7 @@ dependencies = [ [[package]] name = "sc-service" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "derive_more", "exit-future", @@ -6600,7 +6600,7 @@ dependencies = [ "parity-multiaddr 0.7.3", "parity-scale-codec", "parity-util-mem", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "procfs", "sc-chain-spec", "sc-client", @@ -6660,28 +6660,28 @@ dependencies = [ [[package]] name = "sc-state-db" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "env_logger 0.7.1", "log", "parity-scale-codec", "parity-util-mem", "parity-util-mem-derive", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sc-client-api", "sp-core", ] [[package]] name = "sc-telemetry" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "bytes 0.5.4", "futures 0.3.4", "futures-timer 3.0.2", "libp2p", "log", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "pin-project", "rand 0.7.3", "serde", @@ -6695,11 +6695,11 @@ dependencies = [ [[package]] name = "sc-tracing" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "erased-serde", "log", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sc-telemetry", "serde", "serde_json", @@ -6710,7 +6710,7 @@ dependencies = [ [[package]] name = "sc-transaction-graph" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "assert_matches", "criterion 0.3.1", @@ -6720,7 +6720,7 @@ dependencies = [ "log", "parity-scale-codec", "parity-util-mem", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "serde", "sp-blockchain", "sp-core", @@ -6733,7 +6733,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "assert_matches", "derive_more", @@ -6744,7 +6744,7 @@ dependencies = [ "log", "parity-scale-codec", "parity-util-mem", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sc-client-api", "sc-transaction-graph", "sp-api", @@ -7056,9 +7056,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" +checksum = "05720e22615919e4734f6a99ceae50d00226c3c5aca406e102ebc33298214e0a" [[package]] name = "snow" @@ -7093,14 +7093,14 @@ dependencies = [ "log", "rand 0.7.3", "sha1", - "smallvec 1.2.0", + "smallvec 1.3.0", "static_assertions", "thiserror", ] [[package]] name = "sp-allocator" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "derive_more", "log", @@ -7111,7 +7111,7 @@ dependencies = [ [[package]] name = "sp-api" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "hash-db", "parity-scale-codec", @@ -7126,7 +7126,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "blake2-rfc", "proc-macro-crate", @@ -7156,7 +7156,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "parity-scale-codec", "serde", @@ -7178,7 +7178,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "criterion 0.3.1", "integer-sqrt", @@ -7194,7 +7194,7 @@ dependencies = [ [[package]] name = "sp-arithmetic-fuzzer" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "honggfuzz", "num-bigint", @@ -7205,7 +7205,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "parity-scale-codec", "sp-api", @@ -7216,7 +7216,7 @@ dependencies = [ [[package]] name = "sp-authorship" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -7226,7 +7226,7 @@ dependencies = [ [[package]] name = "sp-block-builder" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "parity-scale-codec", "sp-api", @@ -7237,13 +7237,13 @@ dependencies = [ [[package]] name = "sp-blockchain" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "derive_more", "log", "lru", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sp-block-builder", "sp-consensus", "sp-runtime", @@ -7252,7 +7252,7 @@ dependencies = [ [[package]] name = "sp-chain-spec" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "serde", "serde_json", @@ -7260,7 +7260,7 @@ dependencies = [ [[package]] name = "sp-consensus" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "derive_more", "futures 0.3.4", @@ -7269,7 +7269,7 @@ dependencies = [ "libp2p", "log", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "serde", "sp-core", "sp-inherents", @@ -7283,7 +7283,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "parity-scale-codec", "sp-api", @@ -7296,7 +7296,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "parity-scale-codec", "sp-api", @@ -7311,7 +7311,7 @@ dependencies = [ [[package]] name = "sp-consensus-pow" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "parity-scale-codec", "sp-api", @@ -7322,7 +7322,7 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "parity-scale-codec", "schnorrkel", @@ -7333,7 +7333,7 @@ dependencies = [ [[package]] name = "sp-core" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "base58", "blake2-rfc", @@ -7352,7 +7352,7 @@ dependencies = [ "num-traits 0.2.11", "parity-scale-codec", "parity-util-mem", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "pretty_assertions", "primitive-types", "rand 0.7.3", @@ -7377,7 +7377,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "proc-macro2", "quote 1.0.3", @@ -7386,7 +7386,7 @@ dependencies = [ [[package]] name = "sp-externalities" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "environmental", "sp-std", @@ -7395,7 +7395,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "parity-scale-codec", "serde", @@ -7407,7 +7407,7 @@ dependencies = [ [[package]] name = "sp-finality-tracker" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -7416,18 +7416,18 @@ dependencies = [ [[package]] name = "sp-inherents" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "derive_more", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sp-core", "sp-std", ] [[package]] name = "sp-io" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "hash-db", "libsecp256k1", @@ -7444,7 +7444,7 @@ dependencies = [ [[package]] name = "sp-keyring" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "lazy_static", "sp-core", @@ -7454,7 +7454,7 @@ dependencies = [ [[package]] name = "sp-offchain" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "sp-api", "sp-runtime", @@ -7462,7 +7462,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "backtrace", "log", @@ -7470,7 +7470,7 @@ dependencies = [ [[package]] name = "sp-phragmen" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "parity-scale-codec", "rand 0.7.3", @@ -7484,7 +7484,7 @@ dependencies = [ [[package]] name = "sp-phragmen-compact" -version = "2.0.0-dev" +version = "2.0.0-dev.1" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -7494,7 +7494,7 @@ dependencies = [ [[package]] name = "sp-rpc" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "serde", "serde_json", @@ -7503,7 +7503,7 @@ dependencies = [ [[package]] name = "sp-runtime" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "hash256-std-hasher", "impl-trait-for-tuples", @@ -7524,7 +7524,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "parity-scale-codec", "primitive-types", @@ -7543,7 +7543,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "Inflector", "proc-macro-crate", @@ -7589,7 +7589,7 @@ dependencies = [ [[package]] name = "sp-sandbox" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "assert_matches", "parity-scale-codec", @@ -7603,7 +7603,7 @@ dependencies = [ [[package]] name = "sp-serializer" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "serde", "serde_json", @@ -7611,7 +7611,7 @@ dependencies = [ [[package]] name = "sp-session" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "sp-api", "sp-core", @@ -7621,7 +7621,7 @@ dependencies = [ [[package]] name = "sp-staking" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -7630,14 +7630,14 @@ dependencies = [ [[package]] name = "sp-state-machine" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "hash-db", "hex-literal", "log", "num-traits 0.2.11", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "rand 0.7.3", "sp-core", "sp-externalities", @@ -7650,11 +7650,11 @@ dependencies = [ [[package]] name = "sp-std" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" [[package]] name = "sp-storage" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "impl-serde 0.2.3", "serde", @@ -7676,7 +7676,7 @@ dependencies = [ [[package]] name = "sp-timestamp" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -7689,7 +7689,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "derive_more", "futures 0.3.4", @@ -7703,7 +7703,7 @@ dependencies = [ [[package]] name = "sp-trie" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "criterion 0.2.11", "hash-db", @@ -7721,7 +7721,7 @@ dependencies = [ [[package]] name = "sp-utils" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "futures 0.3.4", "futures-core", @@ -7731,7 +7731,7 @@ dependencies = [ [[package]] name = "sp-version" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "impl-serde 0.2.3", "parity-scale-codec", @@ -7742,7 +7742,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -7812,9 +7812,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8faa2719539bbe9d77869bfb15d4ee769f99525e707931452c97b693b3f159d" +checksum = "ff6da2e8d107dfd7b74df5ef4d205c6aebee0706c647f6bc6a2d5789905c00fb" dependencies = [ "clap", "lazy_static", @@ -7823,9 +7823,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f88b8e18c69496aad6f9ddf4630dd7d585bcaf765786cb415b9aec2fe5a0430" +checksum = "a489c87c08fbaf12e386665109dd13470dcc9c4583ea3e10dd2b4523e5ebd9ac" dependencies = [ "heck", "proc-macro-error", @@ -7857,7 +7857,7 @@ dependencies = [ [[package]] name = "subkey" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "clap", "derive_more", @@ -7898,7 +7898,7 @@ dependencies = [ [[package]] name = "substrate-browser-utils" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "chrono", "clear_on_drop", @@ -7923,14 +7923,14 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "platforms", ] [[package]] name = "substrate-frame-rpc-support" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "frame-support", "frame-system", @@ -7941,12 +7941,12 @@ dependencies = [ "sc-rpc-api", "serde", "sp-storage", - "tokio 0.2.16", + "tokio 0.2.18", ] [[package]] name = "substrate-frame-rpc-system" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" dependencies = [ "env_logger 0.7.1", "frame-system-rpc-runtime-api", @@ -7969,7 +7969,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" dependencies = [ "async-std", "derive_more", @@ -7977,7 +7977,7 @@ dependencies = [ "hyper 0.13.4", "log", "prometheus", - "tokio 0.2.16", + "tokio 0.2.18", ] [[package]] @@ -8065,7 +8065,7 @@ dependencies = [ "derive_more", "futures 0.3.4", "parity-scale-codec", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "sc-transaction-graph", "sp-blockchain", "sp-runtime", @@ -8075,7 +8075,7 @@ dependencies = [ [[package]] name = "substrate-test-utils" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" [[package]] name = "substrate-wasm-builder" @@ -8305,18 +8305,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0570dc61221295909abdb95c739f2e74325e14293b2026b0a7e195091ec54ae" +checksum = "54b3d3d2ff68104100ab257bb6bb0cb26c901abe4bd4ba15961f3bf867924012" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "227362df41d566be41a28f64401e07a043157c21c14b9785a0d8e256f940a8fd" +checksum = "ca972988113b7715266f91250ddb98070d033c62a011fa0fcc57434a649310dd" dependencies = [ "proc-macro2", "quote 1.0.3", @@ -8422,9 +8422,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee5a0dd887e37d37390c13ff8ac830f992307fe30a1fff0ab8427af67211ba28" +checksum = "34ef16d072d2b6dc8b4a56c70f5c5ced1a37752116f8e7c1e80c659aa7cb6713" dependencies = [ "bytes 0.5.4", "fnv", @@ -8556,7 +8556,7 @@ checksum = "4adb8b3e5f86b707f1b54e7c15b6de52617a823608ccda98a15d3a24222f265a" dependencies = [ "futures-core", "rustls", - "tokio 0.2.16", + "tokio 0.2.18", "webpki", ] @@ -8668,7 +8668,7 @@ dependencies = [ "futures-sink", "log", "pin-project-lite", - "tokio 0.2.16", + "tokio 0.2.18", ] [[package]] @@ -8724,9 +8724,9 @@ checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" [[package]] name = "trie-bench" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f105ed33e42b534284b691e804e909c42a8898afcf22896a32255c05a1a50488" +checksum = "c48b309cdda1abbdada28424bdc46f8b85362b3e66d6786d91223e83874429c7" dependencies = [ "criterion 0.2.11", "hash-db", @@ -8748,7 +8748,7 @@ dependencies = [ "hashbrown", "log", "rustc-hex", - "smallvec 1.2.0", + "smallvec 1.3.0", ] [[package]] @@ -8778,9 +8778,9 @@ checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" [[package]] name = "trybuild" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b4e093c5ed1a60b22557090120aa14f90ca801549c0949d775ea07c1407720" +checksum = "459186ab1afd6d93bd23c2269125f4f7694f8771fe0e64434b4bdc212b94034d" dependencies = [ "glob 0.3.0", "lazy_static", @@ -8812,9 +8812,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.11.2" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" [[package]] name = "uint" @@ -8852,7 +8852,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" dependencies = [ - "smallvec 1.2.0", + "smallvec 1.3.0", ] [[package]] @@ -8881,9 +8881,9 @@ checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" [[package]] name = "unsigned-varint" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38e01ad4b98f042e166c1bf9a13f9873a99d79eaa171ce7ca81e6dd0f895d8a" +checksum = "f67332660eb59a6f1eb24ff1220c9e8d01738a8503c6002e30bcfe4bd9f2b4a9" dependencies = [ "bytes 0.5.4", "futures-io", @@ -9365,7 +9365,7 @@ dependencies = [ "futures 0.3.4", "log", "nohash-hasher", - "parking_lot 0.10.0", + "parking_lot 0.10.2", "rand 0.7.3", "static_assertions", ] diff --git a/bin/node-template/node/Cargo.toml b/bin/node-template/node/Cargo.toml index a2ccc4fa95..d8ce4b590b 100644 --- a/bin/node-template/node/Cargo.toml +++ b/bin/node-template/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-template" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Anonymous"] description = "Substrate Node template" edition = "2018" @@ -9,6 +9,9 @@ build = "build.rs" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [[bin]] name = "node-template" @@ -17,28 +20,25 @@ futures = "0.3.4" log = "0.4.8" structopt = "0.3.8" -sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sc-executor = { version = "0.8.0-alpha.5", path = "../../../client/executor" } -sc-service = { version = "0.8.0-alpha.5", path = "../../../client/service" } -sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } -sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../client/transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } -sc-network = { version = "0.8.0-alpha.5", path = "../../../client/network" } -sc-consensus-aura = { version = "0.8.0-alpha.5", path = "../../../client/consensus/aura" } -sp-consensus-aura = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/aura" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } -sc-finality-grandpa = { version = "0.8.0-alpha.5", path = "../../../client/finality-grandpa" } -sp-finality-grandpa = { version = "2.0.0-alpha.5", path = "../../../primitives/finality-grandpa" } -sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sc-basic-authorship = { path = "../../../client/basic-authorship", version = "0.8.0-alpha.5"} +sc-cli = { version = "0.8.0-alpha.6", path = "../../../client/cli" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sc-executor = { version = "0.8.0-alpha.6", path = "../../../client/executor" } +sc-service = { version = "0.8.0-alpha.6", path = "../../../client/service" } +sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } +sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../primitives/transaction-pool" } +sc-network = { version = "0.8.0-alpha.6", path = "../../../client/network" } +sc-consensus-aura = { version = "0.8.0-alpha.6", path = "../../../client/consensus/aura" } +sp-consensus-aura = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/aura" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } +sc-finality-grandpa = { version = "0.8.0-alpha.6", path = "../../../client/finality-grandpa" } +sp-finality-grandpa = { version = "2.0.0-alpha.6", path = "../../../primitives/finality-grandpa" } +sc-client = { version = "0.8.0-alpha.6", path = "../../../client/" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sc-basic-authorship = { path = "../../../client/basic-authorship", version = "0.8.0-alpha.6"} -node-template-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } +node-template-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } [build-dependencies] -substrate-build-script-utils = { version = "2.0.0-alpha.5", path = "../../../utils/build-script-utils" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +substrate-build-script-utils = { version = "2.0.0-alpha.6", path = "../../../utils/build-script-utils" } diff --git a/bin/node-template/pallets/template/Cargo.toml b/bin/node-template/pallets/template/Cargo.toml index 69fcd84352..4a2c5ccad1 100644 --- a/bin/node-template/pallets/template/Cargo.toml +++ b/bin/node-template/pallets/template/Cargo.toml @@ -2,37 +2,40 @@ authors = ['Anonymous'] edition = '2018' name = 'pallet-template' -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" license = "Unlicense" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet template" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } [dependencies.frame-support] default-features = false -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" path = "../../../../frame/support" [dependencies.frame-system] default-features = false -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" path = "../../../../frame/system" [dev-dependencies.sp-core] default-features = false -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" path = "../../../../primitives/core" [dev-dependencies.sp-io] default-features = false -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" path = "../../../../primitives/io" [dev-dependencies.sp-runtime] default-features = false -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" path = "../../../../primitives/runtime" @@ -43,6 +46,3 @@ std = [ 'frame-support/std', 'frame-system/std' ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node-template/runtime/Cargo.toml b/bin/node-template/runtime/Cargo.toml index e8653e6df7..4f6f528f05 100644 --- a/bin/node-template/runtime/Cargo.toml +++ b/bin/node-template/runtime/Cargo.toml @@ -1,40 +1,43 @@ [package] name = "node-template-runtime" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Anonymous"] edition = "2018" license = "Unlicense" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -aura = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-aura", path = "../../../frame/aura" } -balances = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-balances", path = "../../../frame/balances" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/support" } -grandpa = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-grandpa", path = "../../../frame/grandpa" } -randomness-collective-flip = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-randomness-collective-flip", path = "../../../frame/randomness-collective-flip" } -sudo = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-sudo", path = "../../../frame/sudo" } -system = { version = "2.0.0-alpha.5", default-features = false, package = "frame-system", path = "../../../frame/system" } -timestamp = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-timestamp", path = "../../../frame/timestamp" } -transaction-payment = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-transaction-payment", path = "../../../frame/transaction-payment" } -frame-executive = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/executive" } +aura = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-aura", path = "../../../frame/aura" } +balances = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-balances", path = "../../../frame/balances" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/support" } +grandpa = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-grandpa", path = "../../../frame/grandpa" } +randomness-collective-flip = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-randomness-collective-flip", path = "../../../frame/randomness-collective-flip" } +sudo = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-sudo", path = "../../../frame/sudo" } +system = { version = "2.0.0-alpha.6", default-features = false, package = "frame-system", path = "../../../frame/system" } +timestamp = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-timestamp", path = "../../../frame/timestamp" } +transaction-payment = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-transaction-payment", path = "../../../frame/transaction-payment" } +frame-executive = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/executive" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/api" } -sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.5"} -sp-consensus-aura = { version = "0.8.0-alpha.5", default-features = false, path = "../../../primitives/consensus/aura" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/core" } -sp-inherents = { path = "../../../primitives/inherents", default-features = false, version = "2.0.0-alpha.5"} -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/io" } -sp-offchain = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/offchain" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } -sp-session = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/session" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" } -sp-transaction-pool = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/transaction-pool" } -sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/version" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/api" } +sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.6"} +sp-consensus-aura = { version = "0.8.0-alpha.6", default-features = false, path = "../../../primitives/consensus/aura" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/core" } +sp-inherents = { path = "../../../primitives/inherents", default-features = false, version = "2.0.0-alpha.6"} +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/io" } +sp-offchain = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/offchain" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } +sp-session = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/session" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/std" } +sp-transaction-pool = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/transaction-pool" } +sp-version = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/version" } -template = { version = "2.0.0-alpha.5", default-features = false, path = "../pallets/template", package = "pallet-template" } +template = { version = "2.0.0-alpha.6", default-features = false, path = "../pallets/template", package = "pallet-template" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } @@ -68,6 +71,3 @@ std = [ "transaction-payment/std", "template/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/bench/Cargo.toml b/bin/node/bench/Cargo.toml index 22e7fe51d8..c07c75e2cf 100644 --- a/bin/node/bench/Cargo.toml +++ b/bin/node/bench/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-bench" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Substrate node integration benchmarks." edition = "2018" @@ -10,11 +10,11 @@ license = "GPL-3.0" [dependencies] log = "0.4.8" -node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } -node-testing = { version = "2.0.0-alpha.5", path = "../testing" } -sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api/" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +node-primitives = { version = "2.0.0-alpha.6", path = "../primitives" } +node-testing = { version = "2.0.0-alpha.6", path = "../testing" } +sc-cli = { version = "0.8.0-alpha.6", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api/" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } serde = "1.0.101" serde_json = "1.0.41" -structopt = "0.3" \ No newline at end of file +structopt = "0.3" diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index 4643df6072..f0cbbcbe97 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-cli" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] description = "Generic Substrate node implementation in Rust." build = "build.rs" @@ -15,6 +15,9 @@ repository = "https://github.com/paritytech/substrate/" # https://github.com/rustwasm/wasm-pack/issues/781 etc. wasm-opt = false +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [badges] travis-ci = { repository = "paritytech/substrate" } maintenance = { status = "actively-developed" } @@ -42,74 +45,74 @@ structopt = { version = "0.3.8", optional = true } tracing = "0.1.10" # primitives -sp-authority-discovery = { version = "2.0.0-alpha.5", path = "../../../primitives/authority-discovery" } -sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/babe" } -grandpa-primitives = { version = "2.0.0-alpha.5", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/timestamp" } -sp-finality-tracker = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/finality-tracker" } -sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.5", path = "../../../primitives/keyring" } -sp-io = { version = "2.0.0-alpha.5", path = "../../../primitives/io" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } +sp-authority-discovery = { version = "2.0.0-alpha.6", path = "../../../primitives/authority-discovery" } +sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/babe" } +grandpa-primitives = { version = "2.0.0-alpha.6", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/timestamp" } +sp-finality-tracker = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/finality-tracker" } +sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } +sp-keyring = { version = "2.0.0-alpha.6", path = "../../../primitives/keyring" } +sp-io = { version = "2.0.0-alpha.6", path = "../../../primitives/io" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../primitives/transaction-pool" } # client dependencies -sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } -sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } -sc-chain-spec = { version = "2.0.0-alpha.5", path = "../../../client/chain-spec" } -sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../client/transaction-pool" } -sc-network = { version = "0.8.0-alpha.5", path = "../../../client/network" } -sc-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../client/consensus/babe" } -grandpa = { version = "0.8.0-alpha.5", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } -sc-client-db = { version = "0.8.0-alpha.5", default-features = false, path = "../../../client/db" } -sc-offchain = { version = "2.0.0-alpha.5", path = "../../../client/offchain" } -sc-rpc = { version = "2.0.0-alpha.5", path = "../../../client/rpc" } -sc-basic-authorship = { version = "0.8.0-alpha.5", path = "../../../client/basic-authorship" } -sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../../../client/service" } -sc-tracing = { version = "2.0.0-alpha.5", path = "../../../client/tracing" } -sc-telemetry = { version = "2.0.0-alpha.5", path = "../../../client/telemetry" } -sc-authority-discovery = { version = "0.8.0-alpha.5", path = "../../../client/authority-discovery" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api" } +sc-client = { version = "0.8.0-alpha.6", path = "../../../client/" } +sc-chain-spec = { version = "2.0.0-alpha.6", path = "../../../client/chain-spec" } +sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../client/transaction-pool" } +sc-network = { version = "0.8.0-alpha.6", path = "../../../client/network" } +sc-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../client/consensus/babe" } +grandpa = { version = "0.8.0-alpha.6", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } +sc-client-db = { version = "0.8.0-alpha.6", default-features = false, path = "../../../client/db" } +sc-offchain = { version = "2.0.0-alpha.6", path = "../../../client/offchain" } +sc-rpc = { version = "2.0.0-alpha.6", path = "../../../client/rpc" } +sc-basic-authorship = { version = "0.8.0-alpha.6", path = "../../../client/basic-authorship" } +sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../../../client/service" } +sc-tracing = { version = "2.0.0-alpha.6", path = "../../../client/tracing" } +sc-telemetry = { version = "2.0.0-alpha.6", path = "../../../client/telemetry" } +sc-authority-discovery = { version = "0.8.0-alpha.6", path = "../../../client/authority-discovery" } # frame dependencies -pallet-indices = { version = "2.0.0-alpha.5", path = "../../../frame/indices" } -pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/timestamp" } -pallet-contracts = { version = "2.0.0-alpha.5", path = "../../../frame/contracts" } -frame-system = { version = "2.0.0-alpha.5", path = "../../../frame/system" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../../../frame/balances" } -pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../../../frame/transaction-payment" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/support" } -pallet-im-online = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/im-online" } -pallet-authority-discovery = { version = "2.0.0-alpha.5", path = "../../../frame/authority-discovery" } -pallet-staking = { version = "2.0.0-alpha.5", path = "../../../frame/staking" } +pallet-indices = { version = "2.0.0-alpha.6", path = "../../../frame/indices" } +pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/timestamp" } +pallet-contracts = { version = "2.0.0-alpha.6", path = "../../../frame/contracts" } +frame-system = { version = "2.0.0-alpha.6", path = "../../../frame/system" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../../../frame/balances" } +pallet-transaction-payment = { version = "2.0.0-alpha.6", path = "../../../frame/transaction-payment" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/support" } +pallet-im-online = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/im-online" } +pallet-authority-discovery = { version = "2.0.0-alpha.6", path = "../../../frame/authority-discovery" } +pallet-staking = { version = "2.0.0-alpha.6", path = "../../../frame/staking" } # node-specific dependencies -node-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } -node-rpc = { version = "2.0.0-alpha.5", path = "../rpc" } -node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } -node-executor = { version = "2.0.0-alpha.5", path = "../executor" } +node-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } +node-rpc = { version = "2.0.0-alpha.6", path = "../rpc" } +node-primitives = { version = "2.0.0-alpha.6", path = "../primitives" } +node-executor = { version = "2.0.0-alpha.6", path = "../executor" } # CLI-specific dependencies -sc-cli = { version = "0.8.0-alpha.5", optional = true, path = "../../../client/cli" } -frame-benchmarking-cli = { version = "2.0.0-alpha.5", optional = true, path = "../../../utils/frame/benchmarking-cli" } -node-transaction-factory = { version = "0.8.0-alpha.5", optional = true, path = "../transaction-factory" } -node-inspect = { version = "0.8.0-alpha.5", optional = true, path = "../inspect" } +sc-cli = { version = "0.8.0-alpha.6", optional = true, path = "../../../client/cli" } +frame-benchmarking-cli = { version = "2.0.0-alpha.6", optional = true, path = "../../../utils/frame/benchmarking-cli" } +node-transaction-factory = { version = "0.8.0-alpha.6", optional = true, path = "../transaction-factory" } +node-inspect = { version = "0.8.0-alpha.6", optional = true, path = "../inspect" } # WASM-specific dependencies wasm-bindgen = { version = "0.2.57", optional = true } wasm-bindgen-futures = { version = "0.4.7", optional = true } -browser-utils = { package = "substrate-browser-utils", path = "../../../utils/browser", optional = true, version = "0.8.0-alpha.5"} +browser-utils = { package = "substrate-browser-utils", path = "../../../utils/browser", optional = true, version = "0.8.0-alpha.6"} [target.'cfg(target_arch="x86_64")'.dependencies] -node-executor = { version = "2.0.0-alpha.4", path = "../executor", features = [ "wasmtime" ] } -sc-cli = { version = "0.8.0-alpha.4", optional = true, path = "../../../client/cli", features = [ "wasmtime" ] } -sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../../../client/service", features = [ "wasmtime" ] } +node-executor = { version = "2.0.0-alpha.6", path = "../executor", features = [ "wasmtime" ] } +sc-cli = { version = "0.8.0-alpha.6", optional = true, path = "../../../client/cli", features = [ "wasmtime" ] } +sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../../../client/service", features = [ "wasmtime" ] } [dev-dependencies] -sc-keystore = { version = "2.0.0-alpha.5", path = "../../../client/keystore" } -sc-consensus-babe = { version = "0.8.0-alpha.5", features = ["test-helpers"], path = "../../../client/consensus/babe" } -sc-consensus-epochs = { version = "0.8.0-alpha.5", path = "../../../client/consensus/epochs" } +sc-keystore = { version = "2.0.0-alpha.6", path = "../../../client/keystore" } +sc-consensus-babe = { version = "0.8.0-alpha.6", features = ["test-helpers"], path = "../../../client/consensus/babe" } +sc-consensus-epochs = { version = "0.8.0-alpha.6", path = "../../../client/consensus/epochs" } sc-service-test = { version = "2.0.0-dev", path = "../../../client/service/test" } futures = "0.3.4" tempfile = "3.1.0" @@ -121,13 +124,13 @@ platforms = "0.2.1" [build-dependencies] structopt = { version = "0.3.8", optional = true } -node-transaction-factory = { version = "0.8.0-alpha.5", optional = true, path = "../transaction-factory" } -node-inspect = { version = "0.8.0-alpha.5", optional = true, path = "../inspect" } -frame-benchmarking-cli = { version = "2.0.0-alpha.5", optional = true, path = "../../../utils/frame/benchmarking-cli" } -substrate-build-script-utils = { version = "2.0.0-alpha.5", optional = true, path = "../../../utils/build-script-utils" } +node-transaction-factory = { version = "0.8.0-alpha.6", optional = true, path = "../transaction-factory" } +node-inspect = { version = "0.8.0-alpha.6", optional = true, path = "../inspect" } +frame-benchmarking-cli = { version = "2.0.0-alpha.6", optional = true, path = "../../../utils/frame/benchmarking-cli" } +substrate-build-script-utils = { version = "2.0.0-alpha.6", optional = true, path = "../../../utils/build-script-utils" } [build-dependencies.sc-cli] -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" package = "sc-cli" path = "../../../client/cli" optional = true @@ -153,6 +156,3 @@ runtime-benchmarks = [ "node-runtime/runtime-benchmarks", "frame-benchmarking-cli", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/executor/Cargo.toml b/bin/node/executor/Cargo.toml index 2f1060a998..791999eb40 100644 --- a/bin/node/executor/Cargo.toml +++ b/bin/node/executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-executor" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] description = "Substrate node implementation in Rust." edition = "2018" @@ -8,35 +8,38 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0" } -node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } -node-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } -sc-executor = { version = "0.8.0-alpha.5", path = "../../../client/executor" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-io = { version = "2.0.0-alpha.5", path = "../../../primitives/io" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } -sp-trie = { version = "2.0.0-alpha.5", path = "../../../primitives/trie" } +node-primitives = { version = "2.0.0-alpha.6", path = "../primitives" } +node-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } +sc-executor = { version = "0.8.0-alpha.6", path = "../../../client/executor" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-io = { version = "2.0.0-alpha.6", path = "../../../primitives/io" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../../primitives/state-machine" } +sp-trie = { version = "2.0.0-alpha.6", path = "../../../primitives/trie" } trie-root = "0.16.0" -frame-benchmarking = { version = "2.0.0-alpha.5", path = "../../../frame/benchmarking" } +frame-benchmarking = { version = "2.0.0-alpha.6", path = "../../../frame/benchmarking" } [dev-dependencies] criterion = "0.3.0" -frame-support = { version = "2.0.0-alpha.5", path = "../../../frame/support" } -frame-system = { version = "2.0.0-alpha.5", path = "../../../frame/system" } -node-testing = { version = "2.0.0-alpha.5", path = "../testing" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../../../frame/balances" } -pallet-contracts = { version = "2.0.0-alpha.5", path = "../../../frame/contracts" } -pallet-grandpa = { version = "2.0.0-alpha.5", path = "../../../frame/grandpa" } -pallet-im-online = { version = "2.0.0-alpha.5", path = "../../../frame/im-online" } -pallet-indices = { version = "2.0.0-alpha.5", path = "../../../frame/indices" } -pallet-session = { version = "2.0.0-alpha.5", path = "../../../frame/session" } -pallet-timestamp = { version = "2.0.0-alpha.5", path = "../../../frame/timestamp" } -pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../../../frame/transaction-payment" } -pallet-treasury = { version = "2.0.0-alpha.5", path = "../../../frame/treasury" } -sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../../primitives/application-crypto" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-externalities = { version = "0.8.0-alpha.5", path = "../../../primitives/externalities" } +frame-support = { version = "2.0.0-alpha.6", path = "../../../frame/support" } +frame-system = { version = "2.0.0-alpha.6", path = "../../../frame/system" } +node-testing = { version = "2.0.0-alpha.6", path = "../testing" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../../../frame/balances" } +pallet-contracts = { version = "2.0.0-alpha.6", path = "../../../frame/contracts" } +pallet-grandpa = { version = "2.0.0-alpha.6", path = "../../../frame/grandpa" } +pallet-im-online = { version = "2.0.0-alpha.6", path = "../../../frame/im-online" } +pallet-indices = { version = "2.0.0-alpha.6", path = "../../../frame/indices" } +pallet-session = { version = "2.0.0-alpha.6", path = "../../../frame/session" } +pallet-timestamp = { version = "2.0.0-alpha.6", path = "../../../frame/timestamp" } +pallet-transaction-payment = { version = "2.0.0-alpha.6", path = "../../../frame/transaction-payment" } +pallet-treasury = { version = "2.0.0-alpha.6", path = "../../../frame/treasury" } +sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../../primitives/application-crypto" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-externalities = { version = "0.8.0-alpha.6", path = "../../../primitives/externalities" } substrate-test-client = { version = "2.0.0-dev", path = "../../../test-utils/client" } wabt = "0.9.2" @@ -52,6 +55,3 @@ stress-test = [] [[bench]] name = "bench" harness = false - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/inspect/Cargo.toml b/bin/node/inspect/Cargo.toml index 9e94fe74d6..98672a8e19 100644 --- a/bin/node/inspect/Cargo.toml +++ b/bin/node/inspect/Cargo.toml @@ -1,23 +1,23 @@ [package] name = "node-inspect" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0" } derive_more = "0.99" log = "0.4.8" -sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } -sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../../../client/service" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sc-cli = { version = "0.8.0-alpha.6", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api" } +sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../../../client/service" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } structopt = "0.3.8" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/primitives/Cargo.toml b/bin/node/primitives/Cargo.toml index 81c5009f39..342623c7d9 100644 --- a/bin/node/primitives/Cargo.toml +++ b/bin/node/primitives/Cargo.toml @@ -1,18 +1,21 @@ [package] name = "node-primitives" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } [dev-dependencies] -sp-serializer = { version = "2.0.0-alpha.5", path = "../../../primitives/serializer" } +sp-serializer = { version = "2.0.0-alpha.6", path = "../../../primitives/serializer" } pretty_assertions = "0.6.1" [features] @@ -21,6 +24,3 @@ std = [ "sp-core/std", "sp-runtime/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/rpc-client/Cargo.toml b/bin/node/rpc-client/Cargo.toml index df095bc5bb..f6c59a309c 100644 --- a/bin/node/rpc-client/Cargo.toml +++ b/bin/node/rpc-client/Cargo.toml @@ -1,20 +1,20 @@ [package] name = "node-rpc-client" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] env_logger = "0.7.0" futures = "0.1.29" hyper = "0.12.35" jsonrpc-core-client = { version = "14.0.5", default-features = false, features = ["http"] } log = "0.4.8" -node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } -sc-rpc = { version = "2.0.0-alpha.5", path = "../../../client/rpc" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +node-primitives = { version = "2.0.0-alpha.6", path = "../primitives" } +sc-rpc = { version = "2.0.0-alpha.6", path = "../../../client/rpc" } diff --git a/bin/node/rpc/Cargo.toml b/bin/node/rpc/Cargo.toml index f1d230af90..706ad06aad 100644 --- a/bin/node/rpc/Cargo.toml +++ b/bin/node/rpc/Cargo.toml @@ -1,30 +1,30 @@ [package] name = "node-rpc" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -[dependencies] -sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } -jsonrpc-core = "14.0.3" -node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } -node-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } -pallet-contracts-rpc = { version = "0.8.0-alpha.5", path = "../../../frame/contracts/rpc/" } -pallet-transaction-payment-rpc = { version = "2.0.0-alpha.5", path = "../../../frame/transaction-payment/rpc/" } -substrate-frame-rpc-system = { version = "2.0.0-alpha.5", path = "../../../utils/frame/rpc/system" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } -sc-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../client/consensus/babe" } -sc-consensus-babe-rpc = { version = "0.8.0-alpha.5", path = "../../../client/consensus/babe/rpc" } -sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/babe" } -sc-keystore = { version = "2.0.0-alpha.5", path = "../../../client/keystore" } -sc-consensus-epochs = { version = "0.8.0-alpha.5", path = "../../../client/consensus/epochs" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } - [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +sc-client = { version = "0.8.0-alpha.6", path = "../../../client/" } +jsonrpc-core = "14.0.3" +node-primitives = { version = "2.0.0-alpha.6", path = "../primitives" } +node-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } +pallet-contracts-rpc = { version = "0.8.0-alpha.6", path = "../../../frame/contracts/rpc/" } +pallet-transaction-payment-rpc = { version = "2.0.0-alpha.6", path = "../../../frame/transaction-payment/rpc/" } +substrate-frame-rpc-system = { version = "2.0.0-alpha.6", path = "../../../utils/frame/rpc/system" } +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../primitives/transaction-pool" } +sc-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../client/consensus/babe" } +sc-consensus-babe-rpc = { version = "0.8.0-alpha.6", path = "../../../client/consensus/babe/rpc" } +sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/babe" } +sc-keystore = { version = "2.0.0-alpha.6", path = "../../../client/keystore" } +sc-consensus-epochs = { version = "0.8.0-alpha.6", path = "../../../client/consensus/epochs" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index b8e5f70629..935f218170 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-runtime" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" @@ -8,6 +8,9 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] # third-party dependencies @@ -16,67 +19,67 @@ integer-sqrt = { version = "0.1.2" } serde = { version = "1.0.102", optional = true } # primitives -sp-authority-discovery = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/authority-discovery" } -sp-consensus-babe = { version = "0.8.0-alpha.5", default-features = false, path = "../../../primitives/consensus/babe" } -sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.5"} -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/inherents" } -node-primitives = { version = "2.0.0-alpha.5", default-features = false, path = "../primitives" } -sp-offchain = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/offchain" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/core" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" } -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/staking" } -sp-keyring = { version = "2.0.0-alpha.5", optional = true, path = "../../../primitives/keyring" } -sp-session = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/session" } -sp-transaction-pool = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/transaction-pool" } -sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/version" } +sp-authority-discovery = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/authority-discovery" } +sp-consensus-babe = { version = "0.8.0-alpha.6", default-features = false, path = "../../../primitives/consensus/babe" } +sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.6"} +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/inherents" } +node-primitives = { version = "2.0.0-alpha.6", default-features = false, path = "../primitives" } +sp-offchain = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/offchain" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/std" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/staking" } +sp-keyring = { version = "2.0.0-alpha.6", optional = true, path = "../../../primitives/keyring" } +sp-session = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/session" } +sp-transaction-pool = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/transaction-pool" } +sp-version = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/version" } # frame dependencies -frame-executive = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/executive" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/system" } -frame-system-rpc-runtime-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } -pallet-authority-discovery = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/authority-discovery" } -pallet-authorship = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/authorship" } -pallet-babe = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/babe" } -pallet-balances = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/balances" } -pallet-collective = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/collective" } -pallet-contracts = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/contracts" } -pallet-contracts-primitives = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/contracts/common/" } -pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.5", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" } -pallet-democracy = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/democracy" } -pallet-elections-phragmen = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/elections-phragmen" } -pallet-finality-tracker = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/finality-tracker" } -pallet-grandpa = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/grandpa" } -pallet-im-online = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/im-online" } -pallet-indices = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/indices" } -pallet-identity = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/identity" } -pallet-membership = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/membership" } -pallet-offences = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/offences" } -pallet-offences-benchmarking = { version = "2.0.0-alpha.5", path = "../../../frame/offences/benchmarking", default-features = false, optional = true } -pallet-randomness-collective-flip = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/randomness-collective-flip" } -pallet-recovery = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/recovery" } -pallet-session = { version = "2.0.0-alpha.5", features = ["historical"], path = "../../../frame/session", default-features = false } -pallet-session-benchmarking = { version = "2.0.0-alpha.5", path = "../../../frame/session/benchmarking", default-features = false, optional = true } -pallet-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/staking" } -pallet-staking-reward-curve = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/staking/reward-curve" } -pallet-scheduler = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/scheduler" } -pallet-society = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/society" } -pallet-sudo = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/sudo" } -pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/timestamp" } -pallet-treasury = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/treasury" } -pallet-utility = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/utility" } -pallet-transaction-payment = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/transaction-payment" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" } -pallet-vesting = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/vesting" } +frame-executive = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/executive" } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/system" } +frame-system-rpc-runtime-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } +pallet-authority-discovery = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/authority-discovery" } +pallet-authorship = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/authorship" } +pallet-babe = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/babe" } +pallet-balances = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/balances" } +pallet-collective = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/collective" } +pallet-contracts = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/contracts" } +pallet-contracts-primitives = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/contracts/common/" } +pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.6", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" } +pallet-democracy = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/democracy" } +pallet-elections-phragmen = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/elections-phragmen" } +pallet-finality-tracker = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/finality-tracker" } +pallet-grandpa = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/grandpa" } +pallet-im-online = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/im-online" } +pallet-indices = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/indices" } +pallet-identity = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/identity" } +pallet-membership = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/membership" } +pallet-offences = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/offences" } +pallet-offences-benchmarking = { version = "2.0.0-alpha.6", path = "../../../frame/offences/benchmarking", default-features = false, optional = true } +pallet-randomness-collective-flip = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/randomness-collective-flip" } +pallet-recovery = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/recovery" } +pallet-session = { version = "2.0.0-alpha.6", features = ["historical"], path = "../../../frame/session", default-features = false } +pallet-session-benchmarking = { version = "2.0.0-alpha.6", path = "../../../frame/session/benchmarking", default-features = false, optional = true } +pallet-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/staking" } +pallet-staking-reward-curve = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/staking/reward-curve" } +pallet-scheduler = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/scheduler" } +pallet-society = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/society" } +pallet-sudo = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/sudo" } +pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/timestamp" } +pallet-treasury = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/treasury" } +pallet-utility = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/utility" } +pallet-transaction-payment = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/transaction-payment" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" } +pallet-vesting = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/vesting" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.5", path = "../../../primitives/io" } +sp-io = { version = "2.0.0-alpha.6", path = "../../../primitives/io" } [features] default = ["std"] @@ -154,6 +157,3 @@ runtime-benchmarks = [ "pallet-offences-benchmarking", "pallet-session-benchmarking", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index df73e20070..1ad3a93e3a 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-testing" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] description = "Test utilities for Substrate node." edition = "2018" @@ -9,49 +9,49 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = true +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -pallet-balances = { version = "2.0.0-alpha.5", path = "../../../frame/balances" } -sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } -sc-client-db = { version = "0.8.0-alpha.5", path = "../../../client/db/", features = ["kvdb-rocksdb"] } -sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api/" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../../../frame/balances" } +sc-client = { version = "0.8.0-alpha.6", path = "../../../client/" } +sc-client-db = { version = "0.8.0-alpha.6", path = "../../../client/db/", features = ["kvdb-rocksdb"] } +sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api/" } codec = { package = "parity-scale-codec", version = "1.3.0" } -pallet-contracts = { version = "2.0.0-alpha.5", path = "../../../frame/contracts" } -pallet-grandpa = { version = "2.0.0-alpha.5", path = "../../../frame/grandpa" } -pallet-indices = { version = "2.0.0-alpha.5", path = "../../../frame/indices" } -sp-keyring = { version = "2.0.0-alpha.5", path = "../../../primitives/keyring" } -node-executor = { version = "2.0.0-alpha.5", path = "../executor" } -node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } -node-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-io = { version = "2.0.0-alpha.5", path = "../../../primitives/io" } -frame-support = { version = "2.0.0-alpha.5", path = "../../../frame/support" } -pallet-session = { version = "2.0.0-alpha.5", path = "../../../frame/session" } -pallet-society = { version = "2.0.0-alpha.5", path = "../../../frame/society" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -pallet-staking = { version = "2.0.0-alpha.5", path = "../../../frame/staking" } -sc-executor = { version = "0.8.0-alpha.5", path = "../../../client/executor", features = ["wasmtime"] } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } -frame-system = { version = "2.0.0-alpha.5", path = "../../../frame/system" } +pallet-contracts = { version = "2.0.0-alpha.6", path = "../../../frame/contracts" } +pallet-grandpa = { version = "2.0.0-alpha.6", path = "../../../frame/grandpa" } +pallet-indices = { version = "2.0.0-alpha.6", path = "../../../frame/indices" } +sp-keyring = { version = "2.0.0-alpha.6", path = "../../../primitives/keyring" } +node-executor = { version = "2.0.0-alpha.6", path = "../executor" } +node-primitives = { version = "2.0.0-alpha.6", path = "../primitives" } +node-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-io = { version = "2.0.0-alpha.6", path = "../../../primitives/io" } +frame-support = { version = "2.0.0-alpha.6", path = "../../../frame/support" } +pallet-session = { version = "2.0.0-alpha.6", path = "../../../frame/session" } +pallet-society = { version = "2.0.0-alpha.6", path = "../../../frame/society" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +pallet-staking = { version = "2.0.0-alpha.6", path = "../../../frame/staking" } +sc-executor = { version = "0.8.0-alpha.6", path = "../../../client/executor", features = ["wasmtime"] } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } +frame-system = { version = "2.0.0-alpha.6", path = "../../../frame/system" } substrate-test-client = { version = "2.0.0-dev", path = "../../../test-utils/client" } -pallet-timestamp = { version = "2.0.0-alpha.5", path = "../../../frame/timestamp" } -pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../../../frame/transaction-payment" } -pallet-treasury = { version = "2.0.0-alpha.5", path = "../../../frame/treasury" } +pallet-timestamp = { version = "2.0.0-alpha.6", path = "../../../frame/timestamp" } +pallet-transaction-payment = { version = "2.0.0-alpha.6", path = "../../../frame/transaction-payment" } +pallet-treasury = { version = "2.0.0-alpha.6", path = "../../../frame/treasury" } wabt = "0.9.2" -sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } -sp-finality-tracker = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/finality-tracker" } -sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/timestamp" } -sp-block-builder = { version = "2.0.0-alpha.5", path = "../../../primitives/block-builder" } -sc-block-builder = { version = "0.8.0-alpha.5", path = "../../../client/block-builder" } -sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } +sp-finality-tracker = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/finality-tracker" } +sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/timestamp" } +sp-block-builder = { version = "2.0.0-alpha.6", path = "../../../primitives/block-builder" } +sc-block-builder = { version = "0.8.0-alpha.6", path = "../../../client/block-builder" } +sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } log = "0.4.8" tempfile = "3.1.0" fs_extra = "1" [dev-dependencies] criterion = "0.3.0" -sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } -sc-service = { version = "0.8.0-alpha.5", path = "../../../client/service", features = ["rocksdb"] } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sc-cli = { version = "0.8.0-alpha.6", path = "../../../client/cli" } +sc-service = { version = "0.8.0-alpha.6", path = "../../../client/service", features = ["rocksdb"] } diff --git a/bin/node/transaction-factory/Cargo.toml b/bin/node/transaction-factory/Cargo.toml index 33ebeb767a..98d996c3fa 100644 --- a/bin/node/transaction-factory/Cargo.toml +++ b/bin/node/transaction-factory/Cargo.toml @@ -1,26 +1,26 @@ [package] name = "node-transaction-factory" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-block-builder = { version = "2.0.0-alpha.5", path = "../../../primitives/block-builder" } -sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } -sc-block-builder = { version = "0.8.0-alpha.5", path = "../../../client/block-builder" } -sc-client = { version = "0.8.0-alpha.5", path = "../../../client" } +sp-block-builder = { version = "2.0.0-alpha.6", path = "../../../primitives/block-builder" } +sc-cli = { version = "0.8.0-alpha.6", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api" } +sc-block-builder = { version = "0.8.0-alpha.6", path = "../../../client/block-builder" } +sc-client = { version = "0.8.0-alpha.6", path = "../../../client" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } log = "0.4.8" -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../../../client/service" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../../../client/service" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } diff --git a/bin/utils/chain-spec-builder/Cargo.toml b/bin/utils/chain-spec-builder/Cargo.toml index bab393a86a..cd9dd516b4 100644 --- a/bin/utils/chain-spec-builder/Cargo.toml +++ b/bin/utils/chain-spec-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "chain-spec-builder" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" @@ -8,14 +8,14 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] ansi_term = "0.12.1" -sc-keystore = { version = "2.0.0-alpha.5", path = "../../../client/keystore" } -sc-chain-spec = { version = "2.0.0-alpha.5", path = "../../../client/chain-spec" } -node-cli = { version = "2.0.0-alpha.5", path = "../../node/cli" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sc-keystore = { version = "2.0.0-alpha.6", path = "../../../client/keystore" } +sc-chain-spec = { version = "2.0.0-alpha.6", path = "../../../client/chain-spec" } +node-cli = { version = "2.0.0-alpha.6", path = "../../node/cli" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } rand = "0.7.2" structopt = "0.3.8" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index 688f066ef1..eddcde46fa 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -1,18 +1,21 @@ [package] name = "subkey" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] futures = "0.1.29" -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -node-runtime = { version = "2.0.0-alpha.5", path = "../../node/runtime" } -node-primitives = { version = "2.0.0-alpha.5", path = "../../node/primitives" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +node-runtime = { version = "2.0.0-alpha.6", path = "../../node/runtime" } +node-primitives = { version = "2.0.0-alpha.6", path = "../../node/primitives" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } rand = "0.7.2" clap = "2.33.0" tiny-bip39 = "0.7" @@ -20,13 +23,13 @@ substrate-bip39 = "0.4.1" hex = "0.4.0" hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.3.0" } -frame-system = { version = "2.0.0-alpha.5", path = "../../../frame/system" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../../../frame/balances" } -pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../../../frame/transaction-payment" } +frame-system = { version = "2.0.0-alpha.6", path = "../../../frame/system" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../../../frame/balances" } +pallet-transaction-payment = { version = "2.0.0-alpha.6", path = "../../../frame/transaction-payment" } rpassword = "4.0.1" itertools = "0.8.2" derive_more = { version = "0.99.2" } -sc-rpc = { version = "2.0.0-alpha.5", path = "../../../client/rpc" } +sc-rpc = { version = "2.0.0-alpha.6", path = "../../../client/rpc" } jsonrpc-core-client = { version = "14.0.3", features = ["http"] } hyper = "0.12.35" libp2p = "0.18.0" @@ -34,6 +37,3 @@ serde_json = "1.0" [features] bench = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/Cargo.toml b/client/Cargo.toml index 5d4b592711..2e6c73818b 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-client" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,34 +8,37 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate Client and associated logic." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sc-block-builder = { version = "0.8.0-alpha.5", path = "block-builder" } -sc-client-api = { version = "2.0.0-alpha.5", path = "api" } +sc-block-builder = { version = "0.8.0-alpha.6", path = "block-builder" } +sc-client-api = { version = "2.0.0-alpha.6", path = "api" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.5", path = "../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../primitives/consensus/common" } derive_more = { version = "0.99.2" } -sc-executor = { version = "0.8.0-alpha.5", path = "executor" } -sp-externalities = { version = "0.8.0-alpha.5", path = "../primitives/externalities" } +sc-executor = { version = "0.8.0-alpha.6", path = "executor" } +sp-externalities = { version = "0.8.0-alpha.6", path = "../primitives/externalities" } fnv = { version = "1.0.6" } futures = { version = "0.3.1", features = ["compat"] } hash-db = { version = "0.15.2" } hex-literal = { version = "0.2.1" } -sp-inherents = { version = "2.0.0-alpha.5", path = "../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.5", path = "../primitives/keyring" } +sp-inherents = { version = "2.0.0-alpha.6", path = "../primitives/inherents" } +sp-keyring = { version = "2.0.0-alpha.6", path = "../primitives/keyring" } kvdb = "0.5.0" log = { version = "0.4.8" } parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.5", path = "../primitives/core" } -sp-std = { version = "2.0.0-alpha.5", path = "../primitives/std" } -sp-version = { version = "2.0.0-alpha.5", path = "../primitives/version" } -sp-api = { version = "2.0.0-alpha.5", path = "../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.5", path = "../primitives/utils" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../primitives/blockchain" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-alpha.5", path = "telemetry" } -sp-trie = { version = "2.0.0-alpha.5", path = "../primitives/trie" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.5", path = "../utils/prometheus" } +sp-core = { version = "2.0.0-alpha.6", path = "../primitives/core" } +sp-std = { version = "2.0.0-alpha.6", path = "../primitives/std" } +sp-version = { version = "2.0.0-alpha.6", path = "../primitives/version" } +sp-api = { version = "2.0.0-alpha.6", path = "../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.6", path = "../primitives/utils" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../primitives/blockchain" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-alpha.6", path = "telemetry" } +sp-trie = { version = "2.0.0-alpha.6", path = "../primitives/trie" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.6", path = "../utils/prometheus" } tracing = "0.1.10" [dev-dependencies] @@ -43,7 +46,4 @@ env_logger = "0.7.0" tempfile = "3.1.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../test-utils/runtime/client" } kvdb-memorydb = "0.5.0" -sp-panic-handler = { version = "2.0.0-alpha.5", path = "../primitives/panic-handler" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sp-panic-handler = { version = "2.0.0-alpha.6", path = "../primitives/panic-handler" } diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index dbe6afe9c7..a9a3361de3 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-client-api" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,38 +9,38 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate client interfaces." documentation = "https://docs.rs/sc-client-api" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } derive_more = { version = "0.99.2" } -sc-executor = { version = "0.8.0-alpha.5", path = "../executor" } -sp-externalities = { version = "0.8.0-alpha.5", path = "../../primitives/externalities" } +sc-executor = { version = "0.8.0-alpha.6", path = "../executor" } +sp-externalities = { version = "0.8.0-alpha.6", path = "../../primitives/externalities" } fnv = { version = "1.0.6" } futures = { version = "0.3.1" } hash-db = { version = "0.15.2", default-features = false } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } hex-literal = { version = "0.2.1" } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } +sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } kvdb = "0.5.0" log = { version = "0.4.8" } parking_lot = "0.10.0" lazy_static = "1.4.0" -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/version" } -sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } -sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } -sp-trie = { version = "2.0.0-alpha.5", path = "../../primitives/trie" } -sp-storage = { version = "2.0.0-alpha.5", path = "../../primitives/storage" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-version = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/version" } +sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } +sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } +sp-trie = { version = "2.0.0-alpha.6", path = "../../primitives/trie" } +sp-storage = { version = "2.0.0-alpha.6", path = "../../primitives/storage" } +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } [dev-dependencies] sp-test-primitives = { version = "2.0.0-dev", path = "../../primitives/test-primitives" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 0aa1e6a6dc..58ee23111b 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-authority-discovery" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" @@ -9,6 +9,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate authority discovery." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [build-dependencies] prost-build = "0.6.1" @@ -20,24 +23,21 @@ futures = "0.3.4" futures-timer = "3.0.1" libp2p = { version = "0.18.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } log = "0.4.8" -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.5"} +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.6"} prost = "0.6.1" rand = "0.7.2" -sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } -sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } -sc-network = { version = "0.8.0-alpha.5", path = "../network" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } +sc-keystore = { version = "2.0.0-alpha.6", path = "../keystore" } +sc-network = { version = "0.8.0-alpha.6", path = "../network" } serde_json = "1.0.41" -sp-authority-discovery = { version = "2.0.0-alpha.5", path = "../../primitives/authority-discovery" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } +sp-authority-discovery = { version = "2.0.0-alpha.6", path = "../../primitives/authority-discovery" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } [dev-dependencies] env_logger = "0.7.0" quickcheck = "0.9.0" -sc-peerset = { version = "2.0.0-alpha.5", path = "../peerset" } +sc-peerset = { version = "2.0.0-alpha.6", path = "../peerset" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client"} - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index 040370ac49..d6aee79575 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-basic-authorship" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,27 +8,27 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Basic implementation of block-authoring logic." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] log = "0.4.8" futures = "0.3.4" codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-alpha.5", path = "../../primitives/inherents" } -sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } -sc-block-builder = { version = "0.8.0-alpha.5", path = "../block-builder" } +sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-alpha.6", path = "../../primitives/inherents" } +sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } +sc-block-builder = { version = "0.8.0-alpha.6", path = "../block-builder" } tokio-executor = { version = "0.2.0-alpha.6", features = ["blocking"] } futures-timer = "3.0.1" [dev-dependencies] -sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../../client/transaction-pool" } +sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../../client/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } parking_lot = "0.10.0" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/block-builder/Cargo.toml b/client/block-builder/Cargo.toml index 5f9ef7c75e..376c6f41df 100644 --- a/client/block-builder/Cargo.toml +++ b/client/block-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-block-builder" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,21 +8,21 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate block builder" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-block-builder = { version = "2.0.0-alpha.5", path = "../../primitives/block-builder" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-block-builder = { version = "2.0.0-alpha.6", path = "../../primitives/block-builder" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } [dev-dependencies] substrate-test-runtime-client = { path = "../../test-utils/runtime/client" } -sp-trie = { version = "2.0.0-alpha.5", path = "../../primitives/trie" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sp-trie = { version = "2.0.0-alpha.6", path = "../../primitives/trie" } diff --git a/client/chain-spec/Cargo.toml b/client/chain-spec/Cargo.toml index cf30ad6063..4d9c1df00e 100644 --- a/client/chain-spec/Cargo.toml +++ b/client/chain-spec/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-chain-spec" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,16 +8,16 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate chain configurations." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sc-chain-spec-derive = { version = "2.0.0-alpha.5", path = "./derive" } +sc-chain-spec-derive = { version = "2.0.0-alpha.6", path = "./derive" } impl-trait-for-tuples = "0.1.3" -sc-network = { version = "0.8.0-alpha.5", path = "../network" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sc-network = { version = "0.8.0-alpha.6", path = "../network" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -sp-chain-spec = { version = "2.0.0-alpha.5", path = "../../primitives/chain-spec" } -sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-chain-spec = { version = "2.0.0-alpha.6", path = "../../primitives/chain-spec" } +sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } diff --git a/client/chain-spec/derive/Cargo.toml b/client/chain-spec/derive/Cargo.toml index 9343c9a6de..14fddcd9be 100644 --- a/client/chain-spec/derive/Cargo.toml +++ b/client/chain-spec/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-chain-spec-derive" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,6 +8,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Macros to derive chain spec extension traits implementation." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [lib] proc-macro = true @@ -18,6 +21,3 @@ quote = "1.0.3" syn = "1.0.7" [dev-dependencies] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 1043818f7c..3c5a7b01bf 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-cli" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Substrate CLI interface." edition = "2018" @@ -8,6 +8,9 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] clap = "2.33.0" derive_more = "0.99.2" @@ -23,23 +26,23 @@ tokio = { version = "0.2.9", features = [ "signal", "rt-core", "rt-threaded" ] } futures = "0.3.4" fdlimit = "0.1.4" serde_json = "1.0.41" -sc-informant = { version = "0.8.0-alpha.5", path = "../informant" } -sp-panic-handler = { version = "2.0.0-alpha.5", path = "../../primitives/panic-handler" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } -sc-network = { version = "0.8.0-alpha.5", path = "../network" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } -sp-version = { version = "2.0.0-alpha.5", path = "../../primitives/version" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../service" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } -substrate-prometheus-endpoint = { path = "../../utils/prometheus" , version = "0.8.0-alpha.5"} -sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } +sc-informant = { version = "0.8.0-alpha.6", path = "../informant" } +sp-panic-handler = { version = "2.0.0-alpha.6", path = "../../primitives/panic-handler" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } +sc-network = { version = "0.8.0-alpha.6", path = "../network" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } +sp-version = { version = "2.0.0-alpha.6", path = "../../primitives/version" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../service" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } +substrate-prometheus-endpoint = { path = "../../utils/prometheus" , version = "0.8.0-alpha.6"} +sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } names = "0.11.0" structopt = "0.3.8" -sc-tracing = { version = "2.0.0-alpha.5", path = "../tracing" } +sc-tracing = { version = "2.0.0-alpha.6", path = "../tracing" } chrono = "0.4.10" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } @@ -56,6 +59,3 @@ tempfile = "3.1.0" wasmtime = [ "sc-service/wasmtime", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/aura/Cargo.toml b/client/consensus/aura/Cargo.toml index f0fe368acb..63bc43a371 100644 --- a/client/consensus/aura/Cargo.toml +++ b/client/consensus/aura/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-aura" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Aura consensus algorithm for substrate" edition = "2018" @@ -8,41 +8,41 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../../primitives/application-crypto" } -sp-consensus-aura = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/aura" } -sp-block-builder = { version = "2.0.0-alpha.5", path = "../../../primitives/block-builder" } -sc-block-builder = { version = "0.8.0-alpha.5", path = "../../../client/block-builder" } -sc-client = { version = "0.8.0-alpha.5", path = "../../" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } +sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../../primitives/application-crypto" } +sp-consensus-aura = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/aura" } +sp-block-builder = { version = "2.0.0-alpha.6", path = "../../../primitives/block-builder" } +sc-block-builder = { version = "0.8.0-alpha.6", path = "../../../client/block-builder" } +sc-client = { version = "0.8.0-alpha.6", path = "../../" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../../api" } codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } derive_more = "0.99.2" futures = "0.3.4" futures-timer = "3.0.1" -sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } -sc-keystore = { version = "2.0.0-alpha.5", path = "../../keystore" } +sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } +sc-keystore = { version = "2.0.0-alpha.6", path = "../../keystore" } log = "0.4.8" parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } -sp-io = { version = "2.0.0-alpha.5", path = "../../../primitives/io" } -sp-version = { version = "2.0.0-alpha.5", path = "../../../primitives/version" } -sc-consensus-slots = { version = "0.8.0-alpha.5", path = "../slots" } -sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-timestamp = { version = "2.0.0-alpha.5", path = "../../../primitives/timestamp" } -sc-telemetry = { version = "2.0.0-alpha.5", path = "../../telemetry" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +sp-io = { version = "2.0.0-alpha.6", path = "../../../primitives/io" } +sp-version = { version = "2.0.0-alpha.6", path = "../../../primitives/version" } +sc-consensus-slots = { version = "0.8.0-alpha.6", path = "../slots" } +sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-timestamp = { version = "2.0.0-alpha.6", path = "../../../primitives/timestamp" } +sc-telemetry = { version = "2.0.0-alpha.6", path = "../../telemetry" } [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.5", path = "../../../primitives/keyring" } -sc-executor = { version = "0.8.0-alpha.5", path = "../../executor" } -sc-network = { version = "0.8.0-alpha.5", path = "../../network" } +sp-keyring = { version = "2.0.0-alpha.6", path = "../../../primitives/keyring" } +sc-executor = { version = "0.8.0-alpha.6", path = "../../executor" } +sc-network = { version = "0.8.0-alpha.6", path = "../../network" } sc-network-test = { version = "0.8.0-dev", path = "../../network/test" } -sc-service = { version = "0.8.0-alpha.5", path = "../../service" } +sc-service = { version = "0.8.0-alpha.6", path = "../../service" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } env_logger = "0.7.0" tempfile = "3.1.0" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index 19c5bf9e58..080fb8d7db 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-babe" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "BABE consensus algorithm for substrate" edition = "2018" @@ -9,33 +9,36 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sc-consensus-babe" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/babe" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../../primitives/application-crypto" } +sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/babe" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../../primitives/application-crypto" } num-bigint = "0.2.3" num-rational = "0.2.2" num-traits = "0.2.8" serde = { version = "1.0.104", features = ["derive"] } -sp-version = { version = "2.0.0-alpha.5", path = "../../../primitives/version" } -sp-io = { version = "2.0.0-alpha.5", path = "../../../primitives/io" } -sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } -sp-timestamp = { version = "2.0.0-alpha.5", path = "../../../primitives/timestamp" } -sc-telemetry = { version = "2.0.0-alpha.5", path = "../../telemetry" } -sc-keystore = { version = "2.0.0-alpha.5", path = "../../keystore" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } -sc-client = { version = "0.8.0-alpha.5", path = "../../" } -sc-consensus-epochs = { version = "0.8.0-alpha.5", path = "../epochs" } -sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } -sp-block-builder = { version = "2.0.0-alpha.5", path = "../../../primitives/block-builder" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } -sp-consensus-vrf = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/vrf" } -sc-consensus-uncles = { version = "0.8.0-alpha.5", path = "../uncles" } -sc-consensus-slots = { version = "0.8.0-alpha.5", path = "../slots" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -fork-tree = { version = "2.0.0-alpha.5", path = "../../../utils/fork-tree" } +sp-version = { version = "2.0.0-alpha.6", path = "../../../primitives/version" } +sp-io = { version = "2.0.0-alpha.6", path = "../../../primitives/io" } +sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } +sp-timestamp = { version = "2.0.0-alpha.6", path = "../../../primitives/timestamp" } +sc-telemetry = { version = "2.0.0-alpha.6", path = "../../telemetry" } +sc-keystore = { version = "2.0.0-alpha.6", path = "../../keystore" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../../api" } +sc-client = { version = "0.8.0-alpha.6", path = "../../" } +sc-consensus-epochs = { version = "0.8.0-alpha.6", path = "../epochs" } +sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } +sp-block-builder = { version = "2.0.0-alpha.6", path = "../../../primitives/block-builder" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } +sp-consensus-vrf = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/vrf" } +sc-consensus-uncles = { version = "0.8.0-alpha.6", path = "../uncles" } +sc-consensus-slots = { version = "0.8.0-alpha.6", path = "../slots" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +fork-tree = { version = "2.0.0-alpha.6", path = "../../../utils/fork-tree" } futures = "0.3.4" futures-timer = "3.0.1" parking_lot = "0.10.0" @@ -47,18 +50,15 @@ pdqselect = "0.1.0" derive_more = "0.99.2" [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.5", path = "../../../primitives/keyring" } -sc-executor = { version = "0.8.0-alpha.5", path = "../../executor" } -sc-network = { version = "0.8.0-alpha.5", path = "../../network" } +sp-keyring = { version = "2.0.0-alpha.6", path = "../../../primitives/keyring" } +sc-executor = { version = "0.8.0-alpha.6", path = "../../executor" } +sc-network = { version = "0.8.0-alpha.6", path = "../../network" } sc-network-test = { version = "0.8.0-dev", path = "../../network/test" } -sc-service = { version = "0.8.0-alpha.5", path = "../../service" } +sc-service = { version = "0.8.0-alpha.6", path = "../../service" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sc-block-builder = { version = "0.8.0-alpha.5", path = "../../block-builder" } +sc-block-builder = { version = "0.8.0-alpha.6", path = "../../block-builder" } env_logger = "0.7.0" tempfile = "3.1.0" [features] test-helpers = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/babe/rpc/Cargo.toml b/client/consensus/babe/rpc/Cargo.toml index 6bdaeb5ddf..6804ef94f5 100644 --- a/client/consensus/babe/rpc/Cargo.toml +++ b/client/consensus/babe/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-babe-rpc" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "RPC extensions for the BABE consensus algorithm" edition = "2018" @@ -8,28 +8,28 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sc-consensus-babe = { version = "0.8.0-alpha.5", path = "../" } +sc-consensus-babe = { version = "0.8.0-alpha.6", path = "../" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.3" -sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../../primitives/consensus/babe" } +sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../../primitives/consensus/babe" } serde = { version = "1.0.104", features=["derive"] } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../../primitives/runtime" } -sc-consensus-epochs = { version = "0.8.0-alpha.5", path = "../../epochs" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../../primitives/runtime" } +sc-consensus-epochs = { version = "0.8.0-alpha.6", path = "../../epochs" } futures = "0.3.4" derive_more = "0.99.2" -sp-api = { version = "2.0.0-alpha.5", path = "../../../../primitives/api" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../../primitives/consensus/common" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../../primitives/core" } -sc-keystore = { version = "2.0.0-alpha.5", path = "../../../keystore" } +sp-api = { version = "2.0.0-alpha.6", path = "../../../../primitives/api" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../../primitives/consensus/common" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../../primitives/core" } +sc-keystore = { version = "2.0.0-alpha.6", path = "../../../keystore" } [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../../test-utils/runtime/client" } -sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../../../primitives/application-crypto" } -sp-keyring = { version = "2.0.0-alpha.5", path = "../../../../primitives/keyring" } +sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../../../primitives/application-crypto" } +sp-keyring = { version = "2.0.0-alpha.6", path = "../../../../primitives/keyring" } tempfile = "3.1.0" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/epochs/Cargo.toml b/client/consensus/epochs/Cargo.toml index 3496141ec7..facbfb3638 100644 --- a/client/consensus/epochs/Cargo.toml +++ b/client/consensus/epochs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-epochs" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Generic epochs-based utilities for consensus" edition = "2018" @@ -8,13 +8,13 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } parking_lot = "0.10.0" -fork-tree = { version = "2.0.0-alpha.5", path = "../../../utils/fork-tree" } -sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.5"} -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } -sc-client-api = { path = "../../api" , version = "2.0.0-alpha.5"} - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +fork-tree = { version = "2.0.0-alpha.6", path = "../../../utils/fork-tree" } +sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.6"} +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +sc-client-api = { path = "../../api" , version = "2.0.0-alpha.6"} diff --git a/client/consensus/manual-seal/Cargo.toml b/client/consensus/manual-seal/Cargo.toml index b7e5f7b0b1..cc989378dd 100644 --- a/client/consensus/manual-seal/Cargo.toml +++ b/client/consensus/manual-seal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-manual-seal" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Manual sealing engine for Substrate" edition = "2018" @@ -8,6 +8,9 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] derive_more = "0.99.2" futures = "0.3.4" @@ -19,22 +22,19 @@ parking_lot = "0.10.0" serde = { version = "1.0", features=["derive"] } assert_matches = "1.3.0" -sc-client = { path = "../../../client" , version = "0.8.0-alpha.5"} -sc-client-api = { path = "../../../client/api" , version = "2.0.0-alpha.5"} -sc-transaction-pool = { path = "../../transaction-pool" , version = "2.0.0-alpha.5"} -sp-blockchain = { path = "../../../primitives/blockchain" , version = "2.0.0-alpha.5"} -sp-consensus = { package = "sp-consensus", path = "../../../primitives/consensus/common" , version = "0.8.0-alpha.5"} -sp-inherents = { path = "../../../primitives/inherents" , version = "2.0.0-alpha.5"} -sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.5"} -sp-transaction-pool = { path = "../../../primitives/transaction-pool" , version = "2.0.0-alpha.5"} +sc-client = { path = "../../../client" , version = "0.8.0-alpha.6"} +sc-client-api = { path = "../../../client/api" , version = "2.0.0-alpha.6"} +sc-transaction-pool = { path = "../../transaction-pool" , version = "2.0.0-alpha.6"} +sp-blockchain = { path = "../../../primitives/blockchain" , version = "2.0.0-alpha.6"} +sp-consensus = { package = "sp-consensus", path = "../../../primitives/consensus/common" , version = "0.8.0-alpha.6"} +sp-inherents = { path = "../../../primitives/inherents" , version = "2.0.0-alpha.6"} +sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.6"} +sp-transaction-pool = { path = "../../../primitives/transaction-pool" , version = "2.0.0-alpha.6"} [dev-dependencies] -sc-basic-authorship = { path = "../../basic-authorship" , version = "0.8.0-alpha.5"} +sc-basic-authorship = { path = "../../basic-authorship" , version = "0.8.0-alpha.6"} substrate-test-runtime-client = { path = "../../../test-utils/runtime/client" , version = "2.0.0-dev"} substrate-test-runtime-transaction-pool = { path = "../../../test-utils/runtime/transaction-pool" , version = "2.0.0-dev"} tokio = { version = "0.2", features = ["rt-core", "macros"] } env_logger = "0.7.0" tempfile = "3.1.0" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/pow/Cargo.toml b/client/consensus/pow/Cargo.toml index c7832baae0..f011a7c060 100644 --- a/client/consensus/pow/Cargo.toml +++ b/client/consensus/pow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-pow" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "PoW consensus algorithm for substrate" edition = "2018" @@ -8,21 +8,21 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } -sp-block-builder = { version = "2.0.0-alpha.5", path = "../../../primitives/block-builder" } -sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } -sp-consensus-pow = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/pow" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../../api" } +sp-block-builder = { version = "2.0.0-alpha.6", path = "../../../primitives/block-builder" } +sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } +sp-consensus-pow = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/pow" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } log = "0.4.8" futures = { version = "0.3.1", features = ["compat"] } -sp-timestamp = { version = "2.0.0-alpha.5", path = "../../../primitives/timestamp" } +sp-timestamp = { version = "2.0.0-alpha.6", path = "../../../primitives/timestamp" } derive_more = "0.99.2" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index bf973ef47a..589ac3255c 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-slots" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Generic slots-based utilities for consensus" edition = "2018" @@ -9,17 +9,20 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } -sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } -sc-telemetry = { version = "2.0.0-alpha.5", path = "../../telemetry" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../../api" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../../primitives/state-machine" } +sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } +sc-telemetry = { version = "2.0.0-alpha.6", path = "../../telemetry" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } futures = "0.3.4" futures-timer = "3.0.1" parking_lot = "0.10.0" @@ -27,6 +30,3 @@ log = "0.4.8" [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/uncles/Cargo.toml b/client/consensus/uncles/Cargo.toml index 7e8014199b..828572ece5 100644 --- a/client/consensus/uncles/Cargo.toml +++ b/client/consensus/uncles/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-uncles" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Generic uncle inclusion utilities for consensus" edition = "2018" @@ -8,14 +8,14 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -[dependencies] -sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-authorship = { version = "2.0.0-alpha.5", path = "../../../primitives/authorship" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } -log = "0.4.8" - [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +sc-client-api = { version = "2.0.0-alpha.6", path = "../../api" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-authorship = { version = "2.0.0-alpha.6", path = "../../../primitives/authorship" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } +log = "0.4.8" diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index c791f253a9..19b7423d6b 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-client-db" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,6 +8,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Client backend that uses RocksDB database as storage." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] parking_lot = "0.10.0" log = "0.4.8" @@ -19,20 +22,20 @@ hash-db = "0.15.2" parity-util-mem = { version = "0.6.0", default-features = false, features = ["std"] } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -sc-client = { version = "0.8.0-alpha.5", path = "../" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } -sc-executor = { version = "0.8.0-alpha.5", path = "../executor" } -sc-state-db = { version = "0.8.0-alpha.5", path = "../state-db" } -sp-trie = { version = "2.0.0-alpha.5", path = "../../primitives/trie" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.5", path = "../../utils/prometheus" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sc-client = { version = "0.8.0-alpha.6", path = "../" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } +sc-executor = { version = "0.8.0-alpha.6", path = "../executor" } +sc-state-db = { version = "0.8.0-alpha.6", path = "../state-db" } +sp-trie = { version = "2.0.0-alpha.6", path = "../../primitives/trie" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.6", path = "../../utils/prometheus" } [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } env_logger = "0.7.0" quickcheck = "0.9" @@ -42,6 +45,3 @@ tempfile = "3" [features] default = [] test-helpers = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index cae0d56d8e..92bf03761c 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,24 +9,27 @@ repository = "https://github.com/paritytech/substrate/" description = "A crate that provides means of executing/dispatching calls into the runtime." documentation = "https://docs.rs/sc-executor" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] derive_more = "0.99.2" codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-trie = { version = "2.0.0-alpha.5", path = "../../primitives/trie" } -sp-serializer = { version = "2.0.0-alpha.5", path = "../../primitives/serializer" } -sp-version = { version = "2.0.0-alpha.5", path = "../../primitives/version" } -sp-panic-handler = { version = "2.0.0-alpha.5", path = "../../primitives/panic-handler" } +sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-trie = { version = "2.0.0-alpha.6", path = "../../primitives/trie" } +sp-serializer = { version = "2.0.0-alpha.6", path = "../../primitives/serializer" } +sp-version = { version = "2.0.0-alpha.6", path = "../../primitives/version" } +sp-panic-handler = { version = "2.0.0-alpha.6", path = "../../primitives/panic-handler" } wasmi = "0.6.2" parity-wasm = "0.41.0" lazy_static = "1.4.0" -sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../primitives/runtime-interface" } -sp-externalities = { version = "0.8.0-alpha.5", path = "../../primitives/externalities" } -sc-executor-common = { version = "0.8.0-alpha.5", path = "common" } -sc-executor-wasmi = { version = "0.8.0-alpha.5", path = "wasmi" } -sc-executor-wasmtime = { version = "0.8.0-alpha.5", path = "wasmtime", optional = true } +sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-alpha.6", path = "../../primitives/runtime-interface" } +sp-externalities = { version = "0.8.0-alpha.6", path = "../../primitives/externalities" } +sc-executor-common = { version = "0.8.0-alpha.6", path = "common" } +sc-executor-wasmi = { version = "0.8.0-alpha.6", path = "wasmi" } +sc-executor-wasmtime = { version = "0.8.0-alpha.6", path = "wasmtime", optional = true } parking_lot = "0.10.0" log = "0.4.8" libsecp256k1 = "0.3.4" @@ -37,9 +40,9 @@ wabt = "0.9.2" hex-literal = "0.2.1" sc-runtime-test = { version = "2.0.0-dev", path = "runtime-test" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } test-case = "0.3.3" -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } [features] default = [ "std" ] @@ -52,6 +55,3 @@ wasmtime = [ wasmi-errno = [ "wasmi/errno" ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/executor/common/Cargo.toml b/client/executor/common/Cargo.toml index f9ce7d4e39..ec11ef8024 100644 --- a/client/executor/common/Cargo.toml +++ b/client/executor/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor-common" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,20 +9,20 @@ repository = "https://github.com/paritytech/substrate/" description = "A set of common definitions that are needed for defining execution engines." documentation = "https://docs.rs/sc-executor-common/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] log = "0.4.8" derive_more = "0.99.2" parity-wasm = "0.41.0" codec = { package = "parity-scale-codec", version = "1.3.0" } wasmi = "0.6.2" -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-alpha.5", path = "../../../primitives/allocator" } -sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime-interface" } -sp-serializer = { version = "2.0.0-alpha.5", path = "../../../primitives/serializer" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-alpha.6", path = "../../../primitives/allocator" } +sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime-interface" } +sp-serializer = { version = "2.0.0-alpha.6", path = "../../../primitives/serializer" } [features] default = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/executor/runtime-test/Cargo.toml b/client/executor/runtime-test/Cargo.toml index e50061f4f2..64cc5b5b5a 100644 --- a/client/executor/runtime-test/Cargo.toml +++ b/client/executor/runtime-test/Cargo.toml @@ -9,13 +9,16 @@ publish = false homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/io" } -sp-sandbox = { version = "0.8.0-alpha.5", default-features = false, path = "../../../primitives/sandbox" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } -sp-allocator = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/allocator" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/io" } +sp-sandbox = { version = "0.8.0-alpha.6", default-features = false, path = "../../../primitives/sandbox" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } +sp-allocator = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/allocator" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } @@ -28,6 +31,3 @@ std = [ "sp-std/std", "sp-allocator/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/executor/wasmi/Cargo.toml b/client/executor/wasmi/Cargo.toml index fe5bd70d00..4867f23a40 100644 --- a/client/executor/wasmi/Cargo.toml +++ b/client/executor/wasmi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor-wasmi" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,15 +9,15 @@ repository = "https://github.com/paritytech/substrate/" description = "This crate provides an implementation of `WasmRuntime` that is baked by wasmi." documentation = "https://docs.rs/sc-executor-wasmi" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] log = "0.4.8" wasmi = "0.6.2" codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-executor-common = { version = "0.8.0-alpha.5", path = "../common" } -sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime-interface" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-alpha.5", path = "../../../primitives/allocator" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sc-executor-common = { version = "0.8.0-alpha.6", path = "../common" } +sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime-interface" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-alpha.6", path = "../../../primitives/allocator" } diff --git a/client/executor/wasmtime/Cargo.toml b/client/executor/wasmtime/Cargo.toml index fcedf20b7a..90c32d0401 100644 --- a/client/executor/wasmtime/Cargo.toml +++ b/client/executor/wasmtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor-wasmtime" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,16 +8,19 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Defines a `WasmRuntime` that uses the Wasmtime JIT to execute." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] log = "0.4.8" scoped-tls = "1.0" parity-wasm = "0.41.0" codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-executor-common = { version = "0.8.0-alpha.5", path = "../common" } -sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime-interface" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-alpha.5", path = "../../../primitives/allocator" } +sc-executor-common = { version = "0.8.0-alpha.6", path = "../common" } +sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime-interface" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-alpha.6", path = "../../../primitives/allocator" } wasmtime = { package = "substrate-wasmtime", version = "0.13.0-threadsafe.1" } wasmtime_runtime = { package = "substrate-wasmtime-runtime", version = "0.13.0-threadsafe.1" } wasmtime-environ = "0.12.0" @@ -26,6 +29,3 @@ cranelift-codegen = "0.59.0" [dev-dependencies] assert_matches = "1.3.0" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index b684c814d1..0221182250 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-finality-grandpa" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,9 +9,12 @@ repository = "https://github.com/paritytech/substrate/" description = "Integration of the GRANDPA finality gadget into substrate." documentation = "https://docs.rs/sc-finality-grandpa" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -fork-tree = { version = "2.0.0-alpha.5", path = "../../utils/fork-tree" } +fork-tree = { version = "2.0.0-alpha.6", path = "../../utils/fork-tree" } futures = "0.3.4" futures-timer = "3.0.1" log = "0.4.8" @@ -19,40 +22,37 @@ parking_lot = "0.10.0" rand = "0.7.2" assert_matches = "1.3.0" parity-scale-codec = { version = "1.3.0", features = ["derive"] } -sp-arithmetic = { version = "2.0.0-alpha.5", path = "../../primitives/arithmetic" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } -sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } -sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } +sp-arithmetic = { version = "2.0.0-alpha.6", path = "../../primitives/arithmetic" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } +sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } +sc-keystore = { version = "2.0.0-alpha.6", path = "../keystore" } serde_json = "1.0.41" -sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } -sc-client = { version = "0.8.0-alpha.5", path = "../" } -sp-inherents = { version = "2.0.0-alpha.5", path = "../../primitives/inherents" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } -sc-network = { version = "0.8.0-alpha.5", path = "../network" } -sc-network-gossip = { version = "0.8.0-alpha.5", path = "../network-gossip" } -sp-finality-tracker = { version = "2.0.0-alpha.5", path = "../../primitives/finality-tracker" } -sp-finality-grandpa = { version = "2.0.0-alpha.5", path = "../../primitives/finality-grandpa" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.5"} -sc-block-builder = { version = "0.8.0-alpha.5", path = "../block-builder" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } +sc-client = { version = "0.8.0-alpha.6", path = "../" } +sp-inherents = { version = "2.0.0-alpha.6", path = "../../primitives/inherents" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } +sc-network = { version = "0.8.0-alpha.6", path = "../network" } +sc-network-gossip = { version = "0.8.0-alpha.6", path = "../network-gossip" } +sp-finality-tracker = { version = "2.0.0-alpha.6", path = "../../primitives/finality-tracker" } +sp-finality-grandpa = { version = "2.0.0-alpha.6", path = "../../primitives/finality-grandpa" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.6"} +sc-block-builder = { version = "0.8.0-alpha.6", path = "../block-builder" } finality-grandpa = { version = "0.11.2", features = ["derive-codec"] } pin-project = "0.4.6" [dev-dependencies] finality-grandpa = { version = "0.11.2", features = ["derive-codec", "test-helpers"] } -sc-network = { version = "0.8.0-alpha.5", path = "../network" } +sc-network = { version = "0.8.0-alpha.6", path = "../network" } sc-network-test = { version = "0.8.0-dev", path = "../network/test" } -sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } -sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/babe" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } +sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/babe" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } env_logger = "0.7.0" tokio = { version = "0.2", features = ["rt-core"] } tempfile = "3.1.0" -sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } diff --git a/client/informant/Cargo.toml b/client/informant/Cargo.toml index b60886d6de..59e26a6cd3 100644 --- a/client/informant/Cargo.toml +++ b/client/informant/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-informant" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Substrate informant." edition = "2018" @@ -8,17 +8,17 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] ansi_term = "0.12.1" futures = "0.3.4" log = "0.4.8" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } wasm-timer = "0.2" -sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } -sc-network = { version = "0.8.0-alpha.5", path = "../network" } -sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../service" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } +sc-network = { version = "0.8.0-alpha.6", path = "../network" } +sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../service" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } diff --git a/client/keystore/Cargo.toml b/client/keystore/Cargo.toml index af9cdf81bf..11acd2ec6a 100644 --- a/client/keystore/Cargo.toml +++ b/client/keystore/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-keystore" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,11 +9,14 @@ repository = "https://github.com/paritytech/substrate/" description = "Keystore (and session key management) for ed25519 based chains like Polkadot." documentation = "https://docs.rs/sc-keystore" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] derive_more = "0.99.2" -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../primitives/application-crypto" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../primitives/application-crypto" } hex = "0.4.0" rand = "0.7.2" serde_json = "1.0.41" @@ -22,6 +25,3 @@ parking_lot = "0.10.0" [dev-dependencies] tempfile = "3.1.0" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index 75fc6c56bd..50d0eae90d 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Gossiping for the Substrate network protocol" name = "sc-network-gossip" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -9,6 +9,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sc-network-gossip" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] futures = "0.3.4" @@ -16,13 +19,10 @@ futures-timer = "3.0.1" libp2p = { version = "0.18.0", default-features = false, features = ["websocket"] } log = "0.4.8" lru = "0.4.3" -sc-network = { version = "0.8.0-alpha.5", path = "../network" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } +sc-network = { version = "0.8.0-alpha.6", path = "../network" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } wasm-timer = "0.2" [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 098fae6018..7b38d07f35 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Substrate network protocol" name = "sc-network" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -10,6 +10,10 @@ repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sc-network" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + + [build-dependencies] prost-build = "0.6.1" @@ -21,7 +25,7 @@ derive_more = "0.99.2" either = "1.5.3" erased-serde = "0.3.9" fnv = "1.0.6" -fork-tree = { version = "2.0.0-alpha.5", path = "../../utils/fork-tree" } +fork-tree = { version = "2.0.0-alpha.6", path = "../../utils/fork-tree" } futures = "0.3.4" futures_codec = "0.3.3" futures-timer = "3.0.1" @@ -35,24 +39,24 @@ parking_lot = "0.10.0" prost = "0.6.1" rand = "0.7.2" hex = "0.4.0" -sc-block-builder = { version = "0.8.0-alpha.5", path = "../block-builder" } -sc-client = { version = "0.8.0-alpha.5", path = "../" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } -sc-peerset = { version = "2.0.0-alpha.5", path = "../peerset" } +sc-block-builder = { version = "0.8.0-alpha.6", path = "../block-builder" } +sc-client = { version = "0.8.0-alpha.6", path = "../" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } +sc-peerset = { version = "2.0.0-alpha.6", path = "../peerset" } pin-project = "0.4.6" serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } slog_derive = "0.2.0" smallvec = "0.6.10" -sp-arithmetic = { version = "2.0.0-alpha.5", path = "../../primitives/arithmetic" } -sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } -sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/babe" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.5", path = "../../utils/prometheus" } +sp-arithmetic = { version = "2.0.0-alpha.6", path = "../../primitives/arithmetic" } +sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } +sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/babe" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.6", path = "../../utils/prometheus" } thiserror = "1" unsigned-varint = { version = "0.3.1", features = ["futures", "futures-codec"] } void = "1.0.2" @@ -70,7 +74,7 @@ env_logger = "0.7.0" libp2p = { version = "0.18.0", default-features = false, features = ["secio"] } quickcheck = "0.9.0" rand = "0.7.2" -sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } sp-test-primitives = { version = "2.0.0-dev", path = "../../primitives/test-primitives" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } @@ -78,7 +82,3 @@ tempfile = "3.1.0" [features] default = [] - - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index bdba0cc205..cd5c60e417 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -9,26 +9,26 @@ publish = false homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sc-network = { version = "0.8.0-alpha.5", path = "../" } +sc-network = { version = "0.8.0-alpha.6", path = "../" } log = "0.4.8" parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" rand = "0.7.2" libp2p = { version = "0.18.0", default-features = false, features = ["libp2p-websocket"] } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } -sc-client = { version = "0.8.0-alpha.5", path = "../../" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sc-block-builder = { version = "0.8.0-alpha.5", path = "../../block-builder" } -sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/babe" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } +sc-client = { version = "0.8.0-alpha.6", path = "../../" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../../api" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sc-block-builder = { version = "0.8.0-alpha.6", path = "../../block-builder" } +sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/babe" } env_logger = "0.7.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../../test-utils/runtime" } tempfile = "3.1.0" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index e7292439e8..3b29f43aef 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -1,32 +1,35 @@ [package] description = "Substrate offchain workers" name = "sc-offchain" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] bytes = "0.5" -sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } -sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } +sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } fnv = "1.0.6" futures = "0.3.4" futures-timer = "3.0.1" log = "0.4.8" threadpool = "1.7" num_cpus = "1.10" -sp-offchain = { version = "2.0.0-alpha.5", path = "../../primitives/offchain" } +sp-offchain = { version = "2.0.0-alpha.6", path = "../../primitives/offchain" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } rand = "0.7.2" -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } -sc-network = { version = "0.8.0-alpha.5", path = "../network" } -sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } +sc-network = { version = "0.8.0-alpha.6", path = "../network" } +sc-keystore = { version = "2.0.0-alpha.6", path = "../keystore" } [target.'cfg(not(target_os = "unknown"))'.dependencies] hyper = "0.13.2" @@ -35,14 +38,11 @@ hyper-rustls = "0.20" [dev-dependencies] env_logger = "0.7.0" fdlimit = "0.1.4" -sc-client-db = { version = "0.8.0-alpha.5", default-features = true, path = "../db/" } -sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../../client/transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } +sc-client-db = { version = "0.8.0-alpha.6", default-features = true, path = "../db/" } +sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } tokio = "0.2" [features] default = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 9385e7487b..1a17701480 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -3,23 +3,23 @@ description = "Connectivity manager based on reputation" homepage = "http://parity.io" license = "GPL-3.0" name = "sc-peerset" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sc-peerset" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] futures = "0.3.4" libp2p = { version = "0.18.0", default-features = false } -sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils"} +sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils"} log = "0.4.8" serde_json = "1.0.41" wasm-timer = "0.2" [dev-dependencies] rand = "0.7.2" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/rpc-api/Cargo.toml b/client/rpc-api/Cargo.toml index 10b4b1746e..e235a9b013 100644 --- a/client/rpc-api/Cargo.toml +++ b/client/rpc-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-rpc-api" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,6 +8,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate RPC interfaces." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0" } derive_more = "0.99.2" @@ -18,14 +21,11 @@ jsonrpc-derive = "14.0.3" jsonrpc-pubsub = "14.0.3" log = "0.4.8" parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-version = { version = "2.0.0-alpha.5", path = "../../primitives/version" } -sp-runtime = { path = "../../primitives/runtime" , version = "2.0.0-alpha.5"} -sp-chain-spec = { path = "../../primitives/chain-spec" , version = "2.0.0-alpha.5"} +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-version = { version = "2.0.0-alpha.6", path = "../../primitives/version" } +sp-runtime = { path = "../../primitives/runtime" , version = "2.0.0-alpha.6"} +sp-chain-spec = { path = "../../primitives/chain-spec" , version = "2.0.0-alpha.6"} serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } -sp-rpc = { version = "2.0.0-alpha.5", path = "../../primitives/rpc" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } +sp-rpc = { version = "2.0.0-alpha.6", path = "../../primitives/rpc" } diff --git a/client/rpc-servers/Cargo.toml b/client/rpc-servers/Cargo.toml index c834d7dbf7..841e7e0831 100644 --- a/client/rpc-servers/Cargo.toml +++ b/client/rpc-servers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-rpc-server" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,17 +8,17 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate RPC servers." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] jsonrpc-core = "14.0.3" pubsub = { package = "jsonrpc-pubsub", version = "14.0.3" } log = "0.4.8" serde = "1.0.101" serde_json = "1.0.41" -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } [target.'cfg(not(target_os = "unknown"))'.dependencies] http = { package = "jsonrpc-http-server", version = "14.0.3" } ws = { package = "jsonrpc-ws-server", version = "14.0.3" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index f852c452d7..0a3f8e4054 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-rpc" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,42 +8,42 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate Client RPC" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sc-rpc-api = { version = "0.8.0-alpha.5", path = "../rpc-api" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } -sc-client = { version = "0.8.0-alpha.5", path = "../" } -sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } +sc-rpc-api = { version = "0.8.0-alpha.6", path = "../rpc-api" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } +sc-client = { version = "0.8.0-alpha.6", path = "../" } +sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.3.0" } futures = { version = "0.3.1", features = ["compat"] } jsonrpc-pubsub = "14.0.3" log = "0.4.8" -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } rpc = { package = "jsonrpc-core", version = "14.0.3" } -sp-version = { version = "2.0.0-alpha.5", path = "../../primitives/version" } +sp-version = { version = "2.0.0-alpha.6", path = "../../primitives/version" } serde_json = "1.0.41" -sp-session = { version = "2.0.0-alpha.5", path = "../../primitives/session" } -sp-offchain = { version = "2.0.0-alpha.5", path = "../../primitives/offchain" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } -sp-rpc = { version = "2.0.0-alpha.5", path = "../../primitives/rpc" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } -sp-chain-spec = { version = "2.0.0-alpha.5", path = "../../primitives/chain-spec" } -sc-executor = { version = "0.8.0-alpha.5", path = "../executor" } -sc-block-builder = { version = "0.8.0-alpha.5", path = "../../client/block-builder" } -sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } +sp-session = { version = "2.0.0-alpha.6", path = "../../primitives/session" } +sp-offchain = { version = "2.0.0-alpha.6", path = "../../primitives/offchain" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } +sp-rpc = { version = "2.0.0-alpha.6", path = "../../primitives/rpc" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } +sp-chain-spec = { version = "2.0.0-alpha.6", path = "../../primitives/chain-spec" } +sc-executor = { version = "0.8.0-alpha.6", path = "../executor" } +sc-block-builder = { version = "0.8.0-alpha.6", path = "../../client/block-builder" } +sc-keystore = { version = "2.0.0-alpha.6", path = "../keystore" } +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } hash-db = { version = "0.15.2", default-features = false } parking_lot = "0.10.0" [dev-dependencies] assert_matches = "1.3.0" futures01 = { package = "futures", version = "0.1.29" } -sc-network = { version = "0.8.0-alpha.5", path = "../network" } -sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } +sc-network = { version = "0.8.0-alpha.6", path = "../network" } +sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } tokio = "0.1.22" -sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../transaction-pool" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../transaction-pool" } diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 634d774a31..b8d1e71097 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-service" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,6 +8,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate service. Starts a thread that spins up the network, client, and extrinsic pool. Manages communication between them." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [features] default = ["rocksdb"] # The RocksDB feature activates the RocksDB database backend. If it is not activated, and you pass @@ -32,32 +35,32 @@ exit-future = "0.2.0" serde = "1.0.101" serde_json = "1.0.41" sysinfo = "0.12.0" -sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } -sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-session = { version = "2.0.0-alpha.5", path = "../../primitives/session" } -sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../primitives/application-crypto" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } -sc-network = { version = "0.8.0-alpha.5", path = "../network" } -sc-chain-spec = { version = "2.0.0-alpha.5", path = "../chain-spec" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } -sc-client = { version = "0.8.0-alpha.5", path = "../" } -sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } -sc-client-db = { version = "0.8.0-alpha.5", path = "../db" } +sc-keystore = { version = "2.0.0-alpha.6", path = "../keystore" } +sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-session = { version = "2.0.0-alpha.6", path = "../../primitives/session" } +sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../primitives/application-crypto" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } +sc-network = { version = "0.8.0-alpha.6", path = "../network" } +sc-chain-spec = { version = "2.0.0-alpha.6", path = "../chain-spec" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } +sc-client = { version = "0.8.0-alpha.6", path = "../" } +sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } +sc-client-db = { version = "0.8.0-alpha.6", path = "../db" } codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-executor = { version = "0.8.0-alpha.5", path = "../executor" } -sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } -sc-rpc-server = { version = "2.0.0-alpha.5", path = "../rpc-servers" } -sc-rpc = { version = "2.0.0-alpha.5", path = "../rpc" } -sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } -sc-offchain = { version = "2.0.0-alpha.5", path = "../offchain" } +sc-executor = { version = "0.8.0-alpha.6", path = "../executor" } +sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../transaction-pool" } +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } +sc-rpc-server = { version = "2.0.0-alpha.6", path = "../rpc-servers" } +sc-rpc = { version = "2.0.0-alpha.6", path = "../rpc" } +sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } +sc-offchain = { version = "2.0.0-alpha.6", path = "../offchain" } parity-multiaddr = { package = "parity-multiaddr", version = "0.7.3" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" , version = "0.8.0-alpha.5"} -sc-tracing = { version = "2.0.0-alpha.5", path = "../tracing" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" , version = "0.8.0-alpha.6"} +sc-tracing = { version = "2.0.0-alpha.6", path = "../tracing" } tracing = "0.1.10" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } @@ -71,9 +74,6 @@ procfs = '0.7.8' [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } -sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/babe" } -grandpa = { version = "0.8.0-alpha.5", package = "sc-finality-grandpa", path = "../finality-grandpa" } -grandpa-primitives = { version = "2.0.0-alpha.5", package = "sp-finality-grandpa", path = "../../primitives/finality-grandpa" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/babe" } +grandpa = { version = "0.8.0-alpha.6", package = "sc-finality-grandpa", path = "../finality-grandpa" } +grandpa-primitives = { version = "2.0.0-alpha.6", package = "sp-finality-grandpa", path = "../../primitives/finality-grandpa" } diff --git a/client/service/test/Cargo.toml b/client/service/test/Cargo.toml index 39c17420bf..79c9899ce0 100644 --- a/client/service/test/Cargo.toml +++ b/client/service/test/Cargo.toml @@ -8,6 +8,9 @@ publish = false homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] tempfile = "3.1.0" tokio = "0.1.22" @@ -16,13 +19,10 @@ log = "0.4.8" env_logger = "0.7.0" fdlimit = "0.1.4" futures = { version = "0.3.1", features = ["compat"] } -sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../../service" } -sc-network = { version = "0.8.0-alpha.5", path = "../../network" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } -sc-client = { version = "0.8.0-alpha.5", path = "../../" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../../service" } +sc-network = { version = "0.8.0-alpha.6", path = "../../network" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } +sc-client = { version = "0.8.0-alpha.6", path = "../../" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../primitives/transaction-pool" } diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index 9da3c4e127..a283ee44b4 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-state-db" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,17 +8,17 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "State database maintenance. Handles canonicalization and pruning in the database." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] parking_lot = "0.10.0" log = "0.4.8" -sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } parity-util-mem = "0.6" parity-util-mem-derive = "0.1.0" [dev-dependencies] env_logger = "0.7.0" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index 5cdc4a870e..50908d6794 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-telemetry" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] description = "Telemetry utils" edition = "2018" @@ -9,6 +9,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sc-telemetry" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] bytes = "0.5" @@ -26,6 +29,3 @@ slog-json = { version = "2.3.0", features = ["nested-values"] } slog-scope = "4.1.2" take_mut = "0.2.2" void = "1.0.2" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/tracing/Cargo.toml b/client/tracing/Cargo.toml index 319526b610..2d5d1592b9 100644 --- a/client/tracing/Cargo.toml +++ b/client/tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-tracing" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -8,6 +8,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Instrumentation implementation for substrate." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] erased-serde = "0.3.9" log = { version = "0.4.8" } @@ -17,10 +20,7 @@ serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } tracing-core = "0.1.7" -sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } +sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } [dev-dependencies] tracing = "0.1.10" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index aeb20e9863..256e307fdf 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-transaction-pool" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,6 +8,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate transaction pool implementation." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0" } derive_more = "0.99.2" @@ -16,23 +19,20 @@ futures-diagnose = "1.0" log = "0.4.8" parking_lot = "0.10.0" wasm-timer = "0.2" -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } -sc-transaction-graph = { version = "2.0.0-alpha.5", path = "./graph" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } +sc-transaction-graph = { version = "2.0.0-alpha.6", path = "./graph" } +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } intervalier = "0.4.0" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] assert_matches = "1.3.0" hex = "0.4" -sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } substrate-test-runtime-transaction-pool = { version = "2.0.0-dev", path = "../../test-utils/runtime/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index df2fd8546a..11df8791ac 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-transaction-graph" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,6 +8,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Generic Transaction Pool" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] derive_more = "0.99.2" futures = "0.3.4" @@ -15,11 +18,11 @@ log = "0.4.8" parking_lot = "0.10.0" serde = { version = "1.0.101", features = ["derive"] } wasm-timer = "0.2" -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } -sp-utils = { version = "2.0.0-alpha.5", path = "../../../primitives/utils" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +sp-utils = { version = "2.0.0-alpha.6", path = "../../../primitives/utils" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../primitives/transaction-pool" } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } linked-hash-map = "0.5.2" @@ -32,6 +35,3 @@ criterion = "0.3" [[bench]] name = "basics" harness = false - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 49d47d611c..b0b9ca9f6c 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -6,10 +6,46 @@ The format is based on [Keep a Changelog]. ## Unreleased -### Changed +## 2.0.0-alpha.5 -> 2.0.0-alpha.6 + + +Runtime +------- + +* Unsigned Validation best practices (#5563) +* Generate Unit Tests for Benchmarks (#5527) +* Mandate weight annotation (#5357) +* Make Staking pallet using a proper Time module. (#4662) +* Pass transaction source to validate_transaction (#5366) +* on_initialize return weight consumed and default cost to default DispatchInfo instead of zero (#5382) + +Client +------ + +* Add new RPC method to get the chain type (#5576) +* Reuse wasmtime instances, the PR (#5567) +* Prometheus Metrics: Turn notifications_total counter into notifications_sizes histogram (#5535) +* Make verbosity level mandatory with telemetry opt (#5057) +* Additional Metrics collected and exposed via prometheus (#5414) +* Switch to new light client protocol (#5472) +* client/finality-grandpa: Instrument until-imported queue (#5438) +* Batch benchmarks together with `*` notation. (#5436) +* src/service/src/builder: Fix memory metric exposed in bytes not KiB (#5459) +* Make transactions and block announces use notifications substre… (#5360) +* Adds state_queryStorageAt (#5362) +* Offchain Phragmén BREAKING. (#4517) * `sc_rpc::system::SystemInfo.impl_version` now returns the full version (2.0.0-alpha.2-b950f731c-x86_64-linux-gnu) instead of the short version (1.0.0) (#5271) +API +--- + +* Unsigned Validation best practices (#5563) +* Split the Roles in three types (#5520) +* Pass transaction source to validate_transaction (#5366) +* on_initialize return weight consumed and default cost to default DispatchInfo instead of zero (#5382) + + ## 2.0.0-alpha.4 -> 2.0.0-alpha.5 Runtime diff --git a/frame/assets/Cargo.toml b/frame/assets/Cargo.toml index 8b242ff0e8..978400b7b9 100644 --- a/frame/assets/Cargo.toml +++ b/frame/assets/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-assets" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,20 +8,23 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME asset management pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } # Needed for various traits. In our case, `OnFinalize`. -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } # Needed for type-safe access to storage DB. -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } # `system` module provides us with all sorts of useful stuff and macros depend on it being around. -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.5", path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.6", path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } [features] default = ["std"] @@ -32,6 +35,3 @@ std = [ "frame-support/std", "frame-system/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/aura/Cargo.toml b/frame/aura/Cargo.toml index 36e7911661..6aa71d6465 100644 --- a/frame/aura/Cargo.toml +++ b/frame/aura/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-aura" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,21 +8,24 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME AURA consensus pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/application-crypto" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../session" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -sp-consensus-aura = { path = "../../primitives/consensus/aura", default-features = false, version = "0.8.0-alpha.5"} -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/timestamp" } -pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../timestamp" } +pallet-session = { version = "2.0.0-alpha.6", default-features = false, path = "../session" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +sp-consensus-aura = { path = "../../primitives/consensus/aura", default-features = false, version = "0.8.0-alpha.6"} +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/timestamp" } +pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../timestamp" } [dev-dependencies] @@ -46,6 +49,3 @@ std = [ "sp-timestamp/std", "pallet-timestamp/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/authority-discovery/Cargo.toml b/frame/authority-discovery/Cargo.toml index f67d4ee038..094599d998 100644 --- a/frame/authority-discovery/Cargo.toml +++ b/frame/authority-discovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-authority-discovery" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,21 +8,24 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for authority discovery" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-authority-discovery = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/authority-discovery" } -sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/application-crypto" } +sp-authority-discovery = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/authority-discovery" } +sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/application-crypto" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -pallet-session = { version = "2.0.0-alpha.5", features = ["historical" ], path = "../session", default-features = false } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +pallet-session = { version = "2.0.0-alpha.6", features = ["historical" ], path = "../session", default-features = false } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] -sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } +sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } [features] default = ["std"] @@ -39,6 +42,3 @@ std = [ "frame-support/std", "frame-system/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/authorship/Cargo.toml b/frame/authorship/Cargo.toml index fb966113d5..db1df713ce 100644 --- a/frame/authorship/Cargo.toml +++ b/frame/authorship/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-authorship" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" description = "Block and Uncle Author tracking for the FRAME" authors = ["Parity Technologies "] edition = "2018" @@ -8,16 +8,19 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } -sp-authorship = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/authorship" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } +sp-authorship = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/authorship" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} impl-trait-for-tuples = "0.1.3" [features] @@ -33,6 +36,3 @@ std = [ "sp-io/std", "sp-authorship/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/babe/Cargo.toml b/frame/babe/Cargo.toml index 8f88550022..e0986cf725 100644 --- a/frame/babe/Cargo.toml +++ b/frame/babe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-babe" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,24 +8,27 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Consensus extension module for BABE consensus. Collects on-chain randomness from VRF outputs and manages epoch transitions." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../timestamp" } -sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/timestamp" } -pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../session" } -sp-consensus-babe = { version = "0.8.0-alpha.5", default-features = false, path = "../../primitives/consensus/babe" } -sp-consensus-vrf = { version = "0.8.0-alpha.5", default-features = false, path = "../../primitives/consensus/vrf" } -sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../timestamp" } +sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/timestamp" } +pallet-session = { version = "2.0.0-alpha.6", default-features = false, path = "../session" } +sp-consensus-babe = { version = "0.8.0-alpha.6", default-features = false, path = "../../primitives/consensus/babe" } +sp-consensus-vrf = { version = "0.8.0-alpha.6", default-features = false, path = "../../primitives/consensus/vrf" } +sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } [features] default = ["std"] @@ -45,6 +48,3 @@ std = [ "pallet-session/std", "sp-io/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/balances/Cargo.toml b/frame/balances/Cargo.toml index f8a59ad154..00cc57eb4f 100644 --- a/frame/balances/Cargo.toml +++ b/frame/balances/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-balances" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,19 +8,22 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet to manage balances" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../transaction-payment" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +pallet-transaction-payment = { version = "2.0.0-alpha.6", path = "../transaction-payment" } [features] default = ["std"] @@ -35,6 +38,3 @@ std = [ "frame-system/std", ] runtime-benchmarks = ["frame-benchmarking"] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/benchmark/Cargo.toml b/frame/benchmark/Cargo.toml index 804a283704..ae00507bc0 100644 --- a/frame/benchmark/Cargo.toml +++ b/frame/benchmark/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-benchmark" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,15 +8,18 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Patterns to benchmark in a FRAME runtime." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } [features] default = ["std"] @@ -31,6 +34,3 @@ std = [ "frame-benchmarking/std", ] runtime-benchmarks = ["frame-benchmarking"] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/benchmarking/Cargo.toml b/frame/benchmarking/Cargo.toml index 3221c7a1d4..80a04867aa 100644 --- a/frame/benchmarking/Cargo.toml +++ b/frame/benchmarking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-benchmarking" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,17 +8,20 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Macro for benchmarking a FRAME runtime." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] linregress = "0.1" paste = "0.1" codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api", default-features = false } -sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../primitives/runtime-interface", default-features = false } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime", default-features = false } -sp-std = { version = "2.0.0-alpha.5", path = "../../primitives/std", default-features = false } -sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.5"} -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api", default-features = false } +sp-runtime-interface = { version = "2.0.0-alpha.6", path = "../../primitives/runtime-interface", default-features = false } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime", default-features = false } +sp-std = { version = "2.0.0-alpha.6", path = "../../primitives/std", default-features = false } +sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.6"} +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [features] default = [ "std" ] @@ -31,6 +34,3 @@ std = [ "frame-support/std", "frame-system/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/collective/Cargo.toml b/frame/collective/Cargo.toml index 113705c2c8..44152b9830 100644 --- a/frame/collective/Cargo.toml +++ b/frame/collective/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-collective" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,20 +8,23 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Collective system: Members of a set of account IDs can make their collective feelings known through dispatched calls from one of two specialized origins." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } [features] default = ["std"] @@ -40,6 +43,3 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "frame-system/runtime-benchmarks", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/contracts/Cargo.toml b/frame/contracts/Cargo.toml index a9318002ce..efcbb196b7 100644 --- a/frame/contracts/Cargo.toml +++ b/frame/contracts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,28 +8,31 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for WASM contracts" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } pwasm-utils = { version = "0.12.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } parity-wasm = { version = "0.41.0", default-features = false } wasmi-validation = { version = "0.3.0", default-features = false } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-sandbox = { version = "0.8.0-alpha.5", default-features = false, path = "../../primitives/sandbox" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -pallet-contracts-primitives = { version = "2.0.0-alpha.5", default-features = false, path = "common" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-sandbox = { version = "0.8.0-alpha.6", default-features = false, path = "../../primitives/sandbox" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +pallet-contracts-primitives = { version = "2.0.0-alpha.6", default-features = false, path = "common" } [dev-dependencies] wabt = "0.9.2" assert_matches = "1.3.0" hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } -pallet-timestamp = { version = "2.0.0-alpha.5", path = "../timestamp" } -pallet-randomness-collective-flip = { version = "2.0.0-alpha.5", path = "../randomness-collective-flip" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +pallet-timestamp = { version = "2.0.0-alpha.6", path = "../timestamp" } +pallet-randomness-collective-flip = { version = "2.0.0-alpha.6", path = "../randomness-collective-flip" } [features] default = ["std"] @@ -48,6 +51,3 @@ std = [ "wasmi-validation/std", "pallet-contracts-primitives/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/contracts/common/Cargo.toml b/frame/contracts/common/Cargo.toml index d181896bd2..42127860f1 100644 --- a/frame/contracts/common/Cargo.toml +++ b/frame/contracts/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts-primitives" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,11 +8,14 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "A crate that hosts a common definitions that are relevant for the pallet-contracts." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] # This crate should not rely on any of the frame primitives. codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } [features] default = ["std"] @@ -21,6 +24,3 @@ std = [ "sp-runtime/std", "sp-std/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/contracts/rpc/Cargo.toml b/frame/contracts/rpc/Cargo.toml index fa13d8ec3f..f6af065f77 100644 --- a/frame/contracts/rpc/Cargo.toml +++ b/frame/contracts/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts-rpc" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,22 +8,22 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Node-specific RPC methods for interaction with contracts." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.3" -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-rpc = { version = "2.0.0-alpha.5", path = "../../../primitives/rpc" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-rpc = { version = "2.0.0-alpha.6", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } -pallet-contracts-primitives = { version = "2.0.0-alpha.5", path = "../common" } -pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.5", path = "./runtime-api" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } +pallet-contracts-primitives = { version = "2.0.0-alpha.6", path = "../common" } +pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.6", path = "./runtime-api" } [dev-dependencies] serde_json = "1.0.41" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/contracts/rpc/runtime-api/Cargo.toml b/frame/contracts/rpc/runtime-api/Cargo.toml index 692bd3f25e..0798f2fa24 100644 --- a/frame/contracts/rpc/runtime-api/Cargo.toml +++ b/frame/contracts/rpc/runtime-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts-rpc-runtime-api" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,12 +8,15 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Runtime API definition required by Contracts RPC extensions." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/api" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/runtime" } -pallet-contracts-primitives = { version = "2.0.0-alpha.5", default-features = false, path = "../../common" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/runtime" } +pallet-contracts-primitives = { version = "2.0.0-alpha.6", default-features = false, path = "../../common" } [features] default = ["std"] @@ -24,6 +27,3 @@ std = [ "sp-runtime/std", "pallet-contracts-primitives/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/democracy/Cargo.toml b/frame/democracy/Cargo.toml index 7886457644..7e46998ba9 100644 --- a/frame/democracy/Cargo.toml +++ b/frame/democracy/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-democracy" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,21 +8,24 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for democracy" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } -pallet-scheduler = { version = "2.0.0-alpha.5", path = "../scheduler" } -sp-storage = { version = "2.0.0-alpha.5", path = "../../primitives/storage" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +pallet-scheduler = { version = "2.0.0-alpha.6", path = "../scheduler" } +sp-storage = { version = "2.0.0-alpha.6", path = "../../primitives/storage" } hex-literal = "0.2.1" [features] @@ -42,6 +45,3 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index fb219bbebc..662dd1d16e 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-elections-phragmen" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,22 +8,25 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME election pallet for PHRAGMEN" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-phragmen = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/phragmen" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-phragmen = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/phragmen" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } +sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } -pallet-scheduler = { version = "2.0.0-alpha.5", path = "../scheduler" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -substrate-test-utils = { version = "2.0.0-alpha.5", path = "../../test-utils" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +pallet-scheduler = { version = "2.0.0-alpha.6", path = "../scheduler" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +substrate-test-utils = { version = "2.0.0-alpha.6", path = "../../test-utils" } [features] default = ["std"] @@ -37,6 +40,3 @@ std = [ "sp-std/std", ] runtime-benchmarks = ["frame-support/runtime-benchmarks"] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/elections/Cargo.toml b/frame/elections/Cargo.toml index 6043ac4681..fecd0be0ba 100644 --- a/frame/elections/Cargo.toml +++ b/frame/elections/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-elections" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,19 +8,22 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for elections" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } [features] default = ["std"] @@ -34,6 +37,3 @@ std = [ "sp-runtime/std", "frame-system/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml index 95b3c24d87..0e19dc7fd3 100644 --- a/frame/evm/Cargo.toml +++ b/frame/evm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-evm" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,17 +8,20 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME EVM contracts pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../timestamp" } -pallet-balances = { version = "2.0.0-alpha.5", default-features = false, path = "../balances" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../timestamp" } +pallet-balances = { version = "2.0.0-alpha.6", default-features = false, path = "../balances" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } primitive-types = { version = "0.7.0", default-features = false, features = ["rlp"] } rlp = { version = "0.4", default-features = false } evm = { version = "0.16", default-features = false } @@ -42,6 +45,3 @@ std = [ "evm/std", "pallet-timestamp/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/example-offchain-worker/Cargo.toml b/frame/example-offchain-worker/Cargo.toml index 6b3452d018..11201b23ce 100644 --- a/frame/example-offchain-worker/Cargo.toml +++ b/frame/example-offchain-worker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-example-offchain-worker" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "Unlicense" @@ -8,15 +8,18 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME example pallet for offchain worker" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } serde = { version = "1.0.101", optional = true } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } lite-json = { version = "0.1", default-features = false } [features] @@ -32,6 +35,3 @@ std = [ "sp-runtime/std", "sp-std/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/example/Cargo.toml b/frame/example/Cargo.toml index 4053cc0b1a..34b4e8c585 100644 --- a/frame/example/Cargo.toml +++ b/frame/example/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-example" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "Unlicense" @@ -8,20 +8,23 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME example pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -pallet-balances = { version = "2.0.0-alpha.5", default-features = false, path = "../balances" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +pallet-balances = { version = "2.0.0-alpha.6", default-features = false, path = "../balances" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core", default-features = false } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core", default-features = false } [features] default = ["std"] @@ -37,6 +40,3 @@ std = [ "sp-std/std" ] runtime-benchmarks = ["frame-benchmarking"] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/executive/Cargo.toml b/frame/executive/Cargo.toml index 3c494199cb..8a07f26ba7 100644 --- a/frame/executive/Cargo.toml +++ b/frame/executive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-executive" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,22 +8,25 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME executives engine" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } serde = { version = "1.0.101", optional = true } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } [dev-dependencies] hex-literal = "0.2.1" -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-io ={ path = "../../primitives/io", version = "2.0.0-alpha.5"} -pallet-indices = { version = "2.0.0-alpha.5", path = "../indices" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } -pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../transaction-payment" } -sp-version = { version = "2.0.0-alpha.5", path = "../../primitives/version" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-io ={ path = "../../primitives/io", version = "2.0.0-alpha.6"} +pallet-indices = { version = "2.0.0-alpha.6", path = "../indices" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +pallet-transaction-payment = { version = "2.0.0-alpha.6", path = "../transaction-payment" } +sp-version = { version = "2.0.0-alpha.6", path = "../../primitives/version" } [features] default = ["std"] @@ -35,6 +38,3 @@ std = [ "sp-runtime/std", "sp-std/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/finality-tracker/Cargo.toml b/frame/finality-tracker/Cargo.toml index e261fae05f..ebb6767f77 100644 --- a/frame/finality-tracker/Cargo.toml +++ b/frame/finality-tracker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-finality-tracker" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,21 +9,24 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME Pallet that tracks the last finalized block, as perceived by block authors." documentation = "https://docs.rs/pallet-finality-tracker" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-finality-tracker = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/finality-tracker" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-finality-tracker = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/finality-tracker" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } [features] default = ["std"] @@ -37,6 +40,3 @@ std = [ "sp-finality-tracker/std", "sp-inherents/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/generic-asset/Cargo.toml b/frame/generic-asset/Cargo.toml index b531a0ed9a..e4161c5b25 100644 --- a/frame/generic-asset/Cargo.toml +++ b/frame/generic-asset/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-generic-asset" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Centrality Developers "] edition = "2018" license = "GPL-3.0" @@ -8,17 +8,20 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for generic asset management" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.5", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-alpha.6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } [features] default = ["std"] @@ -30,6 +33,3 @@ std =[ "frame-support/std", "frame-system/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/grandpa/Cargo.toml b/frame/grandpa/Cargo.toml index 206b563bd9..ff33dff497 100644 --- a/frame/grandpa/Cargo.toml +++ b/frame/grandpa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-grandpa" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,21 +8,24 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for GRANDPA finality gadget" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-finality-grandpa = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/finality-grandpa" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../session" } -pallet-finality-tracker = { version = "2.0.0-alpha.5", default-features = false, path = "../finality-tracker" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-finality-grandpa = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/finality-grandpa" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-alpha.6", default-features = false, path = "../session" } +pallet-finality-tracker = { version = "2.0.0-alpha.6", default-features = false, path = "../finality-tracker" } [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.5", path = "../../primitives/io" } +sp-io ={ version = "2.0.0-alpha.6", path = "../../primitives/io" } [features] default = ["std"] @@ -39,6 +42,3 @@ std = [ "pallet-session/std", "pallet-finality-tracker/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/identity/Cargo.toml b/frame/identity/Cargo.toml index 22b385d06d..73b2d843f4 100644 --- a/frame/identity/Cargo.toml +++ b/frame/identity/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-identity" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,20 +8,23 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME identity management pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } [features] default = ["std"] @@ -36,6 +39,3 @@ std = [ "frame-system/std", ] runtime-benchmarks = ["frame-benchmarking"] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/im-online/Cargo.toml b/frame/im-online/Cargo.toml index dabcc45ef1..6895728a4d 100644 --- a/frame/im-online/Cargo.toml +++ b/frame/im-online/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-im-online" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,21 +8,24 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME's I'm online pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/application-crypto" } -pallet-authorship = { version = "2.0.0-alpha.5", default-features = false, path = "../authorship" } +sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/application-crypto" } +pallet-authorship = { version = "2.0.0-alpha.6", default-features = false, path = "../authorship" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../session" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-alpha.6", default-features = false, path = "../session" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } [features] default = ["std", "pallet-session/historical"] @@ -41,6 +44,3 @@ std = [ "frame-system/std", ] runtime-benchmarks = ["frame-benchmarking"] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/indices/Cargo.toml b/frame/indices/Cargo.toml index f28f393642..d217a1e606 100644 --- a/frame/indices/Cargo.toml +++ b/frame/indices/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-indices" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,19 +8,22 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME indices management pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-keyring = { version = "2.0.0-alpha.5", optional = true, path = "../../primitives/keyring" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-keyring = { version = "2.0.0-alpha.6", optional = true, path = "../../primitives/keyring" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } [features] default = ["std"] @@ -35,6 +38,3 @@ std = [ "sp-runtime/std", "frame-system/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/membership/Cargo.toml b/frame/membership/Cargo.toml index 41e56b584f..eeee5c0f85 100644 --- a/frame/membership/Cargo.toml +++ b/frame/membership/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-membership" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,17 +8,20 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME membership management pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } [features] default = ["std"] @@ -31,6 +34,3 @@ std = [ "frame-support/std", "frame-system/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/metadata/Cargo.toml b/frame/metadata/Cargo.toml index f965e1dddc..d68c8de342 100644 --- a/frame/metadata/Cargo.toml +++ b/frame/metadata/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-metadata" -version = "11.0.0-alpha.5" +version = "11.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,11 +8,14 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Decodable variant of the RuntimeMetadata." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } [features] default = ["std"] @@ -22,6 +25,3 @@ std = [ "sp-core/std", "serde", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/nicks/Cargo.toml b/frame/nicks/Cargo.toml index ea88021d25..7dacabb99a 100644 --- a/frame/nicks/Cargo.toml +++ b/frame/nicks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-nicks" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,18 +8,21 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for nick management" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } [features] default = ["std"] @@ -32,6 +35,3 @@ std = [ "frame-support/std", "frame-system/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/offences/Cargo.toml b/frame/offences/Cargo.toml index eab95dbd04..e9df75d835 100644 --- a/frame/offences/Cargo.toml +++ b/frame/offences/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-offences" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,19 +8,22 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME offences pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -pallet-balances = { version = "2.0.0-alpha.5", default-features = false, path = "../balances" } +pallet-balances = { version = "2.0.0-alpha.6", default-features = false, path = "../balances" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } [features] default = ["std"] @@ -35,6 +38,3 @@ std = [ "frame-system/std", ] runtime-benchmarks = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/offences/benchmarking/Cargo.toml b/frame/offences/benchmarking/Cargo.toml index e343f1ff0c..f04ea3c5be 100644 --- a/frame/offences/benchmarking/Cargo.toml +++ b/frame/offences/benchmarking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-offences-benchmarking" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,20 +8,23 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME offences pallet benchmarking" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" } -sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/staking" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../../benchmarking" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../../system" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../support" } -pallet-im-online = { version = "2.0.0-alpha.5", default-features = false, path = "../../im-online" } -pallet-offences = { version = "2.0.0-alpha.5", default-features = false, features = ["runtime-benchmarks"], path = "../../offences" } -pallet-staking = { version = "2.0.0-alpha.5", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } -pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../../session" } -sp-io = { path = "../../../primitives/io", default-features = false, version = "2.0.0-alpha.5"} +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/std" } +sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/staking" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../../benchmarking" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../../system" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../support" } +pallet-im-online = { version = "2.0.0-alpha.6", default-features = false, path = "../../im-online" } +pallet-offences = { version = "2.0.0-alpha.6", default-features = false, features = ["runtime-benchmarks"], path = "../../offences" } +pallet-staking = { version = "2.0.0-alpha.6", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } +pallet-session = { version = "2.0.0-alpha.6", default-features = false, path = "../../session" } +sp-io = { path = "../../../primitives/io", default-features = false, version = "2.0.0-alpha.6"} [features] @@ -38,6 +41,3 @@ std = [ "pallet-staking/std", "pallet-session/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/randomness-collective-flip/Cargo.toml b/frame/randomness-collective-flip/Cargo.toml index acd1c21688..330b604393 100644 --- a/frame/randomness-collective-flip/Cargo.toml +++ b/frame/randomness-collective-flip/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-randomness-collective-flip" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,17 +8,20 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME randomness collective flip pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] safe-mix = { version = "1.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } [features] default = ["std"] @@ -30,6 +33,3 @@ std = [ "sp-runtime/std", "sp-std/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/recovery/Cargo.toml b/frame/recovery/Cargo.toml index 3347014f6e..02ce71b1d8 100644 --- a/frame/recovery/Cargo.toml +++ b/frame/recovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-recovery" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,19 +8,22 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME account recovery pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } [features] default = ["std"] @@ -33,6 +36,3 @@ std = [ "frame-support/std", "frame-system/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/scheduler/Cargo.toml b/frame/scheduler/Cargo.toml index 531de95867..534d42710f 100644 --- a/frame/scheduler/Cargo.toml +++ b/frame/scheduler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-scheduler" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "Unlicense" @@ -11,15 +11,15 @@ description = "FRAME example pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking" } -frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } -sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core", default-features = false } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core", default-features = false } [features] default = ["std"] diff --git a/frame/scored-pool/Cargo.toml b/frame/scored-pool/Cargo.toml index b878c5bb47..8341098647 100644 --- a/frame/scored-pool/Cargo.toml +++ b/frame/scored-pool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-scored-pool" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,18 +8,21 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for scored pools" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } [features] default = ["std"] @@ -32,6 +35,3 @@ std = [ "frame-support/std", "frame-system/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/session/Cargo.toml b/frame/session/Cargo.toml index f12a8b4a71..b4f10c7eb8 100644 --- a/frame/session/Cargo.toml +++ b/frame/session/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-session" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,22 +8,25 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME sessions pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../timestamp" } -sp-trie = { optional = true, path = "../../primitives/trie", default-features = false, version = "2.0.0-alpha.5"} -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../timestamp" } +sp-trie = { optional = true, path = "../../primitives/trie", default-features = false, version = "2.0.0-alpha.6"} +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../primitives/application-crypto" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../primitives/application-crypto" } lazy_static = "1.4.0" [features] @@ -40,6 +43,3 @@ std = [ "sp-trie/std", "sp-io/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/session/benchmarking/Cargo.toml b/frame/session/benchmarking/Cargo.toml index 140116c82c..cc590b4bb2 100644 --- a/frame/session/benchmarking/Cargo.toml +++ b/frame/session/benchmarking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-session-benchmarking" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,23 +8,26 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME sessions pallet benchmarking" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../../system" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../../benchmarking" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../support" } -pallet-staking = { version = "2.0.0-alpha.5", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } -pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../../session" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../../system" } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../../benchmarking" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../support" } +pallet-staking = { version = "2.0.0-alpha.6", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } +pallet-session = { version = "2.0.0-alpha.6", default-features = false, path = "../../session" } [dev-dependencies] serde = { version = "1.0.101" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -pallet-staking-reward-curve = { version = "2.0.0-alpha.5", path = "../../staking/reward-curve" } -sp-io ={ path = "../../../primitives/io", version = "2.0.0-alpha.5"} -pallet-timestamp = { version = "2.0.0-alpha.5", path = "../../timestamp" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../../balances" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +pallet-staking-reward-curve = { version = "2.0.0-alpha.6", path = "../../staking/reward-curve" } +sp-io ={ path = "../../../primitives/io", version = "2.0.0-alpha.6"} +pallet-timestamp = { version = "2.0.0-alpha.6", path = "../../timestamp" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../../balances" } [features] default = ["std"] @@ -37,6 +40,3 @@ std = [ "pallet-staking/std", "pallet-session/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/society/Cargo.toml b/frame/society/Cargo.toml index be419fb63f..da38ec5e75 100644 --- a/frame/society/Cargo.toml +++ b/frame/society/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-society" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,19 +8,22 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME society pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } rand_chacha = { version = "0.2", default-features = false } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } [features] default = ["std"] @@ -38,6 +41,3 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "frame-system/runtime-benchmarks", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index aac5616e4e..29b6476495 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-staking" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,38 +8,41 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet staking" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-phragmen = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/phragmen" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -pallet-session = { version = "2.0.0-alpha.5", features = ["historical"], path = "../session", default-features = false } -pallet-authorship = { version = "2.0.0-alpha.5", default-features = false, path = "../authorship" } -sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/application-crypto" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-phragmen = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/phragmen" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-alpha.6", features = ["historical"], path = "../session", default-features = false } +pallet-authorship = { version = "2.0.0-alpha.6", default-features = false, path = "../authorship" } +sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/application-crypto" } static_assertions = "1.1.0" # Optional imports for tesing-utils feature -pallet-indices = { version = "2.0.0-alpha.4", optional = true, path = "../indices", default-features = false } -sp-core = { version = "2.0.0-alpha.4", optional = true, path = "../../primitives/core", default-features = false } +pallet-indices = { version = "2.0.0-alpha.6", optional = true, path = "../indices", default-features = false } +sp-core = { version = "2.0.0-alpha.6", optional = true, path = "../../primitives/core", default-features = false } rand = { version = "0.7.3", optional = true, default-features = false } # Optional imports for benchmarking -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } rand_chacha = { version = "0.2", default-features = false, optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-storage = { version = "2.0.0-alpha.5", path = "../../primitives/storage" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } -pallet-timestamp = { version = "2.0.0-alpha.5", path = "../timestamp" } -pallet-staking-reward-curve = { version = "2.0.0-alpha.5", path = "../staking/reward-curve" } -substrate-test-utils = { version = "2.0.0-alpha.5", path = "../../test-utils" } -frame-benchmarking = { version = "2.0.0-alpha.5", path = "../benchmarking" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-storage = { version = "2.0.0-alpha.6", path = "../../primitives/storage" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +pallet-timestamp = { version = "2.0.0-alpha.6", path = "../timestamp" } +pallet-staking-reward-curve = { version = "2.0.0-alpha.6", path = "../staking/reward-curve" } +substrate-test-utils = { version = "2.0.0-alpha.6", path = "../../test-utils" } +frame-benchmarking = { version = "2.0.0-alpha.6", path = "../benchmarking" } rand_chacha = { version = "0.2" } parking_lot = "0.10.0" env_logger = "0.7.1" @@ -72,6 +75,3 @@ runtime-benchmarks = [ "rand_chacha", "frame-benchmarking", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/staking/reward-curve/Cargo.toml b/frame/staking/reward-curve/Cargo.toml index b3b749e96c..fc95ccac79 100644 --- a/frame/staking/reward-curve/Cargo.toml +++ b/frame/staking/reward-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-staking-reward-curve" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,6 +8,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Reward Curve for FRAME staking pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [lib] proc-macro = true @@ -18,7 +21,4 @@ proc-macro2 = "1.0.6" proc-macro-crate = "0.1.4" [dev-dependencies] -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } diff --git a/frame/sudo/Cargo.toml b/frame/sudo/Cargo.toml index 4216b94ec1..295f723ca3 100644 --- a/frame/sudo/Cargo.toml +++ b/frame/sudo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-sudo" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,17 +8,20 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for sudo" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } [features] default = ["std"] @@ -31,6 +34,3 @@ std = [ "frame-support/std", "frame-system/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index 3bad72a115..23e0744a5c 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,28 +8,31 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Support code for the runtime." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] log = "0.4" serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -frame-metadata = { version = "11.0.0-alpha.5", default-features = false, path = "../metadata" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-arithmetic = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/arithmetic" } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } -frame-support-procedural = { version = "2.0.0-alpha.5", path = "./procedural" } +frame-metadata = { version = "11.0.0-alpha.6", default-features = false, path = "../metadata" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-arithmetic = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/arithmetic" } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } +frame-support-procedural = { version = "2.0.0-alpha.6", path = "./procedural" } paste = "0.1.6" once_cell = { version = "1", default-features = false, optional = true } -sp-state-machine = { version = "0.8.0-alpha.5", optional = true, path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-alpha.6", optional = true, path = "../../primitives/state-machine" } bitmask = { version = "0.5.0", default-features = false } impl-trait-for-tuples = "0.1.3" tracing = { version = "0.1.10", optional = true } [dev-dependencies] pretty_assertions = "0.6.1" -frame-system = { version = "2.0.0-alpha.5", path = "../system" } +frame-system = { version = "2.0.0-alpha.6", path = "../system" } [features] default = ["std"] @@ -50,6 +53,3 @@ std = [ nightly = [] strict = [] runtime-benchmarks = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/support/procedural/Cargo.toml b/frame/support/procedural/Cargo.toml index 2f7450e4b8..9b9f888d96 100644 --- a/frame/support/procedural/Cargo.toml +++ b/frame/support/procedural/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support-procedural" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,14 +8,14 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Proc macro of Support code for the runtime." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [lib] proc-macro = true [dependencies] -frame-support-procedural-tools = { version = "2.0.0-alpha.5", path = "./tools" } +frame-support-procedural-tools = { version = "2.0.0-alpha.6", path = "./tools" } proc-macro2 = "1.0.6" quote = "1.0.3" syn = { version = "1.0.7", features = ["full"] } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/support/procedural/tools/Cargo.toml b/frame/support/procedural/tools/Cargo.toml index f199f1245d..a5c07223a1 100644 --- a/frame/support/procedural/tools/Cargo.toml +++ b/frame/support/procedural/tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support-procedural-tools" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,12 +8,12 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Proc macro helpers for procedural macros" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -frame-support-procedural-tools-derive = { version = "2.0.0-alpha.5", path = "./derive" } +frame-support-procedural-tools-derive = { version = "2.0.0-alpha.6", path = "./derive" } proc-macro2 = "1.0.6" quote = "1.0.3" syn = { version = "1.0.7", features = ["full", "visit"] } proc-macro-crate = "0.1.4" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/support/procedural/tools/derive/Cargo.toml b/frame/support/procedural/tools/derive/Cargo.toml index bf6346ab1b..2615ef2121 100644 --- a/frame/support/procedural/tools/derive/Cargo.toml +++ b/frame/support/procedural/tools/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support-procedural-tools-derive" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,6 +8,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Use to derive parsing for parsing struct." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [lib] proc-macro = true @@ -15,6 +18,3 @@ proc-macro = true proc-macro2 = "1.0.6" quote = { version = "1.0.3", features = ["proc-macro"] } syn = { version = "1.0.7", features = ["proc-macro" ,"full", "extra-traits", "parsing"] } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index 773523579b..61b22f24f5 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -8,15 +8,18 @@ publish = false homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-io ={ path = "../../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} -sp-state-machine = { version = "0.8.0-alpha.5", optional = true, path = "../../../primitives/state-machine" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../" } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/inherents" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/core" } +sp-io ={ path = "../../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} +sp-state-machine = { version = "0.8.0-alpha.6", optional = true, path = "../../../primitives/state-machine" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../" } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/inherents" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/core" } trybuild = "1.0.17" pretty_assertions = "0.6.1" @@ -32,6 +35,3 @@ std = [ "sp-runtime/std", "sp-state-machine", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/system/Cargo.toml b/frame/system/Cargo.toml index 78288cff91..f4c6458d5d 100644 --- a/frame/system/Cargo.toml +++ b/frame/system/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-system" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,20 +8,23 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME system module" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.5"} -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/version" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.6"} +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-version = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/version" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] criterion = "0.2.11" -sp-externalities = { version = "0.8.0-alpha.5", path = "../../primitives/externalities" } +sp-externalities = { version = "0.8.0-alpha.6", path = "../../primitives/externalities" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } [features] @@ -41,6 +44,3 @@ runtime-benchmarks = ["sp-runtime/runtime-benchmarks"] [[bench]] name = "bench" harness = false - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/system/rpc/runtime-api/Cargo.toml b/frame/system/rpc/runtime-api/Cargo.toml index 9519427297..18aad0d59c 100644 --- a/frame/system/rpc/runtime-api/Cargo.toml +++ b/frame/system/rpc/runtime-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-system-rpc-runtime-api" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,8 +8,11 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Runtime API definition required by System RPC extensions." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/api" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } [features] @@ -18,6 +21,3 @@ std = [ "sp-api/std", "codec/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/timestamp/Cargo.toml b/frame/timestamp/Cargo.toml index eb7358e197..335ae8d9f8 100644 --- a/frame/timestamp/Cargo.toml +++ b/frame/timestamp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-timestamp" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,23 +9,26 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME Timestamp Module" documentation = "https://docs.rs/pallet-timestamp" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io", optional = true } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/timestamp" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io", optional = true } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/timestamp" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.5", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-alpha.6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } [features] default = ["std"] @@ -41,6 +44,3 @@ std = [ "sp-timestamp/std" ] runtime-benchmarks = ["frame-benchmarking", "sp-io"] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/transaction-payment/Cargo.toml b/frame/transaction-payment/Cargo.toml index 811c2885b1..0ba4b9ca86 100644 --- a/frame/transaction-payment/Cargo.toml +++ b/frame/transaction-payment/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-payment" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,18 +8,21 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet to manage transaction payments" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.5", default-features = false, path = "./rpc/runtime-api" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.6", default-features = false, path = "./rpc/runtime-api" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } [features] default = ["std"] @@ -31,6 +34,3 @@ std = [ "frame-system/std", "pallet-transaction-payment-rpc-runtime-api/std" ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/transaction-payment/rpc/Cargo.toml b/frame/transaction-payment/rpc/Cargo.toml index cd74829b29..beae554464 100644 --- a/frame/transaction-payment/rpc/Cargo.toml +++ b/frame/transaction-payment/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-payment-rpc" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,18 +8,18 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "RPC interface for the transaction payment module." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.3" -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sp-rpc = { version = "2.0.0-alpha.5", path = "../../../primitives/rpc" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-rpc = { version = "2.0.0-alpha.6", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.5", path = "./runtime-api" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.6", path = "./runtime-api" } diff --git a/frame/transaction-payment/rpc/runtime-api/Cargo.toml b/frame/transaction-payment/rpc/runtime-api/Cargo.toml index 447590111c..2c79b111d2 100644 --- a/frame/transaction-payment/rpc/runtime-api/Cargo.toml +++ b/frame/transaction-payment/rpc/runtime-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-payment-rpc-runtime-api" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,13 +8,16 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "RPC runtime API for transaction payment FRAME pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/api" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../../support" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../../support" } [dev-dependencies] serde_json = "1.0.41" @@ -29,6 +32,3 @@ std = [ "sp-runtime/std", "frame-support/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/treasury/Cargo.toml b/frame/treasury/Cargo.toml index 6951c0eba9..17e1e7284f 100644 --- a/frame/treasury/Cargo.toml +++ b/frame/treasury/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-treasury" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,20 +8,23 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet to manage treasury" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -pallet-balances = { version = "2.0.0-alpha.5", default-features = false, path = "../balances" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +pallet-balances = { version = "2.0.0-alpha.6", default-features = false, path = "../balances" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.5", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-alpha.6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } [features] default = ["std"] @@ -38,6 +41,3 @@ runtime-benchmarks = [ "frame-benchmarking", "frame-support/runtime-benchmarks", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/utility/Cargo.toml b/frame/utility/Cargo.toml index cf1042d852..acaa485489 100644 --- a/frame/utility/Cargo.toml +++ b/frame/utility/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-utility" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,21 +8,24 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME utilities pallet" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } [features] default = ["std"] @@ -39,6 +42,3 @@ runtime-benchmarks = [ "frame-benchmarking", "frame-support/runtime-benchmarks", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/vesting/Cargo.toml b/frame/vesting/Cargo.toml index e40062706f..d950db4ea0 100644 --- a/frame/vesting/Cargo.toml +++ b/frame/vesting/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-vesting" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,21 +8,24 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for manage vesting" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } -sp-storage = { version = "2.0.0-alpha.5", path = "../../primitives/storage" } +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +sp-storage = { version = "2.0.0-alpha.6", path = "../../primitives/storage" } hex-literal = "0.2.1" [features] @@ -37,6 +40,3 @@ std = [ "frame-system/std", ] runtime-benchmarks = ["frame-benchmarking"] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/allocator/Cargo.toml b/primitives/allocator/Cargo.toml index 635a3c9128..5d1b899fed 100644 --- a/primitives/allocator/Cargo.toml +++ b/primitives/allocator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-allocator" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,10 +9,13 @@ repository = "https://github.com/paritytech/substrate/" description = "Collection of allocator implementations." documentation = "https://docs.rs/sp-allocator" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-std = { version = "2.0.0-alpha.5", path = "../std", default-features = false } -sp-core = { version = "2.0.0-alpha.5", path = "../core", default-features = false } -sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../wasm-interface", default-features = false } +sp-std = { version = "2.0.0-alpha.6", path = "../std", default-features = false } +sp-core = { version = "2.0.0-alpha.6", path = "../core", default-features = false } +sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../wasm-interface", default-features = false } log = { version = "0.4.8", optional = true } derive_more = { version = "0.99.2", optional = true } @@ -25,6 +28,3 @@ std = [ "log", "derive_more", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/api/Cargo.toml b/primitives/api/Cargo.toml index fedeeceb3f..d565aff9e2 100644 --- a/primitives/api/Cargo.toml +++ b/primitives/api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-api" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,14 +8,17 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate runtime api primitives" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-api-proc-macro = { version = "2.0.0-alpha.5", path = "proc-macro" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } -sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../version" } -sp-state-machine = { version = "0.8.0-alpha.5", optional = true, path = "../../primitives/state-machine" } +sp-api-proc-macro = { version = "2.0.0-alpha.6", path = "proc-macro" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } +sp-version = { version = "2.0.0-alpha.6", default-features = false, path = "../version" } +sp-state-machine = { version = "0.8.0-alpha.6", optional = true, path = "../../primitives/state-machine" } hash-db = { version = "0.15.2", optional = true } [dev-dependencies] @@ -32,6 +35,3 @@ std = [ "sp-version/std", "hash-db", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/api/proc-macro/Cargo.toml b/primitives/api/proc-macro/Cargo.toml index 25c5ae1343..e4fadd03d3 100644 --- a/primitives/api/proc-macro/Cargo.toml +++ b/primitives/api/proc-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-api-proc-macro" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,6 +9,9 @@ repository = "https://github.com/paritytech/substrate/" description = "Macros for declaring and implementing runtime apis." documentation = "https://docs.rs/sp-api-proc-macro" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [lib] proc-macro = true @@ -24,6 +27,3 @@ proc-macro-crate = "0.1.4" [features] default = [ "std" ] std = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/api/test/Cargo.toml b/primitives/api/test/Cargo.toml index f2e66afc24..91d81ee541 100644 --- a/primitives/api/test/Cargo.toml +++ b/primitives/api/test/Cargo.toml @@ -8,23 +8,26 @@ publish = false homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-api = { version = "2.0.0-alpha.5", path = "../" } +sp-api = { version = "2.0.0-alpha.6", path = "../" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-version = { version = "2.0.0-alpha.5", path = "../../version" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../blockchain" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } -sc-block-builder = { version = "0.8.0-alpha.5", path = "../../../client/block-builder" } +sp-version = { version = "2.0.0-alpha.6", path = "../../version" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../runtime" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../blockchain" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } +sc-block-builder = { version = "0.8.0-alpha.6", path = "../../../client/block-builder" } codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../../primitives/state-machine" } trybuild = "1.0.17" rustversion = "1.0.0" [dev-dependencies] criterion = "0.3.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-core = { version = "2.0.0-alpha.5", path = "../../core" } +sp-core = { version = "2.0.0-alpha.6", path = "../../core" } [[bench]] name = "bench" @@ -34,6 +37,3 @@ harness = false [features] default = [ "std" ] std = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/application-crypto/Cargo.toml b/primitives/application-crypto/Cargo.toml index 7c3fb53579..6cd4d81e7b 100644 --- a/primitives/application-crypto/Cargo.toml +++ b/primitives/application-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-application-crypto" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" description = "Provides facilities for generating application specific crypto wrapper types." @@ -9,13 +9,16 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sp-application-crypto" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } [features] default = [ "std" ] @@ -31,6 +34,3 @@ full_crypto = [ "sp-io/disable_panic_handler", "sp-io/disable_oom", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/application-crypto/test/Cargo.toml b/primitives/application-crypto/test/Cargo.toml index d34840b4eb..ad2ab93156 100644 --- a/primitives/application-crypto/test/Cargo.toml +++ b/primitives/application-crypto/test/Cargo.toml @@ -9,12 +9,12 @@ publish = false homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -[dependencies] -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../core" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } -sp-api = { version = "2.0.0-alpha.5", path = "../../api" } -sp-application-crypto = { version = "2.0.0-alpha.5", path = "../" } - [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../core" } +substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../runtime" } +sp-api = { version = "2.0.0-alpha.6", path = "../../api" } +sp-application-crypto = { version = "2.0.0-alpha.6", path = "../" } diff --git a/primitives/arithmetic/Cargo.toml b/primitives/arithmetic/Cargo.toml index b8eaa721d6..7697cf008e 100644 --- a/primitives/arithmetic/Cargo.toml +++ b/primitives/arithmetic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-arithmetic" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,14 +9,17 @@ repository = "https://github.com/paritytech/substrate/" description = "Minimal fixed point arithmetic primitives and types for runtime." documentation = "https://docs.rs/sp-arithmetic" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } integer-sqrt = "0.1.2" num-traits = { version = "0.2.8", default-features = false } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-debug-derive = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/debug-derive" } +sp-debug-derive = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/debug-derive" } primitive-types = { version = "0.7.0", default-features = false } [dev-dependencies] @@ -38,6 +41,3 @@ std = [ [[bench]] name = "bench" harness = false - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/arithmetic/fuzzer/Cargo.toml b/primitives/arithmetic/fuzzer/Cargo.toml index 26b5f8c27b..3b8d012ac7 100644 --- a/primitives/arithmetic/fuzzer/Cargo.toml +++ b/primitives/arithmetic/fuzzer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-arithmetic-fuzzer" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,8 +9,11 @@ repository = "https://github.com/paritytech/substrate/" description = "Fuzzer for fixed point arithmetic primitives." documentation = "https://docs.rs/sp-arithmetic-fuzzer" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-arithmetic = { version = "2.0.0-alpha.5", path = ".." } +sp-arithmetic = { version = "2.0.0-alpha.6", path = ".." } honggfuzz = "0.5" primitive-types = "0.7.0" num-bigint = "0.2" @@ -27,6 +30,3 @@ path = "src/per_thing_rational.rs" [[bin]] name = "rational128" path = "src/rational128.rs" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/authority-discovery/Cargo.toml b/primitives/authority-discovery/Cargo.toml index f37b67fab1..77675bb94e 100644 --- a/primitives/authority-discovery/Cargo.toml +++ b/primitives/authority-discovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-authority-discovery" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] description = "Authority discovery primitives" edition = "2018" @@ -8,12 +8,15 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../application-crypto" } codec = { package = "parity-scale-codec", default-features = false, version = "1.3.0" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } [features] default = ["std"] @@ -24,6 +27,3 @@ std = [ "sp-api/std", "sp-runtime/std" ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/authorship/Cargo.toml b/primitives/authorship/Cargo.toml index a4d5aa03c2..faabfefa8a 100644 --- a/primitives/authorship/Cargo.toml +++ b/primitives/authorship/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-authorship" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] description = "Authorship primitives" edition = "2018" @@ -8,10 +8,13 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../inherents" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../inherents" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } [features] @@ -22,6 +25,3 @@ std = [ "sp-inherents/std", "sp-runtime/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/block-builder/Cargo.toml b/primitives/block-builder/Cargo.toml index df33b2c955..e2bf716aad 100644 --- a/primitives/block-builder/Cargo.toml +++ b/primitives/block-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-block-builder" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,12 +8,15 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "The block builder runtime api." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../inherents" } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../inherents" } [features] default = [ "std" ] @@ -24,6 +27,3 @@ std = [ "sp-api/std", "sp-std/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/blockchain/Cargo.toml b/primitives/blockchain/Cargo.toml index 49e6baead1..9d33ed2d29 100644 --- a/primitives/blockchain/Cargo.toml +++ b/primitives/blockchain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-blockchain" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,6 +9,9 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate blockchain traits and primitives." documentation = "https://docs.rs/sp-blockchain" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] log = "0.4.8" @@ -16,10 +19,7 @@ lru = "0.4.0" parking_lot = "0.10.0" derive_more = "0.99.2" codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.5", path = "../consensus/common" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } -sp-block-builder = { version = "2.0.0-alpha.5", path = "../block-builder" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../state-machine" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sp-consensus = { version = "0.8.0-alpha.6", path = "../consensus/common" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } +sp-block-builder = { version = "2.0.0-alpha.6", path = "../block-builder" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../state-machine" } diff --git a/primitives/chain-spec/Cargo.toml b/primitives/chain-spec/Cargo.toml index 62d64bf614..df79932b28 100644 --- a/primitives/chain-spec/Cargo.toml +++ b/primitives/chain-spec/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-chain-spec" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/consensus/aura/Cargo.toml b/primitives/consensus/aura/Cargo.toml index 99ce51a229..613a6485a6 100644 --- a/primitives/consensus/aura/Cargo.toml +++ b/primitives/consensus/aura/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-aura" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" @@ -8,14 +8,17 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../application-crypto" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../std" } -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../api" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../runtime" } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../inherents" } -sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../timestamp" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../std" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../api" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../runtime" } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../inherents" } +sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../timestamp" } [features] default = ["std"] @@ -28,6 +31,3 @@ std = [ "sp-inherents/std", "sp-timestamp/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/consensus/babe/Cargo.toml b/primitives/consensus/babe/Cargo.toml index 195a54a591..af2e77f220 100644 --- a/primitives/consensus/babe/Cargo.toml +++ b/primitives/consensus/babe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-babe" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Primitives for BABE consensus" edition = "2018" @@ -8,16 +8,19 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../application-crypto" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../std" } -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../api" } -sp-consensus = { version = "0.8.0-alpha.5", optional = true, path = "../common" } -sp-consensus-vrf = { version = "0.8.0-alpha.5", path = "../vrf", default-features = false } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../inherents" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../runtime" } -sp-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../timestamp" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../std" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../api" } +sp-consensus = { version = "0.8.0-alpha.6", optional = true, path = "../common" } +sp-consensus-vrf = { version = "0.8.0-alpha.6", path = "../vrf", default-features = false } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../inherents" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../runtime" } +sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../timestamp" } [features] default = ["std"] @@ -32,6 +35,3 @@ std = [ "sp-runtime/std", "sp-timestamp/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 8b769479d3..7e8a044690 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,21 +9,24 @@ repository = "https://github.com/paritytech/substrate/" description = "Common utilities for building and using consensus engines in substrate." documentation = "https://docs.rs/sp-consensus/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] derive_more = "0.99.2" libp2p = { version = "0.18.0", default-features = false } log = "0.4.8" -sp-core = { path= "../../core", version = "2.0.0-alpha.5"} -sp-inherents = { version = "2.0.0-alpha.5", path = "../../inherents" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } +sp-core = { path= "../../core", version = "2.0.0-alpha.6"} +sp-inherents = { version = "2.0.0-alpha.6", path = "../../inherents" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../../primitives/state-machine" } futures = { version = "0.3.1", features = ["thread-pool"] } futures-timer = "3.0.1" futures-diagnose = "1.0" -sp-std = { version = "2.0.0-alpha.5", path = "../../std" } -sp-version = { version = "2.0.0-alpha.5", path = "../../version" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } -sp-utils = { version = "2.0.0-alpha.5", path = "../../utils" } +sp-std = { version = "2.0.0-alpha.6", path = "../../std" } +sp-version = { version = "2.0.0-alpha.6", path = "../../version" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../runtime" } +sp-utils = { version = "2.0.0-alpha.6", path = "../../utils" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } parking_lot = "0.10.0" serde = { version = "1.0", features = ["derive"] } @@ -33,6 +36,3 @@ sp-test-primitives = { version = "2.0.0-dev", path = "../../test-primitives" } [features] default = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/consensus/pow/Cargo.toml b/primitives/consensus/pow/Cargo.toml index 5ca60bb215..0ff3334bbe 100644 --- a/primitives/consensus/pow/Cargo.toml +++ b/primitives/consensus/pow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-pow" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" @@ -8,11 +8,14 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../api" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../runtime" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../core" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../api" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../runtime" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../core" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } [features] @@ -24,6 +27,3 @@ std = [ "sp-core/std", "codec/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/consensus/vrf/Cargo.toml b/primitives/consensus/vrf/Cargo.toml index cf194ec38b..b584002fe6 100644 --- a/primitives/consensus/vrf/Cargo.toml +++ b/primitives/consensus/vrf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-vrf" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Primitives for VRF based consensus" edition = "2018" @@ -8,12 +8,15 @@ license = "GPL-3.0" repository = "https://github.com/paritytech/substrate/" homepage = "https://substrate.dev" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { version = "1.0.0", package = "parity-scale-codec", default-features = false } schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated"], optional = true } -sp-std = { version = "2.0.0-alpha.5", path = "../../std", default-features = false } -sp-core = { version = "2.0.0-alpha.5", path = "../../core", default-features = false } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../runtime" } +sp-std = { version = "2.0.0-alpha.6", path = "../../std", default-features = false } +sp-core = { version = "2.0.0-alpha.6", path = "../../core", default-features = false } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../runtime" } [features] default = ["std"] @@ -24,6 +27,3 @@ std = [ "sp-core/std", "sp-runtime/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 7708188ea4..a6db02e941 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-core" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,8 +9,11 @@ repository = "https://github.com/paritytech/substrate/" description = "Shareable Substrate types." documentation = "https://docs.rs/sp-core" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } log = { version = "0.4.8", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } @@ -29,9 +32,9 @@ num-traits = { version = "0.2.8", default-features = false } zeroize = { version = "1.0.0", default-features = false } lazy_static = { version = "1.4.0", default-features = false, optional = true } parking_lot = { version = "0.10.0", optional = true } -sp-debug-derive = { version = "2.0.0-alpha.5", path = "../debug-derive" } -sp-externalities = { version = "0.8.0-alpha.5", optional = true, path = "../externalities" } -sp-storage = { version = "2.0.0-alpha.5", default-features = false, path = "../storage" } +sp-debug-derive = { version = "2.0.0-alpha.6", path = "../debug-derive" } +sp-externalities = { version = "0.8.0-alpha.6", optional = true, path = "../externalities" } +sp-storage = { version = "2.0.0-alpha.6", default-features = false, path = "../storage" } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } futures = { version = "0.3.1", optional = true } @@ -45,10 +48,10 @@ hex = { version = "0.4", default-features = false, optional = true } twox-hash = { version = "1.5.0", default-features = false, optional = true } libsecp256k1 = { version = "0.3.2", default-features = false, features = ["hmac"], optional = true } -sp-runtime-interface = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime-interface" } +sp-runtime-interface = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime-interface" } [dev-dependencies] -sp-serializer = { version = "2.0.0-alpha.5", path = "../serializer" } +sp-serializer = { version = "2.0.0-alpha.6", path = "../serializer" } pretty_assertions = "0.6.1" hex-literal = "0.2.1" rand = "0.7.2" @@ -119,6 +122,3 @@ full_crypto = [ "libsecp256k1", "sp-runtime-interface/disable_target_static_assertions", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/debug-derive/Cargo.toml b/primitives/debug-derive/Cargo.toml index 0079b6219f..936e24393f 100644 --- a/primitives/debug-derive/Cargo.toml +++ b/primitives/debug-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-debug-derive" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,6 +9,10 @@ repository = "https://github.com/paritytech/substrate/" description = "Macros to derive runtime debug implementation." documentation = "https://docs.rs/sp-debug-derive" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [lib] proc-macro = true @@ -21,7 +25,3 @@ proc-macro2 = "1.0" std = [] [dev-dependencies] - - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/externalities/Cargo.toml b/primitives/externalities/Cargo.toml index af6e516fbf..2afe7a56a7 100644 --- a/primitives/externalities/Cargo.toml +++ b/primitives/externalities/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-externalities" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -9,10 +9,10 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate externalities abstraction" documentation = "https://docs.rs/sp-externalities" -[dependencies] -sp-storage = { version = "2.0.0-alpha.5", path = "../storage" } -sp-std = { version = "2.0.0-alpha.5", path = "../std" } -environmental = { version = "1.1.1" } - [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +sp-storage = { version = "2.0.0-alpha.6", path = "../storage" } +sp-std = { version = "2.0.0-alpha.6", path = "../std" } +environmental = { version = "1.1.1" } diff --git a/primitives/finality-grandpa/Cargo.toml b/primitives/finality-grandpa/Cargo.toml index 0595fa7ba7..a45098b671 100644 --- a/primitives/finality-grandpa/Cargo.toml +++ b/primitives/finality-grandpa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-finality-grandpa" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,14 +9,17 @@ repository = "https://github.com/paritytech/substrate/" description = "Primitives for GRANDPA integration, suitable for WASM compilation." documentation = "https://docs.rs/sp-finality-grandpa" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../application-crypto" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } [features] default = ["std"] @@ -28,6 +31,3 @@ std = [ "sp-api/std", "sp-runtime/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/finality-tracker/Cargo.toml b/primitives/finality-tracker/Cargo.toml index 4e6cf6c92d..4f3cbd623b 100644 --- a/primitives/finality-tracker/Cargo.toml +++ b/primitives/finality-tracker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-finality-tracker" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,10 +8,13 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME module that tracks the last finalized block, as perceived by block authors." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } [features] default = ["std"] @@ -20,6 +23,3 @@ std = [ "sp-std/std", "sp-inherents/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/inherents/Cargo.toml b/primitives/inherents/Cargo.toml index dd640f00ec..ec794fb90e 100644 --- a/primitives/inherents/Cargo.toml +++ b/primitives/inherents/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-inherents" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,11 +9,14 @@ repository = "https://github.com/paritytech/substrate/" description = "Provides types and traits for creating and checking inherents." documentation = "https://docs.rs/sp-inherents" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] parking_lot = { version = "0.10.0", optional = true } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } derive_more = { version = "0.99.2", optional = true } @@ -26,6 +29,3 @@ std = [ "sp-core/std", "derive_more", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index 9cda2120cc..9194d2506e 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-io" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,18 +9,21 @@ repository = "https://github.com/paritytech/substrate/" description = "I/O for Substrate runtimes" documentation = "https://docs.rs/sp-io" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } hash-db = { version = "0.15.2", default-features = false } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } libsecp256k1 = { version = "0.3.4", optional = true } -sp-state-machine = { version = "0.8.0-alpha.5", optional = true, path = "../../primitives/state-machine" } -sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../primitives/wasm-interface", default-features = false } -sp-runtime-interface = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime-interface" } -sp-trie = { version = "2.0.0-alpha.5", optional = true, path = "../../primitives/trie" } -sp-externalities = { version = "0.8.0-alpha.5", optional = true, path = "../externalities" } +sp-state-machine = { version = "0.8.0-alpha.6", optional = true, path = "../../primitives/state-machine" } +sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../../primitives/wasm-interface", default-features = false } +sp-runtime-interface = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime-interface" } +sp-trie = { version = "2.0.0-alpha.6", optional = true, path = "../../primitives/trie" } +sp-externalities = { version = "0.8.0-alpha.6", optional = true, path = "../externalities" } log = { version = "0.4.8", optional = true } [features] @@ -46,6 +49,3 @@ std = [ disable_panic_handler = [] disable_oom = [] disable_allocator = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/keyring/Cargo.toml b/primitives/keyring/Cargo.toml index 0764146250..0467d3f255 100644 --- a/primitives/keyring/Cargo.toml +++ b/primitives/keyring/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-keyring" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,12 +9,12 @@ repository = "https://github.com/paritytech/substrate/" description = "Keyring support code for the runtime. A set of test accounts." documentation = "https://docs.rs/sp-keyring" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-core = { version = "2.0.0-alpha.5", path = "../core" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } +sp-core = { version = "2.0.0-alpha.6", path = "../core" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } lazy_static = "1.4.0" strum = { version = "0.16.0", features = ["derive"] } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/offchain/Cargo.toml b/primitives/offchain/Cargo.toml index 66febccd59..99bdb1507b 100644 --- a/primitives/offchain/Cargo.toml +++ b/primitives/offchain/Cargo.toml @@ -1,16 +1,19 @@ [package] description = "Substrate offchain workers primitives" name = "sp-offchain" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } [features] default = ["std"] @@ -18,6 +21,3 @@ std = [ "sp-api/std", "sp-runtime/std" ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/panic-handler/Cargo.toml b/primitives/panic-handler/Cargo.toml index 169443f6c4..c4c0ffae6d 100644 --- a/primitives/panic-handler/Cargo.toml +++ b/primitives/panic-handler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-panic-handler" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,9 +9,9 @@ repository = "https://github.com/paritytech/substrate/" description = "Custom panic hook with bug report link" documentation = "https://docs.rs/sp-panic-handler" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] backtrace = "0.3.38" log = "0.4.8" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/phragmen/Cargo.toml b/primitives/phragmen/Cargo.toml index f5d26e8a40..b06ed1e945 100644 --- a/primitives/phragmen/Cargo.toml +++ b/primitives/phragmen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-phragmen" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,17 +8,20 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Phragmen primitives" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -sp-phragmen-compact = { version = "2.0.0-alpha.4", path = "./compact" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-phragmen-compact = { version = "2.0.0-dev.1", path = "./compact" } [dev-dependencies] -substrate-test-utils = { version = "2.0.0-alpha.5", path = "../../test-utils" } +substrate-test-utils = { version = "2.0.0-alpha.6", path = "../../test-utils" } rand = "0.7.3" -sp-phragmen = { path = "." } +sp-phragmen = { path = "." , version = "2.0.0-alpha.6"} [features] default = ["std"] @@ -29,6 +32,3 @@ std = [ "sp-std/std", "sp-runtime/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/phragmen/compact/Cargo.toml b/primitives/phragmen/compact/Cargo.toml index 56b4520c54..49566c5262 100644 --- a/primitives/phragmen/compact/Cargo.toml +++ b/primitives/phragmen/compact/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-phragmen-compact" -version = "2.0.0-dev" +version = "2.0.0-dev.1" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,6 +8,9 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Phragmen Compact Solution" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [lib] proc-macro = true @@ -16,6 +19,3 @@ syn = { version = "1.0.7", features = ["full", "visit"] } quote = "1.0" proc-macro2 = "1.0.6" proc-macro-crate = "0.1.4" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/rpc/Cargo.toml b/primitives/rpc/Cargo.toml index a7975fb475..a2279e3152 100644 --- a/primitives/rpc/Cargo.toml +++ b/primitives/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-rpc" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,12 +8,12 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate RPC primitives and utilities." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", features = ["derive"] } -sp-core = { version = "2.0.0-alpha.5", path = "../core" } +sp-core = { version = "2.0.0-alpha.6", path = "../core" } [dev-dependencies] serde_json = "1.0.41" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 01f7f2f19c..aa35509f39 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-runtime-interface" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,20 +9,23 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate runtime interface" documentation = "https://docs.rs/sp-runtime-interface/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../wasm-interface", default-features = false } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -sp-runtime-interface-proc-macro = { version = "2.0.0-alpha.5", path = "proc-macro" } -sp-externalities = { version = "0.8.0-alpha.5", optional = true, path = "../externalities" } +sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../wasm-interface", default-features = false } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-runtime-interface-proc-macro = { version = "2.0.0-alpha.6", path = "proc-macro" } +sp-externalities = { version = "0.8.0-alpha.6", optional = true, path = "../externalities" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } static_assertions = "1.0.0" primitive-types = { version = "0.7.0", default-features = false } [dev-dependencies] sp-runtime-interface-test-wasm = { version = "2.0.0-dev", path = "test-wasm" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } -sp-core = { version = "2.0.0-alpha.5", path = "../core" } -sp-io = { version = "2.0.0-alpha.5", path = "../io" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } +sp-core = { version = "2.0.0-alpha.6", path = "../core" } +sp-io = { version = "2.0.0-alpha.6", path = "../io" } rustversion = "1.0.0" trybuild = "1.0.23" @@ -43,6 +46,3 @@ std = [ # Disables static assertions in `impls.rs` that checks the word size. To prevent any footgun, the # check is changed into a runtime check. disable_target_static_assertions = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/runtime-interface/proc-macro/Cargo.toml b/primitives/runtime-interface/proc-macro/Cargo.toml index 6d0b7ee5fb..2691e2a4ab 100644 --- a/primitives/runtime-interface/proc-macro/Cargo.toml +++ b/primitives/runtime-interface/proc-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-runtime-interface-proc-macro" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,6 +9,9 @@ repository = "https://github.com/paritytech/substrate/" description = "This crate provides procedural macros for usage within the context of the Substrate runtime interface." documentation = "https://docs.rs/sp-runtime-interface-proc-macro" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [lib] proc-macro = true @@ -18,6 +21,3 @@ quote = "1.0.3" proc-macro2 = "1.0.3" Inflector = "0.11.4" proc-macro-crate = "0.1.4" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml index 6f2d66bd77..15bebea986 100644 --- a/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml +++ b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml @@ -9,11 +9,14 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = false +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-runtime-interface = { version = "2.0.0-alpha.5", default-features = false, path = "../" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../io" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../core" } +sp-runtime-interface = { version = "2.0.0-alpha.6", default-features = false, path = "../" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../io" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../core" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } @@ -21,6 +24,3 @@ wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-run [features] default = [ "std" ] std = [ "sp-runtime-interface/std", "sp-std/std", "sp-core/std", "sp-io/std" ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/runtime-interface/test-wasm/Cargo.toml b/primitives/runtime-interface/test-wasm/Cargo.toml index 4eb4f01c9f..e1d8c077cf 100644 --- a/primitives/runtime-interface/test-wasm/Cargo.toml +++ b/primitives/runtime-interface/test-wasm/Cargo.toml @@ -9,11 +9,14 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = false +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-runtime-interface = { version = "2.0.0-alpha.5", default-features = false, path = "../" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../io" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../core" } +sp-runtime-interface = { version = "2.0.0-alpha.6", default-features = false, path = "../" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../io" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../core" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } @@ -21,6 +24,3 @@ wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-run [features] default = [ "std" ] std = [ "sp-runtime-interface/std", "sp-std/std", "sp-core/std", "sp-io/std" ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/runtime-interface/test/Cargo.toml b/primitives/runtime-interface/test/Cargo.toml index f3bee038c8..a6bab27779 100644 --- a/primitives/runtime-interface/test/Cargo.toml +++ b/primitives/runtime-interface/test/Cargo.toml @@ -8,14 +8,14 @@ publish = false homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../" } -sc-executor = { version = "0.8.0-alpha.5", path = "../../../client/executor" } +sp-runtime-interface = { version = "2.0.0-alpha.6", path = "../" } +sc-executor = { version = "0.8.0-alpha.6", path = "../../../client/executor" } sp-runtime-interface-test-wasm = { version = "2.0.0-dev", path = "../test-wasm" } sp-runtime-interface-test-wasm-deprecated = { version = "2.0.0-dev", path = "../test-wasm-deprecated" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } -sp-io = { version = "2.0.0-alpha.5", path = "../../io" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../../primitives/state-machine" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../runtime" } +sp-io = { version = "2.0.0-alpha.6", path = "../../io" } diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index 0e71e8becd..2c44245684 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-runtime" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,20 +9,23 @@ repository = "https://github.com/paritytech/substrate/" description = "Runtime Modules shared primitive types." documentation = "https://docs.rs/sp-runtime" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } -sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../application-crypto" } -sp-arithmetic = { version = "2.0.0-alpha.5", default-features = false, path = "../arithmetic" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../io" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } +sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../application-crypto" } +sp-arithmetic = { version = "2.0.0-alpha.6", default-features = false, path = "../arithmetic" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../io" } log = { version = "0.4.8", optional = true } paste = "0.1.6" rand = { version = "0.7.2", optional = true } impl-trait-for-tuples = "0.1.3" -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../inherents" } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../inherents" } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } hash256-std-hasher = { version = "0.15.2", default-features = false } @@ -48,6 +51,3 @@ std = [ "parity-util-mem/std", "hash256-std-hasher/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/sandbox/Cargo.toml b/primitives/sandbox/Cargo.toml index 5c1595027f..304d3864e9 100755 --- a/primitives/sandbox/Cargo.toml +++ b/primitives/sandbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-sandbox" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,12 +8,15 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "This crate provides means to instantiate and execute wasm modules." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] wasmi = { version = "0.6.2", optional = true } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../io" } -sp-wasm-interface = { version = "2.0.0-alpha.5", default-features = false, path = "../wasm-interface" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../io" } +sp-wasm-interface = { version = "2.0.0-alpha.6", default-features = false, path = "../wasm-interface" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } [dev-dependencies] @@ -31,6 +34,3 @@ std = [ "sp-wasm-interface/std", ] strict = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/serializer/Cargo.toml b/primitives/serializer/Cargo.toml index 75263321b8..4897df3c1c 100644 --- a/primitives/serializer/Cargo.toml +++ b/primitives/serializer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-serializer" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,9 +9,9 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate customizable serde serializer." documentation = "https://docs.rs/sp-serializer" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] serde = "1.0.101" serde_json = "1.0.41" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/session/Cargo.toml b/primitives/session/Cargo.toml index ffe1bc327f..7972df2a95 100644 --- a/primitives/session/Cargo.toml +++ b/primitives/session/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-session" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,15 +8,15 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Primitives for sessions" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } -sp-runtime = { version = "2.0.0-alpha.5", optional = true, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } +sp-runtime = { version = "2.0.0-alpha.6", optional = true, path = "../runtime" } [features] default = [ "std" ] std = [ "sp-api/std", "sp-std/std", "sp-runtime", "sp-core/std" ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/staking/Cargo.toml b/primitives/staking/Cargo.toml index 60bf3f759e..e349b26bc4 100644 --- a/primitives/staking/Cargo.toml +++ b/primitives/staking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-staking" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,10 +8,13 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "A crate which contains primitives that are useful for implementation that uses staking approaches in general. Definitions related to sessions, slashing, etc go here." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } [features] default = ["std"] @@ -20,6 +23,3 @@ std = [ "sp-runtime/std", "sp-std/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/state-machine/Cargo.toml b/primitives/state-machine/Cargo.toml index 1e0e224b60..038ab5aeae 100644 --- a/primitives/state-machine/Cargo.toml +++ b/primitives/state-machine/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-state-machine" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Substrate State Machine" edition = "2018" @@ -9,26 +9,26 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sp-state-machine" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] log = "0.4.8" parking_lot = "0.10.0" hash-db = "0.15.2" trie-db = "0.20.1" trie-root = "0.16.0" -sp-trie = { version = "2.0.0-alpha.5", path = "../trie" } -sp-core = { version = "2.0.0-alpha.5", path = "../core" } -sp-panic-handler = { version = "2.0.0-alpha.5", path = "../panic-handler" } +sp-trie = { version = "2.0.0-alpha.6", path = "../trie" } +sp-core = { version = "2.0.0-alpha.6", path = "../core" } +sp-panic-handler = { version = "2.0.0-alpha.6", path = "../panic-handler" } codec = { package = "parity-scale-codec", version = "1.3.0" } num-traits = "0.2.8" rand = "0.7.2" -sp-externalities = { version = "0.8.0-alpha.5", path = "../externalities" } +sp-externalities = { version = "0.8.0-alpha.6", path = "../externalities" } [dev-dependencies] hex-literal = "0.2.1" -sp-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } [features] default = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/std/Cargo.toml b/primitives/std/Cargo.toml index 58ff78f2bb..d67bba985c 100644 --- a/primitives/std/Cargo.toml +++ b/primitives/std/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-std" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -10,9 +10,9 @@ repository = "https://github.com/paritytech/substrate/" description = "Lowest-abstraction level for the Substrate runtime: just exports useful primitives from std or client/alloc to be used with any code that depends on the runtime." documentation = "https://docs.rs/sp-std" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [features] default = ["std"] std = [] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/storage/Cargo.toml b/primitives/storage/Cargo.toml index e4e842848d..ba53ad8d12 100644 --- a/primitives/storage/Cargo.toml +++ b/primitives/storage/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-storage" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" description = "Storage related primitives" @@ -9,15 +9,15 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sp-storage/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } impl-serde = { version = "0.2.3", optional = true } -sp-debug-derive = { version = "2.0.0-alpha.5", path = "../debug-derive" } +sp-debug-derive = { version = "2.0.0-alpha.6", path = "../debug-derive" } [features] default = [ "std" ] std = [ "sp-std/std", "serde", "impl-serde" ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/test-primitives/Cargo.toml b/primitives/test-primitives/Cargo.toml index b8cb583835..8c47fc21b2 100644 --- a/primitives/test-primitives/Cargo.toml +++ b/primitives/test-primitives/Cargo.toml @@ -8,12 +8,15 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = false +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../application-crypto" } +sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../application-crypto" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [features] @@ -24,6 +27,3 @@ std = [ "sp-application-crypto/std", "serde", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/timestamp/Cargo.toml b/primitives/timestamp/Cargo.toml index 3c2772077b..0fcd35893e 100644 --- a/primitives/timestamp/Cargo.toml +++ b/primitives/timestamp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-timestamp" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,12 +8,15 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate core types and inherents for timestamps." +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../inherents" } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../inherents" } impl-trait-for-tuples = "0.1.3" wasm-timer = { version = "0.2", optional = true } @@ -27,6 +30,3 @@ std = [ "sp-inherents/std", "wasm-timer", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/transaction-pool/Cargo.toml b/primitives/transaction-pool/Cargo.toml index 6e30fb4ddc..9b0a59ac22 100644 --- a/primitives/transaction-pool/Cargo.toml +++ b/primitives/transaction-pool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-transaction-pool" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,6 +9,9 @@ repository = "https://github.com/paritytech/substrate/" description = "Transaction pool primitives types & Runtime API." documentation = "https://docs.rs/sp-transaction-pool" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", optional = true } @@ -16,9 +19,9 @@ derive_more = { version = "0.99.2", optional = true } futures = { version = "0.3.1", optional = true } log = { version = "0.4.8", optional = true } serde = { version = "1.0.101", features = ["derive"], optional = true} -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } -sp-utils = { version = "2.0.0-alpha.5", default-features = false, path = "../utils" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } +sp-utils = { version = "2.0.0-alpha.6", default-features = false, path = "../utils" } [features] default = [ "std" ] @@ -31,6 +34,3 @@ std = [ "sp-api/std", "sp-runtime/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/trie/Cargo.toml b/primitives/trie/Cargo.toml index bc475745a5..2530cc3f99 100644 --- a/primitives/trie/Cargo.toml +++ b/primitives/trie/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-trie" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] description = "Patricia trie stuff using a parity-scale-codec node format" repository = "https://github.com/paritytech/substrate/" @@ -9,25 +9,28 @@ edition = "2018" homepage = "https://substrate.dev" documentation = "https://docs.rs/sp-trie" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [[bench]] name = "bench" harness = false [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } hash-db = { version = "0.15.2", default-features = false } trie-db = { version = "0.20.1", default-features = false } trie-root = { version = "0.16.0", default-features = false } memory-db = { version = "0.20.0", default-features = false } -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } [dev-dependencies] trie-bench = "0.21.0" trie-standardmap = "0.15.2" criterion = "0.2.11" hex-literal = "0.2.1" -sp-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } [features] default = ["std"] @@ -40,6 +43,3 @@ std = [ "trie-root/std", "sp-core/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/utils/Cargo.toml b/primitives/utils/Cargo.toml index 97e5ce1d9b..24e0294533 100644 --- a/primitives/utils/Cargo.toml +++ b/primitives/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-utils" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/version/Cargo.toml b/primitives/version/Cargo.toml index 726d064642..bb927bb7a1 100644 --- a/primitives/version/Cargo.toml +++ b/primitives/version/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-version" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,13 +9,16 @@ repository = "https://github.com/paritytech/substrate/" description = "Version module for the Substrate runtime; Provides a function that returns the runtime version." documentation = "https://docs.rs/sp-version" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] impl-serde = { version = "0.2.3", optional = true } serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } [features] default = ["std"] @@ -26,6 +29,3 @@ std = [ "sp-std/std", "sp-runtime/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/wasm-interface/Cargo.toml b/primitives/wasm-interface/Cargo.toml index 4a35d5b518..b8402ea0c1 100644 --- a/primitives/wasm-interface/Cargo.toml +++ b/primitives/wasm-interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-wasm-interface" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,15 +9,15 @@ repository = "https://github.com/paritytech/substrate/" description = "Types and traits for interfacing between the host and the wasm runtime." documentation = "https://docs.rs/sp-wasm-interface" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] wasmi = { version = "0.6.2", optional = true } impl-trait-for-tuples = "0.1.2" -sp-std = { version = "2.0.0-alpha.5", path = "../std", default-features = false } +sp-std = { version = "2.0.0-alpha.6", path = "../std", default-features = false } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } [features] default = [ "std" ] std = [ "wasmi", "sp-std/std", "codec/std" ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml index b8c9f9bd60..bf31dfcaa1 100644 --- a/test-utils/Cargo.toml +++ b/test-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-test-utils" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/test-utils/client/Cargo.toml b/test-utils/client/Cargo.toml index ec87e7cd16..3eb93e7380 100644 --- a/test-utils/client/Cargo.toml +++ b/test-utils/client/Cargo.toml @@ -8,20 +8,20 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = false +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sc-client-api = { version = "2.0.0-alpha.5", path = "../../client/api" } -sc-client = { version = "0.8.0-alpha.5", path = "../../client/" } -sc-client-db = { version = "0.8.0-alpha.5", features = ["test-helpers"], path = "../../client/db" } -sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } -sc-executor = { version = "0.8.0-alpha.5", path = "../../client/executor" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../../client/api" } +sc-client = { version = "0.8.0-alpha.6", path = "../../client/" } +sc-client-db = { version = "0.8.0-alpha.6", features = ["test-helpers"], path = "../../client/db" } +sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } +sc-executor = { version = "0.8.0-alpha.6", path = "../../client/executor" } futures = "0.3.4" hash-db = "0.15.2" -sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index 4c3b92db70..fe552b7d85 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -9,44 +9,47 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = false +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/application-crypto" } -sp-consensus-aura = { version = "0.8.0-alpha.5", default-features = false, path = "../../primitives/consensus/aura" } -sp-consensus-babe = { version = "0.8.0-alpha.5", default-features = false, path = "../../primitives/consensus/babe" } -sp-block-builder = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/block-builder" } +sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/application-crypto" } +sp-consensus-aura = { version = "0.8.0-alpha.6", default-features = false, path = "../../primitives/consensus/aura" } +sp-consensus-babe = { version = "0.8.0-alpha.6", default-features = false, path = "../../primitives/consensus/babe" } +sp-block-builder = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/block-builder" } cfg-if = "0.1.10" codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -frame-executive = { version = "2.0.0-alpha.5", default-features = false, path = "../../frame/executive" } -sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.5", optional = true, path = "../../primitives/keyring" } +frame-executive = { version = "2.0.0-alpha.6", default-features = false, path = "../../frame/executive" } +sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } +sp-keyring = { version = "2.0.0-alpha.6", optional = true, path = "../../primitives/keyring" } log = { version = "0.4.8", optional = true } memory-db = { version = "0.20.0", default-features = false } -sp-offchain = { path = "../../primitives/offchain", default-features = false, version = "2.0.0-alpha.5"} -sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-runtime-interface = { path = "../../primitives/runtime-interface", default-features = false, version = "2.0.0-alpha.5"} -sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } -frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../frame/support" } -sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/version" } +sp-offchain = { path = "../../primitives/offchain", default-features = false, version = "2.0.0-alpha.6"} +sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-runtime-interface = { path = "../../primitives/runtime-interface", default-features = false, version = "2.0.0-alpha.6"} +sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../frame/support" } +sp-version = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/version" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-session = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/session" } -sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } -pallet-babe = { version = "2.0.0-alpha.5", default-features = false, path = "../../frame/babe" } -frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../../frame/system" } -frame-system-rpc-runtime-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../frame/system/rpc/runtime-api" } -pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../frame/timestamp" } -sc-client = { version = "0.8.0-alpha.5", optional = true, path = "../../client" } -sp-trie = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/trie" } -sp-transaction-pool = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/transaction-pool" } +sp-session = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/session" } +sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +pallet-babe = { version = "2.0.0-alpha.6", default-features = false, path = "../../frame/babe" } +frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../../frame/system" } +frame-system-rpc-runtime-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../frame/system/rpc/runtime-api" } +pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../frame/timestamp" } +sc-client = { version = "0.8.0-alpha.6", optional = true, path = "../../client" } +sp-trie = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/trie" } +sp-transaction-pool = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/transaction-pool" } trie-db = { version = "0.20.1", default-features = false } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] -sc-block-builder = { version = "0.8.0-alpha.5", path = "../../client/block-builder" } -sc-executor = { version = "0.8.0-alpha.5", path = "../../client/executor" } +sc-block-builder = { version = "0.8.0-alpha.6", path = "../../client/block-builder" } +sc-executor = { version = "0.8.0-alpha.6", path = "../../client/executor" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "./client" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../utils/wasm-builder-runner" } @@ -87,6 +90,3 @@ std = [ "sp-transaction-pool/std", "trie-db/std", ] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/test-utils/runtime/client/Cargo.toml b/test-utils/runtime/client/Cargo.toml index 4be45fe466..95484f75e3 100644 --- a/test-utils/runtime/client/Cargo.toml +++ b/test-utils/runtime/client/Cargo.toml @@ -8,18 +8,18 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = false +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sc-block-builder = { version = "0.8.0-alpha.5", path = "../../../client/block-builder" } +sc-block-builder = { version = "0.8.0-alpha.6", path = "../../../client/block-builder" } substrate-test-client = { version = "2.0.0-dev", path = "../../client" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../runtime" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } -sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } +sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api" } +sc-client = { version = "0.8.0-alpha.6", path = "../../../client/" } futures = "0.3.4" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/test-utils/runtime/transaction-pool/Cargo.toml b/test-utils/runtime/transaction-pool/Cargo.toml index 52e2020dc8..64f093093d 100644 --- a/test-utils/runtime/transaction-pool/Cargo.toml +++ b/test-utils/runtime/transaction-pool/Cargo.toml @@ -8,16 +8,16 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = false +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../client" } parking_lot = "0.10.0" codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } -sc-transaction-graph = { version = "2.0.0-alpha.5", path = "../../../client/transaction-pool/graph" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../primitives/transaction-pool" } +sc-transaction-graph = { version = "2.0.0-alpha.6", path = "../../../client/transaction-pool/graph" } futures = { version = "0.3.1", features = ["compat"] } derive_more = "0.99.2" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 427f067751..3d626d3d78 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-browser-utils" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" authors = ["Parity Technologies "] description = "Utilities for creating a browser light-client." edition = "2018" @@ -8,6 +8,9 @@ license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] futures = "0.3" futures01 = { package = "futures", version = "0.1.29" } @@ -19,10 +22,10 @@ js-sys = "0.3.34" wasm-bindgen = "0.2.57" wasm-bindgen-futures = "0.4.7" kvdb-web = "0.5" -sc-informant = { version = "0.8.0-alpha.5", path = "../../client/informant" } -sc-service = { version = "0.8.0-alpha.5", path = "../../client/service", default-features = false } -sc-network = { path = "../../client/network", version = "0.8.0-alpha.5"} -sc-chain-spec = { path = "../../client/chain-spec", version = "2.0.0-alpha.5"} +sc-informant = { version = "0.8.0-alpha.6", path = "../../client/informant" } +sc-service = { version = "0.8.0-alpha.6", path = "../../client/service", default-features = false } +sc-network = { path = "../../client/network", version = "0.8.0-alpha.6"} +sc-chain-spec = { path = "../../client/chain-spec", version = "2.0.0-alpha.6"} # Imported just for the `no_cc` feature clear_on_drop = { version = "0.2.3", features = ["no_cc"] } @@ -31,6 +34,3 @@ rand6 = { package = "rand", version = "0.6", features = ["wasm-bindgen"] } rand = { version = "0.7", features = ["wasm-bindgen"] } futures-timer = { version = "3.0.1", features = ["wasm-bindgen"]} chrono = { version = "0.4", features = ["wasmbind"] } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/build-script-utils/Cargo.toml b/utils/build-script-utils/Cargo.toml index 637d50d19d..335ec045f3 100644 --- a/utils/build-script-utils/Cargo.toml +++ b/utils/build-script-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-build-script-utils" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,8 +8,8 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Crate with utility functions for `build.rs` scripts." -[dependencies] -platforms = "0.2.1" - [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +platforms = "0.2.1" diff --git a/utils/fork-tree/Cargo.toml b/utils/fork-tree/Cargo.toml index e46618feb8..0c632c4df3 100644 --- a/utils/fork-tree/Cargo.toml +++ b/utils/fork-tree/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fork-tree" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -9,8 +9,8 @@ repository = "https://github.com/paritytech/substrate/" description = "Utility library for managing tree-like ordered data with logic for pruning the tree while finalizing nodes." documentation = "https://docs.rs/fork-tree" -[dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } - [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } diff --git a/utils/frame/benchmarking-cli/Cargo.toml b/utils/frame/benchmarking-cli/Cargo.toml index f4b7218747..eb5e0549f9 100644 --- a/utils/frame/benchmarking-cli/Cargo.toml +++ b/utils/frame/benchmarking-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-benchmarking-cli" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,23 +8,23 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "CLI for benchmarking FRAME" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -frame-benchmarking = { version = "2.0.0-alpha.5", path = "../../../frame/benchmarking" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } -sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../../../client/service" } -sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } -sc-client = { version = "0.8.0-alpha.5", path = "../../../client" } -sc-client-db = { version = "0.8.0-alpha.5", path = "../../../client/db" } -sc-executor = { version = "0.8.0-alpha.5", path = "../../../client/executor" } -sp-externalities = { version = "0.8.0-alpha.5", path = "../../../primitives/externalities" } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } +frame-benchmarking = { version = "2.0.0-alpha.6", path = "../../../frame/benchmarking" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../../../client/service" } +sc-cli = { version = "0.8.0-alpha.6", path = "../../../client/cli" } +sc-client = { version = "0.8.0-alpha.6", path = "../../../client" } +sc-client-db = { version = "0.8.0-alpha.6", path = "../../../client/db" } +sc-executor = { version = "0.8.0-alpha.6", path = "../../../client/executor" } +sp-externalities = { version = "0.8.0-alpha.6", path = "../../../primitives/externalities" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-alpha.6", path = "../../../primitives/state-machine" } structopt = "0.3.8" codec = { version = "1.3.0", package = "parity-scale-codec" } [features] default = ["rocksdb"] rocksdb = ["sc-client-db/kvdb-rocksdb"] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/frame/rpc/support/Cargo.toml b/utils/frame/rpc/support/Cargo.toml index 72884330d2..9d1425e5c9 100644 --- a/utils/frame/rpc/support/Cargo.toml +++ b/utils/frame/rpc/support/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-frame-rpc-support" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies ", "Andrew Dirksen "] edition = "2018" license = "GPL-3.0" @@ -8,19 +8,19 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate RPC for FRAME's support" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] futures = { version = "0.3.0", features = ["compat"] } jsonrpc-client-transports = { version = "14.0.5", default-features = false, features = ["http"] } jsonrpc-core = "14" codec = { package = "parity-scale-codec", version = "1" } serde = "1" -frame-support = { version = "2.0.0-alpha.5", path = "../../../../frame/support" } -sp-storage = { version = "2.0.0-alpha.5", path = "../../../../primitives/storage" } -sc-rpc-api = { version = "0.8.0-alpha.5", path = "../../../../client/rpc-api" } +frame-support = { version = "2.0.0-alpha.6", path = "../../../../frame/support" } +sp-storage = { version = "2.0.0-alpha.6", path = "../../../../primitives/storage" } +sc-rpc-api = { version = "0.8.0-alpha.6", path = "../../../../client/rpc-api" } [dev-dependencies] -frame-system = { version = "2.0.0-alpha.5", path = "../../../../frame/system" } +frame-system = { version = "2.0.0-alpha.6", path = "../../../../frame/system" } tokio = "0.2" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/frame/rpc/system/Cargo.toml b/utils/frame/rpc/system/Cargo.toml index a9e775393d..2c98e41fff 100644 --- a/utils/frame/rpc/system/Cargo.toml +++ b/utils/frame/rpc/system/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-frame-rpc-system" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -8,8 +8,11 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME's system exposed over Substrate RPC" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] -sc-client = { version = "0.8.0-alpha.5", path = "../../../../client/" } +sc-client = { version = "0.8.0-alpha.6", path = "../../../../client/" } codec = { package = "parity-scale-codec", version = "1.3.0" } futures = "0.3.4" jsonrpc-core = "14.0.3" @@ -17,17 +20,14 @@ jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.3" log = "0.4.8" serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.5", path = "../../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.5", path = "../../../../primitives/api" } -frame-system-rpc-runtime-api = { version = "2.0.0-alpha.5", path = "../../../../frame/system/rpc/runtime-api" } -sp-core = { version = "2.0.0-alpha.5", path = "../../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../../primitives/blockchain" } -sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../../primitives/transaction-pool" } +sp-runtime = { version = "2.0.0-alpha.6", path = "../../../../primitives/runtime" } +sp-api = { version = "2.0.0-alpha.6", path = "../../../../primitives/api" } +frame-system-rpc-runtime-api = { version = "2.0.0-alpha.6", path = "../../../../frame/system/rpc/runtime-api" } +sp-core = { version = "2.0.0-alpha.6", path = "../../../../primitives/core" } +sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../../primitives/blockchain" } +sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../../primitives/transaction-pool" } [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../../test-utils/runtime/client" } env_logger = "0.7.0" -sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../../client/transaction-pool" } - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../../client/transaction-pool" } diff --git a/utils/prometheus/Cargo.toml b/utils/prometheus/Cargo.toml index add4b0da5f..307bb7193c 100644 --- a/utils/prometheus/Cargo.toml +++ b/utils/prometheus/Cargo.toml @@ -1,13 +1,16 @@ [package] description = "Endpoint to expose Prometheus metrics" name = "substrate-prometheus-endpoint" -version = "0.8.0-alpha.5" +version = "0.8.0-alpha.6" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] log = "0.4.8" prometheus = "0.8" @@ -18,6 +21,3 @@ derive_more = "0.99" async-std = { version = "1.0.1", features = ["unstable"] } hyper = { version = "0.13.1", default-features = false, features = ["stream"] } tokio = "0.2" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/wasm-builder-runner/Cargo.toml b/utils/wasm-builder-runner/Cargo.toml index 77796ea8d9..c8cbeb169e 100644 --- a/utils/wasm-builder-runner/Cargo.toml +++ b/utils/wasm-builder-runner/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" license = "GPL-3.0" homepage = "https://substrate.dev" -[dependencies] - [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] diff --git a/utils/wasm-builder/Cargo.toml b/utils/wasm-builder/Cargo.toml index ed953cca57..1aa38a790c 100644 --- a/utils/wasm-builder/Cargo.toml +++ b/utils/wasm-builder/Cargo.toml @@ -9,6 +9,9 @@ repository = "https://github.com/paritytech/substrate/" license = "GPL-3.0" homepage = "https://substrate.dev" +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + [dependencies] build-helper = "0.1.1" cargo_metadata = "0.9.0" @@ -19,6 +22,3 @@ fs2 = "0.4.3" wasm-gc-api = "0.1.11" atty = "0.2.13" itertools = "0.8.2" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] -- GitLab From 310fa124a40ddf50da31fadb6dd79208c11e3c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 15 Apr 2020 00:02:14 +0200 Subject: [PATCH 224/300] `decl_runtime_apis!` - check that a method without `changed_in` exists (#5635) * `decl_runtime_apis!` - check that a method without `changed_in` exists This adds another check to the macro that ensures that not only methods with `changed_in` exists, but there are also the default methods exist. * Update primitives/api/proc-macro/src/decl_runtime_apis.rs Co-Authored-By: Nikolay Volf * Fix test Co-authored-by: Nikolay Volf --- .../api/proc-macro/src/decl_runtime_apis.rs | 49 ++++++++++++++++++- primitives/api/src/lib.rs | 4 +- .../tests/ui/changed_in_no_default_method.rs | 19 +++++++ .../ui/changed_in_no_default_method.stderr | 6 +++ 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 primitives/api/test/tests/ui/changed_in_no_default_method.rs create mode 100644 primitives/api/test/tests/ui/changed_in_no_default_method.stderr diff --git a/primitives/api/proc-macro/src/decl_runtime_apis.rs b/primitives/api/proc-macro/src/decl_runtime_apis.rs index e9f3087912..ef50bd840a 100644 --- a/primitives/api/proc-macro/src/decl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/decl_runtime_apis.rs @@ -876,6 +876,53 @@ struct CheckTraitDecl { errors: Vec, } +impl CheckTraitDecl { + /// Check the given trait. + /// + /// All errors will be collected in `self.errors`. + fn check(&mut self, trait_: &ItemTrait) { + self.check_method_declarations(trait_.items.iter().filter_map(|i| match i { + TraitItem::Method(method) => Some(method), + _ => None, + })); + + visit::visit_item_trait(self, trait_); + } + + /// Check that the given method declarations are correct. + /// + /// Any error is stored in `self.errors`. + fn check_method_declarations<'a>(&mut self, methods: impl Iterator) { + let mut method_to_signature_changed = HashMap::>>::new(); + + methods.into_iter().for_each(|method| { + let attributes = remove_supported_attributes(&mut method.attrs.clone()); + + let changed_in = match get_changed_in(&attributes) { + Ok(r) => r, + Err(e) => { self.errors.push(e); return; }, + }; + + method_to_signature_changed + .entry(method.sig.ident.clone()) + .or_default() + .push(changed_in); + }); + + method_to_signature_changed.into_iter().for_each(|(f, changed)| { + // If `changed_in` is `None`, it means it is the current "default" method that calls + // into the latest implementation. + if changed.iter().filter(|c| c.is_none()).count() == 0 { + self.errors.push(Error::new( + f.span(), + "There is no 'default' method with this name (without `changed_in` attribute).\n\ + The 'default' method is used to call into the latest implementation.", + )); + } + }); + } +} + impl<'ast> Visit<'ast> for CheckTraitDecl { fn visit_fn_arg(&mut self, input: &'ast FnArg) { if let FnArg::Receiver(_) = input { @@ -923,7 +970,7 @@ impl<'ast> Visit<'ast> for CheckTraitDecl { /// Check that the trait declarations are in the format we expect. fn check_trait_decls(decls: &[ItemTrait]) -> Result<()> { let mut checker = CheckTraitDecl { errors: Vec::new() }; - decls.iter().for_each(|decl| visit::visit_item_trait(&mut checker, &decl)); + decls.iter().for_each(|decl| checker.check(decl)); if let Some(err) = checker.errors.pop() { Err(checker.errors.into_iter().fold(err, |mut err, other| { diff --git a/primitives/api/src/lib.rs b/primitives/api/src/lib.rs index 74bcf19a99..80a36a904c 100644 --- a/primitives/api/src/lib.rs +++ b/primitives/api/src/lib.rs @@ -113,7 +113,9 @@ use std::{panic::UnwindSafe, cell::RefCell}; /// change is highlighted with the `#[changed_in(2)]` attribute above a method. A method that is /// tagged with this attribute is callable by the name `METHOD_before_version_VERSION`. This /// method will only support calling into wasm, trying to call into native will fail (change the -/// spec version!). Such a method also does not need to be implemented in the runtime. +/// spec version!). Such a method also does not need to be implemented in the runtime. It is +/// required that there exist the "default" of the method without the `#[changed_in(_)]` attribute, +/// this method will be used to call the current default implementation. /// /// ```rust /// sp_api::decl_runtime_apis! { diff --git a/primitives/api/test/tests/ui/changed_in_no_default_method.rs b/primitives/api/test/tests/ui/changed_in_no_default_method.rs new file mode 100644 index 0000000000..6af183a4cd --- /dev/null +++ b/primitives/api/test/tests/ui/changed_in_no_default_method.rs @@ -0,0 +1,19 @@ +use sp_runtime::traits::GetNodeBlockType; +use substrate_test_runtime_client::runtime::Block; + +/// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` +/// trait are done by the `construct_runtime!` macro in a real runtime. +struct Runtime {} +impl GetNodeBlockType for Runtime { + type NodeBlock = Block; +} + +sp_api::decl_runtime_apis! { + #[api_version(2)] + pub trait Api { + #[changed_in(2)] + fn test(data: u64); + } +} + +fn main() {} diff --git a/primitives/api/test/tests/ui/changed_in_no_default_method.stderr b/primitives/api/test/tests/ui/changed_in_no_default_method.stderr new file mode 100644 index 0000000000..ed4c0f9088 --- /dev/null +++ b/primitives/api/test/tests/ui/changed_in_no_default_method.stderr @@ -0,0 +1,6 @@ +error: There is no 'default' method with this name (without `changed_in` attribute). +The 'default' method is used to call into the latest implementation. + --> $DIR/changed_in_no_default_method.rs:15:6 + | +15 | fn test(data: u64); + | ^^^^ -- GitLab From 5938d8623c51c4fd33bd0ae5c7eb860d10ef76d4 Mon Sep 17 00:00:00 2001 From: cheme Date: Wed, 15 Apr 2020 10:23:08 +0200 Subject: [PATCH 225/300] remove terminal space --- primitives/storage/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/primitives/storage/src/lib.rs b/primitives/storage/src/lib.rs index c7cbda520b..49f24a93cb 100644 --- a/primitives/storage/src/lib.rs +++ b/primitives/storage/src/lib.rs @@ -382,10 +382,10 @@ impl ChildTrieParentKeyId { /// A few utilities methods are defined. pub struct ChildrenMap(pub BTreeMap); -/// Type alias for storage of children related content. +/// Type alias for storage of children related content. pub type ChildrenVec = Vec<(ChildInfo, T)>; -/// Type alias for storage of children related content. +/// Type alias for storage of children related content. pub type ChildrenSlice<'a, T> = &'a [(ChildInfo, T)]; #[cfg(feature = "std")] -- GitLab From 5fcd53350d246d005950173accba6ba832ad7463 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 15 Apr 2020 11:10:03 +0200 Subject: [PATCH 226/300] Report tasks metrics to Prometheus (#5619) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Bastian Köcher --- Cargo.lock | 2 +- client/service/Cargo.toml | 2 +- client/service/src/builder.rs | 10 +- client/service/src/lib.rs | 20 ++- client/service/src/task_manager.rs | 150 ++++++++++++++---- .../src/task_manager/prometheus_future.rs | 69 ++++++++ 6 files changed, 211 insertions(+), 42 deletions(-) create mode 100644 client/service/src/task_manager/prometheus_future.rs diff --git a/Cargo.lock b/Cargo.lock index c8e7de7761..b75ecf5fec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6592,7 +6592,6 @@ dependencies = [ "exit-future", "futures 0.1.29", "futures 0.3.4", - "futures-diagnose", "futures-timer 3.0.2", "lazy_static", "log", @@ -6601,6 +6600,7 @@ dependencies = [ "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.2", + "pin-project", "procfs", "sc-chain-spec", "sc-client", diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index b8d1e71097..83cb6d717f 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -24,7 +24,6 @@ wasmtime = [ derive_more = "0.99.2" futures01 = { package = "futures", version = "0.1.29" } futures = "0.3.4" -futures-diagnose = "1.0" parking_lot = "0.10.0" lazy_static = "1.4.0" log = "0.4.8" @@ -32,6 +31,7 @@ slog = { version = "2.5.2", features = ["nested-values"] } futures-timer = "3.0.1" wasm-timer = "0.2" exit-future = "0.2.0" +pin-project = "0.4.8" serde = "1.0.101" serde_json = "1.0.41" sysinfo = "0.12.0" diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 0eefbe730f..acb546fc60 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -170,7 +170,10 @@ fn new_full_parts( KeystoreConfig::InMemory => Keystore::new_in_memory(), }; - let tasks_builder = TaskManagerBuilder::new(); + let tasks_builder = { + let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry); + TaskManagerBuilder::new(registry)? + }; let executor = NativeExecutor::::new( config.wasm_method, @@ -280,7 +283,10 @@ impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { (), TLightBackend, >, Error> { - let tasks_builder = TaskManagerBuilder::new(); + let tasks_builder = { + let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry); + TaskManagerBuilder::new(registry)? + }; let keystore = match &config.keystore { KeystoreConfig::Path { path, password } => Keystore::open( diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index d5db64ea46..969453210e 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -29,7 +29,7 @@ mod builder; mod status_sinks; mod task_manager; -use std::{borrow::Cow, io, pin::Pin}; +use std::{io, pin::Pin}; use std::marker::PhantomData; use std::net::SocketAddr; use std::collections::HashMap; @@ -139,12 +139,18 @@ pub trait AbstractService: 'static + Future> + fn telemetry(&self) -> Option; /// Spawns a task in the background that runs the future passed as parameter. - fn spawn_task(&self, name: impl Into>, task: impl Future + Send + 'static); + /// + /// Information about this task will be reported to Prometheus. + /// + /// The task name is a `&'static str` as opposed to a `String`. The reason for that is that + /// in order to avoid memory consumption issues with the Prometheus metrics, the set of + /// possible task names has to be bounded. + fn spawn_task(&self, name: &'static str, task: impl Future + Send + 'static); /// Spawns a task in the background that runs the future passed as /// parameter. The given task is considered essential, i.e. if it errors we /// trigger a service exit. - fn spawn_essential_task(&self, name: impl Into>, task: impl Future + Send + 'static); + fn spawn_essential_task(&self, name: &'static str, task: impl Future + Send + 'static); /// Returns a handle for spawning tasks. fn spawn_task_handle(&self) -> SpawnTaskHandle; @@ -220,11 +226,11 @@ where self.keystore.clone() } - fn spawn_task(&self, name: impl Into>, task: impl Future + Send + 'static) { + fn spawn_task(&self, name: &'static str, task: impl Future + Send + 'static) { self.task_manager.spawn(name, task) } - fn spawn_essential_task(&self, name: impl Into>, task: impl Future + Send + 'static) { + fn spawn_essential_task(&self, name: &'static str, task: impl Future + Send + 'static) { let mut essential_failed = self.essential_failed_tx.clone(); let essential_task = std::panic::AssertUnwindSafe(task) .catch_unwind() @@ -312,8 +318,8 @@ impl Spawn for &self, future: FutureObj<'static, ()> ) -> Result<(), SpawnError> { - self.task_manager.scheduler().unbounded_send((Box::pin(future), From::from("unnamed"))) - .map_err(|_| SpawnError::shutdown()) + self.task_manager.spawn_handle().spawn("unnamed", future); + Ok(()) } } diff --git a/client/service/src/task_manager.rs b/client/service/src/task_manager.rs index 7c5862e853..fd7fc62ab5 100644 --- a/client/service/src/task_manager.rs +++ b/client/service/src/task_manager.rs @@ -14,9 +14,9 @@ //! Substrate service tasks management module. use std::{ + pin::Pin, result::Result, sync::Arc, task::{Poll, Context}, - borrow::Cow, pin::Pin, }; use exit_future::Signal; use log::{debug, error}; @@ -26,14 +26,21 @@ use futures::{ compat::*, task::{Spawn, FutureObj, SpawnError}, }; +use prometheus_endpoint::{ + exponential_buckets, register, + PrometheusError, + CounterVec, HistogramOpts, HistogramVec, Opts, Registry, U64 +}; use sc_client_api::CloneableSpawn; use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; +mod prometheus_future; + /// Type alias for service task executor (usually runtime). pub type ServiceTaskExecutor = Arc + Send>>) + Send + Sync>; /// Type alias for the task scheduler. -pub type TaskScheduler = TracingUnboundedSender<(Pin + Send>>, Cow<'static, str>)>; +pub type TaskScheduler = TracingUnboundedSender + Send>>>; /// Helper struct to setup background tasks execution for service. pub struct TaskManagerBuilder { @@ -45,20 +52,29 @@ pub struct TaskManagerBuilder { /// Sender for futures that must be spawned as background tasks. to_spawn_tx: TaskScheduler, /// Receiver for futures that must be spawned as background tasks. - to_spawn_rx: TracingUnboundedReceiver<(Pin + Send>>, Cow<'static, str>)>, + to_spawn_rx: TracingUnboundedReceiver + Send>>>, + /// Prometheus metrics where to report the stats about tasks. + metrics: Option, } impl TaskManagerBuilder { /// New asynchronous task manager setup. - pub fn new() -> Self { + /// + /// If a Prometheus registry is passed, it will be used to report statistics about the + /// service tasks. + pub fn new(prometheus_registry: Option<&Registry>) -> Result { let (signal, on_exit) = exit_future::signal(); let (to_spawn_tx, to_spawn_rx) = tracing_unbounded("mpsc_task_manager"); - Self { + + let metrics = prometheus_registry.map(Metrics::register).transpose()?; + + Ok(Self { on_exit, signal: Some(signal), to_spawn_tx, to_spawn_rx, - } + metrics, + }) } /// Get spawn handle. @@ -69,6 +85,7 @@ impl TaskManagerBuilder { SpawnTaskHandle { on_exit: self.on_exit.clone(), sender: self.to_spawn_tx.clone(), + metrics: self.metrics.clone(), } } @@ -78,7 +95,8 @@ impl TaskManagerBuilder { on_exit, signal, to_spawn_rx, - to_spawn_tx + to_spawn_tx, + metrics, } = self; TaskManager { on_exit, @@ -86,6 +104,7 @@ impl TaskManagerBuilder { to_spawn_tx, to_spawn_rx, executor, + metrics, } } } @@ -95,17 +114,45 @@ impl TaskManagerBuilder { pub struct SpawnTaskHandle { sender: TaskScheduler, on_exit: exit_future::Exit, + metrics: Option, } impl SpawnTaskHandle { /// Spawns the given task with the given name. - pub fn spawn(&self, name: impl Into>, task: impl Future + Send + 'static) { + /// + /// Note that the `name` is a `&'static str`. The reason for this choice is that statistics + /// about this task are getting reported to the Prometheus endpoint (if enabled), and that + /// therefore the set of possible task names must be bounded. + /// + /// In other words, it would be a bad idea for someone to do for example + /// `spawn(format!("{:?}", some_public_key))`. + pub fn spawn(&self, name: &'static str, task: impl Future + Send + 'static) { let on_exit = self.on_exit.clone(); + let metrics = self.metrics.clone(); + + // Note that we increase the started counter here and not within the future. This way, + // we could properly visualize on Prometheus situations where the spawning doesn't work. + if let Some(metrics) = &self.metrics { + metrics.tasks_spawned.with_label_values(&[name]).inc(); + // We do a dummy increase in order for the task to show up in metrics. + metrics.tasks_ended.with_label_values(&[name]).inc_by(0); + } + let future = async move { - futures::pin_mut!(task); - let _ = select(on_exit, task).await; + if let Some(metrics) = metrics { + let poll_duration = metrics.poll_duration.with_label_values(&[name]); + let poll_start = metrics.poll_start.with_label_values(&[name]); + let task = prometheus_future::with_poll_durations(poll_duration, poll_start, task); + futures::pin_mut!(task); + let _ = select(on_exit, task).await; + metrics.tasks_ended.with_label_values(&[name]).inc(); + } else { + futures::pin_mut!(task); + let _ = select(on_exit, task).await; + } }; - if self.sender.unbounded_send((Box::pin(future), name.into())).is_err() { + + if self.sender.unbounded_send(Box::pin(future)).is_err() { error!("Failed to send task to spawn over channel"); } } @@ -114,9 +161,8 @@ impl SpawnTaskHandle { impl Spawn for SpawnTaskHandle { fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> { - let future = select(self.on_exit.clone(), future).map(drop); - self.sender.unbounded_send((Box::pin(future), From::from("unnamed"))) - .map_err(|_| SpawnError::shutdown()) + self.spawn("unamed", future); + Ok(()) } } @@ -145,40 +191,34 @@ pub struct TaskManager { /// Sender for futures that must be spawned as background tasks. to_spawn_tx: TaskScheduler, /// Receiver for futures that must be spawned as background tasks. - to_spawn_rx: TracingUnboundedReceiver<(Pin + Send>>, Cow<'static, str>)>, + /// Note: please read comment on [`SpawnTaskHandle::spawn`] for why this is a `&'static str`. + to_spawn_rx: TracingUnboundedReceiver + Send>>>, /// How to spawn background tasks. executor: ServiceTaskExecutor, + /// Prometheus metric where to report the polling times. + metrics: Option, } impl TaskManager { /// Spawn background/async task, which will be aware on exit signal. - pub(super) fn spawn(&self, name: impl Into>, task: impl Future + Send + 'static) { - let on_exit = self.on_exit.clone(); - let future = async move { - futures::pin_mut!(task); - let _ = select(on_exit, task).await; - }; - if self.to_spawn_tx.unbounded_send((Box::pin(future), name.into())).is_err() { - error!("Failed to send task to spawn over channel"); - } + /// + /// See also the documentation of [`SpawnTaskHandler::spawn`]. + pub(super) fn spawn(&self, name: &'static str, task: impl Future + Send + 'static) { + self.spawn_handle().spawn(name, task) } pub(super) fn spawn_handle(&self) -> SpawnTaskHandle { SpawnTaskHandle { on_exit: self.on_exit.clone(), sender: self.to_spawn_tx.clone(), + metrics: self.metrics.clone(), } } - /// Get sender where background/async tasks can be sent. - pub(super) fn scheduler(&self) -> TaskScheduler { - self.to_spawn_tx.clone() - } - /// Process background task receiver. pub(super) fn process_receiver(&mut self, cx: &mut Context) { - while let Poll::Ready(Some((task_to_spawn, name))) = Pin::new(&mut self.to_spawn_rx).poll_next(cx) { - (self.executor)(Box::pin(futures_diagnose::diagnose(name, task_to_spawn))); + while let Poll::Ready(Some(task_to_spawn)) = Pin::new(&mut self.to_spawn_rx).poll_next(cx) { + (self.executor)(task_to_spawn); } } @@ -196,3 +236,51 @@ impl Drop for TaskManager { } } } + +#[derive(Clone)] +struct Metrics { + // This list is ordered alphabetically + poll_duration: HistogramVec, + poll_start: CounterVec, + tasks_spawned: CounterVec, + tasks_ended: CounterVec, +} + +impl Metrics { + fn register(registry: &Registry) -> Result { + Ok(Self { + poll_duration: register(HistogramVec::new( + HistogramOpts { + common_opts: Opts::new( + "tasks_polling_duration", + "Duration in seconds of each invocation of Future::poll" + ), + buckets: exponential_buckets(0.001, 4.0, 9) + .expect("function parameters are constant and always valid; qed"), + }, + &["task_name"] + )?, registry)?, + poll_start: register(CounterVec::new( + Opts::new( + "tasks_polling_started_total", + "Total number of times we started invoking Future::poll" + ), + &["task_name"] + )?, registry)?, + tasks_spawned: register(CounterVec::new( + Opts::new( + "tasks_spawned_total", + "Total number of tasks that have been spawned on the Service" + ), + &["task_name"] + )?, registry)?, + tasks_ended: register(CounterVec::new( + Opts::new( + "tasks_ended_total", + "Total number of tasks for which Future::poll has returned Ready(())" + ), + &["task_name"] + )?, registry)?, + }) + } +} diff --git a/client/service/src/task_manager/prometheus_future.rs b/client/service/src/task_manager/prometheus_future.rs new file mode 100644 index 0000000000..53bd59aa7a --- /dev/null +++ b/client/service/src/task_manager/prometheus_future.rs @@ -0,0 +1,69 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +//! Wrapper around a `Future` that reports statistics about when the `Future` is polled. + +use futures::prelude::*; +use prometheus_endpoint::{Counter, Histogram, U64}; +use std::{fmt, pin::Pin, task::{Context, Poll}}; + +/// Wraps around a `Future`. Report the polling duration to the `Histogram` and when the polling +/// starts to the `Counter`. +pub fn with_poll_durations( + poll_duration: Histogram, + poll_start: Counter, + inner: T +) -> PrometheusFuture { + PrometheusFuture { + inner, + poll_duration, + poll_start, + } +} + +/// Wraps around `Future` and adds diagnostics to it. +#[pin_project::pin_project] +#[derive(Clone)] +pub struct PrometheusFuture { + /// The inner future doing the actual work. + #[pin] + inner: T, + poll_duration: Histogram, + poll_start: Counter, +} + +impl Future for PrometheusFuture +where + T: Future, +{ + type Output = T::Output; + + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { + let this = self.project(); + + this.poll_start.inc(); + let _timer = this.poll_duration.start_timer(); + Future::poll(this.inner, cx) + + // `_timer` is dropped here and will observe the duration + } +} + +impl fmt::Debug for PrometheusFuture +where + T: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&self.inner, f) + } +} -- GitLab From eca2488c1821670cfdaca9543f12aca3e148f1b6 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Wed, 15 Apr 2020 13:18:08 +0200 Subject: [PATCH 227/300] Switch pre-release version to dev (#5637) --- Cargo.lock | 318 +++++++++--------- bin/node-template/node/Cargo.toml | 40 +-- bin/node-template/pallets/template/Cargo.toml | 12 +- bin/node-template/runtime/Cargo.toml | 48 +-- bin/node/bench/Cargo.toml | 12 +- bin/node/cli/Cargo.toml | 116 +++---- bin/node/executor/Cargo.toml | 48 +-- bin/node/inspect/Cargo.toml | 14 +- bin/node/primitives/Cargo.toml | 8 +- bin/node/rpc-client/Cargo.toml | 6 +- bin/node/rpc/Cargo.toml | 34 +- bin/node/runtime/Cargo.toml | 110 +++--- bin/node/runtime/src/lib.rs | 2 +- bin/node/testing/Cargo.toml | 68 ++-- bin/node/transaction-factory/Cargo.toml | 24 +- bin/utils/chain-spec-builder/Cargo.toml | 10 +- bin/utils/subkey/Cargo.toml | 18 +- client/Cargo.toml | 40 +-- client/api/Cargo.toml | 36 +- client/authority-discovery/Cargo.toml | 22 +- client/basic-authorship/Cargo.toml | 24 +- client/block-builder/Cargo.toml | 20 +- client/chain-spec/Cargo.toml | 14 +- client/chain-spec/derive/Cargo.toml | 2 +- client/cli/Cargo.toml | 32 +- client/consensus/aura/Cargo.toml | 46 +-- client/consensus/babe/Cargo.toml | 54 +-- client/consensus/babe/rpc/Cargo.toml | 24 +- client/consensus/epochs/Cargo.toml | 10 +- client/consensus/manual-seal/Cargo.toml | 20 +- client/consensus/pow/Cargo.toml | 22 +- client/consensus/slots/Cargo.toml | 20 +- client/consensus/uncles/Cargo.toml | 14 +- client/db/Cargo.toml | 26 +- client/executor/Cargo.toml | 30 +- client/executor/common/Cargo.toml | 12 +- client/executor/runtime-test/Cargo.toml | 12 +- client/executor/wasmi/Cargo.toml | 12 +- client/executor/wasmtime/Cargo.toml | 12 +- client/finality-grandpa/Cargo.toml | 50 +-- client/informant/Cargo.toml | 12 +- client/keystore/Cargo.toml | 6 +- client/network-gossip/Cargo.toml | 8 +- client/network/Cargo.toml | 30 +- client/network/test/Cargo.toml | 18 +- client/offchain/Cargo.toml | 24 +- client/peerset/Cargo.toml | 4 +- client/rpc-api/Cargo.toml | 14 +- client/rpc-servers/Cargo.toml | 4 +- client/rpc/Cargo.toml | 44 +-- client/service/Cargo.toml | 56 +-- client/service/test/Cargo.toml | 14 +- client/state-db/Cargo.toml | 6 +- client/telemetry/Cargo.toml | 2 +- client/tracing/Cargo.toml | 4 +- client/transaction-pool/Cargo.toml | 20 +- client/transaction-pool/graph/Cargo.toml | 12 +- frame/assets/Cargo.toml | 14 +- frame/aura/Cargo.toml | 26 +- frame/authority-discovery/Cargo.toml | 22 +- frame/authorship/Cargo.toml | 18 +- frame/babe/Cargo.toml | 28 +- frame/balances/Cargo.toml | 18 +- frame/benchmark/Cargo.toml | 14 +- frame/benchmarking/Cargo.toml | 16 +- frame/collective/Cargo.toml | 18 +- frame/contracts/Cargo.toml | 24 +- frame/contracts/common/Cargo.toml | 6 +- frame/contracts/rpc/Cargo.toml | 16 +- frame/contracts/rpc/runtime-api/Cargo.toml | 10 +- frame/democracy/Cargo.toml | 22 +- frame/elections-phragmen/Cargo.toml | 22 +- frame/elections/Cargo.toml | 16 +- frame/evm/Cargo.toml | 18 +- frame/example-offchain-worker/Cargo.toml | 14 +- frame/example/Cargo.toml | 18 +- frame/executive/Cargo.toml | 22 +- frame/finality-tracker/Cargo.toml | 18 +- frame/generic-asset/Cargo.toml | 14 +- frame/grandpa/Cargo.toml | 22 +- frame/identity/Cargo.toml | 18 +- frame/im-online/Cargo.toml | 24 +- frame/indices/Cargo.toml | 18 +- frame/membership/Cargo.toml | 14 +- frame/metadata/Cargo.toml | 6 +- frame/nicks/Cargo.toml | 16 +- frame/offences/Cargo.toml | 18 +- frame/offences/benchmarking/Cargo.toml | 24 +- frame/randomness-collective-flip/Cargo.toml | 14 +- frame/recovery/Cargo.toml | 16 +- frame/scheduler/Cargo.toml | 16 +- frame/scored-pool/Cargo.toml | 16 +- frame/session/Cargo.toml | 22 +- frame/session/benchmarking/Cargo.toml | 26 +- frame/society/Cargo.toml | 16 +- frame/staking/Cargo.toml | 42 +-- frame/staking/reward-curve/Cargo.toml | 4 +- frame/sudo/Cargo.toml | 14 +- frame/support/Cargo.toml | 22 +- frame/support/procedural/Cargo.toml | 4 +- frame/support/procedural/tools/Cargo.toml | 4 +- .../procedural/tools/derive/Cargo.toml | 2 +- frame/support/test/Cargo.toml | 12 +- frame/system/Cargo.toml | 16 +- frame/system/rpc/runtime-api/Cargo.toml | 4 +- frame/timestamp/Cargo.toml | 22 +- frame/transaction-payment/Cargo.toml | 18 +- frame/transaction-payment/rpc/Cargo.toml | 14 +- .../rpc/runtime-api/Cargo.toml | 10 +- frame/treasury/Cargo.toml | 18 +- frame/utility/Cargo.toml | 20 +- frame/vesting/Cargo.toml | 20 +- primitives/allocator/Cargo.toml | 8 +- primitives/api/Cargo.toml | 14 +- primitives/api/proc-macro/Cargo.toml | 2 +- primitives/api/test/Cargo.toml | 16 +- primitives/application-crypto/Cargo.toml | 8 +- primitives/application-crypto/test/Cargo.toml | 8 +- primitives/arithmetic/Cargo.toml | 6 +- primitives/arithmetic/fuzzer/Cargo.toml | 4 +- primitives/authority-discovery/Cargo.toml | 10 +- primitives/authorship/Cargo.toml | 8 +- primitives/block-builder/Cargo.toml | 10 +- primitives/blockchain/Cargo.toml | 10 +- primitives/chain-spec/Cargo.toml | 2 +- primitives/consensus/aura/Cargo.toml | 14 +- primitives/consensus/babe/Cargo.toml | 18 +- primitives/consensus/common/Cargo.toml | 16 +- primitives/consensus/pow/Cargo.toml | 10 +- primitives/consensus/vrf/Cargo.toml | 8 +- primitives/core/Cargo.toml | 14 +- primitives/debug-derive/Cargo.toml | 2 +- primitives/externalities/Cargo.toml | 6 +- primitives/finality-grandpa/Cargo.toml | 10 +- primitives/finality-tracker/Cargo.toml | 6 +- primitives/inherents/Cargo.toml | 6 +- primitives/io/Cargo.toml | 16 +- primitives/keyring/Cargo.toml | 6 +- primitives/offchain/Cargo.toml | 6 +- primitives/panic-handler/Cargo.toml | 2 +- primitives/phragmen/Cargo.toml | 12 +- primitives/phragmen/compact/Cargo.toml | 2 +- primitives/rpc/Cargo.toml | 4 +- primitives/runtime-interface/Cargo.toml | 16 +- .../runtime-interface/proc-macro/Cargo.toml | 2 +- .../test-wasm-deprecated/Cargo.toml | 8 +- .../runtime-interface/test-wasm/Cargo.toml | 8 +- primitives/runtime-interface/test/Cargo.toml | 10 +- primitives/runtime/Cargo.toml | 14 +- primitives/sandbox/Cargo.toml | 10 +- primitives/serializer/Cargo.toml | 2 +- primitives/session/Cargo.toml | 10 +- primitives/staking/Cargo.toml | 6 +- primitives/state-machine/Cargo.toml | 12 +- primitives/std/Cargo.toml | 2 +- primitives/storage/Cargo.toml | 6 +- primitives/test-primitives/Cargo.toml | 6 +- primitives/timestamp/Cargo.toml | 10 +- primitives/transaction-pool/Cargo.toml | 8 +- primitives/trie/Cargo.toml | 8 +- primitives/utils/Cargo.toml | 2 +- primitives/version/Cargo.toml | 6 +- primitives/wasm-interface/Cargo.toml | 4 +- test-utils/Cargo.toml | 2 +- test-utils/client/Cargo.toml | 20 +- test-utils/runtime/Cargo.toml | 54 +-- test-utils/runtime/client/Cargo.toml | 14 +- .../runtime/transaction-pool/Cargo.toml | 8 +- utils/browser/Cargo.toml | 10 +- utils/build-script-utils/Cargo.toml | 2 +- utils/fork-tree/Cargo.toml | 2 +- utils/frame/benchmarking-cli/Cargo.toml | 22 +- utils/frame/rpc/support/Cargo.toml | 10 +- utils/frame/rpc/system/Cargo.toml | 18 +- utils/prometheus/Cargo.toml | 2 +- 175 files changed, 1612 insertions(+), 1612 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b75ecf5fec..72653fefa5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -580,7 +580,7 @@ dependencies = [ [[package]] name = "chain-spec-builder" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "ansi_term 0.12.1", "node-cli", @@ -1425,14 +1425,14 @@ checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" [[package]] name = "fork-tree" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "parity-scale-codec", ] [[package]] name = "frame-benchmarking" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -1448,7 +1448,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "parity-scale-codec", @@ -1466,7 +1466,7 @@ dependencies = [ [[package]] name = "frame-executive" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -1485,7 +1485,7 @@ dependencies = [ [[package]] name = "frame-metadata" -version = "11.0.0-alpha.6" +version = "11.0.0-dev" dependencies = [ "parity-scale-codec", "serde", @@ -1495,7 +1495,7 @@ dependencies = [ [[package]] name = "frame-support" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "bitmask", "frame-metadata", @@ -1520,7 +1520,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support-procedural-tools", "proc-macro2", @@ -1530,7 +1530,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -1541,7 +1541,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "proc-macro2", "quote 1.0.3", @@ -1566,7 +1566,7 @@ dependencies = [ [[package]] name = "frame-system" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "criterion 0.2.11", "frame-support", @@ -1584,7 +1584,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "parity-scale-codec", "sp-api", @@ -3373,7 +3373,7 @@ dependencies = [ [[package]] name = "node-bench" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "log", "node-primitives", @@ -3388,7 +3388,7 @@ dependencies = [ [[package]] name = "node-cli" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "assert_cmd", "frame-benchmarking-cli", @@ -3461,7 +3461,7 @@ dependencies = [ [[package]] name = "node-executor" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "criterion 0.3.1", "frame-benchmarking", @@ -3495,7 +3495,7 @@ dependencies = [ [[package]] name = "node-inspect" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "derive_more", "log", @@ -3511,7 +3511,7 @@ dependencies = [ [[package]] name = "node-primitives" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "pretty_assertions", "sp-core", @@ -3521,7 +3521,7 @@ dependencies = [ [[package]] name = "node-rpc" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "jsonrpc-core", "node-primitives", @@ -3544,7 +3544,7 @@ dependencies = [ [[package]] name = "node-rpc-client" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "env_logger 0.7.1", "futures 0.1.29", @@ -3557,7 +3557,7 @@ dependencies = [ [[package]] name = "node-runtime" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "frame-executive", @@ -3621,7 +3621,7 @@ dependencies = [ [[package]] name = "node-template" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "futures 0.3.4", "log", @@ -3649,7 +3649,7 @@ dependencies = [ [[package]] name = "node-template-runtime" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-executive", "frame-support", @@ -3681,7 +3681,7 @@ dependencies = [ [[package]] name = "node-testing" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "criterion 0.3.1", "frame-support", @@ -3727,7 +3727,7 @@ dependencies = [ [[package]] name = "node-transaction-factory" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "log", "parity-scale-codec", @@ -3918,7 +3918,7 @@ dependencies = [ [[package]] name = "pallet-assets" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -3932,7 +3932,7 @@ dependencies = [ [[package]] name = "pallet-aura" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -3954,7 +3954,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -3972,7 +3972,7 @@ dependencies = [ [[package]] name = "pallet-authorship" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -3988,7 +3988,7 @@ dependencies = [ [[package]] name = "pallet-babe" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4009,7 +4009,7 @@ dependencies = [ [[package]] name = "pallet-balances" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "frame-support", @@ -4025,7 +4025,7 @@ dependencies = [ [[package]] name = "pallet-benchmark" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "frame-support", @@ -4039,7 +4039,7 @@ dependencies = [ [[package]] name = "pallet-collective" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "frame-support", @@ -4056,7 +4056,7 @@ dependencies = [ [[package]] name = "pallet-contracts" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "assert_matches", "frame-support", @@ -4081,7 +4081,7 @@ dependencies = [ [[package]] name = "pallet-contracts-primitives" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -4090,7 +4090,7 @@ dependencies = [ [[package]] name = "pallet-contracts-rpc" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4109,7 +4109,7 @@ dependencies = [ [[package]] name = "pallet-contracts-rpc-runtime-api" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "pallet-contracts-primitives", "parity-scale-codec", @@ -4120,7 +4120,7 @@ dependencies = [ [[package]] name = "pallet-democracy" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "frame-support", @@ -4139,7 +4139,7 @@ dependencies = [ [[package]] name = "pallet-elections" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4155,7 +4155,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4174,7 +4174,7 @@ dependencies = [ [[package]] name = "pallet-evm" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "evm", "frame-support", @@ -4194,7 +4194,7 @@ dependencies = [ [[package]] name = "pallet-example" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "frame-support", @@ -4210,7 +4210,7 @@ dependencies = [ [[package]] name = "pallet-example-offchain-worker" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4225,7 +4225,7 @@ dependencies = [ [[package]] name = "pallet-finality-tracker" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4242,7 +4242,7 @@ dependencies = [ [[package]] name = "pallet-generic-asset" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4256,7 +4256,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4274,7 +4274,7 @@ dependencies = [ [[package]] name = "pallet-identity" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "enumflags2", "frame-benchmarking", @@ -4291,7 +4291,7 @@ dependencies = [ [[package]] name = "pallet-im-online" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "frame-support", @@ -4310,7 +4310,7 @@ dependencies = [ [[package]] name = "pallet-indices" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4326,7 +4326,7 @@ dependencies = [ [[package]] name = "pallet-membership" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4340,7 +4340,7 @@ dependencies = [ [[package]] name = "pallet-nicks" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4355,7 +4355,7 @@ dependencies = [ [[package]] name = "pallet-offences" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4371,7 +4371,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "frame-support", @@ -4389,7 +4389,7 @@ dependencies = [ [[package]] name = "pallet-randomness-collective-flip" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4403,7 +4403,7 @@ dependencies = [ [[package]] name = "pallet-recovery" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "enumflags2", "frame-support", @@ -4419,7 +4419,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "frame-support", @@ -4434,7 +4434,7 @@ dependencies = [ [[package]] name = "pallet-scored-pool" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4449,7 +4449,7 @@ dependencies = [ [[package]] name = "pallet-session" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4469,7 +4469,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "frame-support", @@ -4489,7 +4489,7 @@ dependencies = [ [[package]] name = "pallet-society" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4505,7 +4505,7 @@ dependencies = [ [[package]] name = "pallet-staking" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "env_logger 0.7.1", "frame-benchmarking", @@ -4537,7 +4537,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -4548,7 +4548,7 @@ dependencies = [ [[package]] name = "pallet-sudo" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4562,7 +4562,7 @@ dependencies = [ [[package]] name = "pallet-template" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4574,7 +4574,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "frame-support", @@ -4592,7 +4592,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -4607,7 +4607,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4624,7 +4624,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "parity-scale-codec", @@ -4637,7 +4637,7 @@ dependencies = [ [[package]] name = "pallet-treasury" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "frame-support", @@ -4653,7 +4653,7 @@ dependencies = [ [[package]] name = "pallet-utility" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-benchmarking", "frame-support", @@ -4669,7 +4669,7 @@ dependencies = [ [[package]] name = "pallet-vesting" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "enumflags2", "frame-benchmarking", @@ -5741,7 +5741,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "bytes 0.5.4", "derive_more", @@ -5771,7 +5771,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", @@ -5795,7 +5795,7 @@ dependencies = [ [[package]] name = "sc-block-builder" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -5812,7 +5812,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "impl-trait-for-tuples", "sc-chain-spec-derive", @@ -5827,7 +5827,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5837,7 +5837,7 @@ dependencies = [ [[package]] name = "sc-cli" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "ansi_term 0.12.1", "app_dirs", @@ -5879,7 +5879,7 @@ dependencies = [ [[package]] name = "sc-client" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "derive_more", "env_logger 0.7.1", @@ -5918,7 +5918,7 @@ dependencies = [ [[package]] name = "sc-client-api" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "derive_more", "fnv", @@ -5952,7 +5952,7 @@ dependencies = [ [[package]] name = "sc-client-db" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "env_logger 0.7.1", "hash-db", @@ -5983,7 +5983,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "derive_more", "env_logger 0.7.1", @@ -6021,7 +6021,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "derive_more", "env_logger 0.7.1", @@ -6071,7 +6071,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "derive_more", "futures 0.3.4", @@ -6096,7 +6096,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "fork-tree", "parity-scale-codec", @@ -6108,7 +6108,7 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "assert_matches", "derive_more", @@ -6137,7 +6137,7 @@ dependencies = [ [[package]] name = "sc-consensus-pow" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "derive_more", "futures 0.3.4", @@ -6157,7 +6157,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", @@ -6178,7 +6178,7 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "log", "sc-client-api", @@ -6191,7 +6191,7 @@ dependencies = [ [[package]] name = "sc-executor" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "assert_matches", "derive_more", @@ -6225,7 +6225,7 @@ dependencies = [ [[package]] name = "sc-executor-common" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "derive_more", "log", @@ -6241,7 +6241,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "log", "parity-scale-codec", @@ -6255,7 +6255,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "assert_matches", "cranelift-codegen", @@ -6276,7 +6276,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "assert_matches", "env_logger 0.7.1", @@ -6319,7 +6319,7 @@ dependencies = [ [[package]] name = "sc-informant" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "ansi_term 0.12.1", "futures 0.3.4", @@ -6335,7 +6335,7 @@ dependencies = [ [[package]] name = "sc-keystore" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "derive_more", "hex", @@ -6350,7 +6350,7 @@ dependencies = [ [[package]] name = "sc-network" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "assert_matches", "async-std", @@ -6410,7 +6410,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", @@ -6451,7 +6451,7 @@ dependencies = [ [[package]] name = "sc-offchain" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "bytes 0.5.4", "env_logger 0.7.1", @@ -6484,7 +6484,7 @@ dependencies = [ [[package]] name = "sc-peerset" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "futures 0.3.4", "libp2p", @@ -6497,7 +6497,7 @@ dependencies = [ [[package]] name = "sc-rpc" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "assert_matches", "futures 0.1.29", @@ -6536,7 +6536,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "derive_more", "futures 0.3.4", @@ -6559,7 +6559,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "jsonrpc-core", "jsonrpc-http-server", @@ -6586,7 +6586,7 @@ dependencies = [ [[package]] name = "sc-service" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "derive_more", "exit-future", @@ -6660,7 +6660,7 @@ dependencies = [ [[package]] name = "sc-state-db" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "env_logger 0.7.1", "log", @@ -6674,7 +6674,7 @@ dependencies = [ [[package]] name = "sc-telemetry" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "bytes 0.5.4", "futures 0.3.4", @@ -6695,7 +6695,7 @@ dependencies = [ [[package]] name = "sc-tracing" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "erased-serde", "log", @@ -6710,7 +6710,7 @@ dependencies = [ [[package]] name = "sc-transaction-graph" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "assert_matches", "criterion 0.3.1", @@ -6733,7 +6733,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "assert_matches", "derive_more", @@ -7100,7 +7100,7 @@ dependencies = [ [[package]] name = "sp-allocator" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "derive_more", "log", @@ -7111,7 +7111,7 @@ dependencies = [ [[package]] name = "sp-api" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "hash-db", "parity-scale-codec", @@ -7126,7 +7126,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "blake2-rfc", "proc-macro-crate", @@ -7156,7 +7156,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "parity-scale-codec", "serde", @@ -7178,7 +7178,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "criterion 0.3.1", "integer-sqrt", @@ -7194,7 +7194,7 @@ dependencies = [ [[package]] name = "sp-arithmetic-fuzzer" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "honggfuzz", "num-bigint", @@ -7205,7 +7205,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "parity-scale-codec", "sp-api", @@ -7216,7 +7216,7 @@ dependencies = [ [[package]] name = "sp-authorship" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -7226,7 +7226,7 @@ dependencies = [ [[package]] name = "sp-block-builder" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "parity-scale-codec", "sp-api", @@ -7237,7 +7237,7 @@ dependencies = [ [[package]] name = "sp-blockchain" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "derive_more", "log", @@ -7252,7 +7252,7 @@ dependencies = [ [[package]] name = "sp-chain-spec" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "serde", "serde_json", @@ -7260,7 +7260,7 @@ dependencies = [ [[package]] name = "sp-consensus" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "derive_more", "futures 0.3.4", @@ -7283,7 +7283,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "parity-scale-codec", "sp-api", @@ -7296,7 +7296,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "parity-scale-codec", "sp-api", @@ -7311,7 +7311,7 @@ dependencies = [ [[package]] name = "sp-consensus-pow" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "parity-scale-codec", "sp-api", @@ -7322,7 +7322,7 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "parity-scale-codec", "schnorrkel", @@ -7333,7 +7333,7 @@ dependencies = [ [[package]] name = "sp-core" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "base58", "blake2-rfc", @@ -7377,7 +7377,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "proc-macro2", "quote 1.0.3", @@ -7386,7 +7386,7 @@ dependencies = [ [[package]] name = "sp-externalities" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "environmental", "sp-std", @@ -7395,7 +7395,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "parity-scale-codec", "serde", @@ -7407,7 +7407,7 @@ dependencies = [ [[package]] name = "sp-finality-tracker" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -7416,7 +7416,7 @@ dependencies = [ [[package]] name = "sp-inherents" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "derive_more", "parity-scale-codec", @@ -7427,7 +7427,7 @@ dependencies = [ [[package]] name = "sp-io" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "hash-db", "libsecp256k1", @@ -7444,7 +7444,7 @@ dependencies = [ [[package]] name = "sp-keyring" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "lazy_static", "sp-core", @@ -7454,7 +7454,7 @@ dependencies = [ [[package]] name = "sp-offchain" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "sp-api", "sp-runtime", @@ -7462,7 +7462,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "backtrace", "log", @@ -7470,7 +7470,7 @@ dependencies = [ [[package]] name = "sp-phragmen" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "parity-scale-codec", "rand 0.7.3", @@ -7484,7 +7484,7 @@ dependencies = [ [[package]] name = "sp-phragmen-compact" -version = "2.0.0-dev.1" +version = "2.0.0-dev" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -7494,7 +7494,7 @@ dependencies = [ [[package]] name = "sp-rpc" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "serde", "serde_json", @@ -7503,7 +7503,7 @@ dependencies = [ [[package]] name = "sp-runtime" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "hash256-std-hasher", "impl-trait-for-tuples", @@ -7524,7 +7524,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "parity-scale-codec", "primitive-types", @@ -7543,7 +7543,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "Inflector", "proc-macro-crate", @@ -7589,7 +7589,7 @@ dependencies = [ [[package]] name = "sp-sandbox" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "assert_matches", "parity-scale-codec", @@ -7603,7 +7603,7 @@ dependencies = [ [[package]] name = "sp-serializer" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "serde", "serde_json", @@ -7611,7 +7611,7 @@ dependencies = [ [[package]] name = "sp-session" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "sp-api", "sp-core", @@ -7621,7 +7621,7 @@ dependencies = [ [[package]] name = "sp-staking" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -7630,7 +7630,7 @@ dependencies = [ [[package]] name = "sp-state-machine" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "hash-db", "hex-literal", @@ -7650,11 +7650,11 @@ dependencies = [ [[package]] name = "sp-std" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" [[package]] name = "sp-storage" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "impl-serde 0.2.3", "serde", @@ -7676,7 +7676,7 @@ dependencies = [ [[package]] name = "sp-timestamp" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -7689,7 +7689,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "derive_more", "futures 0.3.4", @@ -7703,7 +7703,7 @@ dependencies = [ [[package]] name = "sp-trie" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "criterion 0.2.11", "hash-db", @@ -7721,7 +7721,7 @@ dependencies = [ [[package]] name = "sp-utils" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "futures 0.3.4", "futures-core", @@ -7731,7 +7731,7 @@ dependencies = [ [[package]] name = "sp-version" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "impl-serde 0.2.3", "parity-scale-codec", @@ -7742,7 +7742,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -7857,7 +7857,7 @@ dependencies = [ [[package]] name = "subkey" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "clap", "derive_more", @@ -7898,7 +7898,7 @@ dependencies = [ [[package]] name = "substrate-browser-utils" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "chrono", "clear_on_drop", @@ -7923,14 +7923,14 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "platforms", ] [[package]] name = "substrate-frame-rpc-support" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "frame-support", "frame-system", @@ -7946,7 +7946,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" dependencies = [ "env_logger 0.7.1", "frame-system-rpc-runtime-api", @@ -7969,7 +7969,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" dependencies = [ "async-std", "derive_more", @@ -8075,7 +8075,7 @@ dependencies = [ [[package]] name = "substrate-test-utils" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" [[package]] name = "substrate-wasm-builder" diff --git a/bin/node-template/node/Cargo.toml b/bin/node-template/node/Cargo.toml index d8ce4b590b..c53710eab4 100644 --- a/bin/node-template/node/Cargo.toml +++ b/bin/node-template/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-template" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Anonymous"] description = "Substrate Node template" edition = "2018" @@ -20,25 +20,25 @@ futures = "0.3.4" log = "0.4.8" structopt = "0.3.8" -sc-cli = { version = "0.8.0-alpha.6", path = "../../../client/cli" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sc-executor = { version = "0.8.0-alpha.6", path = "../../../client/executor" } -sc-service = { version = "0.8.0-alpha.6", path = "../../../client/service" } -sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } -sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../client/transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../primitives/transaction-pool" } -sc-network = { version = "0.8.0-alpha.6", path = "../../../client/network" } -sc-consensus-aura = { version = "0.8.0-alpha.6", path = "../../../client/consensus/aura" } -sp-consensus-aura = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/aura" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } -sc-finality-grandpa = { version = "0.8.0-alpha.6", path = "../../../client/finality-grandpa" } -sp-finality-grandpa = { version = "2.0.0-alpha.6", path = "../../../primitives/finality-grandpa" } -sc-client = { version = "0.8.0-alpha.6", path = "../../../client/" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sc-basic-authorship = { path = "../../../client/basic-authorship", version = "0.8.0-alpha.6"} +sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sc-executor = { version = "0.8.0-dev", path = "../../../client/executor" } +sc-service = { version = "0.8.0-dev", path = "../../../client/service" } +sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } +sc-transaction-pool = { version = "2.0.0-dev", path = "../../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../../primitives/transaction-pool" } +sc-network = { version = "0.8.0-dev", path = "../../../client/network" } +sc-consensus-aura = { version = "0.8.0-dev", path = "../../../client/consensus/aura" } +sp-consensus-aura = { version = "0.8.0-dev", path = "../../../primitives/consensus/aura" } +sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } +sc-finality-grandpa = { version = "0.8.0-dev", path = "../../../client/finality-grandpa" } +sp-finality-grandpa = { version = "2.0.0-dev", path = "../../../primitives/finality-grandpa" } +sc-client = { version = "0.8.0-dev", path = "../../../client/" } +sc-client-api = { version = "2.0.0-dev", path = "../../../client/api" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sc-basic-authorship = { path = "../../../client/basic-authorship", version = "0.8.0-dev"} -node-template-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } +node-template-runtime = { version = "2.0.0-dev", path = "../runtime" } [build-dependencies] -substrate-build-script-utils = { version = "2.0.0-alpha.6", path = "../../../utils/build-script-utils" } +substrate-build-script-utils = { version = "2.0.0-dev", path = "../../../utils/build-script-utils" } diff --git a/bin/node-template/pallets/template/Cargo.toml b/bin/node-template/pallets/template/Cargo.toml index 4a2c5ccad1..01484c608c 100644 --- a/bin/node-template/pallets/template/Cargo.toml +++ b/bin/node-template/pallets/template/Cargo.toml @@ -2,7 +2,7 @@ authors = ['Anonymous'] edition = '2018' name = 'pallet-template' -version = "2.0.0-alpha.6" +version = "2.0.0-dev" license = "Unlicense" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -16,26 +16,26 @@ codec = { package = "parity-scale-codec", version = "1.3.0", default-features = [dependencies.frame-support] default-features = false -version = "2.0.0-alpha.6" +version = "2.0.0-dev" path = "../../../../frame/support" [dependencies.frame-system] default-features = false -version = "2.0.0-alpha.6" +version = "2.0.0-dev" path = "../../../../frame/system" [dev-dependencies.sp-core] default-features = false -version = "2.0.0-alpha.6" +version = "2.0.0-dev" path = "../../../../primitives/core" [dev-dependencies.sp-io] default-features = false -version = "2.0.0-alpha.6" +version = "2.0.0-dev" path = "../../../../primitives/io" [dev-dependencies.sp-runtime] default-features = false -version = "2.0.0-alpha.6" +version = "2.0.0-dev" path = "../../../../primitives/runtime" diff --git a/bin/node-template/runtime/Cargo.toml b/bin/node-template/runtime/Cargo.toml index 4f6f528f05..dfd517130b 100644 --- a/bin/node-template/runtime/Cargo.toml +++ b/bin/node-template/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-template-runtime" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Anonymous"] edition = "2018" license = "Unlicense" @@ -13,31 +13,31 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -aura = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-aura", path = "../../../frame/aura" } -balances = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-balances", path = "../../../frame/balances" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/support" } -grandpa = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-grandpa", path = "../../../frame/grandpa" } -randomness-collective-flip = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-randomness-collective-flip", path = "../../../frame/randomness-collective-flip" } -sudo = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-sudo", path = "../../../frame/sudo" } -system = { version = "2.0.0-alpha.6", default-features = false, package = "frame-system", path = "../../../frame/system" } -timestamp = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-timestamp", path = "../../../frame/timestamp" } -transaction-payment = { version = "2.0.0-alpha.6", default-features = false, package = "pallet-transaction-payment", path = "../../../frame/transaction-payment" } -frame-executive = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/executive" } +aura = { version = "2.0.0-dev", default-features = false, package = "pallet-aura", path = "../../../frame/aura" } +balances = { version = "2.0.0-dev", default-features = false, package = "pallet-balances", path = "../../../frame/balances" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../../../frame/support" } +grandpa = { version = "2.0.0-dev", default-features = false, package = "pallet-grandpa", path = "../../../frame/grandpa" } +randomness-collective-flip = { version = "2.0.0-dev", default-features = false, package = "pallet-randomness-collective-flip", path = "../../../frame/randomness-collective-flip" } +sudo = { version = "2.0.0-dev", default-features = false, package = "pallet-sudo", path = "../../../frame/sudo" } +system = { version = "2.0.0-dev", default-features = false, package = "frame-system", path = "../../../frame/system" } +timestamp = { version = "2.0.0-dev", default-features = false, package = "pallet-timestamp", path = "../../../frame/timestamp" } +transaction-payment = { version = "2.0.0-dev", default-features = false, package = "pallet-transaction-payment", path = "../../../frame/transaction-payment" } +frame-executive = { version = "2.0.0-dev", default-features = false, path = "../../../frame/executive" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/api" } -sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.6"} -sp-consensus-aura = { version = "0.8.0-alpha.6", default-features = false, path = "../../../primitives/consensus/aura" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/core" } -sp-inherents = { path = "../../../primitives/inherents", default-features = false, version = "2.0.0-alpha.6"} -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/io" } -sp-offchain = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/offchain" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } -sp-session = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/session" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/std" } -sp-transaction-pool = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/transaction-pool" } -sp-version = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/version" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/api" } +sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-dev"} +sp-consensus-aura = { version = "0.8.0-dev", default-features = false, path = "../../../primitives/consensus/aura" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/core" } +sp-inherents = { path = "../../../primitives/inherents", default-features = false, version = "2.0.0-dev"} +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/io" } +sp-offchain = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/offchain" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } +sp-session = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/session" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/std" } +sp-transaction-pool = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/transaction-pool" } +sp-version = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/version" } -template = { version = "2.0.0-alpha.6", default-features = false, path = "../pallets/template", package = "pallet-template" } +template = { version = "2.0.0-dev", default-features = false, path = "../pallets/template", package = "pallet-template" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } diff --git a/bin/node/bench/Cargo.toml b/bin/node/bench/Cargo.toml index c07c75e2cf..875a908921 100644 --- a/bin/node/bench/Cargo.toml +++ b/bin/node/bench/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-bench" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Substrate node integration benchmarks." edition = "2018" @@ -10,11 +10,11 @@ license = "GPL-3.0" [dependencies] log = "0.4.8" -node-primitives = { version = "2.0.0-alpha.6", path = "../primitives" } -node-testing = { version = "2.0.0-alpha.6", path = "../testing" } -sc-cli = { version = "0.8.0-alpha.6", path = "../../../client/cli" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api/" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +node-primitives = { version = "2.0.0-dev", path = "../primitives" } +node-testing = { version = "2.0.0-dev", path = "../testing" } +sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0-dev", path = "../../../client/api/" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } serde = "1.0.101" serde_json = "1.0.41" structopt = "0.3" diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index f0cbbcbe97..6d7beaa5ee 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-cli" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] description = "Generic Substrate node implementation in Rust." build = "build.rs" @@ -45,74 +45,74 @@ structopt = { version = "0.3.8", optional = true } tracing = "0.1.10" # primitives -sp-authority-discovery = { version = "2.0.0-alpha.6", path = "../../../primitives/authority-discovery" } -sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/babe" } -grandpa-primitives = { version = "2.0.0-alpha.6", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/timestamp" } -sp-finality-tracker = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/finality-tracker" } -sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.6", path = "../../../primitives/keyring" } -sp-io = { version = "2.0.0-alpha.6", path = "../../../primitives/io" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../primitives/transaction-pool" } +sp-authority-discovery = { version = "2.0.0-dev", path = "../../../primitives/authority-discovery" } +sp-consensus-babe = { version = "0.8.0-dev", path = "../../../primitives/consensus/babe" } +grandpa-primitives = { version = "2.0.0-dev", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/timestamp" } +sp-finality-tracker = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/finality-tracker" } +sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } +sp-keyring = { version = "2.0.0-dev", path = "../../../primitives/keyring" } +sp-io = { version = "2.0.0-dev", path = "../../../primitives/io" } +sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../../primitives/transaction-pool" } # client dependencies -sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api" } -sc-client = { version = "0.8.0-alpha.6", path = "../../../client/" } -sc-chain-spec = { version = "2.0.0-alpha.6", path = "../../../client/chain-spec" } -sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../client/transaction-pool" } -sc-network = { version = "0.8.0-alpha.6", path = "../../../client/network" } -sc-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../client/consensus/babe" } -grandpa = { version = "0.8.0-alpha.6", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } -sc-client-db = { version = "0.8.0-alpha.6", default-features = false, path = "../../../client/db" } -sc-offchain = { version = "2.0.0-alpha.6", path = "../../../client/offchain" } -sc-rpc = { version = "2.0.0-alpha.6", path = "../../../client/rpc" } -sc-basic-authorship = { version = "0.8.0-alpha.6", path = "../../../client/basic-authorship" } -sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../../../client/service" } -sc-tracing = { version = "2.0.0-alpha.6", path = "../../../client/tracing" } -sc-telemetry = { version = "2.0.0-alpha.6", path = "../../../client/telemetry" } -sc-authority-discovery = { version = "0.8.0-alpha.6", path = "../../../client/authority-discovery" } +sc-client-api = { version = "2.0.0-dev", path = "../../../client/api" } +sc-client = { version = "0.8.0-dev", path = "../../../client/" } +sc-chain-spec = { version = "2.0.0-dev", path = "../../../client/chain-spec" } +sc-transaction-pool = { version = "2.0.0-dev", path = "../../../client/transaction-pool" } +sc-network = { version = "0.8.0-dev", path = "../../../client/network" } +sc-consensus-babe = { version = "0.8.0-dev", path = "../../../client/consensus/babe" } +grandpa = { version = "0.8.0-dev", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } +sc-client-db = { version = "0.8.0-dev", default-features = false, path = "../../../client/db" } +sc-offchain = { version = "2.0.0-dev", path = "../../../client/offchain" } +sc-rpc = { version = "2.0.0-dev", path = "../../../client/rpc" } +sc-basic-authorship = { version = "0.8.0-dev", path = "../../../client/basic-authorship" } +sc-service = { version = "0.8.0-dev", default-features = false, path = "../../../client/service" } +sc-tracing = { version = "2.0.0-dev", path = "../../../client/tracing" } +sc-telemetry = { version = "2.0.0-dev", path = "../../../client/telemetry" } +sc-authority-discovery = { version = "0.8.0-dev", path = "../../../client/authority-discovery" } # frame dependencies -pallet-indices = { version = "2.0.0-alpha.6", path = "../../../frame/indices" } -pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/timestamp" } -pallet-contracts = { version = "2.0.0-alpha.6", path = "../../../frame/contracts" } -frame-system = { version = "2.0.0-alpha.6", path = "../../../frame/system" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../../../frame/balances" } -pallet-transaction-payment = { version = "2.0.0-alpha.6", path = "../../../frame/transaction-payment" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/support" } -pallet-im-online = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/im-online" } -pallet-authority-discovery = { version = "2.0.0-alpha.6", path = "../../../frame/authority-discovery" } -pallet-staking = { version = "2.0.0-alpha.6", path = "../../../frame/staking" } +pallet-indices = { version = "2.0.0-dev", path = "../../../frame/indices" } +pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../../frame/timestamp" } +pallet-contracts = { version = "2.0.0-dev", path = "../../../frame/contracts" } +frame-system = { version = "2.0.0-dev", path = "../../../frame/system" } +pallet-balances = { version = "2.0.0-dev", path = "../../../frame/balances" } +pallet-transaction-payment = { version = "2.0.0-dev", path = "../../../frame/transaction-payment" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../../../frame/support" } +pallet-im-online = { version = "2.0.0-dev", default-features = false, path = "../../../frame/im-online" } +pallet-authority-discovery = { version = "2.0.0-dev", path = "../../../frame/authority-discovery" } +pallet-staking = { version = "2.0.0-dev", path = "../../../frame/staking" } # node-specific dependencies -node-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } -node-rpc = { version = "2.0.0-alpha.6", path = "../rpc" } -node-primitives = { version = "2.0.0-alpha.6", path = "../primitives" } -node-executor = { version = "2.0.0-alpha.6", path = "../executor" } +node-runtime = { version = "2.0.0-dev", path = "../runtime" } +node-rpc = { version = "2.0.0-dev", path = "../rpc" } +node-primitives = { version = "2.0.0-dev", path = "../primitives" } +node-executor = { version = "2.0.0-dev", path = "../executor" } # CLI-specific dependencies -sc-cli = { version = "0.8.0-alpha.6", optional = true, path = "../../../client/cli" } -frame-benchmarking-cli = { version = "2.0.0-alpha.6", optional = true, path = "../../../utils/frame/benchmarking-cli" } -node-transaction-factory = { version = "0.8.0-alpha.6", optional = true, path = "../transaction-factory" } -node-inspect = { version = "0.8.0-alpha.6", optional = true, path = "../inspect" } +sc-cli = { version = "0.8.0-dev", optional = true, path = "../../../client/cli" } +frame-benchmarking-cli = { version = "2.0.0-dev", optional = true, path = "../../../utils/frame/benchmarking-cli" } +node-transaction-factory = { version = "0.8.0-dev", optional = true, path = "../transaction-factory" } +node-inspect = { version = "0.8.0-dev", optional = true, path = "../inspect" } # WASM-specific dependencies wasm-bindgen = { version = "0.2.57", optional = true } wasm-bindgen-futures = { version = "0.4.7", optional = true } -browser-utils = { package = "substrate-browser-utils", path = "../../../utils/browser", optional = true, version = "0.8.0-alpha.6"} +browser-utils = { package = "substrate-browser-utils", path = "../../../utils/browser", optional = true, version = "0.8.0-dev"} [target.'cfg(target_arch="x86_64")'.dependencies] -node-executor = { version = "2.0.0-alpha.6", path = "../executor", features = [ "wasmtime" ] } -sc-cli = { version = "0.8.0-alpha.6", optional = true, path = "../../../client/cli", features = [ "wasmtime" ] } -sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../../../client/service", features = [ "wasmtime" ] } +node-executor = { version = "2.0.0-dev", path = "../executor", features = [ "wasmtime" ] } +sc-cli = { version = "0.8.0-dev", optional = true, path = "../../../client/cli", features = [ "wasmtime" ] } +sc-service = { version = "0.8.0-dev", default-features = false, path = "../../../client/service", features = [ "wasmtime" ] } [dev-dependencies] -sc-keystore = { version = "2.0.0-alpha.6", path = "../../../client/keystore" } -sc-consensus-babe = { version = "0.8.0-alpha.6", features = ["test-helpers"], path = "../../../client/consensus/babe" } -sc-consensus-epochs = { version = "0.8.0-alpha.6", path = "../../../client/consensus/epochs" } +sc-keystore = { version = "2.0.0-dev", path = "../../../client/keystore" } +sc-consensus-babe = { version = "0.8.0-dev", features = ["test-helpers"], path = "../../../client/consensus/babe" } +sc-consensus-epochs = { version = "0.8.0-dev", path = "../../../client/consensus/epochs" } sc-service-test = { version = "2.0.0-dev", path = "../../../client/service/test" } futures = "0.3.4" tempfile = "3.1.0" @@ -124,13 +124,13 @@ platforms = "0.2.1" [build-dependencies] structopt = { version = "0.3.8", optional = true } -node-transaction-factory = { version = "0.8.0-alpha.6", optional = true, path = "../transaction-factory" } -node-inspect = { version = "0.8.0-alpha.6", optional = true, path = "../inspect" } -frame-benchmarking-cli = { version = "2.0.0-alpha.6", optional = true, path = "../../../utils/frame/benchmarking-cli" } -substrate-build-script-utils = { version = "2.0.0-alpha.6", optional = true, path = "../../../utils/build-script-utils" } +node-transaction-factory = { version = "0.8.0-dev", optional = true, path = "../transaction-factory" } +node-inspect = { version = "0.8.0-dev", optional = true, path = "../inspect" } +frame-benchmarking-cli = { version = "2.0.0-dev", optional = true, path = "../../../utils/frame/benchmarking-cli" } +substrate-build-script-utils = { version = "2.0.0-dev", optional = true, path = "../../../utils/build-script-utils" } [build-dependencies.sc-cli] -version = "0.8.0-alpha.6" +version = "0.8.0-dev" package = "sc-cli" path = "../../../client/cli" optional = true diff --git a/bin/node/executor/Cargo.toml b/bin/node/executor/Cargo.toml index 791999eb40..99bd83bb4a 100644 --- a/bin/node/executor/Cargo.toml +++ b/bin/node/executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-executor" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] description = "Substrate node implementation in Rust." edition = "2018" @@ -13,33 +13,33 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0" } -node-primitives = { version = "2.0.0-alpha.6", path = "../primitives" } -node-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } -sc-executor = { version = "0.8.0-alpha.6", path = "../../../client/executor" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-io = { version = "2.0.0-alpha.6", path = "../../../primitives/io" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../../primitives/state-machine" } -sp-trie = { version = "2.0.0-alpha.6", path = "../../../primitives/trie" } +node-primitives = { version = "2.0.0-dev", path = "../primitives" } +node-runtime = { version = "2.0.0-dev", path = "../runtime" } +sc-executor = { version = "0.8.0-dev", path = "../../../client/executor" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-io = { version = "2.0.0-dev", path = "../../../primitives/io" } +sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } +sp-trie = { version = "2.0.0-dev", path = "../../../primitives/trie" } trie-root = "0.16.0" -frame-benchmarking = { version = "2.0.0-alpha.6", path = "../../../frame/benchmarking" } +frame-benchmarking = { version = "2.0.0-dev", path = "../../../frame/benchmarking" } [dev-dependencies] criterion = "0.3.0" -frame-support = { version = "2.0.0-alpha.6", path = "../../../frame/support" } -frame-system = { version = "2.0.0-alpha.6", path = "../../../frame/system" } -node-testing = { version = "2.0.0-alpha.6", path = "../testing" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../../../frame/balances" } -pallet-contracts = { version = "2.0.0-alpha.6", path = "../../../frame/contracts" } -pallet-grandpa = { version = "2.0.0-alpha.6", path = "../../../frame/grandpa" } -pallet-im-online = { version = "2.0.0-alpha.6", path = "../../../frame/im-online" } -pallet-indices = { version = "2.0.0-alpha.6", path = "../../../frame/indices" } -pallet-session = { version = "2.0.0-alpha.6", path = "../../../frame/session" } -pallet-timestamp = { version = "2.0.0-alpha.6", path = "../../../frame/timestamp" } -pallet-transaction-payment = { version = "2.0.0-alpha.6", path = "../../../frame/transaction-payment" } -pallet-treasury = { version = "2.0.0-alpha.6", path = "../../../frame/treasury" } -sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../../primitives/application-crypto" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-externalities = { version = "0.8.0-alpha.6", path = "../../../primitives/externalities" } +frame-support = { version = "2.0.0-dev", path = "../../../frame/support" } +frame-system = { version = "2.0.0-dev", path = "../../../frame/system" } +node-testing = { version = "2.0.0-dev", path = "../testing" } +pallet-balances = { version = "2.0.0-dev", path = "../../../frame/balances" } +pallet-contracts = { version = "2.0.0-dev", path = "../../../frame/contracts" } +pallet-grandpa = { version = "2.0.0-dev", path = "../../../frame/grandpa" } +pallet-im-online = { version = "2.0.0-dev", path = "../../../frame/im-online" } +pallet-indices = { version = "2.0.0-dev", path = "../../../frame/indices" } +pallet-session = { version = "2.0.0-dev", path = "../../../frame/session" } +pallet-timestamp = { version = "2.0.0-dev", path = "../../../frame/timestamp" } +pallet-transaction-payment = { version = "2.0.0-dev", path = "../../../frame/transaction-payment" } +pallet-treasury = { version = "2.0.0-dev", path = "../../../frame/treasury" } +sp-application-crypto = { version = "2.0.0-dev", path = "../../../primitives/application-crypto" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-externalities = { version = "0.8.0-dev", path = "../../../primitives/externalities" } substrate-test-client = { version = "2.0.0-dev", path = "../../../test-utils/client" } wabt = "0.9.2" diff --git a/bin/node/inspect/Cargo.toml b/bin/node/inspect/Cargo.toml index 98672a8e19..03d3a94b62 100644 --- a/bin/node/inspect/Cargo.toml +++ b/bin/node/inspect/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-inspect" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,10 +14,10 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "1.3.0" } derive_more = "0.99" log = "0.4.8" -sc-cli = { version = "0.8.0-alpha.6", path = "../../../client/cli" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api" } -sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../../../client/service" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0-dev", path = "../../../client/api" } +sc-service = { version = "0.8.0-dev", default-features = false, path = "../../../client/service" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } structopt = "0.3.8" diff --git a/bin/node/primitives/Cargo.toml b/bin/node/primitives/Cargo.toml index 342623c7d9..11959bde75 100644 --- a/bin/node/primitives/Cargo.toml +++ b/bin/node/primitives/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-primitives" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,11 +11,11 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } [dev-dependencies] -sp-serializer = { version = "2.0.0-alpha.6", path = "../../../primitives/serializer" } +sp-serializer = { version = "2.0.0-dev", path = "../../../primitives/serializer" } pretty_assertions = "0.6.1" [features] diff --git a/bin/node/rpc-client/Cargo.toml b/bin/node/rpc-client/Cargo.toml index f6c59a309c..1df3590d1f 100644 --- a/bin/node/rpc-client/Cargo.toml +++ b/bin/node/rpc-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-rpc-client" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,5 +16,5 @@ futures = "0.1.29" hyper = "0.12.35" jsonrpc-core-client = { version = "14.0.5", default-features = false, features = ["http"] } log = "0.4.8" -node-primitives = { version = "2.0.0-alpha.6", path = "../primitives" } -sc-rpc = { version = "2.0.0-alpha.6", path = "../../../client/rpc" } +node-primitives = { version = "2.0.0-dev", path = "../primitives" } +sc-rpc = { version = "2.0.0-dev", path = "../../../client/rpc" } diff --git a/bin/node/rpc/Cargo.toml b/bin/node/rpc/Cargo.toml index 706ad06aad..d6db49ebf0 100644 --- a/bin/node/rpc/Cargo.toml +++ b/bin/node/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-rpc" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,20 +11,20 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-client = { version = "0.8.0-alpha.6", path = "../../../client/" } +sc-client = { version = "0.8.0-dev", path = "../../../client/" } jsonrpc-core = "14.0.3" -node-primitives = { version = "2.0.0-alpha.6", path = "../primitives" } -node-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } -pallet-contracts-rpc = { version = "0.8.0-alpha.6", path = "../../../frame/contracts/rpc/" } -pallet-transaction-payment-rpc = { version = "2.0.0-alpha.6", path = "../../../frame/transaction-payment/rpc/" } -substrate-frame-rpc-system = { version = "2.0.0-alpha.6", path = "../../../utils/frame/rpc/system" } -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../primitives/transaction-pool" } -sc-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../client/consensus/babe" } -sc-consensus-babe-rpc = { version = "0.8.0-alpha.6", path = "../../../client/consensus/babe/rpc" } -sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/babe" } -sc-keystore = { version = "2.0.0-alpha.6", path = "../../../client/keystore" } -sc-consensus-epochs = { version = "0.8.0-alpha.6", path = "../../../client/consensus/epochs" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +node-primitives = { version = "2.0.0-dev", path = "../primitives" } +node-runtime = { version = "2.0.0-dev", path = "../runtime" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } +pallet-contracts-rpc = { version = "0.8.0-dev", path = "../../../frame/contracts/rpc/" } +pallet-transaction-payment-rpc = { version = "2.0.0-dev", path = "../../../frame/transaction-payment/rpc/" } +substrate-frame-rpc-system = { version = "2.0.0-dev", path = "../../../utils/frame/rpc/system" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../../primitives/transaction-pool" } +sc-consensus-babe = { version = "0.8.0-dev", path = "../../../client/consensus/babe" } +sc-consensus-babe-rpc = { version = "0.8.0-dev", path = "../../../client/consensus/babe/rpc" } +sp-consensus-babe = { version = "0.8.0-dev", path = "../../../primitives/consensus/babe" } +sc-keystore = { version = "2.0.0-dev", path = "../../../client/keystore" } +sc-consensus-epochs = { version = "0.8.0-dev", path = "../../../client/consensus/epochs" } +sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 935f218170..9c93c071c7 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-runtime" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" @@ -19,67 +19,67 @@ integer-sqrt = { version = "0.1.2" } serde = { version = "1.0.102", optional = true } # primitives -sp-authority-discovery = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/authority-discovery" } -sp-consensus-babe = { version = "0.8.0-alpha.6", default-features = false, path = "../../../primitives/consensus/babe" } -sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-alpha.6"} -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/inherents" } -node-primitives = { version = "2.0.0-alpha.6", default-features = false, path = "../primitives" } -sp-offchain = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/offchain" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/core" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/std" } -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/staking" } -sp-keyring = { version = "2.0.0-alpha.6", optional = true, path = "../../../primitives/keyring" } -sp-session = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/session" } -sp-transaction-pool = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/transaction-pool" } -sp-version = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/version" } +sp-authority-discovery = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/authority-discovery" } +sp-consensus-babe = { version = "0.8.0-dev", default-features = false, path = "../../../primitives/consensus/babe" } +sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-dev"} +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/inherents" } +node-primitives = { version = "2.0.0-dev", default-features = false, path = "../primitives" } +sp-offchain = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/offchain" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/std" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } +sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/staking" } +sp-keyring = { version = "2.0.0-dev", optional = true, path = "../../../primitives/keyring" } +sp-session = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/session" } +sp-transaction-pool = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/transaction-pool" } +sp-version = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/version" } # frame dependencies -frame-executive = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/executive" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/system" } -frame-system-rpc-runtime-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } -pallet-authority-discovery = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/authority-discovery" } -pallet-authorship = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/authorship" } -pallet-babe = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/babe" } -pallet-balances = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/balances" } -pallet-collective = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/collective" } -pallet-contracts = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/contracts" } -pallet-contracts-primitives = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/contracts/common/" } -pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.6", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" } -pallet-democracy = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/democracy" } -pallet-elections-phragmen = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/elections-phragmen" } -pallet-finality-tracker = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/finality-tracker" } -pallet-grandpa = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/grandpa" } -pallet-im-online = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/im-online" } -pallet-indices = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/indices" } -pallet-identity = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/identity" } -pallet-membership = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/membership" } -pallet-offences = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/offences" } -pallet-offences-benchmarking = { version = "2.0.0-alpha.6", path = "../../../frame/offences/benchmarking", default-features = false, optional = true } -pallet-randomness-collective-flip = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/randomness-collective-flip" } -pallet-recovery = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/recovery" } -pallet-session = { version = "2.0.0-alpha.6", features = ["historical"], path = "../../../frame/session", default-features = false } -pallet-session-benchmarking = { version = "2.0.0-alpha.6", path = "../../../frame/session/benchmarking", default-features = false, optional = true } -pallet-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/staking" } -pallet-staking-reward-curve = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/staking/reward-curve" } -pallet-scheduler = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/scheduler" } -pallet-society = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/society" } -pallet-sudo = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/sudo" } -pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/timestamp" } -pallet-treasury = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/treasury" } -pallet-utility = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/utility" } -pallet-transaction-payment = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/transaction-payment" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" } -pallet-vesting = { version = "2.0.0-alpha.6", default-features = false, path = "../../../frame/vesting" } +frame-executive = { version = "2.0.0-dev", default-features = false, path = "../../../frame/executive" } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../../../frame/benchmarking", optional = true } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../../../frame/support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../../../frame/system" } +frame-system-rpc-runtime-api = { version = "2.0.0-dev", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } +pallet-authority-discovery = { version = "2.0.0-dev", default-features = false, path = "../../../frame/authority-discovery" } +pallet-authorship = { version = "2.0.0-dev", default-features = false, path = "../../../frame/authorship" } +pallet-babe = { version = "2.0.0-dev", default-features = false, path = "../../../frame/babe" } +pallet-balances = { version = "2.0.0-dev", default-features = false, path = "../../../frame/balances" } +pallet-collective = { version = "2.0.0-dev", default-features = false, path = "../../../frame/collective" } +pallet-contracts = { version = "2.0.0-dev", default-features = false, path = "../../../frame/contracts" } +pallet-contracts-primitives = { version = "2.0.0-dev", default-features = false, path = "../../../frame/contracts/common/" } +pallet-contracts-rpc-runtime-api = { version = "0.8.0-dev", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" } +pallet-democracy = { version = "2.0.0-dev", default-features = false, path = "../../../frame/democracy" } +pallet-elections-phragmen = { version = "2.0.0-dev", default-features = false, path = "../../../frame/elections-phragmen" } +pallet-finality-tracker = { version = "2.0.0-dev", default-features = false, path = "../../../frame/finality-tracker" } +pallet-grandpa = { version = "2.0.0-dev", default-features = false, path = "../../../frame/grandpa" } +pallet-im-online = { version = "2.0.0-dev", default-features = false, path = "../../../frame/im-online" } +pallet-indices = { version = "2.0.0-dev", default-features = false, path = "../../../frame/indices" } +pallet-identity = { version = "2.0.0-dev", default-features = false, path = "../../../frame/identity" } +pallet-membership = { version = "2.0.0-dev", default-features = false, path = "../../../frame/membership" } +pallet-offences = { version = "2.0.0-dev", default-features = false, path = "../../../frame/offences" } +pallet-offences-benchmarking = { version = "2.0.0-dev", path = "../../../frame/offences/benchmarking", default-features = false, optional = true } +pallet-randomness-collective-flip = { version = "2.0.0-dev", default-features = false, path = "../../../frame/randomness-collective-flip" } +pallet-recovery = { version = "2.0.0-dev", default-features = false, path = "../../../frame/recovery" } +pallet-session = { version = "2.0.0-dev", features = ["historical"], path = "../../../frame/session", default-features = false } +pallet-session-benchmarking = { version = "2.0.0-dev", path = "../../../frame/session/benchmarking", default-features = false, optional = true } +pallet-staking = { version = "2.0.0-dev", default-features = false, path = "../../../frame/staking" } +pallet-staking-reward-curve = { version = "2.0.0-dev", default-features = false, path = "../../../frame/staking/reward-curve" } +pallet-scheduler = { version = "2.0.0-dev", default-features = false, path = "../../../frame/scheduler" } +pallet-society = { version = "2.0.0-dev", default-features = false, path = "../../../frame/society" } +pallet-sudo = { version = "2.0.0-dev", default-features = false, path = "../../../frame/sudo" } +pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../../frame/timestamp" } +pallet-treasury = { version = "2.0.0-dev", default-features = false, path = "../../../frame/treasury" } +pallet-utility = { version = "2.0.0-dev", default-features = false, path = "../../../frame/utility" } +pallet-transaction-payment = { version = "2.0.0-dev", default-features = false, path = "../../../frame/transaction-payment" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-dev", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" } +pallet-vesting = { version = "2.0.0-dev", default-features = false, path = "../../../frame/vesting" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.6", path = "../../../primitives/io" } +sp-io = { version = "2.0.0-dev", path = "../../../primitives/io" } [features] default = ["std"] diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 54e236db96..1daad5c12c 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -128,7 +128,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 240, - impl_version: 1, + impl_version: 2, apis: RUNTIME_API_VERSIONS, }; diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index 1ad3a93e3a..ee31b88a66 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-testing" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] description = "Test utilities for Substrate node." edition = "2018" @@ -13,45 +13,45 @@ publish = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -pallet-balances = { version = "2.0.0-alpha.6", path = "../../../frame/balances" } -sc-client = { version = "0.8.0-alpha.6", path = "../../../client/" } -sc-client-db = { version = "0.8.0-alpha.6", path = "../../../client/db/", features = ["kvdb-rocksdb"] } -sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api/" } +pallet-balances = { version = "2.0.0-dev", path = "../../../frame/balances" } +sc-client = { version = "0.8.0-dev", path = "../../../client/" } +sc-client-db = { version = "0.8.0-dev", path = "../../../client/db/", features = ["kvdb-rocksdb"] } +sc-client-api = { version = "2.0.0-dev", path = "../../../client/api/" } codec = { package = "parity-scale-codec", version = "1.3.0" } -pallet-contracts = { version = "2.0.0-alpha.6", path = "../../../frame/contracts" } -pallet-grandpa = { version = "2.0.0-alpha.6", path = "../../../frame/grandpa" } -pallet-indices = { version = "2.0.0-alpha.6", path = "../../../frame/indices" } -sp-keyring = { version = "2.0.0-alpha.6", path = "../../../primitives/keyring" } -node-executor = { version = "2.0.0-alpha.6", path = "../executor" } -node-primitives = { version = "2.0.0-alpha.6", path = "../primitives" } -node-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-io = { version = "2.0.0-alpha.6", path = "../../../primitives/io" } -frame-support = { version = "2.0.0-alpha.6", path = "../../../frame/support" } -pallet-session = { version = "2.0.0-alpha.6", path = "../../../frame/session" } -pallet-society = { version = "2.0.0-alpha.6", path = "../../../frame/society" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -pallet-staking = { version = "2.0.0-alpha.6", path = "../../../frame/staking" } -sc-executor = { version = "0.8.0-alpha.6", path = "../../../client/executor", features = ["wasmtime"] } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } -frame-system = { version = "2.0.0-alpha.6", path = "../../../frame/system" } +pallet-contracts = { version = "2.0.0-dev", path = "../../../frame/contracts" } +pallet-grandpa = { version = "2.0.0-dev", path = "../../../frame/grandpa" } +pallet-indices = { version = "2.0.0-dev", path = "../../../frame/indices" } +sp-keyring = { version = "2.0.0-dev", path = "../../../primitives/keyring" } +node-executor = { version = "2.0.0-dev", path = "../executor" } +node-primitives = { version = "2.0.0-dev", path = "../primitives" } +node-runtime = { version = "2.0.0-dev", path = "../runtime" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-io = { version = "2.0.0-dev", path = "../../../primitives/io" } +frame-support = { version = "2.0.0-dev", path = "../../../frame/support" } +pallet-session = { version = "2.0.0-dev", path = "../../../frame/session" } +pallet-society = { version = "2.0.0-dev", path = "../../../frame/society" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +pallet-staking = { version = "2.0.0-dev", path = "../../../frame/staking" } +sc-executor = { version = "0.8.0-dev", path = "../../../client/executor", features = ["wasmtime"] } +sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } +frame-system = { version = "2.0.0-dev", path = "../../../frame/system" } substrate-test-client = { version = "2.0.0-dev", path = "../../../test-utils/client" } -pallet-timestamp = { version = "2.0.0-alpha.6", path = "../../../frame/timestamp" } -pallet-transaction-payment = { version = "2.0.0-alpha.6", path = "../../../frame/transaction-payment" } -pallet-treasury = { version = "2.0.0-alpha.6", path = "../../../frame/treasury" } +pallet-timestamp = { version = "2.0.0-dev", path = "../../../frame/timestamp" } +pallet-transaction-payment = { version = "2.0.0-dev", path = "../../../frame/transaction-payment" } +pallet-treasury = { version = "2.0.0-dev", path = "../../../frame/treasury" } wabt = "0.9.2" -sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } -sp-finality-tracker = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/finality-tracker" } -sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/timestamp" } -sp-block-builder = { version = "2.0.0-alpha.6", path = "../../../primitives/block-builder" } -sc-block-builder = { version = "0.8.0-alpha.6", path = "../../../client/block-builder" } -sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } +sp-finality-tracker = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/finality-tracker" } +sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/timestamp" } +sp-block-builder = { version = "2.0.0-dev", path = "../../../primitives/block-builder" } +sc-block-builder = { version = "0.8.0-dev", path = "../../../client/block-builder" } +sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } log = "0.4.8" tempfile = "3.1.0" fs_extra = "1" [dev-dependencies] criterion = "0.3.0" -sc-cli = { version = "0.8.0-alpha.6", path = "../../../client/cli" } -sc-service = { version = "0.8.0-alpha.6", path = "../../../client/service", features = ["rocksdb"] } +sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } +sc-service = { version = "0.8.0-dev", path = "../../../client/service", features = ["rocksdb"] } diff --git a/bin/node/transaction-factory/Cargo.toml b/bin/node/transaction-factory/Cargo.toml index 98d996c3fa..273d1163ac 100644 --- a/bin/node/transaction-factory/Cargo.toml +++ b/bin/node/transaction-factory/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-transaction-factory" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -11,16 +11,16 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-block-builder = { version = "2.0.0-alpha.6", path = "../../../primitives/block-builder" } -sc-cli = { version = "0.8.0-alpha.6", path = "../../../client/cli" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api" } -sc-block-builder = { version = "0.8.0-alpha.6", path = "../../../client/block-builder" } -sc-client = { version = "0.8.0-alpha.6", path = "../../../client" } +sp-block-builder = { version = "2.0.0-dev", path = "../../../primitives/block-builder" } +sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0-dev", path = "../../../client/api" } +sc-block-builder = { version = "0.8.0-dev", path = "../../../client/block-builder" } +sc-client = { version = "0.8.0-dev", path = "../../../client" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } log = "0.4.8" -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../../../client/service" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sc-service = { version = "0.8.0-dev", default-features = false, path = "../../../client/service" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } diff --git a/bin/utils/chain-spec-builder/Cargo.toml b/bin/utils/chain-spec-builder/Cargo.toml index cd9dd516b4..a6c2b671fe 100644 --- a/bin/utils/chain-spec-builder/Cargo.toml +++ b/bin/utils/chain-spec-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "chain-spec-builder" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" @@ -13,9 +13,9 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] ansi_term = "0.12.1" -sc-keystore = { version = "2.0.0-alpha.6", path = "../../../client/keystore" } -sc-chain-spec = { version = "2.0.0-alpha.6", path = "../../../client/chain-spec" } -node-cli = { version = "2.0.0-alpha.6", path = "../../node/cli" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sc-keystore = { version = "2.0.0-dev", path = "../../../client/keystore" } +sc-chain-spec = { version = "2.0.0-dev", path = "../../../client/chain-spec" } +node-cli = { version = "2.0.0-dev", path = "../../node/cli" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } rand = "0.7.2" structopt = "0.3.8" diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index eddcde46fa..cd65d49d98 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "subkey" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,10 +12,10 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.1.29" -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -node-runtime = { version = "2.0.0-alpha.6", path = "../../node/runtime" } -node-primitives = { version = "2.0.0-alpha.6", path = "../../node/primitives" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +node-runtime = { version = "2.0.0-dev", path = "../../node/runtime" } +node-primitives = { version = "2.0.0-dev", path = "../../node/primitives" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } rand = "0.7.2" clap = "2.33.0" tiny-bip39 = "0.7" @@ -23,13 +23,13 @@ substrate-bip39 = "0.4.1" hex = "0.4.0" hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.3.0" } -frame-system = { version = "2.0.0-alpha.6", path = "../../../frame/system" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../../../frame/balances" } -pallet-transaction-payment = { version = "2.0.0-alpha.6", path = "../../../frame/transaction-payment" } +frame-system = { version = "2.0.0-dev", path = "../../../frame/system" } +pallet-balances = { version = "2.0.0-dev", path = "../../../frame/balances" } +pallet-transaction-payment = { version = "2.0.0-dev", path = "../../../frame/transaction-payment" } rpassword = "4.0.1" itertools = "0.8.2" derive_more = { version = "0.99.2" } -sc-rpc = { version = "2.0.0-alpha.6", path = "../../../client/rpc" } +sc-rpc = { version = "2.0.0-dev", path = "../../../client/rpc" } jsonrpc-core-client = { version = "14.0.3", features = ["http"] } hyper = "0.12.35" libp2p = "0.18.0" diff --git a/client/Cargo.toml b/client/Cargo.toml index 2e6c73818b..2711a6847f 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-client" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,33 +12,33 @@ description = "Substrate Client and associated logic." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-block-builder = { version = "0.8.0-alpha.6", path = "block-builder" } -sc-client-api = { version = "2.0.0-alpha.6", path = "api" } +sc-block-builder = { version = "0.8.0-dev", path = "block-builder" } +sc-client-api = { version = "2.0.0-dev", path = "api" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.6", path = "../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-dev", path = "../primitives/consensus/common" } derive_more = { version = "0.99.2" } -sc-executor = { version = "0.8.0-alpha.6", path = "executor" } -sp-externalities = { version = "0.8.0-alpha.6", path = "../primitives/externalities" } +sc-executor = { version = "0.8.0-dev", path = "executor" } +sp-externalities = { version = "0.8.0-dev", path = "../primitives/externalities" } fnv = { version = "1.0.6" } futures = { version = "0.3.1", features = ["compat"] } hash-db = { version = "0.15.2" } hex-literal = { version = "0.2.1" } -sp-inherents = { version = "2.0.0-alpha.6", path = "../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.6", path = "../primitives/keyring" } +sp-inherents = { version = "2.0.0-dev", path = "../primitives/inherents" } +sp-keyring = { version = "2.0.0-dev", path = "../primitives/keyring" } kvdb = "0.5.0" log = { version = "0.4.8" } parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.6", path = "../primitives/core" } -sp-std = { version = "2.0.0-alpha.6", path = "../primitives/std" } -sp-version = { version = "2.0.0-alpha.6", path = "../primitives/version" } -sp-api = { version = "2.0.0-alpha.6", path = "../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.6", path = "../primitives/utils" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../primitives/blockchain" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-alpha.6", path = "telemetry" } -sp-trie = { version = "2.0.0-alpha.6", path = "../primitives/trie" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.6", path = "../utils/prometheus" } +sp-core = { version = "2.0.0-dev", path = "../primitives/core" } +sp-std = { version = "2.0.0-dev", path = "../primitives/std" } +sp-version = { version = "2.0.0-dev", path = "../primitives/version" } +sp-api = { version = "2.0.0-dev", path = "../primitives/api" } +sp-runtime = { version = "2.0.0-dev", path = "../primitives/runtime" } +sp-utils = { version = "2.0.0-dev", path = "../primitives/utils" } +sp-blockchain = { version = "2.0.0-dev", path = "../primitives/blockchain" } +sp-state-machine = { version = "0.8.0-dev", path = "../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-dev", path = "telemetry" } +sp-trie = { version = "2.0.0-dev", path = "../primitives/trie" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-dev", path = "../utils/prometheus" } tracing = "0.1.10" [dev-dependencies] @@ -46,4 +46,4 @@ env_logger = "0.7.0" tempfile = "3.1.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../test-utils/runtime/client" } kvdb-memorydb = "0.5.0" -sp-panic-handler = { version = "2.0.0-alpha.6", path = "../primitives/panic-handler" } +sp-panic-handler = { version = "2.0.0-dev", path = "../primitives/panic-handler" } diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index a9a3361de3..2145a09f2d 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-client-api" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,32 +15,32 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } derive_more = { version = "0.99.2" } -sc-executor = { version = "0.8.0-alpha.6", path = "../executor" } -sp-externalities = { version = "0.8.0-alpha.6", path = "../../primitives/externalities" } +sc-executor = { version = "0.8.0-dev", path = "../executor" } +sp-externalities = { version = "0.8.0-dev", path = "../../primitives/externalities" } fnv = { version = "1.0.6" } futures = { version = "0.3.1" } hash-db = { version = "0.15.2", default-features = false } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } +sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } hex-literal = { version = "0.2.1" } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } +sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } kvdb = "0.5.0" log = { version = "0.4.8" } parking_lot = "0.10.0" lazy_static = "1.4.0" -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-version = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/version" } -sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } -sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } -sp-trie = { version = "2.0.0-alpha.6", path = "../../primitives/trie" } -sp-storage = { version = "2.0.0-alpha.6", path = "../../primitives/storage" } -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-version = { version = "2.0.0-dev", default-features = false, path = "../../primitives/version" } +sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } +sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } +sp-trie = { version = "2.0.0-dev", path = "../../primitives/trie" } +sp-storage = { version = "2.0.0-dev", path = "../../primitives/storage" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } [dev-dependencies] sp-test-primitives = { version = "2.0.0-dev", path = "../../primitives/test-primitives" } diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 58ee23111b..bc981db4aa 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-authority-discovery" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" @@ -23,21 +23,21 @@ futures = "0.3.4" futures-timer = "3.0.1" libp2p = { version = "0.18.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } log = "0.4.8" -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.6"} +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-dev"} prost = "0.6.1" rand = "0.7.2" -sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } -sc-keystore = { version = "2.0.0-alpha.6", path = "../keystore" } -sc-network = { version = "0.8.0-alpha.6", path = "../network" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } +sc-keystore = { version = "2.0.0-dev", path = "../keystore" } +sc-network = { version = "0.8.0-dev", path = "../network" } serde_json = "1.0.41" -sp-authority-discovery = { version = "2.0.0-alpha.6", path = "../../primitives/authority-discovery" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } +sp-authority-discovery = { version = "2.0.0-dev", path = "../../primitives/authority-discovery" } +sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } [dev-dependencies] env_logger = "0.7.0" quickcheck = "0.9.0" -sc-peerset = { version = "2.0.0-alpha.6", path = "../peerset" } +sc-peerset = { version = "2.0.0-dev", path = "../peerset" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client"} diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index d6aee79575..a9ac58ef32 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-basic-authorship" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,20 +15,20 @@ targets = ["x86_64-unknown-linux-gnu"] log = "0.4.8" futures = "0.3.4" codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-alpha.6", path = "../../primitives/inherents" } -sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } -sc-block-builder = { version = "0.8.0-alpha.6", path = "../block-builder" } +sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } +sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-dev", path = "../../primitives/inherents" } +sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } +sc-block-builder = { version = "0.8.0-dev", path = "../block-builder" } tokio-executor = { version = "0.2.0-alpha.6", features = ["blocking"] } futures-timer = "3.0.1" [dev-dependencies] -sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../../client/transaction-pool" } +sc-transaction-pool = { version = "2.0.0-dev", path = "../../client/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } parking_lot = "0.10.0" diff --git a/client/block-builder/Cargo.toml b/client/block-builder/Cargo.toml index 376c6f41df..15cc3c1393 100644 --- a/client/block-builder/Cargo.toml +++ b/client/block-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-block-builder" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,16 +13,16 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-block-builder = { version = "2.0.0-alpha.6", path = "../../primitives/block-builder" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } +sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } +sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-block-builder = { version = "2.0.0-dev", path = "../../primitives/block-builder" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } [dev-dependencies] substrate-test-runtime-client = { path = "../../test-utils/runtime/client" } -sp-trie = { version = "2.0.0-alpha.6", path = "../../primitives/trie" } +sp-trie = { version = "2.0.0-dev", path = "../../primitives/trie" } diff --git a/client/chain-spec/Cargo.toml b/client/chain-spec/Cargo.toml index 4d9c1df00e..6906b1ecda 100644 --- a/client/chain-spec/Cargo.toml +++ b/client/chain-spec/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-chain-spec" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,12 +12,12 @@ description = "Substrate chain configurations." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-chain-spec-derive = { version = "2.0.0-alpha.6", path = "./derive" } +sc-chain-spec-derive = { version = "2.0.0-dev", path = "./derive" } impl-trait-for-tuples = "0.1.3" -sc-network = { version = "0.8.0-alpha.6", path = "../network" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sc-network = { version = "0.8.0-dev", path = "../network" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -sp-chain-spec = { version = "2.0.0-alpha.6", path = "../../primitives/chain-spec" } -sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-chain-spec = { version = "2.0.0-dev", path = "../../primitives/chain-spec" } +sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } diff --git a/client/chain-spec/derive/Cargo.toml b/client/chain-spec/derive/Cargo.toml index 14fddcd9be..66058b3f72 100644 --- a/client/chain-spec/derive/Cargo.toml +++ b/client/chain-spec/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-chain-spec-derive" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 3c5a7b01bf..0670961834 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-cli" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Substrate CLI interface." edition = "2018" @@ -26,23 +26,23 @@ tokio = { version = "0.2.9", features = [ "signal", "rt-core", "rt-threaded" ] } futures = "0.3.4" fdlimit = "0.1.4" serde_json = "1.0.41" -sc-informant = { version = "0.8.0-alpha.6", path = "../informant" } -sp-panic-handler = { version = "2.0.0-alpha.6", path = "../../primitives/panic-handler" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } -sc-network = { version = "0.8.0-alpha.6", path = "../network" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } -sp-version = { version = "2.0.0-alpha.6", path = "../../primitives/version" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../service" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } -substrate-prometheus-endpoint = { path = "../../utils/prometheus" , version = "0.8.0-alpha.6"} -sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } +sc-informant = { version = "0.8.0-dev", path = "../informant" } +sp-panic-handler = { version = "2.0.0-dev", path = "../../primitives/panic-handler" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } +sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } +sc-network = { version = "0.8.0-dev", path = "../network" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } +sp-version = { version = "2.0.0-dev", path = "../../primitives/version" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sc-service = { version = "0.8.0-dev", default-features = false, path = "../service" } +sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } +substrate-prometheus-endpoint = { path = "../../utils/prometheus" , version = "0.8.0-dev"} +sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } names = "0.11.0" structopt = "0.3.8" -sc-tracing = { version = "2.0.0-alpha.6", path = "../tracing" } +sc-tracing = { version = "2.0.0-dev", path = "../tracing" } chrono = "0.4.10" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } diff --git a/client/consensus/aura/Cargo.toml b/client/consensus/aura/Cargo.toml index 63bc43a371..40f505f859 100644 --- a/client/consensus/aura/Cargo.toml +++ b/client/consensus/aura/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-aura" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Aura consensus algorithm for substrate" edition = "2018" @@ -12,37 +12,37 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../../primitives/application-crypto" } -sp-consensus-aura = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/aura" } -sp-block-builder = { version = "2.0.0-alpha.6", path = "../../../primitives/block-builder" } -sc-block-builder = { version = "0.8.0-alpha.6", path = "../../../client/block-builder" } -sc-client = { version = "0.8.0-alpha.6", path = "../../" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../../api" } +sp-application-crypto = { version = "2.0.0-dev", path = "../../../primitives/application-crypto" } +sp-consensus-aura = { version = "0.8.0-dev", path = "../../../primitives/consensus/aura" } +sp-block-builder = { version = "2.0.0-dev", path = "../../../primitives/block-builder" } +sc-block-builder = { version = "0.8.0-dev", path = "../../../client/block-builder" } +sc-client = { version = "0.8.0-dev", path = "../../" } +sc-client-api = { version = "2.0.0-dev", path = "../../api" } codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } +sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } derive_more = "0.99.2" futures = "0.3.4" futures-timer = "3.0.1" -sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } -sc-keystore = { version = "2.0.0-alpha.6", path = "../../keystore" } +sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } +sc-keystore = { version = "2.0.0-dev", path = "../../keystore" } log = "0.4.8" parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } -sp-io = { version = "2.0.0-alpha.6", path = "../../../primitives/io" } -sp-version = { version = "2.0.0-alpha.6", path = "../../../primitives/version" } -sc-consensus-slots = { version = "0.8.0-alpha.6", path = "../slots" } -sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-timestamp = { version = "2.0.0-alpha.6", path = "../../../primitives/timestamp" } -sc-telemetry = { version = "2.0.0-alpha.6", path = "../../telemetry" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } +sp-io = { version = "2.0.0-dev", path = "../../../primitives/io" } +sp-version = { version = "2.0.0-dev", path = "../../../primitives/version" } +sc-consensus-slots = { version = "0.8.0-dev", path = "../slots" } +sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-timestamp = { version = "2.0.0-dev", path = "../../../primitives/timestamp" } +sc-telemetry = { version = "2.0.0-dev", path = "../../telemetry" } [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.6", path = "../../../primitives/keyring" } -sc-executor = { version = "0.8.0-alpha.6", path = "../../executor" } -sc-network = { version = "0.8.0-alpha.6", path = "../../network" } +sp-keyring = { version = "2.0.0-dev", path = "../../../primitives/keyring" } +sc-executor = { version = "0.8.0-dev", path = "../../executor" } +sc-network = { version = "0.8.0-dev", path = "../../network" } sc-network-test = { version = "0.8.0-dev", path = "../../network/test" } -sc-service = { version = "0.8.0-alpha.6", path = "../../service" } +sc-service = { version = "0.8.0-dev", path = "../../service" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } env_logger = "0.7.0" tempfile = "3.1.0" diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index 080fb8d7db..7ac3330b6a 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-babe" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "BABE consensus algorithm for substrate" edition = "2018" @@ -14,31 +14,31 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/babe" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../../primitives/application-crypto" } +sp-consensus-babe = { version = "0.8.0-dev", path = "../../../primitives/consensus/babe" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-application-crypto = { version = "2.0.0-dev", path = "../../../primitives/application-crypto" } num-bigint = "0.2.3" num-rational = "0.2.2" num-traits = "0.2.8" serde = { version = "1.0.104", features = ["derive"] } -sp-version = { version = "2.0.0-alpha.6", path = "../../../primitives/version" } -sp-io = { version = "2.0.0-alpha.6", path = "../../../primitives/io" } -sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } -sp-timestamp = { version = "2.0.0-alpha.6", path = "../../../primitives/timestamp" } -sc-telemetry = { version = "2.0.0-alpha.6", path = "../../telemetry" } -sc-keystore = { version = "2.0.0-alpha.6", path = "../../keystore" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../../api" } -sc-client = { version = "0.8.0-alpha.6", path = "../../" } -sc-consensus-epochs = { version = "0.8.0-alpha.6", path = "../epochs" } -sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } -sp-block-builder = { version = "2.0.0-alpha.6", path = "../../../primitives/block-builder" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } -sp-consensus-vrf = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/vrf" } -sc-consensus-uncles = { version = "0.8.0-alpha.6", path = "../uncles" } -sc-consensus-slots = { version = "0.8.0-alpha.6", path = "../slots" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -fork-tree = { version = "2.0.0-alpha.6", path = "../../../utils/fork-tree" } +sp-version = { version = "2.0.0-dev", path = "../../../primitives/version" } +sp-io = { version = "2.0.0-dev", path = "../../../primitives/io" } +sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } +sp-timestamp = { version = "2.0.0-dev", path = "../../../primitives/timestamp" } +sc-telemetry = { version = "2.0.0-dev", path = "../../telemetry" } +sc-keystore = { version = "2.0.0-dev", path = "../../keystore" } +sc-client-api = { version = "2.0.0-dev", path = "../../api" } +sc-client = { version = "0.8.0-dev", path = "../../" } +sc-consensus-epochs = { version = "0.8.0-dev", path = "../epochs" } +sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } +sp-block-builder = { version = "2.0.0-dev", path = "../../../primitives/block-builder" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } +sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } +sp-consensus-vrf = { version = "0.8.0-dev", path = "../../../primitives/consensus/vrf" } +sc-consensus-uncles = { version = "0.8.0-dev", path = "../uncles" } +sc-consensus-slots = { version = "0.8.0-dev", path = "../slots" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +fork-tree = { version = "2.0.0-dev", path = "../../../utils/fork-tree" } futures = "0.3.4" futures-timer = "3.0.1" parking_lot = "0.10.0" @@ -50,13 +50,13 @@ pdqselect = "0.1.0" derive_more = "0.99.2" [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.6", path = "../../../primitives/keyring" } -sc-executor = { version = "0.8.0-alpha.6", path = "../../executor" } -sc-network = { version = "0.8.0-alpha.6", path = "../../network" } +sp-keyring = { version = "2.0.0-dev", path = "../../../primitives/keyring" } +sc-executor = { version = "0.8.0-dev", path = "../../executor" } +sc-network = { version = "0.8.0-dev", path = "../../network" } sc-network-test = { version = "0.8.0-dev", path = "../../network/test" } -sc-service = { version = "0.8.0-alpha.6", path = "../../service" } +sc-service = { version = "0.8.0-dev", path = "../../service" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sc-block-builder = { version = "0.8.0-alpha.6", path = "../../block-builder" } +sc-block-builder = { version = "0.8.0-dev", path = "../../block-builder" } env_logger = "0.7.0" tempfile = "3.1.0" diff --git a/client/consensus/babe/rpc/Cargo.toml b/client/consensus/babe/rpc/Cargo.toml index 6804ef94f5..e3b27e28dd 100644 --- a/client/consensus/babe/rpc/Cargo.toml +++ b/client/consensus/babe/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-babe-rpc" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "RPC extensions for the BABE consensus algorithm" edition = "2018" @@ -12,24 +12,24 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-consensus-babe = { version = "0.8.0-alpha.6", path = "../" } +sc-consensus-babe = { version = "0.8.0-dev", path = "../" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.3" -sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../../primitives/consensus/babe" } +sp-consensus-babe = { version = "0.8.0-dev", path = "../../../../primitives/consensus/babe" } serde = { version = "1.0.104", features=["derive"] } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../../primitives/runtime" } -sc-consensus-epochs = { version = "0.8.0-alpha.6", path = "../../epochs" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-dev", path = "../../../../primitives/runtime" } +sc-consensus-epochs = { version = "0.8.0-dev", path = "../../epochs" } futures = "0.3.4" derive_more = "0.99.2" -sp-api = { version = "2.0.0-alpha.6", path = "../../../../primitives/api" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../../primitives/consensus/common" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../../primitives/core" } -sc-keystore = { version = "2.0.0-alpha.6", path = "../../../keystore" } +sp-api = { version = "2.0.0-dev", path = "../../../../primitives/api" } +sp-consensus = { version = "0.8.0-dev", path = "../../../../primitives/consensus/common" } +sp-core = { version = "2.0.0-dev", path = "../../../../primitives/core" } +sc-keystore = { version = "2.0.0-dev", path = "../../../keystore" } [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../../test-utils/runtime/client" } -sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../../../primitives/application-crypto" } -sp-keyring = { version = "2.0.0-alpha.6", path = "../../../../primitives/keyring" } +sp-application-crypto = { version = "2.0.0-dev", path = "../../../../primitives/application-crypto" } +sp-keyring = { version = "2.0.0-dev", path = "../../../../primitives/keyring" } tempfile = "3.1.0" diff --git a/client/consensus/epochs/Cargo.toml b/client/consensus/epochs/Cargo.toml index facbfb3638..de14b5c6be 100644 --- a/client/consensus/epochs/Cargo.toml +++ b/client/consensus/epochs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-epochs" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Generic epochs-based utilities for consensus" edition = "2018" @@ -14,7 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } parking_lot = "0.10.0" -fork-tree = { version = "2.0.0-alpha.6", path = "../../../utils/fork-tree" } -sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.6"} -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } -sc-client-api = { path = "../../api" , version = "2.0.0-alpha.6"} +fork-tree = { version = "2.0.0-dev", path = "../../../utils/fork-tree" } +sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-dev"} +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } +sc-client-api = { path = "../../api" , version = "2.0.0-dev"} diff --git a/client/consensus/manual-seal/Cargo.toml b/client/consensus/manual-seal/Cargo.toml index cc989378dd..8d67ef30ad 100644 --- a/client/consensus/manual-seal/Cargo.toml +++ b/client/consensus/manual-seal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-manual-seal" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Manual sealing engine for Substrate" edition = "2018" @@ -22,17 +22,17 @@ parking_lot = "0.10.0" serde = { version = "1.0", features=["derive"] } assert_matches = "1.3.0" -sc-client = { path = "../../../client" , version = "0.8.0-alpha.6"} -sc-client-api = { path = "../../../client/api" , version = "2.0.0-alpha.6"} -sc-transaction-pool = { path = "../../transaction-pool" , version = "2.0.0-alpha.6"} -sp-blockchain = { path = "../../../primitives/blockchain" , version = "2.0.0-alpha.6"} -sp-consensus = { package = "sp-consensus", path = "../../../primitives/consensus/common" , version = "0.8.0-alpha.6"} -sp-inherents = { path = "../../../primitives/inherents" , version = "2.0.0-alpha.6"} -sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.6"} -sp-transaction-pool = { path = "../../../primitives/transaction-pool" , version = "2.0.0-alpha.6"} +sc-client = { path = "../../../client" , version = "0.8.0-dev"} +sc-client-api = { path = "../../../client/api" , version = "2.0.0-dev"} +sc-transaction-pool = { path = "../../transaction-pool" , version = "2.0.0-dev"} +sp-blockchain = { path = "../../../primitives/blockchain" , version = "2.0.0-dev"} +sp-consensus = { package = "sp-consensus", path = "../../../primitives/consensus/common" , version = "0.8.0-dev"} +sp-inherents = { path = "../../../primitives/inherents" , version = "2.0.0-dev"} +sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-dev"} +sp-transaction-pool = { path = "../../../primitives/transaction-pool" , version = "2.0.0-dev"} [dev-dependencies] -sc-basic-authorship = { path = "../../basic-authorship" , version = "0.8.0-alpha.6"} +sc-basic-authorship = { path = "../../basic-authorship" , version = "0.8.0-dev"} substrate-test-runtime-client = { path = "../../../test-utils/runtime/client" , version = "2.0.0-dev"} substrate-test-runtime-transaction-pool = { path = "../../../test-utils/runtime/transaction-pool" , version = "2.0.0-dev"} tokio = { version = "0.2", features = ["rt-core", "macros"] } diff --git a/client/consensus/pow/Cargo.toml b/client/consensus/pow/Cargo.toml index f011a7c060..0c1cc9c12c 100644 --- a/client/consensus/pow/Cargo.toml +++ b/client/consensus/pow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-pow" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "PoW consensus algorithm for substrate" edition = "2018" @@ -13,16 +13,16 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../../api" } -sp-block-builder = { version = "2.0.0-alpha.6", path = "../../../primitives/block-builder" } -sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } -sp-consensus-pow = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/pow" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } +sc-client-api = { version = "2.0.0-dev", path = "../../api" } +sp-block-builder = { version = "2.0.0-dev", path = "../../../primitives/block-builder" } +sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } +sp-consensus-pow = { version = "0.8.0-dev", path = "../../../primitives/consensus/pow" } +sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } log = "0.4.8" futures = { version = "0.3.1", features = ["compat"] } -sp-timestamp = { version = "2.0.0-alpha.6", path = "../../../primitives/timestamp" } +sp-timestamp = { version = "2.0.0-dev", path = "../../../primitives/timestamp" } derive_more = "0.99.2" diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index 589ac3255c..d39d538255 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-slots" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Generic slots-based utilities for consensus" edition = "2018" @@ -14,15 +14,15 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../../api" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../../primitives/state-machine" } -sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } -sc-telemetry = { version = "2.0.0-alpha.6", path = "../../telemetry" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } +sc-client-api = { version = "2.0.0-dev", path = "../../api" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } +sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } +sc-telemetry = { version = "2.0.0-dev", path = "../../telemetry" } +sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } futures = "0.3.4" futures-timer = "3.0.1" parking_lot = "0.10.0" diff --git a/client/consensus/uncles/Cargo.toml b/client/consensus/uncles/Cargo.toml index 828572ece5..019c933a20 100644 --- a/client/consensus/uncles/Cargo.toml +++ b/client/consensus/uncles/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-consensus-uncles" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Generic uncle inclusion utilities for consensus" edition = "2018" @@ -12,10 +12,10 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-client-api = { version = "2.0.0-alpha.6", path = "../../api" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-authorship = { version = "2.0.0-alpha.6", path = "../../../primitives/authorship" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-alpha.6", path = "../../../primitives/inherents" } +sc-client-api = { version = "2.0.0-dev", path = "../../api" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-authorship = { version = "2.0.0-dev", path = "../../../primitives/authorship" } +sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } log = "0.4.8" diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index 19b7423d6b..70f1c091a2 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-client-db" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -22,20 +22,20 @@ hash-db = "0.15.2" parity-util-mem = { version = "0.6.0", default-features = false, features = ["std"] } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -sc-client = { version = "0.8.0-alpha.6", path = "../" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } -sc-executor = { version = "0.8.0-alpha.6", path = "../executor" } -sc-state-db = { version = "0.8.0-alpha.6", path = "../state-db" } -sp-trie = { version = "2.0.0-alpha.6", path = "../../primitives/trie" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.6", path = "../../utils/prometheus" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sc-client = { version = "0.8.0-dev", path = "../" } +sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } +sc-executor = { version = "0.8.0-dev", path = "../executor" } +sc-state-db = { version = "0.8.0-dev", path = "../state-db" } +sp-trie = { version = "2.0.0-dev", path = "../../primitives/trie" } +sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-dev", path = "../../utils/prometheus" } [dev-dependencies] -sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } env_logger = "0.7.0" quickcheck = "0.9" diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index 92bf03761c..26d9828d57 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,21 +15,21 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] derive_more = "0.99.2" codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-trie = { version = "2.0.0-alpha.6", path = "../../primitives/trie" } -sp-serializer = { version = "2.0.0-alpha.6", path = "../../primitives/serializer" } -sp-version = { version = "2.0.0-alpha.6", path = "../../primitives/version" } -sp-panic-handler = { version = "2.0.0-alpha.6", path = "../../primitives/panic-handler" } +sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-trie = { version = "2.0.0-dev", path = "../../primitives/trie" } +sp-serializer = { version = "2.0.0-dev", path = "../../primitives/serializer" } +sp-version = { version = "2.0.0-dev", path = "../../primitives/version" } +sp-panic-handler = { version = "2.0.0-dev", path = "../../primitives/panic-handler" } wasmi = "0.6.2" parity-wasm = "0.41.0" lazy_static = "1.4.0" -sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.6", path = "../../primitives/runtime-interface" } -sp-externalities = { version = "0.8.0-alpha.6", path = "../../primitives/externalities" } -sc-executor-common = { version = "0.8.0-alpha.6", path = "common" } -sc-executor-wasmi = { version = "0.8.0-alpha.6", path = "wasmi" } -sc-executor-wasmtime = { version = "0.8.0-alpha.6", path = "wasmtime", optional = true } +sp-wasm-interface = { version = "2.0.0-dev", path = "../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-dev", path = "../../primitives/runtime-interface" } +sp-externalities = { version = "0.8.0-dev", path = "../../primitives/externalities" } +sc-executor-common = { version = "0.8.0-dev", path = "common" } +sc-executor-wasmi = { version = "0.8.0-dev", path = "wasmi" } +sc-executor-wasmtime = { version = "0.8.0-dev", path = "wasmtime", optional = true } parking_lot = "0.10.0" log = "0.4.8" libsecp256k1 = "0.3.4" @@ -40,9 +40,9 @@ wabt = "0.9.2" hex-literal = "0.2.1" sc-runtime-test = { version = "2.0.0-dev", path = "runtime-test" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } test-case = "0.3.3" -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } [features] default = [ "std" ] diff --git a/client/executor/common/Cargo.toml b/client/executor/common/Cargo.toml index ec11ef8024..c27ed8db0a 100644 --- a/client/executor/common/Cargo.toml +++ b/client/executor/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor-common" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -18,11 +18,11 @@ derive_more = "0.99.2" parity-wasm = "0.41.0" codec = { package = "parity-scale-codec", version = "1.3.0" } wasmi = "0.6.2" -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-alpha.6", path = "../../../primitives/allocator" } -sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime-interface" } -sp-serializer = { version = "2.0.0-alpha.6", path = "../../../primitives/serializer" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-dev", path = "../../../primitives/allocator" } +sp-wasm-interface = { version = "2.0.0-dev", path = "../../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-dev", path = "../../../primitives/runtime-interface" } +sp-serializer = { version = "2.0.0-dev", path = "../../../primitives/serializer" } [features] default = [] diff --git a/client/executor/runtime-test/Cargo.toml b/client/executor/runtime-test/Cargo.toml index 64cc5b5b5a..b8ae805192 100644 --- a/client/executor/runtime-test/Cargo.toml +++ b/client/executor/runtime-test/Cargo.toml @@ -13,12 +13,12 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/io" } -sp-sandbox = { version = "0.8.0-alpha.6", default-features = false, path = "../../../primitives/sandbox" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } -sp-allocator = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/allocator" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/io" } +sp-sandbox = { version = "0.8.0-dev", default-features = false, path = "../../../primitives/sandbox" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } +sp-allocator = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/allocator" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } diff --git a/client/executor/wasmi/Cargo.toml b/client/executor/wasmi/Cargo.toml index 4867f23a40..3180eebb4f 100644 --- a/client/executor/wasmi/Cargo.toml +++ b/client/executor/wasmi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor-wasmi" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,8 +16,8 @@ targets = ["x86_64-unknown-linux-gnu"] log = "0.4.8" wasmi = "0.6.2" codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-executor-common = { version = "0.8.0-alpha.6", path = "../common" } -sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime-interface" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-alpha.6", path = "../../../primitives/allocator" } +sc-executor-common = { version = "0.8.0-dev", path = "../common" } +sp-wasm-interface = { version = "2.0.0-dev", path = "../../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-dev", path = "../../../primitives/runtime-interface" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-dev", path = "../../../primitives/allocator" } diff --git a/client/executor/wasmtime/Cargo.toml b/client/executor/wasmtime/Cargo.toml index 90c32d0401..5b1c384141 100644 --- a/client/executor/wasmtime/Cargo.toml +++ b/client/executor/wasmtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-executor-wasmtime" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,11 +16,11 @@ log = "0.4.8" scoped-tls = "1.0" parity-wasm = "0.41.0" codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-executor-common = { version = "0.8.0-alpha.6", path = "../common" } -sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime-interface" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-alpha.6", path = "../../../primitives/allocator" } +sc-executor-common = { version = "0.8.0-dev", path = "../common" } +sp-wasm-interface = { version = "2.0.0-dev", path = "../../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-dev", path = "../../../primitives/runtime-interface" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-dev", path = "../../../primitives/allocator" } wasmtime = { package = "substrate-wasmtime", version = "0.13.0-threadsafe.1" } wasmtime_runtime = { package = "substrate-wasmtime-runtime", version = "0.13.0-threadsafe.1" } wasmtime-environ = "0.12.0" diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index 0221182250..7c0b95a6f0 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-finality-grandpa" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,7 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -fork-tree = { version = "2.0.0-alpha.6", path = "../../utils/fork-tree" } +fork-tree = { version = "2.0.0-dev", path = "../../utils/fork-tree" } futures = "0.3.4" futures-timer = "3.0.1" log = "0.4.8" @@ -22,37 +22,37 @@ parking_lot = "0.10.0" rand = "0.7.2" assert_matches = "1.3.0" parity-scale-codec = { version = "1.3.0", features = ["derive"] } -sp-arithmetic = { version = "2.0.0-alpha.6", path = "../../primitives/arithmetic" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } -sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } -sc-keystore = { version = "2.0.0-alpha.6", path = "../keystore" } +sp-arithmetic = { version = "2.0.0-dev", path = "../../primitives/arithmetic" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } +sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } +sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } +sc-keystore = { version = "2.0.0-dev", path = "../keystore" } serde_json = "1.0.41" -sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } -sc-client = { version = "0.8.0-alpha.6", path = "../" } -sp-inherents = { version = "2.0.0-alpha.6", path = "../../primitives/inherents" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } -sc-network = { version = "0.8.0-alpha.6", path = "../network" } -sc-network-gossip = { version = "0.8.0-alpha.6", path = "../network-gossip" } -sp-finality-tracker = { version = "2.0.0-alpha.6", path = "../../primitives/finality-tracker" } -sp-finality-grandpa = { version = "2.0.0-alpha.6", path = "../../primitives/finality-grandpa" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-alpha.6"} -sc-block-builder = { version = "0.8.0-alpha.6", path = "../block-builder" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } +sc-client = { version = "0.8.0-dev", path = "../" } +sp-inherents = { version = "2.0.0-dev", path = "../../primitives/inherents" } +sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } +sc-network = { version = "0.8.0-dev", path = "../network" } +sc-network-gossip = { version = "0.8.0-dev", path = "../network-gossip" } +sp-finality-tracker = { version = "2.0.0-dev", path = "../../primitives/finality-tracker" } +sp-finality-grandpa = { version = "2.0.0-dev", path = "../../primitives/finality-grandpa" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-dev"} +sc-block-builder = { version = "0.8.0-dev", path = "../block-builder" } finality-grandpa = { version = "0.11.2", features = ["derive-codec"] } pin-project = "0.4.6" [dev-dependencies] finality-grandpa = { version = "0.11.2", features = ["derive-codec", "test-helpers"] } -sc-network = { version = "0.8.0-alpha.6", path = "../network" } +sc-network = { version = "0.8.0-dev", path = "../network" } sc-network-test = { version = "0.8.0-dev", path = "../network/test" } -sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } -sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/babe" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } +sp-consensus-babe = { version = "0.8.0-dev", path = "../../primitives/consensus/babe" } +sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } env_logger = "0.7.0" tokio = { version = "0.2", features = ["rt-core"] } tempfile = "3.1.0" -sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } +sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } diff --git a/client/informant/Cargo.toml b/client/informant/Cargo.toml index 59e26a6cd3..5ece3e0ffb 100644 --- a/client/informant/Cargo.toml +++ b/client/informant/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-informant" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Substrate informant." edition = "2018" @@ -17,8 +17,8 @@ futures = "0.3.4" log = "0.4.8" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } wasm-timer = "0.2" -sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } -sc-network = { version = "0.8.0-alpha.6", path = "../network" } -sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../service" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } +sc-network = { version = "0.8.0-dev", path = "../network" } +sc-service = { version = "0.8.0-dev", default-features = false, path = "../service" } +sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } diff --git a/client/keystore/Cargo.toml b/client/keystore/Cargo.toml index 11acd2ec6a..f3419f55e1 100644 --- a/client/keystore/Cargo.toml +++ b/client/keystore/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-keystore" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,8 +15,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] derive_more = "0.99.2" -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../primitives/application-crypto" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-application-crypto = { version = "2.0.0-dev", path = "../../primitives/application-crypto" } hex = "0.4.0" rand = "0.7.2" serde_json = "1.0.41" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index 50d0eae90d..2b17f6f2f8 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Gossiping for the Substrate network protocol" name = "sc-network-gossip" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -19,9 +19,9 @@ futures-timer = "3.0.1" libp2p = { version = "0.18.0", default-features = false, features = ["websocket"] } log = "0.4.8" lru = "0.4.3" -sc-network = { version = "0.8.0-alpha.6", path = "../network" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } +sc-network = { version = "0.8.0-dev", path = "../network" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } wasm-timer = "0.2" [dev-dependencies] diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 7b38d07f35..85ad1c0289 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Substrate network protocol" name = "sc-network" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -25,7 +25,7 @@ derive_more = "0.99.2" either = "1.5.3" erased-serde = "0.3.9" fnv = "1.0.6" -fork-tree = { version = "2.0.0-alpha.6", path = "../../utils/fork-tree" } +fork-tree = { version = "2.0.0-dev", path = "../../utils/fork-tree" } futures = "0.3.4" futures_codec = "0.3.3" futures-timer = "3.0.1" @@ -39,24 +39,24 @@ parking_lot = "0.10.0" prost = "0.6.1" rand = "0.7.2" hex = "0.4.0" -sc-block-builder = { version = "0.8.0-alpha.6", path = "../block-builder" } -sc-client = { version = "0.8.0-alpha.6", path = "../" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } -sc-peerset = { version = "2.0.0-alpha.6", path = "../peerset" } +sc-block-builder = { version = "0.8.0-dev", path = "../block-builder" } +sc-client = { version = "0.8.0-dev", path = "../" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } +sc-peerset = { version = "2.0.0-dev", path = "../peerset" } pin-project = "0.4.6" serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } slog_derive = "0.2.0" smallvec = "0.6.10" -sp-arithmetic = { version = "2.0.0-alpha.6", path = "../../primitives/arithmetic" } -sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } -sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/babe" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-alpha.6", path = "../../utils/prometheus" } +sp-arithmetic = { version = "2.0.0-dev", path = "../../primitives/arithmetic" } +sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } +sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } +sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } +sp-consensus-babe = { version = "0.8.0-dev", path = "../../primitives/consensus/babe" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-dev", path = "../../utils/prometheus" } thiserror = "1" unsigned-varint = { version = "0.3.1", features = ["futures", "futures-codec"] } void = "1.0.2" @@ -74,7 +74,7 @@ env_logger = "0.7.0" libp2p = { version = "0.18.0", default-features = false, features = ["secio"] } quickcheck = "0.9.0" rand = "0.7.2" -sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } sp-test-primitives = { version = "2.0.0-dev", path = "../../primitives/test-primitives" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index cd5c60e417..200d31fa8c 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -13,21 +13,21 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-network = { version = "0.8.0-alpha.6", path = "../" } +sc-network = { version = "0.8.0-dev", path = "../" } log = "0.4.8" parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" rand = "0.7.2" libp2p = { version = "0.18.0", default-features = false, features = ["libp2p-websocket"] } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } -sc-client = { version = "0.8.0-alpha.6", path = "../../" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../../api" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sc-block-builder = { version = "0.8.0-alpha.6", path = "../../block-builder" } -sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/babe" } +sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } +sc-client = { version = "0.8.0-dev", path = "../../" } +sc-client-api = { version = "2.0.0-dev", path = "../../api" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sc-block-builder = { version = "0.8.0-dev", path = "../../block-builder" } +sp-consensus-babe = { version = "0.8.0-dev", path = "../../../primitives/consensus/babe" } env_logger = "0.7.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../../test-utils/runtime" } diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index 3b29f43aef..ac3a71ad0d 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Substrate offchain workers" name = "sc-offchain" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -13,23 +13,23 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] bytes = "0.5" -sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } -sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } +sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } fnv = "1.0.6" futures = "0.3.4" futures-timer = "3.0.1" log = "0.4.8" threadpool = "1.7" num_cpus = "1.10" -sp-offchain = { version = "2.0.0-alpha.6", path = "../../primitives/offchain" } +sp-offchain = { version = "2.0.0-dev", path = "../../primitives/offchain" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } rand = "0.7.2" -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } -sc-network = { version = "0.8.0-alpha.6", path = "../network" } -sc-keystore = { version = "2.0.0-alpha.6", path = "../keystore" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } +sc-network = { version = "0.8.0-dev", path = "../network" } +sc-keystore = { version = "2.0.0-dev", path = "../keystore" } [target.'cfg(not(target_os = "unknown"))'.dependencies] hyper = "0.13.2" @@ -38,9 +38,9 @@ hyper-rustls = "0.20" [dev-dependencies] env_logger = "0.7.0" fdlimit = "0.1.4" -sc-client-db = { version = "0.8.0-alpha.6", default-features = true, path = "../db/" } -sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../../client/transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } +sc-client-db = { version = "0.8.0-dev", default-features = true, path = "../db/" } +sc-transaction-pool = { version = "2.0.0-dev", path = "../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } tokio = "0.2" diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 1a17701480..1481697c47 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -3,7 +3,7 @@ description = "Connectivity manager based on reputation" homepage = "http://parity.io" license = "GPL-3.0" name = "sc-peerset" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" repository = "https://github.com/paritytech/substrate/" @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" libp2p = { version = "0.18.0", default-features = false } -sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils"} +sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils"} log = "0.4.8" serde_json = "1.0.41" wasm-timer = "0.2" diff --git a/client/rpc-api/Cargo.toml b/client/rpc-api/Cargo.toml index e235a9b013..e0dac773bf 100644 --- a/client/rpc-api/Cargo.toml +++ b/client/rpc-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-rpc-api" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -21,11 +21,11 @@ jsonrpc-derive = "14.0.3" jsonrpc-pubsub = "14.0.3" log = "0.4.8" parking_lot = "0.10.0" -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-version = { version = "2.0.0-alpha.6", path = "../../primitives/version" } -sp-runtime = { path = "../../primitives/runtime" , version = "2.0.0-alpha.6"} -sp-chain-spec = { path = "../../primitives/chain-spec" , version = "2.0.0-alpha.6"} +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-version = { version = "2.0.0-dev", path = "../../primitives/version" } +sp-runtime = { path = "../../primitives/runtime" , version = "2.0.0-dev"} +sp-chain-spec = { path = "../../primitives/chain-spec" , version = "2.0.0-dev"} serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } -sp-rpc = { version = "2.0.0-alpha.6", path = "../../primitives/rpc" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } +sp-rpc = { version = "2.0.0-dev", path = "../../primitives/rpc" } diff --git a/client/rpc-servers/Cargo.toml b/client/rpc-servers/Cargo.toml index 841e7e0831..345aff13d8 100644 --- a/client/rpc-servers/Cargo.toml +++ b/client/rpc-servers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-rpc-server" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -17,7 +17,7 @@ pubsub = { package = "jsonrpc-pubsub", version = "14.0.3" } log = "0.4.8" serde = "1.0.101" serde_json = "1.0.41" -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } [target.'cfg(not(target_os = "unknown"))'.dependencies] http = { package = "jsonrpc-http-server", version = "14.0.3" } diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index 0a3f8e4054..e6aff8a5f8 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-rpc" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,38 +12,38 @@ description = "Substrate Client RPC" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-rpc-api = { version = "0.8.0-alpha.6", path = "../rpc-api" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } -sc-client = { version = "0.8.0-alpha.6", path = "../" } -sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } +sc-rpc-api = { version = "0.8.0-dev", path = "../rpc-api" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } +sc-client = { version = "0.8.0-dev", path = "../" } +sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.3.0" } futures = { version = "0.3.1", features = ["compat"] } jsonrpc-pubsub = "14.0.3" log = "0.4.8" -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } rpc = { package = "jsonrpc-core", version = "14.0.3" } -sp-version = { version = "2.0.0-alpha.6", path = "../../primitives/version" } +sp-version = { version = "2.0.0-dev", path = "../../primitives/version" } serde_json = "1.0.41" -sp-session = { version = "2.0.0-alpha.6", path = "../../primitives/session" } -sp-offchain = { version = "2.0.0-alpha.6", path = "../../primitives/offchain" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } -sp-rpc = { version = "2.0.0-alpha.6", path = "../../primitives/rpc" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } -sp-chain-spec = { version = "2.0.0-alpha.6", path = "../../primitives/chain-spec" } -sc-executor = { version = "0.8.0-alpha.6", path = "../executor" } -sc-block-builder = { version = "0.8.0-alpha.6", path = "../../client/block-builder" } -sc-keystore = { version = "2.0.0-alpha.6", path = "../keystore" } -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } +sp-session = { version = "2.0.0-dev", path = "../../primitives/session" } +sp-offchain = { version = "2.0.0-dev", path = "../../primitives/offchain" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } +sp-rpc = { version = "2.0.0-dev", path = "../../primitives/rpc" } +sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } +sp-chain-spec = { version = "2.0.0-dev", path = "../../primitives/chain-spec" } +sc-executor = { version = "0.8.0-dev", path = "../executor" } +sc-block-builder = { version = "0.8.0-dev", path = "../../client/block-builder" } +sc-keystore = { version = "2.0.0-dev", path = "../keystore" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } +sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } hash-db = { version = "0.15.2", default-features = false } parking_lot = "0.10.0" [dev-dependencies] assert_matches = "1.3.0" futures01 = { package = "futures", version = "0.1.29" } -sc-network = { version = "0.8.0-alpha.6", path = "../network" } -sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } +sc-network = { version = "0.8.0-dev", path = "../network" } +sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } tokio = "0.1.22" -sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../transaction-pool" } +sc-transaction-pool = { version = "2.0.0-dev", path = "../transaction-pool" } diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 83cb6d717f..20b5c12a58 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-service" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -35,32 +35,32 @@ pin-project = "0.4.8" serde = "1.0.101" serde_json = "1.0.41" sysinfo = "0.12.0" -sc-keystore = { version = "2.0.0-alpha.6", path = "../keystore" } -sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-session = { version = "2.0.0-alpha.6", path = "../../primitives/session" } -sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../primitives/application-crypto" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } -sc-network = { version = "0.8.0-alpha.6", path = "../network" } -sc-chain-spec = { version = "2.0.0-alpha.6", path = "../chain-spec" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } -sc-client = { version = "0.8.0-alpha.6", path = "../" } -sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } -sc-client-db = { version = "0.8.0-alpha.6", path = "../db" } +sc-keystore = { version = "2.0.0-dev", path = "../keystore" } +sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } +sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-session = { version = "2.0.0-dev", path = "../../primitives/session" } +sp-application-crypto = { version = "2.0.0-dev", path = "../../primitives/application-crypto" } +sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } +sc-network = { version = "0.8.0-dev", path = "../network" } +sc-chain-spec = { version = "2.0.0-dev", path = "../chain-spec" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } +sc-client = { version = "0.8.0-dev", path = "../" } +sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } +sc-client-db = { version = "0.8.0-dev", path = "../db" } codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-executor = { version = "0.8.0-alpha.6", path = "../executor" } -sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../transaction-pool" } -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } -sc-rpc-server = { version = "2.0.0-alpha.6", path = "../rpc-servers" } -sc-rpc = { version = "2.0.0-alpha.6", path = "../rpc" } -sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } -sc-offchain = { version = "2.0.0-alpha.6", path = "../offchain" } +sc-executor = { version = "0.8.0-dev", path = "../executor" } +sc-transaction-pool = { version = "2.0.0-dev", path = "../transaction-pool" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } +sc-rpc-server = { version = "2.0.0-dev", path = "../rpc-servers" } +sc-rpc = { version = "2.0.0-dev", path = "../rpc" } +sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } +sc-offchain = { version = "2.0.0-dev", path = "../offchain" } parity-multiaddr = { package = "parity-multiaddr", version = "0.7.3" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" , version = "0.8.0-alpha.6"} -sc-tracing = { version = "2.0.0-alpha.6", path = "../tracing" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" , version = "0.8.0-dev"} +sc-tracing = { version = "2.0.0-dev", path = "../tracing" } tracing = "0.1.10" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } @@ -74,6 +74,6 @@ procfs = '0.7.8' [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } -sp-consensus-babe = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/babe" } -grandpa = { version = "0.8.0-alpha.6", package = "sc-finality-grandpa", path = "../finality-grandpa" } -grandpa-primitives = { version = "2.0.0-alpha.6", package = "sp-finality-grandpa", path = "../../primitives/finality-grandpa" } +sp-consensus-babe = { version = "0.8.0-dev", path = "../../primitives/consensus/babe" } +grandpa = { version = "0.8.0-dev", package = "sc-finality-grandpa", path = "../finality-grandpa" } +grandpa-primitives = { version = "2.0.0-dev", package = "sp-finality-grandpa", path = "../../primitives/finality-grandpa" } diff --git a/client/service/test/Cargo.toml b/client/service/test/Cargo.toml index 79c9899ce0..957c3327b7 100644 --- a/client/service/test/Cargo.toml +++ b/client/service/test/Cargo.toml @@ -19,10 +19,10 @@ log = "0.4.8" env_logger = "0.7.0" fdlimit = "0.1.4" futures = { version = "0.3.1", features = ["compat"] } -sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../../service" } -sc-network = { version = "0.8.0-alpha.6", path = "../../network" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } -sc-client = { version = "0.8.0-alpha.6", path = "../../" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../primitives/transaction-pool" } +sc-service = { version = "0.8.0-dev", default-features = false, path = "../../service" } +sc-network = { version = "0.8.0-dev", path = "../../network" } +sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } +sc-client = { version = "0.8.0-dev", path = "../../" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../../primitives/transaction-pool" } diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index a283ee44b4..9fc77c8099 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-state-db" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,8 +14,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] parking_lot = "0.10.0" log = "0.4.8" -sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } parity-util-mem = "0.6" parity-util-mem-derive = "0.1.0" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index 50908d6794..a46d4f7f9a 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-telemetry" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] description = "Telemetry utils" edition = "2018" diff --git a/client/tracing/Cargo.toml b/client/tracing/Cargo.toml index 2d5d1592b9..23f44fd057 100644 --- a/client/tracing/Cargo.toml +++ b/client/tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-tracing" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -20,7 +20,7 @@ serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } tracing-core = "0.1.7" -sc-telemetry = { version = "2.0.0-alpha.6", path = "../telemetry" } +sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } [dev-dependencies] tracing = "0.1.10" diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 256e307fdf..4eea7899f7 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-transaction-pool" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -19,20 +19,20 @@ futures-diagnose = "1.0" log = "0.4.8" parking_lot = "0.10.0" wasm-timer = "0.2" -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-alpha.6", path = "../../primitives/utils" } -sc-transaction-graph = { version = "2.0.0-alpha.6", path = "./graph" } -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../primitives/transaction-pool" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../api" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } +sc-transaction-graph = { version = "2.0.0-dev", path = "./graph" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } +sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } intervalier = "0.4.0" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] assert_matches = "1.3.0" hex = "0.4" -sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } substrate-test-runtime-transaction-pool = { version = "2.0.0-dev", path = "../../test-utils/runtime/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index 11df8791ac..42bf3deead 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-transaction-graph" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -18,11 +18,11 @@ log = "0.4.8" parking_lot = "0.10.0" serde = { version = "1.0.101", features = ["derive"] } wasm-timer = "0.2" -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } -sp-utils = { version = "2.0.0-alpha.6", path = "../../../primitives/utils" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../primitives/transaction-pool" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } +sp-utils = { version = "2.0.0-dev", path = "../../../primitives/utils" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../../primitives/transaction-pool" } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } linked-hash-map = "0.5.2" diff --git a/frame/assets/Cargo.toml b/frame/assets/Cargo.toml index 978400b7b9..4e09ea8aa5 100644 --- a/frame/assets/Cargo.toml +++ b/frame/assets/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-assets" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,16 +15,16 @@ targets = ["x86_64-unknown-linux-gnu"] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } # Needed for various traits. In our case, `OnFinalize`. -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } # Needed for type-safe access to storage DB. -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } # `system` module provides us with all sorts of useful stuff and macros depend on it being around. -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.6", path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-std = { version = "2.0.0-dev", path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/aura/Cargo.toml b/frame/aura/Cargo.toml index 6aa71d6465..623cf80df7 100644 --- a/frame/aura/Cargo.toml +++ b/frame/aura/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-aura" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,20 +12,20 @@ description = "FRAME AURA consensus pallet" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/application-crypto" } +sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../primitives/application-crypto" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -pallet-session = { version = "2.0.0-alpha.6", default-features = false, path = "../session" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -sp-consensus-aura = { path = "../../primitives/consensus/aura", default-features = false, version = "0.8.0-alpha.6"} -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/timestamp" } -pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../timestamp" } +pallet-session = { version = "2.0.0-dev", default-features = false, path = "../session" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-dev"} +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +sp-consensus-aura = { path = "../../primitives/consensus/aura", default-features = false, version = "0.8.0-dev"} +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../primitives/timestamp" } +pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../timestamp" } [dev-dependencies] diff --git a/frame/authority-discovery/Cargo.toml b/frame/authority-discovery/Cargo.toml index 094599d998..5f267b3159 100644 --- a/frame/authority-discovery/Cargo.toml +++ b/frame/authority-discovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-authority-discovery" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,20 +12,20 @@ description = "FRAME pallet for authority discovery" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-authority-discovery = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/authority-discovery" } -sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/application-crypto" } +sp-authority-discovery = { version = "2.0.0-dev", default-features = false, path = "../../primitives/authority-discovery" } +sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../primitives/application-crypto" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -pallet-session = { version = "2.0.0-alpha.6", features = ["historical" ], path = "../session", default-features = false } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +pallet-session = { version = "2.0.0-dev", features = ["historical" ], path = "../session", default-features = false } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } +sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } [features] default = ["std"] diff --git a/frame/authorship/Cargo.toml b/frame/authorship/Cargo.toml index db1df713ce..98776c0e00 100644 --- a/frame/authorship/Cargo.toml +++ b/frame/authorship/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-authorship" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" description = "Block and Uncle Author tracking for the FRAME" authors = ["Parity Technologies "] edition = "2018" @@ -12,15 +12,15 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } -sp-authorship = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/authorship" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } +sp-authorship = { version = "2.0.0-dev", default-features = false, path = "../../primitives/authorship" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-dev"} impl-trait-for-tuples = "0.1.3" [features] diff --git a/frame/babe/Cargo.toml b/frame/babe/Cargo.toml index e0986cf725..c94ec75b26 100644 --- a/frame/babe/Cargo.toml +++ b/frame/babe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-babe" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,21 +14,21 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../timestamp" } -sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/timestamp" } -pallet-session = { version = "2.0.0-alpha.6", default-features = false, path = "../session" } -sp-consensus-babe = { version = "0.8.0-alpha.6", default-features = false, path = "../../primitives/consensus/babe" } -sp-consensus-vrf = { version = "0.8.0-alpha.6", default-features = false, path = "../../primitives/consensus/vrf" } -sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../timestamp" } +sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../primitives/timestamp" } +pallet-session = { version = "2.0.0-dev", default-features = false, path = "../session" } +sp-consensus-babe = { version = "0.8.0-dev", default-features = false, path = "../../primitives/consensus/babe" } +sp-consensus-vrf = { version = "0.8.0-dev", default-features = false, path = "../../primitives/consensus/vrf" } +sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-dev"} [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/balances/Cargo.toml b/frame/balances/Cargo.toml index 00cc57eb4f..769e68112c 100644 --- a/frame/balances/Cargo.toml +++ b/frame/balances/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-balances" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,16 +14,16 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -pallet-transaction-payment = { version = "2.0.0-alpha.6", path = "../transaction-payment" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +pallet-transaction-payment = { version = "2.0.0-dev", path = "../transaction-payment" } [features] default = ["std"] diff --git a/frame/benchmark/Cargo.toml b/frame/benchmark/Cargo.toml index ae00507bc0..0b506d12ec 100644 --- a/frame/benchmark/Cargo.toml +++ b/frame/benchmark/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-benchmark" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,12 +14,12 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } [features] default = ["std"] diff --git a/frame/benchmarking/Cargo.toml b/frame/benchmarking/Cargo.toml index 80a04867aa..8089a2a366 100644 --- a/frame/benchmarking/Cargo.toml +++ b/frame/benchmarking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-benchmarking" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,13 +15,13 @@ targets = ["x86_64-unknown-linux-gnu"] linregress = "0.1" paste = "0.1" codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-api = { version = "2.0.0-alpha.6", path = "../../primitives/api", default-features = false } -sp-runtime-interface = { version = "2.0.0-alpha.6", path = "../../primitives/runtime-interface", default-features = false } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime", default-features = false } -sp-std = { version = "2.0.0-alpha.6", path = "../../primitives/std", default-features = false } -sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.6"} -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-api = { version = "2.0.0-dev", path = "../../primitives/api", default-features = false } +sp-runtime-interface = { version = "2.0.0-dev", path = "../../primitives/runtime-interface", default-features = false } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime", default-features = false } +sp-std = { version = "2.0.0-dev", path = "../../primitives/std", default-features = false } +sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-dev"} +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [features] default = [ "std" ] diff --git a/frame/collective/Cargo.toml b/frame/collective/Cargo.toml index 44152b9830..2107bf0b2f 100644 --- a/frame/collective/Cargo.toml +++ b/frame/collective/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-collective" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,17 +14,17 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } [features] default = ["std"] diff --git a/frame/contracts/Cargo.toml b/frame/contracts/Cargo.toml index efcbb196b7..42dba7299d 100644 --- a/frame/contracts/Cargo.toml +++ b/frame/contracts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -17,22 +17,22 @@ pwasm-utils = { version = "0.12.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } parity-wasm = { version = "0.41.0", default-features = false } wasmi-validation = { version = "0.3.0", default-features = false } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-sandbox = { version = "0.8.0-alpha.6", default-features = false, path = "../../primitives/sandbox" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -pallet-contracts-primitives = { version = "2.0.0-alpha.6", default-features = false, path = "common" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-sandbox = { version = "0.8.0-dev", default-features = false, path = "../../primitives/sandbox" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +pallet-contracts-primitives = { version = "2.0.0-dev", default-features = false, path = "common" } [dev-dependencies] wabt = "0.9.2" assert_matches = "1.3.0" hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } -pallet-timestamp = { version = "2.0.0-alpha.6", path = "../timestamp" } -pallet-randomness-collective-flip = { version = "2.0.0-alpha.6", path = "../randomness-collective-flip" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } +pallet-timestamp = { version = "2.0.0-dev", path = "../timestamp" } +pallet-randomness-collective-flip = { version = "2.0.0-dev", path = "../randomness-collective-flip" } [features] default = ["std"] diff --git a/frame/contracts/common/Cargo.toml b/frame/contracts/common/Cargo.toml index 42127860f1..edf1867be0 100644 --- a/frame/contracts/common/Cargo.toml +++ b/frame/contracts/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts-primitives" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,8 +14,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] # This crate should not rely on any of the frame primitives. codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } [features] default = ["std"] diff --git a/frame/contracts/rpc/Cargo.toml b/frame/contracts/rpc/Cargo.toml index f6af065f77..66d75759f1 100644 --- a/frame/contracts/rpc/Cargo.toml +++ b/frame/contracts/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts-rpc" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,14 +16,14 @@ codec = { package = "parity-scale-codec", version = "1.3.0" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.3" -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-rpc = { version = "2.0.0-alpha.6", path = "../../../primitives/rpc" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-rpc = { version = "2.0.0-dev", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } -pallet-contracts-primitives = { version = "2.0.0-alpha.6", path = "../common" } -pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.6", path = "./runtime-api" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } +pallet-contracts-primitives = { version = "2.0.0-dev", path = "../common" } +pallet-contracts-rpc-runtime-api = { version = "0.8.0-dev", path = "./runtime-api" } [dev-dependencies] serde_json = "1.0.41" diff --git a/frame/contracts/rpc/runtime-api/Cargo.toml b/frame/contracts/rpc/runtime-api/Cargo.toml index 0798f2fa24..81c6ce3760 100644 --- a/frame/contracts/rpc/runtime-api/Cargo.toml +++ b/frame/contracts/rpc/runtime-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-contracts-rpc-runtime-api" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,11 +12,11 @@ description = "Runtime API definition required by Contracts RPC extensions." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/api" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/runtime" } -pallet-contracts-primitives = { version = "2.0.0-alpha.6", default-features = false, path = "../../common" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/runtime" } +pallet-contracts-primitives = { version = "2.0.0-dev", default-features = false, path = "../../common" } [features] default = ["std"] diff --git a/frame/democracy/Cargo.toml b/frame/democracy/Cargo.toml index 7e46998ba9..83caa671ce 100644 --- a/frame/democracy/Cargo.toml +++ b/frame/democracy/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-democracy" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,18 +14,18 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } -pallet-scheduler = { version = "2.0.0-alpha.6", path = "../scheduler" } -sp-storage = { version = "2.0.0-alpha.6", path = "../../primitives/storage" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } +pallet-scheduler = { version = "2.0.0-dev", path = "../scheduler" } +sp-storage = { version = "2.0.0-dev", path = "../../primitives/storage" } hex-literal = "0.2.1" [features] diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index 662dd1d16e..f9d681b760 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-elections-phragmen" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,19 +14,19 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-phragmen = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/phragmen" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-phragmen = { version = "2.0.0-dev", default-features = false, path = "../../primitives/phragmen" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } +sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } -pallet-scheduler = { version = "2.0.0-alpha.6", path = "../scheduler" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -substrate-test-utils = { version = "2.0.0-alpha.6", path = "../../test-utils" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } +pallet-scheduler = { version = "2.0.0-dev", path = "../scheduler" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +substrate-test-utils = { version = "2.0.0-dev", path = "../../test-utils" } [features] default = ["std"] diff --git a/frame/elections/Cargo.toml b/frame/elections/Cargo.toml index fecd0be0ba..407b5ccfdb 100644 --- a/frame/elections/Cargo.toml +++ b/frame/elections/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-elections" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,16 +14,16 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } [features] default = ["std"] diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml index 0e19dc7fd3..eaa5ae3e42 100644 --- a/frame/evm/Cargo.toml +++ b/frame/evm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-evm" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,14 +14,14 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../timestamp" } -pallet-balances = { version = "2.0.0-alpha.6", default-features = false, path = "../balances" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../timestamp" } +pallet-balances = { version = "2.0.0-dev", default-features = false, path = "../balances" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } primitive-types = { version = "0.7.0", default-features = false, features = ["rlp"] } rlp = { version = "0.4", default-features = false } evm = { version = "0.16", default-features = false } diff --git a/frame/example-offchain-worker/Cargo.toml b/frame/example-offchain-worker/Cargo.toml index 11201b23ce..30381adb49 100644 --- a/frame/example-offchain-worker/Cargo.toml +++ b/frame/example-offchain-worker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-example-offchain-worker" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "Unlicense" @@ -13,13 +13,13 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } serde = { version = "1.0.101", optional = true } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } lite-json = { version = "0.1", default-features = false } [features] diff --git a/frame/example/Cargo.toml b/frame/example/Cargo.toml index 34b4e8c585..d12b1e7c83 100644 --- a/frame/example/Cargo.toml +++ b/frame/example/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-example" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "Unlicense" @@ -14,17 +14,17 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -pallet-balances = { version = "2.0.0-alpha.6", default-features = false, path = "../balances" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +pallet-balances = { version = "2.0.0-dev", default-features = false, path = "../balances" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core", default-features = false } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core", default-features = false } [features] default = ["std"] diff --git a/frame/executive/Cargo.toml b/frame/executive/Cargo.toml index 8a07f26ba7..d37339dbdc 100644 --- a/frame/executive/Cargo.toml +++ b/frame/executive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-executive" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,20 +13,20 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } serde = { version = "1.0.101", optional = true } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } [dev-dependencies] hex-literal = "0.2.1" -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-io ={ path = "../../primitives/io", version = "2.0.0-alpha.6"} -pallet-indices = { version = "2.0.0-alpha.6", path = "../indices" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } -pallet-transaction-payment = { version = "2.0.0-alpha.6", path = "../transaction-payment" } -sp-version = { version = "2.0.0-alpha.6", path = "../../primitives/version" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-io ={ path = "../../primitives/io", version = "2.0.0-dev"} +pallet-indices = { version = "2.0.0-dev", path = "../indices" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } +pallet-transaction-payment = { version = "2.0.0-dev", path = "../transaction-payment" } +sp-version = { version = "2.0.0-dev", path = "../../primitives/version" } [features] default = ["std"] diff --git a/frame/finality-tracker/Cargo.toml b/frame/finality-tracker/Cargo.toml index ebb6767f77..1b11fbea5a 100644 --- a/frame/finality-tracker/Cargo.toml +++ b/frame/finality-tracker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-finality-tracker" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,17 +16,17 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-finality-tracker = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/finality-tracker" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-finality-tracker = { version = "2.0.0-dev", default-features = false, path = "../../primitives/finality-tracker" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/generic-asset/Cargo.toml b/frame/generic-asset/Cargo.toml index e4161c5b25..c19a7884b3 100644 --- a/frame/generic-asset/Cargo.toml +++ b/frame/generic-asset/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-generic-asset" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Centrality Developers "] edition = "2018" license = "GPL-3.0" @@ -14,14 +14,14 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.6", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-dev", path = "../../primitives/io" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/grandpa/Cargo.toml b/frame/grandpa/Cargo.toml index ff33dff497..2e1dbc4deb 100644 --- a/frame/grandpa/Cargo.toml +++ b/frame/grandpa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-grandpa" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,18 +14,18 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-finality-grandpa = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/finality-grandpa" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -pallet-session = { version = "2.0.0-alpha.6", default-features = false, path = "../session" } -pallet-finality-tracker = { version = "2.0.0-alpha.6", default-features = false, path = "../finality-tracker" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-finality-grandpa = { version = "2.0.0-dev", default-features = false, path = "../../primitives/finality-grandpa" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-dev", default-features = false, path = "../session" } +pallet-finality-tracker = { version = "2.0.0-dev", default-features = false, path = "../finality-tracker" } [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.6", path = "../../primitives/io" } +sp-io ={ version = "2.0.0-dev", path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/identity/Cargo.toml b/frame/identity/Cargo.toml index 73b2d843f4..f20a8c983d 100644 --- a/frame/identity/Cargo.toml +++ b/frame/identity/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-identity" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,16 +15,16 @@ targets = ["x86_64-unknown-linux-gnu"] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } [features] default = ["std"] diff --git a/frame/im-online/Cargo.toml b/frame/im-online/Cargo.toml index 6895728a4d..55e5a49d58 100644 --- a/frame/im-online/Cargo.toml +++ b/frame/im-online/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-im-online" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,20 +12,20 @@ description = "FRAME's I'm online pallet" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/application-crypto" } -pallet-authorship = { version = "2.0.0-alpha.6", default-features = false, path = "../authorship" } +sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../primitives/application-crypto" } +pallet-authorship = { version = "2.0.0-dev", default-features = false, path = "../authorship" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -pallet-session = { version = "2.0.0-alpha.6", default-features = false, path = "../session" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-dev", default-features = false, path = "../session" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } [features] default = ["std", "pallet-session/historical"] diff --git a/frame/indices/Cargo.toml b/frame/indices/Cargo.toml index d217a1e606..515c0b478d 100644 --- a/frame/indices/Cargo.toml +++ b/frame/indices/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-indices" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,16 +14,16 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-keyring = { version = "2.0.0-alpha.6", optional = true, path = "../../primitives/keyring" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-keyring = { version = "2.0.0-dev", optional = true, path = "../../primitives/keyring" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } [features] default = ["std"] diff --git a/frame/membership/Cargo.toml b/frame/membership/Cargo.toml index eeee5c0f85..742cc124a2 100644 --- a/frame/membership/Cargo.toml +++ b/frame/membership/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-membership" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,14 +14,14 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/metadata/Cargo.toml b/frame/metadata/Cargo.toml index d68c8de342..73418be9b2 100644 --- a/frame/metadata/Cargo.toml +++ b/frame/metadata/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-metadata" -version = "11.0.0-alpha.6" +version = "11.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,8 +14,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/nicks/Cargo.toml b/frame/nicks/Cargo.toml index 7dacabb99a..fcb6473105 100644 --- a/frame/nicks/Cargo.toml +++ b/frame/nicks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-nicks" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,15 +14,15 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } [features] default = ["std"] diff --git a/frame/offences/Cargo.toml b/frame/offences/Cargo.toml index e9df75d835..e0759325fe 100644 --- a/frame/offences/Cargo.toml +++ b/frame/offences/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-offences" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,18 +12,18 @@ description = "FRAME offences pallet" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -pallet-balances = { version = "2.0.0-alpha.6", default-features = false, path = "../balances" } +pallet-balances = { version = "2.0.0-dev", default-features = false, path = "../balances" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/offences/benchmarking/Cargo.toml b/frame/offences/benchmarking/Cargo.toml index f04ea3c5be..de9d68dc80 100644 --- a/frame/offences/benchmarking/Cargo.toml +++ b/frame/offences/benchmarking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-offences-benchmarking" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,17 +14,17 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/std" } -sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/staking" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../../benchmarking" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../../system" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../support" } -pallet-im-online = { version = "2.0.0-alpha.6", default-features = false, path = "../../im-online" } -pallet-offences = { version = "2.0.0-alpha.6", default-features = false, features = ["runtime-benchmarks"], path = "../../offences" } -pallet-staking = { version = "2.0.0-alpha.6", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } -pallet-session = { version = "2.0.0-alpha.6", default-features = false, path = "../../session" } -sp-io = { path = "../../../primitives/io", default-features = false, version = "2.0.0-alpha.6"} +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/std" } +sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/staking" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../../benchmarking" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../../system" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../../support" } +pallet-im-online = { version = "2.0.0-dev", default-features = false, path = "../../im-online" } +pallet-offences = { version = "2.0.0-dev", default-features = false, features = ["runtime-benchmarks"], path = "../../offences" } +pallet-staking = { version = "2.0.0-dev", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } +pallet-session = { version = "2.0.0-dev", default-features = false, path = "../../session" } +sp-io = { path = "../../../primitives/io", default-features = false, version = "2.0.0-dev"} [features] diff --git a/frame/randomness-collective-flip/Cargo.toml b/frame/randomness-collective-flip/Cargo.toml index 330b604393..08d715899f 100644 --- a/frame/randomness-collective-flip/Cargo.toml +++ b/frame/randomness-collective-flip/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-randomness-collective-flip" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,14 +14,14 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] safe-mix = { version = "1.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/recovery/Cargo.toml b/frame/recovery/Cargo.toml index 02ce71b1d8..de422678c3 100644 --- a/frame/recovery/Cargo.toml +++ b/frame/recovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-recovery" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,15 +15,15 @@ targets = ["x86_64-unknown-linux-gnu"] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } [features] default = ["std"] diff --git a/frame/scheduler/Cargo.toml b/frame/scheduler/Cargo.toml index 534d42710f..8a511cd389 100644 --- a/frame/scheduler/Cargo.toml +++ b/frame/scheduler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-scheduler" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "Unlicense" @@ -11,15 +11,15 @@ description = "FRAME example pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core", default-features = false } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core", default-features = false } [features] default = ["std"] diff --git a/frame/scored-pool/Cargo.toml b/frame/scored-pool/Cargo.toml index 8341098647..ae8def3dd3 100644 --- a/frame/scored-pool/Cargo.toml +++ b/frame/scored-pool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-scored-pool" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,15 +14,15 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/session/Cargo.toml b/frame/session/Cargo.toml index b4f10c7eb8..b3ca1ad596 100644 --- a/frame/session/Cargo.toml +++ b/frame/session/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-session" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,19 +14,19 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../timestamp" } -sp-trie = { optional = true, path = "../../primitives/trie", default-features = false, version = "2.0.0-alpha.6"} -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../timestamp" } +sp-trie = { optional = true, path = "../../primitives/trie", default-features = false, version = "2.0.0-dev"} +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-dev"} impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-application-crypto = { version = "2.0.0-alpha.6", path = "../../primitives/application-crypto" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-application-crypto = { version = "2.0.0-dev", path = "../../primitives/application-crypto" } lazy_static = "1.4.0" [features] diff --git a/frame/session/benchmarking/Cargo.toml b/frame/session/benchmarking/Cargo.toml index cc590b4bb2..a3994ab379 100644 --- a/frame/session/benchmarking/Cargo.toml +++ b/frame/session/benchmarking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-session-benchmarking" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,22 +12,22 @@ description = "FRAME sessions pallet benchmarking" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../../system" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../../benchmarking" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../support" } -pallet-staking = { version = "2.0.0-alpha.6", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } -pallet-session = { version = "2.0.0-alpha.6", default-features = false, path = "../../session" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../../system" } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../../benchmarking" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../../support" } +pallet-staking = { version = "2.0.0-dev", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } +pallet-session = { version = "2.0.0-dev", default-features = false, path = "../../session" } [dev-dependencies] serde = { version = "1.0.101" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -pallet-staking-reward-curve = { version = "2.0.0-alpha.6", path = "../../staking/reward-curve" } -sp-io ={ path = "../../../primitives/io", version = "2.0.0-alpha.6"} -pallet-timestamp = { version = "2.0.0-alpha.6", path = "../../timestamp" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../../balances" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +pallet-staking-reward-curve = { version = "2.0.0-dev", path = "../../staking/reward-curve" } +sp-io ={ path = "../../../primitives/io", version = "2.0.0-dev"} +pallet-timestamp = { version = "2.0.0-dev", path = "../../timestamp" } +pallet-balances = { version = "2.0.0-dev", path = "../../balances" } [features] default = ["std"] diff --git a/frame/society/Cargo.toml b/frame/society/Cargo.toml index da38ec5e75..d79eb78b7d 100644 --- a/frame/society/Cargo.toml +++ b/frame/society/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-society" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,16 +14,16 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-dev"} +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } rand_chacha = { version = "0.2", default-features = false } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } [features] default = ["std"] diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index 29b6476495..354b8dd306 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-staking" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,35 +14,35 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-phragmen = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/phragmen" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -pallet-session = { version = "2.0.0-alpha.6", features = ["historical"], path = "../session", default-features = false } -pallet-authorship = { version = "2.0.0-alpha.6", default-features = false, path = "../authorship" } -sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/application-crypto" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-phragmen = { version = "2.0.0-dev", default-features = false, path = "../../primitives/phragmen" } +sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-dev"} +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-dev", features = ["historical"], path = "../session", default-features = false } +pallet-authorship = { version = "2.0.0-dev", default-features = false, path = "../authorship" } +sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../primitives/application-crypto" } static_assertions = "1.1.0" # Optional imports for tesing-utils feature -pallet-indices = { version = "2.0.0-alpha.6", optional = true, path = "../indices", default-features = false } -sp-core = { version = "2.0.0-alpha.6", optional = true, path = "../../primitives/core", default-features = false } +pallet-indices = { version = "2.0.0-dev", optional = true, path = "../indices", default-features = false } +sp-core = { version = "2.0.0-dev", optional = true, path = "../../primitives/core", default-features = false } rand = { version = "0.7.3", optional = true, default-features = false } # Optional imports for benchmarking -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } rand_chacha = { version = "0.2", default-features = false, optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-storage = { version = "2.0.0-alpha.6", path = "../../primitives/storage" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } -pallet-timestamp = { version = "2.0.0-alpha.6", path = "../timestamp" } -pallet-staking-reward-curve = { version = "2.0.0-alpha.6", path = "../staking/reward-curve" } -substrate-test-utils = { version = "2.0.0-alpha.6", path = "../../test-utils" } -frame-benchmarking = { version = "2.0.0-alpha.6", path = "../benchmarking" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-storage = { version = "2.0.0-dev", path = "../../primitives/storage" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } +pallet-timestamp = { version = "2.0.0-dev", path = "../timestamp" } +pallet-staking-reward-curve = { version = "2.0.0-dev", path = "../staking/reward-curve" } +substrate-test-utils = { version = "2.0.0-dev", path = "../../test-utils" } +frame-benchmarking = { version = "2.0.0-dev", path = "../benchmarking" } rand_chacha = { version = "0.2" } parking_lot = "0.10.0" env_logger = "0.7.1" diff --git a/frame/staking/reward-curve/Cargo.toml b/frame/staking/reward-curve/Cargo.toml index fc95ccac79..b11d1cc049 100644 --- a/frame/staking/reward-curve/Cargo.toml +++ b/frame/staking/reward-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-staking-reward-curve" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -21,4 +21,4 @@ proc-macro2 = "1.0.6" proc-macro-crate = "0.1.4" [dev-dependencies] -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } diff --git a/frame/sudo/Cargo.toml b/frame/sudo/Cargo.toml index 295f723ca3..25988b1fe3 100644 --- a/frame/sudo/Cargo.toml +++ b/frame/sudo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-sudo" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,14 +14,14 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index 23e0744a5c..aee2dd79fc 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,24 +15,24 @@ targets = ["x86_64-unknown-linux-gnu"] log = "0.4" serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -frame-metadata = { version = "11.0.0-alpha.6", default-features = false, path = "../metadata" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-arithmetic = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/arithmetic" } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } -frame-support-procedural = { version = "2.0.0-alpha.6", path = "./procedural" } +frame-metadata = { version = "11.0.0-dev", default-features = false, path = "../metadata" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-arithmetic = { version = "2.0.0-dev", default-features = false, path = "../../primitives/arithmetic" } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } +frame-support-procedural = { version = "2.0.0-dev", path = "./procedural" } paste = "0.1.6" once_cell = { version = "1", default-features = false, optional = true } -sp-state-machine = { version = "0.8.0-alpha.6", optional = true, path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-dev", optional = true, path = "../../primitives/state-machine" } bitmask = { version = "0.5.0", default-features = false } impl-trait-for-tuples = "0.1.3" tracing = { version = "0.1.10", optional = true } [dev-dependencies] pretty_assertions = "0.6.1" -frame-system = { version = "2.0.0-alpha.6", path = "../system" } +frame-system = { version = "2.0.0-dev", path = "../system" } [features] default = ["std"] diff --git a/frame/support/procedural/Cargo.toml b/frame/support/procedural/Cargo.toml index 9b9f888d96..55e5513432 100644 --- a/frame/support/procedural/Cargo.toml +++ b/frame/support/procedural/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support-procedural" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,7 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] proc-macro = true [dependencies] -frame-support-procedural-tools = { version = "2.0.0-alpha.6", path = "./tools" } +frame-support-procedural-tools = { version = "2.0.0-dev", path = "./tools" } proc-macro2 = "1.0.6" quote = "1.0.3" syn = { version = "1.0.7", features = ["full"] } diff --git a/frame/support/procedural/tools/Cargo.toml b/frame/support/procedural/tools/Cargo.toml index a5c07223a1..f64ad9b1e6 100644 --- a/frame/support/procedural/tools/Cargo.toml +++ b/frame/support/procedural/tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support-procedural-tools" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,7 +12,7 @@ description = "Proc macro helpers for procedural macros" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -frame-support-procedural-tools-derive = { version = "2.0.0-alpha.6", path = "./derive" } +frame-support-procedural-tools-derive = { version = "2.0.0-dev", path = "./derive" } proc-macro2 = "1.0.6" quote = "1.0.3" syn = { version = "1.0.7", features = ["full", "visit"] } diff --git a/frame/support/procedural/tools/derive/Cargo.toml b/frame/support/procedural/tools/derive/Cargo.toml index 2615ef2121..75721508e8 100644 --- a/frame/support/procedural/tools/derive/Cargo.toml +++ b/frame/support/procedural/tools/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-support-procedural-tools-derive" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index 61b22f24f5..3d2fa71a94 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -14,12 +14,12 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-io ={ path = "../../../primitives/io", default-features = false , version = "2.0.0-alpha.6"} -sp-state-machine = { version = "0.8.0-alpha.6", optional = true, path = "../../../primitives/state-machine" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../" } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/inherents" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../../primitives/core" } +sp-io ={ path = "../../../primitives/io", default-features = false , version = "2.0.0-dev"} +sp-state-machine = { version = "0.8.0-dev", optional = true, path = "../../../primitives/state-machine" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../" } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/inherents" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/core" } trybuild = "1.0.17" pretty_assertions = "0.6.1" diff --git a/frame/system/Cargo.toml b/frame/system/Cargo.toml index f4c6458d5d..210d3664ff 100644 --- a/frame/system/Cargo.toml +++ b/frame/system/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-system" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,17 +14,17 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.6"} -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-version = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/version" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-dev"} +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-version = { version = "2.0.0-dev", default-features = false, path = "../../primitives/version" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] criterion = "0.2.11" -sp-externalities = { version = "0.8.0-alpha.6", path = "../../primitives/externalities" } +sp-externalities = { version = "0.8.0-dev", path = "../../primitives/externalities" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } [features] diff --git a/frame/system/rpc/runtime-api/Cargo.toml b/frame/system/rpc/runtime-api/Cargo.toml index 18aad0d59c..2097e11266 100644 --- a/frame/system/rpc/runtime-api/Cargo.toml +++ b/frame/system/rpc/runtime-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-system-rpc-runtime-api" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,7 +12,7 @@ description = "Runtime API definition required by System RPC extensions." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/api" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } [features] diff --git a/frame/timestamp/Cargo.toml b/frame/timestamp/Cargo.toml index 335ae8d9f8..7691421bbf 100644 --- a/frame/timestamp/Cargo.toml +++ b/frame/timestamp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-timestamp" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,19 +16,19 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io", optional = true } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/timestamp" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io", optional = true } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../primitives/timestamp" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.6", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-dev", path = "../../primitives/io" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/transaction-payment/Cargo.toml b/frame/transaction-payment/Cargo.toml index 0ba4b9ca86..e6720e4b54 100644 --- a/frame/transaction-payment/Cargo.toml +++ b/frame/transaction-payment/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-payment" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,16 +13,16 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.6", default-features = false, path = "./rpc/runtime-api" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-dev", default-features = false, path = "./rpc/runtime-api" } [dev-dependencies] -sp-io = { version = "2.0.0-alpha.6", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } [features] default = ["std"] diff --git a/frame/transaction-payment/rpc/Cargo.toml b/frame/transaction-payment/rpc/Cargo.toml index beae554464..35f421915a 100644 --- a/frame/transaction-payment/rpc/Cargo.toml +++ b/frame/transaction-payment/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-payment-rpc" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,10 +16,10 @@ codec = { package = "parity-scale-codec", version = "1.3.0" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.3" -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sp-rpc = { version = "2.0.0-alpha.6", path = "../../../primitives/rpc" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sp-rpc = { version = "2.0.0-dev", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.6", path = "./runtime-api" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-dev", path = "./runtime-api" } diff --git a/frame/transaction-payment/rpc/runtime-api/Cargo.toml b/frame/transaction-payment/rpc/runtime-api/Cargo.toml index 2c79b111d2..1170e043ee 100644 --- a/frame/transaction-payment/rpc/runtime-api/Cargo.toml +++ b/frame/transaction-payment/rpc/runtime-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-payment-rpc-runtime-api" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,11 +13,11 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/api" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../../support" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/runtime" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../../../support" } [dev-dependencies] serde_json = "1.0.41" diff --git a/frame/treasury/Cargo.toml b/frame/treasury/Cargo.toml index 17e1e7284f..c00ae225c1 100644 --- a/frame/treasury/Cargo.toml +++ b/frame/treasury/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-treasury" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,17 +14,17 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -pallet-balances = { version = "2.0.0-alpha.6", default-features = false, path = "../balances" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +pallet-balances = { version = "2.0.0-dev", default-features = false, path = "../balances" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-io ={ version = "2.0.0-alpha.6", path = "../../primitives/io" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-dev", path = "../../primitives/io" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/utility/Cargo.toml b/frame/utility/Cargo.toml index acaa485489..a830f8ab5b 100644 --- a/frame/utility/Cargo.toml +++ b/frame/utility/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-utility" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,18 +14,18 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } [features] default = ["std"] diff --git a/frame/vesting/Cargo.toml b/frame/vesting/Cargo.toml index d950db4ea0..79430990c3 100644 --- a/frame/vesting/Cargo.toml +++ b/frame/vesting/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-vesting" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,17 +15,17 @@ targets = ["x86_64-unknown-linux-gnu"] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-alpha.6", default-features = false, path = "../benchmarking", optional = true } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-alpha.6", path = "../balances" } -sp-storage = { version = "2.0.0-alpha.6", path = "../../primitives/storage" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-dev", path = "../balances" } +sp-storage = { version = "2.0.0-dev", path = "../../primitives/storage" } hex-literal = "0.2.1" [features] diff --git a/primitives/allocator/Cargo.toml b/primitives/allocator/Cargo.toml index 5d1b899fed..8530e0df0e 100644 --- a/primitives/allocator/Cargo.toml +++ b/primitives/allocator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-allocator" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,9 +13,9 @@ documentation = "https://docs.rs/sp-allocator" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-std = { version = "2.0.0-alpha.6", path = "../std", default-features = false } -sp-core = { version = "2.0.0-alpha.6", path = "../core", default-features = false } -sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../wasm-interface", default-features = false } +sp-std = { version = "2.0.0-dev", path = "../std", default-features = false } +sp-core = { version = "2.0.0-dev", path = "../core", default-features = false } +sp-wasm-interface = { version = "2.0.0-dev", path = "../wasm-interface", default-features = false } log = { version = "0.4.8", optional = true } derive_more = { version = "0.99.2", optional = true } diff --git a/primitives/api/Cargo.toml b/primitives/api/Cargo.toml index d565aff9e2..43decc4f6e 100644 --- a/primitives/api/Cargo.toml +++ b/primitives/api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-api" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,12 +13,12 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-api-proc-macro = { version = "2.0.0-alpha.6", path = "proc-macro" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } -sp-version = { version = "2.0.0-alpha.6", default-features = false, path = "../version" } -sp-state-machine = { version = "0.8.0-alpha.6", optional = true, path = "../../primitives/state-machine" } +sp-api-proc-macro = { version = "2.0.0-dev", path = "proc-macro" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } +sp-version = { version = "2.0.0-dev", default-features = false, path = "../version" } +sp-state-machine = { version = "0.8.0-dev", optional = true, path = "../../primitives/state-machine" } hash-db = { version = "0.15.2", optional = true } [dev-dependencies] diff --git a/primitives/api/proc-macro/Cargo.toml b/primitives/api/proc-macro/Cargo.toml index e4fadd03d3..a970b3e750 100644 --- a/primitives/api/proc-macro/Cargo.toml +++ b/primitives/api/proc-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-api-proc-macro" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/api/test/Cargo.toml b/primitives/api/test/Cargo.toml index 91d81ee541..a945399f1b 100644 --- a/primitives/api/test/Cargo.toml +++ b/primitives/api/test/Cargo.toml @@ -12,22 +12,22 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { version = "2.0.0-alpha.6", path = "../" } +sp-api = { version = "2.0.0-dev", path = "../" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-version = { version = "2.0.0-alpha.6", path = "../../version" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../runtime" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../blockchain" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../../primitives/consensus/common" } -sc-block-builder = { version = "0.8.0-alpha.6", path = "../../../client/block-builder" } +sp-version = { version = "2.0.0-dev", path = "../../version" } +sp-runtime = { version = "2.0.0-dev", path = "../../runtime" } +sp-blockchain = { version = "2.0.0-dev", path = "../../blockchain" } +sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } +sc-block-builder = { version = "0.8.0-dev", path = "../../../client/block-builder" } codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } trybuild = "1.0.17" rustversion = "1.0.0" [dev-dependencies] criterion = "0.3.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-core = { version = "2.0.0-alpha.6", path = "../../core" } +sp-core = { version = "2.0.0-dev", path = "../../core" } [[bench]] name = "bench" diff --git a/primitives/application-crypto/Cargo.toml b/primitives/application-crypto/Cargo.toml index 6cd4d81e7b..be9e5e5a11 100644 --- a/primitives/application-crypto/Cargo.toml +++ b/primitives/application-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-application-crypto" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" description = "Provides facilities for generating application specific crypto wrapper types." @@ -14,11 +14,11 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } [features] default = [ "std" ] diff --git a/primitives/application-crypto/test/Cargo.toml b/primitives/application-crypto/test/Cargo.toml index ad2ab93156..47b477ddd3 100644 --- a/primitives/application-crypto/test/Cargo.toml +++ b/primitives/application-crypto/test/Cargo.toml @@ -13,8 +13,8 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../core" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../core" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../runtime" } -sp-api = { version = "2.0.0-alpha.6", path = "../../api" } -sp-application-crypto = { version = "2.0.0-alpha.6", path = "../" } +sp-runtime = { version = "2.0.0-dev", path = "../../runtime" } +sp-api = { version = "2.0.0-dev", path = "../../api" } +sp-application-crypto = { version = "2.0.0-dev", path = "../" } diff --git a/primitives/arithmetic/Cargo.toml b/primitives/arithmetic/Cargo.toml index 7697cf008e..70efb4ac4a 100644 --- a/primitives/arithmetic/Cargo.toml +++ b/primitives/arithmetic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-arithmetic" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -17,9 +17,9 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } integer-sqrt = "0.1.2" num-traits = { version = "0.2.8", default-features = false } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-debug-derive = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/debug-derive" } +sp-debug-derive = { version = "2.0.0-dev", default-features = false, path = "../../primitives/debug-derive" } primitive-types = { version = "0.7.0", default-features = false } [dev-dependencies] diff --git a/primitives/arithmetic/fuzzer/Cargo.toml b/primitives/arithmetic/fuzzer/Cargo.toml index 3b8d012ac7..b7a63c4566 100644 --- a/primitives/arithmetic/fuzzer/Cargo.toml +++ b/primitives/arithmetic/fuzzer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-arithmetic-fuzzer" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,7 +13,7 @@ documentation = "https://docs.rs/sp-arithmetic-fuzzer" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-arithmetic = { version = "2.0.0-alpha.6", path = ".." } +sp-arithmetic = { version = "2.0.0-dev", path = ".." } honggfuzz = "0.5" primitive-types = "0.7.0" num-bigint = "0.2" diff --git a/primitives/authority-discovery/Cargo.toml b/primitives/authority-discovery/Cargo.toml index 77675bb94e..32f67d5e6e 100644 --- a/primitives/authority-discovery/Cargo.toml +++ b/primitives/authority-discovery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-authority-discovery" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] description = "Authority discovery primitives" edition = "2018" @@ -12,11 +12,11 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../application-crypto" } +sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../application-crypto" } codec = { package = "parity-scale-codec", default-features = false, version = "1.3.0" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/authorship/Cargo.toml b/primitives/authorship/Cargo.toml index faabfefa8a..7bc01953ef 100644 --- a/primitives/authorship/Cargo.toml +++ b/primitives/authorship/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-authorship" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] description = "Authorship primitives" edition = "2018" @@ -12,9 +12,9 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../inherents" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../inherents" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } [features] diff --git a/primitives/block-builder/Cargo.toml b/primitives/block-builder/Cargo.toml index e2bf716aad..70bb5e12d3 100644 --- a/primitives/block-builder/Cargo.toml +++ b/primitives/block-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-block-builder" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,11 +12,11 @@ description = "The block builder runtime api." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../api" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../inherents" } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../inherents" } [features] default = [ "std" ] diff --git a/primitives/blockchain/Cargo.toml b/primitives/blockchain/Cargo.toml index 9d33ed2d29..d5cf80b775 100644 --- a/primitives/blockchain/Cargo.toml +++ b/primitives/blockchain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-blockchain" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -19,7 +19,7 @@ lru = "0.4.0" parking_lot = "0.10.0" derive_more = "0.99.2" codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-consensus = { version = "0.8.0-alpha.6", path = "../consensus/common" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } -sp-block-builder = { version = "2.0.0-alpha.6", path = "../block-builder" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../state-machine" } +sp-consensus = { version = "0.8.0-dev", path = "../consensus/common" } +sp-runtime = { version = "2.0.0-dev", path = "../runtime" } +sp-block-builder = { version = "2.0.0-dev", path = "../block-builder" } +sp-state-machine = { version = "0.8.0-dev", path = "../state-machine" } diff --git a/primitives/chain-spec/Cargo.toml b/primitives/chain-spec/Cargo.toml index df79932b28..585decc68d 100644 --- a/primitives/chain-spec/Cargo.toml +++ b/primitives/chain-spec/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-chain-spec" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/consensus/aura/Cargo.toml b/primitives/consensus/aura/Cargo.toml index 613a6485a6..574b80bd3d 100644 --- a/primitives/consensus/aura/Cargo.toml +++ b/primitives/consensus/aura/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-aura" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" @@ -12,13 +12,13 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../application-crypto" } +sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../application-crypto" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../std" } -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../api" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../runtime" } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../inherents" } -sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../timestamp" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../std" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../../api" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../runtime" } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../inherents" } +sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../timestamp" } [features] default = ["std"] diff --git a/primitives/consensus/babe/Cargo.toml b/primitives/consensus/babe/Cargo.toml index af2e77f220..ba7e7fffb6 100644 --- a/primitives/consensus/babe/Cargo.toml +++ b/primitives/consensus/babe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-babe" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Primitives for BABE consensus" edition = "2018" @@ -12,15 +12,15 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../application-crypto" } +sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../application-crypto" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../std" } -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../api" } -sp-consensus = { version = "0.8.0-alpha.6", optional = true, path = "../common" } -sp-consensus-vrf = { version = "0.8.0-alpha.6", path = "../vrf", default-features = false } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../inherents" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../runtime" } -sp-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../timestamp" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../std" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../../api" } +sp-consensus = { version = "0.8.0-dev", optional = true, path = "../common" } +sp-consensus-vrf = { version = "0.8.0-dev", path = "../vrf", default-features = false } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../inherents" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../runtime" } +sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../timestamp" } [features] default = ["std"] diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 7e8a044690..afb2b8dfb5 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -17,16 +17,16 @@ targets = ["x86_64-unknown-linux-gnu"] derive_more = "0.99.2" libp2p = { version = "0.18.0", default-features = false } log = "0.4.8" -sp-core = { path= "../../core", version = "2.0.0-alpha.6"} -sp-inherents = { version = "2.0.0-alpha.6", path = "../../inherents" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../../primitives/state-machine" } +sp-core = { path= "../../core", version = "2.0.0-dev"} +sp-inherents = { version = "2.0.0-dev", path = "../../inherents" } +sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } futures = { version = "0.3.1", features = ["thread-pool"] } futures-timer = "3.0.1" futures-diagnose = "1.0" -sp-std = { version = "2.0.0-alpha.6", path = "../../std" } -sp-version = { version = "2.0.0-alpha.6", path = "../../version" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../runtime" } -sp-utils = { version = "2.0.0-alpha.6", path = "../../utils" } +sp-std = { version = "2.0.0-dev", path = "../../std" } +sp-version = { version = "2.0.0-dev", path = "../../version" } +sp-runtime = { version = "2.0.0-dev", path = "../../runtime" } +sp-utils = { version = "2.0.0-dev", path = "../../utils" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } parking_lot = "0.10.0" serde = { version = "1.0", features = ["derive"] } diff --git a/primitives/consensus/pow/Cargo.toml b/primitives/consensus/pow/Cargo.toml index 0ff3334bbe..a7bcb6a000 100644 --- a/primitives/consensus/pow/Cargo.toml +++ b/primitives/consensus/pow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-pow" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" @@ -12,10 +12,10 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../api" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../runtime" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../core" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../../api" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../runtime" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../core" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } [features] diff --git a/primitives/consensus/vrf/Cargo.toml b/primitives/consensus/vrf/Cargo.toml index b584002fe6..71b647df59 100644 --- a/primitives/consensus/vrf/Cargo.toml +++ b/primitives/consensus/vrf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-consensus-vrf" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Primitives for VRF based consensus" edition = "2018" @@ -14,9 +14,9 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { version = "1.0.0", package = "parity-scale-codec", default-features = false } schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated"], optional = true } -sp-std = { version = "2.0.0-alpha.6", path = "../../std", default-features = false } -sp-core = { version = "2.0.0-alpha.6", path = "../../core", default-features = false } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../runtime" } +sp-std = { version = "2.0.0-dev", path = "../../std", default-features = false } +sp-core = { version = "2.0.0-dev", path = "../../core", default-features = false } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../runtime" } [features] default = ["std"] diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index a6db02e941..4ab6dd8e97 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-core" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,7 +13,7 @@ documentation = "https://docs.rs/sp-core" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } log = { version = "0.4.8", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } @@ -32,9 +32,9 @@ num-traits = { version = "0.2.8", default-features = false } zeroize = { version = "1.0.0", default-features = false } lazy_static = { version = "1.4.0", default-features = false, optional = true } parking_lot = { version = "0.10.0", optional = true } -sp-debug-derive = { version = "2.0.0-alpha.6", path = "../debug-derive" } -sp-externalities = { version = "0.8.0-alpha.6", optional = true, path = "../externalities" } -sp-storage = { version = "2.0.0-alpha.6", default-features = false, path = "../storage" } +sp-debug-derive = { version = "2.0.0-dev", path = "../debug-derive" } +sp-externalities = { version = "0.8.0-dev", optional = true, path = "../externalities" } +sp-storage = { version = "2.0.0-dev", default-features = false, path = "../storage" } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } futures = { version = "0.3.1", optional = true } @@ -48,10 +48,10 @@ hex = { version = "0.4", default-features = false, optional = true } twox-hash = { version = "1.5.0", default-features = false, optional = true } libsecp256k1 = { version = "0.3.2", default-features = false, features = ["hmac"], optional = true } -sp-runtime-interface = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime-interface" } +sp-runtime-interface = { version = "2.0.0-dev", default-features = false, path = "../runtime-interface" } [dev-dependencies] -sp-serializer = { version = "2.0.0-alpha.6", path = "../serializer" } +sp-serializer = { version = "2.0.0-dev", path = "../serializer" } pretty_assertions = "0.6.1" hex-literal = "0.2.1" rand = "0.7.2" diff --git a/primitives/debug-derive/Cargo.toml b/primitives/debug-derive/Cargo.toml index 936e24393f..a3e9d91fd2 100644 --- a/primitives/debug-derive/Cargo.toml +++ b/primitives/debug-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-debug-derive" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/externalities/Cargo.toml b/primitives/externalities/Cargo.toml index 2afe7a56a7..81c9c5fb5c 100644 --- a/primitives/externalities/Cargo.toml +++ b/primitives/externalities/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-externalities" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -13,6 +13,6 @@ documentation = "https://docs.rs/sp-externalities" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-storage = { version = "2.0.0-alpha.6", path = "../storage" } -sp-std = { version = "2.0.0-alpha.6", path = "../std" } +sp-storage = { version = "2.0.0-dev", path = "../storage" } +sp-std = { version = "2.0.0-dev", path = "../std" } environmental = { version = "1.1.1" } diff --git a/primitives/finality-grandpa/Cargo.toml b/primitives/finality-grandpa/Cargo.toml index a45098b671..b5ce970c0d 100644 --- a/primitives/finality-grandpa/Cargo.toml +++ b/primitives/finality-grandpa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-finality-grandpa" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,12 +14,12 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../application-crypto" } +sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../application-crypto" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/finality-tracker/Cargo.toml b/primitives/finality-tracker/Cargo.toml index 4f3cbd623b..a111c62675 100644 --- a/primitives/finality-tracker/Cargo.toml +++ b/primitives/finality-tracker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-finality-tracker" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,8 +13,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } [features] default = ["std"] diff --git a/primitives/inherents/Cargo.toml b/primitives/inherents/Cargo.toml index ec794fb90e..084d275882 100644 --- a/primitives/inherents/Cargo.toml +++ b/primitives/inherents/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-inherents" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,8 +15,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] parking_lot = { version = "0.10.0", optional = true } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } derive_more = { version = "0.99.2", optional = true } diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index 9194d2506e..c80f3d0ac1 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-io" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,14 +16,14 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } hash-db = { version = "0.15.2", default-features = false } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } libsecp256k1 = { version = "0.3.4", optional = true } -sp-state-machine = { version = "0.8.0-alpha.6", optional = true, path = "../../primitives/state-machine" } -sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../../primitives/wasm-interface", default-features = false } -sp-runtime-interface = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime-interface" } -sp-trie = { version = "2.0.0-alpha.6", optional = true, path = "../../primitives/trie" } -sp-externalities = { version = "0.8.0-alpha.6", optional = true, path = "../externalities" } +sp-state-machine = { version = "0.8.0-dev", optional = true, path = "../../primitives/state-machine" } +sp-wasm-interface = { version = "2.0.0-dev", path = "../../primitives/wasm-interface", default-features = false } +sp-runtime-interface = { version = "2.0.0-dev", default-features = false, path = "../runtime-interface" } +sp-trie = { version = "2.0.0-dev", optional = true, path = "../../primitives/trie" } +sp-externalities = { version = "0.8.0-dev", optional = true, path = "../externalities" } log = { version = "0.4.8", optional = true } [features] diff --git a/primitives/keyring/Cargo.toml b/primitives/keyring/Cargo.toml index 0467d3f255..23e243239a 100644 --- a/primitives/keyring/Cargo.toml +++ b/primitives/keyring/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-keyring" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,7 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-core = { version = "2.0.0-alpha.6", path = "../core" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } +sp-core = { version = "2.0.0-dev", path = "../core" } +sp-runtime = { version = "2.0.0-dev", path = "../runtime" } lazy_static = "1.4.0" strum = { version = "0.16.0", features = ["derive"] } diff --git a/primitives/offchain/Cargo.toml b/primitives/offchain/Cargo.toml index 99bdb1507b..2f87cb1b16 100644 --- a/primitives/offchain/Cargo.toml +++ b/primitives/offchain/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Substrate offchain workers primitives" name = "sp-offchain" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" @@ -12,8 +12,8 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/panic-handler/Cargo.toml b/primitives/panic-handler/Cargo.toml index c4c0ffae6d..b5adb9cb54 100644 --- a/primitives/panic-handler/Cargo.toml +++ b/primitives/panic-handler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-panic-handler" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/phragmen/Cargo.toml b/primitives/phragmen/Cargo.toml index b06ed1e945..bf6e9fede6 100644 --- a/primitives/phragmen/Cargo.toml +++ b/primitives/phragmen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-phragmen" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -14,14 +14,14 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -sp-phragmen-compact = { version = "2.0.0-dev.1", path = "./compact" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-phragmen-compact = { version = "2.0.0-dev", path = "./compact" } [dev-dependencies] -substrate-test-utils = { version = "2.0.0-alpha.6", path = "../../test-utils" } +substrate-test-utils = { version = "2.0.0-dev", path = "../../test-utils" } rand = "0.7.3" -sp-phragmen = { path = "." , version = "2.0.0-alpha.6"} +sp-phragmen = { path = "." , version = "2.0.0-dev"} [features] default = ["std"] diff --git a/primitives/phragmen/compact/Cargo.toml b/primitives/phragmen/compact/Cargo.toml index 49566c5262..386116f268 100644 --- a/primitives/phragmen/compact/Cargo.toml +++ b/primitives/phragmen/compact/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-phragmen-compact" -version = "2.0.0-dev.1" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/rpc/Cargo.toml b/primitives/rpc/Cargo.toml index a2279e3152..740b429c0c 100644 --- a/primitives/rpc/Cargo.toml +++ b/primitives/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-rpc" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,7 +13,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", features = ["derive"] } -sp-core = { version = "2.0.0-alpha.6", path = "../core" } +sp-core = { version = "2.0.0-dev", path = "../core" } [dev-dependencies] serde_json = "1.0.41" diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index aa35509f39..362d79f150 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-runtime-interface" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,19 +13,19 @@ documentation = "https://docs.rs/sp-runtime-interface/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-wasm-interface = { version = "2.0.0-alpha.6", path = "../wasm-interface", default-features = false } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } -sp-runtime-interface-proc-macro = { version = "2.0.0-alpha.6", path = "proc-macro" } -sp-externalities = { version = "0.8.0-alpha.6", optional = true, path = "../externalities" } +sp-wasm-interface = { version = "2.0.0-dev", path = "../wasm-interface", default-features = false } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-runtime-interface-proc-macro = { version = "2.0.0-dev", path = "proc-macro" } +sp-externalities = { version = "0.8.0-dev", optional = true, path = "../externalities" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } static_assertions = "1.0.0" primitive-types = { version = "0.7.0", default-features = false } [dev-dependencies] sp-runtime-interface-test-wasm = { version = "2.0.0-dev", path = "test-wasm" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } -sp-core = { version = "2.0.0-alpha.6", path = "../core" } -sp-io = { version = "2.0.0-alpha.6", path = "../io" } +sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } +sp-core = { version = "2.0.0-dev", path = "../core" } +sp-io = { version = "2.0.0-dev", path = "../io" } rustversion = "1.0.0" trybuild = "1.0.23" diff --git a/primitives/runtime-interface/proc-macro/Cargo.toml b/primitives/runtime-interface/proc-macro/Cargo.toml index 2691e2a4ab..28fe00cc39 100644 --- a/primitives/runtime-interface/proc-macro/Cargo.toml +++ b/primitives/runtime-interface/proc-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-runtime-interface-proc-macro" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml index 15bebea986..f992cad69b 100644 --- a/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml +++ b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml @@ -13,10 +13,10 @@ publish = false targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-runtime-interface = { version = "2.0.0-alpha.6", default-features = false, path = "../" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../io" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../core" } +sp-runtime-interface = { version = "2.0.0-dev", default-features = false, path = "../" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../io" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../core" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } diff --git a/primitives/runtime-interface/test-wasm/Cargo.toml b/primitives/runtime-interface/test-wasm/Cargo.toml index e1d8c077cf..f9e64a5027 100644 --- a/primitives/runtime-interface/test-wasm/Cargo.toml +++ b/primitives/runtime-interface/test-wasm/Cargo.toml @@ -13,10 +13,10 @@ publish = false targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-runtime-interface = { version = "2.0.0-alpha.6", default-features = false, path = "../" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../io" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../core" } +sp-runtime-interface = { version = "2.0.0-dev", default-features = false, path = "../" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../io" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../core" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } diff --git a/primitives/runtime-interface/test/Cargo.toml b/primitives/runtime-interface/test/Cargo.toml index a6bab27779..b3cdb906be 100644 --- a/primitives/runtime-interface/test/Cargo.toml +++ b/primitives/runtime-interface/test/Cargo.toml @@ -12,10 +12,10 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-runtime-interface = { version = "2.0.0-alpha.6", path = "../" } -sc-executor = { version = "0.8.0-alpha.6", path = "../../../client/executor" } +sp-runtime-interface = { version = "2.0.0-dev", path = "../" } +sc-executor = { version = "0.8.0-dev", path = "../../../client/executor" } sp-runtime-interface-test-wasm = { version = "2.0.0-dev", path = "../test-wasm" } sp-runtime-interface-test-wasm-deprecated = { version = "2.0.0-dev", path = "../test-wasm-deprecated" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../../primitives/state-machine" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../runtime" } -sp-io = { version = "2.0.0-alpha.6", path = "../../io" } +sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } +sp-runtime = { version = "2.0.0-dev", path = "../../runtime" } +sp-io = { version = "2.0.0-dev", path = "../../io" } diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index 2c44245684..7e150585c4 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-runtime" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -16,16 +16,16 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } -sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../application-crypto" } -sp-arithmetic = { version = "2.0.0-alpha.6", default-features = false, path = "../arithmetic" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../io" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } +sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../application-crypto" } +sp-arithmetic = { version = "2.0.0-dev", default-features = false, path = "../arithmetic" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../io" } log = { version = "0.4.8", optional = true } paste = "0.1.6" rand = { version = "0.7.2", optional = true } impl-trait-for-tuples = "0.1.3" -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../inherents" } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../inherents" } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } hash256-std-hasher = { version = "0.15.2", default-features = false } diff --git a/primitives/sandbox/Cargo.toml b/primitives/sandbox/Cargo.toml index 304d3864e9..a64854424e 100755 --- a/primitives/sandbox/Cargo.toml +++ b/primitives/sandbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-sandbox" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,10 +13,10 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] wasmi = { version = "0.6.2", optional = true } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../io" } -sp-wasm-interface = { version = "2.0.0-alpha.6", default-features = false, path = "../wasm-interface" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../io" } +sp-wasm-interface = { version = "2.0.0-dev", default-features = false, path = "../wasm-interface" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } [dev-dependencies] diff --git a/primitives/serializer/Cargo.toml b/primitives/serializer/Cargo.toml index 4897df3c1c..187c0e532f 100644 --- a/primitives/serializer/Cargo.toml +++ b/primitives/serializer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-serializer" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/session/Cargo.toml b/primitives/session/Cargo.toml index 7972df2a95..6d210b341f 100644 --- a/primitives/session/Cargo.toml +++ b/primitives/session/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-session" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,10 +12,10 @@ description = "Primitives for sessions" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } -sp-runtime = { version = "2.0.0-alpha.6", optional = true, path = "../runtime" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../api" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } +sp-runtime = { version = "2.0.0-dev", optional = true, path = "../runtime" } [features] default = [ "std" ] diff --git a/primitives/staking/Cargo.toml b/primitives/staking/Cargo.toml index e349b26bc4..28907a75d3 100644 --- a/primitives/staking/Cargo.toml +++ b/primitives/staking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-staking" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -13,8 +13,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } [features] default = ["std"] diff --git a/primitives/state-machine/Cargo.toml b/primitives/state-machine/Cargo.toml index 038ab5aeae..1d608ea6fc 100644 --- a/primitives/state-machine/Cargo.toml +++ b/primitives/state-machine/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-state-machine" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Substrate State Machine" edition = "2018" @@ -18,17 +18,17 @@ parking_lot = "0.10.0" hash-db = "0.15.2" trie-db = "0.20.1" trie-root = "0.16.0" -sp-trie = { version = "2.0.0-alpha.6", path = "../trie" } -sp-core = { version = "2.0.0-alpha.6", path = "../core" } -sp-panic-handler = { version = "2.0.0-alpha.6", path = "../panic-handler" } +sp-trie = { version = "2.0.0-dev", path = "../trie" } +sp-core = { version = "2.0.0-dev", path = "../core" } +sp-panic-handler = { version = "2.0.0-dev", path = "../panic-handler" } codec = { package = "parity-scale-codec", version = "1.3.0" } num-traits = "0.2.8" rand = "0.7.2" -sp-externalities = { version = "0.8.0-alpha.6", path = "../externalities" } +sp-externalities = { version = "0.8.0-dev", path = "../externalities" } [dev-dependencies] hex-literal = "0.2.1" -sp-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } +sp-runtime = { version = "2.0.0-dev", path = "../runtime" } [features] default = [] diff --git a/primitives/std/Cargo.toml b/primitives/std/Cargo.toml index d67bba985c..2b58167f17 100644 --- a/primitives/std/Cargo.toml +++ b/primitives/std/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-std" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/storage/Cargo.toml b/primitives/storage/Cargo.toml index ba53ad8d12..d7ae342b2d 100644 --- a/primitives/storage/Cargo.toml +++ b/primitives/storage/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-storage" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" description = "Storage related primitives" @@ -13,10 +13,10 @@ documentation = "https://docs.rs/sp-storage/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } impl-serde = { version = "0.2.3", optional = true } -sp-debug-derive = { version = "2.0.0-alpha.6", path = "../debug-derive" } +sp-debug-derive = { version = "2.0.0-dev", path = "../debug-derive" } [features] default = [ "std" ] diff --git a/primitives/test-primitives/Cargo.toml b/primitives/test-primitives/Cargo.toml index 8c47fc21b2..16171ea747 100644 --- a/primitives/test-primitives/Cargo.toml +++ b/primitives/test-primitives/Cargo.toml @@ -12,11 +12,11 @@ publish = false targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../application-crypto" } +sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../application-crypto" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [features] diff --git a/primitives/timestamp/Cargo.toml b/primitives/timestamp/Cargo.toml index 0fcd35893e..9de079d1a7 100644 --- a/primitives/timestamp/Cargo.toml +++ b/primitives/timestamp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-timestamp" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,11 +12,11 @@ description = "Substrate core types and inherents for timestamps." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../api" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../inherents" } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../inherents" } impl-trait-for-tuples = "0.1.3" wasm-timer = { version = "0.2", optional = true } diff --git a/primitives/transaction-pool/Cargo.toml b/primitives/transaction-pool/Cargo.toml index 9b0a59ac22..b33687246f 100644 --- a/primitives/transaction-pool/Cargo.toml +++ b/primitives/transaction-pool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-transaction-pool" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -19,9 +19,9 @@ derive_more = { version = "0.99.2", optional = true } futures = { version = "0.3.1", optional = true } log = { version = "0.4.8", optional = true } serde = { version = "1.0.101", features = ["derive"], optional = true} -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } -sp-utils = { version = "2.0.0-alpha.6", default-features = false, path = "../utils" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } +sp-utils = { version = "2.0.0-dev", default-features = false, path = "../utils" } [features] default = [ "std" ] diff --git a/primitives/trie/Cargo.toml b/primitives/trie/Cargo.toml index 2530cc3f99..c010b3262d 100644 --- a/primitives/trie/Cargo.toml +++ b/primitives/trie/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-trie" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] description = "Patricia trie stuff using a parity-scale-codec node format" repository = "https://github.com/paritytech/substrate/" @@ -18,19 +18,19 @@ harness = false [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } hash-db = { version = "0.15.2", default-features = false } trie-db = { version = "0.20.1", default-features = false } trie-root = { version = "0.16.0", default-features = false } memory-db = { version = "0.20.0", default-features = false } -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../core" } +sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } [dev-dependencies] trie-bench = "0.21.0" trie-standardmap = "0.15.2" criterion = "0.2.11" hex-literal = "0.2.1" -sp-runtime = { version = "2.0.0-alpha.6", path = "../runtime" } +sp-runtime = { version = "2.0.0-dev", path = "../runtime" } [features] default = ["std"] diff --git a/primitives/utils/Cargo.toml b/primitives/utils/Cargo.toml index 24e0294533..79a3a33154 100644 --- a/primitives/utils/Cargo.toml +++ b/primitives/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-utils" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/primitives/version/Cargo.toml b/primitives/version/Cargo.toml index bb927bb7a1..1d492ee41c 100644 --- a/primitives/version/Cargo.toml +++ b/primitives/version/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-version" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -17,8 +17,8 @@ targets = ["x86_64-unknown-linux-gnu"] impl-serde = { version = "0.2.3", optional = true } serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/wasm-interface/Cargo.toml b/primitives/wasm-interface/Cargo.toml index b8402ea0c1..8bea87d490 100644 --- a/primitives/wasm-interface/Cargo.toml +++ b/primitives/wasm-interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-wasm-interface" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -15,7 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] wasmi = { version = "0.6.2", optional = true } impl-trait-for-tuples = "0.1.2" -sp-std = { version = "2.0.0-alpha.6", path = "../std", default-features = false } +sp-std = { version = "2.0.0-dev", path = "../std", default-features = false } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } [features] diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml index bf31dfcaa1..43979be553 100644 --- a/test-utils/Cargo.toml +++ b/test-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-test-utils" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/test-utils/client/Cargo.toml b/test-utils/client/Cargo.toml index 3eb93e7380..6e9381bdaf 100644 --- a/test-utils/client/Cargo.toml +++ b/test-utils/client/Cargo.toml @@ -12,16 +12,16 @@ publish = false targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-client-api = { version = "2.0.0-alpha.6", path = "../../client/api" } -sc-client = { version = "0.8.0-alpha.6", path = "../../client/" } -sc-client-db = { version = "0.8.0-alpha.6", features = ["test-helpers"], path = "../../client/db" } -sp-consensus = { version = "0.8.0-alpha.6", path = "../../primitives/consensus/common" } -sc-executor = { version = "0.8.0-alpha.6", path = "../../client/executor" } +sc-client-api = { version = "2.0.0-dev", path = "../../client/api" } +sc-client = { version = "0.8.0-dev", path = "../../client/" } +sc-client-db = { version = "0.8.0-dev", features = ["test-helpers"], path = "../../client/db" } +sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } +sc-executor = { version = "0.8.0-dev", path = "../../client/executor" } futures = "0.3.4" hash-db = "0.15.2" -sp-keyring = { version = "2.0.0-alpha.6", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-core = { version = "2.0.0-alpha.6", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../primitives/runtime" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../primitives/blockchain" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } +sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index fe552b7d85..065a09c889 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -13,43 +13,43 @@ publish = false targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/application-crypto" } -sp-consensus-aura = { version = "0.8.0-alpha.6", default-features = false, path = "../../primitives/consensus/aura" } -sp-consensus-babe = { version = "0.8.0-alpha.6", default-features = false, path = "../../primitives/consensus/babe" } -sp-block-builder = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/block-builder" } +sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../primitives/application-crypto" } +sp-consensus-aura = { version = "0.8.0-dev", default-features = false, path = "../../primitives/consensus/aura" } +sp-consensus-babe = { version = "0.8.0-dev", default-features = false, path = "../../primitives/consensus/babe" } +sp-block-builder = { version = "2.0.0-dev", default-features = false, path = "../../primitives/block-builder" } cfg-if = "0.1.10" codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -frame-executive = { version = "2.0.0-alpha.6", default-features = false, path = "../../frame/executive" } -sp-inherents = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/inherents" } -sp-keyring = { version = "2.0.0-alpha.6", optional = true, path = "../../primitives/keyring" } +frame-executive = { version = "2.0.0-dev", default-features = false, path = "../../frame/executive" } +sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } +sp-keyring = { version = "2.0.0-dev", optional = true, path = "../../primitives/keyring" } log = { version = "0.4.8", optional = true } memory-db = { version = "0.20.0", default-features = false } -sp-offchain = { path = "../../primitives/offchain", default-features = false, version = "2.0.0-alpha.6"} -sp-core = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/std" } -sp-runtime-interface = { path = "../../primitives/runtime-interface", default-features = false, version = "2.0.0-alpha.6"} -sp-io = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/io" } -frame-support = { version = "2.0.0-alpha.6", default-features = false, path = "../../frame/support" } -sp-version = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/version" } +sp-offchain = { path = "../../primitives/offchain", default-features = false, version = "2.0.0-dev"} +sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-runtime-interface = { path = "../../primitives/runtime-interface", default-features = false, version = "2.0.0-dev"} +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-dev", default-features = false, path = "../../frame/support" } +sp-version = { version = "2.0.0-dev", default-features = false, path = "../../primitives/version" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-session = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/session" } -sp-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/runtime" } -pallet-babe = { version = "2.0.0-alpha.6", default-features = false, path = "../../frame/babe" } -frame-system = { version = "2.0.0-alpha.6", default-features = false, path = "../../frame/system" } -frame-system-rpc-runtime-api = { version = "2.0.0-alpha.6", default-features = false, path = "../../frame/system/rpc/runtime-api" } -pallet-timestamp = { version = "2.0.0-alpha.6", default-features = false, path = "../../frame/timestamp" } -sc-client = { version = "0.8.0-alpha.6", optional = true, path = "../../client" } -sp-trie = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/trie" } -sp-transaction-pool = { version = "2.0.0-alpha.6", default-features = false, path = "../../primitives/transaction-pool" } +sp-session = { version = "2.0.0-dev", default-features = false, path = "../../primitives/session" } +sp-api = { version = "2.0.0-dev", default-features = false, path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +pallet-babe = { version = "2.0.0-dev", default-features = false, path = "../../frame/babe" } +frame-system = { version = "2.0.0-dev", default-features = false, path = "../../frame/system" } +frame-system-rpc-runtime-api = { version = "2.0.0-dev", default-features = false, path = "../../frame/system/rpc/runtime-api" } +pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../frame/timestamp" } +sc-client = { version = "0.8.0-dev", optional = true, path = "../../client" } +sp-trie = { version = "2.0.0-dev", default-features = false, path = "../../primitives/trie" } +sp-transaction-pool = { version = "2.0.0-dev", default-features = false, path = "../../primitives/transaction-pool" } trie-db = { version = "0.20.1", default-features = false } parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] -sc-block-builder = { version = "0.8.0-alpha.6", path = "../../client/block-builder" } -sc-executor = { version = "0.8.0-alpha.6", path = "../../client/executor" } +sc-block-builder = { version = "0.8.0-dev", path = "../../client/block-builder" } +sc-executor = { version = "0.8.0-dev", path = "../../client/executor" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "./client" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../utils/wasm-builder-runner" } diff --git a/test-utils/runtime/client/Cargo.toml b/test-utils/runtime/client/Cargo.toml index 95484f75e3..06d4f3fcf5 100644 --- a/test-utils/runtime/client/Cargo.toml +++ b/test-utils/runtime/client/Cargo.toml @@ -12,14 +12,14 @@ publish = false targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-block-builder = { version = "0.8.0-alpha.6", path = "../../../client/block-builder" } +sc-block-builder = { version = "0.8.0-dev", path = "../../../client/block-builder" } substrate-test-client = { version = "2.0.0-dev", path = "../../client" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../runtime" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.6", path = "../../../primitives/api" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-client-api = { version = "2.0.0-alpha.6", path = "../../../client/api" } -sc-client = { version = "0.8.0-alpha.6", path = "../../../client/" } +sc-client-api = { version = "2.0.0-dev", path = "../../../client/api" } +sc-client = { version = "0.8.0-dev", path = "../../../client/" } futures = "0.3.4" diff --git a/test-utils/runtime/transaction-pool/Cargo.toml b/test-utils/runtime/transaction-pool/Cargo.toml index 64f093093d..9ccf9d2e44 100644 --- a/test-utils/runtime/transaction-pool/Cargo.toml +++ b/test-utils/runtime/transaction-pool/Cargo.toml @@ -15,9 +15,9 @@ targets = ["x86_64-unknown-linux-gnu"] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../client" } parking_lot = "0.10.0" codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../primitives/transaction-pool" } -sc-transaction-graph = { version = "2.0.0-alpha.6", path = "../../../client/transaction-pool/graph" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../../primitives/transaction-pool" } +sc-transaction-graph = { version = "2.0.0-dev", path = "../../../client/transaction-pool/graph" } futures = { version = "0.3.1", features = ["compat"] } derive_more = "0.99.2" diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 3d626d3d78..4ffec41633 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-browser-utils" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" authors = ["Parity Technologies "] description = "Utilities for creating a browser light-client." edition = "2018" @@ -22,10 +22,10 @@ js-sys = "0.3.34" wasm-bindgen = "0.2.57" wasm-bindgen-futures = "0.4.7" kvdb-web = "0.5" -sc-informant = { version = "0.8.0-alpha.6", path = "../../client/informant" } -sc-service = { version = "0.8.0-alpha.6", path = "../../client/service", default-features = false } -sc-network = { path = "../../client/network", version = "0.8.0-alpha.6"} -sc-chain-spec = { path = "../../client/chain-spec", version = "2.0.0-alpha.6"} +sc-informant = { version = "0.8.0-dev", path = "../../client/informant" } +sc-service = { version = "0.8.0-dev", path = "../../client/service", default-features = false } +sc-network = { path = "../../client/network", version = "0.8.0-dev"} +sc-chain-spec = { path = "../../client/chain-spec", version = "2.0.0-dev"} # Imported just for the `no_cc` feature clear_on_drop = { version = "0.2.3", features = ["no_cc"] } diff --git a/utils/build-script-utils/Cargo.toml b/utils/build-script-utils/Cargo.toml index 335ec045f3..89c584808a 100644 --- a/utils/build-script-utils/Cargo.toml +++ b/utils/build-script-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-build-script-utils" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/utils/fork-tree/Cargo.toml b/utils/fork-tree/Cargo.toml index 0c632c4df3..c18826d16f 100644 --- a/utils/fork-tree/Cargo.toml +++ b/utils/fork-tree/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fork-tree" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/utils/frame/benchmarking-cli/Cargo.toml b/utils/frame/benchmarking-cli/Cargo.toml index eb5e0549f9..9366c276ed 100644 --- a/utils/frame/benchmarking-cli/Cargo.toml +++ b/utils/frame/benchmarking-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-benchmarking-cli" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,16 +12,16 @@ description = "CLI for benchmarking FRAME" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -frame-benchmarking = { version = "2.0.0-alpha.6", path = "../../../frame/benchmarking" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../primitives/core" } -sc-service = { version = "0.8.0-alpha.6", default-features = false, path = "../../../client/service" } -sc-cli = { version = "0.8.0-alpha.6", path = "../../../client/cli" } -sc-client = { version = "0.8.0-alpha.6", path = "../../../client" } -sc-client-db = { version = "0.8.0-alpha.6", path = "../../../client/db" } -sc-executor = { version = "0.8.0-alpha.6", path = "../../../client/executor" } -sp-externalities = { version = "0.8.0-alpha.6", path = "../../../primitives/externalities" } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-alpha.6", path = "../../../primitives/state-machine" } +frame-benchmarking = { version = "2.0.0-dev", path = "../../../frame/benchmarking" } +sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sc-service = { version = "0.8.0-dev", default-features = false, path = "../../../client/service" } +sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } +sc-client = { version = "0.8.0-dev", path = "../../../client" } +sc-client-db = { version = "0.8.0-dev", path = "../../../client/db" } +sc-executor = { version = "0.8.0-dev", path = "../../../client/executor" } +sp-externalities = { version = "0.8.0-dev", path = "../../../primitives/externalities" } +sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } structopt = "0.3.8" codec = { version = "1.3.0", package = "parity-scale-codec" } diff --git a/utils/frame/rpc/support/Cargo.toml b/utils/frame/rpc/support/Cargo.toml index 9d1425e5c9..c635471bb9 100644 --- a/utils/frame/rpc/support/Cargo.toml +++ b/utils/frame/rpc/support/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-frame-rpc-support" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies ", "Andrew Dirksen "] edition = "2018" license = "GPL-3.0" @@ -17,10 +17,10 @@ jsonrpc-client-transports = { version = "14.0.5", default-features = false, feat jsonrpc-core = "14" codec = { package = "parity-scale-codec", version = "1" } serde = "1" -frame-support = { version = "2.0.0-alpha.6", path = "../../../../frame/support" } -sp-storage = { version = "2.0.0-alpha.6", path = "../../../../primitives/storage" } -sc-rpc-api = { version = "0.8.0-alpha.6", path = "../../../../client/rpc-api" } +frame-support = { version = "2.0.0-dev", path = "../../../../frame/support" } +sp-storage = { version = "2.0.0-dev", path = "../../../../primitives/storage" } +sc-rpc-api = { version = "0.8.0-dev", path = "../../../../client/rpc-api" } [dev-dependencies] -frame-system = { version = "2.0.0-alpha.6", path = "../../../../frame/system" } +frame-system = { version = "2.0.0-dev", path = "../../../../frame/system" } tokio = "0.2" diff --git a/utils/frame/rpc/system/Cargo.toml b/utils/frame/rpc/system/Cargo.toml index 2c98e41fff..20524a460a 100644 --- a/utils/frame/rpc/system/Cargo.toml +++ b/utils/frame/rpc/system/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-frame-rpc-system" -version = "2.0.0-alpha.6" +version = "2.0.0-dev" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" @@ -12,7 +12,7 @@ description = "FRAME's system exposed over Substrate RPC" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-client = { version = "0.8.0-alpha.6", path = "../../../../client/" } +sc-client = { version = "0.8.0-dev", path = "../../../../client/" } codec = { package = "parity-scale-codec", version = "1.3.0" } futures = "0.3.4" jsonrpc-core = "14.0.3" @@ -20,14 +20,14 @@ jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.3" log = "0.4.8" serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-alpha.6", path = "../../../../primitives/runtime" } -sp-api = { version = "2.0.0-alpha.6", path = "../../../../primitives/api" } -frame-system-rpc-runtime-api = { version = "2.0.0-alpha.6", path = "../../../../frame/system/rpc/runtime-api" } -sp-core = { version = "2.0.0-alpha.6", path = "../../../../primitives/core" } -sp-blockchain = { version = "2.0.0-alpha.6", path = "../../../../primitives/blockchain" } -sp-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../../primitives/transaction-pool" } +sp-runtime = { version = "2.0.0-dev", path = "../../../../primitives/runtime" } +sp-api = { version = "2.0.0-dev", path = "../../../../primitives/api" } +frame-system-rpc-runtime-api = { version = "2.0.0-dev", path = "../../../../frame/system/rpc/runtime-api" } +sp-core = { version = "2.0.0-dev", path = "../../../../primitives/core" } +sp-blockchain = { version = "2.0.0-dev", path = "../../../../primitives/blockchain" } +sp-transaction-pool = { version = "2.0.0-dev", path = "../../../../primitives/transaction-pool" } [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../../test-utils/runtime/client" } env_logger = "0.7.0" -sc-transaction-pool = { version = "2.0.0-alpha.6", path = "../../../../client/transaction-pool" } +sc-transaction-pool = { version = "2.0.0-dev", path = "../../../../client/transaction-pool" } diff --git a/utils/prometheus/Cargo.toml b/utils/prometheus/Cargo.toml index 307bb7193c..0b46540903 100644 --- a/utils/prometheus/Cargo.toml +++ b/utils/prometheus/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Endpoint to expose Prometheus metrics" name = "substrate-prometheus-endpoint" -version = "0.8.0-alpha.6" +version = "0.8.0-dev" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" -- GitLab From bc2a198dc0da64899fd6d72cb3af28779b267026 Mon Sep 17 00:00:00 2001 From: cheme Date: Wed, 15 Apr 2020 14:25:27 +0200 Subject: [PATCH 228/300] sp-io documentation changes. --- primitives/io/src/lib.rs | 68 +++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index c8004057a7..5178fb7169 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -145,8 +145,9 @@ pub trait Storage { self.next_storage_key(&key) } - - /// Deprecated, please use dedicated runtime apis. + /// Read child key. + /// + /// Deprecated, please use dedicated runtime apis (`sp_io::default_child_storage::get`). fn child_get( &self, storage_key: &[u8], @@ -160,7 +161,9 @@ pub trait Storage { self.child_storage(&child_info, key).map(|s| s.to_vec()) } - /// Deprecated, please use dedicated runtime apis. + /// Read child key. + /// + /// Deprecated, please use dedicated runtime apis (`sp_io::default_child_storage::read`). fn child_read( &self, storage_key: &[u8], @@ -183,7 +186,9 @@ pub trait Storage { }) } - /// Deprecated, please use dedicated runtime apis. + /// Set a child storage value. + /// + /// Deprecated, please use dedicated runtime apis (`sp_io::default_child_storage::set`). fn child_set( &mut self, storage_key: &[u8], @@ -198,7 +203,9 @@ pub trait Storage { self.set_child_storage(&child_info, key.to_vec(), value.to_vec()); } - /// Deprecated, please use dedicated runtime apis. + /// Remove child key value. + /// + /// Deprecated, please use dedicated runtime apis (`sp_io::default_child_storage::clear`). fn child_clear( &mut self, storage_key: &[u8], @@ -212,7 +219,9 @@ pub trait Storage { self.clear_child_storage(&child_info, key); } - /// Deprecated, please use dedicated runtime apis. + /// Remove all child storage values. + /// + /// Deprecated, please use dedicated runtime apis (`sp_io::default_child_storage::storage_kill`). fn child_storage_kill( &mut self, storage_key: &[u8], @@ -225,7 +234,9 @@ pub trait Storage { self.kill_child_storage(&child_info); } - /// Deprecated, please use dedicated runtime apis. + /// Check a child storage key. + /// + /// Deprecated, please use dedicated runtime apis (`sp_io::default_child_storage::exists`). fn child_exists( &self, storage_key: &[u8], @@ -239,7 +250,9 @@ pub trait Storage { self.exists_child_storage(&child_info, key) } - /// Deprecated, please use dedicated runtime apis. + /// Clear child key by prefix. + /// + /// Deprecated, please use dedicated runtime apis (`sp_io::default_child_storage::clear_prefix`). fn child_clear_prefix( &mut self, storage_key: &[u8], @@ -253,7 +266,9 @@ pub trait Storage { self.clear_child_prefix(&child_info, prefix); } - /// Deprecated, please use dedicated runtime apis. + /// Child trie root calcualation. + /// + /// Deprecated, please use dedicated runtime apis (`sp_io::default_child_storage::clear_root`). fn child_root( &mut self, storage_key: &[u8], @@ -268,7 +283,9 @@ pub trait Storage { self.child_storage_root(&child_info) } - /// Deprecated, please use dedicated runtime apis. + /// Child storage key iteration. + /// + /// Deprecated, please use dedicated runtime apis (`sp_io::default_child_storage::next_key`). fn child_next_key( &mut self, storage_key: &[u8], @@ -281,18 +298,17 @@ pub trait Storage { .expect("Invalid child definition"); self.next_child_storage_key(&child_info, key) } - } - /// Interface for accessing the child storage for default child trie, /// from within the runtime. #[runtime_interface] pub trait DefaultChildStorage { - /// `storage_key` is the unprefixed location of the root of the child trie in the parent trie. + + /// Get a default child storage value for a given key. /// - /// This function specifically returns the data for `key` in the child storage or `None` - /// if the key can not be found. + /// Parameter `storage_key` is the unprefixed location of the root of the child trie in the parent trie. + /// Result is `None` if the value for `key` in the child storage can not be found. fn get( &self, storage_key: &[u8], @@ -302,6 +318,8 @@ pub trait DefaultChildStorage { self.child_storage(&child_info, key).map(|s| s.to_vec()) } + /// Allocation efficient variant of `get`. + /// /// Get `key` from child storage, placing the value into `value_out` and return the number /// of bytes that the entry in storage has beyond the offset or `None` if the storage entry /// doesn't exist at all. @@ -325,6 +343,8 @@ pub trait DefaultChildStorage { }) } + /// Set a child storage value. + /// /// Set `key` to `value` in the child storage denoted by `storage_key`. fn set( &mut self, @@ -336,7 +356,9 @@ pub trait DefaultChildStorage { self.set_child_storage(&child_info, key.to_vec(), value.to_vec()); } - /// Clear the given child storage of the given `key` and its value. + /// Clear a child storage key. + /// + /// For the default child storage at `storage_key`, clear value at `key`. fn clear ( &mut self, storage_key: &[u8], @@ -347,6 +369,9 @@ pub trait DefaultChildStorage { } /// Clear an entire child storage. + /// + /// If it exists, the child storage for `storage_key` + /// is removed. fn storage_kill( &mut self, storage_key: &[u8], @@ -355,7 +380,9 @@ pub trait DefaultChildStorage { self.kill_child_storage(&child_info); } - /// Check whether the given `key` exists in storage. + /// Check a child storage key. + /// + /// Check whether the given `key` exists in default child defined at `storage_key`. fn exists( &self, storage_key: &[u8], @@ -365,6 +392,8 @@ pub trait DefaultChildStorage { self.exists_child_storage(&child_info, key) } + /// Clear child default key by prefix. + /// /// Clear the child storage of each key-value pair where the key starts with the given `prefix`. fn clear_prefix( &mut self, @@ -375,8 +404,9 @@ pub trait DefaultChildStorage { self.clear_child_prefix(&child_info, prefix); } - /// "Commit" all existing operations and compute the resulting child storage root. + /// Default child root calculation. /// + /// "Commit" all existing operations and compute the resulting child storage root. /// The hashing algorithm is defined by the `Block`. /// /// Returns the SCALE encoded hash. @@ -388,6 +418,8 @@ pub trait DefaultChildStorage { self.child_storage_root(&child_info) } + /// Child storage key iteration. + /// /// Get the next key in storage after the given one in lexicographic order in child storage. fn next_key( &mut self, -- GitLab From 88248c040fd0a0ff004f448fc8c47fdf000b653e Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Wed, 15 Apr 2020 14:38:39 +0200 Subject: [PATCH 229/300] New database trait (#5549) * Introduce trait * The trait * Generic * Basic impls. * Remove unneeded bounds * Minor changes * Switch over to the new DB trait * Integrated parity-db and added CLI for db selection * Default impl. * Fix logs. * Started integrating subdb * Apply suggestions from code review Co-Authored-By: Cecile Tonglet * Apply suggestions from code review Co-Authored-By: Nikolay Volf * Enable subdb * Bump parity-db * Fixed CLI macro * Fixed browser build * Fixed features * Sort out features * Use parity-db from crates.io * Typo Co-authored-by: arkpar Co-authored-by: Cecile Tonglet Co-authored-by: Nikolay Volf --- Cargo.lock | 97 +++++++ Cargo.toml | 1 + bin/node/cli/Cargo.toml | 2 +- bin/node/testing/Cargo.toml | 4 +- bin/node/testing/src/bench.rs | 2 +- client/Cargo.toml | 1 + client/cli/src/arg_enums.rs | 14 + client/cli/src/commands/export_blocks_cmd.rs | 2 +- client/cli/src/commands/mod.rs | 9 +- client/cli/src/commands/purge_chain_cmd.rs | 2 +- client/cli/src/config.rs | 23 +- client/cli/src/params/import_params.rs | 17 +- client/cli/src/params/shared_params.rs | 19 +- client/consensus/slots/src/lib.rs | 2 +- client/db/Cargo.toml | 4 + client/db/src/cache/list_storage.rs | 52 ++-- client/db/src/cache/mod.rs | 22 +- client/db/src/changes_tries_storage.rs | 40 +-- client/db/src/children.rs | 35 ++- client/db/src/lib.rs | 274 ++++++++----------- client/db/src/light.rs | 114 ++++---- client/db/src/offchain.rs | 25 +- client/db/src/parity_db.rs | 56 ++++ client/db/src/subdb.rs | 87 ++++++ client/db/src/upgrade.rs | 103 +------ client/db/src/utils.rs | 105 +++---- client/network/test/src/lib.rs | 15 +- client/network/test/src/sync.rs | 27 +- client/service/Cargo.toml | 4 +- client/service/src/builder.rs | 22 +- client/service/src/config.rs | 17 +- client/service/test/src/lib.rs | 2 +- client/src/client.rs | 4 +- client/src/leaves.rs | 73 +++-- frame/support/src/traits.rs | 2 +- primitives/blockchain/src/backend.rs | 2 +- primitives/database/Cargo.toml | 14 + primitives/database/src/kvdb.rs | 59 ++++ primitives/database/src/lib.rs | 187 +++++++++++++ primitives/database/src/mem.rs | 68 +++++ utils/browser/Cargo.toml | 1 + utils/browser/src/lib.rs | 2 +- utils/frame/benchmarking-cli/Cargo.toml | 4 +- 43 files changed, 1036 insertions(+), 579 deletions(-) create mode 100644 client/db/src/parity_db.rs create mode 100644 client/db/src/subdb.rs create mode 100644 primitives/database/Cargo.toml create mode 100644 primitives/database/src/kvdb.rs create mode 100644 primitives/database/src/lib.rs create mode 100644 primitives/database/src/mem.rs diff --git a/Cargo.lock b/Cargo.lock index 72653fefa5..1eab8009dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1081,6 +1081,16 @@ dependencies = [ "dirs-sys", ] +[[package]] +name = "dirs" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +dependencies = [ + "cfg-if", + "dirs-sys", +] + [[package]] name = "dirs-sys" version = "0.3.4" @@ -4686,6 +4696,19 @@ dependencies = [ "sp-storage", ] +[[package]] +name = "parity-db" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4174d70be686b0d7cdee964b2d723e1461e28390c8804f01efc907d81043be9" +dependencies = [ + "blake2-rfc", + "libc", + "log", + "memmap", + "parking_lot 0.10.2", +] + [[package]] name = "parity-multiaddr" version = "0.7.3" @@ -5034,6 +5057,16 @@ dependencies = [ "output_vt100", ] +[[package]] +name = "pretty_env_logger" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" +dependencies = [ + "env_logger 0.7.1", + "log", +] + [[package]] name = "primitive-types" version = "0.7.0" @@ -5900,6 +5933,7 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-core", + "sp-database 2.0.0-dev", "sp-externalities", "sp-inherents", "sp-keyring", @@ -5954,6 +5988,7 @@ dependencies = [ name = "sc-client-db" version = "0.8.0-dev" dependencies = [ + "blake2-rfc", "env_logger 0.7.1", "hash-db", "kvdb", @@ -5961,6 +5996,7 @@ dependencies = [ "kvdb-rocksdb", "linked-hash-map", "log", + "parity-db", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.2", @@ -5972,10 +6008,12 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-core", + "sp-database 2.0.0-dev", "sp-keyring", "sp-runtime", "sp-state-machine", "sp-trie", + "subdb", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", @@ -6995,6 +7033,17 @@ dependencies = [ "libc", ] +[[package]] +name = "simplelog" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcacac97349a890d437921dfb23cbec52ab5b4752551cb637df2721371acd467" +dependencies = [ + "chrono", + "log", + "term", +] + [[package]] name = "slab" version = "0.4.2" @@ -7375,6 +7424,23 @@ dependencies = [ "zeroize", ] +[[package]] +name = "sp-database" +version = "2.0.0-alpha.5" +source = "git+https://github.com/paritytech/substrate?branch=gav-db-trait#9404815700a840586fc8760a60180f4e1bf97ce4" +dependencies = [ + "kvdb", + "parking_lot 0.10.2", +] + +[[package]] +name = "sp-database" +version = "2.0.0-dev" +dependencies = [ + "kvdb", + "parking_lot 0.10.2", +] + [[package]] name = "sp-debug-derive" version = "2.0.0-dev" @@ -7855,6 +7921,26 @@ dependencies = [ "syn 1.0.17", ] +[[package]] +name = "subdb" +version = "0.1.0" +source = "git+https://github.com/paritytech/subdb#353bd49a95e618641b552fe890b272f0feb6d752" +dependencies = [ + "blake2-rfc", + "derive_more", + "hash-db", + "hex", + "log", + "memmap", + "parity-scale-codec", + "parking_lot 0.10.2", + "pretty_env_logger", + "simplelog", + "smallvec 1.3.0", + "sp-database 2.0.0-alpha.5", + "twox-hash", +] + [[package]] name = "subkey" version = "2.0.0-dev" @@ -7917,6 +8003,7 @@ dependencies = [ "sc-informant", "sc-network", "sc-service", + "sp-database 2.0.0-dev", "wasm-bindgen", "wasm-bindgen-futures", ] @@ -8272,6 +8359,16 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "term" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" +dependencies = [ + "dirs", + "winapi 0.3.8", +] + [[package]] name = "termcolor" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index ab19142da6..ad05847f61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -123,6 +123,7 @@ members = [ "primitives/consensus/vrf", "primitives/core", "primitives/chain-spec", + "primitives/database", "primitives/debug-derive", "primitives/storage", "primitives/externalities", diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index 6d7beaa5ee..1f22e85ab6 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -148,7 +148,7 @@ cli = [ "node-transaction-factory", "sc-cli", "frame-benchmarking-cli", - "sc-service/rocksdb", + "sc-service/db", "structopt", "substrate-build-script-utils", ] diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index ee31b88a66..8ca5132eb9 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -15,7 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] pallet-balances = { version = "2.0.0-dev", path = "../../../frame/balances" } sc-client = { version = "0.8.0-dev", path = "../../../client/" } -sc-client-db = { version = "0.8.0-dev", path = "../../../client/db/", features = ["kvdb-rocksdb"] } +sc-client-db = { version = "0.8.0-dev", path = "../../../client/db/", features = ["kvdb-rocksdb", "parity-db"] } sc-client-api = { version = "2.0.0-dev", path = "../../../client/api/" } codec = { package = "parity-scale-codec", version = "1.3.0" } pallet-contracts = { version = "2.0.0-dev", path = "../../../frame/contracts" } @@ -54,4 +54,4 @@ fs_extra = "1" [dev-dependencies] criterion = "0.3.0" sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } -sc-service = { version = "0.8.0-dev", path = "../../../client/service", features = ["rocksdb"] } +sc-service = { version = "0.8.0-dev", path = "../../../client/service", features = ["db"] } diff --git a/bin/node/testing/src/bench.rs b/bin/node/testing/src/bench.rs index 2ca6428bed..9f7ab57895 100644 --- a/bin/node/testing/src/bench.rs +++ b/bin/node/testing/src/bench.rs @@ -184,7 +184,7 @@ impl BenchDb { state_cache_size: 16*1024*1024, state_cache_child_ratio: Some((0, 100)), pruning: PruningMode::ArchiveAll, - source: sc_client_db::DatabaseSettingsSrc::Path { + source: sc_client_db::DatabaseSettingsSrc::RocksDb { path: dir.into(), cache_size: 512, }, diff --git a/client/Cargo.toml b/client/Cargo.toml index 2711a6847f..bf93cdfde8 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -38,6 +38,7 @@ sp-blockchain = { version = "2.0.0-dev", path = "../primitives/blockchain" } sp-state-machine = { version = "0.8.0-dev", path = "../primitives/state-machine" } sc-telemetry = { version = "2.0.0-dev", path = "telemetry" } sp-trie = { version = "2.0.0-dev", path = "../primitives/trie" } +sp-database = { version = "2.0.0-dev", path = "../primitives/database" } prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-dev", path = "../utils/prometheus" } tracing = "0.1.10" diff --git a/client/cli/src/arg_enums.rs b/client/cli/src/arg_enums.rs index f09a8d8d47..2adccdd879 100644 --- a/client/cli/src/arg_enums.rs +++ b/client/cli/src/arg_enums.rs @@ -122,6 +122,20 @@ impl ExecutionStrategy { } } +arg_enum! { + /// Database backend + #[allow(missing_docs)] + #[derive(Debug, Clone, Copy)] + pub enum Database { + // Facebooks RocksDB + RocksDb, + // Subdb. https://github.com/paritytech/subdb/ + SubDb, + // ParityDb. https://github.com/paritytech/parity-db/ + ParityDb, + } +} + /// Default value for the `--execution-syncing` parameter. pub const DEFAULT_EXECUTION_SYNCING: ExecutionStrategy = ExecutionStrategy::NativeElseWasm; /// Default value for the `--execution-import-block` parameter. diff --git a/client/cli/src/commands/export_blocks_cmd.rs b/client/cli/src/commands/export_blocks_cmd.rs index 48abd409d6..297d83506b 100644 --- a/client/cli/src/commands/export_blocks_cmd.rs +++ b/client/cli/src/commands/export_blocks_cmd.rs @@ -74,7 +74,7 @@ impl ExportBlocksCmd { <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, ::Hash: std::str::FromStr, { - if let DatabaseConfig::Path { ref path, .. } = &config.database { + if let DatabaseConfig::RocksDb { ref path, .. } = &config.database { info!("DB path: {}", path.display()); } diff --git a/client/cli/src/commands/mod.rs b/client/cli/src/commands/mod.rs index d05a5464b2..68c22c4868 100644 --- a/client/cli/src/commands/mod.rs +++ b/client/cli/src/commands/mod.rs @@ -204,9 +204,16 @@ macro_rules! substrate_cli_subcommands { &self, base_path: &::std::path::PathBuf, cache_size: usize, + database: $crate::Database, ) -> $crate::Result<::sc_service::config::DatabaseConfig> { match self { - $($enum::$variant(cmd) => cmd.database_config(base_path, cache_size)),* + $($enum::$variant(cmd) => cmd.database_config(base_path, cache_size, database)),* + } + } + + fn database(&self) -> $crate::Result<::std::option::Option<$crate::Database>> { + match self { + $($enum::$variant(cmd) => cmd.database()),* } } diff --git a/client/cli/src/commands/purge_chain_cmd.rs b/client/cli/src/commands/purge_chain_cmd.rs index 845423695e..3be2883bd5 100644 --- a/client/cli/src/commands/purge_chain_cmd.rs +++ b/client/cli/src/commands/purge_chain_cmd.rs @@ -39,7 +39,7 @@ impl PurgeChainCmd { /// Run the purge command pub fn run(&self, config: Configuration) -> error::Result<()> { let db_path = match &config.database { - DatabaseConfig::Path { path, .. } => path, + DatabaseConfig::RocksDb { path, .. } => path, _ => { eprintln!("Cannot purge custom database implementation"); return Ok(()); diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index 6c4cc0e710..8c8490ff1a 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -21,6 +21,7 @@ use crate::{ init_logger, ImportParams, KeystoreParams, NetworkParams, NodeKeyParams, PruningParams, SharedParams, SubstrateCli, }; +use crate::arg_enums::Database; use app_dirs::{AppDataType, AppInfo}; use names::{Generator, Name}; use sc_service::config::{ @@ -152,11 +153,26 @@ pub trait CliConfiguration: Sized { .unwrap_or(Default::default())) } + /// Get the database backend variant. + /// + /// By default this is retrieved from `ImportParams` if it is available. Otherwise its `None`. + fn database(&self) -> Result> { + Ok(self.import_params().map(|x| x.database())) + } + /// Get the database configuration. /// /// By default this is retrieved from `SharedParams` - fn database_config(&self, base_path: &PathBuf, cache_size: usize) -> Result { - Ok(self.shared_params().database_config(base_path, cache_size)) + fn database_config(&self, + base_path: &PathBuf, + cache_size: usize, + database: Database, + ) -> Result { + Ok(self.shared_params().database_config( + base_path, + cache_size, + database, + )) } /// Get the state cache size. @@ -376,6 +392,7 @@ pub trait CliConfiguration: Sized { let net_config_dir = config_dir.join(DEFAULT_NETWORK_CONFIG_PATH); let client_id = C::client_id(); let database_cache_size = self.database_cache_size()?.unwrap_or(128); + let database = self.database()?.unwrap_or(Database::RocksDb); let node_key = self.node_key(&net_config_dir)?; let role = self.role(is_dev)?; let max_runtime_instances = self.max_runtime_instances()?.unwrap_or(8); @@ -394,7 +411,7 @@ pub trait CliConfiguration: Sized { node_key, )?, keystore: self.keystore_config(&config_dir)?, - database: self.database_config(&config_dir, database_cache_size)?, + database: self.database_config(&config_dir, database_cache_size, database)?, state_cache_size: self.state_cache_size()?, state_cache_child_ratio: self.state_cache_child_ratio()?, pruning: self.pruning(is_dev, &role)?, diff --git a/client/cli/src/params/import_params.rs b/client/cli/src/params/import_params.rs index 08ca1c8f8f..95b04b039a 100644 --- a/client/cli/src/params/import_params.rs +++ b/client/cli/src/params/import_params.rs @@ -17,7 +17,7 @@ use crate::arg_enums::{ ExecutionStrategy, TracingReceiver, WasmExecutionMethod, DEFAULT_EXECUTION_BLOCK_CONSTRUCTION, DEFAULT_EXECUTION_IMPORT_BLOCK, DEFAULT_EXECUTION_OFFCHAIN_WORKER, DEFAULT_EXECUTION_OTHER, - DEFAULT_EXECUTION_SYNCING, + DEFAULT_EXECUTION_SYNCING, Database, }; use crate::params::PruningParams; use crate::Result; @@ -54,6 +54,16 @@ pub struct ImportParams { #[structopt(flatten)] pub execution_strategies: ExecutionStrategiesParams, + /// Select database backend to use. + #[structopt( + long = "database", + alias = "db", + value_name = "DB", + case_insensitive = true, + default_value = "RocksDb" + )] + pub database: Database, + /// Limit the memory the database cache can use. #[structopt(long = "db-cache", value_name = "MiB")] pub database_cache_size: Option, @@ -132,6 +142,11 @@ impl ImportParams { pub fn database_cache_size(&self) -> Option { self.database_cache_size } + + /// Limit the memory the database cache can use. + pub fn database(&self) -> Database { + self.database + } } /// Execution strategies parameters. diff --git a/client/cli/src/params/shared_params.rs b/client/cli/src/params/shared_params.rs index f7f9db102c..d6dd1bd9c1 100644 --- a/client/cli/src/params/shared_params.rs +++ b/client/cli/src/params/shared_params.rs @@ -17,9 +17,7 @@ use sc_service::config::DatabaseConfig; use std::path::PathBuf; use structopt::StructOpt; - -/// default sub directory to store database -const DEFAULT_DB_CONFIG_PATH: &'static str = "db"; +use crate::arg_enums::Database; /// Shared parameters used by all `CoreParams`. #[derive(Debug, StructOpt, Clone)] @@ -79,10 +77,19 @@ impl SharedParams { &self, base_path: &PathBuf, cache_size: usize, + database: Database, ) -> DatabaseConfig { - DatabaseConfig::Path { - path: base_path.join(DEFAULT_DB_CONFIG_PATH), - cache_size, + match database { + Database::RocksDb => DatabaseConfig::RocksDb { + path: base_path.join("db"), + cache_size, + }, + Database::SubDb => DatabaseConfig::SubDb { + path: base_path.join("subdb"), + }, + Database::ParityDb => DatabaseConfig::ParityDb { + path: base_path.join("paritydb"), + }, } } diff --git a/client/consensus/slots/src/lib.rs b/client/consensus/slots/src/lib.rs index 5952856bda..2a0739a831 100644 --- a/client/consensus/slots/src/lib.rs +++ b/client/consensus/slots/src/lib.rs @@ -466,7 +466,7 @@ impl SlotDuration { cb(client.runtime_api(), &BlockId::number(Zero::zero()))?; info!( - "⏱ Loaded block-time = {:?} milliseconds from genesis on first-launch", + "⏱ Loaded block-time = {:?} milliseconds from genesis on first-launch", genesis_slot_duration ); diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index 70f1c091a2..307cacbfb2 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -21,6 +21,7 @@ linked-hash-map = "0.5.2" hash-db = "0.15.2" parity-util-mem = { version = "0.6.0", default-features = false, features = ["std"] } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } +blake2-rfc = "0.2.18" sc-client-api = { version = "2.0.0-dev", path = "../api" } sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } @@ -32,6 +33,9 @@ sc-state-db = { version = "0.8.0-dev", path = "../state-db" } sp-trie = { version = "2.0.0-dev", path = "../../primitives/trie" } sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } +sp-database = { version = "2.0.0-dev", path = "../../primitives/database" } +parity-db = { version = "0.1", optional = true } +subdb = { git = "https://github.com/paritytech/subdb", optional = true } prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-dev", path = "../../utils/prometheus" } [dev-dependencies] diff --git a/client/db/src/cache/list_storage.rs b/client/db/src/cache/list_storage.rs index 606090ee14..07cd9fb866 100644 --- a/client/db/src/cache/list_storage.rs +++ b/client/db/src/cache/list_storage.rs @@ -18,17 +18,17 @@ use std::sync::Arc; -use kvdb::{KeyValueDB, DBTransaction}; - use sp_blockchain::{Error as ClientError, Result as ClientResult}; use codec::{Encode, Decode}; use sp_runtime::generic::BlockId; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; -use crate::utils::{self, db_err, meta_keys}; +use sp_database::{Database, Transaction}; +use crate::utils::{self, meta_keys}; use crate::cache::{CacheItemT, ComplexBlockId}; use crate::cache::list_cache::{CommitOperation, Fork}; use crate::cache::list_entry::{Entry, StorageEntry}; +use crate::DbHash; /// Single list-cache metadata. #[derive(Debug)] @@ -97,19 +97,19 @@ pub struct DbColumns { pub struct DbStorage { name: Vec, meta_key: Vec, - db: Arc, + db: Arc>, columns: DbColumns, } impl DbStorage { /// Create new database-backed list cache storage. - pub fn new(name: Vec, db: Arc, columns: DbColumns) -> Self { + pub fn new(name: Vec, db: Arc>, columns: DbColumns) -> Self { let meta_key = meta::key(&name); DbStorage { name, meta_key, db, columns } } /// Get reference to the database. - pub fn db(&self) -> &Arc { &self.db } + pub fn db(&self) -> &Arc> { &self.db } /// Get reference to the database columns. pub fn columns(&self) -> &DbColumns { &self.columns } @@ -135,49 +135,45 @@ impl Storage for DbStorage { } fn read_meta(&self) -> ClientResult> { - self.db.get(self.columns.meta, &self.meta_key) - .map_err(db_err) - .and_then(|meta| match meta { - Some(meta) => meta::decode(&*meta), - None => Ok(Metadata { - finalized: None, - unfinalized: Vec::new(), - }), + match self.db.get(self.columns.meta, &self.meta_key) { + Some(meta) => meta::decode(&*meta), + None => Ok(Metadata { + finalized: None, + unfinalized: Vec::new(), }) + } } fn read_entry(&self, at: &ComplexBlockId) -> ClientResult>> { - self.db.get(self.columns.cache, &self.encode_block_id(at)) - .map_err(db_err) - .and_then(|entry| match entry { - Some(entry) => StorageEntry::::decode(&mut &entry[..]) - .map_err(|_| ClientError::Backend("Failed to decode cache entry".into())) - .map(Some), - None => Ok(None), - }) + match self.db.get(self.columns.cache, &self.encode_block_id(at)) { + Some(entry) => StorageEntry::::decode(&mut &entry[..]) + .map_err(|_| ClientError::Backend("Failed to decode cache entry".into())) + .map(Some), + None => Ok(None), + } } } /// Database-backed list cache storage transaction. pub struct DbStorageTransaction<'a> { storage: &'a DbStorage, - tx: &'a mut DBTransaction, + tx: &'a mut Transaction, } impl<'a> DbStorageTransaction<'a> { /// Create new database transaction. - pub fn new(storage: &'a DbStorage, tx: &'a mut DBTransaction) -> Self { + pub fn new(storage: &'a DbStorage, tx: &'a mut Transaction) -> Self { DbStorageTransaction { storage, tx } } } impl<'a, Block: BlockT, T: CacheItemT> StorageTransaction for DbStorageTransaction<'a> { fn insert_storage_entry(&mut self, at: &ComplexBlockId, entry: &StorageEntry) { - self.tx.put(self.storage.columns.cache, &self.storage.encode_block_id(at), &entry.encode()); + self.tx.set_from_vec(self.storage.columns.cache, &self.storage.encode_block_id(at), entry.encode()); } fn remove_storage_entry(&mut self, at: &ComplexBlockId) { - self.tx.delete(self.storage.columns.cache, &self.storage.encode_block_id(at)); + self.tx.remove(self.storage.columns.cache, &self.storage.encode_block_id(at)); } fn update_meta( @@ -186,10 +182,10 @@ impl<'a, Block: BlockT, T: CacheItemT> StorageTransaction for DbStorag unfinalized: &[Fork], operation: &CommitOperation, ) { - self.tx.put( + self.tx.set_from_vec( self.storage.columns.meta, &self.storage.meta_key, - &meta::encode(best_finalized_entry, unfinalized, operation)); + meta::encode(best_finalized_entry, unfinalized, operation)); } } diff --git a/client/db/src/cache/mod.rs b/client/db/src/cache/mod.rs index 8fd1adc094..8d3e1f358b 100644 --- a/client/db/src/cache/mod.rs +++ b/client/db/src/cache/mod.rs @@ -19,14 +19,14 @@ use std::{sync::Arc, collections::{HashMap, hash_map::Entry}}; use parking_lot::RwLock; -use kvdb::{KeyValueDB, DBTransaction}; - use sc_client_api::blockchain::{well_known_cache_keys::{self, Id as CacheKeyId}, Cache as BlockchainCache}; use sp_blockchain::Result as ClientResult; +use sp_database::{Database, Transaction}; use codec::{Encode, Decode}; use sp_runtime::generic::BlockId; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}; -use crate::utils::{self, COLUMN_META, db_err}; +use crate::utils::{self, COLUMN_META}; +use crate::DbHash; use self::list_cache::{ListCache, PruningStrategy}; @@ -78,7 +78,7 @@ impl CacheItemT for T where T: Clone + Decode + Encode + PartialEq {} /// Database-backed blockchain data cache. pub struct DbCache { cache_at: HashMap, self::list_storage::DbStorage>>, - db: Arc, + db: Arc>, key_lookup_column: u32, header_column: u32, cache_column: u32, @@ -89,7 +89,7 @@ pub struct DbCache { impl DbCache { /// Create new cache. pub fn new( - db: Arc, + db: Arc>, key_lookup_column: u32, header_column: u32, cache_column: u32, @@ -113,7 +113,7 @@ impl DbCache { } /// Begin cache transaction. - pub fn transaction<'a>(&'a mut self, tx: &'a mut DBTransaction) -> DbCacheTransaction<'a, Block> { + pub fn transaction<'a>(&'a mut self, tx: &'a mut Transaction) -> DbCacheTransaction<'a, Block> { DbCacheTransaction { cache: self, tx, @@ -125,7 +125,7 @@ impl DbCache { /// Begin cache transaction with given ops. pub fn transaction_with_ops<'a>( &'a mut self, - tx: &'a mut DBTransaction, + tx: &'a mut Transaction, ops: DbCacheTransactionOps, ) -> DbCacheTransaction<'a, Block> { DbCacheTransaction { @@ -169,7 +169,7 @@ impl DbCache { fn get_cache_helper<'a, Block: BlockT>( cache_at: &'a mut HashMap, self::list_storage::DbStorage>>, name: CacheKeyId, - db: &Arc, + db: &Arc>, key_lookup: u32, header: u32, cache: u32, @@ -215,7 +215,7 @@ impl DbCacheTransactionOps { /// Database-backed blockchain data cache transaction valid for single block import. pub struct DbCacheTransaction<'a, Block: BlockT> { cache: &'a mut DbCache, - tx: &'a mut DBTransaction, + tx: &'a mut Transaction, cache_at_ops: HashMap>>, best_finalized_block: Option>, } @@ -328,7 +328,7 @@ impl BlockchainCache for DbCacheSync { let genesis_hash = cache.genesis_hash; let cache_contents = vec![(*key, data)].into_iter().collect(); let db = cache.db.clone(); - let mut dbtx = DBTransaction::new(); + let mut dbtx = Transaction::new(); let tx = cache.transaction(&mut dbtx); let tx = tx.on_block_insert( ComplexBlockId::new(Default::default(), Zero::zero()), @@ -337,7 +337,7 @@ impl BlockchainCache for DbCacheSync { EntryType::Genesis, )?; let tx_ops = tx.into_ops(); - db.write(dbtx).map_err(db_err)?; + db.commit(dbtx); cache.commit(tx_ops)?; Ok(()) } diff --git a/client/db/src/changes_tries_storage.rs b/client/db/src/changes_tries_storage.rs index a28cd604fe..5447e8b725 100644 --- a/client/db/src/changes_tries_storage.rs +++ b/client/db/src/changes_tries_storage.rs @@ -19,7 +19,6 @@ use std::collections::{HashMap, HashSet}; use std::sync::Arc; use hash_db::Prefix; -use kvdb::{KeyValueDB, DBTransaction}; use codec::{Decode, Encode}; use parking_lot::RwLock; use sp_blockchain::{Error as ClientError, Result as ClientResult}; @@ -27,12 +26,14 @@ use sp_trie::MemoryDB; use sc_client_api::backend::PrunableStateChangesTrieStorage; use sp_blockchain::{well_known_cache_keys, Cache as BlockchainCache}; use sp_core::{ChangesTrieConfiguration, ChangesTrieConfigurationRange, convert_hash}; +use sp_database::Transaction; use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, HashFor, NumberFor, One, Zero, CheckedSub, }; use sp_runtime::generic::{BlockId, DigestItem, ChangesTrieSignal}; -use sp_state_machine::{DBValue, ChangesTrieBuildCache, ChangesTrieCacheAction}; -use crate::utils::{self, Meta, meta_keys, db_err}; +use sp_state_machine::{ChangesTrieBuildCache, ChangesTrieCacheAction}; +use crate::{Database, DbHash}; +use crate::utils::{self, Meta, meta_keys}; use crate::cache::{ DbCacheSync, DbCache, DbCacheTransactionOps, ComplexBlockId, EntryType as CacheEntryType, @@ -76,7 +77,7 @@ impl From> for DbChangesTrieStorageT /// Stores all tries in separate DB column. /// Lock order: meta, tries_meta, cache, build_cache. pub struct DbChangesTrieStorage { - db: Arc, + db: Arc>, meta_column: u32, changes_tries_column: u32, key_lookup_column: u32, @@ -111,7 +112,7 @@ struct ChangesTriesMeta { impl DbChangesTrieStorage { /// Create new changes trie storage. pub fn new( - db: Arc, + db: Arc>, meta_column: u32, changes_tries_column: u32, key_lookup_column: u32, @@ -149,7 +150,7 @@ impl DbChangesTrieStorage { /// Commit new changes trie. pub fn commit( &self, - tx: &mut DBTransaction, + tx: &mut Transaction, mut changes_trie: MemoryDB>, parent_block: ComplexBlockId, block: ComplexBlockId, @@ -160,7 +161,7 @@ impl DbChangesTrieStorage { ) -> ClientResult> { // insert changes trie, associated with block, into DB for (key, (val, _)) in changes_trie.drain() { - tx.put(self.changes_tries_column, key.as_ref(), &val); + tx.set(self.changes_tries_column, key.as_ref(), &val); } // if configuration has not been changed AND block is not finalized => nothing to do here @@ -205,7 +206,7 @@ impl DbChangesTrieStorage { /// Called when block is finalized. pub fn finalize( &self, - tx: &mut DBTransaction, + tx: &mut Transaction, parent_block_hash: Block::Hash, block_hash: Block::Hash, block_num: NumberFor, @@ -254,7 +255,7 @@ impl DbChangesTrieStorage { /// When block is reverted. pub fn revert( &self, - tx: &mut DBTransaction, + tx: &mut Transaction, block: &ComplexBlockId, ) -> ClientResult> { Ok(self.cache.0.write().transaction(tx) @@ -280,7 +281,7 @@ impl DbChangesTrieStorage { /// Prune obsolete changes tries. fn prune( &self, - tx: &mut DBTransaction, + tx: &mut Transaction, block_hash: Block::Hash, block_num: NumberFor, new_header: Option<&Block::Header>, @@ -313,7 +314,7 @@ impl DbChangesTrieStorage { hash: convert_hash(&block_hash), number: block_num, }, - |node| tx.delete(self.changes_tries_column, node.as_ref()), + |node| tx.remove(self.changes_tries_column, node.as_ref()), ); next_digest_range_start = end + One::one(); @@ -486,18 +487,17 @@ where self.build_cache.read().with_changed_keys(root, functor) } - fn get(&self, key: &Block::Hash, _prefix: Prefix) -> Result, String> { - self.db.get(self.changes_tries_column, key.as_ref()) - .map_err(|err| format!("{}", err)) + fn get(&self, key: &Block::Hash, _prefix: Prefix) -> Result>, String> { + Ok(self.db.get(self.changes_tries_column, key.as_ref())) } } /// Read changes tries metadata from database. fn read_tries_meta( - db: &dyn KeyValueDB, + db: &dyn Database, meta_column: u32, ) -> ClientResult> { - match db.get(meta_column, meta_keys::CHANGES_TRIES_META).map_err(db_err)? { + match db.get(meta_column, meta_keys::CHANGES_TRIES_META) { Some(h) => match Decode::decode(&mut &h[..]) { Ok(h) => Ok(h), Err(err) => Err(ClientError::Backend(format!("Error decoding changes tries metadata: {}", err))), @@ -511,11 +511,11 @@ fn read_tries_meta( /// Write changes tries metadata from database. fn write_tries_meta( - tx: &mut DBTransaction, + tx: &mut Transaction, meta_column: u32, meta: &ChangesTriesMeta, ) { - tx.put(meta_column, meta_keys::CHANGES_TRIES_META, &meta.encode()); + tx.set_from_vec(meta_column, meta_keys::CHANGES_TRIES_META, meta.encode()); } #[cfg(test)] @@ -707,7 +707,7 @@ mod tests { let finalize_block = |number| { let header = backend.blockchain().header(BlockId::Number(number)).unwrap().unwrap(); - let mut tx = DBTransaction::new(); + let mut tx = Transaction::new(); let cache_ops = backend.changes_tries_storage.finalize( &mut tx, *header.parent_hash(), @@ -716,7 +716,7 @@ mod tests { None, None, ).unwrap(); - backend.storage.db.write(tx).unwrap(); + backend.storage.db.commit(tx); backend.changes_tries_storage.post_commit(Some(cache_ops)); }; diff --git a/client/db/src/children.rs b/client/db/src/children.rs index 2ef67de6a8..3916321f17 100644 --- a/client/db/src/children.rs +++ b/client/db/src/children.rs @@ -16,23 +16,21 @@ //! Functionality for reading and storing children hashes from db. -use kvdb::{KeyValueDB, DBTransaction}; use codec::{Encode, Decode}; use sp_blockchain; use std::hash::Hash; +use sp_database::{Database, Transaction}; +use crate::DbHash; /// Returns the hashes of the children blocks of the block with `parent_hash`. pub fn read_children< K: Eq + Hash + Clone + Encode + Decode, V: Eq + Hash + Clone + Encode + Decode, ->(db: &dyn KeyValueDB, column: u32, prefix: &[u8], parent_hash: K) -> sp_blockchain::Result> { +>(db: &dyn Database, column: u32, prefix: &[u8], parent_hash: K) -> sp_blockchain::Result> { let mut buf = prefix.to_vec(); parent_hash.using_encoded(|s| buf.extend(s)); - let raw_val_opt = match db.get(column, &buf[..]) { - Ok(raw_val_opt) => raw_val_opt, - Err(_) => return Err(sp_blockchain::Error::Backend("Error reading value from database".into())), - }; + let raw_val_opt = db.get(column, &buf[..]); let raw_val = match raw_val_opt { Some(val) => val, @@ -53,7 +51,7 @@ pub fn write_children< K: Eq + Hash + Clone + Encode + Decode, V: Eq + Hash + Clone + Encode + Decode, >( - tx: &mut DBTransaction, + tx: &mut Transaction, column: u32, prefix: &[u8], parent_hash: K, @@ -61,34 +59,35 @@ pub fn write_children< ) { let mut key = prefix.to_vec(); parent_hash.using_encoded(|s| key.extend(s)); - tx.put_vec(column, &key[..], children_hashes.encode()); + tx.set_from_vec(column, &key[..], children_hashes.encode()); } /// Prepare transaction to remove the children of `parent_hash`. pub fn remove_children< K: Eq + Hash + Clone + Encode + Decode, >( - tx: &mut DBTransaction, + tx: &mut Transaction, column: u32, prefix: &[u8], parent_hash: K, ) { let mut key = prefix.to_vec(); parent_hash.using_encoded(|s| key.extend(s)); - tx.delete(column, &key[..]); + tx.remove(column, &key); } #[cfg(test)] mod tests { use super::*; + use std::sync::Arc; #[test] fn children_write_read_remove() { const PREFIX: &[u8] = b"children"; - let db = ::kvdb_memorydb::create(1); + let db = Arc::new(sp_database::MemDb::default()); - let mut tx = DBTransaction::new(); + let mut tx = Transaction::new(); let mut children1 = Vec::new(); children1.push(1_3); @@ -100,19 +99,19 @@ mod tests { children2.push(1_6); write_children(&mut tx, 0, PREFIX, 1_2, children2); - db.write(tx.clone()).expect("(2) Committing transaction failed"); + db.commit(tx.clone()); - let r1: Vec = read_children(&db, 0, PREFIX, 1_1).expect("(1) Getting r1 failed"); - let r2: Vec = read_children(&db, 0, PREFIX, 1_2).expect("(1) Getting r2 failed"); + let r1: Vec = read_children(&*db, 0, PREFIX, 1_1).expect("(1) Getting r1 failed"); + let r2: Vec = read_children(&*db, 0, PREFIX, 1_2).expect("(1) Getting r2 failed"); assert_eq!(r1, vec![1_3, 1_5]); assert_eq!(r2, vec![1_4, 1_6]); remove_children(&mut tx, 0, PREFIX, 1_2); - db.write(tx).expect("(2) Committing transaction failed"); + db.commit(tx); - let r1: Vec = read_children(&db, 0, PREFIX, 1_1).expect("(2) Getting r1 failed"); - let r2: Vec = read_children(&db, 0, PREFIX, 1_2).expect("(2) Getting r2 failed"); + let r1: Vec = read_children(&*db, 0, PREFIX, 1_1).expect("(2) Getting r1 failed"); + let r2: Vec = read_children(&*db, 0, PREFIX, 1_2).expect("(2) Getting r2 failed"); assert_eq!(r1, vec![1_3, 1_5]); assert_eq!(r2.len(), 0); diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 70f666aebf..782e0f6db2 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Client backend that uses RocksDB database as storage. +//! Client backend that is backed by a database. //! //! # Canonicality vs. Finality //! @@ -40,9 +40,13 @@ mod storage_cache; mod upgrade; mod utils; mod stats; +#[cfg(feature = "parity-db")] +mod parity_db; +#[cfg(feature = "subdb")] +mod subdb; use std::sync::Arc; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::io; use std::collections::HashMap; @@ -57,8 +61,8 @@ use sp_blockchain::{ }; use codec::{Decode, Encode}; use hash_db::Prefix; -use kvdb::{KeyValueDB, DBTransaction}; use sp_trie::{MemoryDB, PrefixedMemoryDB, prefixed_key}; +use sp_database::Transaction; use parking_lot::RwLock; use sp_core::{ChangesTrieConfiguration, traits::CodeExecutor}; use sp_core::storage::{well_known_keys, ChildInfo}; @@ -75,7 +79,7 @@ use sp_state_machine::{ StorageCollection, ChildStorageCollection, backend::Backend as StateBackend, StateMachineStats, }; -use crate::utils::{DatabaseType, Meta, db_err, meta_keys, read_db, read_meta}; +use crate::utils::{DatabaseType, Meta, meta_keys, read_db, read_meta}; use crate::changes_tries_storage::{DbChangesTrieStorage, DbChangesTrieStorageTransaction}; use sc_client::leaves::{LeafSet, FinalizationDisplaced}; use sc_state_db::StateDb; @@ -83,15 +87,15 @@ use sp_blockchain::{CachedHeaderMetadata, HeaderMetadata, HeaderMetadataCache}; use crate::storage_cache::{CachingState, SyncingCachingState, SharedCache, new_shared_cache}; use crate::stats::StateUsageStats; use log::{trace, debug, warn}; -pub use sc_state_db::PruningMode; use prometheus_endpoint::Registry; +// Re-export the Database trait so that one can pass an implementation of it. +pub use sp_database::Database; +pub use sc_state_db::PruningMode; + #[cfg(any(feature = "kvdb-rocksdb", test))] pub use bench::BenchmarkingState; -#[cfg(feature = "test-helpers")] -use sc_client::in_mem::Backend as InMemoryBackend; - const CANONICALIZATION_DELAY: u64 = 4096; const MIN_BLOCKS_TO_KEEP_CHANGES_TRIES_FOR: u32 = 32768; @@ -103,8 +107,8 @@ pub type DbState = sp_state_machine::TrieBackend< Arc>>, HashFor >; -/// Re-export the KVDB trait so that one can pass an implementation of it. -pub use kvdb; +/// Hash type that this backend uses for the database. +pub type DbHash = [u8; 32]; /// A reference tracking state. /// @@ -279,17 +283,42 @@ pub struct DatabaseSettings { } /// Where to find the database.. +#[derive(Clone)] pub enum DatabaseSettingsSrc { - /// Load a database from a given path. Recommended for most uses. - Path { + /// Load a RocksDB database from a given path. Recommended for most uses. + RocksDb { /// Path to the database. path: PathBuf, /// Cache size in MiB. cache_size: usize, }, + /// Load a ParityDb database from a given path. + ParityDb { + /// Path to the database. + path: PathBuf, + }, + + /// Load a Subdb database from a given path. + SubDb { + /// Path to the database. + path: PathBuf, + }, + /// Use a custom already-open database. - Custom(Arc), + Custom(Arc>), +} + +impl DatabaseSettingsSrc { + /// Return dabase path for databases that are on the disk. + pub fn path(&self) -> Option<&Path> { + match self { + DatabaseSettingsSrc::RocksDb { path, .. } => Some(path.as_path()), + DatabaseSettingsSrc::ParityDb { path, .. } => Some(path.as_path()), + DatabaseSettingsSrc::SubDb { path, .. } => Some(path.as_path()), + DatabaseSettingsSrc::Custom(_) => None, + } + } } /// Create an instance of db-backed client. @@ -357,26 +386,26 @@ struct PendingBlock { } // wrapper that implements trait required for state_db -struct StateMetaDb<'a>(&'a dyn KeyValueDB); +struct StateMetaDb<'a>(&'a dyn Database); impl<'a> sc_state_db::MetaDb for StateMetaDb<'a> { type Error = io::Error; fn get_meta(&self, key: &[u8]) -> Result>, Self::Error> { - self.0.get(columns::STATE_META, key).map(|r| r.map(|v| v.to_vec())) + Ok(self.0.get(columns::STATE_META, key)) } } /// Block database pub struct BlockchainDb { - db: Arc, + db: Arc>, meta: Arc, Block::Hash>>>, leaves: RwLock>>, header_metadata_cache: HeaderMetadataCache, } impl BlockchainDb { - fn new(db: Arc) -> ClientResult { + fn new(db: Arc>) -> ClientResult { let meta = read_meta::(&*db, columns::HEADER)?; let leaves = LeafSet::read_from_db(&*db, columns::META, meta_keys::LEAF_PREFIX)?; Ok(BlockchainDb { @@ -547,11 +576,11 @@ pub struct BlockImportOperation { } impl BlockImportOperation { - fn apply_aux(&mut self, transaction: &mut DBTransaction) { + fn apply_aux(&mut self, transaction: &mut Transaction) { for (key, maybe_val) in self.aux_ops.drain(..) { match maybe_val { - Some(val) => transaction.put_vec(columns::AUX, &key, val), - None => transaction.delete(columns::AUX, &key), + Some(val) => transaction.set_from_vec(columns::AUX, &key, val), + None => transaction.remove(columns::AUX, &key), } } } @@ -676,7 +705,7 @@ impl sc_client_api::backend::BlockImportOperation for Bloc } struct StorageDb { - pub db: Arc, + pub db: Arc>, pub state_db: StateDb>, } @@ -693,7 +722,7 @@ impl sc_state_db::NodeDb for StorageDb { type Key = [u8]; fn get(&self, key: &[u8]) -> Result>, Self::Error> { - self.db.get(columns::STATE, key).map(|r| r.map(|v| v.to_vec())) + Ok(self.db.get(columns::STATE, key)) } } @@ -776,13 +805,14 @@ impl Backend { /// The pruning window is how old a block must be before the state is pruned. pub fn new(config: DatabaseSettings, canonicalization_delay: u64) -> ClientResult { let db = crate::utils::open_database::(&config, DatabaseType::Full)?; - Self::from_kvdb(db as Arc<_>, canonicalization_delay, &config) + Self::from_database(db as Arc<_>, canonicalization_delay, &config) } /// Create new memory-backed client backend for tests. #[cfg(any(test, feature = "test-helpers"))] pub fn new_test(keep_blocks: u32, canonicalization_delay: u64) -> Self { - let db = Arc::new(kvdb_memorydb::create(crate::utils::NUM_COLUMNS)); + let db = kvdb_memorydb::create(crate::utils::NUM_COLUMNS); + let db = sp_database::as_database(db); let db_setting = DatabaseSettings { state_cache_size: 16777216, state_cache_child_ratio: Some((50, 100)), @@ -793,8 +823,8 @@ impl Backend { Self::new(db_setting, canonicalization_delay).expect("failed to create test-db") } - fn from_kvdb( - db: Arc, + fn from_database( + db: Arc>, canonicalization_delay: u64, config: &DatabaseSettings, ) -> ClientResult { @@ -843,61 +873,6 @@ impl Backend { }) } - /// Returns in-memory blockchain that contains the same set of blocks as self. - #[cfg(feature = "test-helpers")] - pub fn as_in_memory(&self) -> InMemoryBackend { - use sc_client_api::backend::{Backend as ClientBackend, BlockImportOperation}; - use sc_client::blockchain::Backend as BlockchainBackend; - - let inmem = InMemoryBackend::::new(); - - // get all headers hashes && sort them by number (could be duplicate) - let mut headers: Vec<(NumberFor, Block::Hash, Block::Header)> = Vec::new(); - for (_, header) in self.blockchain.db.iter(columns::HEADER) { - let header = Block::Header::decode(&mut &header[..]).unwrap(); - let hash = header.hash(); - let number = *header.number(); - let pos = headers.binary_search_by(|item| item.0.cmp(&number)); - match pos { - Ok(pos) => headers.insert(pos, (number, hash, header)), - Err(pos) => headers.insert(pos, (number, hash, header)), - } - } - - // insert all other headers + bodies + justifications - let info = self.blockchain.info(); - for (number, hash, header) in headers { - let id = BlockId::Hash(hash); - let justification = self.blockchain.justification(id).unwrap(); - let body = self.blockchain.body(id).unwrap(); - let state = self.state_at(id).unwrap().pairs(); - - let new_block_state = if number.is_zero() { - NewBlockState::Final - } else if hash == info.best_hash { - NewBlockState::Best - } else { - NewBlockState::Normal - }; - let mut op = inmem.begin_operation().unwrap(); - op.set_block_data(header, body, justification, new_block_state).unwrap(); - op.update_db_storage(vec![(None, state.into_iter().map(|(k, v)| (k, Some(v))).collect())]) - .unwrap(); - inmem.commit_operation(op).unwrap(); - } - - // and now finalize the best block we have - inmem.finalize_block(BlockId::Hash(info.finalized_hash), None).unwrap(); - - inmem - } - - /// Returns total number of blocks (headers) in the block DB. - #[cfg(feature = "test-helpers")] - pub fn blocks_count(&self) -> u64 { - self.blockchain.db.iter(columns::HEADER).count() as u64 - } - /// Handle setting head within a transaction. `route_to` should be the last /// block that existed in the database. `best_to` should be the best block /// to be set. @@ -907,7 +882,7 @@ impl Backend { /// to be best, `route_to` should equal to `best_to`. fn set_head_with_transaction( &self, - transaction: &mut DBTransaction, + transaction: &mut Transaction, route_to: Block::Hash, best_to: (NumberFor, Block::Hash), ) -> ClientResult<(Vec, Vec)> { @@ -957,7 +932,7 @@ impl Backend { } let lookup_key = utils::number_and_hash_to_lookup_key(best_to.0, &best_to.1)?; - transaction.put(columns::META, meta_keys::BEST_BLOCK, &lookup_key); + transaction.set_from_vec(columns::META, meta_keys::BEST_BLOCK, lookup_key); utils::insert_number_to_key_mapping( transaction, columns::KEY_LOOKUP, @@ -984,7 +959,7 @@ impl Backend { fn finalize_block_with_transaction( &self, - transaction: &mut DBTransaction, + transaction: &mut Transaction, hash: &Block::Hash, header: &Block::Header, last_finalized: Option, @@ -1005,10 +980,10 @@ impl Backend { )?; if let Some(justification) = justification { - transaction.put( + transaction.set_from_vec( columns::JUSTIFICATION, &utils::number_and_hash_to_lookup_key(number, hash)?, - &justification.encode(), + justification.encode(), ); } Ok((*hash, number, false, true)) @@ -1017,7 +992,7 @@ impl Backend { // performs forced canonicalization with a delay after importing a non-finalized block. fn force_delayed_canonicalize( &self, - transaction: &mut DBTransaction, + transaction: &mut Transaction, hash: Block::Hash, number: NumberFor, ) @@ -1051,7 +1026,7 @@ impl Backend { fn try_commit_operation(&self, mut operation: BlockImportOperation) -> ClientResult<()> { - let mut transaction = DBTransaction::new(); + let mut transaction = Transaction::new(); let mut finalization_displaced_leaves = None; operation.apply_aux(&mut transaction); @@ -1103,17 +1078,17 @@ impl Backend { header_metadata, ); - transaction.put(columns::HEADER, &lookup_key, &pending_block.header.encode()); + transaction.set_from_vec(columns::HEADER, &lookup_key, pending_block.header.encode()); if let Some(body) = &pending_block.body { - transaction.put(columns::BODY, &lookup_key, &body.encode()); + transaction.set_from_vec(columns::BODY, &lookup_key, body.encode()); } if let Some(justification) = pending_block.justification { - transaction.put(columns::JUSTIFICATION, &lookup_key, &justification.encode()); + transaction.set_from_vec(columns::JUSTIFICATION, &lookup_key, justification.encode()); } if number.is_zero() { - transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &lookup_key); - transaction.put(columns::META, meta_keys::GENESIS_HASH, hash.as_ref()); + transaction.set_from_vec(columns::META, meta_keys::FINALIZED_BLOCK, lookup_key); + transaction.set(columns::META, meta_keys::GENESIS_HASH, hash.as_ref()); // for tests, because config is set from within the reset_storage if operation.changes_trie_config_update.is_none() { @@ -1260,31 +1235,17 @@ impl Backend { None }; - let write_result = self.storage.db.write(transaction).map_err(db_err); + self.storage.db.commit(transaction); if let Some(( number, hash, enacted, retracted, - displaced_leaf, + _displaced_leaf, is_best, mut cache, )) = imported { - if let Err(e) = write_result { - let mut leaves = self.blockchain.leaves.write(); - let mut undo = leaves.undo(); - if let Some(displaced_leaf) = displaced_leaf { - undo.undo_import(displaced_leaf); - } - - if let Some(finalization_displaced) = finalization_displaced_leaves { - undo.undo_finalization(finalization_displaced); - } - - return Err(e) - } - cache.sync_cache( &enacted, &retracted, @@ -1317,7 +1278,7 @@ impl Backend { // was not a child of the last finalized block. fn note_finalized( &self, - transaction: &mut DBTransaction, + transaction: &mut Transaction, is_inserted: bool, f_header: &Block::Header, f_hash: Block::Hash, @@ -1328,7 +1289,7 @@ impl Backend { if self.storage.state_db.best_canonical().map(|c| f_num.saturated_into::() > c).unwrap_or(true) { let lookup_key = utils::number_and_hash_to_lookup_key(f_num, f_hash.clone())?; - transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &lookup_key); + transaction.set_from_vec(columns::META, meta_keys::FINALIZED_BLOCK, lookup_key); let commit = self.storage.state_db.canonicalize_block(&f_hash) .map_err(|e: sc_state_db::Error| sp_blockchain::Error::from(format!("State database error: {:?}", e)))?; @@ -1357,18 +1318,18 @@ impl Backend { } } -fn apply_state_commit(transaction: &mut DBTransaction, commit: sc_state_db::CommitSet>) { +fn apply_state_commit(transaction: &mut Transaction, commit: sc_state_db::CommitSet>) { for (key, val) in commit.data.inserted.into_iter() { - transaction.put(columns::STATE, &key[..], &val); + transaction.set_from_vec(columns::STATE, &key[..], val); } for key in commit.data.deleted.into_iter() { - transaction.delete(columns::STATE, &key[..]); + transaction.remove(columns::STATE, &key[..]); } for (key, val) in commit.meta.inserted.into_iter() { - transaction.put(columns::STATE_META, &key[..], &val); + transaction.set_from_vec(columns::STATE_META, &key[..], val); } for key in commit.meta.deleted.into_iter() { - transaction.delete(columns::STATE_META, &key[..]); + transaction.remove(columns::STATE_META, &key[..]); } } @@ -1380,19 +1341,19 @@ impl sc_client_api::backend::AuxStore for Backend where Block: Blo I: IntoIterator, D: IntoIterator, >(&self, insert: I, delete: D) -> ClientResult<()> { - let mut transaction = DBTransaction::new(); + let mut transaction = Transaction::new(); for (k, v) in insert { - transaction.put(columns::AUX, k, v); + transaction.set(columns::AUX, k, v); } for k in delete { - transaction.delete(columns::AUX, k); + transaction.remove(columns::AUX, k); } - self.storage.db.write(transaction).map_err(db_err)?; + self.storage.db.commit(transaction); Ok(()) } fn get_aux(&self, key: &[u8]) -> ClientResult>> { - Ok(self.storage.db.get(columns::AUX, key).map(|r| r.map(|v| v.to_vec())).map_err(db_err)?) + Ok(self.storage.db.get(columns::AUX, key)) } } @@ -1453,36 +1414,24 @@ impl sc_client_api::backend::Backend for Backend { fn finalize_block(&self, block: BlockId, justification: Option) -> ClientResult<()> { - let mut transaction = DBTransaction::new(); + let mut transaction = Transaction::new(); let hash = self.blockchain.expect_block_hash_from_id(&block)?; let header = self.blockchain.expect_header(block)?; let mut displaced = None; - let commit = |displaced| { - let mut changes_trie_cache_ops = None; - let (hash, number, is_best, is_finalized) = self.finalize_block_with_transaction( - &mut transaction, - &hash, - &header, - None, - justification, - &mut changes_trie_cache_ops, - displaced, - )?; - self.storage.db.write(transaction).map_err(db_err)?; - self.blockchain.update_meta(hash, number, is_best, is_finalized); - self.changes_tries_storage.post_commit(changes_trie_cache_ops); - Ok(()) - }; - match commit(&mut displaced) { - Ok(()) => self.storage.state_db.apply_pending(), - e @ Err(_) => { - self.storage.state_db.revert_pending(); - if let Some(displaced) = displaced { - self.blockchain.leaves.write().undo().undo_finalization(displaced); - } - return e; - } - } + + let mut changes_trie_cache_ops = None; + let (hash, number, is_best, is_finalized) = self.finalize_block_with_transaction( + &mut transaction, + &hash, + &header, + None, + justification, + &mut changes_trie_cache_ops, + &mut displaced, + )?; + self.storage.db.commit(transaction); + self.blockchain.update_meta(hash, number, is_best, is_finalized); + self.changes_tries_storage.post_commit(changes_trie_cache_ops); Ok(()) } @@ -1497,11 +1446,12 @@ impl sc_client_api::backend::Backend for Backend { fn usage_info(&self) -> Option { let (io_stats, state_stats) = self.io_stats.take_or_else(|| ( - self.storage.db.io_stats(kvdb::IoStatsKind::SincePrevious), + // TODO: implement DB stats and cache size retrieval + kvdb::IoStats::empty(), self.state_usage.take(), ) ); - let database_cache = MemorySize::from_bytes(parity_util_mem::malloc_size(&*self.storage.db)); + let database_cache = MemorySize::from_bytes(0); let state_cache = MemorySize::from_bytes( (*&self.shared_cache).lock().used_storage_cache_size(), ); @@ -1547,7 +1497,7 @@ impl sc_client_api::backend::Backend for Backend { if best_number.is_zero() { return Ok(c.saturated_into::>()) } - let mut transaction = DBTransaction::new(); + let mut transaction = Transaction::new(); match self.storage.state_db.revert_one() { Some(commit) => { apply_state_commit(&mut transaction, commit); @@ -1571,13 +1521,13 @@ impl sc_client_api::backend::Backend for Backend { removed_number, ), )?; - transaction.put(columns::META, meta_keys::BEST_BLOCK, &key); if update_finalized { - transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &key); + transaction.set_from_vec(columns::META, meta_keys::FINALIZED_BLOCK, key.clone()); } - transaction.delete(columns::KEY_LOOKUP, removed.hash().as_ref()); + transaction.set_from_vec(columns::META, meta_keys::BEST_BLOCK, key); + transaction.remove(columns::KEY_LOOKUP, removed.hash().as_ref()); children::remove_children(&mut transaction, columns::META, meta_keys::CHILDREN_PREFIX, best_hash); - self.storage.db.write(transaction).map_err(db_err)?; + self.storage.db.commit(transaction); self.changes_tries_storage.post_commit(Some(changes_trie_cache_ops)); self.blockchain.update_meta(best_hash, best_number, true, update_finalized); } @@ -1591,12 +1541,12 @@ impl sc_client_api::backend::Backend for Backend { let reverted = revert_blocks()?; let revert_leaves = || -> ClientResult<()> { - let mut transaction = DBTransaction::new(); + let mut transaction = Transaction::new(); let mut leaves = self.blockchain.leaves.write(); leaves.revert(best_hash, best_number); leaves.prepare_transaction(&mut transaction, columns::META, meta_keys::LEAF_PREFIX); - self.storage.db.write(transaction).map_err(db_err)?; + self.storage.db.commit(transaction); Ok(()) }; @@ -1959,7 +1909,7 @@ pub(crate) mod tests { assert_eq!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key, EMPTY_PREFIX) - ).unwrap().unwrap(), &b"hello"[..]); + ).unwrap(), &b"hello"[..]); hash }; @@ -1996,7 +1946,7 @@ pub(crate) mod tests { assert_eq!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key, EMPTY_PREFIX) - ).unwrap().unwrap(), &b"hello"[..]); + ).unwrap(), &b"hello"[..]); hash }; @@ -2034,7 +1984,7 @@ pub(crate) mod tests { assert!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key, EMPTY_PREFIX) - ).unwrap().is_some()); + ).is_some()); hash }; @@ -2068,7 +2018,7 @@ pub(crate) mod tests { assert!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key, EMPTY_PREFIX) - ).unwrap().is_none()); + ).is_none()); } backend.finalize_block(BlockId::Number(1), None).unwrap(); @@ -2077,7 +2027,7 @@ pub(crate) mod tests { assert!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key, EMPTY_PREFIX) - ).unwrap().is_none()); + ).is_none()); } #[test] diff --git a/client/db/src/light.rs b/client/db/src/light.rs index e3dcdedd50..c87388a954 100644 --- a/client/db/src/light.rs +++ b/client/db/src/light.rs @@ -20,8 +20,6 @@ use std::{sync::Arc, collections::HashMap}; use std::convert::TryInto; use parking_lot::RwLock; -use kvdb::{KeyValueDB, DBTransaction}; - use sc_client_api::{backend::{AuxStore, NewBlockState}, UsageInfo}; use sc_client::blockchain::{ BlockStatus, Cache as BlockchainCache,Info as BlockchainInfo, @@ -33,13 +31,14 @@ use sp_blockchain::{ HeaderBackend as BlockchainHeaderBackend, well_known_cache_keys, }; +use sp_database::{Database, Transaction}; use sc_client::light::blockchain::Storage as LightBlockchainStorage; use codec::{Decode, Encode}; use sp_runtime::generic::{DigestItem, BlockId}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Zero, One, NumberFor, HashFor}; use crate::cache::{DbCacheSync, DbCache, ComplexBlockId, EntryType as CacheEntryType}; -use crate::utils::{self, meta_keys, DatabaseType, Meta, db_err, read_db, block_id_to_lookup_key, read_meta}; -use crate::{DatabaseSettings, FrozenForDuration}; +use crate::utils::{self, meta_keys, DatabaseType, Meta, read_db, block_id_to_lookup_key, read_meta}; +use crate::{DatabaseSettings, FrozenForDuration, DbHash}; use log::{trace, warn, debug}; pub(crate) mod columns { @@ -59,7 +58,7 @@ const CHANGES_TRIE_CHT_PREFIX: u8 = 1; /// Light blockchain storage. Stores most recent headers + CHTs for older headers. /// Locks order: meta, cache. pub struct LightStorage { - db: Arc, + db: Arc>, meta: RwLock, Block::Hash>>, cache: Arc>, header_metadata_cache: HeaderMetadataCache, @@ -78,14 +77,11 @@ impl LightStorage { /// Create new memory-backed `LightStorage` for tests. #[cfg(any(test, feature = "test-helpers"))] pub fn new_test() -> Self { - use utils::NUM_COLUMNS; - - let db = Arc::new(::kvdb_memorydb::create(NUM_COLUMNS)); - + let db = Arc::new(sp_database::MemDb::default()); Self::from_kvdb(db as Arc<_>).expect("failed to create test-db") } - fn from_kvdb(db: Arc) -> ClientResult { + fn from_kvdb(db: Arc>) -> ClientResult { let meta = read_meta::(&*db, columns::HEADER)?; let cache = DbCache::new( db.clone(), @@ -230,7 +226,7 @@ impl LightStorage { /// to be best, `route_to` should equal to `best_to`. fn set_head_with_transaction( &self, - transaction: &mut DBTransaction, + transaction: &mut Transaction, route_to: Block::Hash, best_to: (NumberFor, Block::Hash), ) -> ClientResult<()> { @@ -266,7 +262,7 @@ impl LightStorage { } } - transaction.put(columns::META, meta_keys::BEST_BLOCK, &lookup_key); + transaction.set_from_vec(columns::META, meta_keys::BEST_BLOCK, lookup_key); utils::insert_number_to_key_mapping( transaction, columns::KEY_LOOKUP, @@ -280,7 +276,7 @@ impl LightStorage { // Note that a block is finalized. Only call with child of last finalized block. fn note_finalized( &self, - transaction: &mut DBTransaction, + transaction: &mut Transaction, header: &Block::Header, hash: Block::Hash, ) -> ClientResult<()> { @@ -293,7 +289,7 @@ impl LightStorage { } let lookup_key = utils::number_and_hash_to_lookup_key(header.number().clone(), hash)?; - transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &lookup_key); + transaction.set_from_vec(columns::META, meta_keys::FINALIZED_BLOCK, lookup_key); // build new CHT(s) if required if let Some(new_cht_number) = cht::is_build_required(cht::size(), *header.number()) { @@ -309,7 +305,7 @@ impl LightStorage { let new_header_cht_root = cht::compute_root::, _>( cht::size(), new_cht_number, cht_range.map(|num| self.hash(num)) )?; - transaction.put( + transaction.set( columns::CHT, &cht_key(HEADER_CHT_PREFIX, new_cht_start)?, new_header_cht_root.as_ref() @@ -327,7 +323,7 @@ impl LightStorage { cht::size(), new_cht_number, cht_range .map(|num| self.changes_trie_root(BlockId::Number(num))) )?; - transaction.put( + transaction.set( columns::CHT, &cht_key(CHANGES_TRIE_CHT_PREFIX, new_cht_start)?, new_changes_trie_cht_root.as_ref() @@ -350,7 +346,7 @@ impl LightStorage { prune_block, hash )?; - transaction.delete(columns::HEADER, &lookup_key); + transaction.remove(columns::HEADER, &lookup_key); } prune_block += One::one(); } @@ -377,7 +373,7 @@ impl LightStorage { } let cht_start = cht::start_number(cht_size, cht_number); - self.db.get(columns::CHT, &cht_key(cht_type, cht_start)?).map_err(db_err)? + self.db.get(columns::CHT, &cht_key(cht_type, cht_start)?) .ok_or_else(no_cht_for_block) .and_then(|hash| Block::Hash::decode(&mut &*hash).map_err(|_| no_cht_for_block())) .map(Some) @@ -394,18 +390,19 @@ impl AuxStore for LightStorage I: IntoIterator, D: IntoIterator, >(&self, insert: I, delete: D) -> ClientResult<()> { - let mut transaction = DBTransaction::new(); + let mut transaction = Transaction::new(); for (k, v) in insert { - transaction.put(columns::AUX, k, v); + transaction.set(columns::AUX, k, v); } for k in delete { - transaction.delete(columns::AUX, k); + transaction.remove(columns::AUX, k); } - self.db.write(transaction).map_err(db_err) + self.db.commit(transaction); + Ok(()) } fn get_aux(&self, key: &[u8]) -> ClientResult>> { - self.db.get(columns::AUX, key).map(|r| r.map(|v| v.to_vec())).map_err(db_err) + Ok(self.db.get(columns::AUX, key)) } } @@ -419,7 +416,7 @@ impl LightBlockchainStorage for LightStorage leaf_state: NewBlockState, aux_ops: Vec<(Vec, Option>)>, ) -> ClientResult<()> { - let mut transaction = DBTransaction::new(); + let mut transaction = Transaction::new(); let hash = header.hash(); let number = *header.number(); @@ -427,8 +424,8 @@ impl LightBlockchainStorage for LightStorage for (key, maybe_val) in aux_ops { match maybe_val { - Some(val) => transaction.put_vec(columns::AUX, &key, val), - None => transaction.delete(columns::AUX, &key), + Some(val) => transaction.set_from_vec(columns::AUX, &key, val), + None => transaction.remove(columns::AUX, &key), } } @@ -445,7 +442,7 @@ impl LightBlockchainStorage for LightStorage number, hash, )?; - transaction.put(columns::HEADER, &lookup_key, &header.encode()); + transaction.set_from_vec(columns::HEADER, &lookup_key, header.encode()); let header_metadata = CachedHeaderMetadata::from(&header); self.header_metadata_cache.insert_header_metadata( @@ -456,7 +453,7 @@ impl LightBlockchainStorage for LightStorage let is_genesis = number.is_zero(); if is_genesis { self.cache.0.write().set_genesis_hash(hash); - transaction.put(columns::META, meta_keys::GENESIS_HASH, hash.as_ref()); + transaction.set(columns::META, meta_keys::GENESIS_HASH, hash.as_ref()); } let finalized = match leaf_state { @@ -493,7 +490,7 @@ impl LightBlockchainStorage for LightStorage debug!("Light DB Commit {:?} ({})", hash, number); - self.db.write(transaction).map_err(db_err)?; + self.db.commit(transaction); cache.commit(cache_ops) .expect("only fails if cache with given name isn't loaded yet;\ cache is already loaded because there are cache_ops; qed"); @@ -509,9 +506,9 @@ impl LightBlockchainStorage for LightStorage let hash = header.hash(); let number = header.number(); - let mut transaction = DBTransaction::new(); + let mut transaction = Transaction::new(); self.set_head_with_transaction(&mut transaction, hash.clone(), (number.clone(), hash.clone()))?; - self.db.write(transaction).map_err(db_err)?; + self.db.commit(transaction); self.update_meta(hash, header.number().clone(), true, false); Ok(()) } else { @@ -537,7 +534,7 @@ impl LightBlockchainStorage for LightStorage fn finalize_header(&self, id: BlockId) -> ClientResult<()> { if let Some(header) = self.header(id)? { - let mut transaction = DBTransaction::new(); + let mut transaction = Transaction::new(); let hash = header.hash(); let number = *header.number(); self.note_finalized(&mut transaction, &header, hash.clone())?; @@ -550,7 +547,7 @@ impl LightBlockchainStorage for LightStorage )? .into_ops(); - self.db.write(transaction).map_err(db_err)?; + self.db.commit(transaction); cache.commit(cache_ops) .expect("only fails if cache with given name isn't loaded yet;\ cache is already loaded because there are cache_ops; qed"); @@ -575,8 +572,9 @@ impl LightBlockchainStorage for LightStorage fn usage_info(&self) -> Option { use sc_client_api::{MemoryInfo, IoInfo, MemorySize}; - let database_cache = MemorySize::from_bytes(parity_util_mem::malloc_size(&*self.db)); - let io_stats = self.io_stats.take_or_else(|| self.db.io_stats(kvdb::IoStatsKind::SincePrevious)); + // TODO: reimplement IO stats + let database_cache = MemorySize::from_bytes(0); + let io_stats = self.io_stats.take_or_else(|| kvdb::IoStats::empty()); Some(UsageInfo { memory: MemoryInfo { @@ -732,21 +730,25 @@ pub(crate) mod tests { #[test] fn import_header_works() { - let db = LightStorage::new_test(); + let raw_db = Arc::new(sp_database::MemDb::default()); + let db = LightStorage::from_kvdb(raw_db.clone()).unwrap(); let genesis_hash = insert_block(&db, HashMap::new(), || default_header(&Default::default(), 0)); - assert_eq!(db.db.iter(columns::HEADER).count(), 1); - assert_eq!(db.db.iter(columns::KEY_LOOKUP).count(), 2); + assert_eq!(raw_db.count(columns::HEADER), 1); + assert_eq!(raw_db.count(columns::KEY_LOOKUP), 2); let _ = insert_block(&db, HashMap::new(), || default_header(&genesis_hash, 1)); - assert_eq!(db.db.iter(columns::HEADER).count(), 2); - assert_eq!(db.db.iter(columns::KEY_LOOKUP).count(), 4); + assert_eq!(raw_db.count(columns::HEADER), 2); + assert_eq!(raw_db.count(columns::KEY_LOOKUP), 4); } #[test] fn finalized_ancient_headers_are_replaced_with_cht() { - fn insert_headers Header>(header_producer: F) -> LightStorage { - let db = LightStorage::new_test(); + fn insert_headers Header>(header_producer: F) -> + (Arc>, LightStorage) + { + let raw_db = Arc::new(sp_database::MemDb::default()); + let db = LightStorage::from_kvdb(raw_db.clone()).unwrap(); let cht_size: u64 = cht::size(); let ucht_size: usize = cht_size as _; @@ -758,8 +760,8 @@ pub(crate) mod tests { for number in 0..cht::size() { prev_hash = insert_block(&db, HashMap::new(), || header_producer(&prev_hash, 1 + number)); } - assert_eq!(db.db.iter(columns::HEADER).count(), 1 + ucht_size); - assert_eq!(db.db.iter(columns::CHT).count(), 0); + assert_eq!(raw_db.count(columns::HEADER), 1 + ucht_size); + assert_eq!(raw_db.count(columns::CHT), 0); // insert next SIZE blocks && ensure that nothing is pruned for number in 0..(cht_size as _) { @@ -769,8 +771,8 @@ pub(crate) mod tests { || header_producer(&prev_hash, 1 + cht_size + number), ); } - assert_eq!(db.db.iter(columns::HEADER).count(), 1 + ucht_size + ucht_size); - assert_eq!(db.db.iter(columns::CHT).count(), 0); + assert_eq!(raw_db.count(columns::HEADER), 1 + ucht_size + ucht_size); + assert_eq!(raw_db.count(columns::CHT), 0); // insert block #{2 * cht::size() + 1} && check that new CHT is created + headers of this CHT are pruned // nothing is yet finalized, so nothing is pruned. @@ -779,23 +781,23 @@ pub(crate) mod tests { HashMap::new(), || header_producer(&prev_hash, 1 + cht_size + cht_size), ); - assert_eq!(db.db.iter(columns::HEADER).count(), 2 + ucht_size + ucht_size); - assert_eq!(db.db.iter(columns::CHT).count(), 0); + assert_eq!(raw_db.count(columns::HEADER), 2 + ucht_size + ucht_size); + assert_eq!(raw_db.count(columns::CHT), 0); // now finalize the block. for i in (0..(ucht_size + ucht_size)).map(|i| i + 1) { db.finalize_header(BlockId::Number(i as _)).unwrap(); } db.finalize_header(BlockId::Hash(prev_hash)).unwrap(); - db + (raw_db, db) } // when headers are created without changes tries roots - let db = insert_headers(default_header); + let (raw_db, db) = insert_headers(default_header); let cht_size: u64 = cht::size(); - assert_eq!(db.db.iter(columns::HEADER).count(), (1 + cht_size + 1) as usize); - assert_eq!(db.db.iter(columns::KEY_LOOKUP).count(), (2 * (1 + cht_size + 1)) as usize); - assert_eq!(db.db.iter(columns::CHT).count(), 1); + assert_eq!(raw_db.count(columns::HEADER), (1 + cht_size + 1) as usize); + assert_eq!(raw_db.count(columns::KEY_LOOKUP), (2 * (1 + cht_size + 1)) as usize); + assert_eq!(raw_db.count(columns::CHT), 1); assert!((0..cht_size as _).all(|i| db.header(BlockId::Number(1 + i)).unwrap().is_none())); assert!(db.header_cht_root(cht_size, cht_size / 2).unwrap().is_some()); assert!(db.header_cht_root(cht_size, cht_size + cht_size / 2).unwrap().is_none()); @@ -803,9 +805,9 @@ pub(crate) mod tests { assert!(db.changes_trie_cht_root(cht_size, cht_size + cht_size / 2).unwrap().is_none()); // when headers are created with changes tries roots - let db = insert_headers(header_with_changes_trie); - assert_eq!(db.db.iter(columns::HEADER).count(), (1 + cht_size + 1) as usize); - assert_eq!(db.db.iter(columns::CHT).count(), 2); + let (raw_db, db) = insert_headers(header_with_changes_trie); + assert_eq!(raw_db.count(columns::HEADER), (1 + cht_size + 1) as usize); + assert_eq!(raw_db.count(columns::CHT), 2); assert!((0..cht_size as _).all(|i| db.header(BlockId::Number(1 + i)).unwrap().is_none())); assert!(db.header_cht_root(cht_size, cht_size / 2).unwrap().is_some()); assert!(db.header_cht_root(cht_size, cht_size + cht_size / 2).unwrap().is_none()); diff --git a/client/db/src/offchain.rs b/client/db/src/offchain.rs index 3d0f8c6795..8c58d5f42c 100644 --- a/client/db/src/offchain.rs +++ b/client/db/src/offchain.rs @@ -21,14 +21,13 @@ use std::{ sync::Arc, }; -use crate::columns; -use kvdb::KeyValueDB; +use crate::{columns, Database, DbHash, Transaction}; use parking_lot::Mutex; /// Offchain local storage #[derive(Clone)] pub struct LocalStorage { - db: Arc, + db: Arc>, locks: Arc, Arc>>>>, } @@ -43,12 +42,13 @@ impl LocalStorage { /// Create new offchain storage for tests (backed by memorydb) #[cfg(any(test, feature = "test-helpers"))] pub fn new_test() -> Self { - let db = Arc::new(kvdb_memorydb::create(crate::utils::NUM_COLUMNS)); + let db = kvdb_memorydb::create(crate::utils::NUM_COLUMNS); + let db = sp_database::as_database(db); Self::new(db as _) } /// Create offchain local storage with given `KeyValueDB` backend. - pub fn new(db: Arc) -> Self { + pub fn new(db: Arc>) -> Self { Self { db, locks: Default::default(), @@ -59,20 +59,15 @@ impl LocalStorage { impl sp_core::offchain::OffchainStorage for LocalStorage { fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]) { let key: Vec = prefix.iter().chain(key).cloned().collect(); - let mut tx = self.db.transaction(); - tx.put(columns::OFFCHAIN, &key, value); + let mut tx = Transaction::new(); + tx.set(columns::OFFCHAIN, &key, value); - if let Err(e) = self.db.write(tx) { - log::warn!("Error writing to the offchain DB: {:?}", e); - } + self.db.commit(tx); } fn get(&self, prefix: &[u8], key: &[u8]) -> Option> { let key: Vec = prefix.iter().chain(key).cloned().collect(); self.db.get(columns::OFFCHAIN, &key) - .ok() - .and_then(|x| x) - .map(|v| v.to_vec()) } fn compare_and_set( @@ -91,9 +86,7 @@ impl sp_core::offchain::OffchainStorage for LocalStorage { let is_set; { let _key_guard = key_lock.lock(); - let val = self.db.get(columns::OFFCHAIN, &key) - .ok() - .and_then(|x| x); + let val = self.db.get(columns::OFFCHAIN, &key); is_set = val.as_ref().map(|x| &**x) == old_value; if is_set { diff --git a/client/db/src/parity_db.rs b/client/db/src/parity_db.rs new file mode 100644 index 0000000000..a4e64d310b --- /dev/null +++ b/client/db/src/parity_db.rs @@ -0,0 +1,56 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +/// A `Database` adapter for parity-db. + +use sp_database::{Database, Change, Transaction, ColumnId}; + +struct DbAdapter(parity_db::Db); + +fn handle_err(result: parity_db::Result) -> T { + match result { + Ok(r) => r, + Err(e) => { + panic!("Critical database eror: {:?}", e); + } + } +} + +/// Wrap RocksDb database into a trait object that implements `sp_database::Database` +pub fn open(path: &std::path::Path, num_columns: u32) -> parity_db::Result>> { + let db = parity_db::Db::with_columns(path, num_columns as u8)?; + Ok(std::sync::Arc::new(DbAdapter(db))) +} + +impl Database for DbAdapter { + fn commit(&self, transaction: Transaction) { + handle_err(self.0.commit(transaction.0.into_iter().map(|change| + match change { + Change::Set(col, key, value) => (col as u8, key, Some(value)), + Change::Remove(col, key) => (col as u8, key, None), + _ => unimplemented!(), + })) + ); + } + + fn get(&self, col: ColumnId, key: &[u8]) -> Option> { + handle_err(self.0.get(col as u8, key)) + } + + fn lookup(&self, _hash: &H) -> Option> { + unimplemented!(); + } +} diff --git a/client/db/src/subdb.rs b/client/db/src/subdb.rs new file mode 100644 index 0000000000..2e436aa2c9 --- /dev/null +++ b/client/db/src/subdb.rs @@ -0,0 +1,87 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +/// A `Database` adapter for subdb. + +use sp_database::{self, ColumnId}; +use parking_lot::RwLock; +use blake2_rfc::blake2b::blake2b; +use codec::Encode; +use subdb::{Database, KeyType}; + +/// A database hidden behind an RwLock, so that it implements Send + Sync. +/// +/// Construct by creating a `Database` and then using `.into()`. +pub struct DbAdapter(RwLock>); + +/// Wrap RocksDb database into a trait object that implements `sp_database::Database` +pub fn open( + path: &std::path::Path, + _num_columns: u32, +) -> Result>, subdb::Error> { + let db = subdb::Options::from_path(path.into()).open()?; + Ok(std::sync::Arc::new(DbAdapter(RwLock::new(db)))) +} + +impl sp_database::Database for DbAdapter { + fn get(&self, col: ColumnId, key: &[u8]) -> Option> { + let mut hash = H::default(); + (col, key).using_encoded(|d| + hash.as_mut().copy_from_slice(blake2b(32, &[], d).as_bytes()) + ); + self.0.read().get(&hash) + } + + fn with_get(&self, col: ColumnId, key: &[u8], f: &mut dyn FnMut(&[u8])) { + let mut hash = H::default(); + (col, key).using_encoded(|d| + hash.as_mut().copy_from_slice(blake2b(32, &[], d).as_bytes()) + ); + let _ = self.0.read().get_ref(&hash).map(|d| f(d.as_ref())); + } + + fn set(&self, col: ColumnId, key: &[u8], value: &[u8]) { + let mut hash = H::default(); + (col, key).using_encoded(|d| + hash.as_mut().copy_from_slice(blake2b(32, &[], d).as_bytes()) + ); + self.0.write().insert(&value, &hash); + } + + fn remove(&self, col: ColumnId, key: &[u8]) { + let mut hash = H::default(); + (col, key).using_encoded(|d| + hash.as_mut().copy_from_slice(blake2b(32, &[], d).as_bytes()) + ); + let _ = self.0.write().remove(&hash); + } + + fn lookup(&self, hash: &H) -> Option> { + self.0.read().get(hash) + } + + fn with_lookup(&self, hash: &H, f: &mut dyn FnMut(&[u8])) { + let _ = self.0.read().get_ref(hash).map(|d| f(d.as_ref())); + } + + fn store(&self, hash: &H, preimage: &[u8]) { + self.0.write().insert(preimage, hash); + } + + fn release(&self, hash: &H) { + let _ = self.0.write().remove(hash); + } +} diff --git a/client/db/src/upgrade.rs b/client/db/src/upgrade.rs index 5e6794108e..95592d071f 100644 --- a/client/db/src/upgrade.rs +++ b/client/db/src/upgrade.rs @@ -19,18 +19,9 @@ use std::fs; use std::io::{Read, Write, ErrorKind}; use std::path::{Path, PathBuf}; -use std::sync::Arc; -use codec::Encode; -use kvdb_rocksdb::{Database, DatabaseConfig}; -use parking_lot::RwLock; -use sp_blockchain::{well_known_cache_keys, Cache}; -use sp_core::ChangesTrieConfiguration; use sp_runtime::traits::Block as BlockT; -use crate::{ - cache::{ComplexBlockId, DbCache, DbCacheSync}, - utils::{DatabaseType, check_database_type, db_err, read_genesis_hash}, -}; +use crate::utils::DatabaseType; /// Version file name. const VERSION_FILE_NAME: &'static str = "db_version"; @@ -38,69 +29,21 @@ const VERSION_FILE_NAME: &'static str = "db_version"; /// Current db version. const CURRENT_VERSION: u32 = 1; -/// Number of columns in v0. -const V0_NUM_COLUMNS: u32 = 10; - /// Upgrade database to current version. -pub fn upgrade_db(db_path: &Path, db_type: DatabaseType) -> sp_blockchain::Result<()> { - let db_version = current_version(db_path)?; - match db_version { - 0 => migrate_0_to_1::(db_path, db_type)?, - 1 => (), - _ => Err(sp_blockchain::Error::Backend(format!("Future database version: {}", db_version)))?, +pub fn upgrade_db(db_path: &Path, _db_type: DatabaseType) -> sp_blockchain::Result<()> { + let is_empty = db_path.read_dir().map_or(true, |mut d| d.next().is_none()); + if !is_empty { + let db_version = current_version(db_path)?; + match db_version { + 0 => Err(sp_blockchain::Error::Backend(format!("Unsupported database version: {}", db_version)))?, + 1 => (), + _ => Err(sp_blockchain::Error::Backend(format!("Future database version: {}", db_version)))?, + } } update_version(db_path) } -/// Migration from version0 to version1: -/// 1) the number of columns has changed from 10 to 11; -/// 2) changes tries configuration are now cached. -fn migrate_0_to_1(db_path: &Path, db_type: DatabaseType) -> sp_blockchain::Result<()> { - { - let db = open_database(db_path, db_type, V0_NUM_COLUMNS)?; - db.add_column().map_err(db_err)?; - db.flush().map_err(db_err)?; - } - - let db = open_database(db_path, db_type, V0_NUM_COLUMNS + 1)?; - - const V0_FULL_KEY_LOOKUP_COLUMN: u32 = 3; - const V0_FULL_HEADER_COLUMN: u32 = 4; - const V0_FULL_CACHE_COLUMN: u32 = 10; // that's the column we have just added - const V0_LIGHT_KEY_LOOKUP_COLUMN: u32 = 1; - const V0_LIGHT_HEADER_COLUMN: u32 = 2; - const V0_LIGHT_CACHE_COLUMN: u32 = 3; - - let (key_lookup_column, header_column, cache_column) = match db_type { - DatabaseType::Full => ( - V0_FULL_KEY_LOOKUP_COLUMN, - V0_FULL_HEADER_COLUMN, - V0_FULL_CACHE_COLUMN, - ), - DatabaseType::Light => ( - V0_LIGHT_KEY_LOOKUP_COLUMN, - V0_LIGHT_HEADER_COLUMN, - V0_LIGHT_CACHE_COLUMN, - ), - }; - - let genesis_hash: Option = read_genesis_hash(&db)?; - if let Some(genesis_hash) = genesis_hash { - let cache: DbCacheSync = DbCacheSync(RwLock::new(DbCache::new( - Arc::new(db), - key_lookup_column, - header_column, - cache_column, - genesis_hash, - ComplexBlockId::new(genesis_hash, 0.into()), - ))); - let changes_trie_config: Option = None; - cache.initialize(&well_known_cache_keys::CHANGES_TRIE_CONFIG, changes_trie_config.encode())?; - } - - Ok(()) -} /// Reads current database version from the file at given path. /// If the file does not exist returns 0. @@ -118,14 +61,9 @@ fn current_version(path: &Path) -> sp_blockchain::Result { } } -/// Opens database of given type with given number of columns. -fn open_database(db_path: &Path, db_type: DatabaseType, db_columns: u32) -> sp_blockchain::Result { - let db_path = db_path.to_str() - .ok_or_else(|| sp_blockchain::Error::Backend("Invalid database path".into()))?; - let db_cfg = DatabaseConfig::with_columns(db_columns); - let db = Database::open(&db_cfg, db_path).map_err(db_err)?; - check_database_type(&db, db_type)?; - Ok(db) +/// Maps database error to client error +fn db_err(err: std::io::Error) -> sp_blockchain::Error { + sp_blockchain::Error::Backend(format!("{}", err)) } /// Writes current database version to the file. @@ -152,8 +90,6 @@ mod tests { use super::*; fn create_db(db_path: &Path, version: Option) { - let db_cfg = DatabaseConfig::with_columns(V0_NUM_COLUMNS); - Database::open(&db_cfg, db_path.to_str().unwrap()).unwrap(); if let Some(version) = version { fs::create_dir_all(db_path).unwrap(); let mut file = fs::File::create(version_file_path(db_path)).unwrap(); @@ -166,7 +102,7 @@ mod tests { state_cache_size: 0, state_cache_child_ratio: None, pruning: PruningMode::ArchiveAll, - source: DatabaseSettingsSrc::Path { path: db_path.to_owned(), cache_size: 128 }, + source: DatabaseSettingsSrc::RocksDb { path: db_path.to_owned(), cache_size: 128 }, }, DatabaseType::Full).map(|_| ()) } @@ -184,15 +120,4 @@ mod tests { open_database(db_dir.path()).unwrap(); assert_eq!(current_version(db_dir.path()).unwrap(), CURRENT_VERSION); } - - #[test] - fn upgrade_from_0_to_1_works() { - for version_from_file in &[None, Some(0)] { - let db_dir = tempfile::TempDir::new().unwrap(); - let db_path = db_dir.path(); - create_db(db_path, *version_from_file); - open_database(db_path).unwrap(); - assert_eq!(current_version(db_path).unwrap(), CURRENT_VERSION); - } - } } diff --git a/client/db/src/utils.rs b/client/db/src/utils.rs index 16239a82c2..9506dc4e7f 100644 --- a/client/db/src/utils.rs +++ b/client/db/src/utils.rs @@ -18,21 +18,19 @@ //! full and light storages. use std::sync::Arc; -use std::{io, convert::TryInto}; +use std::convert::TryInto; -use kvdb::{KeyValueDB, DBTransaction}; -#[cfg(any(feature = "kvdb-rocksdb", test))] -use kvdb_rocksdb::{Database, DatabaseConfig}; use log::debug; use codec::Decode; use sp_trie::DBValue; +use sp_database::Transaction; use sp_runtime::generic::BlockId; use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, Zero, UniqueSaturatedFrom, UniqueSaturatedInto, }; -use crate::{DatabaseSettings, DatabaseSettingsSrc}; +use crate::{DatabaseSettings, DatabaseSettingsSrc, Database, DbHash}; /// Number of columns in the db. Must be the same for both full && light dbs. /// Otherwise RocksDb will fail to open database && check its type. @@ -136,35 +134,35 @@ pub fn lookup_key_to_number(key: &[u8]) -> sp_blockchain::Result where /// Delete number to hash mapping in DB transaction. pub fn remove_number_to_key_mapping>( - transaction: &mut DBTransaction, + transaction: &mut Transaction, key_lookup_col: u32, number: N, ) -> sp_blockchain::Result<()> { - transaction.delete(key_lookup_col, number_index_key(number)?.as_ref()); + transaction.remove(key_lookup_col, number_index_key(number)?.as_ref()); Ok(()) } /// Remove key mappings. pub fn remove_key_mappings, H: AsRef<[u8]>>( - transaction: &mut DBTransaction, + transaction: &mut Transaction, key_lookup_col: u32, number: N, hash: H, ) -> sp_blockchain::Result<()> { remove_number_to_key_mapping(transaction, key_lookup_col, number)?; - transaction.delete(key_lookup_col, hash.as_ref()); + transaction.remove(key_lookup_col, hash.as_ref()); Ok(()) } /// Place a number mapping into the database. This maps number to current perceived /// block hash at that position. pub fn insert_number_to_key_mapping + Clone, H: AsRef<[u8]>>( - transaction: &mut DBTransaction, + transaction: &mut Transaction, key_lookup_col: u32, number: N, hash: H, ) -> sp_blockchain::Result<()> { - transaction.put_vec( + transaction.set_from_vec( key_lookup_col, number_index_key(number.clone())?.as_ref(), number_and_hash_to_lookup_key(number, hash)?, @@ -174,12 +172,12 @@ pub fn insert_number_to_key_mapping + Clone, H: AsRef<[u8]>>( /// Insert a hash to key mapping in the database. pub fn insert_hash_to_key_mapping, H: AsRef<[u8]> + Clone>( - transaction: &mut DBTransaction, + transaction: &mut Transaction, key_lookup_col: u32, number: N, hash: H, ) -> sp_blockchain::Result<()> { - transaction.put_vec( + transaction.set_from_vec( key_lookup_col, hash.clone().as_ref(), number_and_hash_to_lookup_key(number, hash)?, @@ -191,42 +189,35 @@ pub fn insert_hash_to_key_mapping, H: AsRef<[u8]> + Clone>( /// block lookup key is the DB-key header, block and justification are stored under. /// looks up lookup key by hash from DB as necessary. pub fn block_id_to_lookup_key( - db: &dyn KeyValueDB, + db: &dyn Database, key_lookup_col: u32, id: BlockId ) -> Result>, sp_blockchain::Error> where Block: BlockT, ::sp_runtime::traits::NumberFor: UniqueSaturatedFrom + UniqueSaturatedInto, { - let res = match id { + Ok(match id { BlockId::Number(n) => db.get( key_lookup_col, number_index_key(n)?.as_ref(), ), - BlockId::Hash(h) => db.get(key_lookup_col, h.as_ref()), - }; - - res.map_err(db_err) -} - -/// Maps database error to client error -pub fn db_err(err: io::Error) -> sp_blockchain::Error { - sp_blockchain::Error::Backend(format!("{}", err)) + BlockId::Hash(h) => db.get(key_lookup_col, h.as_ref()) + }) } -/// Open RocksDB database. +/// Opens the configured database. pub fn open_database( config: &DatabaseSettings, db_type: DatabaseType, -) -> sp_blockchain::Result> { - let db: Arc = match &config.source { +) -> sp_blockchain::Result>> { + let db: Arc> = match &config.source { #[cfg(any(feature = "kvdb-rocksdb", test))] - DatabaseSettingsSrc::Path { path, cache_size } => { + DatabaseSettingsSrc::RocksDb { path, cache_size } => { // first upgrade database to required version crate::upgrade::upgrade_db::(&path, db_type)?; // and now open database assuming that it has the latest version - let mut db_config = DatabaseConfig::with_columns(NUM_COLUMNS); + let mut db_config = kvdb_rocksdb::DatabaseConfig::with_columns(NUM_COLUMNS); let state_col_budget = (*cache_size as f64 * 0.9) as usize; let other_col_budget = (cache_size - state_col_budget) / (NUM_COLUMNS as usize - 1); let mut memory_budget = std::collections::HashMap::new(); @@ -245,21 +236,32 @@ pub fn open_database( log::trace!( target: "db", - "Open database at {}, state column budget: {} MiB, others({}) column cache: {} MiB", + "Open RocksDB database at {}, state column budget: {} MiB, others({}) column cache: {} MiB", path, state_col_budget, NUM_COLUMNS, other_col_budget, ); - Arc::new(Database::open(&db_config, &path).map_err(db_err)?) + let db = kvdb_rocksdb::Database::open(&db_config, &path) + .map_err(|err| sp_blockchain::Error::Backend(format!("{}", err)))?; + sp_database::as_database(db) }, - #[cfg(not(any(feature = "kvdb-rocksdb", test)))] - DatabaseSettingsSrc::Path { .. } => { - let msg = "Try to open RocksDB database with RocksDB disabled".into(); - return Err(sp_blockchain::Error::Backend(msg)); + #[cfg(feature = "subdb")] + DatabaseSettingsSrc::SubDb { path } => { + crate::subdb::open(&path, NUM_COLUMNS) + .map_err(|e| sp_blockchain::Error::Backend(format!("{:?}", e)))? + }, + #[cfg(feature = "parity-db")] + DatabaseSettingsSrc::ParityDb { path } => { + crate::parity_db::open(&path, NUM_COLUMNS) + .map_err(|e| sp_blockchain::Error::Backend(format!("{:?}", e)))? }, DatabaseSettingsSrc::Custom(db) => db.clone(), + _ => { + let msg = "Trying to open a unsupported database".into(); + return Err(sp_blockchain::Error::Backend(msg)); + }, }; check_database_type(&*db, db_type)?; @@ -268,8 +270,8 @@ pub fn open_database( } /// Check database type. -pub fn check_database_type(db: &dyn KeyValueDB, db_type: DatabaseType) -> sp_blockchain::Result<()> { - match db.get(COLUMN_META, meta_keys::TYPE).map_err(db_err)? { +pub fn check_database_type(db: &dyn Database, db_type: DatabaseType) -> sp_blockchain::Result<()> { + match db.get(COLUMN_META, meta_keys::TYPE) { Some(stored_type) => { if db_type.as_str().as_bytes() != &*stored_type { return Err(sp_blockchain::Error::Backend( @@ -277,9 +279,9 @@ pub fn check_database_type(db: &dyn KeyValueDB, db_type: DatabaseType) -> sp_blo } }, None => { - let mut transaction = DBTransaction::new(); - transaction.put(COLUMN_META, meta_keys::TYPE, db_type.as_str().as_bytes()); - db.write(transaction).map_err(db_err)?; + let mut transaction = Transaction::new(); + transaction.set(COLUMN_META, meta_keys::TYPE, db_type.as_str().as_bytes()); + db.commit(transaction) }, } @@ -288,7 +290,7 @@ pub fn check_database_type(db: &dyn KeyValueDB, db_type: DatabaseType) -> sp_blo /// Read database column entry for the given block. pub fn read_db( - db: &dyn KeyValueDB, + db: &dyn Database, col_index: u32, col: u32, id: BlockId @@ -297,14 +299,14 @@ pub fn read_db( Block: BlockT, { block_id_to_lookup_key(db, col_index, id).and_then(|key| match key { - Some(key) => db.get(col, key.as_ref()).map_err(db_err), + Some(key) => Ok(db.get(col, key.as_ref())), None => Ok(None), }) } /// Read a header from the database. pub fn read_header( - db: &dyn KeyValueDB, + db: &dyn Database, col_index: u32, col: u32, id: BlockId, @@ -322,7 +324,7 @@ pub fn read_header( /// Required header from the database. pub fn require_header( - db: &dyn KeyValueDB, + db: &dyn Database, col_index: u32, col: u32, id: BlockId, @@ -334,7 +336,7 @@ pub fn require_header( } /// Read meta from the database. -pub fn read_meta(db: &dyn KeyValueDB, col_header: u32) -> Result< +pub fn read_meta(db: &dyn Database, col_header: u32) -> Result< Meta<<::Header as HeaderT>::Number, Block::Hash>, sp_blockchain::Error, > @@ -353,11 +355,10 @@ pub fn read_meta(db: &dyn KeyValueDB, col_header: u32) -> Result< }; let load_meta_block = |desc, key| -> Result<_, sp_blockchain::Error> { - if let Some(Some(header)) = db.get(COLUMN_META, key).and_then(|id| - match id { - Some(id) => db.get(col_header, &id).map(|h| h.map(|b| Block::Header::decode(&mut &b[..]).ok())), - None => Ok(None), - }).map_err(db_err)? + if let Some(Some(header)) = match db.get(COLUMN_META, key) { + Some(id) => db.get(col_header, &id).map(|b| Block::Header::decode(&mut &b[..]).ok()), + None => None, + } { let hash = header.hash(); debug!("DB Opened blockchain db, fetched {} = {:?} ({})", desc, hash, header.number()); @@ -380,8 +381,8 @@ pub fn read_meta(db: &dyn KeyValueDB, col_header: u32) -> Result< } /// Read genesis hash from database. -pub fn read_genesis_hash(db: &dyn KeyValueDB) -> sp_blockchain::Result> { - match db.get(COLUMN_META, meta_keys::GENESIS_HASH).map_err(db_err)? { +pub fn read_genesis_hash(db: &dyn Database) -> sp_blockchain::Result> { + match db.get(COLUMN_META, meta_keys::GENESIS_HASH) { Some(h) => match Decode::decode(&mut &h[..]) { Ok(h) => Ok(Some(h)), Err(err) => Err(sp_blockchain::Error::Backend( diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index fec4f1317b..ae129871db 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -32,6 +32,7 @@ use sp_blockchain::{ use sc_client_api::{BlockchainEvents, BlockImportNotification, FinalityNotifications, ImportNotifications, FinalityNotification, backend::{TransactionFor, AuxStore, Backend, Finalizer}, BlockBackend}; use sc_block_builder::{BlockBuilder, BlockBuilderProvider}; use sc_client::LongestChain; +use sc_client::blockchain::HeaderBackend; use sc_network::config::Role; use sp_consensus::block_validation::DefaultBlockAnnounceValidator; use sp_consensus::import_queue::{ @@ -359,13 +360,9 @@ impl Peer { /// Test helper to compare the blockchain state of multiple (networked) /// clients. - /// Potentially costly, as it creates in-memory copies of both blockchains in order - /// to compare them. If you have easier/softer checks that are sufficient, e.g. - /// by using .info(), you should probably use it instead of this. pub fn blockchain_canon_equals(&self, other: &Self) -> bool { if let (Some(mine), Some(others)) = (self.backend.clone(), other.backend.clone()) { - mine.as_in_memory().blockchain() - .canon_equals_to(others.as_in_memory().blockchain()) + mine.blockchain().info().best_hash == others.blockchain().info().best_hash } else { false } @@ -374,7 +371,7 @@ impl Peer { /// Count the total number of imported blocks. pub fn blocks_count(&self) -> u64 { self.backend.as_ref().map( - |backend| backend.blocks_count() + |backend| backend.blockchain().info().best_number ).unwrap_or(0) } @@ -382,6 +379,12 @@ impl Peer { pub fn failed_verifications(&self) -> HashMap<::Hash, String> { self.verifier.failed_verifications.lock().clone() } + + pub fn has_block(&self, hash: &H256) -> bool { + self.backend.as_ref().map( + |backend| backend.blockchain().header(BlockId::hash(*hash)).unwrap().is_some() + ).unwrap_or(false) + } } /// Implements `BlockImport` for any `Transaction`. Internally the transaction is diff --git a/client/network/test/src/sync.rs b/client/network/test/src/sync.rs index 8acf265e91..60e9e558c5 100644 --- a/client/network/test/src/sync.rs +++ b/client/network/test/src/sync.rs @@ -339,13 +339,15 @@ fn syncs_all_forks() { net.peer(0).push_blocks(2, false); net.peer(1).push_blocks(2, false); - net.peer(0).push_blocks(2, true); - net.peer(1).push_blocks(4, false); + let b1 = net.peer(0).push_blocks(2, true); + let b2 = net.peer(1).push_blocks(4, false); net.block_until_sync(); - // Check that all peers have all of the blocks. - assert_eq!(9, net.peer(0).blocks_count()); - assert_eq!(9, net.peer(1).blocks_count()); + // Check that all peers have all of the branches. + assert!(net.peer(0).has_block(&b1)); + assert!(net.peer(0).has_block(&b2)); + assert!(net.peer(1).has_block(&b1)); + assert!(net.peer(1).has_block(&b2)); } #[test] @@ -587,24 +589,11 @@ fn syncs_header_only_forks() { net.peer(0).push_blocks(2, true); let small_hash = net.peer(0).client().info().best_hash; - let small_number = net.peer(0).client().info().best_number; net.peer(1).push_blocks(4, false); net.block_until_sync(); // Peer 1 will sync the small fork even though common block state is missing - assert_eq!(9, net.peer(0).blocks_count()); - assert_eq!(9, net.peer(1).blocks_count()); - - // Request explicit header-only sync request for the ancient fork. - let first_peer_id = net.peer(0).id(); - net.peer(1).set_sync_fork_request(vec![first_peer_id], small_hash, small_number); - block_on(futures::future::poll_fn::<(), _>(|cx| { - net.poll(cx); - if net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_none() { - return Poll::Pending - } - Poll::Ready(()) - })); + assert!(net.peer(1).has_block(&small_hash)); } #[test] diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 20b5c12a58..ba55c68b34 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -12,10 +12,10 @@ description = "Substrate service. Starts a thread that spins up the network, cli targets = ["x86_64-unknown-linux-gnu"] [features] -default = ["rocksdb"] +default = ["db"] # The RocksDB feature activates the RocksDB database backend. If it is not activated, and you pass # a path to a database, an error will be produced at runtime. -rocksdb = ["sc-client-db/kvdb-rocksdb"] +db = ["sc-client-db/kvdb-rocksdb", "sc-client-db/parity-db"] wasmtime = [ "sc-executor/wasmtime", ] diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index acb546fc60..4f370c1118 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -17,7 +17,7 @@ use crate::{Service, NetworkStatus, NetworkState, error::Error, DEFAULT_PROTOCOL_ID, MallocSizeOfWasm}; use crate::{TaskManagerBuilder, start_rpc_servers, build_network_future, TransactionPoolAdapter}; use crate::status_sinks; -use crate::config::{Configuration, DatabaseConfig, KeystoreConfig, PrometheusConfig}; +use crate::config::{Configuration, KeystoreConfig, PrometheusConfig}; use crate::metrics::MetricsService; use sc_client_api::{ self, @@ -196,15 +196,7 @@ fn new_full_parts( state_cache_child_ratio: config.state_cache_child_ratio.map(|v| (v, 100)), pruning: config.pruning.clone(), - source: match &config.database { - DatabaseConfig::Path { path, cache_size } => - sc_client_db::DatabaseSettingsSrc::Path { - path: path.clone(), - cache_size: *cache_size, - }, - DatabaseConfig::Custom(db) => - sc_client_db::DatabaseSettingsSrc::Custom(db.clone()), - }, + source: config.database.clone(), }; let extensions = sc_client_api::execution_extensions::ExecutionExtensions::new( @@ -308,15 +300,7 @@ impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { state_cache_child_ratio: config.state_cache_child_ratio.map(|v| (v, 100)), pruning: config.pruning.clone(), - source: match &config.database { - DatabaseConfig::Path { path, cache_size } => - sc_client_db::DatabaseSettingsSrc::Path { - path: path.clone(), - cache_size: *cache_size, - }, - DatabaseConfig::Custom(db) => - sc_client_db::DatabaseSettingsSrc::Custom(db.clone()), - }, + source: config.database.clone(), }; sc_client_db::light::LightStorage::new(db_settings)? }; diff --git a/client/service/src/config.rs b/client/service/src/config.rs index 0515a31c7c..b90bed723f 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -17,7 +17,7 @@ //! Service configuration. pub use sc_client::ExecutionStrategies; -pub use sc_client_db::{kvdb::KeyValueDB, PruningMode}; +pub use sc_client_db::{Database, PruningMode, DatabaseSettingsSrc as DatabaseConfig}; pub use sc_network::Multiaddr; pub use sc_network::config::{ExtTransport, MultiaddrWithPeerId, NetworkConfiguration, Role, NodeKeyConfig}; pub use sc_executor::WasmExecutionMethod; @@ -124,21 +124,6 @@ impl KeystoreConfig { } } -/// Configuration of the database of the client. -#[derive(Clone)] -pub enum DatabaseConfig { - /// Database file at a specific path. Recommended for most uses. - Path { - /// Path to the database. - path: PathBuf, - /// Cache Size for internal database in MiB - cache_size: usize, - }, - - /// A custom implementation of an already-open database. - Custom(Arc), -} - /// Configuration of the Prometheus endpoint. #[derive(Clone)] pub struct PrometheusConfig { diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 2811076ba3..a532014658 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -175,7 +175,7 @@ fn node_config { hash: H, @@ -59,7 +61,7 @@ impl FinalizationDisplaced { #[derive(Debug, Clone, PartialEq, Eq)] pub struct LeafSet { storage: BTreeMap, Vec>, - pending_added: Vec>, + pending_added: Vec<(H, N)>, pending_removed: Vec, } @@ -77,21 +79,20 @@ impl LeafSet where } /// Read the leaf list from the DB, using given prefix for keys. - pub fn read_from_db(db: &dyn KeyValueDB, column: u32, prefix: &[u8]) -> Result { + pub fn read_from_db(db: &dyn Database, column: u32, prefix: &[u8]) -> Result { let mut storage = BTreeMap::new(); - for (key, value) in db.iter_from_prefix(column, prefix) { - if !key.starts_with(prefix) { break } - let raw_hash = &mut &key[prefix.len()..]; - let hash = match Decode::decode(raw_hash) { - Ok(hash) => hash, - Err(_) => return Err(Error::Backend("Error decoding hash".into())), - }; - let number = match Decode::decode(&mut &value[..]) { - Ok(number) => number, - Err(_) => return Err(Error::Backend("Error decoding number".into())), - }; - storage.entry(Reverse(number)).or_insert_with(Vec::new).push(hash); + match db.get(column, prefix) { + Some(leaves) => { + let vals: Vec<_> = match Decode::decode(&mut leaves.as_ref()) { + Ok(vals) => vals, + Err(_) => return Err(Error::Backend("Error decoding leaves".into())), + }; + for (number, hashes) in vals.into_iter() { + storage.insert(Reverse(number), hashes); + } + } + None => {}, } Ok(Self { storage, @@ -124,7 +125,7 @@ impl LeafSet where }; self.insert_leaf(Reverse(number.clone()), hash.clone()); - self.pending_added.push(LeafSetItem { hash, number: Reverse(number) }); + self.pending_added.push((hash, number)); displaced } @@ -185,7 +186,7 @@ impl LeafSet where // this is an invariant of regular block import. if !leaves_contains_best { self.insert_leaf(best_number.clone(), best_hash.clone()); - self.pending_added.push(LeafSetItem { hash: best_hash, number: best_number }); + self.pending_added.push((best_hash, best_number.0)); } } @@ -201,18 +202,11 @@ impl LeafSet where } /// Write the leaf list to the database transaction. - pub fn prepare_transaction(&mut self, tx: &mut DBTransaction, column: u32, prefix: &[u8]) { - let mut buf = prefix.to_vec(); - for LeafSetItem { hash, number } in self.pending_added.drain(..) { - hash.using_encoded(|s| buf.extend(s)); - tx.put_vec(column, &buf[..], number.0.encode()); - buf.truncate(prefix.len()); // reuse allocation. - } - for hash in self.pending_removed.drain(..) { - hash.using_encoded(|s| buf.extend(s)); - tx.delete(column, &buf[..]); - buf.truncate(prefix.len()); // reuse allocation. - } + pub fn prepare_transaction(&mut self, tx: &mut Transaction, column: u32, prefix: &[u8]) { + let leaves: Vec<_> = self.storage.iter().map(|(n, h)| (n.0.clone(), h.clone())).collect(); + tx.set_from_vec(column, prefix, leaves.encode()); + self.pending_added.clear(); + self.pending_removed.clear(); } #[cfg(test)] @@ -281,6 +275,7 @@ impl<'a, H: 'a, N: 'a> Drop for Undo<'a, H, N> { #[cfg(test)] mod tests { use super::*; + use std::sync::Arc; #[test] fn it_works() { @@ -305,7 +300,7 @@ mod tests { #[test] fn flush_to_disk() { const PREFIX: &[u8] = b"abcdefg"; - let db = ::kvdb_memorydb::create(1); + let db = Arc::new(sp_database::MemDb::default()); let mut set = LeafSet::new(); set.import(0u32, 0u32, 0u32); @@ -314,12 +309,12 @@ mod tests { set.import(2_1, 2, 1_1); set.import(3_1, 3, 2_1); - let mut tx = DBTransaction::new(); + let mut tx = Transaction::new(); set.prepare_transaction(&mut tx, 0, PREFIX); - db.write(tx).unwrap(); + db.commit(tx); - let set2 = LeafSet::read_from_db(&db, 0, PREFIX).unwrap(); + let set2 = LeafSet::read_from_db(&*db, 0, PREFIX).unwrap(); assert_eq!(set, set2); } @@ -339,7 +334,7 @@ mod tests { #[test] fn finalization_consistent_with_disk() { const PREFIX: &[u8] = b"prefix"; - let db = ::kvdb_memorydb::create(1); + let db = Arc::new(sp_database::MemDb::default()); let mut set = LeafSet::new(); set.import(10_1u32, 10u32, 0u32); @@ -349,21 +344,21 @@ mod tests { assert!(set.contains(10, 10_1)); - let mut tx = DBTransaction::new(); + let mut tx = Transaction::new(); set.prepare_transaction(&mut tx, 0, PREFIX); - db.write(tx).unwrap(); + db.commit(tx); let _ = set.finalize_height(11); - let mut tx = DBTransaction::new(); + let mut tx = Transaction::new(); set.prepare_transaction(&mut tx, 0, PREFIX); - db.write(tx).unwrap(); + db.commit(tx); assert!(set.contains(11, 11_1)); assert!(set.contains(11, 11_2)); assert!(set.contains(12, 12_1)); assert!(!set.contains(10, 10_1)); - let set2 = LeafSet::read_from_db(&db, 0, PREFIX).unwrap(); + let set2 = LeafSet::read_from_db(&*db, 0, PREFIX).unwrap(); assert_eq!(set, set2); } diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 7e2040ee23..35e1231698 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -208,7 +208,7 @@ pub trait Contains { /// /// **Should be used for benchmarking only!!!** #[cfg(feature = "runtime-benchmarks")] - fn add(t: &T); + fn add(t: &T) { unimplemented!() } } /// Determiner to say whether a given account is unused. diff --git a/primitives/blockchain/src/backend.rs b/primitives/blockchain/src/backend.rs index e92dfd8c98..45d627a1c2 100644 --- a/primitives/blockchain/src/backend.rs +++ b/primitives/blockchain/src/backend.rs @@ -242,7 +242,7 @@ pub trait Cache: Send + Sync { } /// Blockchain info -#[derive(Debug)] +#[derive(Debug, Eq, PartialEq)] pub struct Info { /// Best block hash. pub best_hash: Block::Hash, diff --git a/primitives/database/Cargo.toml b/primitives/database/Cargo.toml new file mode 100644 index 0000000000..2ab86de61d --- /dev/null +++ b/primitives/database/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "sp-database" +version = "2.0.0-dev" +authors = ["Parity Technologies "] +edition = "2018" +license = "GPL-3.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "Substrate database trait." +documentation = "https://docs.rs/sp-database" + +[dependencies] +parking_lot = "0.10.0" +kvdb = "0.5.0" diff --git a/primitives/database/src/kvdb.rs b/primitives/database/src/kvdb.rs new file mode 100644 index 0000000000..85a324b5c1 --- /dev/null +++ b/primitives/database/src/kvdb.rs @@ -0,0 +1,59 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +/// A wrapper around `kvdb::Database` that implements `sp_database::Database` trait + +use ::kvdb::{DBTransaction, KeyValueDB}; + +use crate::{Database, Change, Transaction, ColumnId}; + +struct DbAdapter(D); + +fn handle_err(result: std::io::Result) -> T { + match result { + Ok(r) => r, + Err(e) => { + panic!("Critical database eror: {:?}", e); + } + } +} + +/// Wrap RocksDb database into a trait object that implements `sp_database::Database` +pub fn as_database(db: D) -> std::sync::Arc> { + std::sync::Arc::new(DbAdapter(db)) +} + +impl Database for DbAdapter { + fn commit(&self, transaction: Transaction) { + let mut tx = DBTransaction::new(); + for change in transaction.0.into_iter() { + match change { + Change::Set(col, key, value) => tx.put_vec(col, &key, value), + Change::Remove(col, key) => tx.delete(col, &key), + _ => unimplemented!(), + } + } + handle_err(self.0.write(tx)); + } + + fn get(&self, col: ColumnId, key: &[u8]) -> Option> { + handle_err(self.0.get(col, key)) + } + + fn lookup(&self, _hash: &H) -> Option> { + unimplemented!(); + } +} diff --git a/primitives/database/src/lib.rs b/primitives/database/src/lib.rs new file mode 100644 index 0000000000..bd9bd2eb54 --- /dev/null +++ b/primitives/database/src/lib.rs @@ -0,0 +1,187 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The main database trait, allowing Substrate to store data persistently. + +mod mem; +mod kvdb; + +pub use mem::MemDb; +pub use crate::kvdb::as_database; + +/// An identifier for a column. +pub type ColumnId = u32; + +/// An alteration to the database. +#[derive(Clone)] +pub enum Change { + Set(ColumnId, Vec, Vec), + Remove(ColumnId, Vec), + Store(H, Vec), + Release(H), +} + +/// An alteration to the database that references the data. +pub enum ChangeRef<'a, H> { + Set(ColumnId, &'a [u8], &'a [u8]), + Remove(ColumnId, &'a [u8]), + Store(H, &'a [u8]), + Release(H), +} + +/// A series of changes to the database that can be committed atomically. They do not take effect +/// until passed into `Database::commit`. +#[derive(Default, Clone)] +pub struct Transaction(pub Vec>); + +impl Transaction { + /// Create a new transaction to be prepared and committed atomically. + pub fn new() -> Self { + Transaction(Vec::new()) + } + /// Set the value of `key` in `col` to `value`, replacing anything that is there currently. + pub fn set(&mut self, col: ColumnId, key: &[u8], value: &[u8]) { + self.0.push(Change::Set(col, key.to_vec(), value.to_vec())) + } + /// Set the value of `key` in `col` to `value`, replacing anything that is there currently. + pub fn set_from_vec(&mut self, col: ColumnId, key: &[u8], value: Vec) { + self.0.push(Change::Set(col, key.to_vec(), value)) + } + /// Remove the value of `key` in `col`. + pub fn remove(&mut self, col: ColumnId, key: &[u8]) { + self.0.push(Change::Remove(col, key.to_vec())) + } + /// Store the `preimage` of `hash` into the database, so that it may be looked up later with + /// `Database::lookup`. This may be called multiple times, but `Database::lookup` but subsequent + /// calls will ignore `preimage` and simply increase the number of references on `hash`. + pub fn store(&mut self, hash: H, preimage: &[u8]) { + self.0.push(Change::Store(hash, preimage.to_vec())) + } + /// Release the preimage of `hash` from the database. An equal number of these to the number of + /// corresponding `store`s must have been given before it is legal for `Database::lookup` to + /// be unable to provide the preimage. + pub fn release(&mut self, hash: H) { + self.0.push(Change::Release(hash)) + } +} + +pub trait Database: Send + Sync { + /// Commit the `transaction` to the database atomically. Any further calls to `get` or `lookup` + /// will reflect the new state. + fn commit(&self, transaction: Transaction) { + for change in transaction.0.into_iter() { + match change { + Change::Set(col, key, value) => self.set(col, &key, &value), + Change::Remove(col, key) => self.remove(col, &key), + Change::Store(hash, preimage) => self.store(&hash, &preimage), + Change::Release(hash) => self.release(&hash), + } + } + } + + /// Commit the `transaction` to the database atomically. Any further calls to `get` or `lookup` + /// will reflect the new state. + fn commit_ref<'a>(&self, transaction: &mut dyn Iterator>) { + let mut tx = Transaction::new(); + for change in transaction { + match change { + ChangeRef::Set(col, key, value) => tx.set(col, key, value), + ChangeRef::Remove(col, key) => tx.remove(col, key), + ChangeRef::Store(hash, preimage) => tx.store(hash, preimage), + ChangeRef::Release(hash) => tx.release(hash), + } + } + self.commit(tx); + } + + /// Retrieve the value previously stored against `key` or `None` if + /// `key` is not currently in the database. + fn get(&self, col: ColumnId, key: &[u8]) -> Option>; + + /// Call `f` with the value previously stored against `key`. + /// + /// This may be faster than `get` since it doesn't allocate. + /// Use `with_get` helper function if you need `f` to return a value from `f` + fn with_get(&self, col: ColumnId, key: &[u8], f: &mut dyn FnMut(&[u8])) { + self.get(col, key).map(|v| f(&v)); + } + + /// Set the value of `key` in `col` to `value`, replacing anything that is there currently. + fn set(&self, col: ColumnId, key: &[u8], value: &[u8]) { + let mut t = Transaction::new(); + t.set(col, key, value); + self.commit(t); + } + /// Remove the value of `key` in `col`. + fn remove(&self, col: ColumnId, key: &[u8]) { + let mut t = Transaction::new(); + t.remove(col, key); + self.commit(t); + } + + /// Retrieve the first preimage previously `store`d for `hash` or `None` if no preimage is + /// currently stored. + fn lookup(&self, hash: &H) -> Option>; + + /// Call `f` with the preimage stored for `hash` and return the result, or `None` if no preimage + /// is currently stored. + /// + /// This may be faster than `lookup` since it doesn't allocate. + /// Use `with_lookup` helper function if you need `f` to return a value from `f` + fn with_lookup(&self, hash: &H, f: &mut dyn FnMut(&[u8])) { + self.lookup(hash).map(|v| f(&v)); + } + + /// Store the `preimage` of `hash` into the database, so that it may be looked up later with + /// `Database::lookup`. This may be called multiple times, but `Database::lookup` but subsequent + /// calls will ignore `preimage` and simply increase the number of references on `hash`. + fn store(&self, hash: &H, preimage: &[u8]) { + let mut t = Transaction::new(); + t.store(hash.clone(), preimage); + self.commit(t); + } + + /// Release the preimage of `hash` from the database. An equal number of these to the number of + /// corresponding `store`s must have been given before it is legal for `Database::lookup` to + /// be unable to provide the preimage. + fn release(&self, hash: &H) { + let mut t = Transaction::new(); + t.release(hash.clone()); + self.commit(t); + } +} + +/// Call `f` with the value previously stored against `key` and return the result, or `None` if +/// `key` is not currently in the database. +/// +/// This may be faster than `get` since it doesn't allocate. +pub fn with_get(db: &dyn Database, col: ColumnId, key: &[u8], mut f: impl FnMut(&[u8]) -> R) -> Option { + let mut result: Option = None; + let mut adapter = |k: &_| { result = Some(f(k)); }; + db.with_get(col, key, &mut adapter); + result +} + +/// Call `f` with the preimage stored for `hash` and return the result, or `None` if no preimage +/// is currently stored. +/// +/// This may be faster than `lookup` since it doesn't allocate. +pub fn with_lookup(db: &dyn Database, hash: &H, mut f: impl FnMut(&[u8]) -> R) -> Option { + let mut result: Option = None; + let mut adapter = |k: &_| { result = Some(f(k)); }; + db.with_lookup(hash, &mut adapter); + result +} diff --git a/primitives/database/src/mem.rs b/primitives/database/src/mem.rs new file mode 100644 index 0000000000..09d6149bed --- /dev/null +++ b/primitives/database/src/mem.rs @@ -0,0 +1,68 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! In-memory implementation of `Database` + +use std::collections::HashMap; +use crate::{Database, Transaction, ColumnId, Change}; +use parking_lot::RwLock; + +#[derive(Default)] +/// This implements `Database` as an in-memory hash map. `commit` is not atomic. +pub struct MemDb + (RwLock<(HashMap, Vec>>, HashMap>)>); + +impl Database for MemDb + where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash +{ + fn commit(&self, transaction: Transaction) { + let mut s = self.0.write(); + for change in transaction.0.into_iter() { + match change { + Change::Set(col, key, value) => { s.0.entry(col).or_default().insert(key, value); }, + Change::Remove(col, key) => { s.0.entry(col).or_default().remove(&key); }, + Change::Store(hash, preimage) => { s.1.insert(hash, preimage); }, + Change::Release(hash) => { s.1.remove(&hash); }, + } + } + } + + fn get(&self, col: ColumnId, key: &[u8]) -> Option> { + let s = self.0.read(); + s.0.get(&col).and_then(|c| c.get(key).cloned()) + } + + fn lookup(&self, hash: &H) -> Option> { + let s = self.0.read(); + s.1.get(hash).cloned() + } +} + +impl MemDb + where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash +{ + /// Create a new instance + pub fn new() -> Self { + MemDb::default() + } + + /// Count number of values in a column + pub fn count(&self, col: ColumnId) -> usize { + let s = self.0.read(); + s.0.get(&col).map(|c| c.len()).unwrap_or(0) + } +} + diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 4ffec41633..29211298b7 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -22,6 +22,7 @@ js-sys = "0.3.34" wasm-bindgen = "0.2.57" wasm-bindgen-futures = "0.4.7" kvdb-web = "0.5" +sp-database = { version = "2.0.0-dev", path = "../../primitives/database" } sc-informant = { version = "0.8.0-dev", path = "../../client/informant" } sc-service = { version = "0.8.0-dev", path = "../../client/service", default-features = false } sc-network = { path = "../../client/network", version = "0.8.0-dev"} diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index 572ebcb464..35b1bc99c4 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -70,7 +70,7 @@ where info!("Opening Indexed DB database '{}'...", name); let db = kvdb_web::Database::open(name, 10).await?; - DatabaseConfig::Custom(Arc::new(db)) + DatabaseConfig::Custom(sp_database::as_database(db)) }, keystore: KeystoreConfig::InMemory, default_heap_pages: Default::default(), diff --git a/utils/frame/benchmarking-cli/Cargo.toml b/utils/frame/benchmarking-cli/Cargo.toml index 9366c276ed..86eb20faf8 100644 --- a/utils/frame/benchmarking-cli/Cargo.toml +++ b/utils/frame/benchmarking-cli/Cargo.toml @@ -26,5 +26,5 @@ structopt = "0.3.8" codec = { version = "1.3.0", package = "parity-scale-codec" } [features] -default = ["rocksdb"] -rocksdb = ["sc-client-db/kvdb-rocksdb"] +default = ["db"] +db = ["sc-client-db/kvdb-rocksdb", "sc-client-db/parity-db"] -- GitLab From 220b9c670f396ebfc6fb84ae02ebf5d42d584227 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Wed, 15 Apr 2020 15:55:45 +0200 Subject: [PATCH 230/300] Removed subdb dependency (#5646) --- Cargo.lock | 77 ++------------------------------------------ client/db/Cargo.toml | 1 - 2 files changed, 3 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1eab8009dd..37aeca5892 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1081,16 +1081,6 @@ dependencies = [ "dirs-sys", ] -[[package]] -name = "dirs" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" -dependencies = [ - "cfg-if", - "dirs-sys", -] - [[package]] name = "dirs-sys" version = "0.3.4" @@ -5057,16 +5047,6 @@ dependencies = [ "output_vt100", ] -[[package]] -name = "pretty_env_logger" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" -dependencies = [ - "env_logger 0.7.1", - "log", -] - [[package]] name = "primitive-types" version = "0.7.0" @@ -5933,7 +5913,7 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-core", - "sp-database 2.0.0-dev", + "sp-database", "sp-externalities", "sp-inherents", "sp-keyring", @@ -6008,12 +5988,11 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-core", - "sp-database 2.0.0-dev", + "sp-database", "sp-keyring", "sp-runtime", "sp-state-machine", "sp-trie", - "subdb", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", @@ -7033,17 +7012,6 @@ dependencies = [ "libc", ] -[[package]] -name = "simplelog" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcacac97349a890d437921dfb23cbec52ab5b4752551cb637df2721371acd467" -dependencies = [ - "chrono", - "log", - "term", -] - [[package]] name = "slab" version = "0.4.2" @@ -7424,15 +7392,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "sp-database" -version = "2.0.0-alpha.5" -source = "git+https://github.com/paritytech/substrate?branch=gav-db-trait#9404815700a840586fc8760a60180f4e1bf97ce4" -dependencies = [ - "kvdb", - "parking_lot 0.10.2", -] - [[package]] name = "sp-database" version = "2.0.0-dev" @@ -7921,26 +7880,6 @@ dependencies = [ "syn 1.0.17", ] -[[package]] -name = "subdb" -version = "0.1.0" -source = "git+https://github.com/paritytech/subdb#353bd49a95e618641b552fe890b272f0feb6d752" -dependencies = [ - "blake2-rfc", - "derive_more", - "hash-db", - "hex", - "log", - "memmap", - "parity-scale-codec", - "parking_lot 0.10.2", - "pretty_env_logger", - "simplelog", - "smallvec 1.3.0", - "sp-database 2.0.0-alpha.5", - "twox-hash", -] - [[package]] name = "subkey" version = "2.0.0-dev" @@ -8003,7 +7942,7 @@ dependencies = [ "sc-informant", "sc-network", "sc-service", - "sp-database 2.0.0-dev", + "sp-database", "wasm-bindgen", "wasm-bindgen-futures", ] @@ -8359,16 +8298,6 @@ dependencies = [ "winapi 0.3.8", ] -[[package]] -name = "term" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" -dependencies = [ - "dirs", - "winapi 0.3.8", -] - [[package]] name = "termcolor" version = "1.1.0" diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index 307cacbfb2..0540edd550 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -35,7 +35,6 @@ sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/commo sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } sp-database = { version = "2.0.0-dev", path = "../../primitives/database" } parity-db = { version = "0.1", optional = true } -subdb = { git = "https://github.com/paritytech/subdb", optional = true } prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-dev", path = "../../utils/prometheus" } [dev-dependencies] -- GitLab From 4b911072bfe36652c8d3874cb8020f7ff426abed Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 15 Apr 2020 16:49:08 +0200 Subject: [PATCH 231/300] Implement iter for doublemap (#5504) * implement iter for doublemap * fmt * fix tests * fix staking mock * address comment * update doc and constraint for reversible hasher Co-authored-by: Gavin Wood --- frame/recovery/src/lib.rs | 2 +- frame/staking/src/mock.rs | 2 +- frame/staking/src/tests.rs | 4 +- frame/support/src/hash.rs | 5 + frame/support/src/lib.rs | 2 +- .../src/storage/generator/double_map.rs | 212 +++++++++++++----- frame/support/src/storage/mod.rs | 21 +- 7 files changed, 184 insertions(+), 64 deletions(-) diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index c055f2bd97..7348566d26 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -626,7 +626,7 @@ decl_module! { fn remove_recovery(origin) { let who = ensure_signed(origin)?; // Check there are no active recoveries - let mut active_recoveries = >::iter_prefix(&who); + let mut active_recoveries = >::iter_prefix_values(&who); ensure!(active_recoveries.next().is_none(), Error::::StillActive); // Take the recovery configuration for this account. let recovery_config = >::take(&who).ok_or(Error::::NotRecoverable)?; diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index f649c530c1..ce00193a67 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -528,7 +528,7 @@ fn check_ledgers() { fn check_exposures() { // a check per validator to ensure the exposure struct is always sane. let era = active_era(); - ErasStakers::::iter_prefix(era).for_each(|expo| { + ErasStakers::::iter_prefix_values(era).for_each(|expo| { assert_eq!( expo.total as u128, expo.own as u128 + expo.others.iter().map(|e| e.value as u128).sum::(), diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index dd00fdcd3c..15afda1e3a 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -340,7 +340,7 @@ fn less_than_needed_candidates_works() { // But the exposure is updated in a simple way. No external votes exists. // This is purely self-vote. assert!( - ErasStakers::::iter_prefix(Staking::active_era().unwrap().index) + ErasStakers::::iter_prefix_values(Staking::active_era().unwrap().index) .all(|exposure| exposure.others.is_empty()) ); }); @@ -461,7 +461,7 @@ fn nominating_and_rewards_should_work() { // ------ check the staked value of all parties. // 30 and 40 are not chosen anymore - assert_eq!(ErasStakers::::iter_prefix(Staking::active_era().unwrap().index).count(), 2); + assert_eq!(ErasStakers::::iter_prefix_values(Staking::active_era().unwrap().index).count(), 2); assert_eq!( Staking::eras_stakers(Staking::active_era().unwrap().index, 11), Exposure { diff --git a/frame/support/src/hash.rs b/frame/support/src/hash.rs index 693e929a30..40cb1f612f 100644 --- a/frame/support/src/hash.rs +++ b/frame/support/src/hash.rs @@ -60,7 +60,12 @@ pub trait StorageHasher: 'static { } /// Hasher to use to hash keys to insert to storage. +/// +/// Reversible hasher store the encoded key after the hash part. pub trait ReversibleStorageHasher: StorageHasher { + /// Split the hash part out of the input. + /// + /// I.e. for input `&[hash ++ key ++ some]` returns `&[key ++ some]` fn reverse(x: &[u8]) -> &[u8]; } diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index d37a438fc6..9a32d9a779 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -68,7 +68,7 @@ pub mod weights; pub use self::hash::{ Twox256, Twox128, Blake2_256, Blake2_128, Identity, Twox64Concat, Blake2_128Concat, Hashable, - StorageHasher + StorageHasher, ReversibleStorageHasher }; pub use self::storage::{ StorageValue, StorageMap, StorageDoubleMap, StoragePrefixedMap, IterableStorageMap, diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index 9d05ff0b2d..e23b332383 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -208,7 +208,7 @@ impl storage::StorageDoubleMap for G where unhashed::kill_prefix(Self::storage_double_map_final_key1(k1).as_ref()) } - fn iter_prefix(k1: KArg1) -> storage::PrefixIterator where + fn iter_prefix_values(k1: KArg1) -> storage::PrefixIterator where KArg1: ?Sized + EncodeLike { let prefix = Self::storage_double_map_final_key1(k1); @@ -334,41 +334,47 @@ impl storage::StorageDoubleMap for G where } } -/// Utility to iterate through items in a storage map. -pub struct MapIterator { +/// Iterate over a prefix and decode raw_key and raw_value into `T`. +pub struct MapIterator { prefix: Vec, previous_key: Vec, + /// If true then value are removed while iterating drain: bool, - _phantom: ::sp_std::marker::PhantomData<(K, V, Hasher)>, + /// Function that take `(raw_key_without_prefix, raw_value)` and decode `T`. + /// `raw_key_without_prefix` is the raw storage key without the prefix iterated on. + closure: fn(&[u8], &[u8]) -> Result, } -impl< - K: Decode + Sized, - V: Decode + Sized, - Hasher: ReversibleStorageHasher -> Iterator for MapIterator { - type Item = (K, V); +impl Iterator for MapIterator { + type Item = T; - fn next(&mut self) -> Option<(K, V)> { + fn next(&mut self) -> Option { loop { let maybe_next = sp_io::storage::next_key(&self.previous_key) .filter(|n| n.starts_with(&self.prefix)); break match maybe_next { Some(next) => { self.previous_key = next; - match unhashed::get::(&self.previous_key) { - Some(value) => { - if self.drain { - unhashed::kill(&self.previous_key) - } - let mut key_material = Hasher::reverse(&self.previous_key[self.prefix.len()..]); - match K::decode(&mut key_material) { - Ok(key) => Some((key, value)), - Err(_) => continue, - } + let raw_value = match unhashed::get_raw(&self.previous_key) { + Some(raw_value) => raw_value, + None => { + frame_support::print("ERROR: next_key returned a key with no value in MapIterator"); + continue } - None => continue, + }; + if self.drain { + unhashed::kill(&self.previous_key) } + let raw_key_without_prefix = &self.previous_key[self.prefix.len()..]; + let item = match (self.closure)(raw_key_without_prefix, &raw_value[..]) { + Ok(item) => item, + Err(_e) => { + frame_support::print("ERROR: (key, value) failed to decode in MapIterator"); + continue + } + }; + + Some(item) } None => None, } @@ -385,30 +391,50 @@ impl< G::Hasher1: ReversibleStorageHasher, G::Hasher2: ReversibleStorageHasher { - type Iterator = MapIterator; + type PrefixIterator = MapIterator<(K2, V)>; + type Iterator = MapIterator<(K1, K2, V)>; - /// Enumerate all elements in the map. - fn iter(k1: impl EncodeLike) -> Self::Iterator { + fn iter_prefix(k1: impl EncodeLike) -> Self::PrefixIterator { let prefix = G::storage_double_map_final_key1(k1); - Self::Iterator { + Self::PrefixIterator { prefix: prefix.clone(), previous_key: prefix, drain: false, - _phantom: Default::default(), + closure: |raw_key_without_prefix, mut raw_value| { + let mut key_material = G::Hasher2::reverse(raw_key_without_prefix); + Ok((K2::decode(&mut key_material)?, V::decode(&mut raw_value)?)) + }, } } - /// Enumerate all elements in the map. - fn drain(k1: impl EncodeLike) -> Self::Iterator { - let prefix = G::storage_double_map_final_key1(k1); + fn drain_prefix(k1: impl EncodeLike) -> Self::PrefixIterator { + let mut iterator = Self::iter_prefix(k1); + iterator.drain = true; + iterator + } + + fn iter() -> Self::Iterator { + let prefix = G::prefix_hash(); Self::Iterator { prefix: prefix.clone(), previous_key: prefix, - drain: true, - _phantom: Default::default(), + drain: false, + closure: |raw_key_without_prefix, mut raw_value| { + let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); + let k1 = K1::decode(&mut k1_k2_material)?; + let mut k2_material = G::Hasher2::reverse(k1_k2_material); + let k2 = K2::decode(&mut k2_material)?; + Ok((k1, k2, V::decode(&mut raw_value)?)) + }, } } + fn drain() -> Self::Iterator { + let mut iterator = Self::iter(); + iterator.drain = true; + iterator + } + fn translate Option>(f: F) { let prefix = G::prefix_hash(); let mut previous_key = prefix.clone(); @@ -431,33 +457,111 @@ impl< } } +/// Test iterators for StorageDoubleMap #[cfg(test)] -mod test { - use sp_io::TestExternalities; - use crate::storage::{self, StorageDoubleMap}; - use crate::hash::Twox128; +#[allow(dead_code)] +mod test_iterators { + use codec::{Encode, Decode}; + use crate::storage::{generator::StorageDoubleMap, IterableStorageDoubleMap, unhashed}; + + pub trait Trait { + type Origin; + type BlockNumber; + } + + crate::decl_module! { + pub struct Module for enum Call where origin: T::Origin {} + } + + #[derive(PartialEq, Eq, Clone, Encode, Decode)] + struct NoDef(u32); + + crate::decl_storage! { + trait Store for Module as Test { + DoubleMap: double_map hasher(blake2_128_concat) u16, hasher(blake2_128_concat) u32 => u64; + } + } + + fn key_before_prefix(mut prefix: Vec) -> Vec { + let last = prefix.iter_mut().last().unwrap(); + assert!(*last != 0, "mock function not implemented for this prefix"); + *last -= 1; + prefix + } + + fn key_after_prefix(mut prefix: Vec) -> Vec { + let last = prefix.iter_mut().last().unwrap(); + assert!(*last != 255, "mock function not implemented for this prefix"); + *last += 1; + prefix + } + + fn key_in_prefix(mut prefix: Vec) -> Vec { + prefix.push(0); + prefix + } #[test] - fn iter_prefix_works() { - TestExternalities::default().execute_with(|| { - struct MyStorage; - impl storage::generator::StorageDoubleMap for MyStorage { - type Query = Option; - fn module_prefix() -> &'static [u8] { b"MyModule" } - fn storage_prefix() -> &'static [u8] { b"MyStorage" } - type Hasher1 = Twox128; - type Hasher2 = Twox128; - fn from_optional_value_to_query(v: Option) -> Self::Query { v } - fn from_query_to_optional_value(v: Self::Query) -> Option { v } + fn double_map_reversible_reversible_iteration() { + sp_io::TestExternalities::default().execute_with(|| { + // All map iterator + let prefix = DoubleMap::prefix_hash(); + + unhashed::put(&key_before_prefix(prefix.clone()), &1u64); + unhashed::put(&key_after_prefix(prefix.clone()), &1u64); + + for i in 0..4 { + DoubleMap::insert(i as u16, i as u32, i as u64); + } + + assert_eq!( + DoubleMap::iter().collect::>(), + vec![(3, 3, 3), (0, 0, 0), (2, 2, 2), (1, 1, 1)], + ); + + assert_eq!( + DoubleMap::iter_values().collect::>(), + vec![3, 0, 2, 1], + ); + + assert_eq!( + DoubleMap::drain().collect::>(), + vec![(3, 3, 3), (0, 0, 0), (2, 2, 2), (1, 1, 1)], + ); + + assert_eq!(DoubleMap::iter().collect::>(), vec![]); + assert_eq!(unhashed::get(&key_before_prefix(prefix.clone())), Some(1u64)); + assert_eq!(unhashed::get(&key_after_prefix(prefix.clone())), Some(1u64)); + + // Prefix iterator + let k1 = 3 << 8; + let prefix = DoubleMap::storage_double_map_final_key1(k1); + + unhashed::put(&key_before_prefix(prefix.clone()), &1u64); + unhashed::put(&key_after_prefix(prefix.clone()), &1u64); + + for i in 0..4 { + DoubleMap::insert(k1, i as u32, i as u64); } - MyStorage::insert(1, 3, 7); - MyStorage::insert(1, 4, 8); - MyStorage::insert(2, 5, 9); - MyStorage::insert(2, 6, 10); + assert_eq!( + DoubleMap::iter_prefix(k1).collect::>(), + vec![(0, 0), (2, 2), (1, 1), (3, 3)], + ); - assert_eq!(MyStorage::iter_prefix(1).collect::>(), vec![7, 8]); - assert_eq!(MyStorage::iter_prefix(2).collect::>(), vec![10, 9]); - }); + assert_eq!( + DoubleMap::iter_prefix_values(k1).collect::>(), + vec![0, 2, 1, 3], + ); + + assert_eq!( + DoubleMap::drain_prefix(k1).collect::>(), + vec![(0, 0), (2, 2), (1, 1), (3, 3)], + ); + + assert_eq!(DoubleMap::iter_prefix(k1).collect::>(), vec![]); + assert_eq!(unhashed::get(&key_before_prefix(prefix.clone())), Some(1u64)); + assert_eq!(unhashed::get(&key_after_prefix(prefix.clone())), Some(1u64)); + }) } } diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index efec36b540..47201e22e6 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -240,18 +240,29 @@ pub trait IterableStorageDoubleMap< K2: FullCodec, V: FullCodec >: StorageDoubleMap { - /// The type that iterates over all `(key, value)`. - type Iterator: Iterator; + /// The type that iterates over all `(key2, value)`. + type PrefixIterator: Iterator; + + /// The type that iterates over all `(key1, key2, value)`. + type Iterator: Iterator; /// Enumerate all elements in the map with first key `k1` in no particular order. If you add or /// remove values whose first key is `k1` to the map while doing this, you'll get undefined /// results. - fn iter(k1: impl EncodeLike) -> Self::Iterator; + fn iter_prefix(k1: impl EncodeLike) -> Self::PrefixIterator; /// Remove all elements from the map with first key `k1` and iterate through them in no /// particular order. If you add elements with first key `k1` to the map while doing this, /// you'll get undefined results. - fn drain(k1: impl EncodeLike) -> Self::Iterator; + fn drain_prefix(k1: impl EncodeLike) -> Self::PrefixIterator; + + /// Enumerate all elements in the map in no particular order. If you add or remove values to + /// the map while doing this, you'll get undefined results. + fn iter() -> Self::Iterator; + + /// Remove all elements from the map and iterate through them in no particular order. If you + /// add elements to the map while doing this, you'll get undefined results. + fn drain() -> Self::Iterator; /// Translate the values of all elements by a function `f`, in the map in no particular order. /// By returning `None` from `f` for an element, you'll remove it from the map. @@ -310,7 +321,7 @@ pub trait StorageDoubleMap { fn remove_prefix(k1: KArg1) where KArg1: ?Sized + EncodeLike; - fn iter_prefix(k1: KArg1) -> PrefixIterator + fn iter_prefix_values(k1: KArg1) -> PrefixIterator where KArg1: ?Sized + EncodeLike; fn mutate(k1: KArg1, k2: KArg2, f: F) -> R -- GitLab From 619b454c3ccf7b5d35bfaf8eea3df00084ee1272 Mon Sep 17 00:00:00 2001 From: cheme Date: Wed, 15 Apr 2020 16:56:26 +0200 Subject: [PATCH 232/300] Retain compatibility with network protocol. --- client/network/src/protocol.rs | 28 +++++-- client/network/src/protocol/message.rs | 106 +++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 8 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 84b913b284..9b55cc8d6a 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -38,7 +38,7 @@ use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, NumberFor, One, Zero, CheckedSub }; use sp_arithmetic::traits::SaturatedConversion; -use message::{BlockAnnounce, Message}; +use message::{BlockAnnounce, Message, MessageV6}; use message::generic::{Message as GenericMessage, ConsensusMessage, Roles}; use prometheus_endpoint::{Registry, Gauge, GaugeVec, HistogramVec, PrometheusError, Opts, register, U64}; use sync::{ChainSync, SyncState}; @@ -91,7 +91,7 @@ const MAX_KNOWN_BLOCKS: usize = 1024; // ~32kb per peer + LruHashSet overhead const MAX_KNOWN_EXTRINSICS: usize = 4096; // ~128kb per peer + overhead /// Current protocol version. -pub(crate) const CURRENT_VERSION: u32 = 6; +pub(crate) const CURRENT_VERSION: u32 = 7; /// Lowest version we support pub(crate) const MIN_VERSION: u32 = 3; @@ -524,12 +524,24 @@ impl Protocol { data: BytesMut, ) -> CustomMessageOutcome { - let message = match as Decode>::decode(&mut &data[..]) { - Ok(message) => message, - Err(err) => { - debug!(target: "sync", "Couldn't decode packet sent by {}: {:?}: {}", who, data, err.what()); - self.peerset_handle.report_peer(who.clone(), rep::BAD_MESSAGE); - return CustomMessageOutcome::None; + let input = &mut &data[..]; + let decoded_result = as Decode>::decode(input); + let all_read = input.is_empty(); + let message = match (all_read, decoded_result) { + (true, Ok(message)) => message, + (false, _) | (_, Err(_)) => match as Decode>::decode(&mut &data[..]) { + Ok(message) => if let Some(message) = message.into_latest() { + message + } else { + debug!(target: "sync", "Couldn't call packet sent by {}: {:?}: {}", who, data, "Invalid input."); + self.peerset_handle.report_peer(who.clone(), rep::BAD_MESSAGE); + return CustomMessageOutcome::None; + }, + Err(err) => { + debug!(target: "sync", "Couldn't decode packet sent by {}: {:?}: {}", who, data, err.what()); + self.peerset_handle.report_peer(who.clone(), rep::BAD_MESSAGE); + return CustomMessageOutcome::None; + } } }; diff --git a/client/network/src/protocol/message.rs b/client/network/src/protocol/message.rs index 8638e9afc5..bc9d0f79fa 100644 --- a/client/network/src/protocol/message.rs +++ b/client/network/src/protocol/message.rs @@ -25,6 +25,7 @@ pub use self::generic::{ RemoteChangesRequest, RemoteChangesResponse, FinalityProofRequest, FinalityProofResponse, FromBlock, RemoteReadChildRequest, Roles, + RemoteReadChildRequestV6, }; use sc_client_api::StorageProof; @@ -39,6 +40,17 @@ pub type Message = generic::Message< ::Extrinsic, >; +/// Type alias for using the message type using block type parameters. +/// +/// This could be removed as soon as MIN_VERSION switch to 7. +pub type MessageV6 = generic::MessageV6< + ::Header, + ::Hash, + <::Header as HeaderT>::Number, + ::Extrinsic, +>; + + /// Type alias for using the status type using block type parameters. pub type Status = generic::Status< ::Hash, @@ -237,6 +249,49 @@ pub mod generic { Number(Number), } + /// A protocol V6 network message, this is only for backward compatibility. + /// It should only be use when we fail to decode a message + /// with the latest encoding. + #[derive(Decode)] + pub enum MessageV6 { + /// Status packet. + Status(Status), + /// Block request. + BlockRequest(BlockRequest), + /// Block response. + BlockResponse(BlockResponse), + /// Block announce. + BlockAnnounce(BlockAnnounce

), + /// Transactions. + Transactions(Transactions), + /// Consensus protocol message. + Consensus(ConsensusMessage), + /// Remote method call request. + RemoteCallRequest(RemoteCallRequest), + /// Remote method call response. + RemoteCallResponse(RemoteCallResponse), + /// Remote storage read request. + RemoteReadRequest(RemoteReadRequest), + /// Remote storage read response. + RemoteReadResponse(RemoteReadResponse), + /// Remote header request. + RemoteHeaderRequest(RemoteHeaderRequest), + /// Remote header response. + RemoteHeaderResponse(RemoteHeaderResponse
), + /// Remote changes request. + RemoteChangesRequest(RemoteChangesRequest), + /// Remote changes response. + RemoteChangesResponse(RemoteChangesResponse), + /// Remote child storage read request. + RemoteReadChildRequest(RemoteReadChildRequestV6), + /// Finality proof request. + FinalityProofRequest(FinalityProofRequest), + /// Finality proof response. + FinalityProofResponse(FinalityProofResponse), + /// Batch of consensus protocol messages. + ConsensusBatch(Vec), + } + /// A network message. #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub enum Message { @@ -278,6 +333,39 @@ pub mod generic { ConsensusBatch(Vec), } + impl MessageV6 { + /// Get matching latest protocol message for a protocol V6 message. + /// + /// Note that this function expect that V6 message are only created + /// after a failed latest message decoding, so we do only convert for diverging + /// decoding path. + pub fn into_latest(self) -> Option> { + match self { + MessageV6::RemoteReadChildRequest(RemoteReadChildRequestV6 { + id, + block, + storage_key, + child_info: _, + child_type, + keys, + }) => { + // V6 protocol only got implementation for child type 1. + if child_type != 1 { + None + } else { + Some(Message::RemoteReadChildRequest(RemoteReadChildRequest { + id, + block, + storage_key, + keys, + })) + } + }, + _ => None, + } + } + } + impl Message { /// Message id useful for logging. pub fn id(&self) -> &'static str { @@ -468,6 +556,24 @@ pub mod generic { pub keys: Vec>, } + #[derive(Decode)] + /// Backward compatibility remote storage read child request. + pub struct RemoteReadChildRequestV6 { + /// Unique request id. + pub id: RequestId, + /// Block at which to perform call. + pub block: H, + /// Child Storage key. + pub storage_key: Vec, + /// Child trie source information. + pub child_info: Vec, + /// Child type, its required to resolve `child_info` + /// content and choose child implementation. + pub child_type: u32, + /// Storage key. + pub keys: Vec>, + } + #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] /// Remote storage read child request. pub struct RemoteReadChildRequest { -- GitLab From fa52a8c43105e1052e039368ad66e291ca850c84 Mon Sep 17 00:00:00 2001 From: cheme Date: Wed, 15 Apr 2020 17:16:29 +0200 Subject: [PATCH 233/300] Revert "Retain compatibility with network protocol." This reverts commit 619b454c3ccf7b5d35bfaf8eea3df00084ee1272. --- client/network/src/protocol.rs | 28 ++----- client/network/src/protocol/message.rs | 106 ------------------------- 2 files changed, 8 insertions(+), 126 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 9b55cc8d6a..84b913b284 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -38,7 +38,7 @@ use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, NumberFor, One, Zero, CheckedSub }; use sp_arithmetic::traits::SaturatedConversion; -use message::{BlockAnnounce, Message, MessageV6}; +use message::{BlockAnnounce, Message}; use message::generic::{Message as GenericMessage, ConsensusMessage, Roles}; use prometheus_endpoint::{Registry, Gauge, GaugeVec, HistogramVec, PrometheusError, Opts, register, U64}; use sync::{ChainSync, SyncState}; @@ -91,7 +91,7 @@ const MAX_KNOWN_BLOCKS: usize = 1024; // ~32kb per peer + LruHashSet overhead const MAX_KNOWN_EXTRINSICS: usize = 4096; // ~128kb per peer + overhead /// Current protocol version. -pub(crate) const CURRENT_VERSION: u32 = 7; +pub(crate) const CURRENT_VERSION: u32 = 6; /// Lowest version we support pub(crate) const MIN_VERSION: u32 = 3; @@ -524,24 +524,12 @@ impl Protocol { data: BytesMut, ) -> CustomMessageOutcome { - let input = &mut &data[..]; - let decoded_result = as Decode>::decode(input); - let all_read = input.is_empty(); - let message = match (all_read, decoded_result) { - (true, Ok(message)) => message, - (false, _) | (_, Err(_)) => match as Decode>::decode(&mut &data[..]) { - Ok(message) => if let Some(message) = message.into_latest() { - message - } else { - debug!(target: "sync", "Couldn't call packet sent by {}: {:?}: {}", who, data, "Invalid input."); - self.peerset_handle.report_peer(who.clone(), rep::BAD_MESSAGE); - return CustomMessageOutcome::None; - }, - Err(err) => { - debug!(target: "sync", "Couldn't decode packet sent by {}: {:?}: {}", who, data, err.what()); - self.peerset_handle.report_peer(who.clone(), rep::BAD_MESSAGE); - return CustomMessageOutcome::None; - } + let message = match as Decode>::decode(&mut &data[..]) { + Ok(message) => message, + Err(err) => { + debug!(target: "sync", "Couldn't decode packet sent by {}: {:?}: {}", who, data, err.what()); + self.peerset_handle.report_peer(who.clone(), rep::BAD_MESSAGE); + return CustomMessageOutcome::None; } }; diff --git a/client/network/src/protocol/message.rs b/client/network/src/protocol/message.rs index bc9d0f79fa..8638e9afc5 100644 --- a/client/network/src/protocol/message.rs +++ b/client/network/src/protocol/message.rs @@ -25,7 +25,6 @@ pub use self::generic::{ RemoteChangesRequest, RemoteChangesResponse, FinalityProofRequest, FinalityProofResponse, FromBlock, RemoteReadChildRequest, Roles, - RemoteReadChildRequestV6, }; use sc_client_api::StorageProof; @@ -40,17 +39,6 @@ pub type Message = generic::Message< ::Extrinsic, >; -/// Type alias for using the message type using block type parameters. -/// -/// This could be removed as soon as MIN_VERSION switch to 7. -pub type MessageV6 = generic::MessageV6< - ::Header, - ::Hash, - <::Header as HeaderT>::Number, - ::Extrinsic, ->; - - /// Type alias for using the status type using block type parameters. pub type Status = generic::Status< ::Hash, @@ -249,49 +237,6 @@ pub mod generic { Number(Number), } - /// A protocol V6 network message, this is only for backward compatibility. - /// It should only be use when we fail to decode a message - /// with the latest encoding. - #[derive(Decode)] - pub enum MessageV6 { - /// Status packet. - Status(Status), - /// Block request. - BlockRequest(BlockRequest), - /// Block response. - BlockResponse(BlockResponse), - /// Block announce. - BlockAnnounce(BlockAnnounce
), - /// Transactions. - Transactions(Transactions), - /// Consensus protocol message. - Consensus(ConsensusMessage), - /// Remote method call request. - RemoteCallRequest(RemoteCallRequest), - /// Remote method call response. - RemoteCallResponse(RemoteCallResponse), - /// Remote storage read request. - RemoteReadRequest(RemoteReadRequest), - /// Remote storage read response. - RemoteReadResponse(RemoteReadResponse), - /// Remote header request. - RemoteHeaderRequest(RemoteHeaderRequest), - /// Remote header response. - RemoteHeaderResponse(RemoteHeaderResponse
), - /// Remote changes request. - RemoteChangesRequest(RemoteChangesRequest), - /// Remote changes response. - RemoteChangesResponse(RemoteChangesResponse), - /// Remote child storage read request. - RemoteReadChildRequest(RemoteReadChildRequestV6), - /// Finality proof request. - FinalityProofRequest(FinalityProofRequest), - /// Finality proof response. - FinalityProofResponse(FinalityProofResponse), - /// Batch of consensus protocol messages. - ConsensusBatch(Vec), - } - /// A network message. #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub enum Message { @@ -333,39 +278,6 @@ pub mod generic { ConsensusBatch(Vec), } - impl MessageV6 { - /// Get matching latest protocol message for a protocol V6 message. - /// - /// Note that this function expect that V6 message are only created - /// after a failed latest message decoding, so we do only convert for diverging - /// decoding path. - pub fn into_latest(self) -> Option> { - match self { - MessageV6::RemoteReadChildRequest(RemoteReadChildRequestV6 { - id, - block, - storage_key, - child_info: _, - child_type, - keys, - }) => { - // V6 protocol only got implementation for child type 1. - if child_type != 1 { - None - } else { - Some(Message::RemoteReadChildRequest(RemoteReadChildRequest { - id, - block, - storage_key, - keys, - })) - } - }, - _ => None, - } - } - } - impl Message { /// Message id useful for logging. pub fn id(&self) -> &'static str { @@ -556,24 +468,6 @@ pub mod generic { pub keys: Vec>, } - #[derive(Decode)] - /// Backward compatibility remote storage read child request. - pub struct RemoteReadChildRequestV6 { - /// Unique request id. - pub id: RequestId, - /// Block at which to perform call. - pub block: H, - /// Child Storage key. - pub storage_key: Vec, - /// Child trie source information. - pub child_info: Vec, - /// Child type, its required to resolve `child_info` - /// content and choose child implementation. - pub child_type: u32, - /// Storage key. - pub keys: Vec>, - } - #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] /// Remote storage read child request. pub struct RemoteReadChildRequest { -- GitLab From 447c6c93c8a0080967437adf5a111117c05d4705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Wed, 15 Apr 2020 20:49:21 +0100 Subject: [PATCH 234/300] client: avoid spamming telemetry on initial sync (#5651) --- Cargo.lock | 1 + client/Cargo.toml | 1 + client/src/client.rs | 19 ++++++++++++++----- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 37aeca5892..5746491431 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5905,6 +5905,7 @@ dependencies = [ "log", "parity-scale-codec", "parking_lot 0.10.2", + "rand 0.7.3", "sc-block-builder", "sc-client-api", "sc-executor", diff --git a/client/Cargo.toml b/client/Cargo.toml index bf93cdfde8..a28418b9a2 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -28,6 +28,7 @@ sp-keyring = { version = "2.0.0-dev", path = "../primitives/keyring" } kvdb = "0.5.0" log = { version = "0.4.8" } parking_lot = "0.10.0" +rand = "0.7.3" sp-core = { version = "2.0.0-dev", path = "../primitives/core" } sp-std = { version = "2.0.0-dev", path = "../primitives/std" } sp-version = { version = "2.0.0-dev", path = "../primitives/version" } diff --git a/client/src/client.rs b/client/src/client.rs index 34f4ffbb8d..a71d6bf964 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -613,11 +613,20 @@ impl Client where if let Ok(ImportResult::Imported(ref aux)) = result { if aux.is_new_best { - telemetry!(SUBSTRATE_INFO; "block.import"; - "height" => height, - "best" => ?hash, - "origin" => ?origin - ); + use rand::Rng; + + // don't send telemetry block import events during initial sync for every + // block to avoid spamming the telemetry server, these events will be randomly + // sent at a rate of 1/10. + if origin != BlockOrigin::NetworkInitialSync || + rand::thread_rng().gen_bool(0.1) + { + telemetry!(SUBSTRATE_INFO; "block.import"; + "height" => height, + "best" => ?hash, + "origin" => ?origin + ); + } } } -- GitLab From 2b988996d0316d2b62d25dcdfc4b561f08c586bc Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 15 Apr 2020 21:49:53 +0200 Subject: [PATCH 235/300] Remove the tokio thread name (#5650) --- client/cli/src/runner.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/client/cli/src/runner.rs b/client/cli/src/runner.rs index c2c4f9739d..6ebe84f9c5 100644 --- a/client/cli/src/runner.rs +++ b/client/cli/src/runner.rs @@ -80,7 +80,6 @@ where /// Build a tokio runtime with all features pub fn build_runtime() -> std::result::Result { tokio::runtime::Builder::new() - .thread_name("main-tokio-") .threaded_scheduler() .on_thread_start(||{ TOKIO_THREADS_ALIVE.inc(); -- GitLab From c5467053536c2efcbce25ef06e1a984f8ee77641 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 15 Apr 2020 23:27:33 +0200 Subject: [PATCH 236/300] Temporarily increase notifications buffer size (#5644) * Temporarily increase notifications buffer size * Add a 511.0 bucket --- .../network/src/protocol/generic_proto/upgrade/notifications.rs | 2 +- client/network/src/service.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/network/src/protocol/generic_proto/upgrade/notifications.rs b/client/network/src/protocol/generic_proto/upgrade/notifications.rs index f626110a33..cf271016e7 100644 --- a/client/network/src/protocol/generic_proto/upgrade/notifications.rs +++ b/client/network/src/protocol/generic_proto/upgrade/notifications.rs @@ -44,7 +44,7 @@ use unsigned_varint::codec::UviBytes; /// Maximum allowed size of the two handshake messages, in bytes. const MAX_HANDSHAKE_SIZE: usize = 1024; /// Maximum number of buffered messages before we refuse to accept more. -const MAX_PENDING_MESSAGES: usize = 256; +const MAX_PENDING_MESSAGES: usize = 512; /// Upgrade that accepts a substream, sends back a status message, then becomes a unidirectional /// stream of messages. diff --git a/client/network/src/service.rs b/client/network/src/service.rs index b099a5dabf..049ca4273d 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -937,7 +937,7 @@ impl Metrics { "sub_libp2p_notifications_queues_size", "Total size of all the notification queues" ), - buckets: vec![0.0, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0], + buckets: vec![0.0, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 511.0, 512.0], }, &["protocol"] )?, registry)?, -- GitLab From 9209998bf65890db74c4e9be20813a18d5287b79 Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Thu, 16 Apr 2020 00:39:24 +0200 Subject: [PATCH 237/300] change (ci): stop using CARGO_HOME cache until the bug resolves (#5653) --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2c141c51d1..a98819ef2b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -32,7 +32,6 @@ stages: variables: GIT_STRATEGY: fetch GIT_DEPTH: 100 - CARGO_HOME: "/ci-cache/${CI_PROJECT_NAME}/cargo/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME}" SCCACHE_DIR: "/ci-cache/${CI_PROJECT_NAME}/sccache" CARGO_INCREMENTAL: 0 CI_SERVER_NAME: "GitLab CI" -- GitLab From 6dc23feece77d758656651e04de964d72e9b5d34 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 16 Apr 2020 10:42:08 +0200 Subject: [PATCH 238/300] client/authority-discovery: Increase request counter per request (#5632) --- client/authority-discovery/src/lib.rs | 104 +++++++++++++------------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/client/authority-discovery/src/lib.rs b/client/authority-discovery/src/lib.rs index 956e970f26..8086cd959d 100644 --- a/client/authority-discovery/src/lib.rs +++ b/client/authority-discovery/src/lib.rs @@ -87,53 +87,6 @@ const LIBP2P_KADEMLIA_BOOTSTRAP_TIME: Duration = Duration::from_secs(30); /// discovery module. const AUTHORITIES_PRIORITY_GROUP_NAME: &'static str = "authorities"; -/// Prometheus metrics for an `AuthorityDiscovery`. -#[derive(Clone)] -pub(crate) struct Metrics { - publish: Counter, - amount_last_published: Gauge, - request: Counter, - dht_event_received: CounterVec, -} - -impl Metrics { - pub(crate) fn register(registry: &prometheus_endpoint::Registry) -> Result { - Ok(Self { - publish: register( - Counter::new( - "authority_discovery_times_published_total", - "Number of times authority discovery has published external addresses." - )?, - registry, - )?, - amount_last_published: register( - Gauge::new( - "authority_discovery_amount_external_addresses_last_published", - "Number of external addresses published when authority discovery last published addresses ." - )?, - registry, - )?, - request: register( - Counter::new( - "authority_discovery_times_requested_total", - "Number of times authority discovery has requested external addresses." - )?, - registry, - )?, - dht_event_received: register( - CounterVec::new( - Opts::new( - "authority_discovery_dht_event_received", - "Number of dht events received by authority discovery." - ), - &["name"], - )?, - registry, - )?, - }) - } -} - /// An `AuthorityDiscovery` makes a given authority discoverable and discovers other authorities. pub struct AuthorityDiscovery where @@ -309,10 +262,6 @@ where } fn request_addresses_of_others(&mut self) -> Result<()> { - if let Some(metrics) = &self.metrics { - metrics.request.inc(); - } - let id = BlockId::hash(self.client.info().best_hash); let authorities = self @@ -322,6 +271,10 @@ where .map_err(Error::CallingRuntime)?; for authority_id in authorities.iter() { + if let Some(metrics) = &self.metrics { + metrics.request.inc(); + } + self.network .get_value(&hash_authority_id(authority_id.as_ref())); } @@ -605,3 +558,52 @@ fn interval_at(start: Instant, duration: Duration) -> Interval { Box::new(stream) } + +/// Prometheus metrics for an `AuthorityDiscovery`. +#[derive(Clone)] +pub(crate) struct Metrics { + publish: Counter, + amount_last_published: Gauge, + request: Counter, + dht_event_received: CounterVec, +} + +impl Metrics { + pub(crate) fn register(registry: &prometheus_endpoint::Registry) -> Result { + Ok(Self { + publish: register( + Counter::new( + "authority_discovery_times_published_total", + "Number of times authority discovery has published external addresses." + )?, + registry, + )?, + amount_last_published: register( + Gauge::new( + "authority_discovery_amount_external_addresses_last_published", + "Number of external addresses published when authority discovery last \ + published addresses." + )?, + registry, + )?, + request: register( + Counter::new( + "authority_discovery_authority_addresses_requested_total", + "Number of times authority discovery has requested external addresses of a \ + single authority." + )?, + registry, + )?, + dht_event_received: register( + CounterVec::new( + Opts::new( + "authority_discovery_dht_event_received", + "Number of dht events received by authority discovery." + ), + &["name"], + )?, + registry, + )?, + }) + } +} -- GitLab From 2051ecbf79ed6a7262e8da1bfd97be4a423b9bcd Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Thu, 16 Apr 2020 10:43:18 +0200 Subject: [PATCH 239/300] Weights to u64 + Balances Weights (#5446) Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- Cargo.lock | 8 +- bin/node-template/pallets/template/src/lib.rs | 5 +- .../pallets/template/src/mock.rs | 1 + bin/node-template/runtime/src/lib.rs | 5 +- bin/node/executor/tests/basic.rs | 16 +- bin/node/executor/tests/fees.rs | 8 +- bin/node/executor/tests/submit_transaction.rs | 2 +- bin/node/runtime/src/impls.rs | 178 ++++++++++-------- bin/node/runtime/src/lib.rs | 17 +- frame/assets/src/lib.rs | 8 +- frame/aura/src/mock.rs | 1 + frame/authority-discovery/src/lib.rs | 1 + frame/authorship/src/lib.rs | 7 +- frame/babe/src/lib.rs | 4 +- frame/babe/src/mock.rs | 1 + frame/balances/src/lib.rs | 15 +- frame/balances/src/tests.rs | 4 +- frame/balances/src/tests_composite.rs | 1 + frame/balances/src/tests_local.rs | 1 + frame/benchmark/src/lib.rs | 27 +-- frame/benchmarking/src/tests.rs | 10 +- frame/collective/src/lib.rs | 11 +- frame/contracts/src/lib.rs | 11 +- frame/contracts/src/tests.rs | 1 + frame/democracy/src/lib.rs | 62 +++--- frame/democracy/src/tests.rs | 1 + frame/elections-phragmen/src/lib.rs | 19 +- frame/elections/src/lib.rs | 24 +-- frame/elections/src/mock.rs | 1 + frame/evm/src/lib.rs | 12 +- frame/example-offchain-worker/src/lib.rs | 6 +- frame/example-offchain-worker/src/tests.rs | 12 +- frame/example/src/lib.rs | 10 +- frame/executive/src/lib.rs | 1 + frame/finality-tracker/src/lib.rs | 4 +- frame/generic-asset/src/lib.rs | 14 +- frame/generic-asset/src/mock.rs | 1 + frame/grandpa/src/lib.rs | 3 +- frame/grandpa/src/mock.rs | 1 + frame/identity/src/lib.rs | 25 +-- frame/im-online/src/lib.rs | 6 +- frame/im-online/src/mock.rs | 1 + frame/indices/src/lib.rs | 12 +- frame/indices/src/mock.rs | 1 + frame/membership/src/lib.rs | 15 +- frame/nicks/src/lib.rs | 9 +- frame/offences/src/lib.rs | 6 +- frame/offences/src/mock.rs | 1 + frame/randomness-collective-flip/src/lib.rs | 9 +- frame/recovery/src/lib.rs | 18 +- frame/recovery/src/mock.rs | 1 + frame/scheduler/src/lib.rs | 1 + frame/scored-pool/src/lib.rs | 17 +- frame/scored-pool/src/mock.rs | 1 + frame/session/benchmarking/src/mock.rs | 1 + frame/session/src/lib.rs | 8 +- frame/session/src/mock.rs | 1 + frame/society/src/lib.rs | 28 +-- frame/society/src/mock.rs | 1 + frame/staking/src/lib.rs | 53 +++--- frame/staking/src/mock.rs | 1 + frame/sudo/src/lib.rs | 7 +- frame/support/src/dispatch.rs | 33 ++-- frame/support/src/error.rs | 4 +- frame/support/src/metadata.rs | 4 +- frame/support/src/weights.rs | 84 +++++++-- frame/support/test/tests/decl_error.rs | 5 +- frame/support/test/tests/instance.rs | 3 +- .../tests/reserved_keyword/on_initialize.rs | 4 +- frame/system/benches/bench.rs | 1 + frame/system/src/lib.rs | 28 +-- frame/timestamp/src/lib.rs | 8 +- frame/transaction-payment/src/lib.rs | 20 +- frame/treasury/src/lib.rs | 20 +- frame/treasury/src/tests.rs | 1 + frame/utility/src/lib.rs | 8 +- frame/utility/src/tests.rs | 1 + frame/vesting/src/lib.rs | 9 +- primitives/arithmetic/src/fixed128.rs | 62 +++++- primitives/arithmetic/src/fixed64.rs | 21 ++- primitives/runtime/src/lib.rs | 4 +- test-utils/runtime/src/lib.rs | 7 +- 82 files changed, 636 insertions(+), 428 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5746491431..1c1a009425 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4943,18 +4943,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c" +checksum = "6f6a7f5eee6292c559c793430c55c00aea9d3b3d1905e855806ca4d7253426a2" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" +checksum = "8988430ce790d8682672117bc06dda364c0be32d3abd738234f19f3240bad99a" dependencies = [ "proc-macro2", "quote 1.0.3", diff --git a/bin/node-template/pallets/template/src/lib.rs b/bin/node-template/pallets/template/src/lib.rs index a0daecfb72..adddbac21b 100644 --- a/bin/node-template/pallets/template/src/lib.rs +++ b/bin/node-template/pallets/template/src/lib.rs @@ -10,6 +10,7 @@ /// https://github.com/paritytech/substrate/blob/master/frame/example/src/lib.rs use frame_support::{decl_module, decl_storage, decl_event, decl_error, dispatch}; +use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; use frame_system::{self as system, ensure_signed}; #[cfg(test)] @@ -75,7 +76,7 @@ decl_module! { /// Just a dummy entry point. /// function that can be called by the external world as an extrinsics call /// takes a parameter of the type `AccountId`, stores it, and emits an event - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn do_something(origin, something: u32) -> dispatch::DispatchResult { // Check it was signed and get the signer. See also: ensure_root and ensure_none let who = ensure_signed(origin)?; @@ -91,7 +92,7 @@ decl_module! { /// Another dummy entry point. /// takes no parameters, attempts to increment storage value, and possibly throws an error - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn cause_error(origin) -> dispatch::DispatchResult { // Check it was signed and get the signer. See also: ensure_root and ensure_none let _who = ensure_signed(origin)?; diff --git a/bin/node-template/pallets/template/src/mock.rs b/bin/node-template/pallets/template/src/mock.rs index a93ac0359e..fdabf7d03a 100644 --- a/bin/node-template/pallets/template/src/mock.rs +++ b/bin/node-template/pallets/template/src/mock.rs @@ -36,6 +36,7 @@ impl system::Trait for Test { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 94f033fd8f..6238ffda1a 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -120,7 +120,8 @@ pub fn native_version() -> NativeVersion { parameter_types! { pub const BlockHashCount: BlockNumber = 250; - pub const MaximumBlockWeight: Weight = 1_000_000_000; + /// We allow for 2 seconds of compute with a 6 second average block time. + pub const MaximumBlockWeight: Weight = 2_000_000_000_000; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; pub const Version: RuntimeVersion = VERSION; @@ -151,6 +152,8 @@ impl system::Trait for Runtime { type BlockHashCount = BlockHashCount; /// Maximum weight of each block. type MaximumBlockWeight = MaximumBlockWeight; + /// The weight of database operations that the runtime can invoke. + type DbWeight = (); /// Maximum size of all encoded transactions (in bytes) that are allowed in one block. type MaximumBlockLength = MaximumBlockLength; /// Portion of the block weight that is available to all normal transactions. diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index bab3dfa0ae..7fdf4e9c59 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -24,7 +24,7 @@ use sp_core::{ NeverNativeValue, map, traits::Externalities, storage::{well_known_keys, Storage}, }; use sp_runtime::{ - ApplyExtrinsicResult, Fixed64, + ApplyExtrinsicResult, Fixed128, traits::{Hash as HashT, Convert, BlakeTwo256}, transaction_validity::InvalidTransaction, }; @@ -51,7 +51,7 @@ use self::common::{*, sign}; pub const BLOATY_CODE: &[u8] = node_runtime::WASM_BINARY_BLOATY; /// Default transfer fee -fn transfer_fee(extrinsic: &E, fee_multiplier: Fixed64) -> Balance { +fn transfer_fee(extrinsic: &E, fee_multiplier: Fixed128) -> Balance { let length_fee = TransactionByteFee::get() * (extrinsic.encode().len() as Balance); let weight = default_transfer_call().get_dispatch_info().weight; @@ -338,7 +338,7 @@ fn full_native_block_import_works() { EventRecord { phase: Phase::ApplyExtrinsic(0), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 10000, class: DispatchClass::Mandatory, pays_fee: true } + DispatchInfo { weight: 10_000_000, class: DispatchClass::Mandatory, pays_fee: true } )), topics: vec![], }, @@ -359,7 +359,7 @@ fn full_native_block_import_works() { EventRecord { phase: Phase::ApplyExtrinsic(1), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 1000000, class: DispatchClass::Normal, pays_fee: true } + DispatchInfo { weight: 200_000_000, class: DispatchClass::Normal, pays_fee: true } )), topics: vec![], }, @@ -391,7 +391,7 @@ fn full_native_block_import_works() { EventRecord { phase: Phase::ApplyExtrinsic(0), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 10000, class: DispatchClass::Mandatory, pays_fee: true } + DispatchInfo { weight: 10_000_000, class: DispatchClass::Mandatory, pays_fee: true } )), topics: vec![], }, @@ -414,7 +414,7 @@ fn full_native_block_import_works() { EventRecord { phase: Phase::ApplyExtrinsic(1), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 1000000, class: DispatchClass::Normal, pays_fee: true } + DispatchInfo { weight: 200_000_000, class: DispatchClass::Normal, pays_fee: true } )), topics: vec![], }, @@ -437,7 +437,7 @@ fn full_native_block_import_works() { EventRecord { phase: Phase::ApplyExtrinsic(2), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 1000000, class: DispatchClass::Normal, pays_fee: true } + DispatchInfo { weight: 200_000_000, class: DispatchClass::Normal, pays_fee: true } )), topics: vec![], }, @@ -817,5 +817,3 @@ fn should_import_block_with_test_client() { client.import(BlockOrigin::Own, block).unwrap(); } - - diff --git a/bin/node/executor/tests/fees.rs b/bin/node/executor/tests/fees.rs index ea9d740a05..32fef3b326 100644 --- a/bin/node/executor/tests/fees.rs +++ b/bin/node/executor/tests/fees.rs @@ -21,7 +21,7 @@ use frame_support::{ weights::GetDispatchInfo, }; use sp_core::{NeverNativeValue, map, storage::Storage}; -use sp_runtime::{Fixed64, Perbill, traits::{Convert, BlakeTwo256}}; +use sp_runtime::{Fixed128, Perbill, traits::{Convert, BlakeTwo256}}; use node_runtime::{ CheckedExtrinsic, Call, Runtime, Balances, TransactionPayment, TransactionBaseFee, TransactionByteFee, WeightFeeCoefficient, @@ -39,7 +39,7 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() { let mut t = new_test_ext(COMPACT_CODE, false); // initial fee multiplier must be zero - let mut prev_multiplier = Fixed64::from_parts(0); + let mut prev_multiplier = Fixed128::from_parts(0); t.execute_with(|| { assert_eq!(TransactionPayment::next_fee_multiplier(), prev_multiplier); @@ -188,7 +188,9 @@ fn transaction_fee_is_correct_ultimate() { let weight_fee = LinearWeightToFee::::convert(weight); // we know that weight to fee multiplier is effect-less in block 1. - assert_eq!(weight_fee as Balance, MILLICENTS); + // current weight of transfer = 200_000_000 + // Linear weight to fee is 1:1 right now (1 weight = 1 unit of balance) + assert_eq!(weight_fee, weight as Balance); balance_alice -= weight_fee; balance_alice -= tip; diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index 536cf486e3..d92f3e3202 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -178,7 +178,7 @@ fn submitted_transaction_should_be_valid() { let res = Executive::validate_transaction(source, extrinsic); assert_eq!(res.unwrap(), ValidTransaction { - priority: 2_411_002_000_000, + priority: 2_410_600_000_000, requires: vec![], provides: vec![(address, 0).encode()], longevity: 128, diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index 646dc24f57..f613dc5af5 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -16,9 +16,10 @@ //! Some configurable implementations as associated type for the substrate runtime. +use core::num::NonZeroI128; use node_primitives::Balance; use sp_runtime::traits::{Convert, Saturating}; -use sp_runtime::{Fixed64, Perbill}; +use sp_runtime::{Fixed128, Perquintill}; use frame_support::{traits::{OnUnbalanced, Currency, Get}, weights::Weight}; use crate::{Balances, System, Authorship, MaximumBlockWeight, NegativeImbalance}; @@ -51,8 +52,7 @@ pub struct LinearWeightToFee(sp_std::marker::PhantomData); impl> Convert for LinearWeightToFee { fn convert(w: Weight) -> Balance { - // substrate-node a weight of 10_000 (smallest non-zero weight) to be mapped to 10^7 units of - // fees, hence: + // setting this to zero will disable the weight fee. let coefficient = C::get(); Balance::from(w).saturating_mul(coefficient) } @@ -60,16 +60,16 @@ impl> Convert for LinearWeightToFee { /// Update the given multiplier based on the following formula /// -/// diff = (previous_block_weight - target_weight) +/// diff = (previous_block_weight - target_weight)/max_weight /// v = 0.00004 -/// next_weight = weight * (1 + (v . diff) + (v . diff)^2 / 2) +/// next_weight = weight * (1 + (v * diff) + (v * diff)^2 / 2) /// /// Where `target_weight` must be given as the `Get` implementation of the `T` generic type. /// https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#relay-chain-transaction-fees pub struct TargetedFeeAdjustment(sp_std::marker::PhantomData); -impl> Convert for TargetedFeeAdjustment { - fn convert(multiplier: Fixed64) -> Fixed64 { +impl> Convert for TargetedFeeAdjustment { + fn convert(multiplier: Fixed128) -> Fixed128 { let block_weight = System::all_extrinsics_weight(); let max_weight = MaximumBlockWeight::get(); let target_weight = (T::get() * max_weight) as u128; @@ -78,19 +78,20 @@ impl> Convert for TargetedFeeAdjustment { // determines if the first_term is positive let positive = block_weight >= target_weight; let diff_abs = block_weight.max(target_weight) - block_weight.min(target_weight); - // diff is within u32, safe. - let diff = Fixed64::from_rational(diff_abs as i64, max_weight as u64); + // safe, diff_abs cannot exceed u64 and it can always be computed safely even with the lossy + // `Fixed128::from_rational`. + let diff = Fixed128::from_rational( + diff_abs as i128, + NonZeroI128::new(max_weight.max(1) as i128).unwrap(), + ); let diff_squared = diff.saturating_mul(diff); // 0.00004 = 4/100_000 = 40_000/10^9 - let v = Fixed64::from_rational(4, 100_000); - // 0.00004^2 = 16/10^10 ~= 2/10^9. Taking the future /2 into account, then it is just 1 - // parts from a billionth. - let v_squared_2 = Fixed64::from_rational(1, 1_000_000_000); + let v = Fixed128::from_rational(4, NonZeroI128::new(100_000).unwrap()); + // 0.00004^2 = 16/10^10 Taking the future /2 into account... 8/10^10 + let v_squared_2 = Fixed128::from_rational(8, NonZeroI128::new(10_000_000_000).unwrap()); let first_term = v.saturating_mul(diff); - // It is very unlikely that this will exist (in our poor perbill estimate) but we are giving - // it a shot. let second_term = v_squared_2.saturating_mul(diff_squared); if positive { @@ -99,15 +100,15 @@ impl> Convert for TargetedFeeAdjustment { let excess = first_term.saturating_add(second_term); multiplier.saturating_add(excess) } else { - // Proof: first_term > second_term. Safe subtraction. - let negative = first_term - second_term; + // Defensive-only: first_term > second_term. Safe subtraction. + let negative = first_term.saturating_sub(second_term); multiplier.saturating_sub(negative) // despite the fact that apply_to saturates weight (final fee cannot go below 0) // it is crucially important to stop here and don't further reduce the weight fee // multiplier. While at -1, it means that the network is so un-congested that all // transactions have no weight fee. We stop here and only increase if the network // became more busy. - .max(Fixed64::from_rational(-1, 1)) + .max(Fixed128::from_natural(-1)) } } } @@ -119,6 +120,7 @@ mod tests { use crate::{MaximumBlockWeight, AvailableBlockRatio, Runtime}; use crate::{constants::currency::*, TransactionPayment, TargetBlockFullness}; use frame_support::weights::Weight; + use core::num::NonZeroI128; fn max() -> Weight { MaximumBlockWeight::get() @@ -129,26 +131,22 @@ mod tests { } // poc reference implementation. - fn fee_multiplier_update(block_weight: Weight, previous: Fixed64) -> Fixed64 { - let block_weight = block_weight as f32; - let v: f32 = 0.00004; + fn fee_multiplier_update(block_weight: Weight, previous: Fixed128) -> Fixed128 { + let block_weight = block_weight as f64; + let v: f64 = 0.00004; // maximum tx weight - let m = max() as f32; + let m = max() as f64; // Ideal saturation in terms of weight - let ss = target() as f32; + let ss = target() as f64; // Current saturation in terms of weight let s = block_weight; let fm = v * (s/m - ss/m) + v.powi(2) * (s/m - ss/m).powi(2) / 2.0; - let addition_fm = Fixed64::from_parts((fm * 1_000_000_000_f32).round() as i64); + let addition_fm = Fixed128::from_parts((fm * Fixed128::accuracy() as f64).round() as i128); previous.saturating_add(addition_fm) } - fn feemul(parts: i64) -> Fixed64 { - Fixed64::from_parts(parts) - } - fn run_with_system_weight(w: Weight, assertions: F) where F: Fn() -> () { let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::default().build_storage::().unwrap().into(); @@ -160,7 +158,7 @@ mod tests { #[test] fn fee_multiplier_update_poc_works() { - let fm = Fixed64::from_rational(0, 1); + let fm = Fixed128::from_rational(0, NonZeroI128::new(1).unwrap()); let test_set = vec![ (0, fm.clone()), (100, fm.clone()), @@ -171,9 +169,10 @@ mod tests { test_set.into_iter().for_each(|(w, fm)| { run_with_system_weight(w, || { assert_eq_error_rate!( - fee_multiplier_update(w, fm).into_inner(), - TargetedFeeAdjustment::::convert(fm).into_inner(), - 5, + fee_multiplier_update(w, fm), + TargetedFeeAdjustment::::convert(fm), + // Error is only 1 in 10^18 + Fixed128::from_parts(1), ); }) }) @@ -184,12 +183,12 @@ mod tests { // just a few txs per_block. let block_weight = 0; run_with_system_weight(block_weight, || { - let mut fm = Fixed64::default(); + let mut fm = Fixed128::default(); let mut iterations: u64 = 0; loop { let next = TargetedFeeAdjustment::::convert(fm); fm = next; - if fm == Fixed64::from_rational(-1, 1) { break; } + if fm == Fixed128::from_natural(-1) { break; } iterations += 1; } println!("iteration {}, new fm = {:?}. Weight fee is now zero", iterations, fm); @@ -217,7 +216,7 @@ mod tests { run_with_system_weight(block_weight, || { // initial value configured on module - let mut fm = Fixed64::default(); + let mut fm = Fixed128::default(); assert_eq!(fm, TransactionPayment::next_fee_multiplier()); let mut iterations: u64 = 0; @@ -245,79 +244,94 @@ mod tests { #[test] fn stateless_weight_mul() { + // This test will show that heavy blocks have a weight multiplier greater than 0 + // and light blocks will have a weight multiplier less than 0. run_with_system_weight(target() / 4, || { - // Light block. Fee is reduced a little. + // `fee_multiplier_update` is enough as it is the absolute truth value. + let next = TargetedFeeAdjustment::::convert(Fixed128::default()); assert_eq!( - TargetedFeeAdjustment::::convert(Fixed64::default()), - feemul(-7500), + next, + fee_multiplier_update(target() / 4 ,Fixed128::default()) ); + + // Light block. Fee is reduced a little. + assert!(next < Fixed128::zero()) }); run_with_system_weight(target() / 2, || { - // a bit more. Fee is decreased less, meaning that the fee increases as the block grows. + let next = TargetedFeeAdjustment::::convert(Fixed128::default()); assert_eq!( - TargetedFeeAdjustment::::convert(Fixed64::default()), - feemul(-5000), + next, + fee_multiplier_update(target() / 2 ,Fixed128::default()) ); + // Light block. Fee is reduced a little. + assert!(next < Fixed128::zero()) + }); run_with_system_weight(target(), || { // ideal. Original fee. No changes. - assert_eq!( - TargetedFeeAdjustment::::convert(Fixed64::default()), - feemul(0), - ); + let next = TargetedFeeAdjustment::::convert(Fixed128::default()); + assert_eq!(next, Fixed128::zero()) }); run_with_system_weight(target() * 2, || { - // // More than ideal. Fee is increased. + // More than ideal. Fee is increased. + let next = TargetedFeeAdjustment::::convert(Fixed128::default()); assert_eq!( - TargetedFeeAdjustment::::convert(Fixed64::default()), - feemul(10000), + next, + fee_multiplier_update(target() * 2 ,Fixed128::default()) ); + + // Heavy block. Fee is increased a little. + assert!(next > Fixed128::zero()) }); } #[test] fn stateful_weight_mul_grow_to_infinity() { run_with_system_weight(target() * 2, || { - assert_eq!( - TargetedFeeAdjustment::::convert(Fixed64::default()), - feemul(10000) - ); - assert_eq!( - TargetedFeeAdjustment::::convert(feemul(10000)), - feemul(20000) - ); - assert_eq!( - TargetedFeeAdjustment::::convert(feemul(20000)), - feemul(30000) - ); - // ... - assert_eq!( - TargetedFeeAdjustment::::convert(feemul(1_000_000_000)), - feemul(1_000_000_000 + 10000) - ); + let mut original = Fixed128::default(); + let mut next = Fixed128::default(); + + (0..1_000).for_each(|_| { + next = TargetedFeeAdjustment::::convert(original); + assert_eq!( + next, + fee_multiplier_update(target() * 2, original), + ); + // must always increase + assert!(next > original); + original = next; + }); }); } #[test] fn stateful_weight_mil_collapse_to_minus_one() { run_with_system_weight(0, || { + let mut original = Fixed128::default(); // 0 + let mut next; + + // decreases + next = TargetedFeeAdjustment::::convert(original); assert_eq!( - TargetedFeeAdjustment::::convert(Fixed64::default()), - feemul(-10000) - ); - assert_eq!( - TargetedFeeAdjustment::::convert(feemul(-10000)), - feemul(-20000) + next, + fee_multiplier_update(0, original), ); + assert!(next < original); + original = next; + + // keeps decreasing + next = TargetedFeeAdjustment::::convert(original); assert_eq!( - TargetedFeeAdjustment::::convert(feemul(-20000)), - feemul(-30000) + next, + fee_multiplier_update(0, original), ); - // ... + assert!(next < original); + + // ... stops going down at -1 assert_eq!( - TargetedFeeAdjustment::::convert(feemul(1_000_000_000 * -1)), - feemul(-1_000_000_000) + TargetedFeeAdjustment::::convert(Fixed128::from_natural(-1)), + Fixed128::from_natural(-1) ); }) } @@ -326,7 +340,7 @@ mod tests { fn weight_to_fee_should_not_overflow_on_large_weights() { let kb = 1024 as Weight; let mb = kb * kb; - let max_fm = Fixed64::from_natural(i64::max_value()); + let max_fm = Fixed128::from_natural(i128::max_value()); // check that for all values it can compute, correctly. vec![ @@ -339,13 +353,17 @@ mod tests { 100 * kb, mb, 10 * mb, + 2147483647, + 4294967295, + MaximumBlockWeight::get() / 2, + MaximumBlockWeight::get(), Weight::max_value() / 2, Weight::max_value(), ].into_iter().for_each(|i| { run_with_system_weight(i, || { - let next = TargetedFeeAdjustment::::convert(Fixed64::default()); - let truth = fee_multiplier_update(i, Fixed64::default()); - assert_eq_error_rate!(truth.into_inner(), next.into_inner(), 5); + let next = TargetedFeeAdjustment::::convert(Fixed128::default()); + let truth = fee_multiplier_update(i, Fixed128::default()); + assert_eq_error_rate!(truth, next, Fixed128::from_parts(50_000_000)); }); }); diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 1daad5c12c..b1d768eecd 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -31,7 +31,7 @@ pub use node_primitives::{AccountId, Signature}; use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment}; use sp_api::impl_runtime_apis; use sp_runtime::{ - Permill, Perbill, Percent, ApplyExtrinsicResult, + Permill, Perbill, Perquintill, Percent, ApplyExtrinsicResult, impl_opaque_keys, generic, create_runtime_str, }; use sp_runtime::curve::PiecewiseLinear; @@ -127,8 +127,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 240, - impl_version: 2, + spec_version: 241, + impl_version: 0, apis: RUNTIME_API_VERSIONS, }; @@ -161,7 +161,8 @@ impl OnUnbalanced for DealWithFees { parameter_types! { pub const BlockHashCount: BlockNumber = 250; - pub const MaximumBlockWeight: Weight = 1_000_000_000; + /// We allow for 2 seconds of compute with a 6 second average block time. + pub const MaximumBlockWeight: Weight = 2_000_000_000_000; pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; pub const Version: RuntimeVersion = VERSION; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); @@ -180,6 +181,7 @@ impl frame_system::Trait for Runtime { type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = Version; @@ -254,10 +256,11 @@ impl pallet_balances::Trait for Runtime { parameter_types! { pub const TransactionBaseFee: Balance = 1 * CENTS; pub const TransactionByteFee: Balance = 10 * MILLICENTS; - // setting this to zero will disable the weight fee. - pub const WeightFeeCoefficient: Balance = 1_000; + // In the Substrate node, a weight of 10_000_000 (smallest non-zero weight) + // is mapped to 10_000_000 units of fees, hence: + pub const WeightFeeCoefficient: Balance = 1; // for a sane configuration, this should always be less than `AvailableBlockRatio`. - pub const TargetBlockFullness: Perbill = Perbill::from_percent(25); + pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25); } impl pallet_transaction_payment::Trait for Runtime { diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 388eb7780b..15726c9bcb 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -133,6 +133,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use frame_support::{Parameter, decl_module, decl_event, decl_storage, decl_error, ensure}; +use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; use sp_runtime::traits::{Member, AtLeast32Bit, Zero, StaticLookup}; use frame_system::{self as system, ensure_signed}; use sp_runtime::traits::One; @@ -157,7 +158,7 @@ decl_module! { /// Issue a new class of fungible assets. There are, and will only ever be, `total` /// such assets and they'll all belong to the `origin` initially. It will have an /// identifier `AssetId` instance: this will be specified in the `Issued` event. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn issue(origin, #[compact] total: T::Balance) { let origin = ensure_signed(origin)?; @@ -171,7 +172,7 @@ decl_module! { } /// Move some assets from one holder to another. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn transfer(origin, #[compact] id: T::AssetId, target: ::Source, @@ -190,7 +191,7 @@ decl_module! { } /// Destroy any assets of `id` owned by `origin`. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn destroy(origin, #[compact] id: T::AssetId) { let origin = ensure_signed(origin)?; let balance = >::take((id, &origin)); @@ -292,6 +293,7 @@ mod tests { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); diff --git a/frame/aura/src/mock.rs b/frame/aura/src/mock.rs index 05a161ee49..2716806b6e 100644 --- a/frame/aura/src/mock.rs +++ b/frame/aura/src/mock.rs @@ -57,6 +57,7 @@ impl frame_system::Trait for Test { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index b8f28b432b..b3edce4818 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -154,6 +154,7 @@ mod tests { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index e6249849bf..fac4b7d482 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -27,7 +27,7 @@ use frame_support::traits::{FindAuthor, VerifySeal, Get}; use codec::{Encode, Decode}; use frame_system::ensure_none; use sp_runtime::traits::{Header as HeaderT, One, Zero}; -use frame_support::weights::{Weight, SimpleDispatchInfo, WeighData}; +use frame_support::weights::{Weight, MINIMUM_WEIGHT, SimpleDispatchInfo}; use sp_inherents::{InherentIdentifier, ProvideInherent, InherentData}; use sp_authorship::{INHERENT_IDENTIFIER, UnclesInherentData, InherentError}; @@ -197,7 +197,7 @@ decl_module! { T::EventHandler::note_author(Self::author()); - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } fn on_finalize() { @@ -207,7 +207,7 @@ decl_module! { } /// Provide a set of uncles. - #[weight = SimpleDispatchInfo::FixedMandatory(10_000)] + #[weight = SimpleDispatchInfo::FixedMandatory(MINIMUM_WEIGHT)] fn set_uncles(origin, new_uncles: Vec) -> dispatch::DispatchResult { ensure_none(origin)?; ensure!(new_uncles.len() <= MAX_UNCLES, Error::::TooManyUncles); @@ -429,6 +429,7 @@ mod tests { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 5f85b91088..ea2f97e7a9 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -25,7 +25,7 @@ use pallet_timestamp; use sp_std::{result, prelude::*}; use frame_support::{ decl_storage, decl_module, traits::{FindAuthor, Get, Randomness as RandomnessT}, - weights::{Weight, SimpleDispatchInfo, WeighData}, + weights::{Weight, MINIMUM_WEIGHT}, }; use sp_timestamp::OnTimestampSet; use sp_runtime::{generic::DigestItem, ConsensusEngineId, Perbill}; @@ -184,7 +184,7 @@ decl_module! { fn on_initialize(now: T::BlockNumber) -> Weight { Self::do_initialize(now); - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } /// Block finalization diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index ea802b268e..1c7d02a56c 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -68,6 +68,7 @@ impl frame_system::Trait for Test { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type ModuleToIndex = (); diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 39e15b3f4f..98d6a93738 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -159,7 +159,7 @@ use sp_std::{cmp, result, mem, fmt::Debug, ops::BitOr, convert::Infallible}; use codec::{Codec, Encode, Decode}; use frame_support::{ StorageValue, Parameter, decl_event, decl_storage, decl_module, decl_error, ensure, - weights::SimpleDispatchInfo, traits::{ + traits::{ Currency, OnKilledAccount, OnUnbalanced, TryDrop, StoredMap, WithdrawReason, WithdrawReasons, LockIdentifier, LockableCurrency, ExistenceRequirement, Imbalance, SignedImbalance, ReservableCurrency, Get, ExistenceRequirement::KeepAlive, @@ -433,7 +433,7 @@ decl_module! { /// check that the transfer will not kill the origin account. /// /// # - #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] + #[weight = T::DbWeight::get().reads_writes(1, 1) + 200_000_000] pub fn transfer( origin, dest: ::Source, @@ -457,7 +457,7 @@ decl_module! { /// - Independent of the arguments. /// - Contains a limited number of reads and writes. /// # - #[weight = SimpleDispatchInfo::FixedOperational(50_000)] + #[weight = T::DbWeight::get().reads_writes(1, 1) + 100_000_000] fn set_balance( origin, who: ::Source, @@ -495,7 +495,11 @@ decl_module! { /// Exactly as `transfer`, except the origin must be root and the source account may be /// specified. - #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] + /// # + /// - Same as transfer, but additional read and write because the source account is + /// not assumed to be in the overlay. + /// # + #[weight = T::DbWeight::get().reads_writes(2, 2) + 200_000_000] pub fn force_transfer( origin, source: ::Source, @@ -514,7 +518,7 @@ decl_module! { /// 99% of the time you want [`transfer`] instead. /// /// [`transfer`]: struct.Module.html#method.transfer - #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] + #[weight = T::DbWeight::get().reads_writes(1, 1) + 150_000_000] pub fn transfer_keep_alive( origin, dest: ::Source, @@ -842,6 +846,7 @@ impl, I: Instance> frame_system::Trait for ElevatedTrait { type Event = (); type BlockHashCount = T::BlockHashCount; type MaximumBlockWeight = T::MaximumBlockWeight; + type DbWeight = T::DbWeight; type MaximumBlockLength = T::MaximumBlockLength; type AvailableBlockRatio = T::AvailableBlockRatio; type Version = T::Version; diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index 14caf41c1e..7ff7ec0fc4 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -36,7 +36,7 @@ macro_rules! decl_tests { ($test:ty, $ext_builder:ty, $existential_deposit:expr) => { use crate::*; - use sp_runtime::{Fixed64, traits::{SignedExtension, BadOrigin}}; + use sp_runtime::{Fixed128, traits::{SignedExtension, BadOrigin}}; use frame_support::{ assert_noop, assert_ok, assert_err, traits::{ @@ -153,7 +153,7 @@ macro_rules! decl_tests { .monied(true) .build() .execute_with(|| { - pallet_transaction_payment::NextFeeMultiplier::put(Fixed64::from_natural(1)); + pallet_transaction_payment::NextFeeMultiplier::put(Fixed128::from_natural(1)); Balances::set_lock(ID_1, &1, 10, WithdrawReason::Reserve.into()); assert_noop!( >::transfer(&1, &2, 1, AllowDeath), diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index 59c520f4b5..72668ad0d8 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -67,6 +67,7 @@ impl frame_system::Trait for Test { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index 3a9bfb30ce..aab275c781 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -67,6 +67,7 @@ impl frame_system::Trait for Test { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/benchmark/src/lib.rs b/frame/benchmark/src/lib.rs index b571ffb5b9..24b0e43310 100644 --- a/frame/benchmark/src/lib.rs +++ b/frame/benchmark/src/lib.rs @@ -21,6 +21,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use frame_support::{decl_module, decl_storage, decl_event, decl_error}; +use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; use frame_support::traits::Currency; use frame_system::{self as system, ensure_signed}; use codec::{Encode, Decode}; @@ -70,7 +71,7 @@ decl_module! { fn deposit_event() = default; /// Do nothing. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn do_nothing(_origin, input: u32) { if input > 0 { return Ok(()); @@ -82,7 +83,7 @@ decl_module! { /// storage database, however, the `repeat` calls will all pull from the /// storage overlay cache. You must consider this when analyzing the /// results of the benchmark. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn read_value(_origin, repeat: u32) { for _ in 0..repeat { MyValue::get(); @@ -90,7 +91,7 @@ decl_module! { } /// Put a value into a storage value. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn put_value(_origin, repeat: u32) { for r in 0..repeat { MyValue::put(r); @@ -102,7 +103,7 @@ decl_module! { /// storage database, however, the `repeat` calls will all pull from the /// storage overlay cache. You must consider this when analyzing the /// results of the benchmark. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn exists_value(_origin, repeat: u32) { for _ in 0..repeat { MyValue::exists(); @@ -110,7 +111,7 @@ decl_module! { } /// Remove a value from storage `repeat` number of times. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn remove_value(_origin, repeat: u32) { for r in 0..repeat { MyMap::remove(r); @@ -118,7 +119,7 @@ decl_module! { } /// Read a value from storage map `repeat` number of times. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn read_map(_origin, repeat: u32) { for r in 0..repeat { MyMap::get(r); @@ -126,7 +127,7 @@ decl_module! { } /// Insert a value into a map. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn insert_map(_origin, repeat: u32) { for r in 0..repeat { MyMap::insert(r, r); @@ -134,7 +135,7 @@ decl_module! { } /// Check is a map contains a value `repeat` number of times. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn contains_key_map(_origin, repeat: u32) { for r in 0..repeat { MyMap::contains_key(r); @@ -142,7 +143,7 @@ decl_module! { } /// Read a value from storage `repeat` number of times. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn remove_prefix(_origin, repeat: u32) { for r in 0..repeat { MyDoubleMap::remove_prefix(r); @@ -150,21 +151,21 @@ decl_module! { } /// Add user to the list. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn add_member_list(origin) { let who = ensure_signed(origin)?; MyMemberList::::mutate(|x| x.push(who)); } /// Append user to the list. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn append_member_list(origin) { let who = ensure_signed(origin)?; MyMemberList::::append(&[who])?; } /// Encode a vector of accounts to bytes. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn encode_accounts(_origin, accounts: Vec) { let bytes = accounts.encode(); @@ -176,7 +177,7 @@ decl_module! { } /// Decode bytes into a vector of accounts. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn decode_accounts(_origin, bytes: Vec) { let accounts: Vec = Decode::decode(&mut bytes.as_slice()).map_err(|_| "Could not decode")?; diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index 50a39d0fcf..4b26ec732d 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -23,8 +23,9 @@ use codec::Decode; use sp_std::prelude::*; use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::{H256, Header}}; use frame_support::{ - dispatch::DispatchResult, decl_module, decl_storage, impl_outer_origin, - assert_ok, assert_err, ensure + dispatch::DispatchResult, + weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, + decl_module, decl_storage, impl_outer_origin, assert_ok, assert_err, ensure }; use frame_system::{RawOrigin, ensure_signed, ensure_none}; @@ -36,14 +37,14 @@ decl_storage! { decl_module! { pub struct Module for enum Call where origin: T::Origin { - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn set_value(origin, n: u32) -> DispatchResult { let _sender = ensure_signed(origin)?; Value::put(n); Ok(()) } - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn dummy(origin, _n: u32) -> DispatchResult { let _sender = ensure_none(origin)?; Ok(()) @@ -78,6 +79,7 @@ impl frame_system::Trait for Test { type Event = (); type BlockHashCount = (); type MaximumBlockWeight = (); + type DbWeight = (); type MaximumBlockLength = (); type AvailableBlockRatio = (); type Version = (); diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 53e9853221..b5626ae4a6 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -187,7 +187,7 @@ decl_module! { /// - `prime`: The prime member whose vote sets the default. /// /// Requires root origin. - #[weight = SimpleDispatchInfo::FixedOperational(100_000)] + #[weight = SimpleDispatchInfo::FixedOperational(100_000_000)] fn set_members(origin, new_members: Vec, prime: Option) { ensure_root(origin)?; let mut new_members = new_members; @@ -200,7 +200,7 @@ decl_module! { /// Dispatch a proposal from a member using the `Member` origin. /// /// Origin must be a member of the collective. - #[weight = SimpleDispatchInfo::FixedOperational(100_000)] + #[weight = SimpleDispatchInfo::FixedOperational(100_000_000)] fn execute(origin, proposal: Box<>::Proposal>) { let who = ensure_signed(origin)?; ensure!(Self::is_member(&who), Error::::NotMember); @@ -214,7 +214,7 @@ decl_module! { /// - Bounded storage reads and writes. /// - Argument `threshold` has bearing on weight. /// # - #[weight = SimpleDispatchInfo::FixedOperational(5_000_000)] + #[weight = SimpleDispatchInfo::FixedOperational(5_000_000_000)] fn propose(origin, #[compact] threshold: MemberCount, proposal: Box<>::Proposal>) { let who = ensure_signed(origin)?; ensure!(Self::is_member(&who), Error::::NotMember); @@ -244,7 +244,7 @@ decl_module! { /// - Bounded storage read and writes. /// - Will be slightly heavier if the proposal is approved / disapproved after the vote. /// # - #[weight = SimpleDispatchInfo::FixedOperational(200_000)] + #[weight = SimpleDispatchInfo::FixedOperational(200_000_000)] fn vote(origin, proposal: T::Hash, #[compact] index: ProposalIndex, approve: bool) { let who = ensure_signed(origin)?; ensure!(Self::is_member(&who), Error::::NotMember); @@ -303,7 +303,7 @@ decl_module! { /// - `M` is number of members, /// - `P` is number of active proposals, /// - `L` is the encoded length of `proposal` preimage. - #[weight = SimpleDispatchInfo::FixedOperational(200_000)] + #[weight = SimpleDispatchInfo::FixedOperational(200_000_000)] fn close(origin, proposal: T::Hash, #[compact] index: ProposalIndex) { let _ = ensure_signed(origin)?; @@ -553,6 +553,7 @@ mod tests { type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 10938bb7de..91f06d5607 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -123,6 +123,7 @@ use sp_runtime::{ RuntimeDebug, }; use frame_support::dispatch::{DispatchResult, Dispatchable}; +use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; use frame_support::{ Parameter, decl_module, decl_event, decl_storage, decl_error, storage::child, parameter_types, IsSubType, @@ -550,7 +551,7 @@ decl_module! { /// Updates the schedule for metering contracts. /// /// The schedule must have a greater version than the stored schedule. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn update_schedule(origin, schedule: Schedule) -> DispatchResult { ensure_root(origin)?; if >::current_schedule().version >= schedule.version { @@ -565,7 +566,7 @@ decl_module! { /// Stores the given binary Wasm code into the chain's storage and returns its `codehash`. /// You can instantiate contracts only with stored code. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn put_code( origin, #[compact] gas_limit: Gas, @@ -593,7 +594,7 @@ decl_module! { /// * If the account is a regular account, any value will be transferred. /// * If no account exists and the call value is not less than `existential_deposit`, /// a regular account will be created and any value will be transferred. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn call( origin, dest: ::Source, @@ -619,7 +620,7 @@ decl_module! { /// after the execution is saved as the `code` of the account. That code will be invoked /// upon any call received by this account. /// - The contract is initialized. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn instantiate( origin, #[compact] endowment: BalanceOf, @@ -642,7 +643,7 @@ decl_module! { /// /// If contract is not evicted as a result of this call, no actions are taken and /// the sender is not eligible for the reward. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn claim_surcharge(origin, dest: T::AccountId, aux_sender: Option) { let origin = origin.into(); let (signed, rewarded) = match (origin, aux_sender) { diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 1a5aa08454..2bcd708904 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -111,6 +111,7 @@ impl frame_system::Trait for Test { type Event = MetaEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index b09f305c64..a76567ba27 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -171,7 +171,7 @@ use sp_runtime::{ use codec::{Ref, Encode, Decode}; use frame_support::{ decl_module, decl_storage, decl_event, decl_error, ensure, Parameter, - weights::{SimpleDispatchInfo, Weight, WeighData}, + weights::{SimpleDispatchInfo, Weight, MINIMUM_WEIGHT}, traits::{ Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, OnUnbalanced, BalanceStatus, schedule::Named as ScheduleNamed, EnsureOrigin @@ -528,7 +528,7 @@ decl_module! { fn on_runtime_upgrade() -> Weight { Self::migrate(); - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } /// Propose a sensitive action to be taken. @@ -546,7 +546,7 @@ decl_module! { /// - P is the number proposals in the `PublicProps` vec. /// - Two DB changes, one DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] + #[weight = SimpleDispatchInfo::FixedNormal(5_000_000_000)] fn propose(origin, proposal_hash: T::Hash, #[compact] value: BalanceOf @@ -577,7 +577,7 @@ decl_module! { /// - S is the number of seconds a proposal already has. /// - One DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] + #[weight = SimpleDispatchInfo::FixedNormal(5_000_000_000)] fn second(origin, #[compact] proposal: PropIndex) { let who = ensure_signed(origin)?; let mut deposit = Self::deposit_of(proposal) @@ -600,7 +600,7 @@ decl_module! { /// - R is the number of referendums the voter has voted on. /// - One DB change, one DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(200_000)] + #[weight = SimpleDispatchInfo::FixedNormal(200_000_000)] fn vote(origin, #[compact] ref_index: ReferendumIndex, vote: AccountVote>, @@ -621,7 +621,7 @@ decl_module! { /// - `O(1)`. /// - One DB change, one DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(200_000)] + #[weight = SimpleDispatchInfo::FixedNormal(200_000_000)] fn proxy_vote(origin, #[compact] ref_index: ReferendumIndex, vote: AccountVote>, @@ -641,7 +641,7 @@ decl_module! { /// # /// - `O(1)`. /// # - #[weight = SimpleDispatchInfo::FixedOperational(500_000)] + #[weight = SimpleDispatchInfo::FixedOperational(500_000_000)] fn emergency_cancel(origin, ref_index: ReferendumIndex) { T::CancellationOrigin::ensure_origin(origin)?; @@ -664,7 +664,7 @@ decl_module! { /// - `O(1)`. /// - One DB change. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] + #[weight = SimpleDispatchInfo::FixedNormal(5_000_000_000)] fn external_propose(origin, proposal_hash: T::Hash) { T::ExternalOrigin::ensure_origin(origin)?; ensure!(!>::exists(), Error::::DuplicateProposal); @@ -691,7 +691,7 @@ decl_module! { /// - `O(1)`. /// - One DB change. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] + #[weight = SimpleDispatchInfo::FixedNormal(5_000_000_000)] fn external_propose_majority(origin, proposal_hash: T::Hash) { T::ExternalMajorityOrigin::ensure_origin(origin)?; >::put((proposal_hash, VoteThreshold::SimpleMajority)); @@ -711,7 +711,7 @@ decl_module! { /// - `O(1)`. /// - One DB change. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] + #[weight = SimpleDispatchInfo::FixedNormal(5_000_000_000)] fn external_propose_default(origin, proposal_hash: T::Hash) { T::ExternalDefaultOrigin::ensure_origin(origin)?; >::put((proposal_hash, VoteThreshold::SuperMajorityAgainst)); @@ -736,7 +736,7 @@ decl_module! { /// - One DB change. /// - One extra DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(200_000)] + #[weight = SimpleDispatchInfo::FixedNormal(200_000_000)] fn fast_track(origin, proposal_hash: T::Hash, voting_period: T::BlockNumber, @@ -787,7 +787,7 @@ decl_module! { /// be very large. /// - O(log v), v is number of `existing_vetoers` /// # - #[weight = SimpleDispatchInfo::FixedNormal(200_000)] + #[weight = SimpleDispatchInfo::FixedNormal(200_000_000)] fn veto_external(origin, proposal_hash: T::Hash) { let who = T::VetoOrigin::ensure_origin(origin)?; @@ -820,7 +820,7 @@ decl_module! { /// # /// - `O(1)`. /// # - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] fn cancel_referendum(origin, #[compact] ref_index: ReferendumIndex) { ensure_root(origin)?; Self::internal_cancel_referendum(ref_index); @@ -836,7 +836,7 @@ decl_module! { /// - One DB change. /// - O(d) where d is the items in the dispatch queue. /// # - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] fn cancel_queued(origin, which: ReferendumIndex) { ensure_root(origin)?; T::Scheduler::cancel_named((DEMOCRACY_ID, which)) @@ -848,7 +848,7 @@ decl_module! { sp_runtime::print(e); } - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } /// Specify a proxy that is already open to us. Called by the stash. @@ -862,7 +862,7 @@ decl_module! { /// # /// - One extra DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] fn activate_proxy(origin, proxy: T::AccountId) { let who = ensure_signed(origin)?; Proxy::::try_mutate(&proxy, |a| match a.take() { @@ -885,7 +885,7 @@ decl_module! { /// # /// - One DB clear. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] fn close_proxy(origin) { let who = ensure_signed(origin)?; Proxy::::mutate(&who, |a| { @@ -909,7 +909,7 @@ decl_module! { /// # /// - One DB clear. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] fn deactivate_proxy(origin, proxy: T::AccountId) { let who = ensure_signed(origin)?; Proxy::::try_mutate(&proxy, |a| match a.take() { @@ -942,7 +942,7 @@ decl_module! { /// /// # /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] pub fn delegate(origin, to: T::AccountId, conviction: Conviction, balance: BalanceOf) { let who = ensure_signed(origin)?; Self::try_delegate(who, to, conviction, balance)?; @@ -961,7 +961,7 @@ decl_module! { /// # /// - O(1). /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] fn undelegate(origin) { let who = ensure_signed(origin)?; Self::try_undelegate(who)?; @@ -975,7 +975,7 @@ decl_module! { /// - `O(1)`. /// - One DB clear. /// # - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn clear_public_proposals(origin) { ensure_root(origin)?; @@ -995,7 +995,7 @@ decl_module! { /// - Dependent on the size of `encoded_proposal` but protected by a /// required deposit. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] fn note_preimage(origin, encoded_proposal: Vec) { let who = ensure_signed(origin)?; let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); @@ -1030,7 +1030,7 @@ decl_module! { /// # /// - Dependent on the size of `encoded_proposal` and length of dispatch queue. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] fn note_imminent_preimage(origin, encoded_proposal: Vec) { let who = ensure_signed(origin)?; let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); @@ -1066,7 +1066,7 @@ decl_module! { /// # /// - One DB clear. /// # - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn reap_preimage(origin, proposal_hash: T::Hash) { let who = ensure_signed(origin)?; let (provider, deposit, since, expiry) = >::get(&proposal_hash) @@ -1096,7 +1096,7 @@ decl_module! { /// # /// - `O(1)`. /// # - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn unlock(origin, target: T::AccountId) { ensure_signed(origin)?; Self::update_lock(&target); @@ -1115,7 +1115,7 @@ decl_module! { /// # /// - One extra DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] fn open_proxy(origin, target: T::AccountId) { let who = ensure_signed(origin)?; Proxy::::mutate(&who, |a| { @@ -1154,7 +1154,7 @@ decl_module! { /// # /// - `O(R + log R)` where R is the number of referenda that `target` has voted on. /// # - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn remove_vote(origin, index: ReferendumIndex) -> DispatchResult { let who = ensure_signed(origin)?; Self::try_remove_vote(&who, index, UnvoteScope::Any) @@ -1176,7 +1176,7 @@ decl_module! { /// # /// - `O(R + log R)` where R is the number of referenda that `target` has voted on. /// # - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn remove_other_vote(origin, target: T::AccountId, index: ReferendumIndex) -> DispatchResult { let who = ensure_signed(origin)?; let scope = if target == who { UnvoteScope::Any } else { UnvoteScope::OnlyExpired }; @@ -1207,7 +1207,7 @@ decl_module! { /// /// # /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] pub fn proxy_delegate(origin, to: T::AccountId, conviction: Conviction, @@ -1231,7 +1231,7 @@ decl_module! { /// # /// - O(1). /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] fn proxy_undelegate(origin) { let who = ensure_signed(origin)?; let target = Self::proxy(who).and_then(|a| a.as_active()).ok_or(Error::::NotProxy)?; @@ -1251,7 +1251,7 @@ decl_module! { /// # /// - `O(R + log R)` where R is the number of referenda that `target` has voted on. /// # - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn proxy_remove_vote(origin, index: ReferendumIndex) -> DispatchResult { let who = ensure_signed(origin)?; let target = Self::proxy(who).and_then(|a| a.as_active()).ok_or(Error::::NotProxy)?; diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index e7320da082..4d540f63d5 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -80,6 +80,7 @@ impl frame_system::Trait for Test { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index f0d08f6164..fe42183743 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -88,7 +88,7 @@ use sp_runtime::{ }; use frame_support::{ decl_storage, decl_event, ensure, decl_module, decl_error, - weights::{SimpleDispatchInfo, Weight, WeighData}, storage::{StorageMap, IterableStorageMap}, + weights::{SimpleDispatchInfo, Weight, MINIMUM_WEIGHT}, storage::{StorageMap, IterableStorageMap}, traits::{ Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons, ChangeMembers, OnUnbalanced, WithdrawReason, Contains, BalanceStatus, InitializeMembers, @@ -267,7 +267,7 @@ decl_module! { fn on_runtime_upgrade() -> Weight { migration::migrate::(); - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } const CandidacyBond: BalanceOf = T::CandidacyBond::get(); @@ -291,7 +291,7 @@ decl_module! { /// Reads: O(1) /// Writes: O(V) given `V` votes. V is bounded by 16. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] fn vote(origin, votes: Vec, #[compact] value: BalanceOf) { let who = ensure_signed(origin)?; @@ -336,7 +336,7 @@ decl_module! { /// Reads: O(1) /// Writes: O(1) /// # - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn remove_voter(origin) { let who = ensure_signed(origin)?; @@ -358,7 +358,7 @@ decl_module! { /// Reads: O(NLogM) given M current candidates and N votes for `target`. /// Writes: O(1) /// # - #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] + #[weight = SimpleDispatchInfo::FixedNormal(1_000_000_000)] fn report_defunct_voter(origin, target: ::Source) { let reporter = ensure_signed(origin)?; let target = T::Lookup::lookup(target)?; @@ -401,7 +401,7 @@ decl_module! { /// Reads: O(LogN) Given N candidates. /// Writes: O(1) /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] fn submit_candidacy(origin) { let who = ensure_signed(origin)?; @@ -428,7 +428,7 @@ decl_module! { /// - `origin` is a current member. In this case, the bond is unreserved and origin is /// removed as a member, consequently not being a candidate for the next round anymore. /// Similar to [`remove_voter`], if replacement runners exists, they are immediately used. - #[weight = SimpleDispatchInfo::FixedOperational(2_000_000)] + #[weight = SimpleDispatchInfo::FixedOperational(2_000_000_000)] fn renounce_candidacy(origin) { let who = ensure_signed(origin)?; @@ -487,7 +487,7 @@ decl_module! { /// Reads: O(do_phragmen) /// Writes: O(do_phragmen) /// # - #[weight = SimpleDispatchInfo::FixedOperational(2_000_000)] + #[weight = SimpleDispatchInfo::FixedOperational(2_000_000_000)] fn remove_member(origin, who: ::Source) -> DispatchResult { ensure_root(origin)?; let who = T::Lookup::lookup(who)?; @@ -510,7 +510,7 @@ decl_module! { print(e); } - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } } } @@ -907,6 +907,7 @@ mod tests { type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index a8ea0b8c2e..a2398ad485 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -30,7 +30,7 @@ use sp_runtime::{ }; use frame_support::{ decl_storage, decl_event, ensure, decl_module, decl_error, - weights::{Weight, SimpleDispatchInfo, WeighData}, + weights::{Weight, MINIMUM_WEIGHT, SimpleDispatchInfo}, traits::{ Currency, ExistenceRequirement, Get, LockableCurrency, LockIdentifier, BalanceStatus, OnUnbalanced, ReservableCurrency, WithdrawReason, WithdrawReasons, ChangeMembers @@ -405,7 +405,7 @@ decl_module! { /// - Two extra DB entries, one DB change. /// - Argument `votes` is limited in length to number of candidates. /// # - #[weight = SimpleDispatchInfo::FixedNormal(2_500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(2_500_000_000)] fn set_approvals( origin, votes: Vec, @@ -423,7 +423,7 @@ decl_module! { /// # /// - Same as `set_approvals` with one additional storage read. /// # - #[weight = SimpleDispatchInfo::FixedNormal(2_500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(2_500_000_000)] fn proxy_set_approvals(origin, votes: Vec, #[compact] index: VoteIndex, @@ -446,7 +446,7 @@ decl_module! { /// - O(1). /// - Two fewer DB entries, one DB change. /// # - #[weight = SimpleDispatchInfo::FixedNormal(2_500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(2_500_000_000)] fn reap_inactive_voter( origin, #[compact] reporter_index: u32, @@ -520,7 +520,7 @@ decl_module! { /// - O(1). /// - Two fewer DB entries, one DB change. /// # - #[weight = SimpleDispatchInfo::FixedNormal(1_250_000)] + #[weight = SimpleDispatchInfo::FixedNormal(1_250_000_000)] fn retract_voter(origin, #[compact] index: u32) { let who = ensure_signed(origin)?; @@ -548,7 +548,7 @@ decl_module! { /// - Independent of input. /// - Three DB changes. /// # - #[weight = SimpleDispatchInfo::FixedNormal(2_500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(2_500_000_000)] fn submit_candidacy(origin, #[compact] slot: u32) { let who = ensure_signed(origin)?; @@ -585,7 +585,7 @@ decl_module! { /// - O(voters) compute. /// - One DB change. /// # - #[weight = SimpleDispatchInfo::FixedNormal(10_000_000)] + #[weight = SimpleDispatchInfo::FixedNormal(10_000_000_000)] fn present_winner( origin, candidate: ::Source, @@ -659,7 +659,7 @@ decl_module! { /// Set the desired member count; if lower than the current count, then seats will not be up /// election when they expire. If more, then a new vote will be started if one is not /// already in progress. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] fn set_desired_seats(origin, #[compact] count: u32) { ensure_root(origin)?; DesiredSeats::put(count); @@ -669,7 +669,7 @@ decl_module! { /// /// Note: A tally should happen instantly (if not already in a presentation /// period) to fill the seat if removal means that the desired members are not met. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] fn remove_member(origin, who: ::Source) { ensure_root(origin)?; let who = T::Lookup::lookup(who)?; @@ -684,7 +684,7 @@ decl_module! { /// Set the presentation duration. If there is currently a vote being presented for, will /// invoke `finalize_vote`. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] fn set_presentation_duration(origin, #[compact] count: T::BlockNumber) { ensure_root(origin)?; >::put(count); @@ -692,7 +692,7 @@ decl_module! { /// Set the presentation duration. If there is current a vote being presented for, will /// invoke `finalize_vote`. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] fn set_term_duration(origin, #[compact] count: T::BlockNumber) { ensure_root(origin)?; >::put(count); @@ -703,7 +703,7 @@ decl_module! { print("Guru meditation"); print(e); } - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } } } diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index 2898be26ca..a304478abb 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -50,6 +50,7 @@ impl frame_system::Trait for Test { type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index a50c545a46..f67ab767ed 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -25,7 +25,7 @@ pub use crate::backend::{Account, Log, Vicinity, Backend}; use sp_std::{vec::Vec, marker::PhantomData}; use frame_support::{ensure, decl_module, decl_storage, decl_event, decl_error}; -use frame_support::weights::{Weight, DispatchClass, FunctionOf}; +use frame_support::weights::{Weight, MINIMUM_WEIGHT, DispatchClass, FunctionOf}; use frame_support::traits::{Currency, WithdrawReason, ExistenceRequirement}; use frame_system::{self as system, ensure_signed}; use sp_runtime::ModuleId; @@ -191,7 +191,7 @@ decl_module! { fn deposit_event() = default; /// Deposit balance from currency/balances module into EVM. - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn deposit_balance(origin, value: BalanceOf) { let sender = ensure_signed(origin)?; @@ -212,7 +212,7 @@ decl_module! { } /// Withdraw balance from EVM into currency/balances module. - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn withdraw_balance(origin, value: BalanceOf) { let sender = ensure_signed(origin)?; let address = T::ConvertAccountId::convert_account_id(&sender); @@ -236,7 +236,7 @@ decl_module! { } /// Issue an EVM call operation. This is similar to a message call transaction in Ethereum. - #[weight = FunctionOf(|(_, _, _, gas_limit, gas_price, _): (&H160, &Vec, &U256, &u32, &U256, &Option)| (*gas_price).saturated_into::().saturating_mul(*gas_limit), DispatchClass::Normal, true)] + #[weight = FunctionOf(|(_, _, _, gas_limit, gas_price, _): (&H160, &Vec, &U256, &u32, &U256, &Option)| (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight), DispatchClass::Normal, true)] fn call( origin, target: H160, @@ -267,7 +267,7 @@ decl_module! { /// Issue an EVM create operation. This is similar to a contract creation transaction in /// Ethereum. - #[weight = FunctionOf(|(_, _, gas_limit, gas_price, _): (&Vec, &U256, &u32, &U256, &Option)| (*gas_price).saturated_into::().saturating_mul(*gas_limit), DispatchClass::Normal, true)] + #[weight = FunctionOf(|(_, _, gas_limit, gas_price, _): (&Vec, &U256, &u32, &U256, &Option)| (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight), DispatchClass::Normal, true)] fn create( origin, init: Vec, @@ -302,7 +302,7 @@ decl_module! { } /// Issue an EVM create2 operation. - #[weight = FunctionOf(|(_, _, _, gas_limit, gas_price, _): (&Vec, &H256, &U256, &u32, &U256, &Option)| (*gas_price).saturated_into::().saturating_mul(*gas_limit), DispatchClass::Normal, true)] + #[weight = FunctionOf(|(_, _, _, gas_limit, gas_price, _): (&Vec, &H256, &U256, &u32, &U256, &Option)| (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight), DispatchClass::Normal, true)] fn create2( origin, init: Vec, diff --git a/frame/example-offchain-worker/src/lib.rs b/frame/example-offchain-worker/src/lib.rs index ac9ac2d1ee..29a4859c78 100644 --- a/frame/example-offchain-worker/src/lib.rs +++ b/frame/example-offchain-worker/src/lib.rs @@ -44,7 +44,7 @@ use frame_support::{ debug, dispatch::DispatchResult, decl_module, decl_storage, decl_event, traits::Get, - weights::SimpleDispatchInfo, + weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, }; use frame_system::{self as system, ensure_signed, ensure_none, offchain}; use sp_core::crypto::KeyTypeId; @@ -157,7 +157,7 @@ decl_module! { /// working and receives (and provides) meaningful data. /// This example is not focused on correctness of the oracle itself, but rather its /// purpose is to showcase offchain worker capabilities. - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn submit_price(origin, price: u32) -> DispatchResult { // Retrieve sender of the transaction. let who = ensure_signed(origin)?; @@ -182,7 +182,7 @@ decl_module! { /// /// This example is not focused on correctness of the oracle itself, but rather its /// purpose is to showcase offchain worker capabilities. - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn submit_price_unsigned(origin, _block_number: T::BlockNumber, price: u32) -> DispatchResult { diff --git a/frame/example-offchain-worker/src/tests.rs b/frame/example-offchain-worker/src/tests.rs index 727c4942f6..279de7ef4a 100644 --- a/frame/example-offchain-worker/src/tests.rs +++ b/frame/example-offchain-worker/src/tests.rs @@ -19,7 +19,7 @@ use crate::*; use codec::Decode; use frame_support::{ assert_ok, impl_outer_origin, parameter_types, - weights::{GetDispatchInfo, Weight}, + weights::Weight, }; use sp_core::{ H256, @@ -61,6 +61,7 @@ impl frame_system::Trait for Test { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -192,15 +193,6 @@ fn should_submit_unsigned_transaction_on_chain() { }); } -#[test] -fn weights_work() { - // must have a default weight. - let default_call = >::submit_price(10); - let info = default_call.get_dispatch_info(); - // aka. `let info = as GetDispatchInfo>::get_dispatch_info(&default_call);` - assert_eq!(info.weight, 10_000); -} - fn price_oracle_response(state: &mut testing::OffchainState) { state.expect_request(0, testing::PendingRequest { method: "GET".into(), diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 13985671c2..97cad2856a 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -258,6 +258,7 @@ use frame_support::{ dispatch::DispatchResult, decl_module, decl_storage, decl_event, weights::{ SimpleDispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee, + MINIMUM_WEIGHT, }, }; use sp_std::prelude::*; @@ -468,7 +469,7 @@ decl_module! { // weight (a numeric representation of pure execution time and difficulty) of the // transaction and the latter demonstrates the [`DispatchClass`] of the call. A higher // weight means a larger transaction (less of which can be placed in a single block). - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn accumulate_dummy(origin, increase_by: T::Balance) -> DispatchResult { // This is a public call, so we ensure that the origin is some signed account. let _sender = ensure_signed(origin)?; @@ -523,7 +524,7 @@ decl_module! { // Anything that needs to be done at the start of the block. // We don't do anything here. - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } // The signature could also look like: `fn on_finalize()` @@ -753,6 +754,7 @@ mod tests { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -843,11 +845,11 @@ mod tests { #[test] fn weights_work() { - // must have a default weight. + // must have a defined weight. let default_call = >::accumulate_dummy(10); let info = default_call.get_dispatch_info(); // aka. `let info = as GetDispatchInfo>::get_dispatch_info(&default_call);` - assert_eq!(info.weight, 10_000); + assert_eq!(info.weight, 10_000_000); // must have a custom weight of `100 * arg = 2000` let custom_call = >::set_dummy(20); diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 20c79fe4a5..99f934afd2 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -476,6 +476,7 @@ mod tests { type Event = MetaEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = RuntimeVersion; diff --git a/frame/finality-tracker/src/lib.rs b/frame/finality-tracker/src/lib.rs index 8200543ffa..54506784a9 100644 --- a/frame/finality-tracker/src/lib.rs +++ b/frame/finality-tracker/src/lib.rs @@ -23,6 +23,7 @@ use sp_runtime::traits::{One, Zero, SaturatedConversion}; use sp_std::{prelude::*, result, cmp, vec}; use frame_support::{decl_module, decl_storage, decl_error, ensure}; use frame_support::traits::Get; +use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; use frame_system::{ensure_none, Trait as SystemTrait}; use sp_finality_tracker::{INHERENT_IDENTIFIER, FinalizedInherentData}; @@ -76,7 +77,7 @@ decl_module! { /// Hint that the author of this block thinks the best finalized /// block is the given number. - #[weight = frame_support::weights::SimpleDispatchInfo::FixedMandatory(10_000)] + #[weight = SimpleDispatchInfo::FixedMandatory(MINIMUM_WEIGHT)] fn final_hint(origin, #[compact] hint: T::BlockNumber) { ensure_none(origin)?; ensure!(!::Update::exists(), Error::::AlreadyUpdated); @@ -260,6 +261,7 @@ mod tests { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); diff --git a/frame/generic-asset/src/lib.rs b/frame/generic-asset/src/lib.rs index b16666cb6b..720ccd85cc 100644 --- a/frame/generic-asset/src/lib.rs +++ b/frame/generic-asset/src/lib.rs @@ -164,6 +164,7 @@ use sp_std::prelude::*; use sp_std::{cmp, result, fmt::Debug}; use frame_support::{ decl_event, decl_module, decl_storage, ensure, decl_error, + weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, traits::{ Currency, ExistenceRequirement, Imbalance, LockIdentifier, LockableCurrency, ReservableCurrency, SignedImbalance, WithdrawReason, WithdrawReasons, TryDrop, BalanceStatus, @@ -360,14 +361,14 @@ decl_module! { fn deposit_event() = default; /// Create a new kind of asset. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn create(origin, options: AssetOptions) -> DispatchResult { let origin = ensure_signed(origin)?; Self::create_asset(None, Some(origin), options) } /// Transfer some liquid free balance to another account. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn transfer(origin, #[compact] asset_id: T::AssetId, to: T::AccountId, #[compact] amount: T::Balance) { let origin = ensure_signed(origin)?; ensure!(!amount.is_zero(), Error::::ZeroAmount); @@ -377,7 +378,7 @@ decl_module! { /// Updates permission for a given `asset_id` and an account. /// /// The `origin` must have `update` permission. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn update_permission( origin, #[compact] asset_id: T::AssetId, @@ -400,7 +401,7 @@ decl_module! { /// Mints an asset, increases its total issuance. /// The origin must have `mint` permissions. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn mint(origin, #[compact] asset_id: T::AssetId, to: T::AccountId, amount: T::Balance) -> DispatchResult { let who = ensure_signed(origin)?; Self::mint_free(&asset_id, &who, &to, &amount)?; @@ -410,7 +411,7 @@ decl_module! { /// Burns an asset, decreases its total issuance. /// The `origin` must have `burn` permissions. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn burn(origin, #[compact] asset_id: T::AssetId, to: T::AccountId, amount: T::Balance) -> DispatchResult { let who = ensure_signed(origin)?; Self::burn_free(&asset_id, &who, &to, &amount)?; @@ -420,7 +421,7 @@ decl_module! { /// Can be used to create reserved tokens. /// Requires Root call. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn create_reserved( origin, asset_id: T::AssetId, @@ -1124,6 +1125,7 @@ impl frame_system::Trait for ElevatedTrait { type Event = (); type BlockHashCount = T::BlockHashCount; type MaximumBlockWeight = T::MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = T::MaximumBlockLength; type AvailableBlockRatio = T::AvailableBlockRatio; type Version = T::Version; diff --git a/frame/generic-asset/src/mock.rs b/frame/generic-asset/src/mock.rs index c805b793bc..2cd779da03 100644 --- a/frame/generic-asset/src/mock.rs +++ b/frame/generic-asset/src/mock.rs @@ -57,6 +57,7 @@ impl frame_system::Trait for Test { type Header = Header; type Event = TestEvent; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type BlockHashCount = BlockHashCount; diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index 030699b525..10cc8162db 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -33,6 +33,7 @@ pub use sp_finality_grandpa as fg_primitives; use sp_std::prelude::*; use codec::{self as codec, Encode, Decode}; use frame_support::{decl_event, decl_storage, decl_module, decl_error, storage}; +use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; use sp_runtime::{ DispatchResult, generic::{DigestItem, OpaqueDigestItemId}, traits::Zero, Perbill, }; @@ -184,7 +185,7 @@ decl_module! { fn deposit_event() = default; /// Report some misbehavior. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn report_misbehavior(origin, _report: Vec) { ensure_signed(origin)?; // FIXME: https://github.com/paritytech/substrate/issues/1112 diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index 8b94becd5a..90b7c97437 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -61,6 +61,7 @@ impl frame_system::Trait for Test { type Event = TestEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index 2a2d1c9cf8..ddb9bdcce2 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -74,7 +74,7 @@ use sp_runtime::traits::{StaticLookup, Zero, AppendZerosInput}; use frame_support::{ decl_module, decl_event, decl_storage, ensure, decl_error, traits::{Currency, ReservableCurrency, OnUnbalanced, Get, BalanceStatus, EnsureOrigin}, - weights::SimpleDispatchInfo, + weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -474,7 +474,7 @@ decl_module! { /// - One storage mutation (codec `O(R)`). /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn add_registrar(origin, account: T::AccountId) { T::RegistrarOrigin::try_origin(origin) .map(|_| ()) @@ -506,7 +506,7 @@ decl_module! { /// - One storage mutation (codec-read `O(X' + R)`, codec-write `O(X + R)`). /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn set_identity(origin, info: IdentityInfo) { let sender = ensure_signed(origin)?; let extra_fields = info.additional.len() as u32; @@ -552,7 +552,7 @@ decl_module! { /// - At most O(2 * S + 1) storage mutations; codec complexity `O(1 * S + S * 1)`); /// one storage-exists. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn set_subs(origin, subs: Vec<(T::AccountId, Data)>) { let sender = ensure_signed(origin)?; ensure!(>::contains_key(&sender), Error::::NotFound); @@ -599,7 +599,7 @@ decl_module! { /// - `S + 2` storage deletions. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn clear_identity(origin) { let sender = ensure_signed(origin)?; @@ -638,7 +638,7 @@ decl_module! { /// - Storage: 1 read `O(R)`, 1 mutate `O(X + R)`. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn request_judgement(origin, #[compact] reg_index: RegistrarIndex, #[compact] max_fee: BalanceOf, @@ -684,7 +684,7 @@ decl_module! { /// - One storage mutation `O(R + X)`. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn cancel_request(origin, reg_index: RegistrarIndex) { let sender = ensure_signed(origin)?; let mut id = >::get(&sender).ok_or(Error::::NoIdentity)?; @@ -715,7 +715,7 @@ decl_module! { /// - `O(R)`. /// - One storage mutation `O(R)`. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn set_fee(origin, #[compact] index: RegistrarIndex, #[compact] fee: BalanceOf, @@ -742,7 +742,7 @@ decl_module! { /// - `O(R)`. /// - One storage mutation `O(R)`. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn set_account_id(origin, #[compact] index: RegistrarIndex, new: T::AccountId, @@ -769,7 +769,7 @@ decl_module! { /// - `O(R)`. /// - One storage mutation `O(R)`. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn set_fields(origin, #[compact] index: RegistrarIndex, fields: IdentityFields, @@ -803,7 +803,7 @@ decl_module! { /// - Storage: 1 read `O(R)`, 1 mutate `O(R + X)`. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn provide_judgement(origin, #[compact] reg_index: RegistrarIndex, target: ::Source, @@ -852,7 +852,7 @@ decl_module! { /// - `S + 2` storage mutations. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] fn kill_identity(origin, target: ::Source) { T::ForceOrigin::try_origin(origin) .map(|_| ()) @@ -930,6 +930,7 @@ mod tests { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 9c2b55a5c0..1137fc2699 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -43,6 +43,7 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; +//! use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; //! use frame_system::{self as system, ensure_signed}; //! use pallet_im_online::{self as im_online}; //! @@ -50,7 +51,7 @@ //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = frame_support::weights::SimpleDispatchInfo::default()] +//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] //! pub fn is_online(origin, authority_index: u32) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; //! let _is_online = >::is_online(authority_index); @@ -94,6 +95,7 @@ use sp_staking::{ use frame_support::{ decl_module, decl_event, decl_storage, Parameter, debug, decl_error, traits::Get, + weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, }; use frame_system::{self as system, ensure_none}; use frame_system::offchain::SubmitUnsignedTransaction; @@ -316,7 +318,7 @@ decl_module! { fn deposit_event() = default; - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn heartbeat( origin, heartbeat: Heartbeat, diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 73ccaf3f70..d620bb51b7 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -114,6 +114,7 @@ impl frame_system::Trait for Runtime { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index d2ba664d42..2a66af7e7f 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -25,7 +25,7 @@ use sp_runtime::traits::{ StaticLookup, Member, LookupError, Zero, One, BlakeTwo256, Hash, Saturating, AtLeast32Bit }; use frame_support::{Parameter, decl_module, decl_error, decl_event, decl_storage, ensure}; -use frame_support::weights::{Weight, SimpleDispatchInfo, WeighData}; +use frame_support::weights::{Weight, MINIMUM_WEIGHT, SimpleDispatchInfo}; use frame_support::dispatch::DispatchResult; use frame_support::traits::{Currency, ReservableCurrency, Get, BalanceStatus::Reserved}; use frame_support::storage::migration::take_storage_value; @@ -102,7 +102,7 @@ decl_module! { fn on_initialize() -> Weight { Self::migrations(); - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } /// Assign an previously unassigned index. @@ -121,7 +121,7 @@ decl_module! { /// - One reserve operation. /// - One event. /// # - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn claim(origin, index: T::AccountIndex) { let who = ensure_signed(origin)?; @@ -149,7 +149,7 @@ decl_module! { /// - One transfer operation. /// - One event. /// # - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn transfer(origin, new: T::AccountId, index: T::AccountIndex) { let who = ensure_signed(origin)?; ensure!(who != new, Error::::NotTransfer); @@ -180,7 +180,7 @@ decl_module! { /// - One reserve operation. /// - One event. /// # - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn free(origin, index: T::AccountIndex) { let who = ensure_signed(origin)?; @@ -209,7 +209,7 @@ decl_module! { /// - Up to one reserve operation. /// - One event. /// # - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn force_transfer(origin, new: T::AccountId, index: T::AccountIndex) { ensure_root(origin)?; diff --git a/frame/indices/src/mock.rs b/frame/indices/src/mock.rs index 355b3cc792..b8786c2dc8 100644 --- a/frame/indices/src/mock.rs +++ b/frame/indices/src/mock.rs @@ -61,6 +61,7 @@ impl frame_system::Trait for Test { type Event = MetaEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index 8f086fa2f3..e968be19a6 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -118,7 +118,7 @@ decl_module! { /// Add a member `who` to the set. /// /// May only be called from `AddOrigin` or root. - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn add_member(origin, who: T::AccountId) { T::AddOrigin::try_origin(origin) .map(|_| ()) @@ -137,7 +137,7 @@ decl_module! { /// Remove a member `who` from the set. /// /// May only be called from `RemoveOrigin` or root. - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn remove_member(origin, who: T::AccountId) { T::RemoveOrigin::try_origin(origin) .map(|_| ()) @@ -159,7 +159,7 @@ decl_module! { /// May only be called from `SwapOrigin` or root. /// /// Prime membership is *not* passed from `remove` to `add`, if extant. - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn swap_member(origin, remove: T::AccountId, add: T::AccountId) { T::SwapOrigin::try_origin(origin) .map(|_| ()) @@ -188,7 +188,7 @@ decl_module! { /// pass `members` pre-sorted. /// /// May only be called from `ResetOrigin` or root. - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn reset_members(origin, members: Vec) { T::ResetOrigin::try_origin(origin) .map(|_| ()) @@ -211,7 +211,7 @@ decl_module! { /// May only be called from `Signed` origin of a current member. /// /// Prime membership is passed from the origin account to `new`, if extant. - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn change_key(origin, new: T::AccountId) { let remove = ensure_signed(origin)?; @@ -239,7 +239,7 @@ decl_module! { } /// Set the prime member. Must be a current member. - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn set_prime(origin, who: T::AccountId) { T::PrimeOrigin::try_origin(origin) .map(|_| ()) @@ -250,7 +250,7 @@ decl_module! { } /// Remove the prime member if it exists. - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn clear_prime(origin) { T::PrimeOrigin::try_origin(origin) .map(|_| ()) @@ -315,6 +315,7 @@ mod tests { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index ae005e2500..b8a2359450 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -141,7 +141,7 @@ decl_module! { /// - One storage read/write. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn set_name(origin, name: Vec) { let sender = ensure_signed(origin)?; @@ -171,7 +171,7 @@ decl_module! { /// - One storage read/write. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(70_000)] + #[weight = SimpleDispatchInfo::FixedNormal(70_000_000)] fn clear_name(origin) { let sender = ensure_signed(origin)?; @@ -195,7 +195,7 @@ decl_module! { /// - One storage read/write. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(70_000)] + #[weight = SimpleDispatchInfo::FixedNormal(70_000_000)] fn kill_name(origin, target: ::Source) { T::ForceOrigin::try_origin(origin) .map(|_| ()) @@ -223,7 +223,7 @@ decl_module! { /// - One storage read/write. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(70_000)] + #[weight = SimpleDispatchInfo::FixedNormal(70_000_000)] fn force_name(origin, target: ::Source, name: Vec) { T::ForceOrigin::try_origin(origin) .map(|_| ()) @@ -282,6 +282,7 @@ mod tests { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index 40f39ab5f2..2b59c5e796 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -27,7 +27,7 @@ mod tests; use sp_std::vec::Vec; use frame_support::{ decl_module, decl_event, decl_storage, Parameter, debug, - weights::{Weight, SimpleDispatchInfo, WeighData}, + weights::{Weight, MINIMUM_WEIGHT}, }; use sp_runtime::{traits::Hash, Perbill}; use sp_staking::{ @@ -104,7 +104,7 @@ decl_module! { ConcurrentReportsIndex::::remove_all(); ReportsByKindIndex::remove_all(); - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } fn on_initialize(now: T::BlockNumber) -> Weight { @@ -125,7 +125,7 @@ decl_module! { }) } - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } } } diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index e464200396..7eda40cbbb 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -100,6 +100,7 @@ impl frame_system::Trait for Runtime { type Event = TestEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index fdc465b4dc..194879eb65 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -35,13 +35,13 @@ //! ### Example - Get random seed for the current block //! //! ``` -//! use frame_support::{decl_module, dispatch, traits::Randomness, weights::SimpleDispatchInfo}; +//! use frame_support::{decl_module, dispatch, traits::Randomness, weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}}; //! //! pub trait Trait: frame_system::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = SimpleDispatchInfo::default()] +//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] //! pub fn random_module_example(origin) -> dispatch::DispatchResult { //! let _random_seed = >::random_seed(); //! Ok(()) @@ -57,7 +57,7 @@ use sp_std::{prelude::*, convert::TryInto}; use sp_runtime::traits::Hash; use frame_support::{ decl_module, decl_storage, traits::Randomness, - weights::{Weight, SimpleDispatchInfo, WeighData} + weights::{Weight, MINIMUM_WEIGHT} }; use safe_mix::TripletMix; use codec::Encode; @@ -83,7 +83,7 @@ decl_module! { values[index] = parent_hash; }); - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } } } @@ -195,6 +195,7 @@ mod tests { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index 7348566d26..9f30061f93 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -159,7 +159,7 @@ use codec::{Encode, Decode}; use frame_support::{ decl_module, decl_event, decl_storage, decl_error, ensure, - Parameter, RuntimeDebug, weights::{GetDispatchInfo, SimpleDispatchInfo, FunctionOf}, + Parameter, RuntimeDebug, weights::{MINIMUM_WEIGHT, GetDispatchInfo, SimpleDispatchInfo, FunctionOf}, traits::{Currency, ReservableCurrency, Get, BalanceStatus}, dispatch::PostDispatchInfo, }; @@ -365,7 +365,7 @@ decl_module! { /// - One storage write O(1) /// - One event /// # - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn set_recovered(origin, lost: T::AccountId, rescuer: T::AccountId) { ensure_root(origin)?; // Create the recovery storage item. @@ -400,7 +400,7 @@ decl_module! { /// /// Total Complexity: O(F + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] fn create_recovery(origin, friends: Vec, threshold: u16, @@ -460,7 +460,7 @@ decl_module! { /// /// Total Complexity: O(F + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] fn initiate_recovery(origin, account: T::AccountId) { let who = ensure_signed(origin)?; // Check that the account is recoverable @@ -506,7 +506,7 @@ decl_module! { /// /// Total Complexity: O(F + logF + V + logV) /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] fn vouch_recovery(origin, lost: T::AccountId, rescuer: T::AccountId) { let who = ensure_signed(origin)?; // Get the recovery configuration for the lost account. @@ -545,7 +545,7 @@ decl_module! { /// /// Total Complexity: O(F + V) /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] fn claim_recovery(origin, account: T::AccountId) { let who = ensure_signed(origin)?; // Get the recovery configuration for the lost account @@ -590,7 +590,7 @@ decl_module! { /// /// Total Complexity: O(V + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(30_000)] + #[weight = SimpleDispatchInfo::FixedNormal(30_000_000)] fn close_recovery(origin, rescuer: T::AccountId) { let who = ensure_signed(origin)?; // Take the active recovery process started by the rescuer for this account. @@ -622,7 +622,7 @@ decl_module! { /// /// Total Complexity: O(F + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(30_000)] + #[weight = SimpleDispatchInfo::FixedNormal(30_000_000)] fn remove_recovery(origin) { let who = ensure_signed(origin)?; // Check there are no active recoveries @@ -647,7 +647,7 @@ decl_module! { /// # /// - One storage mutation to check account is recovered by `who`. O(1) /// # - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn cancel_recovered(origin, account: T::AccountId) { let who = ensure_signed(origin)?; // Check `who` is allowed to make a call on behalf of `account` diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index 9327ece572..ccc80730a1 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -75,6 +75,7 @@ impl frame_system::Trait for Test { type Event = TestEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index f70204cb1a..3e53b7a505 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -348,6 +348,7 @@ mod tests { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index 2602d38962..eca877f096 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -54,6 +54,7 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; +//! use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; //! use frame_system::{self as system, ensure_signed}; //! use pallet_scored_pool::{self as scored_pool}; //! @@ -61,7 +62,7 @@ //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = frame_support::weights::SimpleDispatchInfo::default()] +//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] //! pub fn candidate(origin) -> dispatch::DispatchResult { //! let who = ensure_signed(origin)?; //! @@ -97,7 +98,7 @@ use sp_std::{ use frame_support::{ decl_module, decl_storage, decl_event, ensure, decl_error, traits::{EnsureOrigin, ChangeMembers, InitializeMembers, Currency, Get, ReservableCurrency}, - weights::{Weight, SimpleDispatchInfo, WeighData}, + weights::{Weight, MINIMUM_WEIGHT, SimpleDispatchInfo}, }; use frame_system::{self as system, ensure_root, ensure_signed}; use sp_runtime::{ @@ -252,7 +253,7 @@ decl_module! { let pool = >::get(); >::refresh_members(pool, ChangeReceiver::MembershipChanged); } - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } /// Add `origin` to the pool of candidates. @@ -266,7 +267,7 @@ decl_module! { /// /// The `index` parameter of this function must be set to /// the index of the transactor in the `Pool`. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn submit_candidacy(origin) { let who = ensure_signed(origin)?; ensure!(!>::contains_key(&who), Error::::AlreadyInPool); @@ -296,7 +297,7 @@ decl_module! { /// /// The `index` parameter of this function must be set to /// the index of the transactor in the `Pool`. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn withdraw_candidacy( origin, index: u32 @@ -316,7 +317,7 @@ decl_module! { /// /// The `index` parameter of this function must be set to /// the index of `dest` in the `Pool`. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn kick( origin, dest: ::Source, @@ -341,7 +342,7 @@ decl_module! { /// /// The `index` parameter of this function must be set to /// the index of the `dest` in the `Pool`. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn score( origin, dest: ::Source, @@ -382,7 +383,7 @@ decl_module! { /// (this happens each `Period`). /// /// May only be called from root. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn change_member_count(origin, count: u32) { ensure_root(origin)?; >::put(&count); diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index a28b789137..07bd8cffbf 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -66,6 +66,7 @@ impl frame_system::Trait for Test { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/session/benchmarking/src/mock.rs b/frame/session/benchmarking/src/mock.rs index ff7965efca..4c022eb8b8 100644 --- a/frame/session/benchmarking/src/mock.rs +++ b/frame/session/benchmarking/src/mock.rs @@ -69,6 +69,7 @@ impl frame_system::Trait for Test { type Event = (); type BlockHashCount = (); type MaximumBlockWeight = (); + type DbWeight = (); type AvailableBlockRatio = (); type MaximumBlockLength = (); type Version = (); diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 9346b060fa..f539004189 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -110,7 +110,7 @@ use frame_support::{ Get, FindAuthor, ValidatorRegistration, EstimateNextSessionRotation, EstimateNextNewSession, }, dispatch::{self, DispatchResult, DispatchError}, - weights::{Weight, SimpleDispatchInfo, WeighData}, + weights::{Weight, MINIMUM_WEIGHT, SimpleDispatchInfo}, }; use frame_system::{self as system, ensure_signed}; @@ -498,7 +498,7 @@ decl_module! { /// - Increases system account refs by one on success iff there were previously no keys set. /// In this case, purge_keys will need to be called before the account can be removed. /// # - #[weight = SimpleDispatchInfo::FixedNormal(150_000)] + #[weight = SimpleDispatchInfo::FixedNormal(150_000_000)] pub fn set_keys(origin, keys: T::Keys, proof: Vec) -> dispatch::DispatchResult { let who = ensure_signed(origin)?; @@ -519,7 +519,7 @@ decl_module! { /// - Removes N + 1 DB entries. /// - Reduces system account refs by one on success. /// # - #[weight = SimpleDispatchInfo::FixedNormal(150_000)] + #[weight = SimpleDispatchInfo::FixedNormal(150_000_000)] pub fn purge_keys(origin) { let who = ensure_signed(origin)?; Self::do_purge_keys(&who)?; @@ -532,7 +532,7 @@ decl_module! { Self::rotate_session(); } - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } } } diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index a888dcfb28..9e8c77edf3 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -184,6 +184,7 @@ impl frame_system::Trait for Test { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index 2061c21d9c..f9908f5d9c 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -260,7 +260,7 @@ use sp_runtime::{Percent, ModuleId, RuntimeDebug, } }; use frame_support::{decl_error, decl_module, decl_storage, decl_event, ensure, dispatch::DispatchResult}; -use frame_support::weights::{SimpleDispatchInfo, Weight, WeighData}; +use frame_support::weights::{SimpleDispatchInfo, Weight, MINIMUM_WEIGHT}; use frame_support::traits::{ Currency, ReservableCurrency, Randomness, Get, ChangeMembers, BalanceStatus, ExistenceRequirement::AllowDeath, EnsureOrigin @@ -527,7 +527,7 @@ decl_module! { /// /// Total Complexity: O(M + B + C + logM + logB + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] pub fn bid(origin, value: BalanceOf) -> DispatchResult { let who = ensure_signed(origin)?; ensure!(!>::contains_key(&who), Error::::Suspended); @@ -566,7 +566,7 @@ decl_module! { /// /// Total Complexity: O(B + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(20_000)] + #[weight = SimpleDispatchInfo::FixedNormal(20_000_000)] pub fn unbid(origin, pos: u32) -> DispatchResult { let who = ensure_signed(origin)?; @@ -636,7 +636,7 @@ decl_module! { /// /// Total Complexity: O(M + B + C + logM + logB + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] pub fn vouch(origin, who: T::AccountId, value: BalanceOf, tip: BalanceOf) -> DispatchResult { let voucher = ensure_signed(origin)?; // Check user is not suspended. @@ -677,7 +677,7 @@ decl_module! { /// /// Total Complexity: O(B) /// # - #[weight = SimpleDispatchInfo::FixedNormal(20_000)] + #[weight = SimpleDispatchInfo::FixedNormal(20_000_000)] pub fn unvouch(origin, pos: u32) -> DispatchResult { let voucher = ensure_signed(origin)?; ensure!(Self::vouching(&voucher) == Some(VouchingStatus::Vouching), Error::::NotVouching); @@ -715,7 +715,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + C) /// # - #[weight = SimpleDispatchInfo::FixedNormal(30_000)] + #[weight = SimpleDispatchInfo::FixedNormal(30_000_000)] pub fn vote(origin, candidate: ::Source, approve: bool) { let voter = ensure_signed(origin)?; let candidate = T::Lookup::lookup(candidate)?; @@ -746,7 +746,7 @@ decl_module! { /// /// Total Complexity: O(M + logM) /// # - #[weight = SimpleDispatchInfo::FixedNormal(20_000)] + #[weight = SimpleDispatchInfo::FixedNormal(20_000_000)] pub fn defender_vote(origin, approve: bool) { let voter = ensure_signed(origin)?; let members = >::get(); @@ -778,7 +778,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + P + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(30_000)] + #[weight = SimpleDispatchInfo::FixedNormal(30_000_000)] pub fn payout(origin) { let who = ensure_signed(origin)?; @@ -820,7 +820,7 @@ decl_module! { /// /// Total Complexity: O(1) /// # - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn found(origin, founder: T::AccountId, max_members: u32, rules: Vec) { T::FounderSetOrigin::ensure_origin(origin)?; ensure!(!>::exists(), Error::::AlreadyFounded); @@ -847,7 +847,7 @@ decl_module! { /// /// Total Complexity: O(1) /// # - #[weight = SimpleDispatchInfo::FixedNormal(20_000)] + #[weight = SimpleDispatchInfo::FixedNormal(20_000_000)] fn unfound(origin) { let founder = ensure_signed(origin)?; ensure!(Founder::::get() == Some(founder.clone()), Error::::NotFounder); @@ -889,7 +889,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + B) /// # - #[weight = SimpleDispatchInfo::FixedNormal(30_000)] + #[weight = SimpleDispatchInfo::FixedNormal(30_000_000)] fn judge_suspended_member(origin, who: T::AccountId, forgive: bool) { T::SuspensionJudgementOrigin::ensure_origin(origin)?; ensure!(>::contains_key(&who), Error::::NotSuspended); @@ -960,7 +960,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + B + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn judge_suspended_candidate(origin, who: T::AccountId, judgement: Judgement) { T::SuspensionJudgementOrigin::ensure_origin(origin)?; if let Some((value, kind)) = >::get(&who) { @@ -1020,7 +1020,7 @@ decl_module! { /// /// Total Complexity: O(1) /// # - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn set_max_members(origin, max: u32) { ensure_root(origin)?; ensure!(max > 1, Error::::MaxMembers); @@ -1046,7 +1046,7 @@ decl_module! { Self::rotate_challenge(&mut members); } - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } } } diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index a66a5e6e04..a410fdbd04 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -75,6 +75,7 @@ impl frame_system::Trait for Test { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index ddf05f6ffd..2d1875ebf0 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -150,6 +150,7 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; +//! use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; //! use frame_system::{self as system, ensure_signed}; //! use pallet_staking::{self as staking}; //! @@ -158,7 +159,7 @@ //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { //! /// Reward a validator. -//! #[weight = frame_support::weights::SimpleDispatchInfo::default()] +//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] //! pub fn reward_myself(origin) -> dispatch::DispatchResult { //! let reported = ensure_signed(origin)?; //! >::reward_by_ids(vec![(reported, 10)]); @@ -274,7 +275,7 @@ use sp_std::{ use codec::{HasCompact, Encode, Decode}; use frame_support::{ decl_module, decl_event, decl_storage, ensure, decl_error, debug, - weights::{SimpleDispatchInfo, Weight}, + weights::{SimpleDispatchInfo, MINIMUM_WEIGHT, Weight}, storage::IterableStorageMap, dispatch::{IsSubType, DispatchResult}, traits::{ @@ -1250,7 +1251,7 @@ decl_module! { /// NOTE: Two of the storage writes (`Self::bonded`, `Self::payee`) are _never_ cleaned /// unless the `origin` falls below _existential deposit_ and gets removed as dust. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] pub fn bond(origin, controller: ::Source, #[compact] value: BalanceOf, @@ -1314,7 +1315,7 @@ decl_module! { /// - O(1). /// - One DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] fn bond_extra(origin, #[compact] max_additional: BalanceOf) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let stash = ensure_signed(origin)?; @@ -1360,7 +1361,7 @@ decl_module! { /// `withdraw_unbonded`. /// - One DB entry. /// - #[weight = SimpleDispatchInfo::FixedNormal(400_000)] + #[weight = SimpleDispatchInfo::FixedNormal(400_000_000)] fn unbond(origin, #[compact] value: BalanceOf) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1408,7 +1409,7 @@ decl_module! { /// - Contains a limited number of reads, yet the size of which could be large based on `ledger`. /// - Writes are limited to the `origin` account key. /// # - #[weight = SimpleDispatchInfo::FixedNormal(400_000)] + #[weight = SimpleDispatchInfo::FixedNormal(400_000_000)] fn withdraw_unbonded(origin) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1451,7 +1452,7 @@ decl_module! { /// - Contains a limited number of reads. /// - Writes are limited to the `origin` account key. /// # - #[weight = SimpleDispatchInfo::FixedNormal(750_000)] + #[weight = SimpleDispatchInfo::FixedNormal(750_000_000)] pub fn validate(origin, prefs: ValidatorPrefs) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1474,7 +1475,7 @@ decl_module! { /// which is capped at CompactAssignments::LIMIT. /// - Both the reads and writes follow a similar pattern. /// # - #[weight = SimpleDispatchInfo::FixedNormal(750_000)] + #[weight = SimpleDispatchInfo::FixedNormal(750_000_000)] pub fn nominate(origin, targets: Vec<::Source>) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1509,7 +1510,7 @@ decl_module! { /// - Contains one read. /// - Writes are limited to the `origin` account key. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] fn chill(origin) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1528,7 +1529,7 @@ decl_module! { /// - Contains a limited number of reads. /// - Writes are limited to the `origin` account key. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] fn set_payee(origin, payee: RewardDestination) { let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; @@ -1547,7 +1548,7 @@ decl_module! { /// - Contains a limited number of reads. /// - Writes are limited to the `origin` account key. /// # - #[weight = SimpleDispatchInfo::FixedNormal(750_000)] + #[weight = SimpleDispatchInfo::FixedNormal(750_000_000)] fn set_controller(origin, controller: ::Source) { let stash = ensure_signed(origin)?; let old_controller = Self::bonded(&stash).ok_or(Error::::NotStash)?; @@ -1564,7 +1565,7 @@ decl_module! { } /// The ideal number of validators. - #[weight = SimpleDispatchInfo::FixedNormal(5_000)] + #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] fn set_validator_count(origin, #[compact] new: u32) { ensure_root(origin)?; ValidatorCount::put(new); @@ -1575,7 +1576,7 @@ decl_module! { /// # /// - No arguments. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000)] + #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] fn force_no_eras(origin) { ensure_root(origin)?; ForceEra::put(Forcing::ForceNone); @@ -1587,21 +1588,21 @@ decl_module! { /// # /// - No arguments. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000)] + #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] fn force_new_era(origin) { ensure_root(origin)?; ForceEra::put(Forcing::ForceNew); } /// Set the validators who cannot be slashed (if any). - #[weight = SimpleDispatchInfo::FixedNormal(5_000)] + #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] fn set_invulnerables(origin, validators: Vec) { ensure_root(origin)?; >::put(validators); } /// Force a current staker to become completely unstaked, immediately. - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn force_unstake(origin, stash: T::AccountId) { ensure_root(origin)?; @@ -1617,7 +1618,7 @@ decl_module! { /// # /// - One storage write /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000)] + #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] fn force_new_era_always(origin) { ensure_root(origin)?; ForceEra::put(Forcing::ForceAlways); @@ -1630,7 +1631,7 @@ decl_module! { /// # /// - One storage write. /// # - #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] + #[weight = SimpleDispatchInfo::FixedNormal(1_000_000_000)] fn cancel_deferred_slash(origin, era: EraIndex, slash_indices: Vec) { T::SlashCancelOrigin::try_origin(origin) .map(|_| ()) @@ -1681,7 +1682,7 @@ decl_module! { /// maximum number of validators that may be nominated by a single nominator, it is /// bounded only economically (all nominators are required to place a minimum stake). /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] fn payout_nominator(origin, era: EraIndex, validators: Vec<(T::AccountId, u32)>) -> DispatchResult { @@ -1708,7 +1709,7 @@ decl_module! { /// - Time complexity: O(1). /// - Contains a limited number of reads and writes. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] fn payout_validator(origin, era: EraIndex) -> DispatchResult { let ctrl = ensure_signed(origin)?; Self::do_payout_validator(ctrl, era) @@ -1729,7 +1730,7 @@ decl_module! { /// - Time complexity: at most O(MaxNominatorRewardedPerValidator). /// - Contains a limited number of reads and writes. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] fn payout_stakers(origin, validator_stash: T::AccountId, era: EraIndex) -> DispatchResult { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); ensure_signed(origin)?; @@ -1745,7 +1746,7 @@ decl_module! { /// - Time complexity: O(1). Bounded by `MAX_UNLOCKING_CHUNKS`. /// - Storage changes: Can't increase storage, only decrease it. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] fn rebond(origin, #[compact] value: BalanceOf) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1759,7 +1760,7 @@ decl_module! { /// Set history_depth value. /// /// Origin must be root. - #[weight = SimpleDispatchInfo::FixedOperational(500_000)] + #[weight = SimpleDispatchInfo::FixedOperational(500_000_000)] fn set_history_depth(origin, #[compact] new_history_depth: EraIndex) { ensure_root(origin)?; if let Some(current_era) = Self::current_era() { @@ -1781,7 +1782,7 @@ decl_module! { /// This can be called from any origin. /// /// - `stash`: The stash account to reap. Its balance must be zero. - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn reap_stash(_origin, stash: T::AccountId) { ensure!(T::Currency::total_balance(&stash).is_zero(), Error::::FundedTarget); Self::kill_stash(&stash)?; @@ -1862,7 +1863,7 @@ decl_module! { /// /// The weight of this call is 1/10th of the blocks total weight. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000_000)] pub fn submit_election_solution( origin, winners: Vec, @@ -1885,7 +1886,7 @@ decl_module! { /// Note that this must pass the [`ValidateUnsigned`] check which only allows transactions /// from the local node to be included. In other words, only the block author can include a /// transaction in the block. - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000_000)] pub fn submit_election_solution_unsigned( origin, winners: Vec, diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index ce00193a67..c6bccdece4 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -203,6 +203,7 @@ impl frame_system::Trait for Test { type Event = MetaEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index 3f2eacdbf8..b8cf9a353f 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -52,13 +52,14 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; +//! use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; //! use frame_system::{self as system, ensure_root}; //! //! pub trait Trait: frame_system::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = frame_support::weights::SimpleDispatchInfo::default()] +//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] //! pub fn privileged_function(origin) -> dispatch::DispatchResult { //! ensure_root(origin)?; //! @@ -92,7 +93,7 @@ use sp_runtime::traits::{StaticLookup, Dispatchable}; use frame_support::{ Parameter, decl_module, decl_event, decl_storage, decl_error, ensure, }; -use frame_support::weights::{GetDispatchInfo, FunctionOf}; +use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT, GetDispatchInfo, FunctionOf}; use frame_system::{self as system, ensure_signed}; pub trait Trait: frame_system::Trait { @@ -150,7 +151,7 @@ decl_module! { /// - Limited storage reads. /// - One DB change. /// # - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn set_key(origin, new: ::Source) { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index aadcec67a3..8512ccb0a8 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -74,14 +74,14 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; -/// # use frame_support::weights::SimpleDispatchInfo; +/// # use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; /// # use frame_system::{self as system, Trait, ensure_signed}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { /// /// // Private functions are dispatchable, but not available to other /// // FRAME pallets. -/// #[weight = SimpleDispatchInfo::default()] +/// #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] /// fn my_function(origin, var: u64) -> dispatch::DispatchResult { /// // Your implementation /// Ok(()) @@ -89,7 +89,7 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// /// // Public functions are both dispatchable and available to other /// // FRAME pallets. -/// #[weight = SimpleDispatchInfo::default()] +/// #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] /// pub fn my_public_function(origin) -> dispatch::DispatchResult { /// // Your implementation /// Ok(()) @@ -117,17 +117,17 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; -/// # use frame_support::weights::SimpleDispatchInfo; +/// # use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; /// # use frame_system::{self as system, Trait, ensure_signed}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { -/// #[weight = SimpleDispatchInfo::default()] +/// #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] /// fn my_long_function(origin) -> dispatch::DispatchResult { /// // Your implementation /// Ok(()) /// } /// -/// #[weight = SimpleDispatchInfo::default()] +/// #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] /// fn my_short_function(origin) { /// // Your implementation /// } @@ -182,11 +182,11 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; -/// # use frame_support::weights::SimpleDispatchInfo; +/// # use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; /// # use frame_system::{self as system, Trait, ensure_signed, ensure_root}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { -/// #[weight = SimpleDispatchInfo::default()] +/// #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] /// fn my_privileged_function(origin) -> dispatch::DispatchResult { /// ensure_root(origin)?; /// // Your implementation @@ -2086,7 +2086,7 @@ macro_rules! __check_reserved_fn_name { #[allow(dead_code)] mod tests { use super::*; - use crate::weights::{DispatchInfo, DispatchClass}; + use crate::weights::{MINIMUM_WEIGHT, DispatchInfo, DispatchClass}; use crate::traits::{ CallMetadata, GetCallMetadata, GetCallName, OnInitialize, OnFinalize, OnRuntimeUpgrade }; @@ -2112,22 +2112,22 @@ mod tests { decl_module! { pub struct Module for enum Call where origin: T::Origin, T::AccountId: From { /// Hi, this is a comment. - #[weight = SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn aux_0(_origin) -> DispatchResult { unreachable!() } - #[weight = SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn aux_1(_origin, #[compact] _data: u32,) -> DispatchResult { unreachable!() } - #[weight = SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn aux_2(_origin, _data: i32, _data2: String) -> DispatchResult { unreachable!() } #[weight = SimpleDispatchInfo::FixedNormal(3)] fn aux_3(_origin) -> DispatchResult { unreachable!() } - #[weight = SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn aux_4(_origin, _data: i32) -> DispatchResult { unreachable!() } - #[weight = SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn aux_5(_origin, _data: i32, #[compact] _data2: u32,) -> DispatchResult { unreachable!() } #[weight = SimpleDispatchInfo::FixedOperational(5)] @@ -2291,11 +2291,6 @@ mod tests { Call::::operational().get_dispatch_info(), DispatchInfo { weight: 5, class: DispatchClass::Operational, pays_fee: true }, ); - // default weight. - assert_eq!( - Call::::aux_0().get_dispatch_info(), - DispatchInfo { weight: 10_000, class: DispatchClass::Normal, pays_fee: true }, - ); // custom basic assert_eq!( Call::::aux_3().get_dispatch_info(), diff --git a/frame/support/src/error.rs b/frame/support/src/error.rs index f619250726..a06f468892 100644 --- a/frame/support/src/error.rs +++ b/frame/support/src/error.rs @@ -35,7 +35,7 @@ pub use frame_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent}; /// /// ``` /// # use frame_support::{decl_error, decl_module}; -/// # use frame_support::weights::SimpleDispatchInfo; +/// # use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; /// decl_error! { /// /// Errors that can occur in my module. /// pub enum MyError for Module { @@ -55,7 +55,7 @@ pub use frame_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent}; /// pub struct Module for enum Call where origin: T::Origin { /// type Error = MyError; /// -/// #[weight = SimpleDispatchInfo::default()] +/// #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] /// fn do_something(origin) -> frame_support::dispatch::DispatchResult { /// Err(MyError::::YouAreNotCoolEnough.into()) /// } diff --git a/frame/support/src/metadata.rs b/frame/support/src/metadata.rs index 3d99ddaa84..6a3e41b809 100644 --- a/frame/support/src/metadata.rs +++ b/frame/support/src/metadata.rs @@ -334,7 +334,7 @@ mod tests { mod event_module { use crate::dispatch::DispatchResult; - use crate::weights::SimpleDispatchInfo; + use crate::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; pub trait Trait: super::system::Trait { type Balance; @@ -352,7 +352,7 @@ mod tests { pub struct Module for enum Call where origin: T::Origin { type Error = Error; - #[weight = SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn aux_0(_origin) -> DispatchResult { unreachable!() } } } diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index df9745bf30..79cfa1b397 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -50,7 +50,13 @@ use crate::dispatch::{DispatchErrorWithPostInfo, DispatchError}; pub use sp_runtime::transaction_validity::TransactionPriority; /// Numeric range of a transaction weight. -pub type Weight = u32; +/// +/// FRAME assumes a weight of `1_000_000_000_000` equals 1 second of compute on a standard +/// machine: (TODO: DEFINE STANDARD MACHINE SPECIFICATIONS) +pub type Weight = u64; + +/// The smallest total weight an extrinsic should have. +pub const MINIMUM_WEIGHT: Weight = 10_000_000; /// Means of weighing some particular kind of data (`T`). pub trait WeighData { @@ -106,6 +112,25 @@ impl Default for DispatchClass { } } +// Implement traits for raw Weight value +impl WeighData for Weight { + fn weigh_data(&self, _: T) -> Weight { + return *self + } +} + +impl ClassifyDispatch for Weight { + fn classify_dispatch(&self, _: T) -> DispatchClass { + DispatchClass::default() + } +} + +impl PaysFee for Weight { + fn pays_fee(&self, _: T) -> bool { + true + } +} + impl From for DispatchClass { fn from(tx: SimpleDispatchInfo) -> Self { match tx { @@ -281,13 +306,6 @@ impl PaysFee for SimpleDispatchInfo { } } -impl Default for SimpleDispatchInfo { - fn default() -> Self { - // Default weight of all transactions. - SimpleDispatchInfo::FixedNormal(10_000) - } -} - impl SimpleDispatchInfo { /// An _additive zero_ variant of SimpleDispatchInfo. pub fn zero() -> Self { @@ -390,24 +408,56 @@ impl GetDispatchInfo for sp_runtime::testing::TestX } } +/// The weight of database operations that the runtime can invoke. +#[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode)] +pub struct RuntimeDbWeight { + pub read: Weight, + pub write: Weight, +} + +impl RuntimeDbWeight { + pub fn reads(self, r: Weight) -> Weight { + self.read.saturating_mul(r) + } + + pub fn writes(self, w: Weight) -> Weight { + self.write.saturating_mul(w) + } + + pub fn reads_writes(self, r: Weight, w: Weight) -> Weight { + let read_weight = self.read.saturating_mul(r); + let write_weight = self.write.saturating_mul(w); + read_weight.saturating_add(write_weight) + } +} + #[cfg(test)] #[allow(dead_code)] mod tests { - use crate::decl_module; + use crate::{decl_module, parameter_types, traits::Get}; use super::*; pub trait Trait { type Origin; type Balance; type BlockNumber; + type DbWeight: Get; } pub struct TraitImpl {} + parameter_types! { + pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 100, + write: 1000, + }; + } + impl Trait for TraitImpl { type Origin = u32; type BlockNumber = u32; type Balance = u32; + type DbWeight = DbWeight; } decl_module! { @@ -417,18 +467,30 @@ mod tests { fn f0(_origin) { unimplemented!(); } // weight = a x 10 + b - #[weight = FunctionOf(|args: (&u32, &u32)| args.0 * 10 + args.1, DispatchClass::Normal, true)] + #[weight = FunctionOf(|args: (&u32, &u32)| (args.0 * 10 + args.1) as Weight, DispatchClass::Normal, true)] fn f11(_origin, _a: u32, _eb: u32) { unimplemented!(); } #[weight = FunctionOf(|_: (&u32, &u32)| 0, DispatchClass::Operational, true)] fn f12(_origin, _a: u32, _eb: u32) { unimplemented!(); } + + #[weight = T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + 10_000] + fn f2(_origin) { unimplemented!(); } + + #[weight = T::DbWeight::get().reads_writes(6, 5) + 40_000] + fn f21(_origin) { unimplemented!(); } + } } #[test] fn weights_are_correct() { + assert_eq!(Call::::f0().get_dispatch_info().weight, 1000); assert_eq!(Call::::f11(10, 20).get_dispatch_info().weight, 120); assert_eq!(Call::::f11(10, 20).get_dispatch_info().class, DispatchClass::Normal); - assert_eq!(Call::::f0().get_dispatch_info().weight, 1000); + assert_eq!(Call::::f12(10, 20).get_dispatch_info().weight, 0); + assert_eq!(Call::::f12(10, 20).get_dispatch_info().class, DispatchClass::Operational); + assert_eq!(Call::::f2().get_dispatch_info().weight, 12300); + assert_eq!(Call::::f21().get_dispatch_info().weight, 45600); + assert_eq!(Call::::f2().get_dispatch_info().class, DispatchClass::Normal); } } diff --git a/frame/support/test/tests/decl_error.rs b/frame/support/test/tests/decl_error.rs index 4191e79f24..cf50b009dd 100644 --- a/frame/support/test/tests/decl_error.rs +++ b/frame/support/test/tests/decl_error.rs @@ -18,6 +18,7 @@ use sp_runtime::{generic, traits::{BlakeTwo256, Block as _, Verify}, DispatchError}; use sp_core::{H256, sr25519}; +use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; mod system; @@ -32,7 +33,7 @@ mod module1 { pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: ::Origin { - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn fail(_origin) -> frame_support::dispatch::DispatchResult { Err(Error::::Something.into()) } @@ -59,7 +60,7 @@ mod module2 { pub struct Module for enum Call where origin: ::Origin { - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] pub fn fail(_origin) -> frame_support::dispatch::DispatchResult { Err(Error::::Something.into()) } diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index ea5d32fea3..00b110ffb9 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -23,6 +23,7 @@ use frame_support::{ DecodeDifferent, StorageMetadata, StorageEntryModifier, StorageEntryType, DefaultByteGetter, StorageEntryMetadata, StorageHasher, }, + weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, StorageValue, StorageMap, StorageDoubleMap, }; use sp_inherents::{ProvideInherent, InherentData, InherentIdentifier, MakeFatalError}; @@ -55,7 +56,7 @@ mod module1 { fn deposit_event() = default; - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn one(origin) { system::ensure_root(origin)?; Self::deposit_event(RawEvent::AnotherVariant(3)); diff --git a/frame/support/test/tests/reserved_keyword/on_initialize.rs b/frame/support/test/tests/reserved_keyword/on_initialize.rs index 8eacc836c4..00aac51cab 100644 --- a/frame/support/test/tests/reserved_keyword/on_initialize.rs +++ b/frame/support/test/tests/reserved_keyword/on_initialize.rs @@ -2,7 +2,7 @@ macro_rules! reserved { ($($reserved:ident)*) => { $( mod $reserved { - pub use frame_support::dispatch; + pub use frame_support::{dispatch, weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}}; pub trait Trait { type Origin; @@ -19,7 +19,7 @@ macro_rules! reserved { frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin { - #[weight = frame_support::weights::SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn $reserved(_origin) -> dispatch::DispatchResult { unreachable!() } } } diff --git a/frame/system/benches/bench.rs b/frame/system/benches/bench.rs index 90a4ad1d34..36711d3177 100644 --- a/frame/system/benches/bench.rs +++ b/frame/system/benches/bench.rs @@ -72,6 +72,7 @@ impl system::Trait for Runtime { type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 70e4f96e9f..31b862f3b2 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -68,14 +68,14 @@ //! ### Example - Get extrinsic count and parent hash for the current block //! //! ``` -//! use frame_support::{decl_module, dispatch, weights::SimpleDispatchInfo}; +//! use frame_support::{decl_module, dispatch, weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}}; //! use frame_system::{self as system, ensure_signed}; //! //! pub trait Trait: system::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = SimpleDispatchInfo::default()] +//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] //! pub fn system_module_example(origin) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; //! let _extrinsic_count = >::extrinsic_count(); @@ -120,7 +120,7 @@ use frame_support::{ Contains, Get, ModuleToIndex, OnNewAccount, OnKilledAccount, IsDeadAccount, Happened, StoredMap, EnsureOrigin, }, - weights::{Weight, DispatchInfo, PostDispatchInfo, DispatchClass, SimpleDispatchInfo, FunctionOf} + weights::{Weight, MINIMUM_WEIGHT, RuntimeDbWeight, DispatchInfo, PostDispatchInfo, DispatchClass, SimpleDispatchInfo, FunctionOf} }; use codec::{Encode, Decode, FullCodec, EncodeLike}; @@ -195,6 +195,9 @@ pub trait Trait: 'static + Eq + Clone { /// The maximum weight of a block. type MaximumBlockWeight: Get; + /// The weight of runtime database operations the runtime can invoke. + type DbWeight: Get; + /// The maximum length of a block (in bytes). type MaximumBlockLength: Get; @@ -482,20 +485,20 @@ decl_module! { } /// Make some on-chain remark. - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn remark(origin, _remark: Vec) { ensure_signed(origin)?; } /// Set the number of pages in the WebAssembly environment's heap. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] fn set_heap_pages(origin, pages: u64) { ensure_root(origin)?; storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode()); } /// Set the new runtime code. - #[weight = SimpleDispatchInfo::FixedOperational(200_000)] + #[weight = SimpleDispatchInfo::FixedOperational(200_000_000)] pub fn set_code(origin, code: Vec) { Self::can_set_code(origin, &code)?; @@ -504,7 +507,7 @@ decl_module! { } /// Set the new runtime code without doing any checks of the given `code`. - #[weight = SimpleDispatchInfo::FixedOperational(200_000)] + #[weight = SimpleDispatchInfo::FixedOperational(200_000_000)] pub fn set_code_without_checks(origin, code: Vec) { ensure_root(origin)?; storage::unhashed::put_raw(well_known_keys::CODE, &code); @@ -512,7 +515,7 @@ decl_module! { } /// Set the new changes trie configuration. - #[weight = SimpleDispatchInfo::FixedOperational(20_000)] + #[weight = SimpleDispatchInfo::FixedOperational(20_000_000)] pub fn set_changes_trie_config(origin, changes_trie_config: Option) { ensure_root(origin)?; match changes_trie_config.clone() { @@ -530,7 +533,7 @@ decl_module! { } /// Set some items of storage. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] fn set_storage(origin, items: Vec) { ensure_root(origin)?; for i in &items { @@ -539,7 +542,7 @@ decl_module! { } /// Kill some items from storage. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] fn kill_storage(origin, keys: Vec) { ensure_root(origin)?; for key in &keys { @@ -548,7 +551,7 @@ decl_module! { } /// Kill all storage items with a key that starts with the given prefix. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] fn kill_prefix(origin, prefix: Key) { ensure_root(origin)?; storage::unhashed::kill_prefix(&prefix); @@ -556,7 +559,7 @@ decl_module! { /// Kill the sending account, assuming there are no references outstanding and the composite /// data is equal to its default value. - #[weight = SimpleDispatchInfo::FixedOperational(25_000)] + #[weight = SimpleDispatchInfo::FixedOperational(25_000_000)] fn suicide(origin) { let who = ensure_signed(origin)?; let account = Account::::get(&who); @@ -1652,6 +1655,7 @@ mod tests { type Event = u16; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = Version; diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 6df8b46065..822848bf7d 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -62,6 +62,7 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; +//! use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; //! # use pallet_timestamp as timestamp; //! use frame_system::{self as system, ensure_signed}; //! @@ -69,7 +70,7 @@ //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = frame_support::weights::SimpleDispatchInfo::default()] +//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] //! pub fn get_time(origin) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; //! let _now = >::get(); @@ -100,7 +101,7 @@ use frame_support::debug; use frame_support::{ Parameter, decl_storage, decl_module, traits::{Time, UnixTime, Get}, - weights::SimpleDispatchInfo, + weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, }; use sp_runtime::{ RuntimeString, @@ -147,7 +148,7 @@ decl_module! { /// `MinimumPeriod`. /// /// The dispatch origin for this call must be `Inherent`. - #[weight = SimpleDispatchInfo::FixedMandatory(10_000)] + #[weight = SimpleDispatchInfo::FixedMandatory(MINIMUM_WEIGHT)] fn set(origin, #[compact] now: T::Moment) { ensure_none(origin)?; assert!(!::DidUpdate::exists(), "Timestamp must be updated only once in the block"); @@ -301,6 +302,7 @@ mod tests { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 0136bcc85a..8e3a9e398d 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -40,7 +40,7 @@ use frame_support::{ dispatch::DispatchResult, }; use sp_runtime::{ - Fixed64, + Fixed128, transaction_validity::{ TransactionPriority, ValidTransaction, InvalidTransaction, TransactionValidityError, TransactionValidity, @@ -52,7 +52,7 @@ use sp_runtime::{ }; use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; -type Multiplier = Fixed64; +type Multiplier = Fixed128; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = @@ -178,10 +178,10 @@ impl ChargeTransactionPayment where let adjustable_fee = len_fee.saturating_add(weight_fee); let targeted_fee_adjustment = NextFeeMultiplier::get(); // adjusted_fee = adjustable_fee + (adjustable_fee * targeted_fee_adjustment) - let adjusted_fee = targeted_fee_adjustment.saturated_multiply_accumulate(adjustable_fee); + let adjusted_fee = targeted_fee_adjustment.saturated_multiply_accumulate(adjustable_fee.saturated_into()); let base_fee = T::TransactionBaseFee::get(); - base_fee.saturating_add(adjusted_fee).saturating_add(tip) + base_fee.saturating_add(adjusted_fee.saturated_into()).saturating_add(tip) } else { tip } @@ -307,6 +307,7 @@ impl SignedExtension for ChargeTransactionPayment whe #[cfg(test)] mod tests { use super::*; + use core::num::NonZeroI128; use codec::Encode; use frame_support::{ impl_outer_dispatch, impl_outer_origin, parameter_types, @@ -360,6 +361,7 @@ mod tests { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -595,7 +597,7 @@ mod tests { .execute_with(|| { // all fees should be x1.5 - NextFeeMultiplier::put(Fixed64::from_rational(1, 2)); + NextFeeMultiplier::put(Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())); let len = 10; assert!( @@ -623,7 +625,7 @@ mod tests { .execute_with(|| { // all fees should be x1.5 - NextFeeMultiplier::put(Fixed64::from_rational(1, 2)); + NextFeeMultiplier::put(Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())); assert_eq!( TransactionPayment::query_info(xt, len), @@ -652,7 +654,7 @@ mod tests { .execute_with(|| { // Next fee multiplier is zero - assert_eq!(NextFeeMultiplier::get(), Fixed64::from_natural(0)); + assert_eq!(NextFeeMultiplier::get(), Fixed128::from_natural(0)); // Tip only, no fees works let dispatch_info = DispatchInfo { @@ -692,7 +694,7 @@ mod tests { .execute_with(|| { // Add a next fee multiplier - NextFeeMultiplier::put(Fixed64::from_rational(1, 2)); // = 1/2 = .5 + NextFeeMultiplier::put(Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())); // = 1/2 = .5 // Base fee is unaffected by multiplier let dispatch_info = DispatchInfo { weight: 0, @@ -726,7 +728,7 @@ mod tests { { // Overflow is handled let dispatch_info = DispatchInfo { - weight: ::max_value(), + weight: Weight::max_value(), class: DispatchClass::Operational, pays_fee: true, }; diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index f07b9b511e..2a255ab2d6 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -98,7 +98,7 @@ use frame_support::traits::{ use sp_runtime::{Permill, ModuleId, Percent, RuntimeDebug, traits::{ Zero, StaticLookup, AccountIdConversion, Saturating, Hash, BadOrigin }}; -use frame_support::weights::{Weight, WeighData, SimpleDispatchInfo}; +use frame_support::weights::{Weight, MINIMUM_WEIGHT, SimpleDispatchInfo}; use frame_support::traits::{Contains, EnsureOrigin}; use codec::{Encode, Decode}; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -327,7 +327,7 @@ decl_module! { /// - Limited storage reads. /// - One DB change, one extra DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] fn propose_spend( origin, #[compact] value: BalanceOf, @@ -354,7 +354,7 @@ decl_module! { /// - Limited storage reads. /// - One DB clear. /// # - #[weight = SimpleDispatchInfo::FixedOperational(100_000)] + #[weight = SimpleDispatchInfo::FixedOperational(100_000_000)] fn reject_proposal(origin, #[compact] proposal_id: ProposalIndex) { T::RejectOrigin::try_origin(origin) .map(|_| ()) @@ -376,7 +376,7 @@ decl_module! { /// - Limited storage reads. /// - One DB change. /// # - #[weight = SimpleDispatchInfo::FixedOperational(100_000)] + #[weight = SimpleDispatchInfo::FixedOperational(100_000_000)] fn approve_proposal(origin, #[compact] proposal_id: ProposalIndex) { T::ApproveOrigin::try_origin(origin) .map(|_| ()) @@ -405,7 +405,7 @@ decl_module! { /// - One storage mutation (codec `O(R)`). /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] fn report_awesome(origin, reason: Vec, who: T::AccountId) { let finder = ensure_signed(origin)?; @@ -447,7 +447,7 @@ decl_module! { /// - Two storage removals (one read, codec `O(T)`). /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn retract_tip(origin, hash: T::Hash) { let who = ensure_signed(origin)?; let tip = Tips::::get(&hash).ok_or(Error::::UnknownTip)?; @@ -479,7 +479,7 @@ decl_module! { /// - Two storage insertions (codecs `O(R)`, `O(T)`), one read `O(1)`. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(150_000)] + #[weight = SimpleDispatchInfo::FixedNormal(150_000_000)] fn tip_new(origin, reason: Vec, who: T::AccountId, tip_value: BalanceOf) { let tipper = ensure_signed(origin)?; ensure!(T::Tippers::contains(&tipper), BadOrigin); @@ -513,7 +513,7 @@ decl_module! { /// - One storage mutation (codec `O(T)`), one storage read `O(1)`. /// - Up to one event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn tip(origin, hash: T::Hash, tip_value: BalanceOf) { let tipper = ensure_signed(origin)?; ensure!(T::Tippers::contains(&tipper), BadOrigin); @@ -539,7 +539,7 @@ decl_module! { /// - One storage retrieval (codec `O(T)`) and two removals. /// - Up to three balance operations. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] fn close_tip(origin, hash: T::Hash) { ensure_signed(origin)?; @@ -558,7 +558,7 @@ decl_module! { Self::spend_funds(); } - SimpleDispatchInfo::default().weigh_data(()) + MINIMUM_WEIGHT } } } diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index 5ad78dcad7..132690d29f 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -56,6 +56,7 @@ impl frame_system::Trait for Test { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 3cd6d103cc..4a1c36b5ad 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -67,7 +67,7 @@ use sp_core::TypeId; use sp_io::hashing::blake2_256; use frame_support::{decl_module, decl_event, decl_error, decl_storage, Parameter, ensure, RuntimeDebug}; use frame_support::{traits::{Get, ReservableCurrency, Currency}, - weights::{GetDispatchInfo, DispatchClass,FunctionOf}, + weights::{Weight, GetDispatchInfo, DispatchClass, FunctionOf}, dispatch::PostDispatchInfo, }; use frame_system::{self as system, ensure_signed}; @@ -317,7 +317,7 @@ decl_module! { /// # #[weight = FunctionOf( |args: (&u16, &Vec, &Option>, &Box<::Call>)| { - args.3.get_dispatch_info().weight + 10_000 * (args.1.len() as u32 + 1) + args.3.get_dispatch_info().weight + 10_000 * (args.1.len() as Weight + 1) }, |args: (&u16, &Vec, &Option>, &Box<::Call>)| { args.3.get_dispatch_info().class @@ -418,7 +418,7 @@ decl_module! { /// # #[weight = FunctionOf( |args: (&u16, &Vec, &Option>, &[u8; 32])| { - 10_000 * (args.1.len() as u32 + 1) + 10_000 * (args.1.len() as Weight + 1) }, DispatchClass::Normal, true @@ -493,7 +493,7 @@ decl_module! { /// # #[weight = FunctionOf( |args: (&u16, &Vec, &Timepoint, &[u8; 32])| { - 10_000 * (args.1.len() as u32 + 1) + 10_000 * (args.1.len() as Weight + 1) }, DispatchClass::Normal, true diff --git a/frame/utility/src/tests.rs b/frame/utility/src/tests.rs index 68bdabd6d9..1b26bb5d5b 100644 --- a/frame/utility/src/tests.rs +++ b/frame/utility/src/tests.rs @@ -71,6 +71,7 @@ impl frame_system::Trait for Test { type Event = TestEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index b0c98e78bd..85545d92b0 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -57,7 +57,7 @@ use frame_support::traits::{ Currency, LockableCurrency, VestingSchedule, WithdrawReason, LockIdentifier, ExistenceRequirement, Get }; -use frame_support::weights::SimpleDispatchInfo; +use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; use frame_system::{self as system, ensure_signed}; mod benchmarking; @@ -194,7 +194,7 @@ decl_module! { /// - One storage read (codec `O(1)`) and up to one removal. /// - One event. /// # - #[weight = SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn vest(origin) -> DispatchResult { let who = ensure_signed(origin)?; Self::update_lock(who) @@ -216,7 +216,7 @@ decl_module! { /// - One storage read (codec `O(1)`) and up to one removal. /// - One event. /// # - #[weight = SimpleDispatchInfo::default()] + #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] fn vest_other(origin, target: ::Source) -> DispatchResult { ensure_signed(origin)?; Self::update_lock(T::Lookup::lookup(target)?) @@ -236,7 +236,7 @@ decl_module! { /// - Creates a new storage entry, but is protected by a minimum transfer /// amount needed to succeed. /// # - #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] + #[weight = SimpleDispatchInfo::FixedNormal(1_000_000_000)] pub fn vested_transfer( origin, target: ::Source, @@ -381,6 +381,7 @@ mod tests { type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); diff --git a/primitives/arithmetic/src/fixed128.rs b/primitives/arithmetic/src/fixed128.rs index d9d55910eb..a0fafe5ee3 100644 --- a/primitives/arithmetic/src/fixed128.rs +++ b/primitives/arithmetic/src/fixed128.rs @@ -18,11 +18,11 @@ use codec::{Decode, Encode}; use primitive_types::U256; use crate::{ traits::{Bounded, Saturating, UniqueSaturatedInto, SaturatedConversion}, - PerThing, + PerThing, Perquintill, }; use sp_std::{ convert::{Into, TryFrom, TryInto}, - fmt, + fmt, ops, num::NonZeroI128, }; @@ -57,7 +57,8 @@ impl Fixed128 { /// Creates self from a rational number. Equal to `n/d`. /// - /// Note that this might be lossy. + /// Note that this might be lossy. Only use this if you are sure that `n * DIV` can fit into an + /// i128. pub fn from_rational>(n: N, d: NonZeroI128) -> Self { let n = n.unique_saturated_into(); Self(n.saturating_mul(DIV.into()) / d.get()) @@ -214,6 +215,61 @@ impl Fixed128 { pub fn is_negative(&self) -> bool { self.0.is_negative() } + + /// Performs a saturated multiply and accumulate by unsigned number. + /// + /// Returns a saturated `int + (self * int)`. + pub fn saturated_multiply_accumulate(self, int: N) -> N + where + N: TryFrom + From + UniqueSaturatedInto + Bounded + Clone + Saturating + + ops::Rem + ops::Div + ops::Mul + + ops::Add, + { + let div = DIV as u128; + let positive = self.0 > 0; + // safe to convert as absolute value. + let parts = self.0.checked_abs().map(|v| v as u128).unwrap_or(i128::max_value() as u128 + 1); + + + // will always fit. + let natural_parts = parts / div; + // might saturate. + let natural_parts: N = natural_parts.saturated_into(); + // fractional parts can always fit into u64. + let perquintill_parts = (parts % div) as u64; + + let n = int.clone().saturating_mul(natural_parts); + let p = Perquintill::from_parts(perquintill_parts) * int.clone(); + + // everything that needs to be either added or subtracted from the original weight. + let excess = n.saturating_add(p); + + if positive { + int.saturating_add(excess) + } else { + int.saturating_sub(excess) + } + } +} + +/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait +/// for safe addition. +impl ops::Add for Fixed128 { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } +} + +/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait +/// for safe subtraction. +impl ops::Sub for Fixed128 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self::Output { + Self(self.0 - rhs.0) + } } impl Saturating for Fixed128 { diff --git a/primitives/arithmetic/src/fixed64.rs b/primitives/arithmetic/src/fixed64.rs index 6b399b6aa5..6f7e5fe842 100644 --- a/primitives/arithmetic/src/fixed64.rs +++ b/primitives/arithmetic/src/fixed64.rs @@ -104,6 +104,10 @@ impl Fixed64 { int.saturating_sub(excess) } } + + pub fn is_negative(&self) -> bool { + self.0.is_negative() + } } impl Saturating for Fixed64 { @@ -124,8 +128,7 @@ impl Saturating for Fixed64 { } } -/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait -/// for safe addition. +/// Use `Saturating` trait for safe addition. impl ops::Add for Fixed64 { type Output = Self; @@ -134,8 +137,7 @@ impl ops::Add for Fixed64 { } } -/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait -/// for safe subtraction. +/// Use `Saturating` trait for safe subtraction. impl ops::Sub for Fixed64 { type Output = Self; @@ -144,8 +146,7 @@ impl ops::Sub for Fixed64 { } } -/// Note that this is a standard, _potentially-panicking_, implementation. Use `CheckedDiv` trait -/// for safe division. +/// Use `CheckedDiv` trait for safe division. impl ops::Div for Fixed64 { type Output = Self; @@ -188,7 +189,13 @@ impl CheckedDiv for Fixed64 { impl sp_std::fmt::Debug for Fixed64 { #[cfg(feature = "std")] fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - write!(f, "Fixed64({},{})", self.0 / DIV, (self.0 % DIV) / 1000) + let integral = { + let int = self.0 / DIV; + let signum_for_zero = if int == 0 && self.is_negative() { "-" } else { "" }; + format!("{}{}", signum_for_zero, int) + }; + let fractional = format!("{:0>9}", (self.0 % DIV).abs()); + write!(f, "Fixed64({}.{})", integral, fractional) } #[cfg(not(feature = "std"))] diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 4e0a2728a9..b30c6ebe94 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -69,8 +69,8 @@ pub use sp_core::RuntimeDebug; /// Re-export top-level arithmetic stuff. pub use sp_arithmetic::{ - Perquintill, Perbill, Permill, Percent, PerU16, Rational128, Fixed64, Fixed128, PerThing, - traits::SaturatedConversion, + Perquintill, Perbill, Permill, Percent, PerU16, Rational128, Fixed64, Fixed128, + PerThing, traits::SaturatedConversion, }; /// Re-export 128 bit helpers. pub use sp_arithmetic::helpers_128bit; diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index c0aea9a2ab..a853912893 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -47,7 +47,7 @@ use sp_version::RuntimeVersion; pub use sp_core::hash::H256; #[cfg(any(feature = "std", test))] use sp_version::NativeVersion; -use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; +use frame_support::{impl_outer_origin, parameter_types, weights::{Weight, RuntimeDbWeight}}; use sp_inherents::{CheckInherentsResult, InherentData}; use cfg_if::cfg_if; use sp_core::storage::ChildType; @@ -380,6 +380,10 @@ parameter_types! { pub const BlockHashCount: BlockNumber = 250; pub const MinimumPeriod: u64 = 5; pub const MaximumBlockWeight: Weight = 4 * 1024 * 1024; + pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 100, + write: 1000, + }; pub const MaximumBlockLength: u32 = 4 * 1024 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } @@ -397,6 +401,7 @@ impl frame_system::Trait for Runtime { type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); -- GitLab From 710722f02f372601b2dae178d66654b8cb372ab5 Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Thu, 16 Apr 2020 10:43:40 +0200 Subject: [PATCH 240/300] Use a Kademlia instance per `ProtocolId`. (#5045) --- client/network/src/behaviour.rs | 17 +- client/network/src/discovery.rs | 500 +++++++++++++++++++++----------- client/network/src/service.rs | 40 ++- 3 files changed, 358 insertions(+), 199 deletions(-) diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index 203435134c..d8f70f7ae0 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -16,7 +16,7 @@ use crate::{ config::Role, - debug_info, discovery::DiscoveryBehaviour, discovery::DiscoveryOut, + debug_info, discovery::{DiscoveryBehaviour, DiscoveryConfig, DiscoveryOut}, Event, ObservedRole, DhtEvent, ExHashT, }; use crate::protocol::{self, light_client_handler, message::Roles, CustomMessageOutcome, Protocol}; @@ -67,28 +67,19 @@ pub enum BehaviourOut { impl Behaviour { /// Builds a new `Behaviour`. - pub async fn new( + pub fn new( substrate: Protocol, role: Role, user_agent: String, local_public_key: PublicKey, - known_addresses: Vec<(PeerId, Multiaddr)>, - enable_mdns: bool, - allow_private_ipv4: bool, - discovery_only_if_under_num: u64, block_requests: protocol::BlockRequests, light_client_handler: protocol::LightClientHandler, + disco_config: DiscoveryConfig, ) -> Self { Behaviour { substrate, debug_info: debug_info::DebugInfoBehaviour::new(user_agent, local_public_key.clone()), - discovery: DiscoveryBehaviour::new( - local_public_key, - known_addresses, - enable_mdns, - allow_private_ipv4, - discovery_only_if_under_num, - ).await, + discovery: disco_config.finish(), block_requests, light_client_handler, events: Vec::new(), diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index a72c3cce65..86a5b84a9e 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -45,85 +45,141 @@ //! of a node's address, you must call `add_self_reported_address`. //! +use crate::config::ProtocolId; use futures::prelude::*; use futures_timer::Delay; use libp2p::core::{connection::{ConnectionId, ListenerId}, ConnectedPoint, Multiaddr, PeerId, PublicKey}; -use libp2p::swarm::{ProtocolsHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; -use libp2p::kad::{Kademlia, KademliaEvent, Quorum, Record}; +use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters, ProtocolsHandler}; +use libp2p::swarm::protocols_handler::multi::MultiHandler; +use libp2p::kad::{Kademlia, KademliaConfig, KademliaEvent, Quorum, Record}; use libp2p::kad::GetClosestPeersError; +use libp2p::kad::handler::KademliaHandler; +use libp2p::kad::QueryId; use libp2p::kad::record::{self, store::MemoryStore}; #[cfg(not(target_os = "unknown"))] -use libp2p::{swarm::toggle::Toggle}; +use libp2p::swarm::toggle::Toggle; #[cfg(not(target_os = "unknown"))] use libp2p::mdns::{Mdns, MdnsEvent}; use libp2p::multiaddr::Protocol; use log::{debug, info, trace, warn, error}; -use std::{cmp, collections::VecDeque, io, time::Duration}; +use std::{cmp, collections::{HashMap, HashSet, VecDeque}, io, time::Duration}; use std::task::{Context, Poll}; use sp_core::hexdisplay::HexDisplay; -/// Implementation of `NetworkBehaviour` that discovers the nodes on the network. -pub struct DiscoveryBehaviour { - /// User-defined list of nodes and their addresses. Typically includes bootstrap nodes and - /// reserved nodes. - user_defined: Vec<(PeerId, Multiaddr)>, - /// Kademlia requests and answers. - kademlia: Kademlia, - /// Discovers nodes on the local network. - #[cfg(not(target_os = "unknown"))] - mdns: Toggle, - /// Stream that fires when we need to perform the next random Kademlia query. - next_kad_random_query: Delay, - /// After `next_kad_random_query` triggers, the next one triggers after this duration. - duration_to_next_kad: Duration, - /// Discovered nodes to return. - discoveries: VecDeque, - /// Identity of our local node. +/// `DiscoveryBehaviour` configuration. +pub struct DiscoveryConfig { local_peer_id: PeerId, - /// Number of nodes we're currently connected to. - num_connections: u64, - /// If false, `addresses_of_peer` won't return any private IPv4 address, except for the ones - /// stored in `user_defined`. + user_defined: Vec<(PeerId, Multiaddr)>, allow_private_ipv4: bool, - /// Number of active connections over which we interrupt the discovery process. discovery_only_if_under_num: u64, + enable_mdns: bool, + kademlias: HashMap> } -impl DiscoveryBehaviour { - /// Builds a new `DiscoveryBehaviour`. - /// - /// `user_defined` is a list of known address for nodes that never expire. - pub async fn new( - local_public_key: PublicKey, - user_defined: Vec<(PeerId, Multiaddr)>, - enable_mdns: bool, - allow_private_ipv4: bool, - discovery_only_if_under_num: u64, - ) -> Self { - if enable_mdns { - #[cfg(target_os = "unknown")] - warn!(target: "sub-libp2p", "mDNS is not available on this platform"); +impl DiscoveryConfig { + /// Crate a default configuration with the given public key. + pub fn new(local_public_key: PublicKey) -> Self { + let mut this = DiscoveryConfig { + local_peer_id: local_public_key.into_peer_id(), + user_defined: Vec::new(), + allow_private_ipv4: true, + discovery_only_if_under_num: std::u64::MAX, + enable_mdns: false, + kademlias: HashMap::new() + }; + + // Temporary hack to retain backwards compatibility. + // We should eventually remove the special handling of DEFAULT_PROTO_NAME. + let proto_id = ProtocolId::from(libp2p::kad::protocol::DEFAULT_PROTO_NAME); + let proto_name = Vec::from(proto_id.as_bytes()); + this.add_kademlia(proto_id, proto_name); + + this + } + + /// Set the number of active connections at which we pause discovery. + pub fn discovery_limit(&mut self, limit: u64) -> &mut Self { + self.discovery_only_if_under_num = limit; + self + } + + /// Set custom nodes which never expire, e.g. bootstrap or reserved nodes. + pub fn with_user_defined(&mut self, user_defined: I) -> &mut Self + where + I: IntoIterator + { + for (peer_id, addr) in user_defined { + for kad in self.kademlias.values_mut() { + kad.add_address(&peer_id, addr.clone()) + } + self.user_defined.push((peer_id, addr)) } + self + } + + /// Should private IPv4 addresses be reported? + pub fn allow_private_ipv4(&mut self, value: bool) -> &mut Self { + self.allow_private_ipv4 = value; + self + } - let local_id = local_public_key.clone().into_peer_id(); - let store = MemoryStore::new(local_id.clone()); - let mut kademlia = Kademlia::new(local_id.clone(), store); - for (peer_id, addr) in &user_defined { - kademlia.add_address(peer_id, addr.clone()); + /// Should MDNS discovery be supported? + pub fn with_mdns(&mut self, value: bool) -> &mut Self { + if value && cfg!(target_os = "unknown") { + log::warn!(target: "sub-libp2p", "mDNS is not available on this platform") } + self.enable_mdns = value; + self + } + /// Add discovery via Kademlia for the given protocol. + pub fn add_protocol(&mut self, p: ProtocolId) -> &mut Self { + // NB: If this protocol name derivation is changed, check if + // `DiscoveryBehaviour::new_handler` is still correct. + let proto_name = { + let mut v = vec![b'/']; + v.extend_from_slice(p.as_bytes()); + v.extend_from_slice(b"/kad"); + v + }; + + self.add_kademlia(p, proto_name); + self + } + + fn add_kademlia(&mut self, id: ProtocolId, proto_name: Vec) { + if self.kademlias.contains_key(&id) { + warn!(target: "sub-libp2p", "Discovery already registered for protocol {:?}", id); + return + } + + let mut config = KademliaConfig::default(); + config.set_protocol_name(proto_name); + + let store = MemoryStore::new(self.local_peer_id.clone()); + let mut kad = Kademlia::with_config(self.local_peer_id.clone(), store, config); + + for (peer_id, addr) in &self.user_defined { + kad.add_address(peer_id, addr.clone()); + } + + self.kademlias.insert(id, kad); + } + + /// Create a `DiscoveryBehaviour` from this config. + pub fn finish(self) -> DiscoveryBehaviour { DiscoveryBehaviour { - user_defined, - kademlia, + user_defined: self.user_defined, + kademlias: self.kademlias, next_kad_random_query: Delay::new(Duration::new(0, 0)), duration_to_next_kad: Duration::from_secs(1), discoveries: VecDeque::new(), - local_peer_id: local_public_key.into_peer_id(), + local_peer_id: self.local_peer_id, num_connections: 0, - allow_private_ipv4, - discovery_only_if_under_num, + allow_private_ipv4: self.allow_private_ipv4, + discovery_only_if_under_num: self.discovery_only_if_under_num, #[cfg(not(target_os = "unknown"))] - mdns: if enable_mdns { + mdns: if self.enable_mdns { match Mdns::new() { Ok(mdns) => Some(mdns).into(), Err(err) => { @@ -136,10 +192,43 @@ impl DiscoveryBehaviour { }, } } +} +/// Implementation of `NetworkBehaviour` that discovers the nodes on the network. +pub struct DiscoveryBehaviour { + /// User-defined list of nodes and their addresses. Typically includes bootstrap nodes and + /// reserved nodes. + user_defined: Vec<(PeerId, Multiaddr)>, + /// Kademlia requests and answers. + kademlias: HashMap>, + /// Discovers nodes on the local network. + #[cfg(not(target_os = "unknown"))] + mdns: Toggle, + /// Stream that fires when we need to perform the next random Kademlia query. + next_kad_random_query: Delay, + /// After `next_kad_random_query` triggers, the next one triggers after this duration. + duration_to_next_kad: Duration, + /// Discovered nodes to return. + discoveries: VecDeque, + /// Identity of our local node. + local_peer_id: PeerId, + /// Number of nodes we're currently connected to. + num_connections: u64, + /// If false, `addresses_of_peer` won't return any private IPv4 address, except for the ones + /// stored in `user_defined`. + allow_private_ipv4: bool, + /// Number of active connections over which we interrupt the discovery process. + discovery_only_if_under_num: u64, +} + +impl DiscoveryBehaviour { /// Returns the list of nodes that we know exist in the network. pub fn known_peers(&mut self) -> impl Iterator { - self.kademlia.kbuckets_entries() + let mut set = HashSet::new(); + for p in self.kademlias.values_mut().map(|k| k.kbuckets_entries()).flatten() { + set.insert(p); + } + set.into_iter() } /// Adds a hard-coded address for the given peer, that never expires. @@ -149,7 +238,9 @@ impl DiscoveryBehaviour { /// If we didn't know this address before, also generates a `Discovered` event. pub fn add_known_address(&mut self, peer_id: PeerId, addr: Multiaddr) { if self.user_defined.iter().all(|(p, a)| *p != peer_id && *a != addr) { - self.kademlia.add_address(&peer_id, addr.clone()); + for k in self.kademlias.values_mut() { + k.add_address(&peer_id, addr.clone()) + } self.discoveries.push_back(peer_id.clone()); self.user_defined.push((peer_id, addr)); } @@ -160,14 +251,18 @@ impl DiscoveryBehaviour { /// **Note**: It is important that you call this method, otherwise the discovery mechanism will /// not properly work. pub fn add_self_reported_address(&mut self, peer_id: &PeerId, addr: Multiaddr) { - self.kademlia.add_address(peer_id, addr); + for k in self.kademlias.values_mut() { + k.add_address(peer_id, addr.clone()) + } } /// Start fetching a record from the DHT. /// /// A corresponding `ValueFound` or `ValueNotFound` event will later be generated. pub fn get_value(&mut self, key: &record::Key) { - self.kademlia.get_record(key, Quorum::One) + for k in self.kademlias.values_mut() { + k.get_record(key, Quorum::One) + } } /// Start putting a record into the DHT. Other nodes can later fetch that value with @@ -175,12 +270,14 @@ impl DiscoveryBehaviour { /// /// A corresponding `ValuePut` or `ValuePutFailed` event will later be generated. pub fn put_value(&mut self, key: record::Key, value: Vec) { - self.kademlia.put_record(Record::new(key, value), Quorum::All); + for k in self.kademlias.values_mut() { + k.put_record(Record::new(key.clone(), value.clone()), Quorum::All) + } } /// Returns the number of nodes that are in the Kademlia k-buckets. pub fn num_kbuckets_entries(&mut self) -> usize { - self.kademlia.kbuckets_entries().count() + self.known_peers().count() } } @@ -215,11 +312,19 @@ pub enum DiscoveryOut { } impl NetworkBehaviour for DiscoveryBehaviour { - type ProtocolsHandler = as NetworkBehaviour>::ProtocolsHandler; + type ProtocolsHandler = MultiHandler>; type OutEvent = DiscoveryOut; fn new_handler(&mut self) -> Self::ProtocolsHandler { - NetworkBehaviour::new_handler(&mut self.kademlia) + let iter = self.kademlias.iter_mut() + .map(|(p, k)| (p.clone(), NetworkBehaviour::new_handler(k))); + + MultiHandler::try_from_iter(iter) + .expect("There can be at most one handler per `ProtocolId` and \ + protocol names contain the `ProtocolId` so no two protocol \ + names in `self.kademlias` can be equal which is the only error \ + `try_from_iter` can return, therefore this call is guaranteed \ + to succeed; qed") } fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { @@ -228,7 +333,11 @@ impl NetworkBehaviour for DiscoveryBehaviour { .collect::>(); { - let mut list_to_filter = self.kademlia.addresses_of_peer(peer_id); + let mut list_to_filter = Vec::new(); + for k in self.kademlias.values_mut() { + list_to_filter.extend(k.addresses_of_peer(peer_id)) + } + #[cfg(not(target_os = "unknown"))] list_to_filter.extend(self.mdns.addresses_of_peer(peer_id)); @@ -248,13 +357,23 @@ impl NetworkBehaviour for DiscoveryBehaviour { } trace!(target: "sub-libp2p", "Addresses of {:?} are {:?}", peer_id, list); + if list.is_empty() { - if self.kademlia.kbuckets_entries().any(|p| p == peer_id) { - debug!(target: "sub-libp2p", "Requested dialing to {:?} (peer in k-buckets), \ - and no address was found", peer_id); + let mut has_entry = false; + for k in self.kademlias.values_mut() { + if k.kbuckets_entries().any(|p| p == peer_id) { + has_entry = true; + break + } + } + if has_entry { + debug!(target: "sub-libp2p", + "Requested dialing to {:?} (peer in k-buckets), and no address was found", + peer_id); } else { - debug!(target: "sub-libp2p", "Requested dialing to {:?} (peer not in k-buckets), \ - and no address was found", peer_id); + debug!(target: "sub-libp2p", + "Requested dialing to {:?} (peer not in k-buckets), and no address was found", + peer_id); } } list @@ -262,20 +381,28 @@ impl NetworkBehaviour for DiscoveryBehaviour { fn inject_connection_established(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { self.num_connections += 1; - NetworkBehaviour::inject_connection_established(&mut self.kademlia, peer_id, conn, endpoint) + for k in self.kademlias.values_mut() { + NetworkBehaviour::inject_connection_established(k, peer_id, conn, endpoint) + } } fn inject_connected(&mut self, peer_id: &PeerId) { - NetworkBehaviour::inject_connected(&mut self.kademlia, peer_id) + for k in self.kademlias.values_mut() { + NetworkBehaviour::inject_connected(k, peer_id) + } } fn inject_connection_closed(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { self.num_connections -= 1; - NetworkBehaviour::inject_connection_closed(&mut self.kademlia, peer_id, conn, endpoint) + for k in self.kademlias.values_mut() { + NetworkBehaviour::inject_connection_closed(k, peer_id, conn, endpoint) + } } fn inject_disconnected(&mut self, peer_id: &PeerId) { - NetworkBehaviour::inject_disconnected(&mut self.kademlia, peer_id) + for k in self.kademlias.values_mut() { + NetworkBehaviour::inject_disconnected(k, peer_id) + } } fn inject_addr_reach_failure( @@ -284,45 +411,65 @@ impl NetworkBehaviour for DiscoveryBehaviour { addr: &Multiaddr, error: &dyn std::error::Error ) { - NetworkBehaviour::inject_addr_reach_failure(&mut self.kademlia, peer_id, addr, error) + for k in self.kademlias.values_mut() { + NetworkBehaviour::inject_addr_reach_failure(k, peer_id, addr, error) + } } fn inject_event( &mut self, peer_id: PeerId, connection: ConnectionId, - event: ::OutEvent, + (pid, event): ::OutEvent, ) { - NetworkBehaviour::inject_event(&mut self.kademlia, peer_id, connection, event) + if let Some(kad) = self.kademlias.get_mut(&pid) { + return kad.inject_event(peer_id, connection, event) + } + log::error!(target: "sub-libp2p", + "inject_node_event: no kademlia instance registered for protocol {:?}", + pid) } fn inject_new_external_addr(&mut self, addr: &Multiaddr) { let new_addr = addr.clone() .with(Protocol::P2p(self.local_peer_id.clone().into())); info!(target: "sub-libp2p", "🔍 Discovered new external address for our node: {}", new_addr); - NetworkBehaviour::inject_new_external_addr(&mut self.kademlia, addr) + for k in self.kademlias.values_mut() { + NetworkBehaviour::inject_new_external_addr(k, addr) + } } fn inject_expired_listen_addr(&mut self, addr: &Multiaddr) { info!(target: "sub-libp2p", "No longer listening on {}", addr); - NetworkBehaviour::inject_expired_listen_addr(&mut self.kademlia, addr) + for k in self.kademlias.values_mut() { + NetworkBehaviour::inject_expired_listen_addr(k, addr) + } } fn inject_dial_failure(&mut self, peer_id: &PeerId) { - NetworkBehaviour::inject_dial_failure(&mut self.kademlia, peer_id) + for k in self.kademlias.values_mut() { + NetworkBehaviour::inject_dial_failure(k, peer_id) + } } fn inject_new_listen_addr(&mut self, addr: &Multiaddr) { - NetworkBehaviour::inject_new_listen_addr(&mut self.kademlia, addr) + for k in self.kademlias.values_mut() { + NetworkBehaviour::inject_new_listen_addr(k, addr) + } } fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) { error!(target: "sub-libp2p", "Error on libp2p listener {:?}: {}", id, err); - NetworkBehaviour::inject_listener_error(&mut self.kademlia, id, err); + for k in self.kademlias.values_mut() { + NetworkBehaviour::inject_listener_error(k, id, err) + } } fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &io::Error>) { - NetworkBehaviour::inject_listener_closed(&mut self.kademlia, id, reason); + error!(target: "sub-libp2p", "Libp2p listener {:?} closed", id); + for k in self.kademlias.values_mut() { + NetworkBehaviour::inject_listener_closed(k, id, reason) + } } fn poll( @@ -348,10 +495,10 @@ impl NetworkBehaviour for DiscoveryBehaviour { debug!(target: "sub-libp2p", "Libp2p <= Starting random Kademlia request for {:?}", random_peer_id); - - self.kademlia.get_closest_peers(random_peer_id); + for k in self.kademlias.values_mut() { + k.get_closest_peers(random_peer_id.clone()) + } true - } else { debug!( target: "sub-libp2p", @@ -373,96 +520,102 @@ impl NetworkBehaviour for DiscoveryBehaviour { } } - // Poll Kademlia. - while let Poll::Ready(ev) = self.kademlia.poll(cx, params) { - match ev { - NetworkBehaviourAction::GenerateEvent(ev) => match ev { - KademliaEvent::UnroutablePeer { peer, .. } => { - let ev = DiscoveryOut::UnroutablePeer(peer); - return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); - } - KademliaEvent::RoutingUpdated { peer, .. } => { - let ev = DiscoveryOut::Discovered(peer); - return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); - } - KademliaEvent::GetClosestPeersResult(res) => { - match res { - Err(GetClosestPeersError::Timeout { key, peers }) => { - debug!(target: "sub-libp2p", - "Libp2p => Query for {:?} timed out with {} results", - HexDisplay::from(&key), peers.len()); - }, - Ok(ok) => { - trace!(target: "sub-libp2p", - "Libp2p => Query for {:?} yielded {:?} results", - HexDisplay::from(&ok.key), ok.peers.len()); - if ok.peers.is_empty() && self.num_connections != 0 { - debug!(target: "sub-libp2p", "Libp2p => Random Kademlia query has yielded empty \ - results"); + // Poll Kademlias. + for (pid, kademlia) in &mut self.kademlias { + while let Poll::Ready(ev) = kademlia.poll(cx, params) { + match ev { + NetworkBehaviourAction::GenerateEvent(ev) => match ev { + KademliaEvent::UnroutablePeer { peer, .. } => { + let ev = DiscoveryOut::UnroutablePeer(peer); + return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); + } + KademliaEvent::RoutingUpdated { peer, .. } => { + let ev = DiscoveryOut::Discovered(peer); + return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); + } + KademliaEvent::GetClosestPeersResult(res) => { + match res { + Err(GetClosestPeersError::Timeout { key, peers }) => { + debug!(target: "sub-libp2p", + "Libp2p => Query for {:?} timed out with {} results", + HexDisplay::from(&key), peers.len()); + }, + Ok(ok) => { + trace!(target: "sub-libp2p", + "Libp2p => Query for {:?} yielded {:?} results", + HexDisplay::from(&ok.key), ok.peers.len()); + if ok.peers.is_empty() && self.num_connections != 0 { + debug!(target: "sub-libp2p", "Libp2p => Random Kademlia query has yielded empty \ + results"); + } } } } - } - KademliaEvent::GetRecordResult(res) => { - let ev = match res { - Ok(ok) => { - let results = ok.records - .into_iter() - .map(|r| (r.key, r.value)) - .collect(); - - DiscoveryOut::ValueFound(results) - } - Err(e @ libp2p::kad::GetRecordError::NotFound { .. }) => { - trace!(target: "sub-libp2p", - "Libp2p => Failed to get record: {:?}", e); - DiscoveryOut::ValueNotFound(e.into_key()) - } - Err(e) => { - warn!(target: "sub-libp2p", - "Libp2p => Failed to get record: {:?}", e); - DiscoveryOut::ValueNotFound(e.into_key()) - } - }; - return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); - } - KademliaEvent::PutRecordResult(res) => { - let ev = match res { - Ok(ok) => DiscoveryOut::ValuePut(ok.key), - Err(e) => { - warn!(target: "sub-libp2p", - "Libp2p => Failed to put record: {:?}", e); - DiscoveryOut::ValuePutFailed(e.into_key()) + KademliaEvent::GetRecordResult(res) => { + let ev = match res { + Ok(ok) => { + let results = ok.records + .into_iter() + .map(|r| (r.key, r.value)) + .collect(); + + DiscoveryOut::ValueFound(results) + } + Err(e @ libp2p::kad::GetRecordError::NotFound { .. }) => { + trace!(target: "sub-libp2p", + "Libp2p => Failed to get record: {:?}", e); + DiscoveryOut::ValueNotFound(e.into_key()) + } + Err(e) => { + warn!(target: "sub-libp2p", + "Libp2p => Failed to get record: {:?}", e); + DiscoveryOut::ValueNotFound(e.into_key()) + } + }; + return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); + } + KademliaEvent::PutRecordResult(res) => { + let ev = match res { + Ok(ok) => DiscoveryOut::ValuePut(ok.key), + Err(e) => { + warn!(target: "sub-libp2p", + "Libp2p => Failed to put record: {:?}", e); + DiscoveryOut::ValuePutFailed(e.into_key()) + } + }; + return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); + } + KademliaEvent::RepublishRecordResult(res) => { + match res { + Ok(ok) => debug!(target: "sub-libp2p", + "Libp2p => Record republished: {:?}", + ok.key), + Err(e) => warn!(target: "sub-libp2p", + "Libp2p => Republishing of record {:?} failed with: {:?}", + e.key(), e) } - }; - return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); - } - KademliaEvent::RepublishRecordResult(res) => { - match res { - Ok(ok) => debug!(target: "sub-libp2p", - "Libp2p => Record republished: {:?}", - ok.key), - Err(e) => warn!(target: "sub-libp2p", - "Libp2p => Republishing of record {:?} failed with: {:?}", - e.key(), e) + } + KademliaEvent::Discovered { .. } => { + // We are not interested in these events at the moment. + } + // We never start any other type of query. + e => { + warn!(target: "sub-libp2p", "Libp2p => Unhandled Kademlia event: {:?}", e) } } - KademliaEvent::Discovered { .. } => { - // We are not interested in these events at the moment. - } - // We never start any other type of query. - e => { - warn!(target: "sub-libp2p", "Libp2p => Unhandled Kademlia event: {:?}", e) - } - }, - NetworkBehaviourAction::DialAddress { address } => - return Poll::Ready(NetworkBehaviourAction::DialAddress { address }), - NetworkBehaviourAction::DialPeer { peer_id, condition } => - return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }), - NetworkBehaviourAction::NotifyHandler { peer_id, handler, event } => - return Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, handler, event }), - NetworkBehaviourAction::ReportObservedAddr { address } => - return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }), + NetworkBehaviourAction::DialAddress { address } => + return Poll::Ready(NetworkBehaviourAction::DialAddress { address }), + NetworkBehaviourAction::DialPeer { peer_id, condition } => + return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }), + NetworkBehaviourAction::NotifyHandler { peer_id, handler, event } => + return Poll::Ready(NetworkBehaviourAction::NotifyHandler { + peer_id, + handler, + event: (pid.clone(), event) + }), + NetworkBehaviourAction::ReportObservedAddr { address } => + return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }), + } } } @@ -511,7 +664,7 @@ mod tests { use libp2p::core::upgrade::{InboundUpgradeExt, OutboundUpgradeExt}; use libp2p::swarm::Swarm; use std::{collections::HashSet, task::Poll}; - use super::{DiscoveryBehaviour, DiscoveryOut}; + use super::{DiscoveryConfig, DiscoveryOut}; #[test] fn discovery_working() { @@ -540,13 +693,14 @@ mod tests { upgrade::apply(stream, upgrade, endpoint, upgrade::Version::V1) }); - let behaviour = futures::executor::block_on({ - let user_defined = user_defined.clone(); - let keypair_public = keypair.public(); - async move { - DiscoveryBehaviour::new(keypair_public, user_defined, false, true, 50).await - } - }); + let behaviour = { + let mut config = DiscoveryConfig::new(keypair.public()); + config.with_user_defined(user_defined.clone()) + .allow_private_ipv4(true) + .discovery_limit(50); + config.finish() + }; + let mut swarm = Swarm::new(transport, behaviour, keypair.public().into_peer_id()); let listen_addr: Multiaddr = format!("/memory/{}", rand::random::()).parse().unwrap(); diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 049ca4273d..642f67d14a 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -28,6 +28,7 @@ use crate::{ behaviour::{Behaviour, BehaviourOut}, config::{parse_addr, parse_str_addr, NonReservedPeerMode, Params, Role, TransportConfig}, + discovery::DiscoveryConfig, error::Error, network_state::{ NetworkState, NotConnectedPeer as NetworkStateNotConnectedPeer, Peer as NetworkStatePeer, @@ -310,24 +311,37 @@ impl NetworkWorker { peerset_handle.clone(), ) }; - let mut behaviour = futures::executor::block_on(Behaviour::new( + + let discovery_config = { + let mut config = DiscoveryConfig::new(local_public.clone()); + config.with_user_defined(known_addresses); + config.discovery_limit(u64::from(params.network_config.out_peers) + 15); + config.add_protocol(params.protocol_id.clone()); + + match params.network_config.transport { + TransportConfig::MemoryOnly => { + config.with_mdns(false); + config.allow_private_ipv4(false); + } + TransportConfig::Normal { enable_mdns, allow_private_ipv4, .. } => { + config.with_mdns(enable_mdns); + config.allow_private_ipv4(allow_private_ipv4); + } + } + + config + }; + + let mut behaviour = Behaviour::new( protocol, params.role, user_agent, local_public, - known_addresses, - match params.network_config.transport { - TransportConfig::MemoryOnly => false, - TransportConfig::Normal { enable_mdns, .. } => enable_mdns, - }, - match params.network_config.transport { - TransportConfig::MemoryOnly => false, - TransportConfig::Normal { allow_private_ipv4, .. } => allow_private_ipv4, - }, - u64::from(params.network_config.out_peers) + 15, block_requests, - light_client_handler - )); + light_client_handler, + discovery_config + ); + for (engine_id, protocol_name) in ¶ms.network_config.notifications_protocols { behaviour.register_notifications_protocol(*engine_id, protocol_name.clone()); } -- GitLab From 419bec40c30aa60d76fc9ca348b154e7fef10181 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Thu, 16 Apr 2020 13:08:16 +0300 Subject: [PATCH 241/300] don't use default features to drop some dependencies (#5658) --- Cargo.lock | 30 ------------------------------ client/state-db/Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c1a009425..07c053a4bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1220,33 +1220,6 @@ dependencies = [ "libc", ] -[[package]] -name = "ethbloom" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e7abcddbdd5db30aeed4deb586adc4824e6c247e2f7238d1187f752893f096b" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-rlp", - "impl-serde 0.3.0", - "tiny-keccak 2.0.2", -] - -[[package]] -name = "ethereum-types" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "964c23cdee0ca07d5be2a628b46d5c11a2134ce554a8c16d8dbc2db647e4fd4d" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-rlp", - "impl-serde 0.3.0", - "primitive-types", - "uint", -] - [[package]] name = "evm" version = "0.16.1" @@ -4788,10 +4761,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e42755f26e5ea21a6a819d9e63cbd70713e9867a2b767ec2cc65ca7659532c5" dependencies = [ "cfg-if", - "ethereum-types", - "hashbrown", "impl-trait-for-tuples", - "lru", "parity-util-mem-derive", "parking_lot 0.10.2", "primitive-types", diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index 9fc77c8099..ebb92ca375 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -17,7 +17,7 @@ log = "0.4.8" sc-client-api = { version = "2.0.0-dev", path = "../api" } sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -parity-util-mem = "0.6" +parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } parity-util-mem-derive = "0.1.0" [dev-dependencies] -- GitLab From f2e00d52e50a60a2fae4e31ab7e1b4536919b5d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 16 Apr 2020 12:59:31 +0200 Subject: [PATCH 242/300] Upgrade sysinfo to `0.13.3` (#5659) This release includes a fix for an out of bound access that was reported by one of the validators. --- Cargo.lock | 4 ++-- client/service/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07c053a4bf..a970e50e7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8230,9 +8230,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.12.0" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ccb41798287e8e299a701b5560d886d6ca2c3e7115e9ea2cb68c123aec339b7" +checksum = "5a0338198966bde7feb14b011a33d404a62a6e03b843352c71512a2a002634b7" dependencies = [ "cfg-if", "doc-comment", diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index ba55c68b34..167c3c1436 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -34,7 +34,7 @@ exit-future = "0.2.0" pin-project = "0.4.8" serde = "1.0.101" serde_json = "1.0.41" -sysinfo = "0.12.0" +sysinfo = "0.13.3" sc-keystore = { version = "2.0.0-dev", path = "../keystore" } sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -- GitLab From bd493da310d6c7f7f9b144dc8b90c7e613eaf83f Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Thu, 16 Apr 2020 16:18:16 +0300 Subject: [PATCH 243/300] Trie integrated benchmark (#5616) --- Cargo.lock | 24 +- bin/node/bench/Cargo.toml | 12 + bin/node/bench/src/core.rs | 6 +- bin/node/bench/src/generator.rs | 107 + bin/node/bench/src/main.rs | 9 + bin/node/bench/src/state_sizes.rs | 4756 +++++++++++++++++++++++++++++ bin/node/bench/src/tempdb.rs | 68 + bin/node/bench/src/trie.rs | 238 ++ 8 files changed, 5216 insertions(+), 4 deletions(-) create mode 100644 bin/node/bench/src/generator.rs create mode 100644 bin/node/bench/src/state_sizes.rs create mode 100644 bin/node/bench/src/tempdb.rs create mode 100644 bin/node/bench/src/trie.rs diff --git a/Cargo.lock b/Cargo.lock index a970e50e7c..830157efd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3348,15 +3348,27 @@ dependencies = [ name = "node-bench" version = "0.8.0-dev" dependencies = [ + "derive_more", + "fs_extra", + "hash-db", + "hex", + "kvdb", + "kvdb-rocksdb", + "lazy_static", "log", "node-primitives", "node-testing", + "rand 0.7.3", "sc-cli", "sc-client-api", "serde", "serde_json", + "sp-core", "sp-runtime", + "sp-state-machine", + "sp-trie", "structopt", + "tempfile", ] [[package]] @@ -5283,7 +5295,7 @@ dependencies = [ "rand_isaac", "rand_jitter", "rand_os", - "rand_pcg", + "rand_pcg 0.1.2", "rand_xorshift", "winapi 0.3.8", ] @@ -5299,6 +5311,7 @@ dependencies = [ "rand_chacha 0.2.2", "rand_core 0.5.1", "rand_hc 0.2.0", + "rand_pcg 0.2.1", ] [[package]] @@ -5408,6 +5421,15 @@ dependencies = [ "rand_core 0.4.2", ] +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + [[package]] name = "rand_xorshift" version = "0.1.1" diff --git a/bin/node/bench/Cargo.toml b/bin/node/bench/Cargo.toml index 875a908921..d8f23f2104 100644 --- a/bin/node/bench/Cargo.toml +++ b/bin/node/bench/Cargo.toml @@ -15,6 +15,18 @@ node-testing = { version = "2.0.0-dev", path = "../testing" } sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } sc-client-api = { version = "2.0.0-dev", path = "../../../client/api/" } sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } serde = "1.0.101" serde_json = "1.0.41" structopt = "0.3" +derive_more = "0.99.2" +kvdb = "0.5" +kvdb-rocksdb = "0.7" +sp-trie = { version = "2.0.0-alpha.5", path = "../../../primitives/trie" } +sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } +hash-db = "0.15.2" +tempfile = "3.1.0" +fs_extra = "1" +hex = "0.4.0" +rand = { version = "0.7.2", features = ["small_rng"] } +lazy_static = "1.4.0" diff --git a/bin/node/bench/src/core.rs b/bin/node/bench/src/core.rs index 32039ac891..9105fcbd01 100644 --- a/bin/node/bench/src/core.rs +++ b/bin/node/bench/src/core.rs @@ -68,12 +68,12 @@ impl fmt::Display for NsFormatter { return write!(f, "{} ns", v) } - if self.0 < 10_000 { + if self.0 < 100_000 { return write!(f, "{:.1} µs", v as f64 / 1000.0) } if self.0 < 1_000_000 { - return write!(f, "{:.1} ms", v as f64 / 1_000_000.0) + return write!(f, "{:.2} ms", v as f64 / 1_000_000.0) } if self.0 < 100_000_000 { @@ -105,7 +105,7 @@ impl fmt::Display for BenchmarkOutput { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "({}: avg {}, w_avg {})", + "{}: avg {}, w_avg {}", self.name, NsFormatter(self.raw_average), NsFormatter(self.average), diff --git a/bin/node/bench/src/generator.rs b/bin/node/bench/src/generator.rs new file mode 100644 index 0000000000..8a161c5705 --- /dev/null +++ b/bin/node/bench/src/generator.rs @@ -0,0 +1,107 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use std::{collections::HashMap, sync::Arc}; + +use kvdb::KeyValueDB; +use node_primitives::Hash; +use sp_trie::{DBValue, trie_types::TrieDBMut, TrieMut}; +use hash_db::{HashDB, AsHashDB, Prefix, Hasher as _}; + +type Hasher = sp_core::Blake2Hasher; + +/// Will fill your database `db` with trie data from `key_values` and +/// return root. +pub fn generate_trie( + db: Arc, + key_values: impl IntoIterator, Vec)>, +) -> Hash { + let mut root = Hash::default(); + + let (db, overlay) = { + let mut overlay = HashMap::new(); + overlay.insert( + hex::decode("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").expect("null key is valid"), + Some(vec![0]), + ); + let mut trie_generator = TrieGenerator { db, overlay: &mut overlay }; + { + let mut trie_db = TrieDBMut::new(&mut trie_generator, &mut root); + + for (key, value) in key_values { + trie_db.insert(&key, &value).expect("trie insertion failed"); + } + + trie_db.commit(); + } + ( trie_generator.db, overlay ) + }; + + let mut transaction = db.transaction(); + for (key, value) in overlay.into_iter() { + match value { + Some(value) => transaction.put(0, &key[..], &value[..]), + None => transaction.delete(0, &key[..]), + } + } + db.write(transaction).expect("Failed to write transaction"); + + root +} + +/// Immutable generated trie database with root. +struct TrieGenerator<'a> { + db: Arc, + overlay: &'a mut HashMap, Option>>, +} + +impl<'a> AsHashDB for TrieGenerator<'a> { + fn as_hash_db(&self) -> &dyn hash_db::HashDB { &*self } + + fn as_hash_db_mut<'b>(&'b mut self) -> &'b mut (dyn HashDB + 'b) { + &mut *self + } +} + +impl<'a> HashDB for TrieGenerator<'a> { + fn get(&self, key: &Hash, prefix: Prefix) -> Option { + let key = sp_trie::prefixed_key::(key, prefix); + if let Some(value) = self.overlay.get(&key) { + return value.clone(); + } + self.db.get(0, &key).expect("Database backend error") + } + + fn contains(&self, hash: &Hash, prefix: Prefix) -> bool { + self.get(hash, prefix).is_some() + } + + fn insert(&mut self, prefix: Prefix, value: &[u8]) -> Hash { + let key = Hasher::hash(value); + self.emplace(key, prefix, value.to_vec()); + key + } + + fn emplace(&mut self, key: Hash, prefix: Prefix, value: DBValue) { + let key = sp_trie::prefixed_key::(&key, prefix); + self.overlay.insert(key, Some(value)); + } + + fn remove(&mut self, key: &Hash, prefix: Prefix) { + let key = sp_trie::prefixed_key::(key, prefix); + self.overlay.insert(key, None); + } +} \ No newline at end of file diff --git a/bin/node/bench/src/main.rs b/bin/node/bench/src/main.rs index 0a95a785c9..c821746b33 100644 --- a/bin/node/bench/src/main.rs +++ b/bin/node/bench/src/main.rs @@ -16,9 +16,14 @@ #[macro_use] mod core; mod import; +mod trie; +mod generator; +mod tempdb; +mod state_sizes; use crate::core::{run_benchmark, Mode as BenchmarkMode}; use import::{ImportBenchmarkDescription, SizeType}; +use trie::{TrieBenchmarkDescription, DatabaseSize}; use node_testing::bench::{Profile, KeyTypes}; use structopt::StructOpt; @@ -77,6 +82,10 @@ fn main() { key_types: KeyTypes::Sr25519, size: *size, }, + size in [ + DatabaseSize::Empty, DatabaseSize::Smallest, DatabaseSize::Small, + DatabaseSize::Medium, DatabaseSize::Large, + ] => TrieBenchmarkDescription { database_size: *size }, ); if opt.list { diff --git a/bin/node/bench/src/state_sizes.rs b/bin/node/bench/src/state_sizes.rs new file mode 100644 index 0000000000..d35989f61b --- /dev/null +++ b/bin/node/bench/src/state_sizes.rs @@ -0,0 +1,4756 @@ +// Copyright 2015-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +/// Kusama value size distribution +pub const KUSAMA_STATE_DISTRIBUTION: &'static[(u32, u32)] = &[ + (32, 35), + (33, 20035), + (34, 5369), + (35, 184), + (36, 54599), + (37, 1515056), + (38, 885), + (39, 69965), + (41, 210754), + (42, 467), + (43, 3241), + (44, 32660), + (45, 231141), + (46, 220016), + (47, 248931), + (48, 157232), + (49, 143236), + (50, 2428), + (51, 1476159), + (52, 31), + (53, 112), + (54, 711), + (55, 1934), + (56, 39), + (57, 407), + (58, 6929), + (59, 6568), + (60, 26), + (61, 268673), + (62, 118137), + (63, 84640), + (64, 193232), + (65, 2584210), + (66, 1002), + (67, 2993), + (68, 4266), + (69, 5633381), + (70, 277369), + (71, 5106), + (72, 722), + (73, 1882), + (74, 8178), + (75, 4045), + (76, 1596), + (77, 5335), + (78, 14591), + (79, 9645), + (80, 44171), + (81, 13474), + (82, 51090), + (83, 2595), + (84, 6276), + (85, 382195), + (86, 1062), + (87, 3846), + (88, 5663), + (89, 3811), + (90, 1580), + (91, 5729), + (92, 19144), + (93, 197), + (94, 235), + (95, 545), + (96, 54914), + (97, 3858), + (98, 1610), + (99, 635), + (100, 2481), + (101, 6457), + (102, 3753951), + (103, 11821), + (104, 11114), + (105, 2601), + (106, 2518), + (107, 521925), + (108, 297), + (109, 411), + (110, 668), + (111, 4500), + (112, 704), + (113, 316), + (114, 59), + (115, 291), + (116, 1727), + (117, 6010), + (118, 51874), + (119, 13969), + (120, 9496), + (121, 274), + (122, 810), + (123, 643), + (124, 69), + (125, 41), + (126, 329), + (127, 175435), + (128, 2641), + (129, 2658), + (130, 415277), + (131, 2705), + (132, 2314), + (133, 4290), + (134, 693), + (135, 1957478), + (136, 1111), + (137, 1474503), + (138, 3656), + (139, 940), + (140, 1755692), + (141, 61), + (142, 4140), + (143, 47), + (144, 6725), + (145, 610), + (146, 250), + (147, 48), + (148, 28), + (149, 132), + (150, 123489), + (151, 7476), + (152, 55), + (153, 68), + (154, 170), + (155, 566), + (156, 8110), + (157, 1243), + (158, 1445), + (159, 2569), + (160, 1096), + (161, 865), + (162, 634), + (163, 372411), + (164, 685), + (165, 3481), + (166, 1467), + (167, 2146), + (168, 556539), + (169, 566), + (170, 5080), + (171, 202), + (172, 123), + (173, 100750), + (174, 667), + (175, 433), + (176, 737), + (177, 315), + (178, 317), + (179, 656), + (180, 2522), + (181, 315), + (182, 406), + (183, 4680), + (184, 4941), + (185, 828), + (186, 782), + (187, 565), + (188, 584), + (189, 376), + (190, 321), + (191, 418), + (192, 167), + (193, 362), + (194, 2198), + (195, 180), + (196, 787), + (197, 2680), + (198, 501), + (199, 843), + (200, 287), + (201, 608362), + (202, 1157), + (203, 959), + (204, 1683623), + (205, 440), + (206, 756), + (207, 812), + (208, 1147), + (209, 723), + (210, 856), + (211, 496), + (212, 916), + (213, 615), + (214, 488), + (215, 522), + (216, 8265), + (217, 32574), + (218, 417), + (219, 247), + (220, 579), + (221, 68), + (222, 126), + (223, 306), + (224, 310), + (225, 24), + (226, 37), + (227, 160), + (228, 11), + (229, 3288), + (230, 349), + (231, 23), + (232, 14), + (233, 45), + (234, 452840), + (235, 118), + (236, 741), + (237, 390), + (238, 517), + (239, 694), + (240, 765), + (241, 542), + (242, 417), + (243, 617), + (244, 1307), + (245, 583), + (246, 1640), + (247, 735), + (248, 478), + (249, 4312), + (250, 5426), + (251, 1067), + (252, 435), + (253, 202), + (254, 122), + (255, 486), + (256, 180), + (257, 279), + (258, 406), + (259, 160), + (260, 2759), + (261, 2600), + (262, 686), + (263, 95), + (264, 164), + (265, 150), + (266, 1013), + (267, 552618), + (268, 217), + (269, 188), + (270, 284), + (271, 416), + (272, 453), + (273, 95), + (274, 42), + (275, 68), + (276, 90), + (277, 123), + (278, 340), + (279, 98), + (280, 2795), + (281, 261), + (282, 7370), + (283, 5768), + (284, 3285), + (285, 461), + (286, 363), + (287, 456), + (288, 1475), + (289, 211), + (290, 153), + (291, 282), + (292, 241), + (293, 2924), + (294, 261), + (295, 1070), + (296, 1301), + (297, 688), + (298, 592), + (299, 95), + (300, 686447), + (301, 42), + (302, 385), + (303, 24), + (304, 931), + (305, 49), + (306, 23), + (307, 67), + (308, 32), + (309, 38), + (310, 2), + (311, 7), + (312, 198), + (313, 11), + (314, 38), + (315, 3704), + (316, 7406), + (317, 116), + (318, 229), + (319, 100), + (320, 437), + (321, 244), + (322, 285), + (323, 433), + (324, 382), + (325, 3171), + (326, 761), + (327, 324), + (328, 2264), + (329, 340), + (330, 353), + (331, 110), + (332, 403), + (333, 731366), + (334, 223), + (335, 350), + (336, 600), + (337, 219), + (338, 112), + (339, 10), + (340, 761), + (341, 35), + (342, 99), + (343, 83), + (344, 136), + (345, 7), + (346, 836), + (347, 11), + (348, 10832), + (349, 8931), + (350, 33), + (351, 64), + (352, 66), + (353, 54), + (354, 78), + (355, 198), + (356, 722), + (357, 2647), + (358, 64), + (359, 71), + (360, 2242), + (361, 1462), + (362, 505), + (363, 444), + (364, 597), + (365, 372), + (366, 664852), + (367, 464), + (368, 605), + (369, 123), + (370, 64), + (371, 117), + (372, 328), + (373, 123), + (374, 227), + (375, 151), + (376, 881), + (377, 111), + (378, 30), + (379, 73), + (380, 2126), + (381, 3662), + (382, 9107), + (383, 18), + (384, 294), + (385, 12), + (386, 262), + (387, 127), + (388, 269), + (389, 2566), + (390, 14), + (391, 17), + (392, 80), + (393, 67), + (394, 1470), + (395, 25), + (396, 220), + (397, 131), + (398, 225), + (399, 484755), + (400, 597), + (401, 300), + (402, 253), + (403, 359), + (404, 523), + (405, 311), + (406, 238), + (407, 999), + (408, 424), + (409, 165), + (410, 96), + (411, 248), + (412, 1771), + (413, 139), + (414, 7374), + (415, 11186), + (416, 1355), + (417, 1283666), + (418, 9), + (419, 116), + (420, 3897), + (421, 2554), + (422, 1), + (423, 1), + (424, 16878), + (425, 3198212), + (426, 335), + (427, 1676), + (428, 80), + (429, 19), + (430, 47), + (431, 495), + (432, 421946), + (433, 73), + (434, 95), + (435, 105), + (436, 184), + (437, 56903), + (438, 132), + (439, 87), + (440, 207411), + (441, 230), + (442, 372), + (443, 361), + (444, 387), + (445, 299), + (446, 175), + (447, 7487), + (448, 16346), + (449, 37), + (450, 98313), + (451, 307), + (452, 304), + (453, 2675), + (454, 229), + (455, 130), + (456, 134), + (457, 50), + (458, 238), + (459, 2), + (460, 2267), + (461, 7), + (462, 1), + (463, 8), + (464, 395), + (465, 1279781), + (466, 9), + (467, 12), + (468, 633), + (469, 37), + (470, 13), + (471, 54), + (472, 247), + (473, 82), + (474, 119), + (475, 114), + (476, 332), + (477, 79), + (478, 116), + (479, 128), + (480, 4206), + (481, 20732), + (482, 311), + (483, 343), + (484, 527), + (485, 2750), + (486, 76), + (487, 152), + (488, 510), + (489, 63), + (490, 257), + (491, 79), + (492, 825), + (493, 4198), + (494, 389), + (495, 72), + (496, 1547), + (497, 34), + (498, 631996), + (499, 5), + (500, 2334), + (501, 34), + (502, 7), + (503, 7), + (504, 7682), + (505, 6), + (506, 26), + (507, 22), + (508, 461), + (509, 95), + (510, 36), + (511, 46), + (512, 2741), + (513, 38455), + (514, 29678), + (515, 179), + (516, 1637), + (517, 2597), + (518, 166), + (519, 230), + (520, 2736), + (521, 187), + (522, 361), + (523, 310), + (524, 3327), + (525, 76), + (526, 8070), + (527, 35), + (528, 3310), + (529, 118), + (530, 167), + (531, 214180), + (532, 4597), + (533, 153), + (534, 126), + (535, 23), + (536, 13920), + (537, 10), + (538, 11), + (539, 50), + (540, 50739), + (541, 8), + (542, 347), + (543, 77), + (544, 451575), + (545, 16), + (546, 218814), + (547, 1859026), + (548, 303), + (549, 2511), + (550, 27), + (551, 28), + (552, 188), + (553, 46), + (554, 216), + (555, 63), + (556, 202), + (557, 192), + (558, 257), + (559, 170377), + (560, 902), + (561, 424), + (562, 186), + (563, 145), + (564, 342), + (565, 76), + (566, 41), + (567, 26), + (568, 136), + (569, 1336), + (570, 988), + (571, 131), + (572, 766), + (573, 95), + (574, 57), + (575, 16), + (576, 47), + (577, 63), + (578, 5), + (579, 140), + (580, 1263808), + (581, 2498), + (583, 2), + (584, 706), + (585, 49), + (586, 502), + (587, 16), + (588, 115), + (589, 25), + (590, 31), + (591, 34), + (592, 818), + (593, 60), + (594, 84), + (595, 116), + (596, 446), + (597, 111), + (598, 151), + (599, 153), + (600, 1408), + (601, 165), + (602, 575), + (603, 163), + (604, 309), + (605, 52), + (606, 40), + (607, 116), + (608, 749), + (609, 231), + (610, 171), + (611, 218), + (612, 1145), + (613, 2572), + (614, 27), + (615, 26), + (616, 2060), + (617, 173), + (618, 1094), + (619, 66), + (620, 14235), + (622, 294), + (623, 2), + (624, 79374), + (625, 1), + (626, 3), + (627, 7), + (628, 335), + (629, 27), + (630, 47), + (631, 113), + (632, 589), + (633, 56), + (634, 75), + (635, 85), + (636, 740), + (637, 118), + (638, 180), + (639, 149), + (640, 1169), + (641, 135), + (642, 169), + (643, 170), + (644, 1802), + (645, 2481), + (646, 28), + (647, 78), + (648, 5585), + (649, 173), + (650, 135), + (651, 177), + (652, 6553), + (653, 129), + (654, 55), + (655, 6), + (656, 13250), + (657, 5), + (658, 15), + (659, 3), + (660, 39892), + (661, 28), + (663, 1), + (664, 575061), + (665, 1), + (666, 5), + (667, 73), + (668, 39), + (669, 62), + (670, 50), + (671, 27), + (672, 33), + (673, 48), + (674, 44), + (675, 151), + (676, 70), + (677, 2540), + (678, 150), + (679, 109), + (680, 117), + (681, 95), + (682, 80), + (683, 44), + (684, 34), + (685, 31), + (686, 125), + (687, 146), + (688, 423), + (689, 142), + (690, 154), + (691, 135), + (692, 194), + (693, 48), + (694, 6), + (695, 141), + (696, 47), + (697, 9), + (699, 1), + (701, 1), + (702, 2), + (703, 81), + (704, 3), + (705, 4), + (706, 23), + (707, 131), + (708, 31), + (709, 2458), + (710, 346), + (711, 43), + (712, 46), + (713, 48), + (714, 85), + (715, 119), + (716, 89), + (717, 97), + (718, 95), + (719, 137), + (720, 437), + (721, 64), + (722, 28), + (723, 29), + (724, 121), + (725, 162), + (726, 241), + (727, 219), + (728, 143), + (729, 92), + (730, 100), + (731, 42), + (732, 38), + (733, 60), + (734, 2), + (735, 71), + (736, 12), + (737, 9), + (738, 7), + (739, 193), + (740, 2), + (741, 2404), + (742, 3), + (743, 11), + (744, 5), + (745, 5), + (746, 9), + (747, 16), + (748, 27), + (749, 32), + (750, 57), + (751, 54), + (752, 383), + (753, 61), + (754, 48), + (755, 84), + (756, 108), + (757, 134), + (758, 121), + (759, 160), + (760, 80), + (761, 68), + (762, 192), + (763, 107), + (764, 270), + (765, 58), + (766, 125), + (767, 151), + (768, 75), + (769, 94), + (770, 91), + (771, 187), + (772, 57), + (773, 2371), + (774, 8), + (775, 93), + (776, 107), + (777, 20), + (779, 1), + (780, 22), + (781, 1), + (783, 6), + (784, 318), + (785, 25), + (786, 31), + (787, 23), + (788, 28), + (789, 62), + (790, 53), + (791, 41), + (792, 68), + (793, 60), + (794, 88), + (795, 108), + (796, 63), + (797, 100), + (798, 68), + (799, 72), + (800, 83), + (801, 46), + (802, 36), + (803, 157), + (804, 139), + (805, 2439), + (806, 73), + (807, 81), + (808, 99), + (809, 66), + (810, 45), + (811, 98), + (812, 1), + (814, 31), + (815, 1), + (816, 312), + (818, 155), + (819, 2), + (820, 12), + (821, 27), + (822, 97), + (823, 23), + (824, 7), + (825, 15), + (826, 37), + (827, 39), + (828, 28), + (829, 33), + (830, 53), + (831, 101), + (832, 189), + (833, 94), + (834, 66), + (835, 173), + (836, 74), + (837, 2402), + (838, 64), + (839, 28), + (840, 20), + (841, 13), + (842, 32), + (843, 72), + (844, 68), + (845, 50), + (846, 41), + (847, 114), + (848, 345), + (849, 33), + (850, 17), + (851, 6), + (852, 61), + (853, 101), + (854, 123), + (855, 28), + (856, 3), + (857, 3), + (858, 30), + (859, 12), + (860, 28), + (861, 16), + (862, 20), + (863, 7), + (864, 23), + (865, 28), + (866, 40), + (867, 159), + (868, 40), + (869, 2361), + (870, 92), + (871, 88), + (872, 193), + (873, 61), + (874, 58), + (875, 67), + (876, 65), + (877, 46), + (878, 55), + (879, 30), + (880, 334), + (881, 74), + (882, 121), + (883, 107), + (884, 36), + (885, 66), + (886, 22), + (887, 25), + (888, 24), + (889, 10), + (890, 44), + (891, 5), + (892, 84), + (893, 4), + (894, 1), + (895, 7), + (896, 3), + (897, 8), + (898, 3), + (899, 126), + (900, 13), + (901, 2280), + (902, 74), + (903, 36), + (904, 46), + (905, 52), + (906, 24), + (907, 23), + (908, 43), + (909, 31), + (910, 66), + (911, 65), + (912, 376), + (913, 77), + (914, 85), + (915, 60), + (916, 29), + (917, 64), + (918, 48), + (919, 135), + (920, 21), + (921, 34), + (922, 26), + (923, 22), + (924, 52), + (925, 28), + (926, 142), + (927, 18), + (928, 14), + (929, 30), + (930, 56), + (931, 113), + (933, 2264), + (934, 14), + (935, 4), + (936, 10), + (937, 18), + (938, 2), + (939, 30), + (940, 9), + (941, 29), + (942, 10), + (943, 17), + (944, 296), + (945, 31), + (946, 40), + (947, 26), + (948, 70), + (949, 66), + (950, 44), + (951, 57), + (952, 55), + (953, 56), + (954, 51), + (955, 133), + (956, 39), + (957, 49), + (958, 45), + (959, 26), + (960, 30), + (961, 35), + (962, 40), + (963, 148), + (964, 34), + (965, 2264), + (966, 50), + (967, 21), + (968, 2), + (970, 24), + (972, 45), + (973, 8), + (974, 11), + (975, 20), + (976, 287), + (977, 20), + (978, 6), + (979, 9), + (980, 99), + (981, 32), + (982, 10), + (983, 13), + (984, 26), + (985, 30), + (986, 31), + (987, 38), + (988, 25), + (989, 32), + (990, 44), + (991, 125), + (992, 58), + (993, 44), + (994, 25), + (995, 140), + (996, 25), + (997, 2222), + (998, 16), + (999, 25), + (1000, 38), + (1001, 66), + (1002, 31), + (1003, 38), + (1004, 38), + (1005, 10), + (1006, 7), + (1008, 283), + (1009, 3), + (1010, 1), + (1011, 17), + (1012, 4), + (1013, 51), + (1014, 1), + (1015, 1), + (1016, 3), + (1017, 12), + (1018, 11), + (1019, 21), + (1020, 31), + (1021, 14), + (1022, 14), + (1023, 23), + (1024, 25), + (1025, 42), + (1026, 39), + (1027, 220), + (1028, 33), + (1029, 2206), + (1030, 24), + (1031, 64), + (1032, 36), + (1033, 61), + (1034, 123), + (1035, 32), + (1036, 20), + (1037, 15), + (1038, 11), + (1039, 33), + (1040, 311), + (1041, 58), + (1042, 80), + (1043, 29), + (1044, 10), + (1045, 48), + (1046, 18), + (1047, 22), + (1048, 3), + (1049, 17), + (1050, 1), + (1051, 2), + (1052, 5), + (1053, 4), + (1054, 4), + (1055, 1), + (1056, 4), + (1057, 15), + (1058, 11), + (1059, 135), + (1060, 59), + (1061, 2132), + (1062, 32), + (1063, 116), + (1064, 37), + (1065, 44), + (1066, 42), + (1067, 28), + (1068, 10), + (1069, 36), + (1070, 59), + (1071, 48), + (1072, 332), + (1073, 59), + (1074, 43), + (1075, 19), + (1076, 19), + (1077, 31), + (1078, 31), + (1079, 20), + (1080, 38), + (1081, 58), + (1082, 37), + (1083, 47), + (1084, 19), + (1085, 24), + (1086, 12), + (1087, 26), + (1088, 89), + (1089, 3), + (1091, 108), + (1093, 2112), + (1094, 13), + (1095, 4), + (1096, 4), + (1097, 17), + (1098, 7), + (1099, 105), + (1100, 12), + (1101, 10), + (1102, 17), + (1103, 19), + (1104, 329), + (1105, 28), + (1106, 58), + (1107, 21), + (1108, 22), + (1109, 63), + (1110, 29), + (1111, 53), + (1112, 84), + (1113, 28), + (1114, 30), + (1115, 22), + (1116, 40), + (1117, 16), + (1118, 20), + (1119, 75), + (1120, 43), + (1121, 49), + (1122, 25), + (1123, 118), + (1124, 8), + (1125, 2083), + (1126, 21), + (1127, 3), + (1128, 43), + (1129, 1), + (1130, 1), + (1132, 3), + (1133, 1), + (1134, 3), + (1135, 83), + (1136, 266), + (1137, 7), + (1138, 22), + (1139, 14), + (1140, 30), + (1141, 54), + (1142, 125), + (1143, 44), + (1144, 34), + (1145, 19), + (1146, 21), + (1147, 19), + (1148, 46), + (1149, 45), + (1150, 54), + (1151, 22), + (1152, 30), + (1153, 20), + (1154, 7), + (1155, 143), + (1156, 23), + (1157, 2078), + (1158, 30), + (1159, 23), + (1160, 12), + (1161, 18), + (1162, 6), + (1164, 5), + (1165, 1), + (1168, 254), + (1169, 1), + (1170, 3), + (1171, 95), + (1172, 37), + (1173, 23), + (1174, 7), + (1175, 11), + (1176, 5), + (1177, 14), + (1178, 15), + (1179, 19), + (1180, 10), + (1181, 28), + (1182, 87), + (1183, 35), + (1184, 30), + (1185, 30), + (1186, 38), + (1187, 148), + (1188, 49), + (1189, 2056), + (1190, 42), + (1191, 41), + (1192, 14), + (1193, 36), + (1194, 37), + (1195, 22), + (1196, 108), + (1197, 62), + (1198, 55), + (1199, 43), + (1200, 261), + (1201, 16), + (1202, 1), + (1203, 9), + (1204, 3), + (1205, 32), + (1207, 81), + (1208, 3), + (1210, 3), + (1212, 4), + (1213, 9), + (1214, 5), + (1215, 6), + (1216, 4), + (1217, 8), + (1218, 13), + (1219, 120), + (1220, 11), + (1221, 1989), + (1222, 11), + (1223, 20), + (1224, 15), + (1225, 21), + (1226, 23), + (1227, 50), + (1228, 37), + (1229, 51), + (1230, 37), + (1231, 21), + (1232, 256), + (1233, 26), + (1234, 25), + (1235, 21), + (1236, 79), + (1237, 50), + (1238, 21), + (1239, 2), + (1240, 6), + (1241, 8), + (1243, 95), + (1244, 1), + (1247, 1), + (1248, 1), + (1249, 1), + (1250, 96), + (1251, 112), + (1252, 43), + (1253, 1960), + (1254, 7), + (1255, 13), + (1256, 16), + (1257, 20), + (1258, 19), + (1259, 17), + (1260, 12), + (1261, 5), + (1262, 12), + (1263, 29), + (1264, 272), + (1265, 63), + (1266, 37), + (1267, 36), + (1268, 25), + (1269, 55), + (1270, 38), + (1271, 7), + (1272, 37), + (1273, 10), + (1274, 16), + (1275, 28), + (1276, 18), + (1277, 11), + (1278, 8), + (1279, 91), + (1280, 1), + (1282, 1), + (1283, 110), + (1284, 20), + (1285, 1923), + (1287, 3), + (1288, 1), + (1290, 23), + (1291, 4), + (1292, 4), + (1293, 12), + (1294, 19), + (1295, 8), + (1296, 248), + (1297, 21), + (1298, 12), + (1299, 31), + (1300, 10), + (1301, 60), + (1302, 1), + (1303, 8), + (1304, 99), + (1305, 29), + (1306, 29), + (1307, 28), + (1308, 33), + (1309, 19), + (1310, 8), + (1311, 1), + (1313, 11), + (1314, 12), + (1315, 236), + (1316, 18), + (1317, 1891), + (1318, 2), + (1322, 21), + (1324, 1), + (1326, 8), + (1327, 3), + (1328, 235), + (1329, 4), + (1330, 1), + (1331, 2), + (1332, 5), + (1333, 38), + (1334, 2), + (1335, 30), + (1336, 18), + (1337, 31), + (1338, 8), + (1339, 5), + (1340, 11), + (1341, 9), + (1342, 12), + (1343, 11), + (1344, 79), + (1345, 37), + (1346, 19), + (1347, 136), + (1348, 9), + (1349, 1861), + (1350, 8), + (1351, 112), + (1352, 10), + (1353, 3), + (1354, 16), + (1355, 4), + (1356, 12), + (1357, 18), + (1358, 67), + (1359, 6), + (1360, 229), + (1361, 1), + (1362, 1), + (1364, 1), + (1365, 27), + (1366, 6), + (1368, 14), + (1370, 8), + (1371, 29), + (1372, 3), + (1373, 21), + (1374, 8), + (1375, 6), + (1376, 3), + (1377, 9), + (1378, 9), + (1379, 120), + (1380, 5), + (1381, 1833), + (1382, 45), + (1383, 35), + (1384, 23), + (1385, 25), + (1386, 26), + (1387, 159), + (1388, 24), + (1389, 16), + (1390, 16), + (1391, 14), + (1392, 273), + (1393, 17), + (1394, 9), + (1395, 5), + (1396, 14), + (1397, 24), + (1398, 27), + (1400, 2), + (1404, 5), + (1405, 8), + (1406, 3), + (1407, 25), + (1408, 2), + (1409, 22), + (1410, 10), + (1411, 111), + (1412, 89), + (1413, 1793), + (1414, 4), + (1415, 9), + (1416, 16), + (1417, 13), + (1418, 13), + (1419, 13), + (1420, 15), + (1421, 19), + (1422, 26), + (1423, 110), + (1424, 229), + (1425, 11), + (1426, 10), + (1427, 7), + (1428, 7), + (1429, 28), + (1430, 12), + (1431, 11), + (1432, 14), + (1433, 2), + (1434, 2), + (1436, 1), + (1437, 1), + (1438, 13), + (1439, 1), + (1440, 1), + (1441, 1), + (1442, 2), + (1443, 132), + (1444, 5), + (1445, 1795), + (1448, 11), + (1449, 10), + (1450, 11), + (1451, 8), + (1452, 47), + (1453, 6), + (1454, 8), + (1455, 12), + (1456, 229), + (1457, 15), + (1458, 12), + (1459, 121), + (1460, 15), + (1461, 48), + (1462, 49), + (1463, 22), + (1464, 11), + (1465, 9), + (1466, 81), + (1467, 1), + (1468, 1), + (1469, 6), + (1470, 6), + (1471, 6), + (1472, 9), + (1473, 12), + (1474, 2), + (1475, 109), + (1476, 5), + (1477, 1721), + (1478, 1), + (1479, 28), + (1480, 7), + (1481, 23), + (1482, 2), + (1483, 12), + (1484, 5), + (1485, 3), + (1486, 2), + (1487, 4), + (1488, 219), + (1489, 7), + (1490, 8), + (1491, 10), + (1492, 16), + (1493, 32), + (1494, 25), + (1495, 96), + (1496, 13), + (1497, 15), + (1498, 16), + (1499, 12), + (1500, 14), + (1501, 19), + (1502, 7), + (1503, 11), + (1504, 3), + (1505, 8), + (1506, 41), + (1507, 108), + (1508, 25), + (1509, 1719), + (1510, 8), + (1511, 10), + (1514, 2), + (1515, 25), + (1516, 2), + (1517, 32), + (1518, 6), + (1519, 7), + (1520, 273), + (1521, 2), + (1522, 6), + (1523, 5), + (1524, 6), + (1525, 36), + (1526, 3), + (1527, 12), + (1528, 7), + (1529, 9), + (1530, 12), + (1531, 107), + (1532, 44), + (1533, 17), + (1534, 12), + (1535, 18), + (1536, 12), + (1537, 26), + (1538, 35), + (1539, 131), + (1540, 15), + (1541, 1693), + (1542, 11), + (1543, 7), + (1544, 2), + (1545, 6), + (1546, 14), + (1547, 6), + (1548, 2), + (1549, 24), + (1550, 2), + (1551, 33), + (1552, 206), + (1553, 18), + (1555, 1), + (1556, 7), + (1557, 38), + (1558, 6), + (1559, 3), + (1560, 21), + (1562, 2), + (1563, 5), + (1564, 7), + (1565, 5), + (1566, 6), + (1567, 110), + (1568, 9), + (1569, 16), + (1570, 13), + (1571, 109), + (1572, 6), + (1573, 1664), + (1574, 53), + (1575, 14), + (1576, 21), + (1577, 31), + (1578, 42), + (1579, 13), + (1580, 10), + (1581, 12), + (1582, 11), + (1583, 85), + (1584, 202), + (1585, 7), + (1586, 6), + (1587, 25), + (1588, 5), + (1589, 41), + (1590, 4), + (1591, 5), + (1593, 1), + (1595, 5), + (1596, 11), + (1598, 1), + (1599, 1), + (1600, 1), + (1601, 4), + (1602, 19), + (1603, 200), + (1604, 10), + (1605, 1640), + (1606, 15), + (1607, 14), + (1608, 7), + (1609, 12), + (1610, 5), + (1611, 2), + (1612, 3), + (1613, 7), + (1614, 37), + (1615, 4), + (1616, 203), + (1617, 13), + (1618, 3), + (1619, 12), + (1620, 38), + (1621, 22), + (1622, 12), + (1623, 43), + (1624, 19), + (1625, 35), + (1626, 15), + (1627, 26), + (1628, 43), + (1629, 2), + (1630, 10), + (1631, 1), + (1633, 1), + (1634, 1), + (1635, 110), + (1637, 1612), + (1638, 1), + (1639, 107), + (1640, 1), + (1641, 2), + (1643, 7), + (1644, 9), + (1645, 8), + (1646, 3), + (1647, 19), + (1648, 206), + (1649, 2), + (1650, 9), + (1651, 8), + (1652, 19), + (1653, 22), + (1654, 4), + (1655, 13), + (1656, 3), + (1657, 5), + (1658, 5), + (1659, 35), + (1660, 10), + (1661, 26), + (1662, 8), + (1663, 10), + (1664, 7), + (1665, 4), + (1666, 2), + (1667, 110), + (1668, 12), + (1669, 1594), + (1670, 1), + (1671, 2), + (1672, 15), + (1673, 4), + (1674, 2), + (1675, 303), + (1676, 12), + (1678, 1), + (1680, 194), + (1681, 1), + (1682, 40), + (1683, 2), + (1684, 2), + (1685, 19), + (1686, 16), + (1687, 2), + (1688, 6), + (1689, 9), + (1690, 18), + (1691, 15), + (1692, 5), + (1693, 7), + (1694, 6), + (1695, 32), + (1696, 4), + (1697, 34), + (1698, 1), + (1699, 117), + (1700, 5), + (1701, 1590), + (1702, 20), + (1703, 4), + (1704, 6), + (1705, 20), + (1707, 2), + (1710, 3), + (1711, 89), + (1712, 195), + (1713, 4), + (1714, 2), + (1715, 1), + (1716, 3), + (1717, 16), + (1718, 9), + (1719, 2), + (1720, 3), + (1723, 18), + (1724, 1), + (1725, 2), + (1726, 3), + (1727, 3), + (1728, 9), + (1729, 5), + (1730, 7), + (1731, 132), + (1732, 28), + (1733, 1585), + (1734, 5), + (1735, 3), + (1736, 5), + (1737, 27), + (1738, 4), + (1739, 19), + (1740, 15), + (1741, 4), + (1742, 15), + (1743, 9), + (1744, 183), + (1745, 12), + (1747, 119), + (1748, 1), + (1749, 15), + (1750, 5), + (1754, 1), + (1757, 2), + (1758, 8), + (1759, 7), + (1760, 7), + (1761, 2), + (1762, 13), + (1763, 113), + (1764, 8), + (1765, 1547), + (1766, 7), + (1767, 21), + (1768, 3), + (1769, 34), + (1770, 5), + (1772, 6), + (1773, 7), + (1774, 12), + (1775, 9), + (1776, 189), + (1777, 25), + (1778, 10), + (1779, 4), + (1780, 1), + (1781, 21), + (1782, 3), + (1783, 186), + (1784, 2), + (1787, 1), + (1788, 10), + (1789, 8), + (1790, 1), + (1791, 34), + (1792, 1), + (1793, 1), + (1794, 1), + (1795, 108), + (1796, 4), + (1797, 1519), + (1798, 9), + (1799, 9), + (1800, 3), + (1801, 6), + (1802, 4), + (1803, 35), + (1804, 15), + (1805, 30), + (1806, 5), + (1807, 7), + (1808, 192), + (1809, 8), + (1811, 4), + (1812, 24), + (1813, 36), + (1814, 4), + (1815, 14), + (1816, 2), + (1817, 2), + (1818, 4), + (1819, 72), + (1820, 3), + (1822, 1), + (1823, 4), + (1825, 1), + (1826, 5), + (1827, 104), + (1828, 1), + (1829, 1494), + (1830, 11), + (1831, 5), + (1832, 2), + (1833, 2), + (1834, 2), + (1835, 4), + (1836, 9), + (1837, 1), + (1838, 14), + (1839, 33), + (1840, 188), + (1841, 27), + (1842, 13), + (1843, 10), + (1844, 28), + (1845, 52), + (1846, 17), + (1847, 40), + (1848, 35), + (1849, 6), + (1850, 6), + (1851, 2), + (1853, 4), + (1854, 6), + (1855, 77), + (1856, 1), + (1859, 106), + (1860, 2), + (1861, 1466), + (1863, 2), + (1866, 1), + (1869, 1), + (1870, 2), + (1872, 179), + (1873, 1), + (1874, 9), + (1875, 29), + (1876, 15), + (1877, 43), + (1878, 2), + (1880, 8), + (1881, 13), + (1882, 18), + (1883, 12), + (1884, 14), + (1885, 18), + (1886, 16), + (1887, 6), + (1888, 2), + (1889, 3), + (1890, 9), + (1891, 196), + (1892, 13), + (1893, 1456), + (1894, 14), + (1895, 8), + (1896, 2), + (1898, 1), + (1899, 17), + (1900, 5), + (1901, 1), + (1904, 175), + (1905, 1), + (1906, 2), + (1907, 3), + (1908, 6), + (1909, 10), + (1910, 3), + (1911, 22), + (1912, 6), + (1913, 22), + (1914, 6), + (1915, 10), + (1916, 5), + (1917, 2), + (1918, 6), + (1919, 4), + (1920, 7), + (1921, 14), + (1922, 4), + (1923, 107), + (1924, 10), + (1925, 1434), + (1926, 7), + (1927, 76), + (1928, 4), + (1929, 7), + (1930, 10), + (1931, 14), + (1932, 6), + (1933, 15), + (1934, 4), + (1935, 2), + (1936, 182), + (1937, 2), + (1939, 11), + (1940, 1), + (1941, 4), + (1942, 2), + (1943, 9), + (1944, 1), + (1947, 24), + (1949, 22), + (1952, 15), + (1953, 14), + (1954, 5), + (1955, 111), + (1956, 11), + (1957, 1435), + (1958, 5), + (1959, 5), + (1960, 10), + (1961, 6), + (1962, 11), + (1963, 95), + (1964, 11), + (1965, 7), + (1966, 7), + (1967, 2), + (1968, 182), + (1969, 6), + (1970, 15), + (1972, 7), + (1973, 11), + (1974, 6), + (1975, 2), + (1976, 6), + (1977, 3), + (1978, 2), + (1983, 24), + (1985, 26), + (1986, 3), + (1987, 109), + (1988, 3), + (1989, 1421), + (1990, 1), + (1991, 3), + (1992, 8), + (1993, 4), + (1994, 6), + (1995, 5), + (1996, 13), + (1997, 6), + (1998, 10), + (1999, 92), + (2000, 181), + (2001, 5), + (2002, 5), + (2003, 1), + (2004, 1), + (2005, 14), + (2006, 12), + (2007, 10), + (2008, 7), + (2009, 9), + (2010, 6), + (2011, 8), + (2012, 13), + (2013, 2), + (2014, 2), + (2018, 1), + (2019, 128), + (2021, 1429), + (2022, 4), + (2026, 2), + (2027, 2), + (2030, 7), + (2032, 175), + (2033, 1), + (2035, 90), + (2036, 3), + (2037, 11), + (2038, 2), + (2039, 4), + (2040, 3), + (2041, 2), + (2042, 1), + (2043, 2), + (2044, 5), + (2045, 1), + (2046, 3), + (2047, 21), + (2048, 5), + (2050, 16), + (2051, 120), + (2053, 1403), + (2054, 4), + (2055, 29), + (2057, 26), + (2058, 3), + (2059, 4), + (2060, 4), + (2061, 7), + (2063, 1), + (2065, 170), + (2066, 3), + (2067, 2), + (2068, 7), + (2069, 13), + (2071, 77), + (2072, 1), + (2075, 4), + (2077, 1), + (2078, 2), + (2079, 5), + (2080, 4), + (2081, 3), + (2082, 3), + (2083, 2), + (2084, 293), + (2085, 6), + (2086, 1395), + (2087, 2), + (2089, 4), + (2090, 10), + (2091, 26), + (2092, 14), + (2093, 25), + (2097, 170), + (2099, 2), + (2100, 1), + (2101, 8), + (2102, 5), + (2104, 2), + (2105, 2), + (2107, 90), + (2108, 1), + (2110, 15), + (2112, 1), + (2113, 1), + (2114, 3), + (2115, 8), + (2116, 3), + (2117, 5), + (2118, 1380), + (2119, 4), + (2120, 1), + (2121, 3), + (2122, 1), + (2123, 6), + (2124, 24), + (2125, 1), + (2127, 33), + (2128, 4), + (2129, 197), + (2132, 1), + (2133, 3), + (2134, 8), + (2141, 1), + (2143, 95), + (2144, 6), + (2146, 1), + (2147, 1), + (2148, 3), + (2150, 1369), + (2152, 1), + (2153, 1), + (2155, 5), + (2156, 7), + (2157, 12), + (2158, 2), + (2159, 6), + (2160, 7), + (2161, 174), + (2162, 22), + (2163, 27), + (2164, 5), + (2165, 24), + (2166, 6), + (2169, 8), + (2170, 2), + (2171, 1), + (2172, 1), + (2174, 8), + (2175, 10), + (2176, 2), + (2177, 3), + (2179, 72), + (2180, 4), + (2181, 1), + (2182, 1366), + (2183, 2), + (2184, 5), + (2185, 4), + (2188, 3), + (2191, 1), + (2192, 2), + (2193, 169), + (2198, 7), + (2199, 27), + (2201, 28), + (2205, 2), + (2206, 2), + (2209, 9), + (2213, 8), + (2214, 1364), + (2215, 95), + (2216, 1), + (2217, 2), + (2218, 1), + (2219, 1), + (2220, 3), + (2221, 2), + (2222, 3), + (2223, 41), + (2225, 168), + (2228, 1), + (2229, 6), + (2230, 8), + (2231, 1), + (2232, 2), + (2233, 6), + (2234, 1), + (2235, 41), + (2236, 2), + (2237, 17), + (2240, 7), + (2242, 6), + (2244, 1), + (2246, 1350), + (2249, 2), + (2250, 4), + (2251, 89), + (2252, 1), + (2257, 167), + (2260, 4), + (2261, 3), + (2262, 6), + (2265, 1), + (2269, 2), + (2270, 4), + (2271, 32), + (2273, 21), + (2274, 1), + (2275, 3), + (2276, 1), + (2277, 2), + (2278, 1344), + (2279, 2), + (2280, 1), + (2281, 1), + (2284, 1), + (2287, 98), + (2288, 2), + (2289, 168), + (2292, 3), + (2293, 3), + (2294, 4), + (2298, 3), + (2303, 9), + (2307, 26), + (2308, 1), + (2309, 30), + (2310, 1344), + (2314, 1), + (2318, 1), + (2321, 164), + (2323, 1), + (2324, 82), + (2325, 1), + (2326, 5), + (2327, 1), + (2334, 6), + (2338, 1), + (2339, 1), + (2340, 1), + (2342, 1337), + (2343, 55), + (2344, 27), + (2345, 6), + (2346, 25), + (2347, 1), + (2348, 18), + (2350, 1), + (2351, 3), + (2352, 2), + (2353, 166), + (2358, 6), + (2360, 87), + (2361, 3), + (2362, 1), + (2373, 9), + (2374, 1330), + (2376, 1), + (2377, 1), + (2378, 11), + (2379, 4), + (2380, 28), + (2382, 29), + (2383, 2), + (2384, 8), + (2385, 169), + (2386, 4), + (2387, 9), + (2388, 8), + (2389, 4), + (2390, 15), + (2392, 1), + (2396, 117), + (2397, 4), + (2399, 1), + (2406, 1330), + (2410, 1), + (2414, 1), + (2415, 4), + (2416, 26), + (2417, 164), + (2418, 31), + (2421, 3), + (2422, 4), + (2424, 6), + (2425, 3), + (2426, 3), + (2427, 5), + (2428, 1), + (2429, 2), + (2432, 100), + (2433, 1), + (2435, 1), + (2436, 1), + (2438, 1328), + (2441, 10), + (2443, 11), + (2448, 2), + (2449, 163), + (2451, 1), + (2452, 27), + (2453, 8), + (2454, 24), + (2455, 1), + (2456, 2), + (2457, 2), + (2460, 4), + (2465, 5), + (2466, 3), + (2468, 95), + (2469, 6), + (2470, 1324), + (2471, 1), + (2472, 1), + (2476, 2), + (2477, 2), + (2478, 2), + (2479, 4), + (2481, 163), + (2484, 2), + (2485, 6), + (2486, 2), + (2488, 23), + (2489, 1), + (2490, 26), + (2491, 1), + (2493, 1), + (2494, 1), + (2495, 3), + (2496, 1), + (2500, 3), + (2502, 1327), + (2503, 1), + (2504, 93), + (2505, 2), + (2506, 1), + (2511, 4), + (2513, 166), + (2516, 3), + (2517, 5), + (2518, 8), + (2519, 2), + (2521, 1), + (2524, 27), + (2526, 20), + (2532, 1), + (2534, 1320), + (2535, 1), + (2540, 114), + (2541, 1), + (2543, 1), + (2545, 163), + (2550, 3), + (2555, 3), + (2557, 4), + (2558, 3), + (2559, 2), + (2560, 26), + (2561, 6), + (2562, 26), + (2564, 5), + (2565, 1), + (2566, 1325), + (2567, 5), + (2568, 9), + (2569, 10), + (2570, 2), + (2571, 1), + (2576, 97), + (2577, 165), + (2582, 3), + (2583, 5), + (2593, 2), + (2596, 42), + (2597, 1), + (2598, 1336), + (2602, 1), + (2609, 163), + (2612, 97), + (2613, 1), + (2614, 2), + (2619, 1), + (2621, 2), + (2624, 2), + (2628, 2), + (2630, 1684946), + (2632, 27), + (2633, 2), + (2634, 25), + (2635, 1), + (2637, 4), + (2639, 1), + (2640, 1), + (2641, 163), + (2644, 1), + (2645, 3), + (2646, 2), + (2648, 112), + (2649, 1), + (2653, 5), + (2659, 3), + (2660, 1), + (2661, 1), + (2662, 1315), + (2664, 1), + (2668, 30), + (2669, 1), + (2670, 26), + (2673, 163), + (2674, 2), + (2675, 1), + (2678, 7), + (2679, 1), + (2680, 1), + (2684, 90), + (2685, 1), + (2686, 1), + (2694, 1315), + (2699, 1), + (2701, 1), + (2704, 30), + (2705, 163), + (2706, 27), + (2710, 2), + (2712, 1), + (2720, 112), + (2721, 2), + (2723, 5), + (2726, 1316), + (2736, 1), + (2737, 165), + (2738, 2), + (2740, 25), + (2742, 33), + (2745, 1), + (2756, 97), + (2757, 1), + (2758, 1315), + (2769, 163), + (2774, 3), + (2776, 32), + (2778, 34), + (2781, 1), + (2782, 1), + (2784, 1), + (2790, 1313), + (2792, 94), + (2793, 12), + (2796, 1), + (2800, 1), + (2801, 163), + (2804, 2), + (2805, 6), + (2806, 2), + (2807, 2), + (2809, 1), + (2810, 1), + (2812, 23), + (2814, 33), + (2815, 3), + (2816, 1), + (2820, 2), + (2821, 1), + (2822, 1314), + (2824, 1), + (2828, 104), + (2829, 1), + (2833, 163), + (2837, 6), + (2838, 4), + (2839, 1), + (2848, 32), + (2849, 4), + (2850, 32), + (2852, 4), + (2853, 1), + (2854, 1312), + (2861, 1), + (2863, 52), + (2864, 111), + (2865, 164), + (2868, 2), + (2869, 15), + (2870, 2), + (2871, 1), + (2884, 30), + (2886, 1333), + (2890, 2), + (2891, 2), + (2892, 3), + (2893, 4), + (2894, 2), + (2897, 163), + (2899, 3), + (2900, 230), + (2901, 1), + (2902, 2), + (2908, 2), + (2911, 1), + (2918, 1312), + (2920, 42), + (2922, 25), + (2923, 1), + (2925, 1), + (2929, 165), + (2930, 2), + (2931, 5), + (2932, 4), + (2933, 8), + (2934, 2), + (2936, 110), + (2937, 1), + (2938, 1), + (2939, 1), + (2948, 1), + (2950, 1313), + (2956, 38), + (2958, 32), + (2961, 163), + (2964, 1), + (2966, 4), + (2967, 2), + (2969, 1), + (2971, 1), + (2972, 151), + (2973, 1), + (2975, 3), + (2976, 4), + (2977, 3), + (2978, 1), + (2979, 1), + (2980, 1), + (2982, 1312), + (2992, 28), + (2993, 163), + (2994, 29), + (2998, 2), + (3006, 1), + (3007, 2), + (3008, 188), + (3009, 2), + (3014, 1311), + (3015, 5), + (3016, 9), + (3017, 1), + (3020, 1), + (3025, 164), + (3028, 27), + (3030, 31), + (3044, 223), + (3045, 1), + (3046, 1311), + (3048, 1), + (3057, 163), + (3061, 2), + (3062, 4), + (3064, 41), + (3066, 35), + (3076, 2), + (3078, 1310), + (3080, 151), + (3081, 2), + (3089, 163), + (3094, 2), + (3100, 35), + (3101, 2), + (3102, 38), + (3104, 2), + (3110, 1310), + (3116, 106), + (3117, 2), + (3121, 163), + (3125, 5), + (3126, 2), + (3132, 2), + (3136, 36), + (3138, 39), + (3140, 2), + (3141, 1), + (3142, 1309), + (3143, 1), + (3144, 1), + (3152, 120), + (3153, 164), + (3155, 1), + (3157, 1), + (3158, 2), + (3163, 1), + (3164, 1), + (3172, 34), + (3174, 1343), + (3185, 163), + (3188, 136), + (3189, 1), + (3190, 2), + (3203, 1), + (3204, 1), + (3206, 1308), + (3208, 53), + (3210, 52), + (3217, 163), + (3220, 38), + (3221, 114), + (3222, 2), + (3224, 141), + (3225, 5), + (3230, 1), + (3236, 38), + (3238, 1308), + (3244, 35), + (3246, 46), + (3249, 163), + (3254, 2), + (3260, 105), + (3261, 4), + (3263, 1), + (3270, 1308), + (3280, 38), + (3281, 163), + (3282, 28), + (3286, 3), + (3292, 1), + (3296, 138), + (3297, 1), + (3301, 1), + (3302, 1308), + (3304, 1), + (3313, 163), + (3316, 33), + (3318, 34), + (3329, 1), + (3331, 1), + (3332, 120), + (3333, 1), + (3334, 1309), + (3345, 163), + (3350, 3), + (3352, 34), + (3354, 31), + (3357, 1), + (3366, 1307), + (3368, 230), + (3369, 6), + (3377, 163), + (3382, 2), + (3388, 37), + (3390, 45), + (3398, 1307), + (3404, 3128), + (3405, 2), + (3409, 163), + (3414, 2), + (3424, 40), + (3426, 23), + (3430, 1307), + (3440, 117), + (3441, 164), + (3446, 2), + (3460, 30), + (3462, 1344), + (3469, 1), + (3473, 163), + (3476, 116), + (3477, 1), + (3478, 3), + (3494, 1305), + (3496, 36), + (3498, 38), + (3501, 2), + (3504, 2), + (3505, 163), + (3510, 2), + (3512, 124), + (3513, 4), + (3515, 1), + (3525, 1), + (3526, 1305), + (3532, 27), + (3534, 33), + (3537, 165), + (3541, 2), + (3542, 2), + (3544, 2), + (3548, 119), + (3549, 1), + (3558, 1305), + (3568, 29), + (3569, 163), + (3570, 53), + (3574, 2), + (3581, 6), + (3584, 115), + (3585, 2), + (3590, 1306), + (3601, 163), + (3604, 39), + (3606, 45), + (3620, 107), + (3621, 1), + (3622, 1304), + (3633, 163), + (3634, 1), + (3637, 1), + (3638, 2), + (3640, 43), + (3642, 35), + (3654, 1305), + (3656, 126), + (3657, 2), + (3661, 1), + (3664, 1), + (3665, 163), + (3670, 3), + (3676, 32), + (3678, 48), + (3679, 1), + (3686, 1303), + (3692, 128), + (3693, 2), + (3697, 163), + (3702, 3), + (3712, 33), + (3714, 28), + (3718, 1302), + (3728, 137), + (3729, 165), + (3734, 2), + (3748, 54), + (3749, 1), + (3750, 1333), + (3758, 1), + (3761, 163), + (3764, 125), + (3765, 2), + (3766, 3), + (3782, 1301), + (3784, 32), + (3786, 50), + (3793, 163), + (3798, 2), + (3800, 123), + (3801, 3), + (3805, 1), + (3814, 1301), + (3820, 53), + (3822, 30), + (3825, 163), + (3830, 2), + (3833, 1), + (3836, 109), + (3837, 3), + (3846, 1301), + (3856, 35), + (3857, 163), + (3858, 54), + (3860, 20), + (3861, 51), + (3862, 2), + (3872, 124), + (3873, 2), + (3876, 17), + (3878, 1302), + (3882, 1), + (3889, 163), + (3892, 45), + (3894, 47), + (3901, 2), + (3903, 1), + (3904, 2), + (3908, 138), + (3909, 2), + (3910, 1300), + (3917, 2), + (3921, 163), + (3926, 2), + (3928, 38), + (3930, 37), + (3942, 1300), + (3944, 137), + (3945, 2), + (3953, 163), + (3958, 2), + (3964, 66), + (3966, 37), + (3971, 1), + (3974, 1300), + (3980, 166), + (3981, 1), + (3985, 163), + (3990, 2), + (4000, 35), + (4002, 54), + (4006, 1300), + (4016, 150), + (4017, 164), + (4021, 38), + (4022, 2), + (4024, 38), + (4036, 47), + (4038, 1347), + (4049, 163), + (4052, 134), + (4053, 10), + (4054, 2), + (4068, 1), + (4070, 1300), + (4072, 52), + (4074, 40), + (4075, 1), + (4081, 163), + (4085, 7), + (4086, 2), + (4088, 123), + (4089, 4), + (4100, 2), + (4102, 1300), + (4108, 38), + (4110, 43), + (4113, 163), + (4118, 2), + (4119, 2), + (4124, 159), + (4125, 3), + (4128, 1), + (4134, 1299), + (4141, 1), + (4144, 51), + (4145, 163), + (4146, 41), + (4150, 2), + (4152, 30), + (4160, 153), + (4161, 1), + (4164, 2), + (4166, 1299), + (4177, 163), + (4180, 225), + (4181, 596), + (4182, 50), + (4187, 1), + (4196, 373), + (4197, 3), + (4198, 1299), + (4209, 163), + (4214, 2), + (4216, 66), + (4217, 3), + (4218, 69), + (4221, 1), + (4230, 1299), + (4232, 158), + (4233, 2), + (4241, 163), + (4246, 2), + (4252, 45), + (4253, 1), + (4254, 48), + (4262, 1300), + (4267, 2), + (4268, 145), + (4269, 3), + (4270, 1), + (4271, 1), + (4273, 163), + (4278, 3), + (4288, 75), + (4290, 36), + (4294, 1298), + (4301, 1), + (4304, 173), + (4305, 166), + (4309, 2), + (4310, 2), + (4324, 52), + (4326, 1359), + (4337, 163), + (4340, 195), + (4341, 2), + (4342, 3), + (4358, 1297), + (4360, 76), + (4362, 56), + (4365, 2), + (4369, 163), + (4374, 2), + (4376, 171), + (4377, 1), + (4390, 1298), + (4396, 52), + (4398, 49), + (4401, 163), + (4406, 3), + (4407, 2), + (4412, 170), + (4413, 2), + (4421, 1), + (4422, 1296), + (4432, 57), + (4433, 163), + (4434, 51), + (4436, 1), + (4438, 2), + (4448, 481), + (4449, 2), + (4451, 1), + (4454, 1295), + (4463, 1), + (4465, 163), + (4468, 74), + (4470, 92), + (4484, 448), + (4485, 3), + (4486, 1295), + (4487, 1), + (4497, 163), + (4502, 2), + (4504, 52), + (4506, 65), + (4518, 1295), + (4519, 2), + (4520, 631), + (4521, 3), + (4529, 164), + (4530, 1), + (4532, 1), + (4533, 3), + (4534, 2), + (4540, 55), + (4542, 48), + (4550, 1294), + (4556, 2358), + (4557, 3), + (4561, 163), + (4562, 1), + (4566, 2), + (4576, 58), + (4578, 74), + (4582, 1294), + (4592, 193), + (4593, 167), + (4598, 2), + (4612, 66), + (4614, 1363), + (4621, 2), + (4625, 163), + (4628, 218), + (4629, 3), + (4630, 2), + (4635, 3), + (4640, 1), + (4645, 1), + (4646, 1295), + (4648, 57), + (4650, 90), + (4657, 163), + (4662, 3), + (4664, 194), + (4665, 1), + (4678, 1295), + (4684, 49), + (4685, 1), + (4686, 85), + (4689, 163), + (4694, 4), + (4700, 183), + (4701, 3), + (4710, 1291), + (4720, 61), + (4721, 163), + (4722, 75), + (4726, 3), + (4736, 175), + (4737, 4), + (4742, 1291), + (4753, 163), + (4756, 84), + (4758, 53), + (4772, 210), + (4773, 4), + (4774, 1291), + (4785, 163), + (4790, 2), + (4792, 54), + (4794, 66), + (4799, 2), + (4806, 1292), + (4808, 180), + (4809, 6), + (4817, 164), + (4820, 32), + (4821, 132), + (4822, 3), + (4824, 17), + (4828, 70), + (4830, 62), + (4836, 42), + (4838, 1290), + (4844, 199), + (4845, 3), + (4849, 163), + (4854, 2), + (4864, 104), + (4866, 98), + (4870, 1290), + (4873, 1), + (4880, 184), + (4881, 164), + (4886, 2), + (4900, 88), + (4902, 1387), + (4909, 1), + (4913, 163), + (4916, 187), + (4917, 6), + (4918, 2), + (4934, 1290), + (4936, 65), + (4938, 59), + (4945, 163), + (4948, 1), + (4950, 2), + (4952, 198), + (4953, 3), + (4966, 1290), + (4972, 64), + (4974, 108), + (4977, 163), + (4982, 2), + (4988, 199), + (4989, 8), + (4998, 1290), + (5008, 82), + (5009, 163), + (5010, 113), + (5012, 3), + (5013, 9), + (5014, 2), + (5017, 1), + (5024, 228), + (5025, 2), + (5028, 4), + (5030, 1290), + (5041, 162), + (5044, 96), + (5046, 71), + (5060, 275), + (5061, 6), + (5062, 1291), + (5064, 1), + (5070, 1), + (5073, 162), + (5078, 3), + (5080, 66), + (5082, 153), + (5094, 1289), + (5096, 272), + (5097, 10), + (5101, 2), + (5104, 2), + (5105, 162), + (5110, 2), + (5116, 87), + (5118, 80), + (5126, 1289), + (5132, 266), + (5133, 5), + (5135, 1), + (5137, 162), + (5140, 190), + (5141, 681), + (5142, 2), + (5152, 104), + (5154, 184), + (5156, 238), + (5158, 1289), + (5168, 257), + (5169, 165), + (5174, 2), + (5188, 99), + (5190, 1435), + (5201, 162), + (5204, 228), + (5205, 6), + (5206, 2), + (5221, 206), + (5222, 1289), + (5224, 312), + (5226, 110), + (5231, 1), + (5233, 162), + (5238, 2), + (5240, 266), + (5241, 7), + (5254, 1289), + (5260, 87), + (5262, 243), + (5265, 162), + (5270, 2), + (5274, 8), + (5276, 318), + (5277, 7), + (5286, 1289), + (5288, 86), + (5296, 88), + (5297, 162), + (5298, 123), + (5302, 3), + (5312, 351), + (5313, 1), + (5318, 1289), + (5329, 162), + (5332, 115), + (5334, 173), + (5339, 6), + (5344, 1), + (5348, 313), + (5349, 3), + (5350, 1289), + (5352, 24), + (5353, 14), + (5361, 162), + (5366, 3), + (5368, 157), + (5370, 107), + (5374, 1), + (5382, 1289), + (5384, 293), + (5385, 4), + (5388, 4), + (5393, 162), + (5396, 1), + (5398, 2), + (5404, 142), + (5406, 201), + (5407, 1), + (5414, 1289), + (5417, 3), + (5420, 285), + (5421, 5), + (5423, 1), + (5425, 162), + (5430, 2), + (5436, 1), + (5440, 142), + (5442, 210), + (5444, 1), + (5446, 1294), + (5456, 318), + (5457, 166), + (5462, 3), + (5476, 123), + (5478, 1608), + (5482, 2), + (5489, 162), + (5492, 329), + (5493, 2), + (5494, 2), + (5504, 1), + (5506, 1), + (5510, 1289), + (5511, 1), + (5512, 165), + (5514, 167), + (5521, 163), + (5522, 1), + (5526, 2), + (5528, 367), + (5529, 8), + (5542, 1289), + (5548, 192), + (5550, 291), + (5553, 162), + (5558, 2), + (5564, 399), + (5565, 13), + (5574, 1289), + (5584, 188), + (5585, 163), + (5586, 356), + (5590, 2), + (5592, 1), + (5599, 1), + (5600, 375), + (5601, 3), + (5606, 1290), + (5608, 1), + (5617, 162), + (5618, 1), + (5620, 261), + (5622, 667), + (5623, 1), + (5626, 1), + (5633, 1), + (5636, 406), + (5637, 4), + (5638, 1289), + (5639, 1), + (5649, 162), + (5654, 2), + (5656, 468), + (5658, 1159), + (5662, 1), + (5670, 1289), + (5671, 1), + (5672, 349), + (5673, 8), + (5675, 1), + (5681, 162), + (5686, 2), + (5692, 321), + (5694, 3067), + (5702, 1289), + (5706, 1), + (5708, 443), + (5709, 7), + (5713, 162), + (5718, 2), + (5728, 496), + (5730, 4577), + (5734, 1289), + (5744, 383), + (5745, 165), + (5750, 3), + (5756, 1), + (5758, 1), + (5764, 5847), + (5766, 8966), + (5775, 1), + (5777, 162), + (5780, 616), + (5781, 240), + (5782, 2), + (5784, 1), + (5788, 1), + (5796, 81), + (5798, 1289), + (5799, 1), + (5800, 5543), + (5802, 13287), + (5809, 162), + (5814, 2), + (5816, 409), + (5817, 3), + (5830, 1289), + (5833, 1), + (5836, 123), + (5838, 59), + (5841, 162), + (5846, 2), + (5852, 480), + (5853, 10), + (5862, 1289), + (5872, 191), + (5873, 162), + (5874, 38), + (5878, 2), + (5888, 616), + (5889, 12), + (5894, 1289), + (5905, 162), + (5908, 139), + (5910, 54), + (5922, 1), + (5924, 675), + (5925, 9), + (5926, 1289), + (5937, 162), + (5942, 2), + (5944, 153), + (5946, 48), + (5958, 1289), + (5960, 614), + (5961, 33), + (5969, 162), + (5974, 2), + (5980, 140), + (5982, 95), + (5990, 1289), + (5996, 628), + (5997, 10), + (6001, 162), + (6006, 2), + (6016, 155), + (6018, 67), + (6021, 42), + (6022, 1289), + (6024, 42), + (6032, 772), + (6033, 177), + (6038, 2), + (6049, 1), + (6052, 109), + (6054, 1340), + (6065, 162), + (6068, 749), + (6069, 11), + (6070, 2), + (6086, 1289), + (6088, 364), + (6090, 49), + (6096, 1), + (6097, 162), + (6102, 2), + (6104, 975), + (6105, 4), + (6106, 1), + (6118, 1289), + (6124, 273), + (6126, 58), + (6129, 162), + (6134, 2), + (6138, 1), + (6140, 1053), + (6141, 13), + (6150, 1289), + (6152, 1), + (6153, 2), + (6160, 372), + (6161, 162), + (6162, 70), + (6164, 1), + (6166, 2), + (6172, 1), + (6176, 1088), + (6177, 96), + (6178, 1), + (6182, 1290), + (6188, 4), + (6193, 162), + (6194, 1), + (6196, 346), + (6198, 101), + (6206, 1), + (6212, 1352), + (6213, 4), + (6214, 1290), + (6219, 2), + (6223, 1), + (6225, 162), + (6230, 1), + (6232, 321), + (6234, 170), + (6246, 1290), + (6248, 1755), + (6249, 4), + (6257, 162), + (6261, 4), + (6262, 1), + (6264, 4), + (6268, 616), + (6270, 141), + (6275, 1), + (6278, 1289), + (6280, 1), + (6281, 1), + (6284, 2516), + (6285, 73), + (6289, 162), + (6294, 1), + (6304, 409), + (6306, 163), + (6310, 1289), + (6314, 2), + (6320, 2276), + (6321, 210), + (6326, 1), + (6340, 445), + (6342, 1437), + (6353, 162), + (6356, 4090), + (6357, 55), + (6358, 1), + (6364, 1), + (6374, 1290), + (6376, 929), + (6378, 270), + (6385, 162), + (6390, 1), + (6392, 6135), + (6393, 16), + (6400, 1), + (6406, 1289), + (6412, 607), + (6414, 386), + (6417, 162), + (6420, 1), + (6421, 238), + (6422, 1), + (6424, 238), + (6428, 15189), + (6429, 227), + (6438, 1289), + (6443, 1), + (6448, 1211), + (6449, 162), + (6450, 1135), + (6453, 2), + (6454, 1), + (6464, 66588), + (6465, 77), + (6470, 1289), + (6474, 31), + (6481, 162), + (6484, 21001), + (6486, 9926), + (6488, 95), + (6498, 1), + (6500, 51017), + (6501, 2547), + (6502, 1289), + (6513, 162), + (6518, 1), + (6520, 11978), + (6522, 2546), + (6534, 1289), + (6536, 1), + (6537, 4), + (6539, 7), + (6545, 162), + (6546, 1), + (6550, 1), + (6553, 27), + (6566, 1289), + (6572, 1), + (6573, 2), + (6574, 1), + (6577, 163), + (6582, 2), + (6587, 1), + (6588, 17), + (6598, 1289), + (6600, 1), + (6603, 1), + (6605, 1), + (6606, 2), + (6608, 1), + (6609, 163), + (6610, 1), + (6614, 1), + (6623, 4), + (6630, 1289), + (6631, 1), + (6633, 1), + (6635, 1), + (6640, 1), + (6641, 162), + (6644, 1), + (6645, 2), + (6646, 2), + (6662, 1289), + (6666, 1), + (6670, 1), + (6673, 162), + (6678, 1), + (6679, 1), + (6680, 1), + (6681, 5), + (6686, 1), + (6694, 1289), + (6705, 162), + (6710, 1), + (6711, 1), + (6714, 1), + (6716, 1), + (6717, 10), + (6726, 1289), + (6734, 1), + (6737, 163), + (6738, 1), + (6740, 2), + (6742, 1), + (6752, 1), + (6753, 1), + (6757, 1), + (6758, 1289), + (6769, 162), + (6770, 1), + (6774, 1), + (6775, 1), + (6788, 1), + (6789, 3), + (6790, 1289), + (6797, 1), + (6801, 162), + (6802, 1), + (6803, 1), + (6806, 1), + (6818, 1), + (6819, 1), + (6822, 1289), + (6824, 1), + (6825, 5), + (6833, 162), + (6834, 1), + (6837, 1), + (6838, 1), + (6844, 2), + (6854, 1289), + (6860, 1), + (6861, 5), + (6865, 163), + (6869, 1), + (6870, 1), + (6872, 1), + (6875, 1), + (6881, 3), + (6886, 1289), + (6896, 1), + (6897, 166), + (6902, 1), + (6915, 1), + (6918, 1289), + (6929, 162), + (6932, 2), + (6933, 1), + (6934, 1), + (6947, 1), + (6950, 1290), + (6961, 162), + (6966, 1), + (6969, 2), + (6982, 1289), + (6993, 162), + (6998, 1), + (7004, 1), + (7005, 1), + (7014, 1289), + (7025, 162), + (7030, 1), + (7032, 1), + (7034, 1), + (7040, 1), + (7041, 1), + (7046, 1289), + (7057, 162), + (7058, 1), + (7059, 1), + (7062, 1), + (7070, 1), + (7076, 1), + (7077, 3), + (7078, 1289), + (7084, 1), + (7089, 162), + (7094, 1), + (7110, 1289), + (7112, 1), + (7113, 5), + (7121, 162), + (7124, 1), + (7126, 1), + (7133, 1), + (7142, 1289), + (7148, 1), + (7149, 12), + (7153, 162), + (7158, 1), + (7174, 1289), + (7184, 1), + (7185, 170), + (7190, 1), + (7206, 1289), + (7217, 162), + (7220, 1), + (7221, 82), + (7222, 1), + (7224, 81), + (7229, 1), + (7237, 1), + (7238, 1289), + (7242, 1), + (7243, 1), + (7248, 1), + (7249, 162), + (7254, 1), + (7256, 1), + (7257, 1), + (7266, 4), + (7270, 1289), + (7274, 13), + (7280, 20), + (7281, 162), + (7286, 1), + (7288, 12), + (7292, 1), + (7293, 5), + (7296, 1), + (7302, 1289), + (7308, 1), + (7313, 162), + (7315, 1), + (7318, 1), + (7328, 1), + (7329, 1), + (7334, 1290), + (7345, 162), + (7349, 1), + (7350, 1), + (7353, 1), + (7364, 1), + (7365, 1), + (7366, 1290), + (7377, 162), + (7382, 1), + (7392, 1), + (7398, 1289), + (7400, 1), + (7401, 4), + (7406, 1), + (7409, 162), + (7411, 1), + (7414, 1), + (7430, 1289), + (7431, 3), + (7436, 1), + (7437, 2), + (7441, 162), + (7445, 5), + (7446, 1), + (7448, 1), + (7460, 1), + (7462, 1289), + (7472, 1), + (7473, 166), + (7474, 1), + (7478, 1), + (7494, 1289), + (7505, 162), + (7508, 3), + (7509, 2), + (7510, 2), + (7525, 1), + (7526, 1289), + (7532, 1), + (7537, 162), + (7542, 1), + (7544, 1), + (7545, 9), + (7546, 1), + (7558, 1289), + (7569, 162), + (7574, 1), + (7580, 1), + (7581, 6), + (7590, 1289), + (7601, 162), + (7606, 1), + (7616, 1), + (7617, 6), + (7622, 1289), + (7623, 1), + (7625, 1), + (7633, 162), + (7638, 1), + (7652, 1), + (7653, 11), + (7654, 1289), + (7657, 1), + (7665, 162), + (7670, 1), + (7686, 1289), + (7688, 1), + (7689, 1), + (7697, 162), + (7702, 1), + (7708, 1), + (7715, 1), + (7717, 2), + (7718, 1289), + (7724, 1), + (7725, 3), + (7729, 162), + (7734, 1), + (7746, 1), + (7750, 1289), + (7760, 1), + (7761, 167), + (7766, 1), + (7782, 1289), + (7793, 162), + (7794, 1), + (7796, 1), + (7797, 1), + (7798, 1), + (7814, 1289), + (7820, 1), + (7825, 162), + (7826, 1), + (7830, 1), + (7832, 1), + (7833, 14), + (7842, 1), + (7846, 1289), + (7857, 162), + (7862, 1), + (7863, 1), + (7868, 1), + (7869, 4), + (7878, 1289), + (7885, 1), + (7889, 162), + (7894, 1), + (7904, 1), + (7905, 2), + (7910, 1289), + (7921, 162), + (7926, 1), + (7929, 1), + (7940, 1), + (7941, 2), + (7942, 1289), + (7953, 162), + (7958, 1), + (7963, 1), + (7973, 1), + (7974, 1289), + (7976, 1), + (7977, 16), + (7985, 162), + (7989, 1), + (7990, 1), + (7991, 1), + (7997, 1), + (8000, 1), + (8006, 1289), + (8012, 1), + (8013, 14), + (8017, 162), + (8022, 1), + (8038, 1289), + (8048, 1), + (8049, 185), + (8054, 2), + (8070, 1289), + (8081, 162), + (8084, 1), + (8085, 24), + (8086, 1), + (8102, 1289), + (8113, 162), + (8118, 1), + (8119, 1), + (8120, 1), + (8121, 1), + (8126, 1), + (8134, 1289), + (8140, 1), + (8145, 162), + (8150, 1), + (8157, 20), + (8166, 1289), + (8177, 162), + (8182, 1), + (8192, 1), + (8193, 1), + (8198, 1289), + (8209, 162), + (8214, 1), + (8228, 1), + (8229, 32), + (8230, 1290), + (8246, 1), + (8264, 1), + (8265, 27), + (8269, 1), + (8276, 1), + (8282, 1), + (8300, 1), + (8301, 133), + (8336, 2), + (8337, 60), + (8348, 3), + (8356, 1), + (8358, 1), + (8372, 1), + (8373, 196), + (8408, 1), + (8444, 1), + (8468, 1), + (8480, 1), + (8499, 1), + (8516, 1), + (8552, 1), + (8555, 1), + (8588, 1), + (8624, 1), + (8660, 3), + (8675, 1), + (8696, 1), + (8704, 1), + (8724, 1), + (8732, 1), + (8768, 1), + (8779, 1), + (8804, 1), + (8840, 1), + (8852, 2), + (8876, 1), + (8912, 1), + (8948, 1), + (8984, 1), + (9020, 1), + (9128, 1), + (9164, 1), + (9192, 1), + (9200, 2), + (9236, 1), + (9272, 1), + (9308, 1), + (9344, 1), + (9380, 1), + (9416, 1), + (9452, 1), + (9524, 1), + (9560, 1), + (9589, 1), + (9632, 1), + (9642, 1), + (9704, 1), + (9776, 1), + (9848, 1), + (9992, 1), + (10064, 1), + (10100, 1), + (10136, 1), + (10172, 1), + (10208, 1), + (10244, 1), + (10280, 1), + (10316, 1), + (10388, 1), + (10532, 1), + (10572, 1), + (10620, 1), + (10640, 1), + (10669, 1), + (10748, 1), + (10856, 1), + (10964, 1), + (11067, 1), + (11072, 1), + (11180, 1), + (11216, 1), + (11252, 1), + (11288, 1), + (11324, 1), + (11348, 2), + (11360, 1), + (11396, 1), + (11432, 1), + (11468, 1), + (11504, 1), + (11540, 1), + (11576, 1), + (11612, 1), + (11648, 1), + (11756, 1), + (11792, 1), + (11828, 1), + (11864, 1), + (11936, 1), + (12008, 1), + (12080, 1), + (12152, 1), + (12188, 1), + (12224, 1), + (12260, 1), + (12296, 1), + (12332, 1), + (12360, 1), + (12368, 1), + (12404, 1), + (12440, 1), + (12476, 1), + (12501, 2), + (12512, 1), + (12548, 1), + (12584, 1), + (12620, 1), + (12656, 1), + (12693, 1), + (12728, 1), + (12885, 1), + (13123, 1), + (13269, 1), + (13461, 1), + (13653, 1), + (13664, 1), + (13740, 1), + (13872, 1), + (13946, 1), + (14109, 1), + (14613, 2), + (14805, 2), + (14945, 1), + (14997, 1), + (15176, 1), + (15276, 1), + (15384, 1), + (15492, 1), + (15600, 1), + (15708, 1), + (15716, 1), + (15765, 1), + (15816, 1), + (15924, 1), + (16068, 1), + (16104, 1), + (16140, 1), + (16176, 1), + (16212, 1), + (16248, 1), + (16284, 1), + (16320, 1), + (16356, 1), + (16392, 1), + (16430, 1), + (16468, 1), + (16504, 1), + (16540, 1), + (16727, 2), + (16728, 1), + (16919, 2), + (16921, 1), + (16938, 1), + (17111, 6), + (17413, 1), + (17430, 1), + (17495, 1), + (17880, 1), + (18647, 2), + (18672, 1), + (19223, 38), + (19680, 1), + (20436, 1), + (21156, 1), + (21732, 1), + (22380, 1), + (22992, 1), + (23063, 17), + (23244, 1), + (23532, 1), + (23892, 1), + (24108, 1), + (24215, 1), + (24324, 1), + (24407, 2), + (24504, 1), + (24720, 1), + (24900, 1), + (24983, 205), + (25440, 1), + (25620, 1), + (26088, 1), + (26268, 1), + (26448, 1), + (26664, 1), + (26988, 1), + (27276, 1), + (27492, 1), + (27744, 1), + (28032, 1), + (28284, 1), + (28536, 1), + (28823, 42), + (28896, 1), + (29184, 1), + (29292, 1), + (29400, 1), + (29796, 1), + (29975, 4), + (30156, 1), + (30228, 1), + (30743, 238), + (30768, 1), + (31056, 1), + (31092, 1), + (31416, 1), + (32100, 1), + (32712, 1), + (33144, 1), + (33324, 1), + (33792, 1), + (34008, 1), + (34440, 1), + (34583, 81), + (34656, 1), + (34872, 1), + (34944, 1), + (35160, 1), + (35304, 1), + (35376, 1), + (35412, 1), + (35556, 1), + (35628, 1), + (35664, 1), + (35808, 1), + (36204, 1), + (36744, 1), + (37788, 1), + (39372, 1), + (40956, 1), + (41640, 1), + (41892, 1), + (42144, 1), + (42576, 1), + (42936, 1), + (43476, 1), + (45096, 1), + (47256, 1), + (47760, 1), + (47796, 1), + (47868, 1), + (48228, 1), + (48948, 1), + (49128, 1), + (49452, 1), + (49560, 1), + (49668, 1), + (49776, 1), + (50352, 1), + (50964, 1), + (52008, 1), + (53880, 1), + (55284, 1), + (55860, 1), + (56040, 1), + (56400, 1), + (56904, 1), + (57444, 1), + (59424, 1), + (60156, 1), + (60626, 1), + (60641, 1), + (61260, 1), + (62520, 1), + (64392, 1), + (65976, 1), + (67308, 1), + (68064, 1), + (68748, 1), + (69216, 1), + (69504, 1), + (69648, 1), + (69684, 1), + (69720, 1), + (69756, 1), + (69792, 1), + (69828, 1), + (70224, 1), + (70620, 1), + (71016, 1), + (71412, 1), + (71772, 1), + (71952, 1), + (72024, 1), + (72096, 1), + (72168, 1), + (72240, 1), + (72312, 1), + (72348, 1), + (72420, 1), + (72492, 1), + (72600, 1), + (72672, 1), + (72780, 1), + (72996, 1), + (73320, 1), + (73356, 1), + (73500, 1), + (73536, 1), + (73572, 1), + (73608, 1), + (73680, 1), + (73716, 1), + (73788, 1), + (73896, 1), + (74040, 1), + (74112, 1), + (74170, 1), + (74184, 1), + (74185, 1), + (74220, 1), + (74256, 1), + (74292, 1), + (74328, 1), + (74364, 1), + (74400, 1), + (74436, 1), + (74472, 1), + (74616, 1), + (74976, 1), + (75156, 1), + (75228, 1), + (75336, 1), + (75408, 1), + (75588, 1), + (75696, 1), + (75804, 1), + (75984, 1), + (76056, 1), + (76164, 1), + (76308, 1), + (76452, 1), + (76560, 1), + (76776, 1), + (76920, 1), + (77064, 1), + (77208, 1), + (77316, 1), + (77532, 1), + (77676, 1), + (77748, 1), + (77820, 1), + (77928, 1), + (78000, 1), + (78036, 1), + (78072, 1), + (78108, 1), + (78180, 1), + (78324, 1), + (78396, 1), + (78576, 1), + (78684, 1), + (78828, 1), + (78864, 1), + (78900, 1), + (78972, 1), + (79080, 1), + (79116, 1), + (79152, 1), + (79512, 1), + (79872, 1), + (80268, 1), + (80592, 1), + (80700, 1), + (80916, 1), + (81168, 1), + (81276, 1), + (81528, 1), + (81708, 1), + (81816, 1), + (81888, 1), + (82068, 1), + (82176, 1), + (82284, 1), + (82356, 1), + (82716, 1), + (83004, 1), + (83312, 1), + (83436, 1), + (83688, 1), + (83904, 1), + (84012, 1), + (84408, 1), + (84660, 1), + (85056, 1), + (85488, 1), + (85776, 1), + (85992, 1), + (86172, 1), + (86424, 1), + (86615, 1), + (86640, 1), + (86928, 1), + (87072, 1), + (87288, 1), + (87576, 1), + (87684, 1), + (87756, 1), + (87972, 1), + (88044, 1), + (88152, 1), + (88368, 1), + (88728, 1), + (88836, 1), + (88944, 1), + (89088, 1), + (89448, 1), + (89592, 1), + (89700, 1), + (89808, 1), + (89952, 1), + (90060, 1), + (90204, 1), + (90348, 1), + (90528, 1), + (90636, 1), + (90744, 1), + (90816, 1), + (91032, 1), + (91068, 1), + (91140, 1), + (91212, 1), + (91284, 1), + (91860, 1), + (92112, 1), + (92292, 1), + (92400, 1), + (92544, 1), + (92652, 1), + (92796, 1), + (92904, 1), + (92976, 1), + (93192, 1), + (93300, 1), + (93444, 1), + (93516, 1), + (93624, 1), + (93696, 1), + (93840, 1), + (93984, 1), + (94056, 1), + (94128, 1), + (94164, 1), + (94200, 1), + (94236, 1), + (94272, 1), + (94344, 1), + (94452, 1), + (94524, 1), + (94596, 1), + (94704, 1), + (94776, 1), + (94884, 1), + (94956, 1), + (95172, 1), + (95244, 1), + (95280, 1), + (95316, 1), + (95352, 1), + (95388, 1), + (95424, 1), + (95460, 1), + (95496, 1), + (95604, 1), + (95676, 1), + (95784, 1), + (95856, 1), + (95928, 1), + (96000, 1), + (96036, 1), + (96072, 1), + (96108, 1), + (96144, 1), + (96180, 1), + (96216, 1), + (96288, 1), + (96576, 1), + (98029, 1), + (98304, 1), + (98527, 1), + (98628, 1), + (99276, 1), + (99528, 1), + (99780, 1), + (99996, 1), + (100212, 1), + (100428, 1), + (100680, 1), + (100752, 1), + (100788, 1), + (100860, 1), + (100932, 1), + (101004, 1), + (101076, 1), + (101148, 1), + (101220, 1), + (101256, 1), + (101328, 1), + (101364, 1), + (101400, 1), + (101436, 1), + (101472, 1), + (101508, 1), + (101544, 1), + (101616, 1), + (101652, 1), + (101724, 1), + (101832, 1), + (101904, 1), + (101940, 1), + (101976, 1), + (102012, 1), + (102048, 1), + (102084, 1), + (102120, 1), + (102264, 1), + (102516, 1), + (102588, 1), + (102624, 1), + (102660, 1), + (102696, 1), + (102732, 1), + (102768, 1), + (102804, 1), + (102840, 1), + (102876, 1), + (102912, 1), + (102948, 1), + (102984, 1), + (103056, 1), + (103092, 1), + (103128, 1), + (103164, 1), + (103200, 1), + (103236, 1), + (103272, 1), + (103308, 1), + (103344, 1), + (103380, 1), + (103452, 1), + (103560, 1), + (103596, 1), + (103632, 1), + (103668, 1), + (103704, 1), + (103740, 1), + (103776, 1), + (103848, 1), + (103920, 1), + (103956, 1), + (104028, 1), + (104100, 1), + (104136, 1), + (104208, 1), + (104244, 1), + (104316, 1), + (104352, 1), + (104388, 1), + (104424, 1), + (104460, 1), + (104496, 1), + (104532, 1), + (104568, 1), + (104604, 1), + (104676, 1), + (104712, 1), + (104748, 1), + (104784, 1), + (104820, 1), + (104856, 1), + (104892, 1), + (104928, 1), + (104964, 1), + (105000, 1), + (105036, 1), + (105072, 1), + (105108, 1), + (105216, 1), + (105324, 1), + (105360, 1), + (105396, 1), + (105432, 1), + (105468, 1), + (105504, 1), + (105540, 1), + (105576, 1), + (105612, 1), + (105648, 1), + (105684, 1), + (105720, 1), + (105756, 1), + (105792, 1), + (105828, 1), + (105864, 1), + (105900, 1), + (105936, 1), + (110580, 1), + (115224, 1), + (118788, 1), + (121056, 1), + (121452, 1), + (121848, 1), + (122244, 1), + (122604, 1), + (122928, 1), + (123252, 1), + (123288, 1), + (123360, 1), + (123432, 1), + (123468, 1), + (123504, 1), + (123540, 1), + (123612, 1), + (123684, 1), + (123756, 1), + (123828, 1), + (123900, 1), + (123972, 1), + (124080, 1), + (124188, 1), + (124296, 1), + (124404, 1), + (124548, 1), + (124764, 1), + (124872, 1), + (124980, 1), + (125088, 1), + (125196, 1), + (125304, 1), + (125412, 1), + (125448, 1), + (125520, 1), + (125628, 1), + (125700, 1), + (125772, 1), + (125844, 1), + (125880, 1), + (125916, 1), + (125952, 1), + (125988, 1), + (126024, 1), + (126060, 1), + (126096, 1), + (126168, 1), + (126276, 1), + (126312, 1), + (126348, 1), + (126420, 1), + (126492, 1), + (126564, 1), + (126636, 1), + (126708, 1), + (126780, 1), + (126852, 1), + (126960, 1), + (127068, 1), + (127176, 1), + (127212, 1), + (127248, 1), + (127284, 1), + (127320, 1), + (127356, 1), + (127392, 1), + (127464, 1), + (127536, 1), + (127608, 1), + (127644, 1), + (127680, 1), + (127716, 1), + (127788, 1), + (127860, 1), + (127932, 1), + (128004, 1), + (128076, 1), + (128148, 1), + (128220, 1), + (128256, 1), + (128292, 1), + (128328, 1), + (128364, 1), + (128400, 1), + (128436, 1), + (128472, 1), + (128508, 1), + (128544, 1), + (128580, 1), + (128616, 1), + (128652, 1), + (128688, 1), + (128724, 1), + (128760, 1), + (128832, 1), + (128904, 1), + (128976, 1), + (129048, 1), + (129120, 1), + (129192, 1), + (129228, 1), + (129264, 1), + (129300, 1), + (129372, 1), + (129408, 1), + (129444, 1), + (129480, 1), + (129516, 1), + (129552, 1), + (129588, 1), + (129660, 1), + (129732, 1), + (129768, 1), + (129804, 1), + (129840, 1), + (129876, 1), + (129912, 1), + (129948, 1), + (129984, 1), + (130020, 1), + (130056, 1), + (130128, 1), + (130200, 1), + (130236, 1), + (130272, 1), + (130308, 1), + (130380, 1), + (130452, 1), + (130524, 1), + (130560, 1), + (130596, 1), + (130632, 1), + (130668, 1), + (130704, 1), + (130776, 1), + (130812, 1), + (130848, 1), + (130920, 1), + (130992, 1), + (131064, 1), + (131136, 1), + (131172, 1), + (131208, 1), + (131244, 1), + (131316, 1), + (131388, 1), + (131424, 1), + (131532, 1), + (131640, 1), + (131784, 1), + (131892, 1), + (131964, 1), + (132036, 1), + (132108, 1), + (132180, 1), + (132252, 1), + (132324, 1), + (132360, 1), + (132432, 1), + (132504, 1), + (132576, 1), + (132684, 1), + (132792, 1), + (132900, 1), + (132972, 1), + (133044, 1), + (133116, 1), + (133188, 1), + (133260, 1), + (133332, 1), + (133368, 1), + (133404, 1), + (133440, 1), + (133476, 1), + (133512, 1), + (133548, 1), + (133620, 1), + (133692, 1), + (133764, 1), + (133836, 1), + (133908, 1), + (133980, 1), + (134016, 1), + (134052, 1), + (134088, 1), + (134124, 1), + (134160, 1), + (134196, 1), + (134232, 1), + (134268, 1), + (134304, 1), + (134340, 1), + (134376, 1), + (134412, 1), + (134484, 1), + (134592, 1), + (134700, 1), + (134808, 1), + (134916, 1), + (134988, 1), + (135024, 1), + (135060, 1), + (135096, 1), + (135132, 1), + (135168, 1), + (135204, 1), + (135240, 1), + (135276, 1), + (135312, 1), + (135348, 1), + (135384, 1), + (135456, 1), + (135492, 1), + (135528, 1), + (135564, 1), + (135600, 1), + (135636, 1), + (135672, 1), + (135708, 1), + (135744, 1), + (135780, 1), + (135816, 1), + (135852, 1), + (135888, 1), + (135924, 1), + (135960, 1), + (135996, 1), + (136032, 1), + (136068, 1), + (136140, 1), + (136212, 1), + (136284, 1), + (136356, 1), + (136428, 1), + (136500, 1), + (136572, 1), + (136608, 1), + (136644, 1), + (136680, 1), + (136716, 1), + (136752, 1), + (136788, 1), + (136824, 1), + (136860, 1), + (136896, 1), + (136932, 1), + (136968, 1), + (137004, 1), + (137040, 1), + (137076, 1), + (137112, 1), + (137148, 1), + (137184, 1), + (137256, 1), + (137328, 1), + (137400, 1), + (137472, 1), + (137544, 1), + (137580, 1), + (137616, 1), + (137652, 1), + (137688, 1), + (137724, 1), + (137796, 1), + (137832, 1), + (137868, 1), + (137904, 1), + (137940, 1), + (137976, 1), + (138012, 1), + (138048, 1), + (138084, 1), + (138120, 1), + (138228, 1), + (138300, 1), + (138336, 1), + (138372, 1), + (138408, 1), + (138444, 1), + (138480, 1), + (138516, 1), + (138552, 1), + (138588, 1), + (138624, 1), + (138696, 1), + (138768, 1), + (138840, 1), + (138912, 1), + (138948, 1), + (138984, 1), + (139020, 1), + (139056, 1), + (139092, 1), + (139128, 1), + (139164, 1), + (139200, 1), + (139272, 1), + (139308, 1), + (139380, 1), + (139452, 1), + (139488, 1), + (139524, 1), + (139596, 1), + (139632, 1), + (139668, 1), + (139704, 1), + (139740, 1), + (139776, 1), + (139848, 1), + (139884, 1), + (139920, 1), + (139956, 1), + (139992, 1), + (140028, 1), + (140064, 1), + (140136, 1), + (140172, 1), + (140208, 1), + (140244, 1), + (140280, 1), + (140316, 1), + (140352, 1), + (140424, 1), + (140460, 1), + (140496, 1), + (140532, 1), + (140604, 1), + (140640, 1), + (140676, 1), + (140712, 1), + (140748, 1), + (140784, 1), + (140820, 1), + (140856, 1), + (140928, 1), + (141036, 1), + (141072, 1), + (141108, 1), + (141144, 1), + (141180, 1), + (141216, 1), + (141252, 1), + (141324, 1), + (141396, 1), + (141432, 1), + (141468, 1), + (141504, 1), + (141612, 1), + (142152, 1), + (142188, 1), + (142260, 1), + (142296, 1), + (142800, 1), + (143304, 1), + (143376, 1), + (143448, 1), + (143520, 1), + (143592, 1), + (143664, 1), + (143700, 1), + (143736, 1), + (143772, 1), + (143808, 1), + (143844, 1), + (143880, 1), + (143952, 1), + (144096, 1), + (144240, 1), + (144348, 1), + (144456, 1), + (144564, 1), + (144672, 1), + (144708, 1), + (144744, 1), + (144780, 1), + (144816, 1), + (144852, 1), + (144888, 1), + (144924, 1), + (144960, 1), + (144996, 1), + (145032, 1), + (145068, 1), + (145104, 1), + (145140, 1), + (145176, 1), + (145212, 1), + (145248, 1), + (145284, 1), + (145320, 1), + (145356, 1), + (145392, 1), + (145464, 1), + (145500, 1), + (145536, 1), + (145572, 1), + (145644, 1), + (145716, 1), + (145752, 1), + (145788, 1), + (145824, 1), + (145860, 1), + (145896, 1), + (145932, 1), + (145968, 1), + (146004, 1), + (146040, 1), + (146076, 1), + (146112, 1), + (146148, 1), + (146184, 1), + (146220, 1), + (146256, 1), + (146292, 1), + (146328, 1), + (146364, 1), + (146400, 1), + (146436, 1), + (146472, 1), + (146508, 1), + (146544, 1), + (146580, 1), + (146616, 1), + (146652, 1), + (146688, 1), + (146724, 1), + (146760, 1), + (146796, 1), + (146832, 1), + (146868, 1), + (146940, 1), + (146976, 1), + (147012, 1), + (147048, 1), + (147084, 1), + (147120, 1), + (147156, 1), + (147192, 1), + (147228, 1), + (147264, 1), + (147300, 1), + (147336, 1), + (147372, 1), + (147408, 1), + (147444, 1), + (147480, 1), + (147516, 1), + (147552, 1), + (147588, 1), + (147624, 1), + (147660, 1), + (147732, 1), + (147768, 1), + (147804, 1), + (147840, 1), + (147876, 1), + (147912, 1), + (147948, 1), + (147984, 1), + (148020, 1), + (148056, 1), + (148092, 1), + (148128, 1), + (148164, 1), + (148200, 1), + (148236, 1), + (148272, 1), + (1070556, 1), + (1079378, 1), + (1085421, 1), + (1086835, 1), + (1121118, 1), + (1121208, 1), + (1124515, 1), + (1128287, 1), + (1128379, 1), + (1153308, 1), + (1153342, 4), + (1153344, 5), + (1153398, 1), + (1153571, 1), + (1153663, 1), + (1153670, 1), + (1153672, 3), + (1153688, 3), + (1154504, 1), + (1154538, 5), + (1154540, 6), + (1154596, 1), + (1164963, 1), + (1165053, 1), + (1166494, 1), + (1166586, 1), + (1175528, 1), + (1175636, 1), + (1177016, 1), + (1193653, 1), + (1193743, 1), + (1205060, 1), + (1205152, 1), + (1323322, 1), + (1323414, 1), + (1336354, 1), + (1336444, 1), + (1348925, 1), + (1349015, 1), + (1353326, 1), + (1353418, 1), + (1426757, 1), + (1426845, 1), + (1426847, 1), + (1426937, 1), + (1476463, 1), + (1476553, 1), + (1516580, 1), + (1516670, 1), + (1605731, 1), + (1605821, 1), +]; \ No newline at end of file diff --git a/bin/node/bench/src/tempdb.rs b/bin/node/bench/src/tempdb.rs new file mode 100644 index 0000000000..067db6a565 --- /dev/null +++ b/bin/node/bench/src/tempdb.rs @@ -0,0 +1,68 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use std::sync::Arc; +use kvdb::KeyValueDB; +use kvdb_rocksdb::{DatabaseConfig, Database}; + +pub struct TempDatabase(tempfile::TempDir); + +impl TempDatabase { + pub fn new() -> Self { + let dir = tempfile::tempdir().expect("temp dir creation failed"); + log::trace!( + target: "bench-logistics", + "Created temp db at {}", + dir.path().to_string_lossy(), + ); + + TempDatabase(dir) + } + + pub fn open(&mut self) -> Arc { + let db_cfg = DatabaseConfig::with_columns(1); + let db = Database::open(&db_cfg, &self.0.path().to_string_lossy()).expect("Database backend error"); + Arc::new(db) + } +} + +impl Clone for TempDatabase { + fn clone(&self) -> Self { + let new_dir = tempfile::tempdir().expect("temp dir creation failed"); + let self_dir = self.0.path(); + + log::trace!( + target: "bench-logistics", + "Cloning db ({}) to {}", + self_dir.to_string_lossy(), + new_dir.path().to_string_lossy(), + ); + let self_db_files = std::fs::read_dir(self_dir) + .expect("failed to list file in seed dir") + .map(|f_result| + f_result.expect("failed to read file in seed db") + .path() + .clone() + ).collect(); + fs_extra::copy_items( + &self_db_files, + new_dir.path(), + &fs_extra::dir::CopyOptions::new(), + ).expect("Copy of seed database is ok"); + + TempDatabase(new_dir) + } +} diff --git a/bin/node/bench/src/trie.rs b/bin/node/bench/src/trie.rs new file mode 100644 index 0000000000..6f75741fa7 --- /dev/null +++ b/bin/node/bench/src/trie.rs @@ -0,0 +1,238 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Trie benchmark (integrated). + +use std::{borrow::Cow, sync::Arc}; +use kvdb::KeyValueDB; +use lazy_static::lazy_static; +use rand::Rng; +use hash_db::Prefix; +use sp_state_machine::Backend as _; + +use node_primitives::Hash; + +use crate::{ + core::{self, Mode, Path}, + generator::generate_trie, + tempdb::TempDatabase, +}; + +pub const SAMPLE_SIZE: usize = 100; + +pub type KeyValues = Vec<(Vec, Vec)>; + +#[derive(Clone, Copy, Debug, derive_more::Display)] +pub enum DatabaseSize { + #[display(fmt = "empty")] + Empty, + #[display(fmt = "smallest")] + Smallest, + #[display(fmt = "small")] + Small, + #[display(fmt = "medium")] + Medium, + #[display(fmt = "large")] + Large, + #[display(fmt = "largest")] + Largest, +} + +lazy_static! { + static ref KUSAMA_STATE_DISTRIBUTION: SizePool = + SizePool::from_histogram(crate::state_sizes::KUSAMA_STATE_DISTRIBUTION); +} + +impl DatabaseSize { + /// Should be multiple of SAMPLE_SIZE! + fn keys(&self) -> usize { + let val = match *self { + Self::Empty => 200, // still need some keys to query + Self::Smallest => 1_000, + Self::Small => 10_000, + Self::Medium => 100_000, + Self::Large => 200_000, + Self::Largest => 1_000_000, + }; + + assert_eq!(val % SAMPLE_SIZE, 0); + + val + } +} + +pub struct TrieBenchmarkDescription { + pub database_size: DatabaseSize, +} + +pub struct TrieBenchmark { + database: TempDatabase, + root: Hash, + warmup_keys: KeyValues, + query_keys: KeyValues, +} + +impl core::BenchmarkDescription for TrieBenchmarkDescription { + fn path(&self) -> Path { + let mut path = Path::new(&["trie"]); + path.push(&format!("{}", self.database_size)); + path + } + + fn setup(self: Box) -> Box { + let mut database = TempDatabase::new(); + + // TODO: make seedable + let mut rng = rand::thread_rng(); + let warmup_prefix = KUSAMA_STATE_DISTRIBUTION.key(&mut rng); + + let mut key_values = KeyValues::new(); + let mut warmup_keys = KeyValues::new(); + let mut query_keys = KeyValues::new(); + let every_x_key = self.database_size.keys() / SAMPLE_SIZE; + for idx in 0..self.database_size.keys() { + let kv = ( + KUSAMA_STATE_DISTRIBUTION.key(&mut rng).to_vec(), + KUSAMA_STATE_DISTRIBUTION.value(&mut rng), + ); + if idx % every_x_key == 0 { + // warmup keys go to separate tree with high prob + let mut actual_warmup_key = warmup_prefix.clone(); + actual_warmup_key[16..].copy_from_slice(&kv.0[16..]); + warmup_keys.push((actual_warmup_key.clone(), kv.1.clone())); + key_values.push((actual_warmup_key.clone(), kv.1.clone())); + } else if idx % every_x_key == 1 { + query_keys.push(kv.clone()); + } + + key_values.push(kv) + } + + assert_eq!(warmup_keys.len(), SAMPLE_SIZE); + assert_eq!(query_keys.len(), SAMPLE_SIZE); + + let root = generate_trie( + database.open(), + key_values, + ); + + Box::new(TrieBenchmark { + database, + root, + warmup_keys, + query_keys, + }) + } + + fn name(&self) -> Cow<'static, str> { + + fn pretty_print(v: usize) -> String { + let mut print = String::new(); + for (idx, val) in v.to_string().chars().rev().enumerate() { + if idx != 0 && idx % 3 == 0 { + print.insert(0, ','); + } + print.insert(0, val); + } + print + } + + format!( + "Trie benchmark({} database ({} keys))", + self.database_size, + pretty_print(self.database_size.keys()), + ).into() + } +} + +struct Storage(Arc); + +impl sp_state_machine::Storage for Storage { + fn get(&self, key: &Hash, prefix: Prefix) -> Result>, String> { + let key = sp_trie::prefixed_key::(key, prefix); + self.0.get(0, &key).map_err(|e| format!("Database backend error: {:?}", e)) + } +} + +impl core::Benchmark for TrieBenchmark { + fn run(&mut self, mode: Mode) -> std::time::Duration { + let mut db = self.database.clone(); + let storage: Arc> = + Arc::new(Storage(db.open())); + + let trie_backend = sp_state_machine::TrieBackend::new( + storage, + self.root, + ); + for (warmup_key, warmup_value) in self.warmup_keys.iter() { + let value = trie_backend.storage(&warmup_key[..]) + .expect("Failed to get key: db error") + .expect("Warmup key should exist"); + + // sanity for warmup keys + assert_eq!(&value, warmup_value); + } + + if mode == Mode::Profile { + std::thread::park_timeout(std::time::Duration::from_secs(3)); + } + + let started = std::time::Instant::now(); + for (key, _) in self.query_keys.iter() { + let _ = trie_backend.storage(&key[..]); + } + let elapsed = started.elapsed(); + + if mode == Mode::Profile { + std::thread::park_timeout(std::time::Duration::from_secs(1)); + } + + elapsed / (SAMPLE_SIZE as u32) + } +} + +struct SizePool { + distribution: std::collections::BTreeMap, + total: u32, +} + +impl SizePool { + fn from_histogram(h: &[(u32, u32)]) -> SizePool { + let mut distribution = std::collections::BTreeMap::default(); + let mut total = 0; + for (size, count) in h { + total += count; + distribution.insert(total, *size); + } + SizePool { distribution, total } + } + + fn value(&self, rng: &mut R) -> Vec { + let sr = (rng.next_u64() % self.total as u64) as u32; + let mut range = self.distribution.range((std::ops::Bound::Included(sr), std::ops::Bound::Unbounded)); + let size = *range.next().unwrap().1 as usize; + let mut v = Vec::new(); + v.resize(size, 0); + rng.fill_bytes(&mut v); + v + } + + fn key(&self, rng: &mut R) -> Vec { + let mut key = [0u8; 32]; + rng.fill_bytes(&mut key[..]); + key.to_vec() + } +} \ No newline at end of file -- GitLab From 36683a1a1a572d7834d6e475d257bd467a78326c Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 16 Apr 2020 15:18:35 +0200 Subject: [PATCH 244/300] Several tweaks to networking Prometheus metrics (#5636) --- client/network/src/service.rs | 86 ++++++++++++++---------- client/network/src/service/out_events.rs | 20 +++--- 2 files changed, 64 insertions(+), 42 deletions(-) diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 642f67d14a..89ddf6fafd 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -859,12 +859,12 @@ pub struct NetworkWorker { struct Metrics { // This list is ordered alphabetically - connections: GaugeVec, connections_closed_total: CounterVec, + connections_opened_total: CounterVec, import_queue_blocks_submitted: Counter, import_queue_finality_proofs_submitted: Counter, import_queue_justifications_submitted: Counter, - incoming_connections_errors_total: Counter, + incoming_connections_errors_total: CounterVec, incoming_connections_total: Counter, is_major_syncing: Gauge, issued_light_requests: Counter, @@ -874,7 +874,8 @@ struct Metrics { network_per_sec_bytes: GaugeVec, notifications_queues_size: HistogramVec, notifications_sizes: HistogramVec, - opened_notification_streams: GaugeVec, + notifications_streams_closed_total: CounterVec, + notifications_streams_opened_total: CounterVec, peers_count: Gauge, peerset_num_discovered: Gauge, peerset_num_requested: Gauge, @@ -887,19 +888,19 @@ impl Metrics { fn register(registry: &Registry) -> Result { Ok(Self { // This list is ordered alphabetically - connections: register(GaugeVec::new( + connections_closed_total: register(CounterVec::new( Opts::new( - "sub_libp2p_connections", - "Number of established libp2p connections" + "sub_libp2p_connections_closed_total", + "Total number of connections closed, by reason and direction" ), - &["direction"] + &["direction", "reason"] )?, registry)?, - connections_closed_total: register(CounterVec::new( + connections_opened_total: register(CounterVec::new( Opts::new( - "sub_libp2p_connections_closed_total", - "Total number of connections closed, by reason" + "sub_libp2p_connections_opened_total", + "Total number of connections opened" ), - &["reason"] + &["direction"] )?, registry)?, import_queue_blocks_submitted: register(Counter::new( "import_queue_blocks_submitted", @@ -913,9 +914,13 @@ impl Metrics { "import_queue_justifications_submitted", "Number of justifications submitted to the import queue.", )?, registry)?, - incoming_connections_errors_total: register(Counter::new( - "sub_libp2p_incoming_connections_handshake_errors_total", - "Total number of incoming connections that have failed during the initial handshake" + incoming_connections_errors_total: register(CounterVec::new( + Opts::new( + "sub_libp2p_incoming_connections_handshake_errors_total", + "Total number of incoming connections that have failed during the \ + initial handshake" + ), + &["reason"] )?, registry)?, incoming_connections_total: register(Counter::new( "sub_libp2p_incoming_connections_total", @@ -966,10 +971,17 @@ impl Metrics { }, &["direction", "protocol"] )?, registry)?, - opened_notification_streams: register(GaugeVec::new( + notifications_streams_closed_total: register(CounterVec::new( Opts::new( - "sub_libp2p_opened_notification_streams", - "Number of open notification substreams" + "sub_libp2p_notifications_streams_closed_total", + "Total number of notification substreams that have been closed" + ), + &["protocol"] + )?, registry)?, + notifications_streams_opened_total: register(CounterVec::new( + Opts::new( + "sub_libp2p_notifications_streams_opened_total", + "Total number of notification substreams that have been opened" ), &["protocol"] )?, registry)?, @@ -1002,10 +1014,10 @@ impl Metrics { fn update_with_network_event(&self, event: &Event) { match event { Event::NotificationStreamOpened { engine_id, .. } => { - self.opened_notification_streams.with_label_values(&[&engine_id_to_string(&engine_id)]).inc(); + self.notifications_streams_opened_total.with_label_values(&[&engine_id_to_string(&engine_id)]).inc(); }, Event::NotificationStreamClosed { engine_id, .. } => { - self.opened_notification_streams.with_label_values(&[&engine_id_to_string(&engine_id)]).dec(); + self.notifications_streams_closed_total.with_label_values(&[&engine_id_to_string(&engine_id)]).inc(); }, Event::NotificationsReceived { messages, .. } => { for (engine_id, message) in messages { @@ -1129,34 +1141,33 @@ impl Future for NetworkWorker { if let Some(metrics) = this.metrics.as_ref() { match endpoint { ConnectedPoint::Dialer { .. } => - metrics.connections.with_label_values(&["out"]).inc(), + metrics.connections_opened_total.with_label_values(&["out"]).inc(), ConnectedPoint::Listener { .. } => - metrics.connections.with_label_values(&["in"]).inc(), + metrics.connections_opened_total.with_label_values(&["in"]).inc(), } } }, Poll::Ready(SwarmEvent::ConnectionClosed { peer_id, cause, endpoint, .. }) => { trace!(target: "sub-libp2p", "Libp2p => Disconnected({:?}, {:?})", peer_id, cause); if let Some(metrics) = this.metrics.as_ref() { - match endpoint { - ConnectedPoint::Dialer { .. } => - metrics.connections.with_label_values(&["out"]).dec(), - ConnectedPoint::Listener { .. } => - metrics.connections.with_label_values(&["in"]).dec(), - } + let dir = match endpoint { + ConnectedPoint::Dialer { .. } => "out", + ConnectedPoint::Listener { .. } => "in", + }; + match cause { ConnectionError::IO(_) => - metrics.connections_closed_total.with_label_values(&["transport-error"]).inc(), + metrics.connections_closed_total.with_label_values(&[dir, "transport-error"]).inc(), ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( EitherError::A(EitherError::B(EitherError::A(PingFailure::Timeout))))))) => - metrics.connections_closed_total.with_label_values(&["ping-timeout"]).inc(), + metrics.connections_closed_total.with_label_values(&[dir, "ping-timeout"]).inc(), ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( EitherError::A(EitherError::A(EitherError::B(LegacyConnectionKillError))))))) => - metrics.connections_closed_total.with_label_values(&["force-closed"]).inc(), + metrics.connections_closed_total.with_label_values(&[dir, "force-closed"]).inc(), ConnectionError::Handler(NodeHandlerWrapperError::Handler(_)) => - metrics.connections_closed_total.with_label_values(&["protocol-error"]).inc(), + metrics.connections_closed_total.with_label_values(&[dir, "protocol-error"]).inc(), ConnectionError::Handler(NodeHandlerWrapperError::KeepAliveTimeout) => - metrics.connections_closed_total.with_label_values(&["keep-alive-timeout"]).inc(), + metrics.connections_closed_total.with_label_values(&[dir, "keep-alive-timeout"]).inc(), } } }, @@ -1214,14 +1225,21 @@ impl Future for NetworkWorker { trace!(target: "sub-libp2p", "Libp2p => IncomingConnectionError({},{}): {}", local_addr, send_back_addr, error); if let Some(metrics) = this.metrics.as_ref() { - metrics.incoming_connections_errors_total.inc(); + let reason = match error { + PendingConnectionError::ConnectionLimit(_) => "limit-reached", + PendingConnectionError::InvalidPeerId => "invalid-peer-id", + PendingConnectionError::Transport(_) | + PendingConnectionError::IO(_) => "transport-error", + }; + + metrics.incoming_connections_errors_total.with_label_values(&[reason]).inc(); } }, Poll::Ready(SwarmEvent::BannedPeer { peer_id, endpoint }) => { trace!(target: "sub-libp2p", "Libp2p => BannedPeer({}). Connected via {:?}.", peer_id, endpoint); if let Some(metrics) = this.metrics.as_ref() { - metrics.incoming_connections_errors_total.inc(); + metrics.incoming_connections_errors_total.with_label_values(&["banned"]).inc(); } }, Poll::Ready(SwarmEvent::UnknownPeerUnreachableAddr { address, error }) => diff --git a/client/network/src/service/out_events.rs b/client/network/src/service/out_events.rs index b279be3c22..cda53246de 100644 --- a/client/network/src/service/out_events.rs +++ b/client/network/src/service/out_events.rs @@ -35,7 +35,7 @@ use super::engine_id_to_string; use futures::{prelude::*, channel::mpsc, ready}; use parking_lot::Mutex; -use prometheus_endpoint::{register, CounterVec, Gauge, Opts, PrometheusError, Registry, U64}; +use prometheus_endpoint::{register, CounterVec, GaugeVec, Opts, PrometheusError, Registry, U64}; use std::{ convert::TryFrom as _, fmt, pin::Pin, sync::Arc, @@ -77,7 +77,7 @@ impl Drop for Sender { fn drop(&mut self) { let metrics = self.metrics.lock(); if let Some(Some(metrics)) = metrics.as_ref().map(|m| &**m) { - metrics.num_channels.dec(); + metrics.num_channels.with_label_values(&[self.name]).dec(); } } } @@ -151,11 +151,12 @@ impl OutChannels { debug_assert!(metrics.is_none()); *metrics = Some(self.metrics.clone()); drop(metrics); - self.event_streams.push(sender); if let Some(metrics) = &*self.metrics { - metrics.num_channels.inc(); + metrics.num_channels.with_label_values(&[sender.name]).inc(); } + + self.event_streams.push(sender); } /// Sends an event. @@ -184,7 +185,7 @@ struct Metrics { // This list is ordered alphabetically events_total: CounterVec, notifications_sizes: CounterVec, - num_channels: Gauge, + num_channels: GaugeVec, } impl Metrics { @@ -206,9 +207,12 @@ impl Metrics { ), &["protocol", "action", "name"] )?, registry)?, - num_channels: register(Gauge::new( - "sub_libp2p_out_events_num_channels", - "Number of internal active channels that broadcast network events", + num_channels: register(GaugeVec::new( + Opts::new( + "sub_libp2p_out_events_num_channels", + "Number of internal active channels that broadcast network events", + ), + &["name"] )?, registry)?, }) } -- GitLab From 64c0dd70a30e8dddc37d8f7ae477a4b538d92397 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 16 Apr 2020 17:09:13 +0200 Subject: [PATCH 245/300] client/authority-discovery: Rework error handling (#5631) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * client/authority-discovery: Rework error handling Instead of `handle_dht_events` returning a `Result<(), Error>`, return a `Poll` where `Poll::Pending` signals that there are no more events to handle and `Poll::Ready(Error)` signals that a fatal error occured. Non fatal errors are handled within `handle_dht_events` directly, thus looping in `poll` is not necessary anymore. * client/authority-discovery: Return () instead of error on termiantion * Update client/authority-discovery/src/lib.rs Co-Authored-By: André Silva <123550+andresilva@users.noreply.github.com> Co-authored-by: Bastian Köcher Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> --- client/authority-discovery/src/error.rs | 3 - client/authority-discovery/src/lib.rs | 112 +++++++++++++----------- client/authority-discovery/src/tests.rs | 12 ++- 3 files changed, 68 insertions(+), 59 deletions(-) diff --git a/client/authority-discovery/src/error.rs b/client/authority-discovery/src/error.rs index 751e3e76e9..b1358485c3 100644 --- a/client/authority-discovery/src/error.rs +++ b/client/authority-discovery/src/error.rs @@ -40,9 +40,6 @@ pub enum Error { MatchingHashedAuthorityIdWithAuthorityId, /// Failed to set the authority discovery peerset priority group in the peerset module. SettingPeersetPriorityGroup(String), - /// The sender side of the dht event stream has been closed likely due to the network - /// terminating. - DhtEventStreamTerminated, /// Failed to encode a protobuf payload. EncodingProto(prost::EncodeError), /// Failed to decode a protobuf payload. diff --git a/client/authority-discovery/src/lib.rs b/client/authority-discovery/src/lib.rs index 8086cd959d..5142dd7259 100644 --- a/client/authority-discovery/src/lib.rs +++ b/client/authority-discovery/src/lib.rs @@ -51,7 +51,7 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use futures::task::{Context, Poll}; -use futures::{Future, FutureExt, Stream, StreamExt}; +use futures::{Future, FutureExt, ready, Stream, StreamExt}; use futures_timer::Delay; use codec::{Decode, Encode}; @@ -80,6 +80,8 @@ mod schema { type Interval = Box + Unpin + Send + Sync>; +const LOG_TARGET: &'static str = "sub-authority-discovery"; + /// Upper bound estimation on how long one should wait before accessing the Kademlia DHT. const LIBP2P_KADEMLIA_BOOTSTRAP_TIME: Duration = Duration::from_secs(30); @@ -174,7 +176,7 @@ where match Metrics::register(®istry) { Ok(metrics) => Some(metrics), Err(e) => { - error!(target: "sub-authority-discovery", "Failed to register metrics: {:?}", e); + error!(target: LOG_TARGET, "Failed to register metrics: {:?}", e); None }, } @@ -282,10 +284,15 @@ where Ok(()) } - fn handle_dht_events(&mut self, cx: &mut Context) -> Result<()> { + /// Handle incoming Dht events. + /// + /// Returns either: + /// - Poll::Pending when there are no more events to handle or + /// - Poll::Ready(()) when the dht event stream terminated. + fn handle_dht_events(&mut self, cx: &mut Context) -> Poll<()>{ loop { - match self.dht_event_rx.poll_next_unpin(cx) { - Poll::Ready(Some(DhtEvent::ValueFound(v))) => { + match ready!(self.dht_event_rx.poll_next_unpin(cx)) { + Some(DhtEvent::ValueFound(v)) => { if let Some(metrics) = &self.metrics { metrics.dht_event_received.with_label_values(&["value_found"]).inc(); } @@ -293,47 +300,52 @@ where if log_enabled!(log::Level::Debug) { let hashes = v.iter().map(|(hash, _value)| hash.clone()); debug!( - target: "sub-authority-discovery", + target: LOG_TARGET, "Value for hash '{:?}' found on Dht.", hashes, ); } - self.handle_dht_value_found_event(v)?; + if let Err(e) = self.handle_dht_value_found_event(v) { + error!( + target: LOG_TARGET, + "Failed to handle Dht value found event: {:?}", e, + ); + } } - Poll::Ready(Some(DhtEvent::ValueNotFound(hash))) => { + Some(DhtEvent::ValueNotFound(hash)) => { if let Some(metrics) = &self.metrics { metrics.dht_event_received.with_label_values(&["value_not_found"]).inc(); } debug!( - target: "sub-authority-discovery", + target: LOG_TARGET, "Value for hash '{:?}' not found on Dht.", hash ) }, - Poll::Ready(Some(DhtEvent::ValuePut(hash))) => { + Some(DhtEvent::ValuePut(hash)) => { if let Some(metrics) = &self.metrics { metrics.dht_event_received.with_label_values(&["value_put"]).inc(); } debug!( - target: "sub-authority-discovery", + target: LOG_TARGET, "Successfully put hash '{:?}' on Dht.", hash, ) }, - Poll::Ready(Some(DhtEvent::ValuePutFailed(hash))) => { + Some(DhtEvent::ValuePutFailed(hash)) => { if let Some(metrics) = &self.metrics { metrics.dht_event_received.with_label_values(&["value_put_failed"]).inc(); } warn!( - target: "sub-authority-discovery", + target: LOG_TARGET, "Failed to put hash '{:?}' on Dht.", hash ) }, - // The sender side of the dht event stream has been closed, likely due to the - // network terminating. - Poll::Ready(None) => return Err(Error::DhtEventStreamTerminated), - Poll::Pending => return Ok(()), + None => { + debug!(target: LOG_TARGET, "Dht event stream terminated."); + return Poll::Ready(()); + }, } } } @@ -442,7 +454,7 @@ where let addresses = self.addr_cache.get_subset(); debug!( - target: "sub-authority-discovery", + target: LOG_TARGET, "Applying priority group {:?} to peerset.", addresses, ); self.network @@ -464,46 +476,42 @@ where type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { - let mut inner = || -> Result<()> { - // Process incoming events before triggering new ones. - self.handle_dht_events(cx)?; - - if let Poll::Ready(_) = self.publish_interval.poll_next_unpin(cx) { - // Make sure to call interval.poll until it returns Async::NotReady once. Otherwise, - // in case one of the function calls within this block do a `return`, we don't call - // `interval.poll` again and thereby the underlying Tokio task is never registered - // with Tokio's Reactor to be woken up on the next interval tick. - while let Poll::Ready(_) = self.publish_interval.poll_next_unpin(cx) {} - - self.publish_ext_addresses()?; - } + // Process incoming events. + if let Poll::Ready(()) = self.handle_dht_events(cx) { + // `handle_dht_events` returns `Poll::Ready(())` when the Dht event stream terminated. + // Termination of the Dht event stream implies that the underlying network terminated, + // thus authority discovery should terminate as well. + return Poll::Ready(()); + } - if let Poll::Ready(_) = self.query_interval.poll_next_unpin(cx) { - // Make sure to call interval.poll until it returns Async::NotReady once. Otherwise, - // in case one of the function calls within this block do a `return`, we don't call - // `interval.poll` again and thereby the underlying Tokio task is never registered - // with Tokio's Reactor to be woken up on the next interval tick. - while let Poll::Ready(_) = self.query_interval.poll_next_unpin(cx) {} - self.request_addresses_of_others()?; - } + // Publish own addresses. + if let Poll::Ready(_) = self.publish_interval.poll_next_unpin(cx) { + // Register waker of underlying task for next interval. + while let Poll::Ready(_) = self.publish_interval.poll_next_unpin(cx) {} - Ok(()) - }; - - loop { - match inner() { - Ok(()) => return Poll::Pending, + if let Err(e) = self.publish_ext_addresses() { + error!( + target: LOG_TARGET, + "Failed to publish external addresses: {:?}", e, + ); + } + } - // Handle fatal errors. - // - // Given that the network likely terminated authority discovery should do the same. - Err(Error::DhtEventStreamTerminated) => return Poll::Ready(()), + // Request addresses of authorities. + if let Poll::Ready(_) = self.query_interval.poll_next_unpin(cx) { + // Register waker of underlying task for next interval. + while let Poll::Ready(_) = self.query_interval.poll_next_unpin(cx) {} - // Handle non-fatal errors. - Err(e) => error!(target: "sub-authority-discovery", "Poll failure: {:?}", e), - }; + if let Err(e) = self.request_addresses_of_others() { + error!( + target: LOG_TARGET, + "Failed to request addresses of authorities: {:?}", e, + ); + } } + + Poll::Pending } } diff --git a/client/authority-discovery/src/tests.rs b/client/authority-discovery/src/tests.rs index 78ff5f33c2..79c50818c4 100644 --- a/client/authority-discovery/src/tests.rs +++ b/client/authority-discovery/src/tests.rs @@ -286,6 +286,7 @@ fn request_addresses_of_others_triggers_dht_get_query() { #[test] fn handle_dht_events_with_value_found_should_call_set_priority_group() { let _ = ::env_logger::try_init(); + // Create authority discovery. let (mut dht_event_tx, dht_event_rx) = channel(1000); @@ -331,7 +332,9 @@ fn handle_dht_events_with_value_found_should_call_set_priority_group() { // Make authority discovery handle the event. let f = |cx: &mut Context<'_>| -> Poll<()> { - authority_discovery.handle_dht_events(cx).unwrap(); + if let Poll::Ready(e) = authority_discovery.handle_dht_events(cx) { + panic!("Unexpected error: {:?}", e); + } // Expect authority discovery to set the priority set. assert_eq!(network.set_priority_group_call.lock().unwrap().len(), 1); @@ -439,15 +442,16 @@ fn dont_stop_polling_when_error_is_returned() { // Now we call `await` and give the control to the authority discovery future. assert_eq!(Some(Event::Processed), discovery_update_rx.next().await); - // Drop the event rx to stop the authority discovery. If it was polled correctly, it should - // end properly. + // Drop the event rx to stop the authority discovery. If it was polled correctly, it + // should end properly. drop(dht_event_tx); assert!( discovery_update_rx.collect::>() .await .into_iter() - .any(|evt| evt == Event::End), "The authority should have ended", + .any(|evt| evt == Event::End), + "The authority discovery should have ended", ); } ); -- GitLab From 3f8b4a93daa737fa94fb7193f5f6ada93cb9bdee Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 16 Apr 2020 17:36:14 +0200 Subject: [PATCH 246/300] Add alternative RPC methods to system_networkState (#5643) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add alternatives to system_networkState * Fix tests * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga Co-authored-by: Tomasz Drwięga --- client/network/src/service.rs | 12 ++++++++++++ client/rpc-api/src/system/mod.rs | 11 +++++++++++ client/rpc/src/system/mod.rs | 17 +++++++++++++++++ client/rpc/src/system/tests.rs | 28 ++++++++++++++++++++++++++++ client/service/src/lib.rs | 11 +++++++++++ 5 files changed, 79 insertions(+) diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 89ddf6fafd..d9e970a61a 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -478,6 +478,18 @@ impl NetworkWorker { self.network_service.user_protocol_mut().on_block_finalized(hash, &header); } + /// Returns the local `PeerId`. + pub fn local_peer_id(&self) -> &PeerId { + Swarm::::local_peer_id(&self.network_service) + } + + /// Returns the list of addresses we are listening on. + /// + /// Does **NOT** include a trailing `/p2p/` with our `PeerId`. + pub fn listen_addresses(&self) -> impl Iterator { + Swarm::::listeners(&self.network_service) + } + /// Get network state. /// /// **Note**: Use this only for debugging. This API is unstable. There are warnings literally diff --git a/client/rpc-api/src/system/mod.rs b/client/rpc-api/src/system/mod.rs index 25f147b694..e66ac97a68 100644 --- a/client/rpc-api/src/system/mod.rs +++ b/client/rpc-api/src/system/mod.rs @@ -59,6 +59,17 @@ pub trait SystemApi { #[rpc(name = "system_health", returns = "Health")] fn system_health(&self) -> Receiver; + /// Returns the base58-encoded PeerId of the node. + #[rpc(name = "system_localPeerId", returns = "String")] + fn system_local_peer_id(&self) -> Receiver; + + /// Returns the multiaddresses that the local node is listening on + /// + /// The addresses include a trailing `/p2p/` with the local PeerId, and are thus suitable to + /// be passed to `system_addReservedPeer` or as a bootnode address for example. + #[rpc(name = "system_localListenAddresses", returns = "Vec")] + fn system_local_listen_addresses(&self) -> Receiver>; + /// Returns currently connected peers #[rpc(name = "system_peers", returns = "Vec>")] fn system_peers(&self) -> Receiver>>; diff --git a/client/rpc/src/system/mod.rs b/client/rpc/src/system/mod.rs index e18d4d09a1..84e06c20a6 100644 --- a/client/rpc/src/system/mod.rs +++ b/client/rpc/src/system/mod.rs @@ -41,6 +41,11 @@ pub struct System { pub enum Request { /// Must return the health of the network. Health(oneshot::Sender), + /// Must return the base58-encoded local `PeerId`. + LocalPeerId(oneshot::Sender), + /// Must return the string representation of the addresses we listen on, including the + /// trailing `/p2p/`. + LocalListenAddresses(oneshot::Sender>), /// Must return information about the peers we are connected to. Peers(oneshot::Sender::Number>>>), /// Must return the state of the network. @@ -96,6 +101,18 @@ impl SystemApi::Number> for Sy Receiver(Compat::new(rx)) } + fn system_local_peer_id(&self) -> Receiver { + let (tx, rx) = oneshot::channel(); + let _ = self.send_back.unbounded_send(Request::LocalPeerId(tx)); + Receiver(Compat::new(rx)) + } + + fn system_local_listen_addresses(&self) -> Receiver> { + let (tx, rx) = oneshot::channel(); + let _ = self.send_back.unbounded_send(Request::LocalListenAddresses(tx)); + Receiver(Compat::new(rx)) + } + fn system_peers(&self) -> Receiver::Number>>> { let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::Peers(tx)); diff --git a/client/rpc/src/system/tests.rs b/client/rpc/src/system/tests.rs index f0331f50ed..921d941a1c 100644 --- a/client/rpc/src/system/tests.rs +++ b/client/rpc/src/system/tests.rs @@ -55,6 +55,15 @@ fn api>>(sync: T) -> System { should_have_peers, }); }, + Request::LocalPeerId(sender) => { + let _ = sender.send("QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV".to_string()); + }, + Request::LocalListenAddresses(sender) => { + let _ = sender.send(vec![ + "/ip4/198.51.100.19/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV".to_string(), + "/ip4/127.0.0.1/tcp/30334/ws/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV".to_string(), + ]); + }, Request::Peers(sender) => { let mut peers = vec![]; for _peer in 0..status.peers { @@ -208,6 +217,25 @@ fn system_health() { ); } +#[test] +fn system_local_peer_id_works() { + assert_eq!( + wait_receiver(api(None).system_local_peer_id()), + "QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV".to_owned(), + ); +} + +#[test] +fn system_local_listen_addresses_works() { + assert_eq!( + wait_receiver(api(None).system_local_listen_addresses()), + vec![ + "/ip4/198.51.100.19/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV".to_string(), + "/ip4/127.0.0.1/tcp/30334/ws/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV".to_string(), + ] + ); +} + #[test] fn system_peers() { let peer_id = PeerId::random(); diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 969453210e..f416d363de 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -373,6 +373,17 @@ fn build_network_future< should_have_peers, }); }, + sc_rpc::system::Request::LocalPeerId(sender) => { + let _ = sender.send(network.local_peer_id().to_base58()); + }, + sc_rpc::system::Request::LocalListenAddresses(sender) => { + let peer_id = network.local_peer_id().clone().into(); + let p2p_proto_suffix = sc_network::multiaddr::Protocol::P2p(peer_id); + let addresses = network.listen_addresses() + .map(|addr| addr.clone().with(p2p_proto_suffix.clone()).to_string()) + .collect(); + let _ = sender.send(addresses); + }, sc_rpc::system::Request::Peers(sender) => { let _ = sender.send(network.peers_debug_info().into_iter().map(|(peer_id, p)| sc_rpc::system::PeerInfo { -- GitLab From 75134a2f11edd12581264e757c5fc833f8fbae77 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 16 Apr 2020 19:11:26 +0200 Subject: [PATCH 247/300] client/authority-discovery: Allow to be run by sentry node (#5568) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * client/authority-discovery: Allow to be run by sentry node When run as a sentry node, the authority discovery module does not publish any addresses to the dht, but still discovers validators and sentry nodes of validators. * client/authority-discovery/src/lib: Wrap lines at 100 characters * client/authority-discovery: Remove TODO and unused import * client/authority-discovery: Pass role to new unit tests * client/authority-discovery: Apply suggestions Co-Authored-By: André Silva <123550+andresilva@users.noreply.github.com> * bin/node/cli/src/service: Use expressions instead of statements Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> --- .maintain/sentry-node/docker-compose.yml | 6 +- bin/node/cli/src/service.rs | 23 +++++++- client/authority-discovery/src/lib.rs | 73 ++++++++++++++++-------- client/authority-discovery/src/tests.rs | 12 ++-- 4 files changed, 77 insertions(+), 37 deletions(-) diff --git a/.maintain/sentry-node/docker-compose.yml b/.maintain/sentry-node/docker-compose.yml index 225fc74f98..376538dde5 100644 --- a/.maintain/sentry-node/docker-compose.yml +++ b/.maintain/sentry-node/docker-compose.yml @@ -82,13 +82,12 @@ services: - "--chain=local" - "--port" - "30333" - - "--charlie" - "--sentry" - "/dns4/validator-a/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR" - - "--bootnodes" - - "/dns4/validator-b/tcp/30333/p2p/QmSVnNf9HwVMT1Y4cK1P6aoJcEZjmoTXpjKBmAABLMnZEk" - "--reserved-nodes" - "/dns4/validator-a/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR" + - "--bootnodes" + - "/dns4/validator-b/tcp/30333/p2p/QmSVnNf9HwVMT1Y4cK1P6aoJcEZjmoTXpjKBmAABLMnZEk" - "--no-telemetry" - "--rpc-cors" - "all" @@ -97,7 +96,6 @@ services: - "--unsafe-rpc-external" - "--log" - "sub-authority-discovery=trace" - - "--sentry" - "--prometheus-external" validator-b: diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 757022655d..07099d9c97 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -146,7 +146,7 @@ macro_rules! new_full { ($with_startup_data)(&block_import, &babe_link); - if let sc_service::config::Role::Authority { sentry_nodes } = &role { + if let sc_service::config::Role::Authority { .. } = &role { let proposer = sc_basic_authorship::ProposerFactory::new( service.client(), service.transaction_pool() @@ -174,6 +174,23 @@ macro_rules! new_full { let babe = sc_consensus_babe::start_babe(babe_config)?; service.spawn_essential_task("babe-proposer", babe); + } + + // Spawn authority discovery module. + if matches!(role, sc_service::config::Role::Authority{..} | sc_service::config::Role::Sentry {..}) { + let (sentries, authority_discovery_role) = match role { + sc_service::config::Role::Authority { ref sentry_nodes } => ( + sentry_nodes.clone(), + sc_authority_discovery::Role::Authority ( + service.keystore(), + ), + ), + sc_service::config::Role::Sentry {..} => ( + vec![], + sc_authority_discovery::Role::Sentry, + ), + _ => unreachable!("Due to outer matches! constraint; qed.") + }; let network = service.network(); let dht_event_stream = network.event_stream("authority-discovery").filter_map(|e| async move { match e { @@ -183,9 +200,9 @@ macro_rules! new_full { let authority_discovery = sc_authority_discovery::AuthorityDiscovery::new( service.client(), network, - sentry_nodes.clone(), - service.keystore(), + sentries, dht_event_stream, + authority_discovery_role, service.prometheus_registry(), ); diff --git a/client/authority-discovery/src/lib.rs b/client/authority-discovery/src/lib.rs index 5142dd7259..2cf455f17b 100644 --- a/client/authority-discovery/src/lib.rs +++ b/client/authority-discovery/src/lib.rs @@ -25,13 +25,11 @@ //! //! 1. **Makes itself discoverable** //! -//! 1. Retrieves its external addresses. +//! 1. Retrieves its external addresses (including peer id) or the ones of its sentry nodes. //! -//! 2. Adds its network peer id to the addresses. +//! 2. Signs the above. //! -//! 3. Signs the above. -//! -//! 4. Puts the signature and the addresses on the libp2p Kademlia DHT. +//! 3. Puts the signature and the addresses on the libp2p Kademlia DHT. //! //! //! 2. **Discovers other authorities** @@ -43,6 +41,12 @@ //! 3. Validates the signatures of the retrieved key value pairs. //! //! 4. Adds the retrieved external addresses as priority nodes to the peerset. +//! +//! When run as a sentry node, the authority discovery module does not +//! publish any addresses to the DHT but still discovers validators and +//! sentry nodes of validators, i.e. only step 2 (Discovers other authorities) +//! is executed. + use std::collections::{HashMap, HashSet}; use std::convert::TryInto; use std::marker::PhantomData; @@ -62,7 +66,7 @@ use prost::Message; use sc_client_api::blockchain::HeaderBackend; use sc_network::{Multiaddr, config::MultiaddrWithPeerId, DhtEvent, ExHashT, NetworkStateInfo}; use sp_authority_discovery::{AuthorityDiscoveryApi, AuthorityId, AuthoritySignature, AuthorityPair}; -use sp_core::crypto::{key_types, CryptoTypePublicPair, Pair}; +use sp_core::crypto::{key_types, Pair}; use sp_core::traits::BareCryptoStorePtr; use sp_runtime::{traits::Block as BlockT, generic::BlockId}; use sp_api::ProvideRuntimeApi; @@ -89,6 +93,17 @@ const LIBP2P_KADEMLIA_BOOTSTRAP_TIME: Duration = Duration::from_secs(30); /// discovery module. const AUTHORITIES_PRIORITY_GROUP_NAME: &'static str = "authorities"; +/// Role an authority discovery module can run as. +pub enum Role { + /// Actual authority as well as a reference to its key store. + Authority(BareCryptoStorePtr), + /// Sentry node that guards an authority. + /// + /// No reference to its key store needed, as sentry nodes don't have an identity to sign + /// addresses with in the first place. + Sentry, +} + /// An `AuthorityDiscovery` makes a given authority discoverable and discovers other authorities. pub struct AuthorityDiscovery where @@ -111,8 +126,6 @@ where /// Channel we receive Dht events on. dht_event_rx: Pin + Send>>, - key_store: BareCryptoStorePtr, - /// Interval to be proactive, publishing own addresses. publish_interval: Interval, /// Interval on which to query for addresses of other authorities. @@ -122,6 +135,8 @@ where metrics: Option, + role: Role, + phantom: PhantomData, } @@ -142,8 +157,8 @@ where client: Arc, network: Arc, sentry_nodes: Vec, - key_store: BareCryptoStorePtr, dht_event_rx: Pin + Send>>, + role: Role, prometheus_registry: Option, ) -> Self { // Kademlia's default time-to-live for Dht records is 36h, republishing records every 24h. @@ -189,10 +204,10 @@ where network, sentry_nodes, dht_event_rx, - key_store, publish_interval, query_interval, addr_cache, + role, metrics, phantom: PhantomData, } @@ -200,6 +215,14 @@ where /// Publish either our own or if specified the public addresses of our sentry nodes. fn publish_ext_addresses(&mut self) -> Result<()> { + let key_store = match &self.role { + Role::Authority(key_store) => key_store, + // Only authority nodes can put addresses (their own or the ones of their sentry nodes) + // on the Dht. Sentry nodes don't have a known identity to authenticate such addresses, + // thus `publish_ext_addresses` becomes a no-op. + Role::Sentry => return Ok(()), + }; + if let Some(metrics) = &self.metrics { metrics.publish.inc() } @@ -226,13 +249,12 @@ where .encode(&mut serialized_addresses) .map_err(Error::EncodingProto)?; - let keys: Vec = self.get_own_public_keys_within_authority_set()? - .into_iter() - .map(Into::into) - .collect(); + let keys = AuthorityDiscovery::get_own_public_keys_within_authority_set( + &key_store, + &self.client, + )?.into_iter().map(Into::into).collect::>(); - let signatures = self.key_store - .read() + let signatures = key_store.read() .sign_with_all( key_types::AUTHORITY_DISCOVERY, keys.clone(), @@ -424,17 +446,17 @@ where // one for the upcoming session. In addition it could be participating in the current authority // set with two keys. The function does not return all of the local authority discovery public // keys, but only the ones intersecting with the current authority set. - fn get_own_public_keys_within_authority_set(&mut self) -> Result> { - let local_pub_keys = self.key_store - .read() + fn get_own_public_keys_within_authority_set( + key_store: &BareCryptoStorePtr, + client: &Client, + ) -> Result> { + let local_pub_keys = key_store.read() .sr25519_public_keys(key_types::AUTHORITY_DISCOVERY) .into_iter() .collect::>(); - let id = BlockId::hash(self.client.info().best_hash); - let current_authorities = self - .client - .runtime_api() + let id = BlockId::hash(client.info().best_hash); + let current_authorities = client.runtime_api() .authorities(&id) .map_err(Error::CallingRuntime)? .into_iter() @@ -458,7 +480,10 @@ where "Applying priority group {:?} to peerset.", addresses, ); self.network - .set_priority_group(AUTHORITIES_PRIORITY_GROUP_NAME.to_string(), addresses.into_iter().collect()) + .set_priority_group( + AUTHORITIES_PRIORITY_GROUP_NAME.to_string(), + addresses.into_iter().collect(), + ) .map_err(Error::SettingPeersetPriorityGroup)?; Ok(()) diff --git a/client/authority-discovery/src/tests.rs b/client/authority-discovery/src/tests.rs index 79c50818c4..c9b5e392d8 100644 --- a/client/authority-discovery/src/tests.rs +++ b/client/authority-discovery/src/tests.rs @@ -216,8 +216,8 @@ fn new_registers_metrics() { test_api, network.clone(), vec![], - key_store, dht_event_rx.boxed(), + Role::Authority(key_store), Some(registry.clone()), ); @@ -241,8 +241,8 @@ fn publish_ext_addresses_puts_record_on_dht() { test_api, network.clone(), vec![], - key_store, dht_event_rx.boxed(), + Role::Authority(key_store), None, ); @@ -272,8 +272,8 @@ fn request_addresses_of_others_triggers_dht_get_query() { test_api, network.clone(), vec![], - key_store, dht_event_rx.boxed(), + Role::Authority(key_store), None, ); @@ -301,8 +301,8 @@ fn handle_dht_events_with_value_found_should_call_set_priority_group() { test_api, network.clone(), vec![], - key_store, dht_event_rx.boxed(), + Role::Authority(key_store), None, ); @@ -366,8 +366,8 @@ fn terminate_when_event_stream_terminates() { test_api, network.clone(), vec![], - key_store, dht_event_rx.boxed(), + Role::Authority(key_store), None, ); @@ -407,8 +407,8 @@ fn dont_stop_polling_when_error_is_returned() { test_api, network.clone(), vec![], - key_store, dht_event_rx.boxed(), + Role::Authority(key_store), None, ); -- GitLab From 93698e4b50b71b268cdfae50f08aab361efe2836 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Thu, 16 Apr 2020 22:38:04 +0300 Subject: [PATCH 248/300] update parity-util-mem (#5668) --- Cargo.lock | 4 ++-- client/cli/Cargo.toml | 2 +- client/db/Cargo.toml | 2 +- client/informant/Cargo.toml | 2 +- client/service/Cargo.toml | 2 +- client/state-db/Cargo.toml | 2 +- client/transaction-pool/Cargo.toml | 2 +- client/transaction-pool/graph/Cargo.toml | 2 +- primitives/core/Cargo.toml | 2 +- primitives/runtime/Cargo.toml | 2 +- primitives/test-primitives/Cargo.toml | 2 +- test-utils/runtime/Cargo.toml | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 830157efd3..8a494655dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4768,9 +4768,9 @@ checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" [[package]] name = "parity-util-mem" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e42755f26e5ea21a6a819d9e63cbd70713e9867a2b767ec2cc65ca7659532c5" +checksum = "2c6e2583649a3ca84894d1d71da249abcfda54d5aca24733d72ca10d0f02361c" dependencies = [ "cfg-if", "impl-trait-for-tuples", diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 0670961834..198a9df5b5 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -44,7 +44,7 @@ names = "0.11.0" structopt = "0.3.8" sc-tracing = { version = "2.0.0-dev", path = "../tracing" } chrono = "0.4.10" -parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } [target.'cfg(not(target_os = "unknown"))'.dependencies] rpassword = "4.0.1" diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index 0540edd550..10ad5e30f1 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -19,7 +19,7 @@ kvdb-rocksdb = { version = "0.7", optional = true } kvdb-memorydb = "0.5.0" linked-hash-map = "0.5.2" hash-db = "0.15.2" -parity-util-mem = { version = "0.6.0", default-features = false, features = ["std"] } +parity-util-mem = { version = "0.6.1", default-features = false, features = ["std"] } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } blake2-rfc = "0.2.18" diff --git a/client/informant/Cargo.toml b/client/informant/Cargo.toml index 5ece3e0ffb..f8e6ca85f9 100644 --- a/client/informant/Cargo.toml +++ b/client/informant/Cargo.toml @@ -15,7 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] ansi_term = "0.12.1" futures = "0.3.4" log = "0.4.8" -parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } wasm-timer = "0.2" sc-client-api = { version = "2.0.0-dev", path = "../api" } sc-network = { version = "0.8.0-dev", path = "../network" } diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 167c3c1436..1cc7e85b7a 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -62,7 +62,7 @@ parity-multiaddr = { package = "parity-multiaddr", version = "0.7.3" } prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" , version = "0.8.0-dev"} sc-tracing = { version = "2.0.0-dev", path = "../tracing" } tracing = "0.1.10" -parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } [target.'cfg(any(unix, windows))'.dependencies] diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index ebb92ca375..c2d2f2eb0b 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -17,7 +17,7 @@ log = "0.4.8" sc-client-api = { version = "2.0.0-dev", path = "../api" } sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } parity-util-mem-derive = "0.1.0" [dev-dependencies] diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 4eea7899f7..a6a5ec67e7 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -28,7 +28,7 @@ sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transact sc-client-api = { version = "2.0.0-dev", path = "../api" } sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } intervalier = "0.4.0" -parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } [dev-dependencies] assert_matches = "1.3.0" diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index 42bf3deead..842d54f920 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -23,7 +23,7 @@ sp-utils = { version = "2.0.0-dev", path = "../../../primitives/utils" } sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } sp-transaction-pool = { version = "2.0.0-dev", path = "../../../primitives/transaction-pool" } -parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } linked-hash-map = "0.5.2" [dev-dependencies] diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 4ab6dd8e97..e010002a5c 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -35,7 +35,7 @@ parking_lot = { version = "0.10.0", optional = true } sp-debug-derive = { version = "2.0.0-dev", path = "../debug-derive" } sp-externalities = { version = "0.8.0-dev", optional = true, path = "../externalities" } sp-storage = { version = "2.0.0-dev", default-features = false, path = "../storage" } -parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } futures = { version = "0.3.1", optional = true } # full crypto diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index 7e150585c4..d3ad92aeb6 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -26,7 +26,7 @@ paste = "0.1.6" rand = { version = "0.7.2", optional = true } impl-trait-for-tuples = "0.1.3" sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../inherents" } -parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } hash256-std-hasher = { version = "0.15.2", default-features = false } [dev-dependencies] diff --git a/primitives/test-primitives/Cargo.toml b/primitives/test-primitives/Cargo.toml index 16171ea747..386f7be17c 100644 --- a/primitives/test-primitives/Cargo.toml +++ b/primitives/test-primitives/Cargo.toml @@ -17,7 +17,7 @@ codec = { package = "parity-scale-codec", version = "1.3.0", default-features = sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } -parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } [features] default = [ diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index 065a09c889..96daca8bed 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -43,7 +43,7 @@ sc-client = { version = "0.8.0-dev", optional = true, path = "../../client" } sp-trie = { version = "2.0.0-dev", default-features = false, path = "../../primitives/trie" } sp-transaction-pool = { version = "2.0.0-dev", default-features = false, path = "../../primitives/transaction-pool" } trie-db = { version = "0.20.1", default-features = false } -parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } [dev-dependencies] sc-block-builder = { version = "0.8.0-dev", path = "../../client/block-builder" } -- GitLab From d61504391dcc730b747b8a825230933d034666e8 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Thu, 16 Apr 2020 22:40:04 +0300 Subject: [PATCH 249/300] Batch signature verification (#5023) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * create parallel tasks extension * make type system happy * basic externalities * test for dynamic extensions * batching test * remove premature verify_batch * shnschnorrkel batch * alter test * shnschnorrkel test * executive batching * some docs * also multi/any signatgures * error propagation * styling * make verification extension optional * experimental ed25519 parallelization * some merge fallout * utilize task executor * merge fallout * utilize task executor more * another merge fallout * feature-gate sp-io * arrange toml * fix no-std * sr25519 batching and refactoring * add docs * fix name * add newline * fix block import test * long sr25519 test * blocking instead of parking * move everything in crypto * return batch_verify to check :) * use condvars * use multi-threaded executor for benches * don't call via host interface * try no spawning * add true * cleanup * straighten batching * remove signature check from this test (?) * remove now pointless test * remove another now useless test * fix warnings * Revert "remove another now useless test" This reverts commit bbdec24bb67ed4373072daef7c863e1a8825bd8b. * rethink the sp-io-part * Revert "remove now pointless test" This reverts commit 4d553066322e65782264caa6053d4cd5538df977. * fix wording * add wording * add todo and fix * return check and fix * add logging in sp-io * Update primitives/io/src/batch_verifier.rs Co-Authored-By: cheme * address review and use std condvar * account for early exit * address reivew * address review * more suggestions * add docs for batch verification * remove unused * more review suggestions * move to sp-runtime * add expects * remove blocks * use entry * Update primitives/io/src/batch_verifier.rs Co-Authored-By: Bastian Köcher * Update primitives/externalities/src/extensions.rs Co-Authored-By: Bastian Köcher * update overlooked note * remove stupid return * Update primitives/io/src/lib.rs Co-Authored-By: Bastian Köcher * Update primitives/io/src/lib.rs Co-Authored-By: Bastian Köcher * fix wording * bump spec_version Co-authored-by: cheme Co-authored-by: Bastian Köcher --- Cargo.lock | 5 + bin/node/runtime/src/lib.rs | 2 +- bin/node/testing/Cargo.toml | 1 + bin/node/testing/src/bench.rs | 39 ++- client/transaction-pool/src/testing/pool.rs | 5 +- frame/executive/Cargo.toml | 1 + frame/executive/src/lib.rs | 4 + primitives/core/Cargo.toml | 4 +- primitives/core/src/sr25519.rs | 39 +++ primitives/externalities/src/extensions.rs | 32 ++- primitives/externalities/src/lib.rs | 30 +++ primitives/io/Cargo.toml | 4 + primitives/io/src/batch_verifier.rs | 163 ++++++++++++ primitives/io/src/lib.rs | 243 +++++++++++++++++- primitives/runtime/Cargo.toml | 1 + .../src/generic/unchecked_extrinsic.rs | 7 +- primitives/runtime/src/lib.rs | 53 +++- primitives/runtime/src/traits.rs | 6 +- primitives/state-machine/src/basic.rs | 69 ++++- primitives/state-machine/src/ext.rs | 25 +- primitives/state-machine/src/testing.rs | 25 +- 21 files changed, 711 insertions(+), 47 deletions(-) create mode 100644 primitives/io/src/batch_verifier.rs diff --git a/Cargo.lock b/Cargo.lock index 8a494655dd..a3f24d6748 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3672,6 +3672,7 @@ dependencies = [ "frame-support", "frame-system", "fs_extra", + "futures 0.3.4", "log", "node-executor", "node-primitives", @@ -7359,6 +7360,7 @@ dependencies = [ "lazy_static", "libsecp256k1", "log", + "merlin", "num-traits 0.2.11", "parity-scale-codec", "parity-util-mem", @@ -7447,10 +7449,12 @@ dependencies = [ name = "sp-io" version = "2.0.0-dev" dependencies = [ + "futures 0.3.4", "hash-db", "libsecp256k1", "log", "parity-scale-codec", + "parking_lot 0.10.2", "sp-core", "sp-externalities", "sp-runtime-interface", @@ -7537,6 +7541,7 @@ dependencies = [ "sp-core", "sp-inherents", "sp-io", + "sp-state-machine", "sp-std", ] diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index b1d768eecd..24fc3fb2fc 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -127,7 +127,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 241, + spec_version: 242, impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index 8ca5132eb9..3d8ab42621 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -50,6 +50,7 @@ sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" log = "0.4.8" tempfile = "3.1.0" fs_extra = "1" +futures = "0.3.1" [dev-dependencies] criterion = "0.3.0" diff --git a/bin/node/testing/src/bench.rs b/bin/node/testing/src/bench.rs index 9f7ab57895..ea48f02650 100644 --- a/bin/node/testing/src/bench.rs +++ b/bin/node/testing/src/bench.rs @@ -47,7 +47,7 @@ use node_runtime::{ AccountId, Signature, }; -use sp_core::{ExecutionContext, blake2_256}; +use sp_core::{ExecutionContext, blake2_256, traits::CloneableSpawn}; use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; use sp_inherents::InherentData; @@ -57,6 +57,7 @@ use sc_client_api::{ }; use sp_core::{Pair, Public, sr25519, ed25519}; use sc_block_builder::BlockBuilderProvider; +use futures::{executor, task}; /// Keyring full of accounts for benching. /// @@ -142,6 +143,36 @@ impl BlockType { } } +/// Benchmarking task executor. +/// +/// Uses multiple threads as the regular executable. +#[derive(Debug, Clone)] +pub struct TaskExecutor { + pool: executor::ThreadPool, +} + +impl TaskExecutor { + fn new() -> Self { + Self { + pool: executor::ThreadPool::new() + .expect("Failed to create task executor") + } + } +} + +impl task::Spawn for TaskExecutor { + fn spawn_obj(&self, future: task::FutureObj<'static, ()>) + -> Result<(), task::SpawnError> { + self.pool.spawn_obj(future) + } +} + +impl CloneableSpawn for TaskExecutor { + fn clone(&self) -> Box { + Box::new(Clone::clone(self)) + } +} + impl BenchDb { /// New immutable benchmarking database. /// @@ -168,8 +199,8 @@ impl BenchDb { /// and keep it there until struct is dropped. /// /// You can `clone` this database or you can `create_context` from it - /// (which also do `clone`) to run actual operation against new database - /// which will be identical to this. + /// (which also does `clone`) to run actual operation against new database + /// which will be identical to the original. pub fn new(keyring_length: usize) -> Self { Self::with_key_types(keyring_length, KeyTypes::Sr25519) } @@ -197,7 +228,7 @@ impl BenchDb { None, None, ExecutionExtensions::new(profile.into_execution_strategies(), None), - sp_core::tasks::executor(), + Box::new(TaskExecutor::new()), None, ).expect("Should not fail"); diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index e7021e8ea0..f2815db1c3 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -20,7 +20,7 @@ use futures::executor::block_on; use txpool::{self, Pool}; use sp_runtime::{ generic::BlockId, - transaction_validity::{ValidTransaction, InvalidTransaction, TransactionSource}, + transaction_validity::{ValidTransaction, TransactionSource, InvalidTransaction}, }; use substrate_test_runtime_client::{ runtime::{Block, Hash, Index, Header, Extrinsic, Transfer}, @@ -263,7 +263,6 @@ fn should_not_retain_invalid_hashes_from_retracted() { let event = block_event_with_retracted(1, vec![retracted_hash]); block_on(pool.maintain(event)); - // maintenance is in background block_on(notifier.next()); assert_eq!(pool.status().ready, 0); @@ -701,6 +700,6 @@ fn should_not_accept_old_signatures() { Err(error::Error::Pool( sp_transaction_pool::error::Error::InvalidTransaction(InvalidTransaction::BadProof) )), - "Should be invalid transactiono with bad proof", + "Should be invalid transaction with bad proof", ); } diff --git a/frame/executive/Cargo.toml b/frame/executive/Cargo.toml index d37339dbdc..f46dc8462d 100644 --- a/frame/executive/Cargo.toml +++ b/frame/executive/Cargo.toml @@ -18,6 +18,7 @@ frame-system = { version = "2.0.0-dev", default-features = false, path = "../sys serde = { version = "1.0.101", optional = true } sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } [dev-dependencies] hex-literal = "0.2.1" diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 99f934afd2..32f4c8f1b1 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -237,9 +237,13 @@ where // any initial checks Self::initial_checks(&block); + let batching_safeguard = sp_runtime::SignatureBatching::start(); // execute extrinsics let (header, extrinsics) = block.deconstruct(); Self::execute_extrinsics_with_book_keeping(extrinsics, *header.number()); + if !sp_runtime::SignatureBatching::verify(batching_safeguard) { + panic!("Signature verification failed."); + } // any final checks Self::final_checks(&header); diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index e010002a5c..5eecd83853 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -47,6 +47,7 @@ sha2 = { version = "0.8.0", default-features = false, optional = true } hex = { version = "0.4", default-features = false, optional = true } twox-hash = { version = "1.5.0", default-features = false, optional = true } libsecp256k1 = { version = "0.3.2", default-features = false, features = ["hmac"], optional = true } +merlin = { version = "2.0", default-features = false, optional = true } sp-runtime-interface = { version = "2.0.0-dev", default-features = false, path = "../runtime-interface" } @@ -97,7 +98,6 @@ std = [ "schnorrkel/std", "regex", "num-traits/std", - "libsecp256k1/std", "tiny-keccak", "sp-debug-derive/std", "sp-externalities", @@ -106,6 +106,7 @@ std = [ "zeroize/alloc", "futures", "futures/thread-pool", + "libsecp256k1/std", ] # This feature enables all crypto primitives for `no_std` builds like microcontrollers @@ -121,4 +122,5 @@ full_crypto = [ "twox-hash", "libsecp256k1", "sp-runtime-interface/disable_target_static_assertions", + "merlin", ] diff --git a/primitives/core/src/sr25519.rs b/primitives/core/src/sr25519.rs index 717952eb01..cadfb25776 100644 --- a/primitives/core/src/sr25519.rs +++ b/primitives/core/src/sr25519.rs @@ -611,6 +611,45 @@ impl CryptoType for Pair { type Pair = Pair; } +/// Batch verification. +/// +/// `messages`, `signatures` and `pub_keys` should all have equal length. +/// +/// Returns `true` if all signatures are correct, `false` otherwise. +#[cfg(feature = "std")] +pub fn verify_batch( + messages: Vec<&[u8]>, + signatures: Vec<&Signature>, + pub_keys: Vec<&Public>, +) -> bool { + let mut sr_pub_keys = Vec::with_capacity(pub_keys.len()); + for pub_key in pub_keys { + match schnorrkel::PublicKey::from_bytes(pub_key.as_ref()) { + Ok(pk) => sr_pub_keys.push(pk), + Err(_) => return false, + }; + } + + let mut sr_signatures = Vec::with_capacity(signatures.len()); + for signature in signatures { + match schnorrkel::Signature::from_bytes(signature.as_ref()) { + Ok(s) => sr_signatures.push(s), + Err(_) => return false + }; + } + + let mut messages: Vec = messages.into_iter().map( + |msg| signing_context(SIGNING_CTX).bytes(msg) + ).collect(); + + schnorrkel::verify_batch( + &mut messages, + &sr_signatures, + &sr_pub_keys, + true, + ).is_ok() +} + #[cfg(test)] mod compatibility_test { use super::*; diff --git a/primitives/externalities/src/extensions.rs b/primitives/externalities/src/extensions.rs index a61c03534f..f38f256bb9 100644 --- a/primitives/externalities/src/extensions.rs +++ b/primitives/externalities/src/extensions.rs @@ -21,7 +21,8 @@ //! //! It is required that each extension implements the [`Extension`] trait. -use std::{collections::HashMap, any::{Any, TypeId}, ops::DerefMut}; +use std::{collections::HashMap, collections::hash_map::Entry, any::{Any, TypeId}, ops::DerefMut}; +use crate::Error; /// Marker trait for types that should be registered as [`Externalities`](crate::Externalities) extension. /// @@ -87,6 +88,16 @@ pub trait ExtensionStore { /// It is advised to use [`ExternalitiesExt::extension`](crate::ExternalitiesExt::extension) /// instead of this function to get type system support and automatic type downcasting. fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any>; + + /// Register extension `extension` with speciifed `type_id`. + /// + /// It should return error if extension is already registered. + fn register_extension_with_type_id(&mut self, type_id: TypeId, extension: Box) -> Result<(), Error>; + + /// Deregister extension with speicifed 'type_id' and drop it. + /// + /// It should return error if extension is not registered. + fn deregister_extension_by_type_id(&mut self, type_id: TypeId) -> Result<(), Error>; } /// Stores extensions that should be made available through the externalities. @@ -95,6 +106,12 @@ pub struct Extensions { extensions: HashMap>, } +impl std::fmt::Debug for Extensions { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Extensions: ({})", self.extensions.len()) + } +} + impl Extensions { /// Create new instance of `Self`. pub fn new() -> Self { @@ -106,10 +123,23 @@ impl Extensions { self.extensions.insert(ext.type_id(), Box::new(ext)); } + /// Register extension `ext`. + pub fn register_with_type_id(&mut self, type_id: TypeId, extension: Box) -> Result<(), Error> { + match self.extensions.entry(type_id) { + Entry::Vacant(vacant) => { vacant.insert(extension); Ok(()) }, + Entry::Occupied(_) => Err(Error::ExtensionAlreadyRegistered), + } + } + /// Return a mutable reference to the requested extension. pub fn get_mut(&mut self, ext_type_id: TypeId) -> Option<&mut dyn Any> { self.extensions.get_mut(&ext_type_id).map(DerefMut::deref_mut).map(Extension::as_mut_any) } + + /// Deregister extension of type `E`. + pub fn deregister(&mut self, type_id: TypeId) -> Option> { + self.extensions.remove(&type_id) + } } #[cfg(test)] diff --git a/primitives/externalities/src/lib.rs b/primitives/externalities/src/lib.rs index 6a7f943947..2c0f50cd74 100644 --- a/primitives/externalities/src/lib.rs +++ b/primitives/externalities/src/lib.rs @@ -32,6 +32,17 @@ pub use extensions::{Extension, Extensions, ExtensionStore}; mod extensions; mod scope_limited; +/// Externalities error. +#[derive(Debug)] +pub enum Error { + /// Same extension cannot be registered twice. + ExtensionAlreadyRegistered, + /// Extensions are not supported. + ExtensionsAreNotSupported, + /// Extension `TypeId` is not registered. + ExtensionIsNotRegistered(TypeId), +} + /// The Substrate externalities. /// /// Provides access to the storage and to other registered extensions. @@ -198,10 +209,29 @@ pub trait Externalities: ExtensionStore { pub trait ExternalitiesExt { /// Tries to find a registered extension and returns a mutable reference. fn extension(&mut self) -> Option<&mut T>; + + /// Register extension `ext`. + /// + /// Should return error if extension is already registered or extensions are not supported. + fn register_extension(&mut self, ext: T) -> Result<(), Error>; + + /// Deregister and drop extension of `T` type. + /// + /// Should return error if extension of type `T` is not registered or + /// extensions are not supported. + fn deregister_extension(&mut self) -> Result<(), Error>; } impl ExternalitiesExt for &mut dyn Externalities { fn extension(&mut self) -> Option<&mut T> { self.extension_by_type_id(TypeId::of::()).and_then(Any::downcast_mut) } + + fn register_extension(&mut self, ext: T) -> Result<(), Error> { + self.register_extension_with_type_id(TypeId::of::(), Box::new(ext)) + } + + fn deregister_extension(&mut self) -> Result<(), Error> { + self.deregister_extension_by_type_id(TypeId::of::()) + } } diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index c80f3d0ac1..93c8cc9d38 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -25,6 +25,8 @@ sp-runtime-interface = { version = "2.0.0-dev", default-features = false, path = sp-trie = { version = "2.0.0-dev", optional = true, path = "../../primitives/trie" } sp-externalities = { version = "0.8.0-dev", optional = true, path = "../externalities" } log = { version = "0.4.8", optional = true } +futures = { version = "0.3.1", features = ["thread-pool"], optional = true } +parking_lot = { version = "0.10.0", optional = true } [features] default = ["std"] @@ -40,6 +42,8 @@ std = [ "sp-externalities", "sp-wasm-interface/std", "log", + "futures", + "parking_lot", ] # These two features are used for `no_std` builds for the environments which already provides diff --git a/primitives/io/src/batch_verifier.rs b/primitives/io/src/batch_verifier.rs new file mode 100644 index 0000000000..a23b8fcbc2 --- /dev/null +++ b/primitives/io/src/batch_verifier.rs @@ -0,0 +1,163 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Batch/parallel verification. + +use sp_core::{ed25519, sr25519, crypto::Pair, traits::CloneableSpawn}; +use std::sync::{Arc, atomic::{AtomicBool, Ordering as AtomicOrdering}}; +use futures::{future::FutureExt, task::FutureObj, channel::oneshot}; + +#[derive(Debug, Clone)] +struct Sr25519BatchItem { + signature: sr25519::Signature, + pub_key: sr25519::Public, + message: Vec, +} + +/// Batch verifier. +/// +/// Used to parallel-verify signatures for runtime host. Provide task executor and +/// just push (`push_ed25519`, `push_sr25519`) as many signature as you need. At the end, +/// call `verify_and_clear to get a result. After that, batch verifier is ready for the +/// next batching job. +pub struct BatchVerifier { + scheduler: Box, + sr25519_items: Vec, + invalid: Arc, + pending_tasks: Vec>, +} + +impl BatchVerifier { + pub fn new(scheduler: Box) -> Self { + BatchVerifier { + scheduler, + sr25519_items: Default::default(), + invalid: Arc::new(false.into()), + pending_tasks: vec![], + } + } + + fn spawn_verification_task( + &mut self, f: impl FnOnce() -> bool + Send + 'static, + ) -> Result<(), ()> { + // there is already invalid transaction encountered + if self.invalid.load(AtomicOrdering::Relaxed) { return Err(()); } + + let invalid_clone = self.invalid.clone(); + let (sender, receiver) = oneshot::channel(); + self.pending_tasks.push(receiver); + + self.scheduler.spawn_obj(FutureObj::new(async move { + if !f() { + invalid_clone.store(true, AtomicOrdering::Relaxed); + } + if sender.send(()).is_err() { + // sanity + log::warn!("Verification halted while result was pending"); + invalid_clone.store(true, AtomicOrdering::Relaxed); + } + }.boxed())).map_err(drop) + } + + /// Push ed25519 signature to verify. + /// + /// Returns false if some of the pushed signatures before already failed the check + /// (in this case it won't verify anything else) + pub fn push_ed25519( + &mut self, + signature: ed25519::Signature, + pub_key: ed25519::Public, + message: Vec, + ) -> bool { + if self.invalid.load(AtomicOrdering::Relaxed) { return false; } + + if self.spawn_verification_task(move || ed25519::Pair::verify(&signature, &message, &pub_key)).is_err() { + log::debug!( + target: "runtime", + "Batch-verification returns false because failed to spawn background task.", + ); + + return false; + } + true + } + + /// Push sr25519 signature to verify. + /// + /// Returns false if some of the pushed signatures before already failed the check. + /// (in this case it won't verify anything else) + pub fn push_sr25519( + &mut self, + signature: sr25519::Signature, + pub_key: sr25519::Public, + message: Vec, + ) -> bool { + if self.invalid.load(AtomicOrdering::Relaxed) { return false; } + self.sr25519_items.push(Sr25519BatchItem { signature, pub_key, message }); + true + } + + /// Verify all previously pushed signatures since last call and return + /// aggregated result. + #[must_use] + pub fn verify_and_clear(&mut self) -> bool { + use std::sync::{Mutex, Condvar}; + + let pending = std::mem::replace(&mut self.pending_tasks, vec![]); + + log::trace!( + target: "runtime", + "Batch-verification: {} pending tasks, {} sr25519 signatures", + pending.len(), + self.sr25519_items.len(), + ); + + let messages = self.sr25519_items.iter().map(|item| &item.message[..]).collect(); + let signatures = self.sr25519_items.iter().map(|item| &item.signature).collect(); + let pub_keys = self.sr25519_items.iter().map(|item| &item.pub_key).collect(); + + if !sr25519::verify_batch(messages, signatures, pub_keys) { + self.sr25519_items.clear(); + + return false; + } + + self.sr25519_items.clear(); + + if pending.len() > 0 { + let pair = Arc::new((Mutex::new(()), Condvar::new())); + let pair_clone = pair.clone(); + + if self.scheduler.spawn_obj(FutureObj::new(async move { + futures::future::join_all(pending).await; + pair_clone.1.notify_all(); + }.boxed())).is_err() { + log::debug!( + target: "runtime", + "Batch-verification returns false because failed to spawn background task.", + ); + + return false; + } + + let (mtx, cond_var) = &*pair; + let mtx = mtx.lock().expect("Locking can only fail when the mutex is poisoned; qed"); + let _ = cond_var.wait(mtx).expect("Waiting can only fail when the mutex waited on is poisoned; qed"); + } + + !self.invalid.swap(false, AtomicOrdering::Relaxed) + } +} diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index bc49df159e..ee146dbc29 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! This is part of the Substrate runtime. +//! I/O host interface for substrate runtime. #![warn(missing_docs)] @@ -34,7 +34,7 @@ use sp_std::ops::Deref; #[cfg(feature = "std")] use sp_core::{ crypto::Pair, - traits::{KeystoreExt, CallInWasmExt}, + traits::{KeystoreExt, CallInWasmExt, TaskExecutorExt}, offchain::{OffchainExt, TransactionPoolExt}, hexdisplay::HexDisplay, storage::{ChildStorageKey, ChildInfo}, @@ -57,6 +57,12 @@ use codec::{Encode, Decode}; #[cfg(feature = "std")] use sp_externalities::{ExternalitiesExt, Externalities}; +#[cfg(feature = "std")] +mod batch_verifier; + +#[cfg(feature = "std")] +use batch_verifier::BatchVerifier; + /// Error verifying ECDSA signature #[derive(Encode, Decode)] pub enum EcdsaVerifyError { @@ -416,16 +422,98 @@ pub trait Crypto { .ok() } - /// Verify an `ed25519` signature. + /// Verify `ed25519` signature. /// - /// Returns `true` when the verification in successful. + /// Returns `true` when the verification is either successful or batched. + /// If no batching verification extension registered, this will return the result + /// of verification immediately. If batching verification extension is registered + /// caller should call `crypto::finish_batch_verify` to actualy check all submitted + /// signatures. fn ed25519_verify( - &self, sig: &ed25519::Signature, msg: &[u8], pub_key: &ed25519::Public, ) -> bool { - ed25519::Pair::verify(sig, msg, pub_key) + // TODO: see #5554, this is used outside of externalities context/runtime, thus this manual + // `with_externalities`. + // + // This `with_externalities(..)` block returns Some(Some(result)) if signature verification was successfully + // batched, everything else (Some(None)/None) means it was not batched and needs to be verified. + let evaluated = sp_externalities::with_externalities(|mut instance| + instance.extension::().map( + |extension| extension.push_ed25519( + sig.clone(), + pub_key.clone(), + msg.to_vec(), + ) + ) + ); + + match evaluated { + Some(Some(val)) => val, + _ => ed25519::Pair::verify(sig, msg, pub_key), + } + } + + /// Verify `sr25519` signature. + /// + /// Returns `true` when the verification is either successful or batched. + /// If no batching verification extension registered, this will return the result + /// of verification immediately. If batching verification extension is registered, + /// caller should call `crypto::finish_batch_verify` to actualy check all submitted + #[version(2)] + fn sr25519_verify( + sig: &sr25519::Signature, + msg: &[u8], + pub_key: &sr25519::Public, + ) -> bool { + // TODO: see #5554, this is used outside of externalities context/runtime, thus this manual + // `with_externalities`. + // + // This `with_externalities(..)` block returns Some(Some(result)) if signature verification was successfully + // batched, everything else (Some(None)/None) means it was not batched and needs to be verified. + let evaluated = sp_externalities::with_externalities(|mut instance| + instance.extension::().map( + |extension| extension.push_sr25519( + sig.clone(), + pub_key.clone(), + msg.to_vec(), + ) + ) + ); + + match evaluated { + Some(Some(val)) => val, + _ => sr25519::Pair::verify(sig, msg, pub_key), + } + } + + /// Start verification extension. + fn start_batch_verify(&mut self) { + let scheduler = self.extension::() + .expect("No task executor associated with the current context!") + .0 + .clone(); + + self.register_extension(VerificationExt(BatchVerifier::new(scheduler))) + .expect("Failed to register required extension: `VerificationExt`"); + } + + /// Finish batch-verification of signatures. + /// + /// Verify or wait for verification to finish for all signatures which were previously + /// deferred by `sr25519_verify`/`ed25519_verify`. + /// + /// Will panic if no `VerificationExt` is registered (`start_batch_verify` was not called). + fn finish_batch_verify(&mut self) -> bool { + let result = self.extension::() + .expect("`finish_batch_verify` should only be called after `start_batch_verify`") + .verify_and_clear(); + + self.deregister_extension::() + .expect("No verification extension in current context!"); + + result } /// Returns all `sr25519` public keys for the given key id from the keystore. @@ -477,14 +565,6 @@ pub trait Crypto { sr25519::Pair::verify_deprecated(sig, msg, pubkey) } - /// Verify an `sr25519` signature. - /// - /// Returns `true` when the verification in successful. - #[version(2)] - fn sr25519_verify(sig: &sr25519::Signature, msg: &[u8], pubkey: &sr25519::Public) -> bool { - sr25519::Pair::verify(sig, msg, pubkey) - } - /// Verify and recover a SECP256k1 ECDSA signature. /// /// - `sig` is passed in RSV format. V should be either `0/1` or `27/28`. @@ -566,6 +646,12 @@ pub trait Hashing { } } +#[cfg(feature = "std")] +sp_externalities::decl_extension! { + /// The keystore extension to register/retrieve from the externalities. + pub struct VerificationExt(BatchVerifier); +} + /// Interface that provides functions to access the offchain functionality. #[runtime_interface] pub trait Offchain { @@ -949,6 +1035,7 @@ mod tests { use sp_core::map; use sp_state_machine::BasicExternalities; use sp_core::storage::Storage; + use std::any::TypeId; #[test] fn storage_works() { @@ -1010,4 +1097,132 @@ mod tests { assert!(storage::get(b":abc").is_none()); }); } + + #[test] + fn dynamic_extensions_work() { + let mut ext = BasicExternalities::with_tasks_executor(); + ext.execute_with(|| { + crypto::start_batch_verify(); + }); + + assert!(ext.extensions().get_mut(TypeId::of::()).is_some()); + + ext.execute_with(|| { + crypto::finish_batch_verify(); + }); + + assert!(ext.extensions().get_mut(TypeId::of::()).is_none()); + } + + #[test] + fn long_sr25519_batching() { + let mut ext = BasicExternalities::with_tasks_executor(); + ext.execute_with(|| { + let pair = sr25519::Pair::generate_with_phrase(None).0; + crypto::start_batch_verify(); + for it in 0..70 { + let msg = format!("Schnorrkel {}!", it); + let signature = pair.sign(msg.as_bytes()); + crypto::sr25519_verify(&signature, msg.as_bytes(), &pair.public()); + } + + // push invlaid + crypto::sr25519_verify( + &Default::default(), + &Vec::new(), + &Default::default(), + ); + assert!(!crypto::finish_batch_verify()); + + crypto::start_batch_verify(); + for it in 0..70 { + let msg = format!("Schnorrkel {}!", it); + let signature = pair.sign(msg.as_bytes()); + crypto::sr25519_verify(&signature, msg.as_bytes(), &pair.public()); + } + assert!(crypto::finish_batch_verify()); + }); + } + + #[test] + fn batching_works() { + let mut ext = BasicExternalities::with_tasks_executor(); + ext.execute_with(|| { + // invalid ed25519 signature + crypto::start_batch_verify(); + crypto::ed25519_verify( + &Default::default(), + &Vec::new(), + &Default::default(), + ); + assert!(!crypto::finish_batch_verify()); + + // 2 valid ed25519 signatures + crypto::start_batch_verify(); + + let pair = ed25519::Pair::generate_with_phrase(None).0; + let msg = b"Important message"; + let signature = pair.sign(msg); + crypto::ed25519_verify(&signature, msg, &pair.public()); + + let pair = ed25519::Pair::generate_with_phrase(None).0; + let msg = b"Even more important message"; + let signature = pair.sign(msg); + crypto::ed25519_verify(&signature, msg, &pair.public()); + + assert!(crypto::finish_batch_verify()); + + // 1 valid, 1 invalid ed25519 signature + crypto::start_batch_verify(); + + let pair = ed25519::Pair::generate_with_phrase(None).0; + let msg = b"Important message"; + let signature = pair.sign(msg); + crypto::ed25519_verify(&signature, msg, &pair.public()); + + crypto::ed25519_verify( + &Default::default(), + &Vec::new(), + &Default::default(), + ); + + assert!(!crypto::finish_batch_verify()); + + // 1 valid ed25519, 2 valid sr25519 + crypto::start_batch_verify(); + + let pair = ed25519::Pair::generate_with_phrase(None).0; + let msg = b"Ed25519 batching"; + let signature = pair.sign(msg); + crypto::ed25519_verify(&signature, msg, &pair.public()); + + let pair = sr25519::Pair::generate_with_phrase(None).0; + let msg = b"Schnorrkel rules"; + let signature = pair.sign(msg); + crypto::sr25519_verify(&signature, msg, &pair.public()); + + let pair = sr25519::Pair::generate_with_phrase(None).0; + let msg = b"Schnorrkel batches!"; + let signature = pair.sign(msg); + crypto::sr25519_verify(&signature, msg, &pair.public()); + + assert!(crypto::finish_batch_verify()); + + // 1 valid sr25519, 1 invalid sr25519 + crypto::start_batch_verify(); + + let pair = sr25519::Pair::generate_with_phrase(None).0; + let msg = b"Schnorrkcel!"; + let signature = pair.sign(msg); + crypto::sr25519_verify(&signature, msg, &pair.public()); + + crypto::sr25519_verify( + &Default::default(), + &Vec::new(), + &Default::default(), + ); + + assert!(!crypto::finish_batch_verify()); + }); + } } diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index d3ad92aeb6..030f0a61cb 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -32,6 +32,7 @@ hash256-std-hasher = { version = "0.15.2", default-features = false } [dev-dependencies] serde_json = "1.0.41" rand = "0.7.2" +sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } [features] bench = [] diff --git a/primitives/runtime/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs index 3e9e52ba8b..4aae575b2c 100644 --- a/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -24,7 +24,8 @@ use crate::{ self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic, ExtrinsicMetadata, IdentifyAccount, }, - generic::CheckedExtrinsic, transaction_validity::{TransactionValidityError, InvalidTransaction}, + generic::CheckedExtrinsic, + transaction_validity::{TransactionValidityError, InvalidTransaction}, }; const TRANSACTION_VERSION: u8 = 4; @@ -125,9 +126,7 @@ where Some((signed, signature, extra)) => { let signed = lookup.lookup(signed)?; let raw_payload = SignedPayload::new(self.function, extra)?; - if !raw_payload.using_encoded(|payload| { - signature.verify(payload, &signed) - }) { + if !raw_payload.using_encoded(|payload| signature.verify(payload, &signed)) { return Err(InvalidTransaction::BadProof.into()) } diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index b30c6ebe94..e69f892626 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -42,7 +42,8 @@ pub use sp_core::storage::{Storage, StorageChild}; use sp_std::prelude::*; use sp_std::convert::TryFrom; -use sp_core::{crypto, ed25519, sr25519, ecdsa, hash::{H256, H512}}; +use sp_core::{crypto::{self, Public}, ed25519, sr25519, ecdsa, hash::{H256, H512}}; + use codec::{Encode, Decode}; pub mod curve; @@ -299,7 +300,6 @@ impl std::fmt::Display for MultiSigner { impl Verify for MultiSignature { type Signer = MultiSigner; fn verify>(&self, mut msg: L, signer: &AccountId32) -> bool { - use sp_core::crypto::Public; match (self, signer) { (MultiSignature::Ed25519(ref sig), who) => sig.verify(msg, &ed25519::Public::from_slice(who.as_ref())), (MultiSignature::Sr25519(ref sig), who) => sig.verify(msg, &sr25519::Public::from_slice(who.as_ref())), @@ -324,7 +324,6 @@ pub struct AnySignature(H512); impl Verify for AnySignature { type Signer = sr25519::Public; fn verify>(&self, mut msg: L, signer: &sr25519::Public) -> bool { - use sp_core::crypto::Public; let msg = msg.get(); sr25519::Signature::try_from(self.0.as_fixed_bytes().as_ref()) .map(|s| s.verify(msg, signer)) @@ -735,6 +734,39 @@ pub fn print(print: impl traits::Printable) { print.print(); } + +/// Batching session. +/// +/// To be used in runtime only. Outside of runtime, just construct +/// `BatchVerifier` directly. +#[must_use = "`verify()` needs to be called to finish batch signature verification!"] +pub struct SignatureBatching(bool); + +impl SignatureBatching { + /// Start new batching session. + pub fn start() -> Self { + sp_io::crypto::start_batch_verify(); + SignatureBatching(false) + } + + /// Verify all signatures submitted during the batching session. + #[must_use] + pub fn verify(mut self) -> bool { + self.0 = true; + sp_io::crypto::finish_batch_verify() + } +} + +impl Drop for SignatureBatching { + fn drop(&mut self) { + // Sanity check. If user forgets to actually call `verify()`. + if !self.0 { + panic!("Signature verification has not been called before `SignatureBatching::drop`") + } + } +} + + #[cfg(test)] mod tests { use super::*; @@ -782,4 +814,19 @@ mod tests { let multi_signer = MultiSigner::from(pair.public()); assert!(multi_sig.verify(msg, &multi_signer.into_account())); } + + + #[test] + #[should_panic(expected = "Signature verification has not been called")] + fn batching_still_finishes_when_not_called_directly() { + let mut ext = sp_state_machine::BasicExternalities::with_tasks_executor(); + ext.execute_with(|| { + let _batching = SignatureBatching::start(); + sp_io::crypto::sr25519_verify( + &Default::default(), + &Vec::new(), + &Default::default(), + ); + }); + } } diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index fdf1d6396d..d843bdc478 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -81,12 +81,15 @@ impl IdentifyAccount for sp_core::ecdsa::Public { pub trait Verify { /// Type of the signer. type Signer: IdentifyAccount; - /// Verify a signature. Return `true` if signature is valid for the value. + /// Verify a signature. + /// + /// Return `true` if signature is valid for the value. fn verify>(&self, msg: L, signer: &::AccountId) -> bool; } impl Verify for sp_core::ed25519::Signature { type Signer = sp_core::ed25519::Public; + fn verify>(&self, mut msg: L, signer: &sp_core::ed25519::Public) -> bool { sp_io::crypto::ed25519_verify(self, msg.get(), signer) } @@ -94,6 +97,7 @@ impl Verify for sp_core::ed25519::Signature { impl Verify for sp_core::sr25519::Signature { type Signer = sp_core::sr25519::Public; + fn verify>(&self, mut msg: L, signer: &sp_core::sr25519::Public) -> bool { sp_io::crypto::sr25519_verify(self, msg.get(), signer) } diff --git a/primitives/state-machine/src/basic.rs b/primitives/state-machine/src/basic.rs index 819244050b..b49913418a 100644 --- a/primitives/state-machine/src/basic.rs +++ b/primitives/state-machine/src/basic.rs @@ -32,17 +32,35 @@ use sp_core::{ }; use log::warn; use codec::Encode; +use sp_externalities::Extensions; /// Simple Map-based Externalities impl. #[derive(Debug)] pub struct BasicExternalities { inner: Storage, + extensions: Extensions, } impl BasicExternalities { /// Create a new instance of `BasicExternalities` pub fn new(inner: Storage) -> Self { - BasicExternalities { inner } + BasicExternalities { inner, extensions: Default::default() } + } + + /// New basic externalities with empty storage. + pub fn new_empty() -> Self { + Self::new(Storage::default()) + } + + /// New basic extternalities with tasks executor. + pub fn with_tasks_executor() -> Self { + let mut extensions = Extensions::default(); + extensions.register(sp_core::traits::TaskExecutorExt(sp_core::tasks::executor())); + + Self { + inner: Storage::default(), + extensions, + } } /// Insert key/value @@ -62,10 +80,13 @@ impl BasicExternalities { storage: &mut sp_core::storage::Storage, f: impl FnOnce() -> R, ) -> R { - let mut ext = Self { inner: Storage { - top: std::mem::replace(&mut storage.top, Default::default()), - children: std::mem::replace(&mut storage.children, Default::default()), - }}; + let mut ext = Self { + inner: Storage { + top: std::mem::replace(&mut storage.top, Default::default()), + children: std::mem::replace(&mut storage.children, Default::default()), + }, + extensions: Default::default(), + }; let r = ext.execute_with(f); @@ -80,6 +101,11 @@ impl BasicExternalities { pub fn execute_with(&mut self, f: impl FnOnce() -> R) -> R { sp_externalities::set_and_run_with_externalities(self, f) } + + /// List of active extensions. + pub fn extensions(&mut self) -> &mut Extensions { + &mut self.extensions + } } impl PartialEq for BasicExternalities { @@ -103,10 +129,13 @@ impl Default for BasicExternalities { impl From> for BasicExternalities { fn from(hashmap: BTreeMap) -> Self { - BasicExternalities { inner: Storage { - top: hashmap, - children: Default::default(), - }} + BasicExternalities { + inner: Storage { + top: hashmap, + children: Default::default(), + }, + extensions: Default::default(), + } } } @@ -279,9 +308,23 @@ impl Externalities for BasicExternalities { } impl sp_externalities::ExtensionStore for BasicExternalities { - fn extension_by_type_id(&mut self, _: TypeId) -> Option<&mut dyn Any> { - warn!("Extensions are not supported by `BasicExternalities`."); - None + fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any> { + self.extensions.get_mut(type_id) + } + + fn register_extension_with_type_id( + &mut self, + type_id: TypeId, + extension: Box, + ) -> Result<(), sp_externalities::Error> { + self.extensions.register_with_type_id(type_id, extension) + } + + fn deregister_extension_by_type_id(&mut self, type_id: TypeId) -> Result<(), sp_externalities::Error> { + self.extensions + .deregister(type_id) + .ok_or(sp_externalities::Error::ExtensionIsNotRegistered(type_id)) + .map(drop) } } @@ -347,7 +390,7 @@ mod tests { #[test] fn basic_externalities_is_empty() { // Make sure no values are set by default in `BasicExternalities`. - let storage = BasicExternalities::new(Default::default()).into_storages(); + let storage = BasicExternalities::new_empty().into_storages(); assert!(storage.top.is_empty()); assert!(storage.children.is_empty()); } diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index 133af7ccd9..3a6b544290 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -28,7 +28,7 @@ use sp_core::{ traits::Externalities, hexdisplay::HexDisplay, }; use sp_trie::{trie_types::Layout, default_child_trie_root}; -use sp_externalities::Extensions; +use sp_externalities::{Extensions, Extension}; use codec::{Decode, Encode}; use std::{error, fmt, any::{Any, TypeId}}; @@ -548,6 +548,29 @@ where fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any> { self.extensions.as_mut().and_then(|exts| exts.get_mut(type_id)) } + + fn register_extension_with_type_id( + &mut self, + type_id: TypeId, + extension: Box, + ) -> Result<(), sp_externalities::Error> { + if let Some(ref mut extensions) = self.extensions { + extensions.register_with_type_id(type_id, extension) + } else { + Err(sp_externalities::Error::ExtensionsAreNotSupported) + } + } + + fn deregister_extension_by_type_id(&mut self, type_id: TypeId) -> Result<(), sp_externalities::Error> { + if let Some(ref mut extensions) = self.extensions { + match extensions.deregister(type_id) { + Some(_) => Ok(()), + None => Err(sp_externalities::Error::ExtensionIsNotRegistered(type_id)) + } + } else { + Err(sp_externalities::Error::ExtensionsAreNotSupported) + } + } } #[cfg(test)] diff --git a/primitives/state-machine/src/testing.rs b/primitives/state-machine/src/testing.rs index aec42c7678..2b971d816a 100644 --- a/primitives/state-machine/src/testing.rs +++ b/primitives/state-machine/src/testing.rs @@ -80,6 +80,11 @@ impl TestExternalities Self::new_with_code(&[], storage) } + /// New empty test externalities. + pub fn new_empty() -> Self { + Self::new_with_code(&[], Storage::default()) + } + /// Create a new instance of `TestExternalities` with code and storage. pub fn new_with_code(code: &[u8], mut storage: Storage) -> Self { let mut overlay = OverlayedChanges::default(); @@ -93,12 +98,15 @@ impl TestExternalities storage.top.insert(HEAP_PAGES.to_vec(), 8u64.encode()); storage.top.insert(CODE.to_vec(), code.to_vec()); + let mut extensions = Extensions::default(); + extensions.register(sp_core::traits::TaskExecutorExt(sp_core::tasks::executor())); + TestExternalities { overlay, changes_trie_config, + extensions, changes_trie_storage: ChangesTrieInMemoryStorage::new(), backend: storage.into(), - extensions: Default::default(), storage_transaction_cache: Default::default(), } } @@ -191,6 +199,21 @@ impl sp_externalities::ExtensionStore for TestExternalities where fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any> { self.extensions.get_mut(type_id) } + + fn register_extension_with_type_id( + &mut self, + type_id: TypeId, + extension: Box, + ) -> Result<(), sp_externalities::Error> { + self.extensions.register_with_type_id(type_id, extension) + } + + fn deregister_extension_by_type_id(&mut self, type_id: TypeId) -> Result<(), sp_externalities::Error> { + self.extensions + .deregister(type_id) + .expect("There should be an extension we try to remove in TestExternalities"); + Ok(()) + } } #[cfg(test)] -- GitLab From 9918b2e100eacc54f8ef2a0505e072206f1045f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 17 Apr 2020 08:42:50 +0200 Subject: [PATCH 250/300] Add performance tracing to validate_transaction (#5671) * Validate transaction timeouts * Add timing * Add tracing to transaction validation. * Fix docs. Co-authored-by: NikVolf --- Cargo.lock | 1 + client/transaction-pool/Cargo.toml | 15 +++++++------- client/transaction-pool/src/api.rs | 5 +++++ frame/executive/src/lib.rs | 22 ++++++++++++++++---- frame/support/src/lib.rs | 32 ++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a3f24d6748..051e6448b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6767,6 +6767,7 @@ dependencies = [ "sp-utils", "substrate-test-runtime-client", "substrate-test-runtime-transaction-pool", + "tracing", "wasm-timer", ] diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index a6a5ec67e7..2a757652f9 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -16,19 +16,20 @@ codec = { package = "parity-scale-codec", version = "1.3.0" } derive_more = "0.99.2" futures = { version = "0.3.1", features = ["compat"] } futures-diagnose = "1.0" +intervalier = "0.4.0" log = "0.4.8" +parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } parking_lot = "0.10.0" -wasm-timer = "0.2" -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sc-client-api = { version = "2.0.0-dev", path = "../api" } +sc-transaction-graph = { version = "2.0.0-dev", path = "./graph" } sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } +sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } -sc-transaction-graph = { version = "2.0.0-dev", path = "./graph" } sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } -sc-client-api = { version = "2.0.0-dev", path = "../api" } sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } -intervalier = "0.4.0" -parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } +sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } +tracing = "0.1.10" +wasm-timer = "0.2" [dev-dependencies] assert_matches = "1.3.0" diff --git a/client/transaction-pool/src/api.rs b/client/transaction-pool/src/api.rs index bf104c8d78..2e590ccad8 100644 --- a/client/transaction-pool/src/api.rs +++ b/client/transaction-pool/src/api.rs @@ -89,12 +89,17 @@ impl sc_transaction_graph::ChainApi for FullChainApi, _>( &at, |v| v >= 2, ) .unwrap_or_default(); + std::mem::drop(guard); + let span = tracing::span!(tracing::Level::DEBUG, "validate_transaction"); + let _guard = span.enter(); let res = if has_v2 { runtime_api.validate_transaction(&at, source, uxt) } else { diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 32f4c8f1b1..747fc85866 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -348,11 +348,25 @@ where source: TransactionSource, uxt: Block::Extrinsic, ) -> TransactionValidity { - let encoded_len = uxt.using_encoded(|d| d.len()); - let xt = uxt.check(&Default::default())?; + use frame_support::tracing_span; - let dispatch_info = xt.get_dispatch_info(); - xt.validate::(source, &dispatch_info, encoded_len) + tracing_span!{ "validate_transaction::using_encoded"; + let encoded_len = uxt.using_encoded(|d| d.len()); + }; + + tracing_span!{ "validate_transaction::check"; + let xt = uxt.check(&Default::default())?; + }; + + tracing_span!{ "validate_transaction::dispatch_info"; + let dispatch_info = xt.get_dispatch_info(); + }; + + tracing_span!{ "validate_transaction::validate"; + let result = xt.validate::(source, &dispatch_info, encoded_len); + }; + + result } /// Start an offchain worker and generate extrinsics. diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 9a32d9a779..eed5c95b17 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -222,6 +222,38 @@ macro_rules! assert_ok { } } +/// Runs given code within a tracing span, measuring it's execution time. +/// +/// Has effect only when running in native environment. In WASM, it simply inserts the +/// code in-place, without any metrics added. +#[macro_export] +macro_rules! tracing_span { + ($name:expr; $( $code:tt )*) => { + let span = $crate::if_tracing!( + $crate::tracing::span!($crate::tracing::Level::TRACE, $name) + , + () + ); + let guard = $crate::if_tracing!(span.enter(), ()); + $( $code )* + + $crate::sp_std::mem::drop(guard); + $crate::sp_std::mem::drop(span); + } +} + +#[macro_export] +#[cfg(feature = "tracing")] +macro_rules! if_tracing { + ( $if:expr, $else:expr ) => {{ $if }} +} + +#[macro_export] +#[cfg(not(feature = "tracing"))] +macro_rules! if_tracing { + ( $if:expr, $else:expr ) => {{ $else }} +} + /// The void type - it cannot exist. // Oh rust, you crack me up... #[derive(Clone, Eq, PartialEq, RuntimeDebug)] -- GitLab From 631386869747a6b78888e20d32a813a2c525a2c3 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 17 Apr 2020 09:11:47 +0200 Subject: [PATCH 251/300] Adjustments to Kademlia-related metrics (#5660) * Turn kbuckets_num_nodes into a GaugeVec * random_kademlia_queries -> kademlia_random_queries * kademalia_random_queries_total now a CounterVec * Add metrics about records store --- client/network/src/behaviour.rs | 22 +++++-- client/network/src/discovery.rs | 33 ++++++++--- client/network/src/service.rs | 73 ++++++++++++++++++------ client/network/src/service/out_events.rs | 6 +- 4 files changed, 103 insertions(+), 31 deletions(-) diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index d8f70f7ae0..cb9c552115 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use crate::{ - config::Role, + config::{ProtocolId, Role}, debug_info, discovery::{DiscoveryBehaviour, DiscoveryConfig, DiscoveryOut}, Event, ObservedRole, DhtEvent, ExHashT, }; @@ -61,7 +61,7 @@ pub enum BehaviourOut { JustificationImport(Origin, B::Hash, NumberFor, Justification), FinalityProofImport(Origin, B::Hash, NumberFor, Vec), /// Started a random Kademlia discovery query. - RandomKademliaStarted, + RandomKademliaStarted(ProtocolId), Event(Event), } @@ -98,10 +98,20 @@ impl Behaviour { } /// Returns the number of nodes that are in the Kademlia k-buckets. - pub fn num_kbuckets_entries(&mut self) -> usize { + pub fn num_kbuckets_entries(&mut self) -> impl ExactSizeIterator { self.discovery.num_kbuckets_entries() } + /// Returns the number of records in the Kademlia record stores. + pub fn num_kademlia_records(&mut self) -> impl ExactSizeIterator { + self.discovery.num_kademlia_records() + } + + /// Returns the total size in bytes of all the records in the Kademlia record stores. + pub fn kademlia_records_total_size(&mut self) -> impl ExactSizeIterator { + self.discovery.kademlia_records_total_size() + } + /// Borrows `self` and returns a struct giving access to the information about a node. /// /// Returns `None` if we don't know anything about this node. Always returns `Some` for nodes @@ -268,8 +278,10 @@ impl NetworkBehaviourEventProcess DiscoveryOut::ValuePutFailed(key) => { self.events.push(BehaviourOut::Event(Event::Dht(DhtEvent::ValuePutFailed(key)))); } - DiscoveryOut::RandomKademliaStarted => { - self.events.push(BehaviourOut::RandomKademliaStarted); + DiscoveryOut::RandomKademliaStarted(protocols) => { + for protocol in protocols { + self.events.push(BehaviourOut::RandomKademliaStarted(protocol)); + } } } } diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index 86a5b84a9e..fc78e9b3e3 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -55,7 +55,7 @@ use libp2p::kad::{Kademlia, KademliaConfig, KademliaEvent, Quorum, Record}; use libp2p::kad::GetClosestPeersError; use libp2p::kad::handler::KademliaHandler; use libp2p::kad::QueryId; -use libp2p::kad::record::{self, store::MemoryStore}; +use libp2p::kad::record::{self, store::{MemoryStore, RecordStore}}; #[cfg(not(target_os = "unknown"))] use libp2p::swarm::toggle::Toggle; #[cfg(not(target_os = "unknown"))] @@ -77,7 +77,7 @@ pub struct DiscoveryConfig { } impl DiscoveryConfig { - /// Crate a default configuration with the given public key. + /// Create a default configuration with the given public key. pub fn new(local_public_key: PublicKey) -> Self { let mut this = DiscoveryConfig { local_peer_id: local_public_key.into_peer_id(), @@ -276,8 +276,27 @@ impl DiscoveryBehaviour { } /// Returns the number of nodes that are in the Kademlia k-buckets. - pub fn num_kbuckets_entries(&mut self) -> usize { - self.known_peers().count() + pub fn num_kbuckets_entries(&mut self) -> impl ExactSizeIterator { + self.kademlias.iter_mut().map(|(id, kad)| (id, kad.kbuckets_entries().count())) + } + + /// Returns the number of records in the Kademlia record stores. + pub fn num_kademlia_records(&mut self) -> impl ExactSizeIterator { + // Note that this code is ok only because we use a `MemoryStore`. + self.kademlias.iter_mut().map(|(id, kad)| { + let num = kad.store_mut().records().count(); + (id, num) + }) + } + + /// Returns the total size in bytes of all the records in the Kademlia record stores. + pub fn kademlia_records_total_size(&mut self) -> impl ExactSizeIterator { + // Note that this code is ok only because we use a `MemoryStore`. If the records were + // for example stored on disk, this would load every single one of them every single time. + self.kademlias.iter_mut().map(|(id, kad)| { + let size = kad.store_mut().records().fold(0, |tot, rec| tot + rec.value.len()); + (id, size) + }) } } @@ -307,8 +326,8 @@ pub enum DiscoveryOut { /// Inserting a value into the DHT failed. ValuePutFailed(record::Key), - /// Started a random Kademlia query. - RandomKademliaStarted, + /// Started a random Kademlia query for each DHT identified by the given `ProtocolId`s. + RandomKademliaStarted(Vec), } impl NetworkBehaviour for DiscoveryBehaviour { @@ -515,7 +534,7 @@ impl NetworkBehaviour for DiscoveryBehaviour { Duration::from_secs(60)); if actually_started { - let ev = DiscoveryOut::RandomKademliaStarted; + let ev = DiscoveryOut::RandomKademliaStarted(self.kademlias.keys().cloned().collect()); return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); } } diff --git a/client/network/src/service.rs b/client/network/src/service.rs index d9e970a61a..da488d2a87 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -880,7 +880,10 @@ struct Metrics { incoming_connections_total: Counter, is_major_syncing: Gauge, issued_light_requests: Counter, - kbuckets_num_nodes: Gauge, + kademlia_random_queries_total: CounterVec, + kademlia_records_count: GaugeVec, + kademlia_records_sizes_total: GaugeVec, + kbuckets_num_nodes: GaugeVec, listeners_local_addresses: Gauge, listeners_errors_total: Counter, network_per_sec_bytes: GaugeVec, @@ -893,7 +896,6 @@ struct Metrics { peerset_num_requested: Gauge, pending_connections: Gauge, pending_connections_errors_total: CounterVec, - random_kademalia_queries_total: Counter, } impl Metrics { @@ -945,8 +947,33 @@ impl Metrics { "issued_light_requests", "Number of light client requests that our node has issued.", )?, registry)?, - kbuckets_num_nodes: register(Gauge::new( - "sub_libp2p_kbuckets_num_nodes", "Number of nodes in the Kademlia k-buckets" + kademlia_random_queries_total: register(CounterVec::new( + Opts::new( + "sub_libp2p_kademlia_random_queries_total", + "Number of random Kademlia queries started" + ), + &["protocol"] + )?, registry)?, + kademlia_records_count: register(GaugeVec::new( + Opts::new( + "sub_libp2p_kademlia_records_count", + "Number of records in the Kademlia records store" + ), + &["protocol"] + )?, registry)?, + kademlia_records_sizes_total: register(GaugeVec::new( + Opts::new( + "sub_libp2p_kademlia_records_sizes_total", + "Total size of all the records in the Kademlia records store" + ), + &["protocol"] + )?, registry)?, + kbuckets_num_nodes: register(GaugeVec::new( + Opts::new( + "sub_libp2p_kbuckets_num_nodes", + "Number of nodes in the Kademlia k-buckets" + ), + &["protocol"] )?, registry)?, listeners_local_addresses: register(Gauge::new( "sub_libp2p_listeners_local_addresses", "Number of local addresses we're listening on" @@ -1017,24 +1044,23 @@ impl Metrics { ), &["reason"] )?, registry)?, - random_kademalia_queries_total: register(Counter::new( - "sub_libp2p_random_kademalia_queries_total", "Number of random Kademlia queries started", - )?, registry)?, }) } fn update_with_network_event(&self, event: &Event) { match event { Event::NotificationStreamOpened { engine_id, .. } => { - self.notifications_streams_opened_total.with_label_values(&[&engine_id_to_string(&engine_id)]).inc(); + self.notifications_streams_opened_total + .with_label_values(&[&maybe_utf8_bytes_to_string(engine_id)]).inc(); }, Event::NotificationStreamClosed { engine_id, .. } => { - self.notifications_streams_closed_total.with_label_values(&[&engine_id_to_string(&engine_id)]).inc(); + self.notifications_streams_closed_total + .with_label_values(&[&maybe_utf8_bytes_to_string(engine_id)]).inc(); }, Event::NotificationsReceived { messages, .. } => { for (engine_id, message) in messages { self.notifications_sizes - .with_label_values(&["in", &engine_id_to_string(&engine_id)]) + .with_label_values(&["in", &maybe_utf8_bytes_to_string(engine_id)]) .observe(message.len() as f64); } }, @@ -1097,7 +1123,7 @@ impl Future for NetworkWorker { ServiceToWorkerMsg::WriteNotification { message, engine_id, target } => { if let Some(metrics) = this.metrics.as_ref() { metrics.notifications_sizes - .with_label_values(&["out", &engine_id_to_string(&engine_id)]) + .with_label_values(&["out", &maybe_utf8_bytes_to_string(&engine_id)]) .observe(message.len() as f64); } this.network_service.user_protocol_mut().write_notification(target, engine_id, message) @@ -1137,9 +1163,11 @@ impl Future for NetworkWorker { } this.import_queue.import_finality_proof(origin, hash, nb, proof); }, - Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::RandomKademliaStarted)) => { + Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::RandomKademliaStarted(protocol))) => { if let Some(metrics) = this.metrics.as_ref() { - metrics.random_kademalia_queries_total.inc(); + metrics.kademlia_random_queries_total + .with_label_values(&[&maybe_utf8_bytes_to_string(protocol.as_bytes())]) + .inc(); } }, Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::Event(ev))) => { @@ -1292,7 +1320,18 @@ impl Future for NetworkWorker { metrics.network_per_sec_bytes.with_label_values(&["in"]).set(this.service.bandwidth.average_download_per_sec()); metrics.network_per_sec_bytes.with_label_values(&["out"]).set(this.service.bandwidth.average_upload_per_sec()); metrics.is_major_syncing.set(is_major_syncing as u64); - metrics.kbuckets_num_nodes.set(this.network_service.num_kbuckets_entries() as u64); + for (proto, num_entries) in this.network_service.num_kbuckets_entries() { + let proto = maybe_utf8_bytes_to_string(proto.as_bytes()); + metrics.kbuckets_num_nodes.with_label_values(&[&proto]).set(num_entries as u64); + } + for (proto, num_entries) in this.network_service.num_kademlia_records() { + let proto = maybe_utf8_bytes_to_string(proto.as_bytes()); + metrics.kademlia_records_count.with_label_values(&[&proto]).set(num_entries as u64); + } + for (proto, num_entries) in this.network_service.kademlia_records_total_size() { + let proto = maybe_utf8_bytes_to_string(proto.as_bytes()); + metrics.kademlia_records_sizes_total.with_label_values(&[&proto]).set(num_entries as u64); + } metrics.peers_count.set(num_connected_peers as u64); metrics.peerset_num_discovered.set(this.network_service.user_protocol().num_discovered_peers() as u64); metrics.peerset_num_requested.set(this.network_service.user_protocol().requested_peers().count() as u64); @@ -1306,8 +1345,10 @@ impl Future for NetworkWorker { impl Unpin for NetworkWorker { } -/// Turns a `ConsensusEngineId` into a representable string. -fn engine_id_to_string(id: &ConsensusEngineId) -> Cow { +/// Turns bytes that are potentially UTF-8 into a reasonable representable string. +/// +/// Meant to be used only for debugging or metrics-reporting purposes. +fn maybe_utf8_bytes_to_string(id: &[u8]) -> Cow { if let Ok(s) = std::str::from_utf8(&id[..]) { Cow::Borrowed(s) } else { diff --git a/client/network/src/service/out_events.rs b/client/network/src/service/out_events.rs index cda53246de..8f9c138095 100644 --- a/client/network/src/service/out_events.rs +++ b/client/network/src/service/out_events.rs @@ -31,7 +31,7 @@ //! use crate::Event; -use super::engine_id_to_string; +use super::maybe_utf8_bytes_to_string; use futures::{prelude::*, channel::mpsc, ready}; use parking_lot::Mutex; @@ -240,7 +240,7 @@ impl Metrics { .with_label_values(&[&format!("notif-{:?}", engine_id), "sent", name]) .inc_by(num); self.notifications_sizes - .with_label_values(&[&engine_id_to_string(engine_id), "sent", name]) + .with_label_values(&[&maybe_utf8_bytes_to_string(engine_id), "sent", name]) .inc_by(num.saturating_mul(u64::try_from(message.len()).unwrap_or(u64::max_value()))); } }, @@ -270,7 +270,7 @@ impl Metrics { .with_label_values(&[&format!("notif-{:?}", engine_id), "received", name]) .inc(); self.notifications_sizes - .with_label_values(&[&engine_id_to_string(engine_id), "received", name]) + .with_label_values(&[&maybe_utf8_bytes_to_string(engine_id), "received", name]) .inc_by(u64::try_from(message.len()).unwrap_or(u64::max_value())); } }, -- GitLab From bfd4479a996235fbbc6ebd531faed037aa54ce4d Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 17 Apr 2020 09:53:30 +0200 Subject: [PATCH 252/300] =?UTF-8?q?Clean=20Phragm=C3=A9n=20Equlise=20API?= =?UTF-8?q?=20(#5452)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Clean phragmen API and equalise() * Stabilize new api * Fix phragmen fuzzers * More fixes * Make fuzzers reproducible * improvements * Make equalize update assignments as well. * total function for staked_assignment. * Fix fuzzer build * remvoe TODO * Fix a bunch more. * clean stray debug stuff * Update primitives/phragmen/src/lib.rs Co-Authored-By: thiolliere * fix range function * fix number generator Co-authored-by: thiolliere --- Cargo.lock | 11 + Cargo.toml | 1 + frame/elections-phragmen/src/lib.rs | 36 +-- frame/staking/src/lib.rs | 35 ++- frame/staking/src/mock.rs | 9 +- frame/staking/src/offchain_election.rs | 4 +- primitives/phragmen/Cargo.toml | 2 +- primitives/phragmen/benches/phragmen.rs | 252 +++++++++++---------- primitives/phragmen/compact/src/staked.rs | 9 +- primitives/phragmen/fuzzer/Cargo.toml | 19 +- primitives/phragmen/fuzzer/src/common.rs | 29 +++ primitives/phragmen/fuzzer/src/equalize.rs | 146 ++++++++++++ primitives/phragmen/fuzzer/src/reduce.rs | 47 ++-- primitives/phragmen/src/helpers.rs | 22 +- primitives/phragmen/src/lib.rs | 83 +++---- primitives/phragmen/src/mock.rs | 41 ++-- primitives/phragmen/src/tests.rs | 145 ++++++++---- 17 files changed, 578 insertions(+), 313 deletions(-) create mode 100644 primitives/phragmen/fuzzer/src/common.rs create mode 100644 primitives/phragmen/fuzzer/src/equalize.rs diff --git a/Cargo.lock b/Cargo.lock index 051e6448b3..f4823d0495 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7515,6 +7515,17 @@ dependencies = [ "syn 1.0.17", ] +[[package]] +name = "sp-phragmen-fuzzer" +version = "2.0.0-alpha.5" +dependencies = [ + "honggfuzz", + "rand 0.7.3", + "sp-phragmen", + "sp-runtime", + "sp-std", +] + [[package]] name = "sp-rpc" version = "2.0.0-dev" diff --git a/Cargo.toml b/Cargo.toml index ad05847f61..5c4e93d84c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -134,6 +134,7 @@ members = [ "primitives/offchain", "primitives/panic-handler", "primitives/phragmen", + "primitives/phragmen/fuzzer", "primitives/phragmen/compact", "primitives/rpc", "primitives/runtime-interface", diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index fe42183743..610f008457 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -94,7 +94,7 @@ use frame_support::{ ChangeMembers, OnUnbalanced, WithdrawReason, Contains, BalanceStatus, InitializeMembers, } }; -use sp_phragmen::{build_support_map, ExtendedBalance}; +use sp_phragmen::{build_support_map, ExtendedBalance, VoteWeight, PhragmenResult}; use frame_system::{self as system, ensure_signed, ensure_root}; const MODULE_ID: LockIdentifier = *b"phrelect"; @@ -123,7 +123,7 @@ pub trait Trait: frame_system::Trait { /// Convert a balance into a number used for election calculation. /// This must fit into a `u64` but is allowed to be sensibly lossy. - type CurrencyToVote: Convert, u64> + Convert>; + type CurrencyToVote: Convert, VoteWeight> + Convert>; /// How much should be locked up in order to submit one's candidacy. type CandidacyBond: Get>; @@ -703,17 +703,28 @@ impl Module { // previous runners_up are also always candidates for the next round. candidates.append(&mut Self::runners_up_ids()); + // helper closures to deal with balance/stake. + let to_votes = |b: BalanceOf| -> VoteWeight { + , VoteWeight>>::convert(b) + }; + let to_balance = |e: ExtendedBalance| -> BalanceOf { + >>::convert(e) + }; + let stake_of = |who: &T::AccountId| -> VoteWeight { + to_votes(Self::locked_stake_of(who)) + }; + let voters_and_votes = Voting::::iter() - .map(|(voter, (stake, targets))| { (voter, stake, targets) }) + .map(|(voter, (stake, targets))| { (voter, to_votes(stake), targets) }) .collect::>(); - let maybe_phragmen_result = sp_phragmen::elect::<_, _, T::CurrencyToVote, Perbill>( + let maybe_phragmen_result = sp_phragmen::elect::( num_to_elect, 0, candidates, voters_and_votes.clone(), ); - if let Some(phragmen_result) = maybe_phragmen_result { + if let Some(PhragmenResult { winners, assignments }) = maybe_phragmen_result { let old_members_ids = >::take().into_iter() .map(|(m, _)| m) .collect::>(); @@ -726,26 +737,19 @@ impl Module { // vote are still considered by phragmen and when good candidates are scarce, then these // cheap ones might get elected. We might actually want to remove the filter and allow // zero-voted candidates to also make it to the membership set. - let new_set_with_approval = phragmen_result.winners; + let new_set_with_approval = winners; let new_set = new_set_with_approval .into_iter() .filter_map(|(m, a)| if a.is_zero() { None } else { Some(m) } ) .collect::>(); - let stake_of = |who: &T::AccountId| -> ExtendedBalance { - , u64>>::convert( - Self::locked_stake_of(who) - ) as ExtendedBalance - }; let staked_assignments = sp_phragmen::assignment_ratio_to_staked( - phragmen_result.assignments, + assignments, stake_of, ); let (support_map, _) = build_support_map::(&new_set, &staked_assignments); - let to_balance = |e: ExtendedBalance| - >>::convert(e); let new_set_with_stake = new_set .into_iter() .map(|ref m| { @@ -766,14 +770,14 @@ impl Module { // save the members, sorted based on account id. new_members.sort_by(|i, j| i.0.cmp(&j.0)); - let mut prime_votes: Vec<_> = new_members.iter().map(|c| (&c.0, BalanceOf::::zero())).collect(); + let mut prime_votes: Vec<_> = new_members.iter().map(|c| (&c.0, VoteWeight::zero())).collect(); for (_, stake, targets) in voters_and_votes.into_iter() { for (votes, who) in targets.iter() .enumerate() .map(|(votes, who)| ((MAXIMUM_VOTE - votes) as u32, who)) { if let Ok(i) = prime_votes.binary_search_by_key(&who, |k| k.0) { - prime_votes[i].1 += stake * votes.into(); + prime_votes[i].1 += stake * votes as VoteWeight; } } } diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 2d1875ebf0..b6ffa9081b 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -308,7 +308,7 @@ use frame_system::{ }; use sp_phragmen::{ ExtendedBalance, Assignment, PhragmenScore, PhragmenResult, build_support_map, evaluate_support, - elect, generate_compact_solution_type, is_score_better, VotingLimit, SupportMap, + elect, generate_compact_solution_type, is_score_better, VotingLimit, SupportMap, VoteWeight, }; const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4; @@ -737,12 +737,11 @@ pub trait Trait: frame_system::Trait { /// is not used. type UnixTime: UnixTime; - /// Convert a balance into a number used for election calculation. - /// This must fit into a `u64` but is allowed to be sensibly lossy. - /// TODO: #1377 - /// The backward convert should be removed as the new Phragmen API returns ratio. - /// The post-processing needs it but will be moved to off-chain. TODO: #2908 - type CurrencyToVote: Convert, u64> + Convert>; + /// Convert a balance into a number used for election calculation. This must fit into a `u64` + /// but is allowed to be sensibly lossy. The `u64` is used to communicate with the + /// [`sp_phragmen`] crate which accepts u64 numbers and does operations in 128. Consequently, + /// the backward convert is used convert the u128s from phragmen back to a [`BalanceOf`]. + type CurrencyToVote: Convert, VoteWeight> + Convert>; /// Tokens have been minted and are unused for validator-reward. type RewardRemainder: OnUnbalanced>; @@ -1853,7 +1852,7 @@ decl_module! { /// - Memory: O(n + m) reads to map index to `AccountId` for un-compact. /// /// - Storage: O(e) accountid reads from `Nomination` to read correct nominations. - /// - Storage: O(e) calls into `slashable_balance_of_extended` to convert ratio to staked. + /// - Storage: O(e) calls into `slashable_balance_of_vote_weight` to convert ratio to staked. /// /// - Memory: build_support_map. O(e). /// - Memory: evaluate_support: O(E). @@ -1953,11 +1952,11 @@ impl Module { Self::bonded(stash).and_then(Self::ledger).map(|l| l.active).unwrap_or_default() } - /// internal impl of [`slashable_balance_of`] that returns [`ExtendedBalance`]. - fn slashable_balance_of_extended(stash: &T::AccountId) -> ExtendedBalance { - , u64>>::convert( + /// internal impl of [`slashable_balance_of`] that returns [`VoteWeight`]. + fn slashable_balance_of_vote_weight(stash: &T::AccountId) -> VoteWeight { + , VoteWeight>>::convert( Self::slashable_balance_of(stash) - ) as ExtendedBalance + ) } /// Dump the list of validators and nominators into vectors and keep them on-chain. @@ -2456,7 +2455,7 @@ impl Module { // convert into staked assignments. let staked_assignments = sp_phragmen::assignment_ratio_to_staked( assignments, - Self::slashable_balance_of_extended, + Self::slashable_balance_of_vote_weight, ); // build the support map thereof in order to evaluate. @@ -2711,7 +2710,7 @@ impl Module { let staked_assignments = sp_phragmen::assignment_ratio_to_staked( assignments, - Self::slashable_balance_of_extended, + Self::slashable_balance_of_vote_weight, ); let (supports, _) = build_support_map::( @@ -2747,11 +2746,11 @@ impl Module { /// /// No storage item is updated. fn do_phragmen() -> Option> { - let mut all_nominators: Vec<(T::AccountId, BalanceOf, Vec)> = Vec::new(); + let mut all_nominators: Vec<(T::AccountId, VoteWeight, Vec)> = Vec::new(); let mut all_validators = Vec::new(); for (validator, _) in >::iter() { // append self vote - let self_vote = (validator.clone(), Self::slashable_balance_of(&validator), vec![validator.clone()]); + let self_vote = (validator.clone(), Self::slashable_balance_of_vote_weight(&validator), vec![validator.clone()]); all_nominators.push(self_vote); all_validators.push(validator); } @@ -2771,11 +2770,11 @@ impl Module { (nominator, targets) }); all_nominators.extend(nominator_votes.map(|(n, ns)| { - let s = Self::slashable_balance_of(&n); + let s = Self::slashable_balance_of_vote_weight(&n); (n, s, ns) })); - elect::<_, _, T::CurrencyToVote, Accuracy>( + elect::<_, Accuracy>( Self::validator_count() as usize, Self::minimum_validator_count().max(1) as usize, all_validators, diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index c6bccdece4..d522a19615 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -33,6 +33,7 @@ use frame_system::offchain::TransactionSubmitter; use sp_io; use sp_phragmen::{ build_support_map, evaluate_support, reduce, ExtendedBalance, StakedAssignment, PhragmenScore, + VoteWeight, }; use crate::*; @@ -846,10 +847,10 @@ pub(crate) fn prepare_submission_with( } = Staking::do_phragmen::().unwrap(); let winners = winners.into_iter().map(|(w, _)| w).collect::>(); - let stake_of = |who: &AccountId| -> ExtendedBalance { - >::convert( + let stake_of = |who: &AccountId| -> VoteWeight { + >::convert( Staking::slashable_balance_of(&who) - ) as ExtendedBalance + ) }; let mut staked = sp_phragmen::assignment_ratio_to_staked(assignments, stake_of); @@ -888,7 +889,7 @@ pub(crate) fn prepare_submission_with( let score = { let staked = sp_phragmen::assignment_ratio_to_staked( assignments_reduced.clone(), - Staking::slashable_balance_of_extended, + Staking::slashable_balance_of_vote_weight, ); let (support_map, _) = build_support_map::( diff --git a/frame/staking/src/offchain_election.rs b/frame/staking/src/offchain_election.rs index 19196e917f..4d8ccc6f25 100644 --- a/frame/staking/src/offchain_election.rs +++ b/frame/staking/src/offchain_election.rs @@ -167,7 +167,7 @@ pub fn prepare_submission( // convert into absolute value and to obtain the reduced version. let mut staked = sp_phragmen::assignment_ratio_to_staked( assignments, - >::slashable_balance_of_extended, + >::slashable_balance_of_vote_weight, ); if do_reduce { @@ -188,7 +188,7 @@ pub fn prepare_submission( let score = { let staked = sp_phragmen::assignment_ratio_to_staked( low_accuracy_assignment.clone(), - >::slashable_balance_of_extended, + >::slashable_balance_of_vote_weight, ); let (support_map, _) = build_support_map::(&winners, &staked); diff --git a/primitives/phragmen/Cargo.toml b/primitives/phragmen/Cargo.toml index bf6e9fede6..ff3b331406 100644 --- a/primitives/phragmen/Cargo.toml +++ b/primitives/phragmen/Cargo.toml @@ -21,7 +21,7 @@ sp-phragmen-compact = { version = "2.0.0-dev", path = "./compact" } [dev-dependencies] substrate-test-utils = { version = "2.0.0-dev", path = "../../test-utils" } rand = "0.7.3" -sp-phragmen = { path = "." , version = "2.0.0-dev"} +sp-phragmen = { version = "2.0.0-dev", path = "." } [features] default = ["std"] diff --git a/primitives/phragmen/benches/phragmen.rs b/primitives/phragmen/benches/phragmen.rs index 33da0b1956..e274586f60 100644 --- a/primitives/phragmen/benches/phragmen.rs +++ b/primitives/phragmen/benches/phragmen.rs @@ -24,133 +24,139 @@ extern crate test; use test::Bencher; use rand::{self, Rng}; -extern crate sp_phragmen as phragmen; -use phragmen::{Support, SupportMap, PhragmenStakedAssignment}; +use sp_phragmen::{PhragmenResult, VoteWeight}; use std::collections::BTreeMap; -use sp_runtime::traits::{Convert, SaturatedConversion}; +use sp_runtime::{Perbill, traits::Zero}; -const VALIDATORS: u64 = 1000; -const NOMINATORS: u64 = 10_000; +// default params. Each will be scaled by the benchmarks individually. +const VALIDATORS: u64 = 100; +const NOMINATORS: u64 = 1_000; const EDGES: u64 = 2; -const TO_ELECT: usize = 100; -const STAKE: Balance = 1000; +const TO_ELECT: usize = 10; +const STAKE: VoteWeight = 1000; + +const PREFIX: AccountId = 1000_000; -type Balance = u128; type AccountId = u64; -pub struct TestCurrencyToVote; -impl Convert for TestCurrencyToVote { - fn convert(x: Balance) -> u64 { x.saturated_into() } -} -impl Convert for TestCurrencyToVote { - fn convert(x: u128) -> Balance { x.saturated_into() } -} +mod bench_closure_and_slice { + use sp_phragmen::{ + VoteWeight, ExtendedBalance, Assignment, StakedAssignment, IdentifierT, + assignment_ratio_to_staked, + }; + use sp_runtime::{Perbill, PerThing}; + use rand::{self, Rng, RngCore}; + use test::Bencher; + + fn random_assignment() -> Assignment { + let mut rng = rand::thread_rng(); + let who = rng.next_u32(); + let distribution = (0..5) + .map(|x| (x + rng.next_u32(), Perbill::from_percent(rng.next_u32() % 100))) + .collect::>(); + Assignment { who, distribution } + } -fn do_phragmen( - b: &mut Bencher, - num_vals: u64, - num_noms: u64, - count: usize, - votes_per: u64, - eq_iters: usize, - _eq_tolerance: u128, -) { - assert!(num_vals > votes_per); - let rr = |a, b| rand::thread_rng().gen_range(a as usize, b as usize) as Balance; + /// Converts a vector of ratio assignments into ones with absolute budget value. + pub fn assignment_ratio_to_staked_slice( + ratio: Vec>, + stakes: &[VoteWeight], + ) -> Vec> + where + T: sp_std::ops::Mul, + ExtendedBalance: From<::Inner>, + { + ratio + .into_iter() + .zip(stakes.into_iter().map(|x| *x as ExtendedBalance)) + .map(|(a, stake)| { + a.into_staked(stake.into(), true) + }) + .collect() + } - // prefix to distinguish the validator and nominator account ranges. - let np = 10_000; + #[bench] + fn closure(b: &mut Bencher) { + let assignments = (0..1000).map(|_| random_assignment()).collect::>>(); + let stake_of = |x: &u32| -> VoteWeight { (x * 2 + 100).into() }; - let mut candidates = Vec::with_capacity(num_vals as usize); - let mut slashable_balance_of: BTreeMap = BTreeMap::new(); + // each have one clone of assignments + b.iter(|| assignment_ratio_to_staked(assignments.clone(), stake_of)); + } - (1 ..= num_vals) - .for_each(|acc| { - candidates.push(acc); - slashable_balance_of.insert(acc, STAKE + rr(10, 50)); - }); + #[bench] + fn slice(b: &mut Bencher) { + let assignments = (0..1000).map(|_| random_assignment()).collect::>>(); + let stake_of = |x: &u32| -> VoteWeight { (x * 2 + 100).into() }; - let mut voters = Vec::with_capacity(num_noms as usize); - (np ..= (np + num_noms)) - .for_each(|acc| { - let mut stashes_to_vote = candidates.clone(); - let votes = (0 .. votes_per) - .map(|_| { - stashes_to_vote.remove(rr(0, stashes_to_vote.len()) as usize) - }) - .collect::>(); - voters.push((acc, votes)); - slashable_balance_of.insert(acc, STAKE + rr(10, 50)); + b.iter(|| { + let local = assignments.clone(); + let stakes = local.iter().map(|x| stake_of(&x.who)).collect::>(); + assignment_ratio_to_staked_slice(local, stakes.as_ref()); }); + } +} - let slashable_balance = |who: &AccountId| -> Balance { - *slashable_balance_of.get(who).unwrap() - }; +fn do_phragmen( + b: &mut Bencher, + num_validators: u64, + num_nominators: u64, + to_elect: usize, + edge_per_voter: u64, + eq_iters: usize, + eq_tolerance: u128, +) { + assert!(num_validators > edge_per_voter); + let rr = |a, b| rand::thread_rng().gen_range(a as usize, b as usize) as VoteWeight; + + let mut candidates = Vec::with_capacity(num_validators as usize); + let mut stake_of_tree: BTreeMap = BTreeMap::new(); + + (1 ..= num_validators).for_each(|acc| { + candidates.push(acc); + stake_of_tree.insert(acc, STAKE + rr(10, 1000)); + }); + + let mut voters = Vec::with_capacity(num_nominators as usize); + (PREFIX ..= (PREFIX + num_nominators)).for_each(|acc| { + // all possible targets + let mut all_targets = candidates.clone(); + // we remove and pop into `targets` `edge_per_voter` times. + let targets = (0 .. edge_per_voter).map(|_| { + all_targets.remove(rr(0, all_targets.len()) as usize) + }) + .collect::>(); + + let stake = STAKE + rr(10, 1000); + stake_of_tree.insert(acc, stake); + voters.push((acc, stake, targets)); + }); b.iter(|| { - let r = phragmen::elect::( - count, - 1_usize, + let PhragmenResult { winners, assignments } = sp_phragmen::elect::( + to_elect, + Zero::zero(), candidates.clone(), voters.clone(), - slashable_balance, - true, ).unwrap(); + let stake_of = |who: &AccountId| -> VoteWeight { + *stake_of_tree.get(who).unwrap() + }; + // Do the benchmarking with equalize. if eq_iters > 0 { - let elected_stashes = r.winners; - let assignments = r.assignments; - - let to_votes = |b: Balance| - >::convert(b) as u128; - - // Initialize the support of each candidate. - let mut supports = >::new(); - elected_stashes - .iter() - .map(|(e, _)| (e, to_votes(slashable_balance(e)))) - .for_each(|(e, s)| { - let item = Support { own: s, total: s, ..Default::default() }; - supports.insert(e.clone(), item); - }); - - // build support struct. - for (n, assignment) in assignments.iter() { - for (c, per_thing) in assignment.iter() { - let nominator_stake = to_votes(slashable_balance(n)); - let other_stake = *per_thing * nominator_stake; - if let Some(support) = supports.get_mut(c) { - support.total = support.total.saturating_add(other_stake); - support.others.push((n.clone(), other_stake)); - } - } - } - - let mut staked_assignments - : Vec<(AccountId, Vec>)> - = Vec::with_capacity(assignments.len()); - for (n, assignment) in assignments.iter() { - let mut staked_assignment - : Vec> - = Vec::with_capacity(assignment.len()); - for (c, per_thing) in assignment.iter() { - let nominator_stake = to_votes(slashable_balance(n)); - let other_stake = *per_thing * nominator_stake; - staked_assignment.push((c.clone(), other_stake)); - } - staked_assignments.push((n.clone(), staked_assignment)); - } - - let tolerance = 0_u128; - let iterations = 2_usize; - phragmen::equalize::<_, _, TestCurrencyToVote, _>( - staked_assignments, - &mut supports, - tolerance, - iterations, - slashable_balance, + use sp_phragmen::{equalize, assignment_ratio_to_staked, build_support_map, to_without_backing}; + let staked = assignment_ratio_to_staked(assignments, &stake_of); + let winners = to_without_backing(winners); + let mut support = build_support_map(winners.as_ref(), staked.as_ref()).0; + + equalize( + staked.into_iter().map(|a| (a.clone(), stake_of(&a.who))).collect(), + &mut support, + eq_tolerance, + eq_iters, ); } }) @@ -176,13 +182,13 @@ macro_rules! phragmen_benches { phragmen_benches! { bench_1_1: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 0, 0), - bench_1_2: (VALIDATORS*2, NOMINATORS, TO_ELECT, EDGES, 0, 0), - bench_1_3: (VALIDATORS*4, NOMINATORS, TO_ELECT, EDGES, 0, 0), - bench_1_4: (VALIDATORS*8, NOMINATORS, TO_ELECT, EDGES, 0, 0), + bench_1_2: (VALIDATORS * 2, NOMINATORS, TO_ELECT, EDGES, 0, 0), + bench_1_3: (VALIDATORS * 4, NOMINATORS, TO_ELECT, EDGES, 0, 0), + bench_1_4: (VALIDATORS * 8, NOMINATORS, TO_ELECT, EDGES, 0, 0), bench_1_1_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 2, 0), - bench_1_2_eq: (VALIDATORS*2, NOMINATORS, TO_ELECT, EDGES, 2, 0), - bench_1_3_eq: (VALIDATORS*4, NOMINATORS, TO_ELECT, EDGES, 2, 0), - bench_1_4_eq: (VALIDATORS*8, NOMINATORS, TO_ELECT, EDGES, 2, 0), + bench_1_2_eq: (VALIDATORS * 2, NOMINATORS, TO_ELECT, EDGES, 2, 0), + bench_1_3_eq: (VALIDATORS * 4, NOMINATORS, TO_ELECT, EDGES, 2, 0), + bench_1_4_eq: (VALIDATORS * 8, NOMINATORS, TO_ELECT, EDGES, 2, 0), bench_0_1: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 0, 0), bench_0_2: (VALIDATORS, NOMINATORS, TO_ELECT * 4, EDGES, 0, 0), @@ -194,20 +200,20 @@ phragmen_benches! { bench_0_4_eq: (VALIDATORS, NOMINATORS, TO_ELECT * 16, EDGES , 2, 0), bench_2_1: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 0, 0), - bench_2_2: (VALIDATORS, NOMINATORS*2, TO_ELECT, EDGES, 0, 0), - bench_2_3: (VALIDATORS, NOMINATORS*4, TO_ELECT, EDGES, 0, 0), - bench_2_4: (VALIDATORS, NOMINATORS*8, TO_ELECT, EDGES, 0, 0), + bench_2_2: (VALIDATORS, NOMINATORS * 2, TO_ELECT, EDGES, 0, 0), + bench_2_3: (VALIDATORS, NOMINATORS * 4, TO_ELECT, EDGES, 0, 0), + bench_2_4: (VALIDATORS, NOMINATORS * 8, TO_ELECT, EDGES, 0, 0), bench_2_1_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 2, 0), - bench_2_2_eq: (VALIDATORS, NOMINATORS*2, TO_ELECT, EDGES, 2, 0), - bench_2_3_eq: (VALIDATORS, NOMINATORS*4, TO_ELECT, EDGES, 2, 0), - bench_2_4_eq: (VALIDATORS, NOMINATORS*8, TO_ELECT, EDGES, 2, 0), + bench_2_2_eq: (VALIDATORS, NOMINATORS * 2, TO_ELECT, EDGES, 2, 0), + bench_2_3_eq: (VALIDATORS, NOMINATORS * 4, TO_ELECT, EDGES, 2, 0), + bench_2_4_eq: (VALIDATORS, NOMINATORS * 8, TO_ELECT, EDGES, 2, 0), bench_3_1: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 0, 0 ), - bench_3_2: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*2, 0, 0), - bench_3_3: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*4, 0, 0), - bench_3_4: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*8, 0, 0), + bench_3_2: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES * 2, 0, 0), + bench_3_3: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES * 4, 0, 0), + bench_3_4: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES * 8, 0, 0), bench_3_1_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES, 2, 0), - bench_3_2_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*2, 2, 0), - bench_3_3_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*4, 2, 0), - bench_3_4_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES*8, 2, 0), + bench_3_2_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES * 2, 2, 0), + bench_3_3_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES * 4, 2, 0), + bench_3_4_eq: (VALIDATORS, NOMINATORS, TO_ELECT, EDGES * 8, 2, 0), } diff --git a/primitives/phragmen/compact/src/staked.rs b/primitives/phragmen/compact/src/staked.rs index a7cf853f17..81ccb5c559 100644 --- a/primitives/phragmen/compact/src/staked.rs +++ b/primitives/phragmen/compact/src/staked.rs @@ -73,7 +73,7 @@ fn into_impl(count: usize) -> TokenStream2 { quote!( for (voter_index, target_index) in self.#name { let who = voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?; - let all_stake = max_of(&who); + let all_stake: u128 = max_of(&who).into(); assignments.push(_phragmen::StakedAssignment { who, distribution: vec![(target_at(target_index).ok_or(_phragmen::Error::CompactInvalidIndex)?, all_stake)], @@ -87,7 +87,7 @@ fn into_impl(count: usize) -> TokenStream2 { quote!( for (voter_index, (t1_idx, w1), t2_idx) in self.#name { let who = voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?; - let all_stake = max_of(&who); + let all_stake: u128 = max_of(&who).into(); if w1 >= all_stake { return Err(_phragmen::Error::CompactStakeOverflow); @@ -112,7 +112,7 @@ fn into_impl(count: usize) -> TokenStream2 { for (voter_index, inners, t_last_idx) in self.#name { let who = voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?; let mut sum = u128::min_value(); - let all_stake = max_of(&who); + let all_stake: u128 = max_of(&who).into(); let mut inners_parsed = inners .iter() @@ -154,6 +154,7 @@ pub(crate) fn staked( let from_impl = from_impl(count); let into_impl = into_impl(count); + quote!( impl< #voter_type: _phragmen::codec::Codec + Default + Copy, @@ -196,7 +197,7 @@ pub(crate) fn staked( ) -> Result>, _phragmen::Error> where - for<'r> FM: Fn(&'r A) -> u128, + for<'r> FM: Fn(&'r A) -> u64, A: _phragmen::IdentifierT, { let mut assignments: Vec<_phragmen::StakedAssignment> = Default::default(); diff --git a/primitives/phragmen/fuzzer/Cargo.toml b/primitives/phragmen/fuzzer/Cargo.toml index 90af69a707..4c1e16906a 100644 --- a/primitives/phragmen/fuzzer/Cargo.toml +++ b/primitives/phragmen/fuzzer/Cargo.toml @@ -1,19 +1,28 @@ [package] name = "sp-phragmen-fuzzer" -version = "2.0.0" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "Fuzzer for phragmén implementation." +documentation = "https://docs.rs/sp-phragmen-fuzzer" [dependencies] -sp-phragmen = { version = "2.0.0-alpha.3", path = ".." } +sp-phragmen = { version = "2.0.0-alpha.5", path = ".." } +sp-std = { version = "2.0.0-alpha.5", path = "../../std" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } honggfuzz = "0.5" -rand = "0.7.3" - -[workspace] +rand = { version = "0.7.3", features = ["std", "small_rng"] } [[bin]] name = "reduce" path = "src/reduce.rs" +[[bin]] +name = "equalize" +path = "src/equalize.rs" + [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/phragmen/fuzzer/src/common.rs b/primitives/phragmen/fuzzer/src/common.rs new file mode 100644 index 0000000000..3429dcb20a --- /dev/null +++ b/primitives/phragmen/fuzzer/src/common.rs @@ -0,0 +1,29 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Common fuzzing utils. + +/// converts x into the range [a, b] in a pseudo-fair way. +pub fn to_range(x: usize, a: usize, b: usize) -> usize { + // does not work correctly if b < 2*a + assert!(b > 2 * a); + let collapsed = x % b; + if collapsed >= a { + collapsed + } else { + collapsed + a + } +} diff --git a/primitives/phragmen/fuzzer/src/equalize.rs b/primitives/phragmen/fuzzer/src/equalize.rs new file mode 100644 index 0000000000..cb4f98c4eb --- /dev/null +++ b/primitives/phragmen/fuzzer/src/equalize.rs @@ -0,0 +1,146 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Fuzzing fro the equalize algorithm +//! +//! It ensures that any solution which gets equalized will lead into a better or equally scored +//! one. + +mod common; +use common::to_range; +use honggfuzz::fuzz; +use sp_phragmen::{ + equalize, assignment_ratio_to_staked, build_support_map, to_without_backing, elect, + PhragmenResult, VoteWeight, evaluate_support, is_score_better, +}; +use sp_std::collections::btree_map::BTreeMap; +use sp_runtime::Perbill; +use rand::{self, Rng, SeedableRng, RngCore}; + +type AccountId = u64; + +fn generate_random_phragmen_result( + voter_count: u64, + target_count: u64, + to_elect: usize, + edge_per_voter: u64, + mut rng: impl RngCore, +) -> (PhragmenResult, BTreeMap) { + let prefix = 100_000; + // Note, it is important that stakes are always bigger than ed and + let base_stake: u64 = 1_000_000_000; + let ed: u64 = base_stake; + + let mut candidates = Vec::with_capacity(target_count as usize); + let mut stake_of_tree: BTreeMap = BTreeMap::new(); + + (1..=target_count).for_each(|acc| { + candidates.push(acc); + let stake_var = rng.gen_range(ed, 100 * ed); + stake_of_tree.insert(acc, base_stake + stake_var); + }); + + let mut voters = Vec::with_capacity(voter_count as usize); + (prefix ..= (prefix + voter_count)).for_each(|acc| { + // all possible targets + let mut all_targets = candidates.clone(); + // we remove and pop into `targets` `edge_per_voter` times. + let targets = (0..edge_per_voter).map(|_| { + let upper = all_targets.len() - 1; + let idx = rng.gen_range(0, upper); + all_targets.remove(idx) + }) + .collect::>(); + + let stake_var = rng.gen_range(ed, 100 * ed) ; + let stake = base_stake + stake_var; + stake_of_tree.insert(acc, stake); + voters.push((acc, stake, targets)); + }); + + ( + elect::( + to_elect, + 0, + candidates, + voters, + ).unwrap(), + stake_of_tree, + ) +} + +fn main() { + loop { + fuzz!(|data: (usize, usize, usize, usize, usize, u64)| { + let (mut target_count, mut voter_count, mut iterations, mut edge_per_voter, mut to_elect, seed) = data; + let rng = rand::rngs::SmallRng::seed_from_u64(seed); + target_count = to_range(target_count, 50, 2000); + voter_count = to_range(voter_count, 50, 1000); + iterations = to_range(iterations, 1, 20); + to_elect = to_range(to_elect, 25, target_count); + edge_per_voter = to_range(edge_per_voter, 1, target_count); + + println!("++ [{} / {} / {} / {}]", voter_count, target_count, to_elect, iterations); + let (PhragmenResult { winners, assignments }, stake_of_tree) = generate_random_phragmen_result( + voter_count as u64, + target_count as u64, + to_elect, + edge_per_voter as u64, + rng, + ); + + let stake_of = |who: &AccountId| -> VoteWeight { + *stake_of_tree.get(who).unwrap() + }; + + let mut staked = assignment_ratio_to_staked(assignments.clone(), &stake_of); + let winners = to_without_backing(winners); + let mut support = build_support_map(winners.as_ref(), staked.as_ref()).0; + + let initial_score = evaluate_support(&support); + if initial_score[0] == 0 { + // such cases cannot be improved by reduce. + return; + } + + let i = equalize( + &mut staked, + &mut support, + 10, + iterations, + ); + + let final_score = evaluate_support(&support); + if final_score[0] == initial_score[0] { + // such solutions can only be improved by such a tiny fiction that it is most often + // wrong due to rounding errors. + return; + } + + let enhance = is_score_better(initial_score, final_score); + + println!( + "iter = {} // {:?} -> {:?} [{}]", + i, + initial_score, + final_score, + enhance, + ); + // if more than one iteration has been done, or they must be equal. + assert!(enhance || initial_score == final_score || i == 0) + }); + } +} diff --git a/primitives/phragmen/fuzzer/src/reduce.rs b/primitives/phragmen/fuzzer/src/reduce.rs index 4bf08590a1..f0a1646663 100644 --- a/primitives/phragmen/fuzzer/src/reduce.rs +++ b/primitives/phragmen/fuzzer/src/reduce.rs @@ -14,6 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +//! Fuzzing for the reduce algorithm. +//! +//! It that reduce always return a new set og edges in which the bound is kept (`edges_after <= m + +//! n,`) and the result must effectively be the same, meaning that the same support map should be +//! computable from both. +//! //! # Running //! //! Run with `cargo hfuzz run reduce`. `honggfuzz`. @@ -24,8 +30,11 @@ //! `cargo hfuzz run-debug reduce hfuzz_workspace/reduce/*.fuzz`. use honggfuzz::fuzz; + +mod common; +use common::to_range; use sp_phragmen::{StakedAssignment, ExtendedBalance, build_support_map, reduce}; -use rand::{self, Rng}; +use rand::{self, Rng, SeedableRng, RngCore}; type Balance = u128; type AccountId = u64; @@ -35,15 +44,20 @@ const KSM: Balance = 1_000_000_000_000; fn main() { loop { - fuzz!(|_data: _| { - let (assignments, winners) = generate_random_phragmen_assignment( - rr(100, 1000), - rr(100, 2000), - 8, - 8, - ); + fuzz!(|data: (usize, usize, u64)| { + let (mut voter_count, mut target_count, seed) = data; + let rng = rand::rngs::SmallRng::seed_from_u64(seed); + target_count = to_range(target_count, 100, 1000); + voter_count = to_range(voter_count, 100, 2000); + let (assignments, winners) = generate_random_phragmen_assignment( + voter_count, + target_count, + 8, + 8, + rng + ); reduce_and_compare(&assignments, &winners); - }); + }); } } @@ -52,13 +66,10 @@ fn generate_random_phragmen_assignment( target_count: usize, avg_edge_per_voter: usize, edge_per_voter_var: usize, + mut rng: impl RngCore, ) -> (Vec>, Vec) { - // random in range of (a, b) - let rr_128 = |a: u128, b: u128| -> u128 { rand::thread_rng().gen_range(a, b) }; - // prefix to distinguish the voter and target account ranges. let target_prefix = 1_000_000; - // let target_prefix = 1000; assert!(voter_count < target_prefix); let mut assignments = Vec::with_capacity(voter_count as usize); @@ -70,17 +81,17 @@ fn generate_random_phragmen_assignment( (1..=voter_count).for_each(|acc| { let mut targets_to_chose_from = all_targets.clone(); - let targets_to_chose = if edge_per_voter_var > 0 { rr( + let targets_to_chose = if edge_per_voter_var > 0 { rng.gen_range( avg_edge_per_voter - edge_per_voter_var, avg_edge_per_voter + edge_per_voter_var, ) } else { avg_edge_per_voter }; let distribution = (0..targets_to_chose).map(|_| { - let target = targets_to_chose_from.remove(rr(0, targets_to_chose_from.len())); + let target = targets_to_chose_from.remove(rng.gen_range(0, targets_to_chose_from.len())); if winners.iter().find(|w| **w == target).is_none() { winners.push(target.clone()); } - (target, rr_128(1 * KSM, 100 * KSM)) + (target, rng.gen_range(1 * KSM, 100 * KSM)) }).collect::>(); assignments.push(StakedAssignment { @@ -139,7 +150,3 @@ fn assignment_len(assignments: &[StakedAssignment]) -> u32 { assignments.iter().for_each(|x| x.distribution.iter().for_each(|_| counter += 1)); counter } - -fn rr(a: usize, b: usize) -> usize { - rand::thread_rng().gen_range(a, b) -} diff --git a/primitives/phragmen/src/helpers.rs b/primitives/phragmen/src/helpers.rs index 27f51b4a05..216de9243e 100644 --- a/primitives/phragmen/src/helpers.rs +++ b/primitives/phragmen/src/helpers.rs @@ -16,7 +16,7 @@ //! Helper methods for phragmen. -use crate::{Assignment, ExtendedBalance, IdentifierT, StakedAssignment}; +use crate::{Assignment, ExtendedBalance, VoteWeight, IdentifierT, StakedAssignment, WithApprovalOf}; use sp_runtime::PerThing; use sp_std::prelude::*; @@ -26,7 +26,7 @@ pub fn assignment_ratio_to_staked( stake_of: FS, ) -> Vec> where - for<'r> FS: Fn(&'r A) -> ExtendedBalance, + for<'r> FS: Fn(&'r A) -> VoteWeight, T: sp_std::ops::Mul, ExtendedBalance: From<::Inner>, { @@ -34,30 +34,34 @@ where .into_iter() .map(|a| { let stake = stake_of(&a.who); - a.into_staked(stake, true) + a.into_staked(stake.into(), true) }) .collect() } /// Converts a vector of staked assignments into ones with ratio values. pub fn assignment_staked_to_ratio( - ratio: Vec>, + staked: Vec>, ) -> Vec> where ExtendedBalance: From<::Inner>, { - ratio.into_iter().map(|a| a.into_assignment(true)).collect() + staked.into_iter().map(|a| a.into_assignment(true)).collect() +} + +/// consumes a vector of winners with backing stake to just winners. +pub fn to_without_backing(winners: Vec>) -> Vec { + winners.into_iter().map(|(who, _)| who).collect::>() } #[cfg(test)] mod tests { use super::*; - use crate::ExtendedBalance; use sp_runtime::Perbill; #[test] fn into_staked_works() { - let ratio = vec![ + let assignments = vec![ Assignment { who: 1u32, distribution: vec![ @@ -74,8 +78,8 @@ mod tests { }, ]; - let stake_of = |_: &u32| -> ExtendedBalance { 100u128 }; - let staked = assignment_ratio_to_staked(ratio, stake_of); + let stake_of = |_: &u32| -> VoteWeight { 100 }; + let staked = assignment_ratio_to_staked(assignments, stake_of); assert_eq!( staked, diff --git a/primitives/phragmen/src/lib.rs b/primitives/phragmen/src/lib.rs index c0d94a71e1..01d034a95e 100644 --- a/primitives/phragmen/src/lib.rs +++ b/primitives/phragmen/src/lib.rs @@ -35,7 +35,7 @@ use sp_std::{prelude::*, collections::btree_map::BTreeMap, fmt::Debug, cmp::Ordering, convert::TryFrom}; use sp_runtime::{helpers_128bit::multiply_by_rational, PerThing, Rational128, RuntimeDebug, SaturatedConversion}; -use sp_runtime::traits::{Zero, Convert, Member, AtLeast32Bit, Saturating, Bounded}; +use sp_runtime::traits::{Zero, Member, Saturating, Bounded}; #[cfg(test)] mod mock; @@ -88,17 +88,19 @@ pub enum Error { CompactInvalidIndex, } -/// A type in which performing operations on balances and stakes of candidates and voters are safe. -/// -/// This module's functions expect a `Convert` type to convert all balances to u64. Hence, u128 is -/// a safe type for arithmetic operations over them. -/// -/// Balance types converted to `ExtendedBalance` are referred to as `Votes`. +/// A type which is used in the API of this crate as a numeric weight of a vote, most often the +/// stake of the voter. It is always converted to [`ExtendedBalance`] for computation. +pub type VoteWeight = u64; + +/// A type in which performing operations on vote weights are safe. pub type ExtendedBalance = u128; /// The score of an assignment. This can be computed from the support map via [`evaluate_support`]. pub type PhragmenScore = [ExtendedBalance; 3]; +/// A winner, with their respective approval stake. +pub type WithApprovalOf = (A, ExtendedBalance); + /// The denominator used for loads. Since votes are collected as u64, the smallest ratio that we /// might collect is `1/approval_stake` where approval stake is the sum of votes. Hence, some number /// bigger than u64::max_value() is needed. For maximum accuracy we simply use u128; @@ -146,7 +148,7 @@ struct Edge { pub struct PhragmenResult { /// Just winners zipped with their approval stake. Note that the approval stake is merely the /// sub of their received stake and could be used for very basic sorting and approval voting. - pub winners: Vec<(AccountId, ExtendedBalance)>, + pub winners: Vec>, /// Individual assignments. for each tuple, the first elements is a voter and the second /// is the list of candidates that it supports. pub assignments: Vec>, @@ -285,6 +287,11 @@ impl StakedAssignment { distribution, } } + + /// Get the total stake of this assignment (aka voter budget). + pub fn total(&self) -> ExtendedBalance { + self.distribution.iter().fold(Zero::zero(), |a, b| a.saturating_add(b.1)) + } } /// A structure to demonstrate the phragmen result from the perspective of the candidate, i.e. how @@ -316,25 +323,20 @@ pub type SupportMap = BTreeMap>; /// `None` is returned. /// * `initial_candidates`: candidates list to be elected from. /// * `initial_voters`: voters list. -/// * `stake_of`: something that can return the stake stake of a particular candidate or voter. /// /// This function does not strip out candidates who do not have any backing stake. It is the /// responsibility of the caller to make sure only those candidates who have a sensible economic /// value are passed in. From the perspective of this function, a candidate can easily be among the /// winner with no backing stake. -pub fn elect( +pub fn elect( candidate_count: usize, minimum_candidate_count: usize, initial_candidates: Vec, - initial_voters: Vec<(AccountId, Balance, Vec)>, + initial_voters: Vec<(AccountId, VoteWeight, Vec)>, ) -> Option> where AccountId: Default + Ord + Member, - Balance: Default + Copy + AtLeast32Bit, - C: Convert + Convert, R: PerThing, { - let to_votes = |b: Balance| >::convert(b) as ExtendedBalance; - // return structures let mut elected_candidates: Vec<(AccountId, ExtendedBalance)>; let mut assigned: Vec>; @@ -368,14 +370,14 @@ pub fn elect( if let Some(idx) = c_idx_cache.get(&v) { // This candidate is valid + already cached. candidates[*idx].approval_stake = candidates[*idx].approval_stake - .saturating_add(to_votes(voter_stake)); + .saturating_add(voter_stake.into()); edges.push(Edge { who: v.clone(), candidate_index: *idx, ..Default::default() }); } // else {} would be wrong votes. We don't really care about it. } Voter { who, edges: edges, - budget: to_votes(voter_stake), + budget: voter_stake.into(), load: Rational128::zero(), } })); @@ -633,32 +635,27 @@ pub fn is_score_better(this: PhragmenScore, that: PhragmenScore) -> bool { /// rounds. The number of rounds and the maximum diff-per-round tolerance can be tuned through input /// parameters. /// -/// No value is returned from the function and the `supports` parameter is updated. +/// Returns the number of iterations that were preformed. /// /// - `assignments`: exactly the same is the output of phragmen. /// - `supports`: mutable reference to s `SupportMap`. This parameter is updated. /// - `tolerance`: maximum difference that can occur before an early quite happens. /// - `iterations`: maximum number of iterations that will be processed. -/// - `stake_of`: something that can return the stake stake of a particular candidate or voter. -pub fn equalize( - mut assignments: Vec>, +pub fn equalize( + assignments: &mut Vec>, supports: &mut SupportMap, tolerance: ExtendedBalance, iterations: usize, - stake_of: FS, -) where - C: Convert + Convert, - for<'r> FS: Fn(&'r AccountId) -> Balance, - AccountId: Ord + Clone, -{ - // prepare the data for equalise - for _i in 0..iterations { - let mut max_diff = 0; +) -> usize where AccountId: Ord + Clone { + if iterations == 0 { return 0; } - for StakedAssignment { who, distribution } in assignments.iter_mut() { - let voter_budget = stake_of(&who); - - let diff = do_equalize::<_, _, C>( + let mut i = 0 ; + loop { + let mut max_diff = 0; + for assignment in assignments.iter_mut() { + let voter_budget = assignment.total(); + let StakedAssignment { who, distribution } = assignment; + let diff = do_equalize( who, voter_budget, distribution, @@ -668,28 +665,22 @@ pub fn equalize( if diff > max_diff { max_diff = diff; } } - if max_diff < tolerance { - break; + i += 1; + if max_diff <= tolerance || i >= iterations { + break i; } } } /// actually perform equalize. same interface is `equalize`. Just called in loops with a check for /// maximum difference. -fn do_equalize( +fn do_equalize( voter: &AccountId, - budget_balance: Balance, + budget: ExtendedBalance, elected_edges: &mut Vec<(AccountId, ExtendedBalance)>, support_map: &mut SupportMap, tolerance: ExtendedBalance -) -> ExtendedBalance where - C: Convert + Convert, - AccountId: Ord + Clone, -{ - let to_votes = |b: Balance| - >::convert(b) as ExtendedBalance; - let budget = to_votes(budget_balance); - +) -> ExtendedBalance where AccountId: Ord + Clone { // Nothing to do. This voter had nothing useful. // Defensive only. Assignment list should always be populated. 1 might happen for self vote. if elected_edges.is_empty() || elected_edges.len() == 1 { return 0; } diff --git a/primitives/phragmen/src/mock.rs b/primitives/phragmen/src/mock.rs index 31ce3d38c3..5aab5ff2f7 100644 --- a/primitives/phragmen/src/mock.rs +++ b/primitives/phragmen/src/mock.rs @@ -18,21 +18,13 @@ #![cfg(test)] -use crate::{elect, PhragmenResult, Assignment}; +use crate::{elect, PhragmenResult, Assignment, VoteWeight, ExtendedBalance}; use sp_runtime::{ assert_eq_error_rate, PerThing, - traits::{Convert, Member, SaturatedConversion, Zero, One} + traits::{Member, SaturatedConversion, Zero, One} }; use sp_std::collections::btree_map::BTreeMap; -pub(crate) struct TestCurrencyToVote; -impl Convert for TestCurrencyToVote { - fn convert(x: Balance) -> u64 { x.saturated_into() } -} -impl Convert for TestCurrencyToVote { - fn convert(x: u128) -> Balance { x } -} - #[derive(Default, Debug)] pub(crate) struct _Candidate { who: A, @@ -66,12 +58,11 @@ pub(crate) struct _Support { pub(crate) type _PhragmenAssignment = (A, f64); pub(crate) type _SupportMap = BTreeMap>; -pub(crate) type Balance = u128; pub(crate) type AccountId = u64; #[derive(Debug, Clone)] pub(crate) struct _PhragmenResult { - pub winners: Vec<(A, Balance)>, + pub winners: Vec<(A, ExtendedBalance)>, pub assignments: Vec<(A, Vec<_PhragmenAssignment>)> } @@ -87,9 +78,9 @@ pub(crate) fn elect_float( stake_of: FS, ) -> Option<_PhragmenResult> where A: Default + Ord + Member + Copy, - for<'r> FS: Fn(&'r A) -> Balance, + for<'r> FS: Fn(&'r A) -> VoteWeight, { - let mut elected_candidates: Vec<(A, Balance)>; + let mut elected_candidates: Vec<(A, ExtendedBalance)>; let mut assigned: Vec<(A, Vec<_PhragmenAssignment>)>; let mut c_idx_cache = BTreeMap::::new(); let num_voters = initial_candidates.len() + initial_voters.len(); @@ -161,7 +152,7 @@ pub(crate) fn elect_float( } } - elected_candidates.push((winner.who.clone(), winner.approval_stake as Balance)); + elected_candidates.push((winner.who.clone(), winner.approval_stake as ExtendedBalance)); } else { break } @@ -195,7 +186,7 @@ pub(crate) fn equalize_float( iterations: usize, stake_of: FS, ) where - for<'r> FS: Fn(&'r A) -> Balance, + for<'r> FS: Fn(&'r A) -> VoteWeight, A: Ord + Clone + std::fmt::Debug, { for _i in 0..iterations { @@ -220,7 +211,7 @@ pub(crate) fn equalize_float( pub(crate) fn do_equalize_float( voter: &A, - budget_balance: Balance, + budget_balance: VoteWeight, elected_edges: &mut Vec<_PhragmenAssignment>, support_map: &mut _SupportMap, tolerance: f64 @@ -310,12 +301,12 @@ pub(crate) fn do_equalize_float( } -pub(crate) fn create_stake_of(stakes: &[(AccountId, Balance)]) - -> Box Balance> +pub(crate) fn create_stake_of(stakes: &[(AccountId, VoteWeight)]) + -> Box VoteWeight> { - let mut storage = BTreeMap::::new(); + let mut storage = BTreeMap::::new(); stakes.iter().for_each(|s| { storage.insert(s.0, s.1); }); - let stake_of = move |who: &AccountId| -> Balance { storage.get(who).unwrap().to_owned() }; + let stake_of = move |who: &AccountId| -> VoteWeight { storage.get(who).unwrap().to_owned() }; Box::new(stake_of) } @@ -331,12 +322,12 @@ pub fn check_assignments_sum(assignments: Vec( candidates: Vec, voters: Vec<(AccountId, Vec)>, - stake_of: &Box Balance>, + stake_of: &Box VoteWeight>, to_elect: usize, min_to_elect: usize, ) { // run fixed point code. - let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments } = elect::<_, Output>( to_elect, min_to_elect, candidates.clone(), @@ -352,7 +343,7 @@ pub(crate) fn run_and_compare( &stake_of, ).unwrap(); - assert_eq!(winners, truth_value.winners); + assert_eq!(winners.iter().map(|(x, _)| x).collect::>(), truth_value.winners.iter().map(|(x, _)| x).collect::>()); for Assignment { who, distribution } in assignments.clone() { if let Some(float_assignments) = truth_value.assignments.iter().find(|x| x.0 == who) { @@ -379,7 +370,7 @@ pub(crate) fn build_support_map_float( result: &mut _PhragmenResult, stake_of: FS, ) -> _SupportMap - where for<'r> FS: Fn(&'r AccountId) -> Balance + where for<'r> FS: Fn(&'r AccountId) -> VoteWeight { let mut supports = <_SupportMap>::new(); result.winners diff --git a/primitives/phragmen/src/tests.rs b/primitives/phragmen/src/tests.rs index e9861ede72..9d16d67495 100644 --- a/primitives/phragmen/src/tests.rs +++ b/primitives/phragmen/src/tests.rs @@ -20,11 +20,11 @@ use crate::mock::*; use crate::{ - elect, equalize, build_support_map, is_score_better, + elect, equalize, build_support_map, is_score_better, helpers::*, Support, StakedAssignment, Assignment, PhragmenResult, ExtendedBalance, }; use substrate_test_utils::assert_eq_uvec; -use sp_runtime::{Perbill, Permill, Percent, PerU16, traits::Convert}; +use sp_runtime::{Perbill, Permill, Percent, PerU16}; #[test] fn float_phragmen_poc_works() { @@ -82,7 +82,7 @@ fn phragmen_poc_works() { ]; let stake_of = create_stake_of(&[(10, 10), (20, 20), (30, 30)]); - let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Perbill>( + let PhragmenResult { winners, assignments } = elect::<_, Perbill>( 2, 2, candidates, @@ -110,6 +110,77 @@ fn phragmen_poc_works() { }, ] ); + + let mut staked = assignment_ratio_to_staked(assignments, &stake_of); + let winners = to_without_backing(winners); + let mut support_map = build_support_map::(&winners, &staked).0; + + assert_eq_uvec!( + staked, + vec![ + StakedAssignment { + who: 10u64, + distribution: vec![(2, 10)], + }, + StakedAssignment { + who: 20, + distribution: vec![(3, 20)], + }, + StakedAssignment { + who: 30, + distribution: vec![ + (2, 15), + (3, 15), + ], + }, + ] + ); + + assert_eq!( + *support_map.get(&2).unwrap(), + Support:: { total: 25, voters: vec![(10, 10), (30, 15)] }, + ); + assert_eq!( + *support_map.get(&3).unwrap(), + Support:: { total: 35, voters: vec![(20, 20), (30, 15)] }, + ); + + equalize( + &mut staked, + &mut support_map, + 0, + 2, + ); + + assert_eq_uvec!( + staked, + vec![ + StakedAssignment { + who: 10u64, + distribution: vec![(2, 10)], + }, + StakedAssignment { + who: 20, + distribution: vec![(3, 20)], + }, + StakedAssignment { + who: 30, + distribution: vec![ + (2, 20), + (3, 10), + ], + }, + ] + ); + + assert_eq!( + *support_map.get(&2).unwrap(), + Support:: { total: 30, voters: vec![(10, 10), (30, 20)] }, + ); + assert_eq!( + *support_map.get(&3).unwrap(), + Support:: { total: 30, voters: vec![(20, 20), (30, 10)] }, + ); } #[test] @@ -168,7 +239,7 @@ fn phragmen_accuracy_on_large_scale_only_validators() { (5, (u64::max_value() - 2).into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Perbill>( + let PhragmenResult { winners, assignments } = elect::<_, Perbill>( 2, 2, candidates.clone(), @@ -198,7 +269,7 @@ fn phragmen_accuracy_on_large_scale_validators_and_nominators() { (14, u64::max_value().into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Perbill>( + let PhragmenResult { winners, assignments } = elect::<_, Perbill>( 2, 2, candidates, @@ -241,7 +312,7 @@ fn phragmen_accuracy_on_small_scale_self_vote() { (30, 1), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, _, TestCurrencyToVote, Perbill>( + let PhragmenResult { winners, assignments: _ } = elect::<_, Perbill>( 3, 3, candidates, @@ -271,7 +342,7 @@ fn phragmen_accuracy_on_small_scale_no_self_vote() { (3, 1), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, _, TestCurrencyToVote, Perbill>( + let PhragmenResult { winners, assignments: _ } = elect::<_, Perbill>( 3, 3, candidates, @@ -304,7 +375,7 @@ fn phragmen_large_scale_test() { (50, 990000000000000000), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Perbill>( + let PhragmenResult { winners, assignments } = elect::<_, Perbill>( 2, 2, candidates, @@ -330,7 +401,7 @@ fn phragmen_large_scale_test_2() { (50, nom_budget.into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Perbill>( + let PhragmenResult { winners, assignments } = elect::<_, Perbill>( 2, 2, candidates, @@ -406,7 +477,7 @@ fn elect_has_no_entry_barrier() { (2, 10), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, _, TestCurrencyToVote, Perbill>( + let PhragmenResult { winners, assignments: _ } = elect::<_, Perbill>( 3, 3, candidates, @@ -433,7 +504,7 @@ fn minimum_to_elect_is_respected() { (2, 10), ]); - let maybe_result = elect::<_, _, TestCurrencyToVote, Perbill>( + let maybe_result = elect::<_, Perbill>( 10, 10, candidates, @@ -459,7 +530,7 @@ fn self_votes_should_be_kept() { (1, 8), ]); - let result = elect::<_, _, TestCurrencyToVote, Perbill>( + let result = elect::<_, Perbill>( 2, 2, candidates, @@ -480,16 +551,11 @@ fn self_votes_should_be_kept() { ], ); - let staked_assignments: Vec> = result.assignments - .into_iter() - .map(|a| { - let stake = >::convert(stake_of(&a.who)) as ExtendedBalance; - a.into_staked(stake, true) - }).collect(); + let mut staked_assignments = assignment_ratio_to_staked(result.assignments, &stake_of); + let winners = to_without_backing(result.winners); - let winners = result.winners.into_iter().map(|(who, _)| who).collect::>(); let (mut supports, _) = build_support_map::( - winners.as_slice(), + &winners, &staked_assignments, ); @@ -503,12 +569,11 @@ fn self_votes_should_be_kept() { &Support { total: 24u128, voters: vec![(20u64, 20u128), (1u64, 4u128)] }, ); - equalize::( - staked_assignments, + equalize( + &mut staked_assignments, &mut supports, 0, 2usize, - &stake_of, ); assert_eq!( @@ -526,7 +591,7 @@ fn assignment_convert_works() { let staked = StakedAssignment { who: 1 as AccountId, distribution: vec![ - (20, 100 as Balance), + (20, 100 as ExtendedBalance), (30, 25), ], }; @@ -578,10 +643,10 @@ fn score_comparison_is_lexicographical() { mod compact { use codec::{Decode, Encode}; - use crate::generate_compact_solution_type; - use super::{AccountId, Balance}; + use crate::{generate_compact_solution_type, VoteWeight}; + use super::{AccountId}; // these need to come from the same dev-dependency `sp-phragmen`, not from the crate. - use sp_phragmen::{Assignment, StakedAssignment, Error as PhragmenError}; + use sp_phragmen::{Assignment, StakedAssignment, Error as PhragmenError, ExtendedBalance}; use sp_std::{convert::{TryInto, TryFrom}, fmt::Debug}; use sp_runtime::Percent; @@ -736,7 +801,7 @@ mod compact { let assignments = vec![ StakedAssignment { who: 2 as AccountId, - distribution: vec![(20, 100 as Balance)] + distribution: vec![(20, 100 as ExtendedBalance)] }, StakedAssignment { who: 4, @@ -773,7 +838,7 @@ mod compact { targets.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() }; - let compacted = >::from_staked( + let compacted = >::from_staked( assignments.clone(), voter_index, target_index, @@ -794,7 +859,7 @@ mod compact { } ); - let max_of_fn = |_: &AccountId| -> Balance { 100u128 }; + let max_of_fn = |_: &AccountId| -> VoteWeight { 100 }; let voter_at = |a: u16| -> Option { voters.get(a as usize).cloned() }; let target_at = |a: u16| -> Option { targets.get(a as usize).cloned() }; @@ -812,14 +877,14 @@ mod compact { fn compact_into_stake_must_report_overflow() { // The last edge which is computed from the rest should ALWAYS be positive. // in votes2 - let compact = TestCompact:: { + let compact = TestCompact:: { votes1: Default::default(), votes2: vec![(0, (1, 10), 2)], ..Default::default() }; let entity_at = |a: u16| -> Option { Some(a as AccountId) }; - let max_of = |_: &AccountId| -> Balance { 5 }; + let max_of = |_: &AccountId| -> VoteWeight { 5 }; assert_eq!( compact.into_staked(&max_of, &entity_at, &entity_at).unwrap_err(), @@ -827,7 +892,7 @@ mod compact { ); // in votes3 onwards - let compact = TestCompact:: { + let compact = TestCompact:: { votes1: Default::default(), votes2: Default::default(), votes3: vec![(0, [(1, 7), (2, 8)], 3)], @@ -840,7 +905,7 @@ mod compact { ); // Also if equal - let compact = TestCompact:: { + let compact = TestCompact:: { votes1: Default::default(), votes2: Default::default(), // 5 is total, we cannot leave none for 30 here. @@ -889,13 +954,13 @@ mod compact { let assignments = vec![ StakedAssignment { who: 1 as AccountId, - distribution: (10..26).map(|i| (i as AccountId, i as Balance)).collect::>(), + distribution: (10..26).map(|i| (i as AccountId, i as ExtendedBalance)).collect::>(), }, ]; let entity_index = |a: &AccountId| -> Option { Some(*a as u16) }; - let compacted = >::from_staked( + let compacted = >::from_staked( assignments.clone(), entity_index, entity_index, @@ -906,11 +971,11 @@ mod compact { let assignments = vec![ StakedAssignment { who: 1 as AccountId, - distribution: (10..27).map(|i| (i as AccountId, i as Balance)).collect::>(), + distribution: (10..27).map(|i| (i as AccountId, i as ExtendedBalance)).collect::>(), }, ]; - let compacted = >::from_staked( + let compacted = >::from_staked( assignments.clone(), entity_index, entity_index, @@ -948,7 +1013,7 @@ mod compact { let assignments = vec![ StakedAssignment { who: 1 as AccountId, - distribution: vec![(10, 100 as Balance), (11, 100)] + distribution: vec![(10, 100 as ExtendedBalance), (11, 100)] }, StakedAssignment { who: 2, @@ -963,7 +1028,7 @@ mod compact { targets.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() }; - let compacted = >::from_staked( + let compacted = >::from_staked( assignments.clone(), voter_index, target_index, -- GitLab From 0354855d876e82de969738587090b37c4fcf7221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 17 Apr 2020 09:53:52 +0200 Subject: [PATCH 253/300] Listen on ipv6 by default as well (#5677) Instead of just listening on ipv4 by default, this enables listening on ipv6 as well. While doing this, it also fixes a bug which lead to always listen on all sockets, even if we specify listen addresses explicitly. --- client/cli/src/params/network_params.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/client/cli/src/params/network_params.rs b/client/cli/src/params/network_params.rs index 21e44f9782..6d9ffd6a6e 100644 --- a/client/cli/src/params/network_params.rs +++ b/client/cli/src/params/network_params.rs @@ -20,8 +20,6 @@ use sc_network::{ multiaddr::Protocol, }; use sc_service::{ChainSpec, config::{Multiaddr, MultiaddrWithPeerId}}; -use std::iter; -use std::net::Ipv4Addr; use std::path::PathBuf; use structopt::StructOpt; @@ -48,9 +46,7 @@ pub struct NetworkParams { pub listen_addr: Vec, /// Specify p2p protocol TCP port. - /// - /// Only used if --listen-addr is not specified. - #[structopt(long = "port", value_name = "PORT")] + #[structopt(long = "port", value_name = "PORT", conflicts_with_all = &[ "listen-addr" ])] pub port: Option, /// Forbid connecting to private IPv4 addresses (as specified in @@ -106,11 +102,19 @@ impl NetworkParams { node_key: NodeKeyConfig, ) -> NetworkConfiguration { let port = self.port.unwrap_or(30333); - let mut listen_addresses = vec![iter::once(Protocol::Ip4(Ipv4Addr::new(0, 0, 0, 0))) - .chain(iter::once(Protocol::Tcp(port))) - .collect()]; - listen_addresses.extend(self.listen_addr.iter().cloned()); + let listen_addresses = if self.listen_addr.is_empty() { + vec![ + Multiaddr::empty() + .with(Protocol::Ip4([0, 0, 0, 0].into())) + .with(Protocol::Tcp(port)), + Multiaddr::empty() + .with(Protocol::Ip6([0, 0, 0, 0, 0, 0, 0, 0].into())) + .with(Protocol::Tcp(port)), + ] + } else { + self.listen_addr.clone() + }; let mut boot_nodes = chain_spec.boot_nodes().to_vec(); boot_nodes.extend(self.bootnodes.clone()); -- GitLab From 6349e1dd3aedd9d64d884a2057b081dbc759d62c Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 17 Apr 2020 09:56:17 +0200 Subject: [PATCH 254/300] Add migration for transaction-payment (#5673) --- Cargo.lock | 1 + frame/support/src/storage/migration.rs | 2 +- frame/transaction-payment/Cargo.toml | 1 + frame/transaction-payment/src/lib.rs | 48 ++++++++++++++++++++++++++ primitives/arithmetic/src/fixed64.rs | 3 -- 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4823d0495..870f4e34e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4589,6 +4589,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std", + "sp-storage", ] [[package]] diff --git a/frame/support/src/storage/migration.rs b/frame/support/src/storage/migration.rs index 8e6beefa88..264c3c644e 100644 --- a/frame/support/src/storage/migration.rs +++ b/frame/support/src/storage/migration.rs @@ -159,7 +159,7 @@ pub fn get_storage_value(module: &[u8], item: &[u8], hash: &[ frame_support::storage::unhashed::get::(&key) } -/// Get a particular value in storage by the `module`, the map's `item` name and the key `hash`. +/// Take a particular value in storage by the `module`, the map's `item` name and the key `hash`. pub fn take_storage_value(module: &[u8], item: &[u8], hash: &[u8]) -> Option { let mut key = vec![0u8; 32 + hash.len()]; key[0..16].copy_from_slice(&Twox128::hash(module)); diff --git a/frame/transaction-payment/Cargo.toml b/frame/transaction-payment/Cargo.toml index e6720e4b54..a969f30086 100644 --- a/frame/transaction-payment/Cargo.toml +++ b/frame/transaction-payment/Cargo.toml @@ -23,6 +23,7 @@ pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-dev", default-fe sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } pallet-balances = { version = "2.0.0-dev", path = "../balances" } +sp-storage = { version = "2.0.0-dev", path = "../../primitives/storage" } [features] default = ["std"] diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 8e3a9e398d..bf55885363 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -99,6 +99,20 @@ decl_module! { *fm = T::FeeMultiplierUpdate::convert(*fm) }); } + + fn on_runtime_upgrade() -> Weight { + // TODO: Remove this code after on-chain upgrade from u32 to u64 weights + use sp_runtime::Fixed64; + use frame_support::migration::take_storage_value; + if let Some(old_next_fee_multiplier) = take_storage_value::(b"TransactionPayment", b"NextFeeMultiplier", &[]) { + let raw_multiplier = old_next_fee_multiplier.into_inner() as i128; + // Fixed64 used 10^9 precision, where Fixed128 uses 10^18, so we need to add 9 zeros. + let new_raw_multiplier: i128 = raw_multiplier.saturating_mul(1_000_000_000); + let new_next_fee_multiplier: Fixed128 = Fixed128::from_parts(new_raw_multiplier); + NextFeeMultiplier::put(new_next_fee_multiplier); + } + 0 + } } } @@ -792,4 +806,38 @@ mod tests { assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); }); } + + // TODO Remove after u32 to u64 weights upgrade + #[test] + fn upgrade_to_fixed128_works() { + // TODO You can remove this from dev-dependencies after removing this test + use sp_storage::Storage; + use sp_runtime::Fixed64; + use frame_support::storage::generator::StorageValue; + use frame_support::traits::OnRuntimeUpgrade; + use core::num::NonZeroI128; + + let mut s = Storage::default(); + + let original_multiplier = Fixed64::from_rational(1, 2); + + let data = vec![ + ( + NextFeeMultiplier::storage_value_final_key().to_vec(), + original_multiplier.encode().to_vec() + ), + ]; + + s.top = data.into_iter().collect(); + + sp_io::TestExternalities::new(s).execute_with(|| { + let old_value = NextFeeMultiplier::get(); + assert!(old_value != Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())); + + // Convert Fixed64(.5) to Fixed128(.5) + TransactionPayment::on_runtime_upgrade(); + let new_value = NextFeeMultiplier::get(); + assert_eq!(new_value, Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())); + }); + } } diff --git a/primitives/arithmetic/src/fixed64.rs b/primitives/arithmetic/src/fixed64.rs index 6f7e5fe842..af4dbf34e2 100644 --- a/primitives/arithmetic/src/fixed64.rs +++ b/primitives/arithmetic/src/fixed64.rs @@ -49,9 +49,6 @@ impl Fixed64 { } /// Consume self and return the inner value. - /// - /// This should only be used for testing. - #[cfg(any(feature = "std", test))] pub fn into_inner(self) -> i64 { self.0 } /// Raw constructor. Equal to `parts / 1_000_000_000`. -- GitLab From 515990198f546952a27fbd6ce997e6012a96daef Mon Sep 17 00:00:00 2001 From: Joshy Orndorff Date: Fri, 17 Apr 2020 04:35:50 -0400 Subject: [PATCH 255/300] remove rustdocs script (#5675) --- .gitlab-ci.yml | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a98819ef2b..a7cf6f2ed8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -548,46 +548,6 @@ publish-s3-doc: - aws s3 ls s3://${BUCKET}/${PREFIX}/ --human-readable --summarize - -publish-gh-doc: - stage: publish - image: parity/tools:latest - allow_failure: true - dependencies: - - build-rust-doc-release - cache: {} - <<: *build-only - <<: *kubernetes-build - variables: - GIT_STRATEGY: none - GITHUB_API: "https://api.github.com" - script: - - test -r ./crate-docs/index.html || ( - echo "./crate-docs/index.html not present, build:rust:doc:release job not complete"; - exit 1 - ) - - test "${GITHUB_USER}" -a "${GITHUB_EMAIL}" -a "${GITHUB_TOKEN}" || ( - echo "environment variables for github insufficient"; - exit 1 - ) - - | - cat > ${HOME}/.gitconfig <&1 | sed -r "s|(${GITHUB_USER}):[a-f0-9]+@|\1:REDACTED@|g" - after_script: - - rm -vrf ${HOME}/.gitconfig - publish-draft-release: stage: publish image: parity/tools:latest -- GitLab From 86824f8e8bcb79f50762592227494a796fda7ba1 Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Fri, 17 Apr 2020 20:37:00 +1200 Subject: [PATCH 256/300] emit TipClosed event on success tip payout (#5656) * emit TipClosed event on success tip payout * test for events * bump version --- bin/node/runtime/src/lib.rs | 2 +- frame/treasury/src/lib.rs | 5 ++-- frame/treasury/src/tests.rs | 59 ++++++++++++++++++++++++++++++++++--- 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 24fc3fb2fc..ca9c1d80e0 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -127,7 +127,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 242, + spec_version: 243, impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 2a255ab2d6..af39985133 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -549,7 +549,7 @@ decl_module! { // closed. Reasons::::remove(&tip.reason); Tips::::remove(hash); - Self::payout_tip(tip); + Self::payout_tip(hash, tip); } fn on_initialize(n: T::BlockNumber) -> Weight { @@ -627,7 +627,7 @@ impl Module { /// /// Up to three balance operations. /// Plus `O(T)` (`T` is Tippers length). - fn payout_tip(tip: OpenTip, T::BlockNumber, T::Hash>) { + fn payout_tip(hash: T::Hash, tip: OpenTip, T::BlockNumber, T::Hash>) { let mut tips = tip.tips; Self::retain_active_tips(&mut tips); tips.sort_by_key(|i| i.1); @@ -647,6 +647,7 @@ impl Module { } // same as above: best-effort only. let _ = T::Currency::transfer(&treasury, &tip.who, payout, KeepAlive); + Self::deposit_event(RawEvent::TipClosed(hash, tip.who, payout)); } // Spend some money! diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index 132690d29f..8752ba746b 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -21,7 +21,7 @@ use super::*; use std::cell::RefCell; use frame_support::{ - assert_noop, assert_ok, impl_outer_origin, parameter_types, weights::Weight, + assert_noop, assert_ok, impl_outer_origin, impl_outer_event, parameter_types, weights::Weight, traits::{Contains, OnInitialize} }; use sp_core::H256; @@ -35,6 +35,21 @@ impl_outer_origin! { pub enum Origin for Test where system = frame_system {} } + +mod treasury { + // Re-export needed for `impl_outer_event!`. + pub use super::super::*; +} + +impl_outer_event! { + pub enum Event for Test { + system, + pallet_balances, + treasury, + } +} + + #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { @@ -53,7 +68,7 @@ impl frame_system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type Event = (); + type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type DbWeight = (); @@ -70,7 +85,7 @@ parameter_types! { } impl pallet_balances::Trait for Test { type Balance = u64; - type Event = (); + type Event = Event; type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; @@ -113,7 +128,7 @@ impl Trait for Test { type TipFindersFee = TipFindersFee; type TipReportDepositBase = TipReportDepositBase; type TipReportDepositPerByte = TipReportDepositPerByte; - type Event = (); + type Event = Event; type ProposalRejection = (); type ProposalBond = ProposalBond; type ProposalBondMinimum = ProposalBondMinimum; @@ -206,15 +221,41 @@ fn report_awesome_from_beneficiary_and_tip_works() { #[test] fn close_tip_works() { new_test_ext().execute_with(|| { + System::set_block_number(1); + Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_eq!(Treasury::pot(), 100); assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10)); + let h = tip_hash(); + + assert_eq!( + System::events().into_iter().map(|r| r.event) + .filter_map(|e| { + if let Event::treasury(inner) = e { Some(inner) } else { None } + }) + .last() + .unwrap(), + RawEvent::NewTip(h), + ); + assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); + assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::::StillOpen); assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); + + assert_eq!( + System::events().into_iter().map(|r| r.event) + .filter_map(|e| { + if let Event::treasury(inner) = e { Some(inner) } else { None } + }) + .last() + .unwrap(), + RawEvent::TipClosing(h), + ); + assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::::Premature); System::set_block_number(2); @@ -222,6 +263,16 @@ fn close_tip_works() { assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); assert_eq!(Balances::free_balance(3), 10); + assert_eq!( + System::events().into_iter().map(|r| r.event) + .filter_map(|e| { + if let Event::treasury(inner) = e { Some(inner) } else { None } + }) + .last() + .unwrap(), + RawEvent::TipClosed(h, 3, 10), + ); + assert_noop!(Treasury::close_tip(Origin::signed(100), h.into()), Error::::UnknownTip); }); } -- GitLab From b7b60fa35dca0fe1b76f08327e46b826e6197c89 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Fri, 17 Apr 2020 12:02:45 +0300 Subject: [PATCH 257/300] Add prometheus registry to transaction pool, with couple of initial metrics (#5657) * make new contructor * add metrics to txpool * fix review * fix doc comment * change to counters * Update client/transaction-pool/src/metrics.rs Co-Authored-By: Max Inden * Update client/transaction-pool/src/metrics.rs Co-Authored-By: Max Inden * Update client/transaction-pool/src/metrics.rs Co-Authored-By: Max Inden * Update client/transaction-pool/src/lib.rs Co-Authored-By: Max Inden * Update client/transaction-pool/src/lib.rs Co-Authored-By: Max Inden * use dedicated wrapper Co-authored-by: Max Inden --- Cargo.lock | 1 + bin/node-template/node/src/service.rs | 8 +-- bin/node/cli/src/service.rs | 8 +-- .../basic-authorship/src/basic_authorship.rs | 25 +++++-- client/basic-authorship/src/lib.rs | 2 +- client/consensus/manual-seal/src/lib.rs | 6 +- client/offchain/src/lib.rs | 1 + client/rpc/src/author/tests.rs | 1 + client/service/src/builder.rs | 3 + client/service/src/lib.rs | 1 + client/transaction-pool/Cargo.toml | 1 + client/transaction-pool/src/lib.rs | 45 ++++++++++-- client/transaction-pool/src/metrics.rs | 69 +++++++++++++++++++ client/transaction-pool/src/testing/pool.rs | 6 +- utils/frame/rpc/system/src/lib.rs | 6 +- 15 files changed, 157 insertions(+), 26 deletions(-) create mode 100644 client/transaction-pool/src/metrics.rs diff --git a/Cargo.lock b/Cargo.lock index 870f4e34e5..c51f495589 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6766,6 +6766,7 @@ dependencies = [ "sp-runtime", "sp-transaction-pool", "sp-utils", + "substrate-prometheus-endpoint", "substrate-test-runtime-client", "substrate-test-runtime-transaction-pool", "tracing", diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index 7c4a574f6b..b8e4d73db6 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -35,9 +35,9 @@ macro_rules! new_full_start { .with_select_chain(|_config, backend| { Ok(sc_client::LongestChain::new(backend.clone())) })? - .with_transaction_pool(|config, client, _fetcher| { + .with_transaction_pool(|config, client, _fetcher, prometheus_registry| { let pool_api = sc_transaction_pool::FullChainApi::new(client.clone()); - Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api))) + Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api), prometheus_registry)) })? .with_import_queue(|_config, client, mut select_chain, _transaction_pool| { let select_chain = select_chain.take() @@ -183,13 +183,13 @@ pub fn new_light(config: Configuration) .with_select_chain(|_config, backend| { Ok(LongestChain::new(backend.clone())) })? - .with_transaction_pool(|config, client, fetcher| { + .with_transaction_pool(|config, client, fetcher, prometheus_registry| { let fetcher = fetcher .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?; let pool_api = sc_transaction_pool::LightChainApi::new(client.clone(), fetcher.clone()); let pool = sc_transaction_pool::BasicPool::with_revalidation_type( - config, Arc::new(pool_api), sc_transaction_pool::RevalidationType::Light, + config, Arc::new(pool_api), prometheus_registry, sc_transaction_pool::RevalidationType::Light, ); Ok(pool) })? diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 07099d9c97..0acd553ea0 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -56,9 +56,9 @@ macro_rules! new_full_start { .with_select_chain(|_config, backend| { Ok(sc_client::LongestChain::new(backend.clone())) })? - .with_transaction_pool(|config, client, _fetcher| { + .with_transaction_pool(|config, client, _fetcher, prometheus_registry| { let pool_api = sc_transaction_pool::FullChainApi::new(client.clone()); - Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api))) + Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api), prometheus_registry)) })? .with_import_queue(|_config, client, mut select_chain, _transaction_pool| { let select_chain = select_chain.take() @@ -312,12 +312,12 @@ pub fn new_light(config: Configuration) .with_select_chain(|_config, backend| { Ok(LongestChain::new(backend.clone())) })? - .with_transaction_pool(|config, client, fetcher| { + .with_transaction_pool(|config, client, fetcher, prometheus_registry| { let fetcher = fetcher .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?; let pool_api = sc_transaction_pool::LightChainApi::new(client.clone(), fetcher.clone()); let pool = sc_transaction_pool::BasicPool::with_revalidation_type( - config, Arc::new(pool_api), sc_transaction_pool::RevalidationType::Light, + config, Arc::new(pool_api), prometheus_registry, sc_transaction_pool::RevalidationType::Light, ); Ok(pool) })? diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index 37bb34a4b6..e1e99938e3 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -360,7 +360,11 @@ mod tests { // given let client = Arc::new(substrate_test_runtime_client::new()); let txpool = Arc::new( - BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))).0 + BasicPool::new( + Default::default(), + Arc::new(FullChainApi::new(client.clone())), + None, + ).0 ); futures::executor::block_on( @@ -408,7 +412,11 @@ mod tests { fn should_not_panic_when_deadline_is_reached() { let client = Arc::new(substrate_test_runtime_client::new()); let txpool = Arc::new( - BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))).0 + BasicPool::new( + Default::default(), + Arc::new(FullChainApi::new(client.clone())), + None, + ).0 ); let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone()); @@ -440,8 +448,13 @@ mod tests { .build_with_backend(); let client = Arc::new(client); let txpool = Arc::new( - BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))).0 + BasicPool::new( + Default::default(), + Arc::new(FullChainApi::new(client.clone())), + None, + ).0 ); + let genesis_hash = client.info().best_hash; let block_id = BlockId::Hash(genesis_hash); @@ -493,7 +506,11 @@ mod tests { // given let mut client = Arc::new(substrate_test_runtime_client::new()); let txpool = Arc::new( - BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))).0 + BasicPool::new( + Default::default(), + Arc::new(FullChainApi::new(client.clone())), + None, + ).0 ); futures::executor::block_on( diff --git a/client/basic-authorship/src/lib.rs b/client/basic-authorship/src/lib.rs index 5ec0bc6f9a..5eb60f1cd5 100644 --- a/client/basic-authorship/src/lib.rs +++ b/client/basic-authorship/src/lib.rs @@ -26,7 +26,7 @@ //! # use substrate_test_runtime_client::{self, runtime::{Extrinsic, Transfer}, AccountKeyring}; //! # use sc_transaction_pool::{BasicPool, FullChainApi}; //! # let client = Arc::new(substrate_test_runtime_client::new()); -//! # let txpool = Arc::new(BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))).0); +//! # let txpool = Arc::new(BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone())), None).0); //! // The first step is to create a `ProposerFactory`. //! let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone()); //! diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs index 8294ae049f..687d072aaa 100644 --- a/client/consensus/manual-seal/src/lib.rs +++ b/client/consensus/manual-seal/src/lib.rs @@ -217,7 +217,7 @@ mod tests { let (client, select_chain) = builder.build_with_longest_chain(); let client = Arc::new(client); let inherent_data_providers = InherentDataProviders::new(); - let pool = Arc::new(BasicPool::new(Options::default(), api()).0); + let pool = Arc::new(BasicPool::new(Options::default(), api(), None).0); let env = ProposerFactory::new( client.clone(), pool.clone() @@ -281,7 +281,7 @@ mod tests { let (client, select_chain) = builder.build_with_longest_chain(); let client = Arc::new(client); let inherent_data_providers = InherentDataProviders::new(); - let pool = Arc::new(BasicPool::new(Options::default(), api()).0); + let pool = Arc::new(BasicPool::new(Options::default(), api(), None).0); let env = ProposerFactory::new( client.clone(), pool.clone() @@ -349,7 +349,7 @@ mod tests { let client = Arc::new(client); let inherent_data_providers = InherentDataProviders::new(); let pool_api = api(); - let pool = Arc::new(BasicPool::new(Options::default(), pool_api.clone()).0); + let pool = Arc::new(BasicPool::new(Options::default(), pool_api.clone(), None).0); let env = ProposerFactory::new( client.clone(), pool.clone(), diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index 94850e3fd3..332e9f779a 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -206,6 +206,7 @@ mod tests { let pool = Arc::new(TestPool(BasicPool::new( Default::default(), Arc::new(FullChainApi::new(client.clone())), + None, ).0)); client.execution_extensions() .register_transaction_pool(Arc::downgrade(&pool.clone()) as _); diff --git a/client/rpc/src/author/tests.rs b/client/rpc/src/author/tests.rs index 8b956c23a5..445888c523 100644 --- a/client/rpc/src/author/tests.rs +++ b/client/rpc/src/author/tests.rs @@ -65,6 +65,7 @@ impl Default for TestSetup { let pool = Arc::new(BasicPool::new( Default::default(), Arc::new(FullChainApi::new(client.clone())), + None, ).0); TestSetup { runtime: runtime::Runtime::new().expect("Failed to create runtime in test setup"), diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 4f370c1118..90e644481f 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -53,6 +53,7 @@ use wasm_timer::SystemTime; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; use sp_transaction_pool::{MaintainedTransactionPool, ChainEvent}; use sp_blockchain; +use prometheus_endpoint::Registry as PrometheusRegistry; pub type BackgroundTask = Pin + Send>>; @@ -585,6 +586,7 @@ impl sc_transaction_pool::txpool::Options, Arc, Option, + Option<&PrometheusRegistry>, ) -> Result<(UExPool, Option), Error> ) -> Result, Error> @@ -593,6 +595,7 @@ impl self.config.transaction_pool.clone(), self.client.clone(), self.fetcher.clone(), + self.config.prometheus_config.as_ref().map(|config| &config.registry), )?; if let Some(background_task) = background_task{ diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index f416d363de..97481fcc25 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -696,6 +696,7 @@ mod tests { let pool = Arc::new(BasicPool::new( Default::default(), Arc::new(FullChainApi::new(client.clone())), + None, ).0); let source = sp_runtime::transaction_validity::TransactionSource::External; let best = longest_chain.best_chain().unwrap(); diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 2a757652f9..c96e4c0332 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -20,6 +20,7 @@ intervalier = "0.4.0" log = "0.4.8" parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } parking_lot = "0.10.0" +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-dev"} sc-client-api = { version = "2.0.0-dev", path = "../api" } sc-transaction-graph = { version = "2.0.0-dev", path = "./graph" } sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index c50d9dbbb4..e095191c57 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -21,8 +21,10 @@ #![warn(unused_extern_crates)] mod api; -pub mod error; mod revalidation; +mod metrics; + +pub mod error; #[cfg(any(feature = "test-helpers", test))] pub mod testing; @@ -45,6 +47,9 @@ use sp_transaction_pool::{ }; use wasm_timer::Instant; +use prometheus_endpoint::Registry as PrometheusRegistry; +use crate::metrics::MetricsLink as PrometheusMetrics; + type BoxedReadyIterator = Box>> + Send>; type ReadyIteratorFor = BoxedReadyIterator, sc_transaction_graph::ExtrinsicFor>; @@ -62,6 +67,7 @@ pub struct BasicPool revalidation_strategy: Arc>>>, revalidation_queue: Arc>, ready_poll: Arc, Block>>>, + metrics: PrometheusMetrics, } struct ReadyPoll { @@ -147,8 +153,9 @@ impl BasicPool pub fn new( options: sc_transaction_graph::Options, pool_api: Arc, + prometheus: Option<&PrometheusRegistry>, ) -> (Self, Option + Send>>>) { - Self::with_revalidation_type(options, pool_api, RevalidationType::Full) + Self::with_revalidation_type(options, pool_api, prometheus, RevalidationType::Full) } /// Create new basic transaction pool with provided api, for tests. @@ -166,6 +173,7 @@ impl BasicPool revalidation_queue: Arc::new(revalidation_queue), revalidation_strategy: Arc::new(Mutex::new(RevalidationStrategy::Always)), ready_poll: Default::default(), + metrics: Default::default(), }, background_task, notifier, @@ -177,6 +185,7 @@ impl BasicPool pub fn with_revalidation_type( options: sc_transaction_graph::Options, pool_api: Arc, + prometheus: Option<&PrometheusRegistry>, revalidation_type: RevalidationType, ) -> (Self, Option + Send>>>) { let pool = Arc::new(sc_transaction_graph::Pool::new(options, pool_api.clone())); @@ -187,6 +196,7 @@ impl BasicPool (queue, Some(background)) }, }; + ( BasicPool { api: pool_api, @@ -199,6 +209,7 @@ impl BasicPool } )), ready_poll: Default::default(), + metrics: PrometheusMetrics::new(prometheus), }, background_task, ) @@ -228,8 +239,15 @@ impl TransactionPool for BasicPool ) -> PoolFuture, Self::Error>>, Self::Error> { let pool = self.pool.clone(); let at = *at; + + self.metrics.report(|metrics| metrics.validations_scheduled.inc_by(xts.len() as u64)); + + let metrics = self.metrics.clone(); async move { - pool.submit_at(&at, source, xts, false).await + let tx_count = xts.len(); + let res = pool.submit_at(&at, source, xts, false).await; + metrics.report(|metrics| metrics.validations_finished.inc_by(tx_count as u64)); + res }.boxed() } @@ -241,8 +259,16 @@ impl TransactionPool for BasicPool ) -> PoolFuture, Self::Error> { let pool = self.pool.clone(); let at = *at; + + self.metrics.report(|metrics| metrics.validations_scheduled.inc()); + + let metrics = self.metrics.clone(); async move { - pool.submit_one(&at, source, xt).await + let res = pool.submit_one(&at, source, xt).await; + + metrics.report(|metrics| metrics.validations_finished.inc()); + res + }.boxed() } @@ -255,10 +281,17 @@ impl TransactionPool for BasicPool let at = *at; let pool = self.pool.clone(); + self.metrics.report(|metrics| metrics.validations_scheduled.inc()); + + let metrics = self.metrics.clone(); async move { - pool.submit_and_watch(&at, source, xt) + let result = pool.submit_and_watch(&at, source, xt) .map(|result| result.map(|watcher| Box::new(watcher.into_stream()) as _)) - .await + .await; + + metrics.report(|metrics| metrics.validations_finished.inc()); + + result }.boxed() } diff --git a/client/transaction-pool/src/metrics.rs b/client/transaction-pool/src/metrics.rs new file mode 100644 index 0000000000..78e49b3ca5 --- /dev/null +++ b/client/transaction-pool/src/metrics.rs @@ -0,0 +1,69 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Transaction pool Prometheus metrics. + +use std::sync::Arc; + +use prometheus_endpoint::{register, Counter, PrometheusError, Registry, U64}; + +#[derive(Clone, Default)] +pub struct MetricsLink(Arc>); + +impl MetricsLink { + pub fn new(registry: Option<&Registry>) -> Self { + Self(Arc::new( + registry.and_then(|registry| + Metrics::register(registry) + .map_err(|err| { log::warn!("Failed to register prometheus metrics: {}", err); }) + .ok() + ) + )) + } + + pub fn report(&self, do_this: impl FnOnce(&Metrics)) { + if let Some(metrics) = self.0.as_ref() { + do_this(metrics); + } + } +} + +/// Transaction pool Prometheus metrics. +pub struct Metrics { + pub validations_scheduled: Counter, + pub validations_finished: Counter, +} + +impl Metrics { + pub fn register(registry: &Registry) -> Result { + Ok(Self { + validations_scheduled: register( + Counter::new( + "sub_txpool_validations_scheduled", + "Total number of transactions scheduled for validation", + )?, + registry, + )?, + validations_finished: register( + Counter::new( + "sub_txpool_validations_finished", + "Total number of transactions that finished validation", + )?, + registry, + )?, + }) + } +} diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index f2815db1c3..45fb6f42c3 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -415,7 +415,7 @@ fn finalization() { let xt = uxt(Alice, 209); let api = TestApi::with_alice_nonce(209); api.push_block(1, vec![]); - let (pool, _background) = BasicPool::new(Default::default(), api.into()); + let (pool, _background, _) = BasicPool::new_test(api.into()); let watcher = block_on( pool.submit_and_watch(&BlockId::number(1), SOURCE, xt.clone()) ).expect("1. Imported"); @@ -446,7 +446,7 @@ fn fork_aware_finalization() { // starting block A1 (last finalized.) api.push_block(1, vec![]); - let (pool, _background) = BasicPool::new(Default::default(), api.into()); + let (pool, _background, _) = BasicPool::new_test(api.into()); let mut canon_watchers = vec![]; let from_alice = uxt(Alice, 1); @@ -677,7 +677,7 @@ fn should_not_accept_old_signatures() { let client = Arc::new(substrate_test_runtime_client::new()); let pool = Arc::new( - BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client))).0 + BasicPool::new_test(Arc::new(FullChainApi::new(client))).0 ); let transfer = Transfer { diff --git a/utils/frame/rpc/system/src/lib.rs b/utils/frame/rpc/system/src/lib.rs index c73ddfe93e..4838e8e8f4 100644 --- a/utils/frame/rpc/system/src/lib.rs +++ b/utils/frame/rpc/system/src/lib.rs @@ -236,7 +236,11 @@ mod tests { let _ = env_logger::try_init(); let client = Arc::new(substrate_test_runtime_client::new()); let pool = Arc::new( - BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))).0 + BasicPool::new( + Default::default(), + Arc::new(FullChainApi::new(client.clone())), + None, + ).0 ); let source = sp_runtime::transaction_validity::TransactionSource::External; -- GitLab From 71852f439bbf0b876b29b33da276973b1b97ffa5 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Fri, 17 Apr 2020 12:10:31 +0200 Subject: [PATCH 258/300] Transaction versioning in the RuntimeVersion (#5582) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add transaction_version * Semantic versioning for runtimes * Move new field to bottom * Versioning * Runtime versioning stuff. * Fix test * Adds tests and fixes bugs * Bump runtime Co-authored-by: Bastian Köcher --- Cargo.lock | 1 + bin/node-template/runtime/src/lib.rs | 1 + bin/node/runtime/src/lib.rs | 1 + client/executor/Cargo.toml | 1 + client/executor/src/wasm_runtime.rs | 73 +++++++++++++++++++++++-- client/rpc/src/state/tests.rs | 5 +- frame/system/src/lib.rs | 1 + primitives/api/src/lib.rs | 45 ++++++++++++++- primitives/core/src/hashing.rs | 12 ++++ primitives/sr-api/proc-macro/src/lib.rs | 1 + primitives/version/src/lib.rs | 18 +++++- test-utils/runtime/src/lib.rs | 1 + 12 files changed, 149 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c51f495589..c0cb38679a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6218,6 +6218,7 @@ dependencies = [ "sc-executor-wasmi", "sc-executor-wasmtime", "sc-runtime-test", + "sp-api", "sp-core", "sp-externalities", "sp-io", diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 6238ffda1a..863f263077 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -98,6 +98,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_version: 1, impl_version: 1, apis: RUNTIME_API_VERSIONS, + transaction_version: 1, }; pub const MILLISECS_PER_BLOCK: u64 = 6000; diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index ca9c1d80e0..337242f884 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -130,6 +130,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_version: 243, impl_version: 0, apis: RUNTIME_API_VERSIONS, + transaction_version: 1, }; /// Native version. diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index 26d9828d57..ef1b24ea71 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -24,6 +24,7 @@ sp-panic-handler = { version = "2.0.0-dev", path = "../../primitives/panic-handl wasmi = "0.6.2" parity-wasm = "0.41.0" lazy_static = "1.4.0" +sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } sp-wasm-interface = { version = "2.0.0-dev", path = "../../primitives/wasm-interface" } sp-runtime-interface = { version = "2.0.0-dev", path = "../../primitives/runtime-interface" } sp-externalities = { version = "0.8.0-dev", path = "../../primitives/externalities" } diff --git a/client/executor/src/wasm_runtime.rs b/client/executor/src/wasm_runtime.rs index 7a369cc470..87a08f714d 100644 --- a/client/executor/src/wasm_runtime.rs +++ b/client/executor/src/wasm_runtime.rs @@ -287,6 +287,25 @@ pub fn create_wasm_runtime_with_code( } } +fn decode_version(version: &[u8]) -> Result { + let v: RuntimeVersion = sp_api::OldRuntimeVersion::decode(&mut &version[..]) + .map_err(|_| + WasmError::Instantiation( + "failed to decode \"Core_version\" result using old runtime version".into(), + ) + )?.into(); + + let core_api_id = sp_core::hashing::blake2_64(b"Core"); + if v.has_api_with(&core_api_id, |v| v >= 3) { + sp_api::RuntimeVersion::decode(&mut &version[..]) + .map_err(|_| + WasmError::Instantiation("failed to decode \"Core_version\" result".into()) + ) + } else { + Ok(v) + } +} + fn create_versioned_wasm_runtime( code: &[u8], code_hash: Vec, @@ -321,10 +340,7 @@ fn create_versioned_wasm_runtime( ).map_err(|_| WasmError::Instantiation("panic in call to get runtime version".into()))? }; let version = match version_result { - Ok(version) => Some(RuntimeVersion::decode(&mut version.as_slice()) - .map_err(|_| - WasmError::Instantiation("failed to decode \"Core_version\" result".into()) - )?), + Ok(version) => Some(decode_version(&version)?), Err(_) => None, }; #[cfg(not(target_os = "unknown"))] @@ -350,7 +366,11 @@ fn create_versioned_wasm_runtime( #[cfg(test)] mod tests { + use super::*; use sp_wasm_interface::HostFunctions; + use sp_api::{Core, RuntimeApiInfo}; + use substrate_test_runtime::Block; + use codec::Encode; #[test] fn host_functions_are_equal() { @@ -359,4 +379,49 @@ mod tests { let equal = &host_functions[..] == &host_functions[..]; assert!(equal, "Host functions are not equal"); } + + #[test] + fn old_runtime_version_decodes() { + let old_runtime_version = sp_api::OldRuntimeVersion { + spec_name: "test".into(), + impl_name: "test".into(), + authoring_version: 1, + spec_version: 1, + impl_version: 1, + apis: sp_api::create_apis_vec!([(Core::::ID, 1)]), + }; + + let version = decode_version(&old_runtime_version.encode()).unwrap(); + assert_eq!(1, version.transaction_version); + } + + #[test] + fn old_runtime_version_decodes_fails_with_version_3() { + let old_runtime_version = sp_api::OldRuntimeVersion { + spec_name: "test".into(), + impl_name: "test".into(), + authoring_version: 1, + spec_version: 1, + impl_version: 1, + apis: sp_api::create_apis_vec!([(Core::::ID, 3)]), + }; + + decode_version(&old_runtime_version.encode()).unwrap_err(); + } + + #[test] + fn new_runtime_version_decodes() { + let old_runtime_version = sp_api::RuntimeVersion { + spec_name: "test".into(), + impl_name: "test".into(), + authoring_version: 1, + spec_version: 1, + impl_version: 1, + apis: sp_api::create_apis_vec!([(Core::::ID, 3)]), + transaction_version: 3, + }; + + let version = decode_version(&old_runtime_version.encode()).unwrap(); + assert_eq!(3, version.transaction_version); + } } diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index 4a9b701959..0f2358a3ed 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -437,10 +437,11 @@ fn should_return_runtime_version() { let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); let result = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ - \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",2],\ + \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",3],\ [\"0x37e397fc7c91f5e4\",1],[\"0xd2bc9897eed08f15\",2],[\"0x40fe3ad401f8959a\",4],\ [\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",1],\ - [\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],[\"0xbc9d89904f5b923f\",1]]}"; + [\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],[\"0xbc9d89904f5b923f\",1]],\ + \"transactionVersion\":1}"; let runtime_version = api.runtime_version(None.into()).wait().unwrap(); let serialized = serde_json::to_string(&runtime_version).unwrap(); diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 31b862f3b2..50f2b089f2 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -1617,6 +1617,7 @@ mod tests { spec_version: 1, impl_version: 1, apis: sp_version::create_apis_vec!([]), + transaction_version: 1, }; } diff --git a/primitives/api/src/lib.rs b/primitives/api/src/lib.rs index 80a36a904c..a3fc15ba7e 100644 --- a/primitives/api/src/lib.rs +++ b/primitives/api/src/lib.rs @@ -53,7 +53,7 @@ pub use sp_runtime::{ Block as BlockT, GetNodeBlockType, GetRuntimeBlockType, HashFor, NumberFor, Header as HeaderT, Hash as HashT, }, - generic::BlockId, transaction_validity::TransactionValidity, + generic::BlockId, transaction_validity::TransactionValidity, RuntimeString, }; #[doc(hidden)] pub use sp_core::{offchain, ExecutionContext}; @@ -224,6 +224,7 @@ pub use sp_api_proc_macro::decl_runtime_apis; /// impl_version: 0, /// // Here we are exposing the runtime api versions. /// apis: RUNTIME_API_VERSIONS, +/// transaction_version: 1, /// }; /// /// # fn main() {} @@ -520,13 +521,53 @@ pub trait RuntimeApiInfo { #[cfg(feature = "std")] pub type ApiErrorFor = <>::Api as ApiErrorExt>::Error; +#[derive(codec::Encode, codec::Decode)] +pub struct OldRuntimeVersion { + pub spec_name: RuntimeString, + pub impl_name: RuntimeString, + pub authoring_version: u32, + pub spec_version: u32, + pub impl_version: u32, + pub apis: ApisVec, +} + +impl From for RuntimeVersion { + fn from(x: OldRuntimeVersion) -> Self { + Self { + spec_name: x.spec_name, + impl_name: x.impl_name, + authoring_version: x.authoring_version, + spec_version: x.spec_version, + impl_version: x.impl_version, + apis: x.apis, + transaction_version: 1, + } + } +} + +impl From for OldRuntimeVersion { + fn from(x: RuntimeVersion) -> Self { + Self { + spec_name: x.spec_name, + impl_name: x.impl_name, + authoring_version: x.authoring_version, + spec_version: x.spec_version, + impl_version: x.impl_version, + apis: x.apis, + } + } +} + decl_runtime_apis! { /// The `Core` runtime api that every Substrate runtime needs to implement. #[core_trait] - #[api_version(2)] + #[api_version(3)] pub trait Core { /// Returns the version of the runtime. fn version() -> RuntimeVersion; + /// Returns the version of the runtime. + #[changed_in(3)] + fn version() -> OldRuntimeVersion; /// Execute the given block. #[skip_initialize_block] fn execute_block(block: Block); diff --git a/primitives/core/src/hashing.rs b/primitives/core/src/hashing.rs index 87f6469b57..d958da6c32 100644 --- a/primitives/core/src/hashing.rs +++ b/primitives/core/src/hashing.rs @@ -57,6 +57,18 @@ pub fn blake2_128(data: &[u8]) -> [u8; 16] { r } +/// Do a Blake2 64-bit hash and place result in `dest`. +pub fn blake2_64_into(data: &[u8], dest: &mut [u8; 8]) { + dest.copy_from_slice(blake2_rfc::blake2b::blake2b(8, &[], data).as_bytes()); +} + +/// Do a Blake2 64-bit hash and return result. +pub fn blake2_64(data: &[u8]) -> [u8; 8] { + let mut r = [0; 8]; + blake2_64_into(data, &mut r); + r +} + /// Do a XX 64-bit hash and place result in `dest`. pub fn twox_64_into(data: &[u8], dest: &mut [u8; 8]) { use ::core::hash::Hasher; diff --git a/primitives/sr-api/proc-macro/src/lib.rs b/primitives/sr-api/proc-macro/src/lib.rs index adb3b9636d..0c506a1455 100644 --- a/primitives/sr-api/proc-macro/src/lib.rs +++ b/primitives/sr-api/proc-macro/src/lib.rs @@ -103,6 +103,7 @@ mod utils; /// impl_version: 0, /// // Here we are exposing the runtime api versions. /// apis: RUNTIME_API_VERSIONS, +/// transaction_version: 1, /// }; /// /// # fn main() {} diff --git a/primitives/version/src/lib.rs b/primitives/version/src/lib.rs index 0534f87490..613b23156a 100644 --- a/primitives/version/src/lib.rs +++ b/primitives/version/src/lib.rs @@ -93,17 +93,29 @@ pub struct RuntimeVersion { ) )] pub apis: ApisVec, + + /// All existing dispatches are fully compatible when this number doesn't change. If this + /// number changes, then `spec_version` must change, also. + /// + /// This number must change when an existing dispatchable (module ID, dispatch ID) is changed, + /// either through an alteration in its user-level semantics, a parameter added/removed/changed, + /// a dispatchable being removed, a module being removed, or a dispatchable/module changing its + /// index. + /// + /// It need *not* change when a new module is added or when a dispatchable is added. + pub transaction_version: u32, } #[cfg(feature = "std")] impl fmt::Display for RuntimeVersion { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}-{}:{}({}-{})", + write!(f, "{}-{} ({}-{}.tx{}.au{})", self.spec_name, self.spec_version, - self.authoring_version, self.impl_name, - self.impl_version + self.impl_version, + self.transaction_version, + self.authoring_version, ) } } diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index a853912893..65fbf300bb 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -68,6 +68,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_version: 2, impl_version: 2, apis: RUNTIME_API_VERSIONS, + transaction_version: 1, }; fn version() -> RuntimeVersion { -- GitLab From d39981d230a0b524211bb87ed46b45b4582e3b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Fri, 17 Apr 2020 12:20:04 +0200 Subject: [PATCH 259/300] Fix weight refund to use proper adjustment factor (#5640) --- frame/transaction-payment/src/lib.rs | 101 ++++++++++++++++++--------- 1 file changed, 69 insertions(+), 32 deletions(-) diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index bf55885363..75809e0ed6 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -141,27 +141,11 @@ impl Module where // a very very little potential gain in the future. let dispatch_info = ::get_dispatch_info(&unchecked_extrinsic); - let partial_fee = - >::compute_fee(len, &dispatch_info, 0u32.into()); + let partial_fee = Self::compute_fee(len, &dispatch_info, 0u32.into()); let DispatchInfo { weight, class, .. } = dispatch_info; RuntimeDispatchInfo { weight, class, partial_fee } } -} - -/// Require the transactor pay for themselves and maybe include a tip to gain additional priority -/// in the queue. -#[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct ChargeTransactionPayment(#[codec(compact)] BalanceOf); - -impl ChargeTransactionPayment where - T::Call: Dispatchable, - BalanceOf: Send + Sync, -{ - /// utility constructor. Used only in client/factory code. - pub fn from(fee: BalanceOf) -> Self { - Self(fee) - } /// Compute the final fee value for a particular transaction. /// @@ -186,12 +170,11 @@ impl ChargeTransactionPayment where let len = >::from(len); let per_byte = T::TransactionByteFee::get(); let len_fee = per_byte.saturating_mul(len); - let weight_fee = Self::compute_weight_fee(info.weight); + let unadjusted_weight_fee = Self::weight_to_fee(info.weight); // the adjustable part of the fee - let adjustable_fee = len_fee.saturating_add(weight_fee); + let adjustable_fee = len_fee.saturating_add(unadjusted_weight_fee); let targeted_fee_adjustment = NextFeeMultiplier::get(); - // adjusted_fee = adjustable_fee + (adjustable_fee * targeted_fee_adjustment) let adjusted_fee = targeted_fee_adjustment.saturated_multiply_accumulate(adjustable_fee.saturated_into()); let base_fee = T::TransactionBaseFee::get(); @@ -201,12 +184,39 @@ impl ChargeTransactionPayment where } } - fn compute_weight_fee(weight: Weight) -> BalanceOf { + /// Compute the fee for the specified weight. + /// + /// This fee is already adjusted by the per block fee adjustment factor and is therefore + /// the share that the weight contributes to the overall fee of a transaction. + pub fn weight_to_fee_with_adjustment(weight: Weight) -> BalanceOf where + BalanceOf: From + { + NextFeeMultiplier::get().saturated_multiply_accumulate( + Self::weight_to_fee(weight) + ) + } + + fn weight_to_fee(weight: Weight) -> BalanceOf { // cap the weight to the maximum defined in runtime, otherwise it will be the // `Bounded` maximum of its data type, which is not desired. let capped_weight = weight.min(::MaximumBlockWeight::get()); T::WeightToFee::convert(capped_weight) } +} + +/// Require the transactor pay for themselves and maybe include a tip to gain additional priority +/// in the queue. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct ChargeTransactionPayment(#[codec(compact)] BalanceOf); + +impl ChargeTransactionPayment where + T::Call: Dispatchable, + BalanceOf: Send + Sync, +{ + /// utility constructor. Used only in client/factory code. + pub fn from(fee: BalanceOf) -> Self { + Self(fee) + } fn withdraw_fee( &self, @@ -215,7 +225,7 @@ impl ChargeTransactionPayment where len: usize, ) -> Result<(BalanceOf, Option>), TransactionValidityError> { let tip = self.0; - let fee = Self::compute_fee(len as u32, info, tip); + let fee = Module::::compute_fee(len as u32, info, tip); // Only mess with balances if fee is not zero. if fee.is_zero() { @@ -250,7 +260,7 @@ impl sp_std::fmt::Debug for ChargeTransactionPayment } impl SignedExtension for ChargeTransactionPayment where - BalanceOf: Send + Sync, + BalanceOf: Send + Sync + From, T::Call: Dispatchable, { const IDENTIFIER: &'static str = "ChargeTransactionPayment"; @@ -296,7 +306,7 @@ impl SignedExtension for ChargeTransactionPayment whe ) -> Result<(), TransactionValidityError> { let (tip, who, imbalance) = pre; if let Some(payed) = imbalance { - let refund = Self::compute_weight_fee(post_info.calc_unspent(info)); + let refund = Module::::weight_to_fee_with_adjustment(post_info.calc_unspent(info)); let actual_payment = match T::Currency::deposit_into_existing(&who, refund) { Ok(refund_imbalance) => { // The refund cannot be larger than the up front payed max weight. @@ -541,6 +551,33 @@ mod tests { }); } + #[test] + fn signed_extension_transaction_payment_multiplied_refund_works() { + ExtBuilder::default() + .balance_factor(10) + .base_fee(5) + .build() + .execute_with(|| + { + let len = 10; + NextFeeMultiplier::put(Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())); + + let pre = ChargeTransactionPayment::::from(5 /* tipped */) + .pre_dispatch(&2, CALL, &info_from_weight(100), len) + .unwrap(); + // 5 base fee, 3/2 * 10 byte fee, 3/2 * 100 weight fee, 5 tip + assert_eq!(Balances::free_balance(2), 200 - 5 - 15 - 150 - 5); + + assert!( + ChargeTransactionPayment:: + ::post_dispatch(pre, &info_from_weight(100), &post_info_from_weight(50), len, &Ok(())) + .is_ok() + ); + // 75 (3/2 of the returned 50 units of weight ) is refunded + assert_eq!(Balances::free_balance(2), 200 - 5 - 15 - 75 - 5); + }); + } + #[test] fn signed_extension_transaction_payment_is_bounded() { ExtBuilder::default() @@ -676,25 +713,25 @@ mod tests { class: DispatchClass::Operational, pays_fee: false, }; - assert_eq!(ChargeTransactionPayment::::compute_fee(0, &dispatch_info, 10), 10); + assert_eq!(Module::::compute_fee(0, &dispatch_info, 10), 10); // No tip, only base fee works let dispatch_info = DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: true, }; - assert_eq!(ChargeTransactionPayment::::compute_fee(0, &dispatch_info, 0), 100); + assert_eq!(Module::::compute_fee(0, &dispatch_info, 0), 100); // Tip + base fee works - assert_eq!(ChargeTransactionPayment::::compute_fee(0, &dispatch_info, 69), 169); + assert_eq!(Module::::compute_fee(0, &dispatch_info, 69), 169); // Len (byte fee) + base fee works - assert_eq!(ChargeTransactionPayment::::compute_fee(42, &dispatch_info, 0), 520); + assert_eq!(Module::::compute_fee(42, &dispatch_info, 0), 520); // Weight fee + base fee works let dispatch_info = DispatchInfo { weight: 1000, class: DispatchClass::Operational, pays_fee: true, }; - assert_eq!(ChargeTransactionPayment::::compute_fee(0, &dispatch_info, 0), 1100); + assert_eq!(Module::::compute_fee(0, &dispatch_info, 0), 1100); }); } @@ -715,7 +752,7 @@ mod tests { class: DispatchClass::Operational, pays_fee: true, }; - assert_eq!(ChargeTransactionPayment::::compute_fee(0, &dispatch_info, 0), 100); + assert_eq!(Module::::compute_fee(0, &dispatch_info, 0), 100); // Everything works together :) let dispatch_info = DispatchInfo { @@ -727,7 +764,7 @@ mod tests { // adjustable fee = (123 * 1) + (456 * 10) = 4683 // adjusted fee = (4683 * .5) + 4683 = 7024.5 -> 7024 // final fee = 100 + 7024 + 789 tip = 7913 - assert_eq!(ChargeTransactionPayment::::compute_fee(456, &dispatch_info, 789), 7913); + assert_eq!(Module::::compute_fee(456, &dispatch_info, 789), 7913); }); } @@ -747,7 +784,7 @@ mod tests { pays_fee: true, }; assert_eq!( - ChargeTransactionPayment::::compute_fee( + Module::::compute_fee( ::max_value(), &dispatch_info, ::max_value() -- GitLab From 69ed11886456732ae8ec83bf3e3ff1aeff854cac Mon Sep 17 00:00:00 2001 From: cheme Date: Fri, 17 Apr 2020 12:31:33 +0200 Subject: [PATCH 260/300] fix renamed field related error --- primitives/state-machine/src/basic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/state-machine/src/basic.rs b/primitives/state-machine/src/basic.rs index 8d3ecb1b19..7f26085958 100644 --- a/primitives/state-machine/src/basic.rs +++ b/primitives/state-machine/src/basic.rs @@ -83,7 +83,7 @@ impl BasicExternalities { let mut ext = Self { inner: Storage { top: std::mem::replace(&mut storage.top, Default::default()), - children_default: std::mem::replace(&mut storage.children, Default::default()), + children_default: std::mem::replace(&mut storage.children_default, Default::default()), }, extensions: Default::default(), }; -- GitLab From 2d8f3b42c4425bfebd18b0775c0f7a6dbd83df06 Mon Sep 17 00:00:00 2001 From: Ashley Date: Fri, 17 Apr 2020 14:48:45 +0200 Subject: [PATCH 261/300] Make network_config_path an Option (#5661) * Make network_config_path an Option * Fix network tests * Use None as the network config path * Fix cli * Don't make PathBuf an Option in a cli context --- client/cli/src/commands/mod.rs | 2 +- client/cli/src/config.rs | 8 ++++---- client/cli/src/params/network_params.rs | 4 ++-- client/network/src/config.rs | 10 +++++----- client/network/src/service.rs | 4 +++- client/network/test/src/lib.rs | 4 ++-- client/service/test/src/lib.rs | 5 ++--- utils/browser/src/lib.rs | 2 +- 8 files changed, 20 insertions(+), 19 deletions(-) diff --git a/client/cli/src/commands/mod.rs b/client/cli/src/commands/mod.rs index 68c22c4868..ae2fe55467 100644 --- a/client/cli/src/commands/mod.rs +++ b/client/cli/src/commands/mod.rs @@ -173,7 +173,7 @@ macro_rules! substrate_cli_subcommands { &self, chain_spec: &::std::boxed::Box, is_dev: bool, - net_config_dir: &::std::path::PathBuf, + net_config_dir: ::std::path::PathBuf, client_id: &str, node_name: &str, node_key: ::sc_service::config::NodeKeyConfig, diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index 8c8490ff1a..04a6647402 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -110,7 +110,7 @@ pub trait CliConfiguration: Sized { &self, chain_spec: &Box, is_dev: bool, - net_config_dir: &PathBuf, + net_config_dir: PathBuf, client_id: &str, node_name: &str, node_key: NodeKeyConfig, @@ -119,7 +119,7 @@ pub trait CliConfiguration: Sized { network_params.network_config( chain_spec, is_dev, - net_config_dir, + Some(net_config_dir), client_id, node_name, node_key, @@ -129,7 +129,7 @@ pub trait CliConfiguration: Sized { node_name, client_id, node_key, - net_config_dir, + Some(net_config_dir), ) }) } @@ -405,7 +405,7 @@ pub trait CliConfiguration: Sized { network: self.network_config( &chain_spec, is_dev, - &net_config_dir, + net_config_dir, client_id.as_str(), self.node_name()?.as_str(), node_key, diff --git a/client/cli/src/params/network_params.rs b/client/cli/src/params/network_params.rs index 6d9ffd6a6e..45500a5e06 100644 --- a/client/cli/src/params/network_params.rs +++ b/client/cli/src/params/network_params.rs @@ -96,7 +96,7 @@ impl NetworkParams { &self, chain_spec: &Box, is_dev: bool, - net_config_path: &PathBuf, + net_config_path: Option, client_id: &str, node_name: &str, node_key: NodeKeyConfig, @@ -121,7 +121,7 @@ impl NetworkParams { NetworkConfiguration { boot_nodes, - net_config_path: net_config_path.clone(), + net_config_path, reserved_nodes: self.reserved_nodes.clone(), non_reserved_mode: if self.reserved_only { NonReservedPeerMode::Deny diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 01acbe6875..4914ad680a 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -315,7 +315,7 @@ impl From for ParseErr { #[derive(Clone, Debug)] pub struct NetworkConfiguration { /// Directory path to store network-specific configuration. None means nothing will be saved. - pub net_config_path: PathBuf, + pub net_config_path: Option, /// Multiaddresses to listen for incoming connections. pub listen_addresses: Vec, /// Multiaddresses to advertise. Detected automatically if empty. @@ -351,10 +351,10 @@ impl NetworkConfiguration { node_name: SN, client_version: SV, node_key: NodeKeyConfig, - net_config_path: &PathBuf, + net_config_path: Option, ) -> Self { NetworkConfiguration { - net_config_path: net_config_path.clone(), + net_config_path, listen_addresses: Vec::new(), public_addresses: Vec::new(), boot_nodes: Vec::new(), @@ -384,7 +384,7 @@ impl NetworkConfiguration { "test-node", "test-client", Default::default(), - &std::env::current_dir().expect("current directory must exist"), + None, ); config.listen_addresses = vec![ @@ -402,7 +402,7 @@ impl NetworkConfiguration { "test-node", "test-client", Default::default(), - &std::env::current_dir().expect("current directory must exist"), + None, ); config.listen_addresses = vec![ diff --git a/client/network/src/service.rs b/client/network/src/service.rs index da488d2a87..091c75d635 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -184,7 +184,9 @@ impl NetworkWorker { pub fn new(params: Params) -> Result, Error> { let (to_worker, from_worker) = tracing_unbounded("mpsc_network_worker"); - fs::create_dir_all(¶ms.network_config.net_config_path)?; + if let Some(path) = params.network_config.net_config_path { + fs::create_dir_all(&path)?; + } // List of multiaddresses that we know in the network. let mut known_addresses = Vec::new(); diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index ae129871db..7b070f8041 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -607,7 +607,7 @@ pub trait TestNetFactory: Sized { "test-node", "test-client", Default::default(), - &std::env::current_dir().expect("current directory must exist"), + None, ); network_config.transport = TransportConfig::MemoryOnly; network_config.listen_addresses = vec![listen_addr.clone()]; @@ -683,7 +683,7 @@ pub trait TestNetFactory: Sized { "test-node", "test-client", Default::default(), - &std::env::current_dir().expect("current directory must exist"), + None, ); network_config.transport = TransportConfig::MemoryOnly; network_config.listen_addresses = vec![listen_addr.clone()]; diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index a532014658..1e824cb273 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -143,12 +143,11 @@ fn node_config Date: Fri, 17 Apr 2020 20:34:23 +0200 Subject: [PATCH 262/300] Revert listening on IPv6 by default (#5687) --- client/cli/src/params/network_params.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/cli/src/params/network_params.rs b/client/cli/src/params/network_params.rs index 45500a5e06..635fc51cfd 100644 --- a/client/cli/src/params/network_params.rs +++ b/client/cli/src/params/network_params.rs @@ -108,9 +108,6 @@ impl NetworkParams { Multiaddr::empty() .with(Protocol::Ip4([0, 0, 0, 0].into())) .with(Protocol::Tcp(port)), - Multiaddr::empty() - .with(Protocol::Ip6([0, 0, 0, 0, 0, 0, 0, 0].into())) - .with(Protocol::Tcp(port)), ] } else { self.listen_addr.clone() -- GitLab From dcb7941652915619f1c9600da9f3b8c68cc8936e Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 17 Apr 2020 23:00:44 +0200 Subject: [PATCH 263/300] Force libp2p 0.18.1 (#5689) --- Cargo.lock | 8 ++++---- bin/utils/subkey/Cargo.toml | 2 +- client/authority-discovery/Cargo.toml | 2 +- client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 4 ++-- client/network/test/Cargo.toml | 2 +- client/peerset/Cargo.toml | 2 +- client/telemetry/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c0cb38679a..f7f8510641 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2576,9 +2576,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa5aedb713f76577818529be8283e35ec5e8b3ecdccfe0231ba4d860687438ab" +checksum = "32ea742c86405b659c358223a8f0f9f5a9eb27bb6083894c6340959b05269662" dependencies = [ "bytes 0.5.4", "futures 0.3.4", @@ -2901,9 +2901,9 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622605817885e67b5572189c2507e514b786beb69ed85a120dbb245a7f15383d" +checksum = "44ab289ae44cc691da0a6fe96aefa43f26c86c6c7813998e203f6d80f1860f18" dependencies = [ "futures 0.3.4", "libp2p-core", diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index cd65d49d98..b0c642ec43 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -32,7 +32,7 @@ derive_more = { version = "0.99.2" } sc-rpc = { version = "2.0.0-dev", path = "../../../client/rpc" } jsonrpc-core-client = { version = "14.0.3", features = ["http"] } hyper = "0.12.35" -libp2p = "0.18.0" +libp2p = "0.18.1" serde_json = "1.0" [features] diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index bc981db4aa..1a0c3d89af 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -21,7 +21,7 @@ codec = { package = "parity-scale-codec", default-features = false, version = "1 derive_more = "0.99.2" futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.18.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } +libp2p = { version = "0.18.1", default-features = false, features = ["secp256k1", "libp2p-websocket"] } log = "0.4.8" prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-dev"} prost = "0.6.1" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index 2b17f6f2f8..a4b3f72b04 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.18.0", default-features = false, features = ["websocket"] } +libp2p = { version = "0.18.1", default-features = false, features = ["websocket"] } log = "0.4.8" lru = "0.4.3" sc-network = { version = "0.8.0-dev", path = "../network" } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 85ad1c0289..f8e35a924f 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -63,7 +63,7 @@ void = "1.0.2" zeroize = "1.0.0" [dependencies.libp2p] -version = "0.18.0" +version = "0.18.1" default-features = false features = ["websocket", "kad", "mdns", "ping", "identify", "mplex", "yamux", "noise"] @@ -71,7 +71,7 @@ features = ["websocket", "kad", "mdns", "ping", "identify", "mplex", "yamux", "n async-std = "1.5" assert_matches = "1.3" env_logger = "0.7.0" -libp2p = { version = "0.18.0", default-features = false, features = ["secio"] } +libp2p = { version = "0.18.1", default-features = false, features = ["secio"] } quickcheck = "0.9.0" rand = "0.7.2" sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index 200d31fa8c..08d0e90871 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" rand = "0.7.2" -libp2p = { version = "0.18.0", default-features = false, features = ["libp2p-websocket"] } +libp2p = { version = "0.18.1", default-features = false, features = ["libp2p-websocket"] } sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } sc-client = { version = "0.8.0-dev", path = "../../" } sc-client-api = { version = "2.0.0-dev", path = "../../api" } diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 1481697c47..d5aa08f2f4 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -15,7 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" -libp2p = { version = "0.18.0", default-features = false } +libp2p = { version = "0.18.1", default-features = false } sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils"} log = "0.4.8" serde_json = "1.0.41" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index a46d4f7f9a..0928d1d2a1 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" wasm-timer = "0.2.0" -libp2p = { version = "0.18.0", default-features = false, features = ["websocket", "wasm-ext", "tcp", "dns"] } +libp2p = { version = "0.18.1", default-features = false, features = ["websocket", "wasm-ext", "tcp", "dns"] } log = "0.4.8" pin-project = "0.4.6" rand = "0.7.2" diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index afb2b8dfb5..d34333c883 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -15,7 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] derive_more = "0.99.2" -libp2p = { version = "0.18.0", default-features = false } +libp2p = { version = "0.18.1", default-features = false } log = "0.4.8" sp-core = { path= "../../core", version = "2.0.0-dev"} sp-inherents = { version = "2.0.0-dev", path = "../../inherents" } -- GitLab From 3418e64b124442c74722774373c597c60970dc4a Mon Sep 17 00:00:00 2001 From: Eliott Teissonniere <10683430+ETeissonniere@users.noreply.github.com> Date: Fri, 17 Apr 2020 15:17:36 -0700 Subject: [PATCH 264/300] subkey: compute and inspect a moduleid (#5676) * create moduleid command * fill README * make it work on the last master --- bin/utils/subkey/README.adoc | 13 +++++++++++++ bin/utils/subkey/src/main.rs | 21 ++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/bin/utils/subkey/README.adoc b/bin/utils/subkey/README.adoc index 07533a002f..1fa0753312 100644 --- a/bin/utils/subkey/README.adoc +++ b/bin/utils/subkey/README.adoc @@ -68,3 +68,16 @@ subkey sign-transaction \ ``` Will output a signed and encoded `UncheckedMortalCompactExtrinsic` as hex. + +=== Inspecting a module ID + +```bash +subkey --network kusama moduleid "py/trsry" + +OUTPUT: +Public Key URI `F3opxRbN5ZbjJNU511Kj2TLuzFcDq9BGduA9TgiECafpg29` is account: + Network ID/version: kusama + Public key (hex): 0x6d6f646c70792f74727372790000000000000000000000000000000000000000 + Account ID: 0x6d6f646c70792f74727372790000000000000000000000000000000000000000 + SS58 Address: F3opxRbN5ZbjJNU511Kj2TLuzFcDq9BGduA9TgiECafpg29 +``` \ No newline at end of file diff --git a/bin/utils/subkey/src/main.rs b/bin/utils/subkey/src/main.rs index 08a46f1190..2d9302bf8c 100644 --- a/bin/utils/subkey/src/main.rs +++ b/bin/utils/subkey/src/main.rs @@ -31,7 +31,7 @@ use sp_core::{ crypto::{set_default_ss58_version, Ss58AddressFormat, Ss58Codec}, ed25519, sr25519, ecdsa, Pair, Public, H256, hexdisplay::HexDisplay, }; -use sp_runtime::{traits::{IdentifyAccount, Verify}, generic::Era}; +use sp_runtime::{traits::{AccountIdConversion, IdentifyAccount, Verify}, generic::Era, ModuleId}; use std::{ convert::{TryInto, TryFrom}, io::{stdin, Read}, str::FromStr, path::PathBuf, fs, fmt, }; @@ -318,6 +318,11 @@ fn get_app<'a, 'b>(usage: &'a str) -> App<'a, 'b> { 'Key type, examples: \"gran\", or \"imon\" ' [node-url] 'Node JSON-RPC endpoint, default \"http:://localhost:9933\"' "), + SubCommand::with_name("moduleid") + .about("Inspect a module ID address") + .args_from_usage(" + 'The module ID used to derive the account' + ") ]) } @@ -507,6 +512,20 @@ where sp_core::Bytes(pair.public().as_ref().to_vec()), ); } + ("moduleid", Some(matches)) => { + let id = get_uri("id", &matches)?; + if id.len() != 8 { + Err("a module id must be a string of 8 characters")? + } + + let id_fixed_array: [u8; 8] = id.as_bytes().try_into() + .map_err(|_| Error::Static("Cannot convert argument to moduleid: argument should be 8-character string"))?; + + let account_id: AccountId = ModuleId(id_fixed_array).into_account(); + let v = maybe_network.unwrap_or(Ss58AddressFormat::SubstrateAccount); + + C::print_from_uri(&account_id.to_ss58check_with_version(v), password, maybe_network, output); + } _ => print_usage(&matches), } -- GitLab From d55823f830be2b9fcaea31bccfce3aa1df58d596 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Sat, 18 Apr 2020 14:04:23 +0200 Subject: [PATCH 265/300] Refactor misleading log in discovery (#5679) * Refactor misleading log * Forgot to git add the compilation fix --- client/network/src/discovery.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index fc78e9b3e3..f3b9c5cc71 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -375,9 +375,10 @@ impl NetworkBehaviour for DiscoveryBehaviour { list.extend(list_to_filter); } - trace!(target: "sub-libp2p", "Addresses of {:?} are {:?}", peer_id, list); + if !list.is_empty() { + trace!(target: "sub-libp2p", "Addresses of {:?}: {:?}", peer_id, list); - if list.is_empty() { + } else { let mut has_entry = false; for k in self.kademlias.values_mut() { if k.kbuckets_entries().any(|p| p == peer_id) { @@ -386,15 +387,12 @@ impl NetworkBehaviour for DiscoveryBehaviour { } } if has_entry { - debug!(target: "sub-libp2p", - "Requested dialing to {:?} (peer in k-buckets), and no address was found", - peer_id); + trace!(target: "sub-libp2p", "Addresses of {:?}: none (peer in k-buckets)", peer_id); } else { - debug!(target: "sub-libp2p", - "Requested dialing to {:?} (peer not in k-buckets), and no address was found", - peer_id); + trace!(target: "sub-libp2p", "Addresses of {:?}: none (peer not in k-buckets)", peer_id); } } + list } -- GitLab From 3ac409ba427170af77c9d97440b30d98fc0464dd Mon Sep 17 00:00:00 2001 From: Joshy Orndorff Date: Sun, 19 Apr 2020 05:57:16 -0400 Subject: [PATCH 266/300] Revise docs on randomness (#5497) * Initial attempt to revise docs. * Remove incorrect warning from Babe pallet * Add more hints that collective flip is for low security --- frame/babe/src/lib.rs | 15 ++++++++++ frame/randomness-collective-flip/src/lib.rs | 32 ++------------------- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index ea2f97e7a9..5227dd9442 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -205,6 +205,21 @@ decl_module! { } impl RandomnessT<::Hash> for Module { + /// Some BABE blocks have VRF outputs where the block producer has exactly one bit of influence, + /// either they make the block or they do not make the block and thus someone else makes the + /// next block. Yet, this randomness is not fresh in all BABE blocks. + /// + /// If that is an insufficient security guarantee then two things can be used to improve this + /// randomness: + /// + /// - Name, in advance, the block number whose random value will be used; ensure your module + /// retains a buffer of previous random values for its subject and then index into these in + /// order to obviate the ability of your user to look up the parent hash and choose when to + /// transact based upon it. + /// - Require your user to first commit to an additional value by first posting its hash. + /// Require them to reveal the value to determine the final result, hashing it with the + /// output of this random function. This reduces the ability of a cabal of block producers + /// from conspiring against individuals. fn random(subject: &[u8]) -> T::Hash { let mut subject = subject.to_vec(); subject.reserve(VRF_OUTPUT_LENGTH); diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index 194879eb65..cf6dadf7cb 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -19,7 +19,8 @@ //! The Randomness Collective Flip module provides a [`random`](./struct.Module.html#method.random) //! function that generates low-influence random values based on the block hashes from the previous //! `81` blocks. Low-influence randomness can be useful when defending against relatively weak -//! adversaries. +//! adversaries. Using this pallet as a randomness source is advisable primarily in low-security +//! situations like testing. //! //! ## Public Functions //! @@ -43,7 +44,7 @@ //! pub struct Module for enum Call where origin: T::Origin { //! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] //! pub fn random_module_example(origin) -> dispatch::DispatchResult { -//! let _random_seed = >::random_seed(); +//! let _random_value = >::random(&b"my context"[..]); //! Ok(()) //! } //! } @@ -98,17 +99,6 @@ decl_storage! { } impl Randomness for Module { - /// Get a low-influence "random" value. - /// - /// Being a deterministic block chain, real randomness is difficult to come by. This gives you - /// something that approximates it. `subject` is a context identifier and allows you to get a - /// different result to other callers of this function; use it like - /// `random(&b"my context"[..])`. This is initially implemented through a low-influence - /// "triplet mix" convolution of previous block hash values. In the future it will be generated - /// from a secure verifiable random function (VRF). - /// - /// ### Security Notes - /// /// This randomness uses a low-influence function, drawing upon the block hashes from the /// previous 81 blocks. Its result for any given subject will be known far in advance by anyone /// observing the chain. Any block producer has significant influence over their block hashes @@ -116,22 +106,6 @@ impl Randomness for Module { /// block producer's influence over the randomness, but increases the influence of small /// colluding groups of recent block producers. /// - /// Some BABE blocks have VRF outputs where the block producer has exactly one bit of influence, - /// either they make the block or they do not make the block and thus someone else makes the - /// next block. Yet, this randomness is not fresh in all BABE blocks. - /// - /// If that is an insufficient security guarantee then two things can be used to improve this - /// randomness: - /// - /// - Name, in advance, the block number whose random value will be used; ensure your module - /// retains a buffer of previous random values for its subject and then index into these in - /// order to obviate the ability of your user to look up the parent hash and choose when to - /// transact based upon it. - /// - Require your user to first commit to an additional value by first posting its hash. - /// Require them to reveal the value to determine the final result, hashing it with the - /// output of this random function. This reduces the ability of a cabal of block producers - /// from conspiring against individuals. - /// /// WARNING: Hashing the result of this function will remove any low-influence properties it has /// and mean that all bits of the resulting value are entirely manipulatable by the author of /// the parent block, who can determine the value of `parent_hash`. -- GitLab From 58d32c138f44021e8064b42230f2abf46b5149f2 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 20 Apr 2020 11:03:58 +0200 Subject: [PATCH 267/300] Allow to expose a subset of unsafe RPCs (#5233) * sc-cli: Use type-safe constructors for RPC/Prometheus interfaces * service: Simplify rpc handler creation Could probably be further simplifies once [this][commit] lands. [commit]: https://github.com/paritytech/jsonrpc/commit/20485387ed06a48f1a70bf4d609a7cde6cf0accf * service: Streamline some HTTP & WS server start logic * client: Introduce a simple RPC policy mechanism * rpc/system: Check unsafe RPCs * rpc/offchain: Check unsafe RPCs * rpc/author: Check unsafe RPCs --- client/cli/src/commands/mod.rs | 6 ++ client/cli/src/commands/runcmd.rs | 83 ++++++++++++++-------------- client/cli/src/config.rs | 8 +++ client/rpc-api/src/author/error.rs | 4 ++ client/rpc-api/src/lib.rs | 2 + client/rpc-api/src/offchain/error.rs | 8 ++- client/rpc-api/src/policy.rs | 60 ++++++++++++++++++++ client/rpc-api/src/system/mod.rs | 6 +- client/rpc/src/author/mod.rs | 16 +++++- client/rpc/src/author/tests.rs | 1 + client/rpc/src/lib.rs | 2 +- client/rpc/src/offchain/mod.rs | 9 ++- client/rpc/src/offchain/tests.rs | 19 ++++++- client/rpc/src/system/mod.rs | 39 +++++++++++-- client/rpc/src/system/tests.rs | 40 +++++++++----- client/service/src/builder.rs | 48 ++++++++-------- client/service/src/config.rs | 2 + client/service/src/lib.rs | 23 ++++++-- client/service/test/src/lib.rs | 1 + utils/browser/src/lib.rs | 1 + 20 files changed, 282 insertions(+), 96 deletions(-) create mode 100644 client/rpc-api/src/policy.rs diff --git a/client/cli/src/commands/mod.rs b/client/cli/src/commands/mod.rs index ae2fe55467..ec36fb3b64 100644 --- a/client/cli/src/commands/mod.rs +++ b/client/cli/src/commands/mod.rs @@ -279,6 +279,12 @@ macro_rules! substrate_cli_subcommands { } } + fn unsafe_rpc_expose(&self) -> $crate::Result { + match self { + $($enum::$variant(cmd) => cmd.unsafe_rpc_expose()),* + } + } + fn rpc_ws_max_connections(&self) -> $crate::Result<::std::option::Option> { match self { $($enum::$variant(cmd) => cmd.rpc_ws_max_connections()),* diff --git a/client/cli/src/commands/runcmd.rs b/client/cli/src/commands/runcmd.rs index b3ce6ce6d1..3a3a17ea3f 100644 --- a/client/cli/src/commands/runcmd.rs +++ b/client/cli/src/commands/runcmd.rs @@ -27,7 +27,7 @@ use sc_service::{ ChainSpec, Role, }; use sc_telemetry::TelemetryEndpoints; -use std::net::SocketAddr; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use structopt::{clap::arg_enum, StructOpt}; arg_enum! { @@ -93,6 +93,14 @@ pub struct RunCmd { #[structopt(long = "unsafe-rpc-external")] pub unsafe_rpc_external: bool, + /// Don't deny potentially unsafe RPCs when listening on external interfaces. + /// + /// Default is false. This allows exposing RPC methods publicly (same as `--unsafe-{rpc,ws}-external` ) + /// but will allow doing so even on validator nodes, which is prohibited by default. + /// Please do this if you know what you're doing. + #[structopt(long = "unsafe-rpc-expose")] + pub unsafe_rpc_expose: bool, + /// Listen to all Websocket interfaces. /// /// Default is local. Note: not all RPC methods are safe to be exposed publicly. Use an RPC proxy @@ -361,22 +369,19 @@ impl CliConfiguration for RunCmd { } fn prometheus_config(&self) -> Result> { - if self.no_prometheus { - Ok(None) + Ok(if self.no_prometheus { + None } else { - let prometheus_interface: &str = if self.prometheus_external { - "0.0.0.0" + let interface = if self.prometheus_external { + Ipv4Addr::UNSPECIFIED } else { - "127.0.0.1" + Ipv4Addr::LOCALHOST }; - Ok(Some(PrometheusConfig::new_with_default_registry( - parse_address( - &format!("{}:{}", prometheus_interface, 9615), - self.prometheus_port, - )?, - ))) - } + Some(PrometheusConfig::new_with_default_registry( + SocketAddr::new(interface.into(), self.prometheus_port.unwrap_or(9615)) + )) + }) } fn disable_grandpa(&self) -> Result { @@ -409,23 +414,29 @@ impl CliConfiguration for RunCmd { } fn rpc_http(&self) -> Result> { - let rpc_interface: &str = - interface_str(self.rpc_external, self.unsafe_rpc_external, self.validator)?; + let interface = rpc_interface( + self.rpc_external, + self.unsafe_rpc_external, + self.unsafe_rpc_expose, + self.validator + )?; - Ok(Some(parse_address( - &format!("{}:{}", rpc_interface, 9933), - self.rpc_port, - )?)) + Ok(Some(SocketAddr::new(interface, self.rpc_port.unwrap_or(9933)))) } fn rpc_ws(&self) -> Result> { - let ws_interface: &str = - interface_str(self.ws_external, self.unsafe_ws_external, self.validator)?; + let interface = rpc_interface( + self.ws_external, + self.unsafe_ws_external, + self.unsafe_rpc_expose, + self.validator + )?; - Ok(Some(parse_address( - &format!("{}:{}", ws_interface, 9944), - self.ws_port, - )?)) + Ok(Some(SocketAddr::new(interface, self.ws_port.unwrap_or(9944)))) + } + + fn unsafe_rpc_expose(&self) -> Result { + Ok(self.unsafe_rpc_expose) } fn offchain_worker(&self, role: &Role) -> Result { @@ -468,23 +479,13 @@ pub fn is_node_name_valid(_name: &str) -> std::result::Result<(), &str> { Ok(()) } -fn parse_address(address: &str, port: Option) -> std::result::Result { - let mut address: SocketAddr = address - .parse() - .map_err(|_| format!("Invalid address: {}", address))?; - if let Some(port) = port { - address.set_port(port); - } - - Ok(address) -} - -fn interface_str( +fn rpc_interface( is_external: bool, is_unsafe_external: bool, + is_unsafe_rpc_expose: bool, is_validator: bool, -) -> Result<&'static str> { - if is_external && is_validator { +) -> Result { + if is_external && is_validator && !is_unsafe_rpc_expose { return Err(Error::Input( "--rpc-external and --ws-external options shouldn't be \ used if the node is running as a validator. Use `--unsafe-rpc-external` if you understand \ @@ -499,9 +500,9 @@ fn interface_str( available set of RPC methods." ); - Ok("0.0.0.0") + Ok(Ipv4Addr::UNSPECIFIED.into()) } else { - Ok("127.0.0.1") + Ok(Ipv4Addr::LOCALHOST.into()) } } diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index 04a6647402..9de2022a59 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -249,6 +249,13 @@ pub trait CliConfiguration: Sized { Ok(Default::default()) } + /// Returns `Ok(true) if potentially unsafe RPC is to be exposed. + /// + /// By default this is `false`. + fn unsafe_rpc_expose(&self) -> Result { + Ok(Default::default()) + } + /// Get the RPC websockets maximum connections (`None` if unlimited). /// /// By default this is `None`. @@ -419,6 +426,7 @@ pub trait CliConfiguration: Sized { execution_strategies: self.execution_strategies(is_dev)?, rpc_http: self.rpc_http()?, rpc_ws: self.rpc_ws()?, + unsafe_rpc_expose: self.unsafe_rpc_expose()?, rpc_ws_max_connections: self.rpc_ws_max_connections()?, rpc_cors: self.rpc_cors(is_dev)?, prometheus_config: self.prometheus_config()?, diff --git a/client/rpc-api/src/author/error.rs b/client/rpc-api/src/author/error.rs index f1b5691008..dfd488e5da 100644 --- a/client/rpc-api/src/author/error.rs +++ b/client/rpc-api/src/author/error.rs @@ -57,6 +57,8 @@ pub enum Error { /// Invalid session keys encoding. #[display(fmt="Session keys are not encoded correctly")] InvalidSessionKeys, + /// Call to an unsafe RPC was denied. + UnsafeRpcCalled(crate::policy::UnsafeRpcError), } impl std::error::Error for Error { @@ -65,6 +67,7 @@ impl std::error::Error for Error { Error::Client(ref err) => Some(&**err), Error::Pool(ref err) => Some(err), Error::Verification(ref err) => Some(&**err), + Error::UnsafeRpcCalled(ref err) => Some(err), _ => None, } } @@ -152,6 +155,7 @@ impl From for rpc::Error { request to insert the key successfully.".into() ), }, + Error::UnsafeRpcCalled(e) => e.into(), e => errors::internal(e), } } diff --git a/client/rpc-api/src/lib.rs b/client/rpc-api/src/lib.rs index 8ad2d94bfd..2d541be2a7 100644 --- a/client/rpc-api/src/lib.rs +++ b/client/rpc-api/src/lib.rs @@ -22,11 +22,13 @@ mod errors; mod helpers; +mod policy; mod subscriptions; pub use jsonrpc_core::IoHandlerExtension as RpcExtension; pub use subscriptions::{Subscriptions, TaskExecutor}; pub use helpers::Receiver; +pub use policy::DenyUnsafe; pub mod author; pub mod chain; diff --git a/client/rpc-api/src/offchain/error.rs b/client/rpc-api/src/offchain/error.rs index c28a2a2f39..695c0cf41f 100644 --- a/client/rpc-api/src/offchain/error.rs +++ b/client/rpc-api/src/offchain/error.rs @@ -27,11 +27,16 @@ pub enum Error { /// Unavailable storage kind error. #[display(fmt="This storage kind is not available yet.")] UnavailableStorageKind, + /// Call to an unsafe RPC was denied. + UnsafeRpcCalled(crate::policy::UnsafeRpcError), } impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - None + match self { + Self::UnsafeRpcCalled(err) => Some(err), + _ => None, + } } } @@ -46,6 +51,7 @@ impl From for rpc::Error { message: "This storage kind is not available yet" .into(), data: None, }, + Error::UnsafeRpcCalled(e) => e.into(), } } } diff --git a/client/rpc-api/src/policy.rs b/client/rpc-api/src/policy.rs new file mode 100644 index 0000000000..c01b5232f3 --- /dev/null +++ b/client/rpc-api/src/policy.rs @@ -0,0 +1,60 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Policy-related types. +//! +//! Contains a `DenyUnsafe` type that can be used to deny potentially unsafe +//! RPC when accessed externally. + +use jsonrpc_core as rpc; + +/// Signifies whether a potentially unsafe RPC should be denied. +#[derive(Clone, Copy, Debug)] +pub enum DenyUnsafe { + /// Denies only potentially unsafe RPCs. + Yes, + /// Allows calling every RPCs. + No +} + +impl DenyUnsafe { + /// Returns `Ok(())` if the RPCs considered unsafe are safe to call, + /// otherwise returns `Err(UnsafeRpcError)`. + pub fn check_if_safe(self) -> Result<(), UnsafeRpcError> { + match self { + DenyUnsafe::Yes => Err(UnsafeRpcError), + DenyUnsafe::No => Ok(()) + } + } +} + +/// Signifies whether an RPC considered unsafe is denied to be called externally. +#[derive(Debug)] +pub struct UnsafeRpcError; + +impl std::fmt::Display for UnsafeRpcError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "RPC call is unsafe to be called externally") + } +} + +impl std::error::Error for UnsafeRpcError {} + +impl From for rpc::Error { + fn from(_: UnsafeRpcError) -> rpc::Error { + rpc::Error::method_not_found() + } +} diff --git a/client/rpc-api/src/system/mod.rs b/client/rpc-api/src/system/mod.rs index e66ac97a68..486623477e 100644 --- a/client/rpc-api/src/system/mod.rs +++ b/client/rpc-api/src/system/mod.rs @@ -72,14 +72,16 @@ pub trait SystemApi { /// Returns currently connected peers #[rpc(name = "system_peers", returns = "Vec>")] - fn system_peers(&self) -> Receiver>>; + fn system_peers(&self) + -> Compat>>>>; /// Returns current state of the network. /// /// **Warning**: This API is not stable. // TODO: make this stable and move structs https://github.com/paritytech/substrate/issues/1890 #[rpc(name = "system_networkState", returns = "jsonrpc_core::Value")] - fn system_network_state(&self) -> Receiver; + fn system_network_state(&self) + -> Compat>>; /// Adds a reserved peer. Returns the empty string or an error. The string /// parameter should encode a `p2p` multiaddr. diff --git a/client/rpc/src/author/mod.rs b/client/rpc/src/author/mod.rs index a3f23e8e14..23aed953d0 100644 --- a/client/rpc/src/author/mod.rs +++ b/client/rpc/src/author/mod.rs @@ -30,7 +30,7 @@ use rpc::futures::{ }; use futures::{StreamExt as _, compat::Compat}; use futures::future::{ready, FutureExt, TryFutureExt}; -use sc_rpc_api::Subscriptions; +use sc_rpc_api::{DenyUnsafe, Subscriptions}; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use codec::{Encode, Decode}; use sp_core::{Bytes, traits::BareCryptoStorePtr}; @@ -56,6 +56,8 @@ pub struct Author { subscriptions: Subscriptions, /// The key store. keystore: BareCryptoStorePtr, + /// Whether to deny unsafe calls + deny_unsafe: DenyUnsafe, } impl Author { @@ -65,12 +67,14 @@ impl Author { pool: Arc

, subscriptions: Subscriptions, keystore: BareCryptoStorePtr, + deny_unsafe: DenyUnsafe, ) -> Self { Author { client, pool, subscriptions, keystore, + deny_unsafe, } } } @@ -97,6 +101,8 @@ impl AuthorApi, BlockHash

> for Author suri: String, public: Bytes, ) -> Result<()> { + self.deny_unsafe.check_if_safe()?; + let key_type = key_type.as_str().try_into().map_err(|_| Error::BadKeyType)?; let mut keystore = self.keystore.write(); keystore.insert_unknown(key_type, &suri, &public[..]) @@ -105,6 +111,8 @@ impl AuthorApi, BlockHash

> for Author } fn rotate_keys(&self) -> Result { + self.deny_unsafe.check_if_safe()?; + let best_block_hash = self.client.info().best_hash; self.client.runtime_api().generate_session_keys( &generic::BlockId::Hash(best_block_hash), @@ -113,6 +121,8 @@ impl AuthorApi, BlockHash

> for Author } fn has_session_keys(&self, session_keys: Bytes) -> Result { + self.deny_unsafe.check_if_safe()?; + let best_block_hash = self.client.info().best_hash; let keys = self.client.runtime_api().decode_session_keys( &generic::BlockId::Hash(best_block_hash), @@ -124,6 +134,8 @@ impl AuthorApi, BlockHash

> for Author } fn has_key(&self, public_key: Bytes, key_type: String) -> Result { + self.deny_unsafe.check_if_safe()?; + let key_type = key_type.as_str().try_into().map_err(|_| Error::BadKeyType)?; Ok(self.keystore.read().has_keys(&[(public_key.to_vec(), key_type)])) } @@ -151,6 +163,8 @@ impl AuthorApi, BlockHash

> for Author &self, bytes_or_hash: Vec>>, ) -> Result>> { + self.deny_unsafe.check_if_safe()?; + let hashes = bytes_or_hash.into_iter() .map(|x| match x { hash::ExtrinsicOrHash::Hash(h) => Ok(h), diff --git a/client/rpc/src/author/tests.rs b/client/rpc/src/author/tests.rs index 445888c523..de2ee92fe3 100644 --- a/client/rpc/src/author/tests.rs +++ b/client/rpc/src/author/tests.rs @@ -83,6 +83,7 @@ impl TestSetup { pool: self.pool.clone(), subscriptions: Subscriptions::new(Arc::new(self.runtime.executor())), keystore: self.keystore.clone(), + deny_unsafe: DenyUnsafe::No, } } } diff --git a/client/rpc/src/lib.rs b/client/rpc/src/lib.rs index ea65785c20..c4389913b4 100644 --- a/client/rpc/src/lib.rs +++ b/client/rpc/src/lib.rs @@ -22,7 +22,7 @@ mod metadata; -pub use sc_rpc_api::Subscriptions; +pub use sc_rpc_api::{DenyUnsafe, Subscriptions}; pub use self::metadata::Metadata; pub use rpc::IoHandlerExtension as RpcExtension; diff --git a/client/rpc/src/offchain/mod.rs b/client/rpc/src/offchain/mod.rs index 61984d4845..16c03395c7 100644 --- a/client/rpc/src/offchain/mod.rs +++ b/client/rpc/src/offchain/mod.rs @@ -21,6 +21,7 @@ mod tests; /// Re-export the API for backward compatibility. pub use sc_rpc_api::offchain::*; +use sc_rpc_api::DenyUnsafe; use self::error::{Error, Result}; use sp_core::{ Bytes, @@ -34,13 +35,15 @@ use std::sync::Arc; pub struct Offchain { /// Offchain storage storage: Arc>, + deny_unsafe: DenyUnsafe, } impl Offchain { /// Create new instance of Offchain API. - pub fn new(storage: T) -> Self { + pub fn new(storage: T, deny_unsafe: DenyUnsafe) -> Self { Offchain { storage: Arc::new(RwLock::new(storage)), + deny_unsafe, } } } @@ -48,6 +51,8 @@ impl Offchain { impl OffchainApi for Offchain { /// Set offchain local storage under given key and prefix. fn set_local_storage(&self, kind: StorageKind, key: Bytes, value: Bytes) -> Result<()> { + self.deny_unsafe.check_if_safe()?; + let prefix = match kind { StorageKind::PERSISTENT => sp_offchain::STORAGE_PREFIX, StorageKind::LOCAL => return Err(Error::UnavailableStorageKind), @@ -58,6 +63,8 @@ impl OffchainApi for Offchain { /// Get offchain local storage under given key and prefix. fn get_local_storage(&self, kind: StorageKind, key: Bytes) -> Result> { + self.deny_unsafe.check_if_safe()?; + let prefix = match kind { StorageKind::PERSISTENT => sp_offchain::STORAGE_PREFIX, StorageKind::LOCAL => return Err(Error::UnavailableStorageKind), diff --git a/client/rpc/src/offchain/tests.rs b/client/rpc/src/offchain/tests.rs index ac1a6a4de3..cb05f3d4db 100644 --- a/client/rpc/src/offchain/tests.rs +++ b/client/rpc/src/offchain/tests.rs @@ -21,7 +21,7 @@ use sp_core::{Bytes, offchain::storage::InMemOffchainStorage}; #[test] fn local_storage_should_work() { let storage = InMemOffchainStorage::default(); - let offchain = Offchain::new(storage); + let offchain = Offchain::new(storage, DenyUnsafe::No); let key = Bytes(b"offchain_storage".to_vec()); let value = Bytes(b"offchain_value".to_vec()); @@ -34,3 +34,20 @@ fn local_storage_should_work() { Ok(Some(ref v)) if *v == value ); } + +#[test] +fn offchain_calls_considered_unsafe() { + let storage = InMemOffchainStorage::default(); + let offchain = Offchain::new(storage, DenyUnsafe::Yes); + let key = Bytes(b"offchain_storage".to_vec()); + let value = Bytes(b"offchain_value".to_vec()); + + assert_matches!( + offchain.set_local_storage(StorageKind::PERSISTENT, key.clone(), value.clone()), + Err(Error::UnsafeRpcCalled(_)) + ); + assert_matches!( + offchain.get_local_storage(StorageKind::PERSISTENT, key), + Err(Error::UnsafeRpcCalled(_)) + ); +} diff --git a/client/rpc/src/system/mod.rs b/client/rpc/src/system/mod.rs index 84e06c20a6..2a19e5412e 100644 --- a/client/rpc/src/system/mod.rs +++ b/client/rpc/src/system/mod.rs @@ -21,7 +21,7 @@ mod tests; use futures::{future::BoxFuture, FutureExt, TryFutureExt}; use futures::{channel::oneshot, compat::Compat}; -use sc_rpc_api::Receiver; +use sc_rpc_api::{DenyUnsafe, Receiver}; use sp_utils::mpsc::TracingUnboundedSender; use sp_runtime::traits::{self, Header as HeaderT}; @@ -31,10 +31,19 @@ pub use sc_rpc_api::system::*; pub use self::helpers::{SystemInfo, Health, PeerInfo, NodeRole}; pub use self::gen_client::Client as SystemClient; +macro_rules! bail_if_unsafe { + ($value: expr) => { + if let Err(err) = $value.check_if_safe() { + return async move { Err(err.into()) }.boxed().compat(); + } + }; +} + /// System API implementation pub struct System { info: SystemInfo, send_back: TracingUnboundedSender>, + deny_unsafe: DenyUnsafe, } /// Request to be processed. @@ -66,10 +75,12 @@ impl System { pub fn new( info: SystemInfo, send_back: TracingUnboundedSender>, + deny_unsafe: DenyUnsafe, ) -> Self { System { info, send_back, + deny_unsafe, } } } @@ -113,21 +124,37 @@ impl SystemApi::Number> for Sy Receiver(Compat::new(rx)) } - fn system_peers(&self) -> Receiver::Number>>> { + fn system_peers(&self) + -> Compat::Number>>>>> + { + bail_if_unsafe!(self.deny_unsafe); + let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::Peers(tx)); - Receiver(Compat::new(rx)) + + async move { + rx.await.map_err(|_| rpc::Error::internal_error()) + }.boxed().compat() } - fn system_network_state(&self) -> Receiver { + fn system_network_state(&self) + -> Compat>> + { + bail_if_unsafe!(self.deny_unsafe); + let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::NetworkState(tx)); - Receiver(Compat::new(rx)) + + async move { + rx.await.map_err(|_| rpc::Error::internal_error()) + }.boxed().compat() } fn system_add_reserved_peer(&self, peer: String) -> Compat>> { + bail_if_unsafe!(self.deny_unsafe); + let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::NetworkAddReservedPeer(peer, tx)); async move { @@ -142,6 +169,8 @@ impl SystemApi::Number> for Sy fn system_remove_reserved_peer(&self, peer: String) -> Compat>> { + bail_if_unsafe!(self.deny_unsafe); + let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::NetworkRemoveReservedPeer(peer, tx)); async move { diff --git a/client/rpc/src/system/tests.rs b/client/rpc/src/system/tests.rs index 921d941a1c..d0ec695126 100644 --- a/client/rpc/src/system/tests.rs +++ b/client/rpc/src/system/tests.rs @@ -109,13 +109,17 @@ fn api>>(sync: T) -> System { future::ready(()) })) }); - System::new(SystemInfo { - impl_name: "testclient".into(), - impl_version: "0.2.0".into(), - chain_name: "testchain".into(), - properties: Default::default(), - chain_type: Default::default(), - }, tx) + System::new( + SystemInfo { + impl_name: "testclient".into(), + impl_version: "0.2.0".into(), + chain_name: "testchain".into(), + properties: Default::default(), + chain_type: Default::default(), + }, + tx, + sc_rpc_api::DenyUnsafe::No + ) } fn wait_receiver(rx: Receiver) -> T { @@ -238,14 +242,19 @@ fn system_local_listen_addresses_works() { #[test] fn system_peers() { + let mut runtime = tokio::runtime::current_thread::Runtime::new().unwrap(); + let peer_id = PeerId::random(); + let req = api(Status { + peer_id: peer_id.clone(), + peers: 1, + is_syncing: false, + is_dev: true, + }).system_peers(); + let res = runtime.block_on(req).unwrap(); + assert_eq!( - wait_receiver(api(Status { - peer_id: peer_id.clone(), - peers: 1, - is_syncing: false, - is_dev: true, - }).system_peers()), + res, vec![PeerInfo { peer_id: peer_id.to_base58(), roles: "FULL".into(), @@ -258,7 +267,10 @@ fn system_peers() { #[test] fn system_network_state() { - let res = wait_receiver(api(None).system_network_state()); + let mut runtime = tokio::runtime::current_thread::Runtime::new().unwrap(); + let req = api(None).system_network_state(); + let res = runtime.block_on(req).unwrap(); + assert_eq!( serde_json::from_value::(res).unwrap(), sc_network::network_state::NetworkState { diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 90e644481f..200707dad4 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -46,6 +46,7 @@ use sp_runtime::traits::{ use sp_api::ProvideRuntimeApi; use sc_executor::{NativeExecutor, NativeExecutionDispatch}; use std::{ + collections::HashMap, io::{Read, Write, Seek}, marker::PhantomData, sync::Arc, pin::Pin }; @@ -1001,7 +1002,7 @@ ServiceBuilder< // RPC let (system_rpc_tx, system_rpc_rx) = tracing_unbounded("mpsc_system_rpc"); - let gen_handler = || { + let gen_handler = |deny_unsafe: sc_rpc::DenyUnsafe| { use sc_rpc::{chain, state, author, system, offchain}; let system_info = sc_rpc::system::SystemInfo { @@ -1043,32 +1044,31 @@ ServiceBuilder< transaction_pool.clone(), subscriptions, keystore.clone(), + deny_unsafe, ); - let system = system::System::new(system_info, system_rpc_tx.clone()); - - match offchain_storage.clone() { - Some(storage) => { - let offchain = sc_rpc::offchain::Offchain::new(storage); - sc_rpc_server::rpc_handler(( - state::StateApi::to_delegate(state), - chain::ChainApi::to_delegate(chain), - offchain::OffchainApi::to_delegate(offchain), - author::AuthorApi::to_delegate(author), - system::SystemApi::to_delegate(system), - rpc_extensions.clone(), - )) - }, - None => sc_rpc_server::rpc_handler(( - state::StateApi::to_delegate(state), - chain::ChainApi::to_delegate(chain), - author::AuthorApi::to_delegate(author), - system::SystemApi::to_delegate(system), - rpc_extensions.clone(), - )) - } + let system = system::System::new(system_info, system_rpc_tx.clone(), deny_unsafe); + + let maybe_offchain_rpc = offchain_storage.clone() + .map(|storage| { + let offchain = sc_rpc::offchain::Offchain::new(storage, deny_unsafe); + // FIXME: Use plain Option (don't collect into HashMap) when we upgrade to jsonrpc 14.1 + // https://github.com/paritytech/jsonrpc/commit/20485387ed06a48f1a70bf4d609a7cde6cf0accf + let delegate = offchain::OffchainApi::to_delegate(offchain); + delegate.into_iter().collect::>() + }).unwrap_or_default(); + + sc_rpc_server::rpc_handler(( + state::StateApi::to_delegate(state), + chain::ChainApi::to_delegate(chain), + maybe_offchain_rpc, + author::AuthorApi::to_delegate(author), + system::SystemApi::to_delegate(system), + rpc_extensions.clone(), + )) }; - let rpc_handlers = gen_handler(); let rpc = start_rpc_servers(&config, gen_handler)?; + // This is used internally, so don't restrict access to unsafe RPC + let rpc_handlers = gen_handler(sc_rpc::DenyUnsafe::No); spawn_handle.spawn( "network-worker", diff --git a/client/service/src/config.rs b/client/service/src/config.rs index b90bed723f..affb4aabfc 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -59,6 +59,8 @@ pub struct Configuration { pub wasm_method: WasmExecutionMethod, /// Execution strategies. pub execution_strategies: ExecutionStrategies, + /// Whether potentially unsafe RPC is considered safe to be exposed. + pub unsafe_rpc_expose: bool, /// RPC over HTTP binding address. `None` if disabled. pub rpc_http: Option, /// RPC over Websockets binding address. `None` if disabled. diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 97481fcc25..039e0257ab 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -511,7 +511,7 @@ mod waiting { /// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive. #[cfg(not(target_os = "unknown"))] -fn start_rpc_servers sc_rpc_server::RpcHandler>( +fn start_rpc_servers sc_rpc_server::RpcHandler>( config: &Configuration, mut gen_handler: H ) -> Result, error::Error> { @@ -533,10 +533,23 @@ fn start_rpc_servers sc_rpc_server::RpcHandler>( }) } + fn deny_unsafe(addr: &Option, unsafe_rpc_expose: bool) -> sc_rpc::DenyUnsafe { + let is_exposed_addr = addr.map(|x| x.ip().is_loopback()).unwrap_or(false); + if is_exposed_addr && !unsafe_rpc_expose { + sc_rpc::DenyUnsafe::Yes + } else { + sc_rpc::DenyUnsafe::No + } + } + Ok(Box::new(( maybe_start_server( config.rpc_http, - |address| sc_rpc_server::start_http(address, config.rpc_cors.as_ref(), gen_handler()), + |address| sc_rpc_server::start_http( + address, + config.rpc_cors.as_ref(), + gen_handler(deny_unsafe(&config.rpc_http, config.unsafe_rpc_expose)), + ), )?.map(|s| waiting::HttpServer(Some(s))), maybe_start_server( config.rpc_ws, @@ -544,15 +557,15 @@ fn start_rpc_servers sc_rpc_server::RpcHandler>( address, config.rpc_ws_max_connections, config.rpc_cors.as_ref(), - gen_handler(), + gen_handler(deny_unsafe(&config.rpc_ws, config.unsafe_rpc_expose)), ), - )?.map(|s| waiting::WsServer(Some(s))).map(Mutex::new), + )?.map(|s| waiting::WsServer(Some(s))), ))) } /// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive. #[cfg(target_os = "unknown")] -fn start_rpc_servers sc_rpc_server::RpcHandler>( +fn start_rpc_servers sc_rpc_server::RpcHandler>( _: &Configuration, _: H ) -> Result, error::Error> { diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 1e824cb273..9b9140dd8d 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -184,6 +184,7 @@ fn node_config Date: Mon, 20 Apr 2020 13:13:45 +0200 Subject: [PATCH 268/300] Pass max-total to RewardRemainder on end_era (#5697) * Pass max-total to RewardRemainder on end_era * add test and event * add doc Co-authored-by: thiolliere --- frame/staking/src/inflation.rs | 5 +++-- frame/staking/src/lib.rs | 31 ++++++++++++++++++++++++++++--- frame/staking/src/mock.rs | 27 ++++++++++++++++++++++++++- frame/staking/src/tests.rs | 5 +++++ 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/frame/staking/src/inflation.rs b/frame/staking/src/inflation.rs index d20741d9bc..63d008a197 100644 --- a/frame/staking/src/inflation.rs +++ b/frame/staking/src/inflation.rs @@ -21,10 +21,11 @@ use sp_runtime::{Perbill, traits::AtLeast32Bit, curve::PiecewiseLinear}; -/// The total payout to all validators (and their nominators) per era. +/// The total payout to all validators (and their nominators) per era and maximum payout. /// /// Defined as such: -/// `payout = yearly_inflation(npos_token_staked / total_tokens) * total_tokens / era_per_year` +/// `staker-payout = yearly_inflation(npos_token_staked / total_tokens) * total_tokens / era_per_year` +/// `maximum-payout = max_yearly_inflation * total_tokens / era_per_year` /// /// `era_duration` is expressed in millisecond. pub fn compute_total_payout( diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index b6ffa9081b..40fce5b0d4 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -172,6 +172,22 @@ //! //! ## Implementation Details //! +//! ### Era payout +//! +//! The era payout is computed using yearly inflation curve defined at +//! [`T::RewardCurve`](./trait.Trait.html#associatedtype.RewardCurve) as such: +//! +//! ```nocompile +//! staker_payout = yearly_inflation(npos_token_staked / total_tokens) * total_tokens / era_per_year +//! ``` +//! This payout is used to reward stakers as defined in next section +//! +//! ```nocompile +//! remaining_payout = max_yearly_inflation * total_tokens / era_per_year - staker_payout +//! ``` +//! The remaining reward is send to the configurable end-point +//! [`T::RewardRemainder`](./trait.Trait.html#associatedtype.RewardRemainder). +//! //! ### Reward Calculation //! //! Validators and nominators are rewarded at the end of each era. The total reward of an era is @@ -744,6 +760,7 @@ pub trait Trait: frame_system::Trait { type CurrencyToVote: Convert, VoteWeight> + Convert>; /// Tokens have been minted and are unused for validator-reward. + /// See [Era payout](./index.html#era-payout). type RewardRemainder: OnUnbalanced>; /// The overarching event type. @@ -772,7 +789,8 @@ pub trait Trait: frame_system::Trait { /// Interface for interacting with a session module. type SessionInterface: self::SessionInterface; - /// The NPoS reward curve to use. + /// The NPoS reward curve used to define yearly inflation. + /// See [Era payout](./index.html#era-payout). type RewardCurve: Get<&'static PiecewiseLinear<'static>>; /// Something that can estimate the next session change, accurately or as a best effort guess. @@ -1059,6 +1077,9 @@ decl_storage! { decl_event!( pub enum Event where Balance = BalanceOf, ::AccountId { + /// The era payout has been set; the first balance is the validator-payout; the second is + /// the remainder from the maximum amount of reward. + EraPayout(EraIndex, Balance, Balance), /// The staker has been rewarded by this amount. `AccountId` is the stash account. Reward(AccountId, Balance), /// One validator (and its nominators) has been slashed by the given amount. @@ -2570,16 +2591,20 @@ impl Module { let now_as_millis_u64 = T::UnixTime::now().as_millis().saturated_into::(); let era_duration = now_as_millis_u64 - active_era_start; - let (total_payout, _max_payout) = inflation::compute_total_payout( + let (validator_payout, max_payout) = inflation::compute_total_payout( &T::RewardCurve::get(), Self::eras_total_stake(&active_era.index), T::Currency::total_issuance(), // Duration of era; more than u64::MAX is rewarded as u64::MAX. era_duration.saturated_into::(), ); + let rest = max_payout.saturating_sub(validator_payout); + + Self::deposit_event(RawEvent::EraPayout(active_era.index, validator_payout, rest)); // Set ending era reward. - >::insert(&active_era.index, total_payout); + >::insert(&active_era.index, validator_payout); + T::RewardRemainder::on_unbalanced(T::Currency::issue(rest)); } } diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index d522a19615..20ec6f46a6 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -277,11 +277,26 @@ parameter_types! { pub const UnsignedPriority: u64 = 1 << 20; } +thread_local! { + pub static REWARD_REMAINDER_UNBALANCED: RefCell = RefCell::new(0); +} + +pub struct RewardRemainderMock; + +impl OnUnbalanced> for RewardRemainderMock { + fn on_nonzero_unbalanced(amount: NegativeImbalanceOf) { + REWARD_REMAINDER_UNBALANCED.with(|v| { + *v.borrow_mut() += amount.peek(); + }); + drop(amount); + } +} + impl Trait for Test { type Currency = Balances; type UnixTime = Timestamp; type CurrencyToVote = CurrencyToVoteHandler; - type RewardRemainder = (); + type RewardRemainder = RewardRemainderMock; type Event = MetaEvent; type Slash = (); type Reward = (); @@ -976,3 +991,13 @@ macro_rules! assert_session_era { ); }; } + +pub(crate) fn staking_events() -> Vec> { + System::events().into_iter().map(|r| r.event).filter_map(|e| { + if let MetaEvent::staking(inner) = e { + Some(inner) + } else { + None + } + }).collect() +} diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 15afda1e3a..3920b7bc0d 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -152,6 +152,7 @@ fn rewards_should_work() { // should check that: // * rewards get recorded per session // * rewards get paid per Era + // * `RewardRemainder::on_unbalanced` is called // * Check that nominators are also rewarded ExtBuilder::default().nominate(true).build_and_execute(|| { let init_balance_10 = Balances::total_balance(&10); @@ -197,6 +198,8 @@ fn rewards_should_work() { start_session(3); assert_eq!(Staking::active_era().unwrap().index, 1); + assert_eq!(mock::REWARD_REMAINDER_UNBALANCED.with(|v| *v.borrow()), 7050); + assert_eq!(*mock::staking_events().last().unwrap(), RawEvent::EraPayout(0, 2350, 7050)); mock::make_all_reward_payment(0); assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * total_payout_0*2/3, 2); @@ -220,6 +223,8 @@ fn rewards_should_work() { assert!(total_payout_1 > 10); // Test is meaningful if reward something mock::start_era(2); + assert_eq!(mock::REWARD_REMAINDER_UNBALANCED.with(|v| *v.borrow()), 7050*2); + assert_eq!(*mock::staking_events().last().unwrap(), RawEvent::EraPayout(1, 2350, 7050)); mock::make_all_reward_payment(1); assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * (total_payout_0 * 2/3 + total_payout_1), 2); -- GitLab From f8879226cc05f19868d9647cb0bd799e65250f5c Mon Sep 17 00:00:00 2001 From: thiolliere Date: Mon, 20 Apr 2020 13:37:05 +0200 Subject: [PATCH 269/300] update code owners (#5700) --- docs/CODEOWNERS | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index d1eb924d0d..ddb776ea22 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -57,15 +57,12 @@ /primitives/consensus/pow/ @sorpaas # Contracts -/frame/contracts/ @pepyakin @thiolliere +/frame/contracts/ @pepyakin /frame/contracts/src/wasm/runtime.rs @Robbepop # EVM /frame/evm/ @sorpaas -# Inflation points -/frame/staking/src/inflation.rs @thiolliere - # NPoS and Governance and Phragmén /frame/staking/ @kianenigma /frame/elections/ @kianenigma @@ -73,7 +70,7 @@ /primitives/phragmen/ @kianenigma # Fixed point arithmetic -/primitives/sp-arithmetic/ @kianenigma @thiolliere +/primitives/sp-arithmetic/ @kianenigma # End to end testing of substrate node /bin/node/executor/ @kianenigma @@ -82,7 +79,7 @@ /frame/support/src/weights.rs @kianenigma # Support crates -/frame/support/ @thiolliere @kianenigma +/frame/support/ @kianenigma # Authority discovery /client/authority-discovery/ @mxinden -- GitLab From 217d5c60ca08bbecd368c330862f8a78dccc6359 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 20 Apr 2020 14:35:17 +0200 Subject: [PATCH 270/300] Move around definitions in sc_network (#5701) --- client/network/src/config.rs | 59 +++++++++++++++++- client/network/src/lib.rs | 37 +++++++++++- client/network/src/protocol.rs | 14 +++-- client/network/src/service.rs | 92 +---------------------------- client/network/src/service/tests.rs | 2 +- 5 files changed, 104 insertions(+), 100 deletions(-) diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 4914ad680a..c53d2734d2 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -21,7 +21,6 @@ pub use crate::chain::{Client, FinalityProofProvider}; pub use crate::on_demand_layer::{AlwaysBadChecker, OnDemand}; -pub use crate::service::{TransactionPool, EmptyTransactionPool}; pub use libp2p::{identity, core::PublicKey, wasm_ext::ExtTransport, build_multiaddr}; // Note: this re-export shouldn't be part of the public API of the crate and will be removed in @@ -29,17 +28,19 @@ pub use libp2p::{identity, core::PublicKey, wasm_ext::ExtTransport, build_multia #[doc(hidden)] pub use crate::protocol::ProtocolConfig; -use crate::service::ExHashT; +use crate::{ExHashT, ReportHandle}; use core::{fmt, iter}; use libp2p::identity::{ed25519, Keypair}; use libp2p::wasm_ext; use libp2p::{multiaddr, Multiaddr, PeerId}; use prometheus_endpoint::Registry; +use sc_peerset::ReputationChange; use sp_consensus::{block_validation::BlockAnnounceValidator, import_queue::ImportQueue}; use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; use std::{borrow::Cow, convert::TryFrom, future::Future, pin::Pin, str::FromStr}; use std::{ + collections::HashMap, error::Error, fs, io::{self, Write}, @@ -166,6 +167,60 @@ impl FinalityProofRequestBuilder for DummyFinalityProofRequestBuil /// Shared finality proof request builder struct used by the queue. pub type BoxFinalityProofRequestBuilder = Box + Send + Sync>; +/// Transaction pool interface +pub trait TransactionPool: Send + Sync { + /// Get transactions from the pool that are ready to be propagated. + fn transactions(&self) -> Vec<(H, B::Extrinsic)>; + /// Get hash of transaction. + fn hash_of(&self, transaction: &B::Extrinsic) -> H; + /// Import a transaction into the pool. + /// + /// Peer reputation is changed by reputation_change if transaction is accepted by the pool. + fn import( + &self, + report_handle: ReportHandle, + who: PeerId, + reputation_change_good: ReputationChange, + reputation_change_bad: ReputationChange, + transaction: B::Extrinsic, + ); + /// Notify the pool about transactions broadcast. + fn on_broadcasted(&self, propagations: HashMap>); + /// Get transaction by hash. + fn transaction(&self, hash: &H) -> Option; +} + +/// Dummy implementation of the [`TransactionPool`] trait for a transaction pool that is always +/// empty and discards all incoming transactions. +/// +/// Requires the "hash" type to implement the `Default` trait. +/// +/// Useful for testing purposes. +pub struct EmptyTransactionPool; + +impl TransactionPool for EmptyTransactionPool { + fn transactions(&self) -> Vec<(H, B::Extrinsic)> { + Vec::new() + } + + fn hash_of(&self, _transaction: &B::Extrinsic) -> H { + Default::default() + } + + fn import( + &self, + _report_handle: ReportHandle, + _who: PeerId, + _rep_change_good: ReputationChange, + _rep_change_bad: ReputationChange, + _transaction: B::Extrinsic + ) {} + + fn on_broadcasted(&self, _: HashMap>) {} + + fn transaction(&self, _h: &H) -> Option { None } +} + /// Name of a protocol, transmitted on the wire. Should be unique for each chain. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ProtocolId(smallvec::SmallVec<[u8; 6]>); diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index d8afa1f153..ed96215d20 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -246,7 +246,7 @@ pub mod config; pub mod error; pub mod network_state; -pub use service::{NetworkService, NetworkStateInfo, NetworkWorker, ExHashT, ReportHandle}; +pub use service::{NetworkService, NetworkWorker}; pub use protocol::PeerInfo; pub use protocol::event::{Event, DhtEvent, ObservedRole}; pub use protocol::sync::SyncState; @@ -264,3 +264,38 @@ pub use sc_peerset::ReputationChange; /// case of (possibly repeated) simultaneous dialing attempts between /// two peers, the per-peer connection limit is not set to 1 but 2. const MAX_CONNECTIONS_PER_PEER: usize = 2; + +/// Minimum Requirements for a Hash within Networking +pub trait ExHashT: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static {} + +impl ExHashT for T where T: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static +{} + +/// A cloneable handle for reporting cost/benefits of peers. +#[derive(Clone)] +pub struct ReportHandle { + inner: sc_peerset::PeersetHandle, // wraps it so we don't have to worry about breaking API. +} + +impl From for ReportHandle { + fn from(peerset_handle: sc_peerset::PeersetHandle) -> Self { + ReportHandle { inner: peerset_handle } + } +} + +impl ReportHandle { + /// Report a given peer as either beneficial (+) or costly (-) according to the + /// given scalar. + pub fn report_peer(&self, who: PeerId, cost_benefit: ReputationChange) { + self.inner.report_peer(who, cost_benefit); + } +} + +/// Trait for providing information about the local network state +pub trait NetworkStateInfo { + /// Returns the local external addresses. + fn external_addresses(&self) -> Vec; + + /// Returns the local Peer ID. + fn local_peer_id(&self) -> PeerId; +} diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 49479aa2d4..f59a775216 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -14,8 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::config::ProtocolId; -use crate::utils::interval; +use crate::{ + ExHashT, + chain::{Client, FinalityProofProvider}, + config::{BoxFinalityProofRequestBuilder, ProtocolId, TransactionPool}, + error, + utils::interval +}; + use bytes::{Bytes, BytesMut}; use futures::prelude::*; use generic_proto::{GenericProto, GenericProtoOut}; @@ -42,17 +48,13 @@ use message::{BlockAnnounce, Message}; use message::generic::{Message as GenericMessage, ConsensusMessage, Roles}; use prometheus_endpoint::{Registry, Gauge, GaugeVec, HistogramVec, PrometheusError, Opts, register, U64}; use sync::{ChainSync, SyncState}; -use crate::service::{TransactionPool, ExHashT}; -use crate::config::BoxFinalityProofRequestBuilder; use std::borrow::Cow; use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; use std::sync::Arc; use std::fmt::Write; use std::{cmp, io, num::NonZeroUsize, pin::Pin, task::Poll, time}; use log::{log, Level, trace, debug, warn, error}; -use crate::chain::{Client, FinalityProofProvider}; use sc_client_api::{ChangesProof, StorageProof}; -use crate::error; use util::LruHashSet; use wasm_timer::Instant; diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 091c75d635..d29cb94ee8 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -26,6 +26,7 @@ //! which is then processed by [`NetworkWorker::poll`]. use crate::{ + ExHashT, NetworkStateInfo, behaviour::{Behaviour, BehaviourOut}, config::{parse_addr, parse_str_addr, NonReservedPeerMode, Params, Role, TransportConfig}, discovery::DiscoveryConfig, @@ -57,7 +58,7 @@ use sp_runtime::{ use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; use std::{ borrow::Cow, - collections::{HashMap, HashSet}, + collections::HashSet, fs, io, marker::PhantomData, pin::Pin, @@ -73,86 +74,6 @@ mod out_events; #[cfg(test)] mod tests; -/// Minimum Requirements for a Hash within Networking -pub trait ExHashT: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static {} - -impl ExHashT for T where T: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static -{} - -/// Transaction pool interface -pub trait TransactionPool: Send + Sync { - /// Get transactions from the pool that are ready to be propagated. - fn transactions(&self) -> Vec<(H, B::Extrinsic)>; - /// Get hash of transaction. - fn hash_of(&self, transaction: &B::Extrinsic) -> H; - /// Import a transaction into the pool. - /// - /// Peer reputation is changed by reputation_change if transaction is accepted by the pool. - fn import( - &self, - report_handle: ReportHandle, - who: PeerId, - reputation_change_good: ReputationChange, - reputation_change_bad: ReputationChange, - transaction: B::Extrinsic, - ); - /// Notify the pool about transactions broadcast. - fn on_broadcasted(&self, propagations: HashMap>); - /// Get transaction by hash. - fn transaction(&self, hash: &H) -> Option; -} - -/// Dummy implementation of the [`TransactionPool`] trait for a transaction pool that is always -/// empty and discards all incoming transactions. -/// -/// Requires the "hash" type to implement the `Default` trait. -/// -/// Useful for testing purposes. -pub struct EmptyTransactionPool; - -impl TransactionPool for EmptyTransactionPool { - fn transactions(&self) -> Vec<(H, B::Extrinsic)> { - Vec::new() - } - - fn hash_of(&self, _transaction: &B::Extrinsic) -> H { - Default::default() - } - - fn import( - &self, - _report_handle: ReportHandle, - _who: PeerId, - _rep_change_good: ReputationChange, - _rep_change_bad: ReputationChange, - _transaction: B::Extrinsic - ) {} - - fn on_broadcasted(&self, _: HashMap>) {} - - fn transaction(&self, _h: &H) -> Option { None } -} - -/// A cloneable handle for reporting cost/benefits of peers. -#[derive(Clone)] -pub struct ReportHandle { - inner: PeersetHandle, // wraps it so we don't have to worry about breaking API. -} - -impl From for ReportHandle { - fn from(peerset_handle: PeersetHandle) -> Self { - ReportHandle { inner: peerset_handle } - } -} - -impl ReportHandle { - /// Report a given peer as either beneficial (+) or costly (-) according to the - /// given scalar. - pub fn report_peer(&self, who: PeerId, cost_benefit: ReputationChange) { - self.inner.report_peer(who, cost_benefit); - } -} - /// Substrate network service. Handles network IO and manages connectivity. pub struct NetworkService { /// Number of peers we're connected to. @@ -792,15 +713,6 @@ impl<'a, B: BlockT + 'static, H: ExHashT> sp_consensus::SyncOracle } } -/// Trait for providing information about the local network state -pub trait NetworkStateInfo { - /// Returns the local external addresses. - fn external_addresses(&self) -> Vec; - - /// Returns the local Peer ID. - fn local_peer_id(&self) -> PeerId; -} - impl NetworkStateInfo for NetworkService where B: sp_runtime::traits::Block, diff --git a/client/network/src/service/tests.rs b/client/network/src/service/tests.rs index a60b32efb4..84c393fbd2 100644 --- a/client/network/src/service/tests.rs +++ b/client/network/src/service/tests.rs @@ -95,7 +95,7 @@ fn build_test_full_node(config: config::NetworkConfiguration) finality_proof_provider: None, finality_proof_request_builder: None, on_demand: None, - transaction_pool: Arc::new(crate::service::EmptyTransactionPool), + transaction_pool: Arc::new(crate::config::EmptyTransactionPool), protocol_id: config::ProtocolId::from(&b"/test-protocol-name"[..]), import_queue, block_announce_validator: Box::new( -- GitLab From b9a9589d23efb1043fc43e46ffe3817770d3494e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 20 Apr 2020 14:37:27 +0200 Subject: [PATCH 271/300] Improve tracing (#5698) * Improve tracing implementation * Enable tracing in runtime interfaces * Switch to `TRACE` level --- Cargo.lock | 14 +++- Cargo.toml | 1 + client/tracing/src/lib.rs | 14 +--- client/transaction-pool/Cargo.toml | 2 +- client/transaction-pool/src/api.rs | 14 ++-- frame/executive/Cargo.toml | 2 + frame/executive/src/lib.rs | 23 ++--- frame/support/Cargo.toml | 4 +- frame/support/src/dispatch.rs | 56 +++---------- frame/support/src/lib.rs | 37 +------- primitives/runtime-interface/Cargo.toml | 2 + .../bare_function_interface.rs | 2 + .../host_function_interface.rs | 1 + primitives/runtime-interface/src/lib.rs | 3 + primitives/runtime-interface/test/Cargo.toml | 1 + primitives/runtime-interface/test/src/lib.rs | 46 ++++++++++ primitives/tracing/Cargo.toml | 19 +++++ primitives/tracing/src/lib.rs | 84 +++++++++++++++++++ 18 files changed, 206 insertions(+), 119 deletions(-) create mode 100644 primitives/tracing/Cargo.toml create mode 100644 primitives/tracing/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index f7f8510641..078f0c6708 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1453,6 +1453,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std", + "sp-tracing", "sp-version", ] @@ -1488,7 +1489,7 @@ dependencies = [ "sp-runtime", "sp-state-machine", "sp-std", - "tracing", + "sp-tracing", ] [[package]] @@ -6765,12 +6766,12 @@ dependencies = [ "sp-core", "sp-keyring", "sp-runtime", + "sp-tracing", "sp-transaction-pool", "sp-utils", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "substrate-test-runtime-transaction-pool", - "tracing", "wasm-timer", ] @@ -7574,6 +7575,7 @@ dependencies = [ "sp-runtime-interface-test-wasm", "sp-state-machine", "sp-std", + "sp-tracing", "sp-wasm-interface", "static_assertions", "trybuild", @@ -7601,6 +7603,7 @@ dependencies = [ "sp-runtime-interface-test-wasm", "sp-runtime-interface-test-wasm-deprecated", "sp-state-machine", + "tracing", ] [[package]] @@ -7725,6 +7728,13 @@ dependencies = [ "wasm-timer", ] +[[package]] +name = "sp-tracing" +version = "2.0.0-dev" +dependencies = [ + "tracing", +] + [[package]] name = "sp-transaction-pool" version = "2.0.0-dev" diff --git a/Cargo.toml b/Cargo.toml index 5c4e93d84c..f5ecad013c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,6 +159,7 @@ members = [ "primitives/timestamp", "primitives/test-primitives", "primitives/transaction-pool", + "primitives/tracing", "primitives/trie", "primitives/utils", "primitives/wasm-interface", diff --git a/client/tracing/src/lib.rs b/client/tracing/src/lib.rs index c00bca9275..d450700ed3 100644 --- a/client/tracing/src/lib.rs +++ b/client/tracing/src/lib.rs @@ -20,20 +20,8 @@ //! //! # Usage //! -//! Monitor performance throughout the codebase via the creation of `Span`s. -//! A span is set in the following way: -//! ``` -//! let span = tracing::span!(tracing::Level::INFO, "my_span_name"); -//! let _guard = span.enter(); -//! ``` -//! To begin timing, a span must be entered. When the span is dropped, the execution time -//! is recorded and details sent to the `Receiver` which defines how to process it. +//! See `sp-tracing` for examples on how to use tracing. //! -//! It's possible to record values with each span in the following way: -//! ``` -//! let span = tracing::span!(tracing::Level::INFO, "my_span_name", my_number = 10, a_key = "a value"); -//! let _guard = span.enter(); -//! ``` //! Currently we provide `Log` (default), `Telemetry` variants for `Receiver` use std::collections::HashMap; diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index c96e4c0332..6d4f69676c 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -26,10 +26,10 @@ sc-transaction-graph = { version = "2.0.0-dev", path = "./graph" } sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-tracing = { version = "2.0.0-dev", path = "../../primitives/tracing" } sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } -tracing = "0.1.10" wasm-timer = "0.2" [dev-dependencies] diff --git a/client/transaction-pool/src/api.rs b/client/transaction-pool/src/api.rs index 2e590ccad8..bd7e11a3a6 100644 --- a/client/transaction-pool/src/api.rs +++ b/client/transaction-pool/src/api.rs @@ -89,17 +89,17 @@ impl sc_transaction_graph::ChainApi for FullChainApi, _>( &at, |v| v >= 2, ) - .unwrap_or_default(); - std::mem::drop(guard); - let span = tracing::span!(tracing::Level::DEBUG, "validate_transaction"); - let _guard = span.enter(); + .unwrap_or_default() + }; + + sp_tracing::enter_span!("runtime::validate_transaction"); let res = if has_v2 { runtime_api.validate_transaction(&at, source, uxt) } else { diff --git a/frame/executive/Cargo.toml b/frame/executive/Cargo.toml index f46dc8462d..3e0e1c938a 100644 --- a/frame/executive/Cargo.toml +++ b/frame/executive/Cargo.toml @@ -17,6 +17,7 @@ frame-support = { version = "2.0.0-dev", default-features = false, path = "../su frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } serde = { version = "1.0.101", optional = true } sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-tracing = { version = "2.0.0-dev", default-features = false, path = "../../primitives/tracing" } sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } @@ -37,5 +38,6 @@ std = [ "frame-system/std", "serde", "sp-runtime/std", + "sp-tracing/std", "sp-std/std", ] diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 747fc85866..f3a4388dcf 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -348,25 +348,20 @@ where source: TransactionSource, uxt: Block::Extrinsic, ) -> TransactionValidity { - use frame_support::tracing_span; + use sp_tracing::tracing_span; - tracing_span!{ "validate_transaction::using_encoded"; - let encoded_len = uxt.using_encoded(|d| d.len()); - }; + sp_tracing::enter_span!("validate_transaction"); - tracing_span!{ "validate_transaction::check"; - let xt = uxt.check(&Default::default())?; - }; + let encoded_len = tracing_span!{ "using_encoded"; uxt.using_encoded(|d| d.len()) }; - tracing_span!{ "validate_transaction::dispatch_info"; - let dispatch_info = xt.get_dispatch_info(); - }; + let xt = tracing_span!{ "check"; uxt.check(&Default::default())? }; - tracing_span!{ "validate_transaction::validate"; - let result = xt.validate::(source, &dispatch_info, encoded_len); - }; + let dispatch_info = tracing_span!{ "dispatch_info"; xt.get_dispatch_info() }; - result + tracing_span! { + "validate"; + xt.validate::(source, &dispatch_info, encoded_len) + } } /// Start an offchain worker and generate extrinsics. diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index aee2dd79fc..0168705da7 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -19,6 +19,7 @@ frame-metadata = { version = "11.0.0-dev", default-features = false, path = "../ sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-tracing = { version = "2.0.0-dev", default-features = false, path = "../../primitives/tracing" } sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } sp-arithmetic = { version = "2.0.0-dev", default-features = false, path = "../../primitives/arithmetic" } sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } @@ -28,7 +29,6 @@ once_cell = { version = "1", default-features = false, optional = true } sp-state-machine = { version = "0.8.0-dev", optional = true, path = "../../primitives/state-machine" } bitmask = { version = "0.5.0", default-features = false } impl-trait-for-tuples = "0.1.3" -tracing = { version = "0.1.10", optional = true } [dev-dependencies] pretty_assertions = "0.6.1" @@ -37,7 +37,6 @@ frame-system = { version = "2.0.0-dev", path = "../system" } [features] default = ["std"] std = [ - "tracing", "once_cell", "bitmask/std", "serde", @@ -45,6 +44,7 @@ std = [ "codec/std", "sp-std/std", "sp-runtime/std", + "sp-tracing/std", "sp-arithmetic/std", "frame-metadata/std", "sp-inherents/std", diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index 8512ccb0a8..4287f2c1ce 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -1030,12 +1030,7 @@ macro_rules! decl_module { for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_initialize(_block_number_not_used: $trait_instance::BlockNumber) -> $return { - use $crate::sp_std::if_std; - if_std! { - use $crate::tracing; - let span = tracing::span!(tracing::Level::DEBUG, "on_initialize"); - let _enter = span.enter(); - } + $crate::sp_tracing::enter_span!("on_initialize"); { $( $impl )* } } } @@ -1051,12 +1046,7 @@ macro_rules! decl_module { for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_initialize($param: $param_ty) -> $return { - use $crate::sp_std::if_std; - if_std! { - use $crate::tracing; - let span = tracing::span!(tracing::Level::DEBUG, "on_initialize"); - let _enter = span.enter(); - } + $crate::sp_tracing::enter_span!("on_initialize"); { $( $impl )* } } } @@ -1082,12 +1072,7 @@ macro_rules! decl_module { for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_runtime_upgrade() -> $return { - use $crate::sp_std::if_std; - if_std! { - use $crate::tracing; - let span = tracing::span!(tracing::Level::DEBUG, "on_runtime_upgrade"); - let _enter = span.enter(); - } + $crate::sp_tracing::enter_span!("on_runtime_upgrade"); { $( $impl )* } } } @@ -1114,12 +1099,7 @@ macro_rules! decl_module { for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_finalize(_block_number_not_used: $trait_instance::BlockNumber) { - use $crate::sp_std::if_std; - if_std! { - use $crate::tracing; - let span = tracing::span!(tracing::Level::DEBUG, "on_finalize"); - let _enter = span.enter(); - } + $crate::sp_tracing::enter_span!("on_finalize"); { $( $impl )* } } } @@ -1135,12 +1115,7 @@ macro_rules! decl_module { for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_finalize($param: $param_ty) { - use $crate::sp_std::if_std; - if_std! { - use $crate::tracing; - let span = tracing::span!(tracing::Level::DEBUG, "on_finalize"); - let _enter = span.enter(); - } + $crate::sp_tracing::enter_span!("on_finalize"); { $( $impl )* } } } @@ -1209,15 +1184,9 @@ macro_rules! decl_module { $vis fn $name( $origin: $origin_ty $(, $param: $param_ty )* ) -> $crate::dispatch::DispatchResult { - $crate::sp_std::if_std! { - use $crate::tracing; - let span = tracing::span!(tracing::Level::DEBUG, stringify!($name)); - let _enter = span.enter(); - } - { - { $( $impl )* } - Ok(()) - } + $crate::sp_tracing::enter_span!(stringify!($name)); + { $( $impl )* } + Ok(()) } }; @@ -1234,13 +1203,8 @@ macro_rules! decl_module { ) => { $(#[doc = $doc_attr])* $vis fn $name($origin: $origin_ty $(, $param: $param_ty )* ) -> $result { - use $crate::sp_std::if_std; - if_std! { - use $crate::tracing; - let span = tracing::span!(tracing::Level::DEBUG, stringify!($name)); - let _enter = span.enter(); - } - { $( $impl )* } + $crate::sp_tracing::enter_span!(stringify!($name)); + $( $impl )* } }; diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index eed5c95b17..8a88496eda 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -23,8 +23,9 @@ extern crate self as frame_support; #[macro_use] extern crate bitmask; -#[cfg(feature = "std")] -pub extern crate tracing; + +#[doc(hidden)] +pub use sp_tracing; #[cfg(feature = "std")] pub use serde; @@ -222,38 +223,6 @@ macro_rules! assert_ok { } } -/// Runs given code within a tracing span, measuring it's execution time. -/// -/// Has effect only when running in native environment. In WASM, it simply inserts the -/// code in-place, without any metrics added. -#[macro_export] -macro_rules! tracing_span { - ($name:expr; $( $code:tt )*) => { - let span = $crate::if_tracing!( - $crate::tracing::span!($crate::tracing::Level::TRACE, $name) - , - () - ); - let guard = $crate::if_tracing!(span.enter(), ()); - $( $code )* - - $crate::sp_std::mem::drop(guard); - $crate::sp_std::mem::drop(span); - } -} - -#[macro_export] -#[cfg(feature = "tracing")] -macro_rules! if_tracing { - ( $if:expr, $else:expr ) => {{ $if }} -} - -#[macro_export] -#[cfg(not(feature = "tracing"))] -macro_rules! if_tracing { - ( $if:expr, $else:expr ) => {{ $else }} -} - /// The void type - it cannot exist. // Oh rust, you crack me up... #[derive(Clone, Eq, PartialEq, RuntimeDebug)] diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 362d79f150..1d0ae8f951 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -15,6 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] sp-wasm-interface = { version = "2.0.0-dev", path = "../wasm-interface", default-features = false } sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-tracing = { version = "2.0.0-dev", default-features = false, path = "../tracing" } sp-runtime-interface-proc-macro = { version = "2.0.0-dev", path = "proc-macro" } sp-externalities = { version = "0.8.0-dev", optional = true, path = "../externalities" } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } @@ -34,6 +35,7 @@ default = [ "std" ] std = [ "sp-wasm-interface/std", "sp-std/std", + "sp-tracing/std", "codec/std", "sp-externalities", "primitive-types/std", diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs index e7c34fbf99..8e83556f04 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs @@ -146,6 +146,7 @@ fn function_std_impl( is_wasm_only: bool, ) -> Result { let function_name = create_function_ident_with_version(&method.sig.ident, version); + let function_name_str = function_name.to_string(); let crate_ = generate_crate_access(); let args = get_function_arguments(&method.sig).map(FnArg::Typed).chain( @@ -172,6 +173,7 @@ fn function_std_impl( #[cfg(feature = "std")] #( #attrs )* fn #function_name( #( #args, )* ) #return_value { + #crate_::sp_tracing::enter_span!(#function_name_str); #call_to_trait } } diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs index 205ee87105..46de98c3c3 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs @@ -226,6 +226,7 @@ fn generate_host_function_implementation( __function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext, args: &mut dyn Iterator, ) -> std::result::Result, String> { + #crate_::sp_tracing::enter_span!(#name); #( #wasm_to_ffi_values )* #( #ffi_to_host_values )* #host_function_call diff --git a/primitives/runtime-interface/src/lib.rs b/primitives/runtime-interface/src/lib.rs index fd158d4b8a..4f748825e5 100644 --- a/primitives/runtime-interface/src/lib.rs +++ b/primitives/runtime-interface/src/lib.rs @@ -109,6 +109,9 @@ extern crate self as sp_runtime_interface; #[cfg(feature = "std")] pub use sp_wasm_interface; +#[doc(hidden)] +pub use sp_tracing; + #[doc(hidden)] pub use sp_std; diff --git a/primitives/runtime-interface/test/Cargo.toml b/primitives/runtime-interface/test/Cargo.toml index b3cdb906be..0809eeb8a1 100644 --- a/primitives/runtime-interface/test/Cargo.toml +++ b/primitives/runtime-interface/test/Cargo.toml @@ -19,3 +19,4 @@ sp-runtime-interface-test-wasm-deprecated = { version = "2.0.0-dev", path = "../ sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } sp-runtime = { version = "2.0.0-dev", path = "../../runtime" } sp-io = { version = "2.0.0-dev", path = "../../io" } +tracing = "0.1.13" diff --git a/primitives/runtime-interface/test/src/lib.rs b/primitives/runtime-interface/test/src/lib.rs index 110eda980f..8815a17a08 100644 --- a/primitives/runtime-interface/test/src/lib.rs +++ b/primitives/runtime-interface/test/src/lib.rs @@ -27,6 +27,8 @@ use sp_runtime_interface_test_wasm_deprecated::WASM_BINARY as WASM_BINARY_DEPREC use sp_wasm_interface::HostFunctions as HostFunctionsT; use sc_executor::CallInWasm; +use std::{collections::HashSet, sync::{Arc, Mutex}}; + type TestExternalities = sp_state_machine::TestExternalities; fn call_wasm_method(binary: &[u8], method: &str) -> TestExternalities { @@ -150,3 +152,47 @@ fn test_versionining_with_new_host_works() { "test_versionning_works", ); } + +#[test] +fn test_tracing() { + use tracing::span::Id as SpanId; + + #[derive(Clone)] + struct TracingSubscriber(Arc>); + + #[derive(Default)] + struct Inner { + spans: HashSet<&'static str>, + } + + impl tracing::subscriber::Subscriber for TracingSubscriber { + fn enabled(&self, _: &tracing::Metadata) -> bool { true } + + fn new_span(&self, span: &tracing::span::Attributes) -> tracing::Id { + let mut inner = self.0.lock().unwrap(); + let id = SpanId::from_u64((inner.spans.len() + 1) as _); + inner.spans.insert(span.metadata().name()); + id + } + + fn record(&self, _: &SpanId, _: &tracing::span::Record) {} + + fn record_follows_from(&self, _: &SpanId, _: &SpanId) {} + + fn event(&self, _: &tracing::Event) {} + + fn enter(&self, _: &SpanId) {} + + fn exit(&self, _: &SpanId) {} + } + + let subscriber = TracingSubscriber(Default::default()); + let _guard = tracing::subscriber::set_default(subscriber.clone()); + + // Call some method to generate a trace + call_wasm_method::(&WASM_BINARY[..], "test_return_data"); + + let inner = subscriber.0.lock().unwrap(); + assert!(inner.spans.contains("return_input_version_1")); + assert!(inner.spans.contains("ext_test_api_return_input_version_1")); +} diff --git a/primitives/tracing/Cargo.toml b/primitives/tracing/Cargo.toml new file mode 100644 index 0000000000..8eb3bc2bea --- /dev/null +++ b/primitives/tracing/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "sp-tracing" +version = "2.0.0-dev" +license = "GPL-3.0" +authors = ["Parity Technologies "] +edition = "2018" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "Instrumentation primitives and macros for Substrate." + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +tracing = { version = "0.1.13", optional = true } + +[features] +default = [ "std" ] +std = [ "tracing" ] diff --git a/primitives/tracing/src/lib.rs b/primitives/tracing/src/lib.rs new file mode 100644 index 0000000000..e5bc93cf9e --- /dev/null +++ b/primitives/tracing/src/lib.rs @@ -0,0 +1,84 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate tracing primitives and macros. +//! +//! To trace functions or invidual code in Substrate, this crate provides [`tracing_span`] +//! and [`enter_span`]. See the individual docs for how to use these macros. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "std")] +#[doc(hidden)] +pub use tracing; + +/// Runs given code within a tracing span, measuring it's execution time. +/// +/// If tracing is not enabled, the code is still executed. +/// +/// # Example +/// +/// ``` +/// sp_tracing::tracing_span! { +/// "test-span"; +/// 1 + 1; +/// // some other complex code +/// } +/// ``` +#[macro_export] +macro_rules! tracing_span { + ( + $name:expr; + $( $code:tt )* + ) => { + { + $crate::enter_span!($name); + $( $code )* + } + } +} + +/// Enter a span. +/// +/// The span will be valid, until the scope is left. +/// +/// # Example +/// +/// ``` +/// sp_tracing::enter_span!("test-span"); +/// ``` +#[macro_export] +macro_rules! enter_span { + ( $name:expr ) => { + let __tracing_span__ = $crate::if_tracing!( + $crate::tracing::span!($crate::tracing::Level::TRACE, $name) + ); + let __tracing_guard__ = $crate::if_tracing!(__tracing_span__.enter()); + } +} + +/// Generates the given code if the tracing dependency is enabled. +#[macro_export] +#[cfg(feature = "std")] +macro_rules! if_tracing { + ( $if:expr ) => {{ $if }} +} + +#[macro_export] +#[cfg(not(feature = "std"))] +macro_rules! if_tracing { + ( $if:expr ) => {{}} +} -- GitLab From 9207eda27cd2a58c3b482034b205988dde67928e Mon Sep 17 00:00:00 2001 From: Ashley Date: Mon, 20 Apr 2020 14:45:13 +0200 Subject: [PATCH 272/300] Add a crate to test the in-browser light client. (#4887) Co-Authored-By: Pierre Krieger --- .gitlab-ci.yml | 13 +++- Cargo.lock | 43 +++++++++++++ Cargo.toml | 1 + bin/node/browser-testing/Cargo.toml | 21 +++++++ bin/node/browser-testing/src/lib.rs | 84 +++++++++++++++++++++++++ bin/node/browser-testing/webdriver.json | 7 +++ bin/node/cli/src/browser.rs | 1 - 7 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 bin/node/browser-testing/Cargo.toml create mode 100644 bin/node/browser-testing/src/lib.rs create mode 100644 bin/node/browser-testing/webdriver.json diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a7cf6f2ed8..e5eba33e55 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -40,6 +40,9 @@ variables: # FIXME set to release CARGO_UNLEASH_INSTALL_PARAMS: "--version 1.0.0-alpha.10" CARGO_UNLEASH_PKG_DEF: "--skip node node-* pallet-template pallet-example pallet-example-* subkey chain-spec-builder sp-arithmetic-fuzzer" + CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER: "wasm-bindgen-test-runner" + WASM_BINDGEN_TEST_TIMEOUT: 120 + CHROMEDRIVER_ARGS: "--log-level=INFO --whitelisted-ips=127.0.0.1" .collect-artifacts: &collect-artifacts @@ -312,7 +315,6 @@ test-linux-stable-int: paths: - ${CI_COMMIT_SHORT_SHA}_int_failure.log - check-web-wasm: stage: test <<: *docker-env @@ -354,6 +356,15 @@ test-full-crypto-feature: #### stage: build +test-browser-node: + stage: build + <<: *docker-env + needs: + - job: check-web-wasm + artifacts: false + script: + - cargo +nightly test --target wasm32-unknown-unknown -p node-browser-testing -Z features=itarget + build-linux-substrate: &build-binary stage: build <<: *collect-artifacts diff --git a/Cargo.lock b/Cargo.lock index 078f0c6708..fd131ec18f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3372,6 +3372,23 @@ dependencies = [ "tempfile", ] +[[package]] +name = "node-browser-testing" +version = "2.0.0" +dependencies = [ + "futures 0.3.4", + "futures-timer 3.0.2", + "jsonrpc-core", + "libp2p", + "node-cli", + "sc-rpc-api", + "serde", + "serde_json", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", +] + [[package]] name = "node-cli" version = "2.0.0-dev" @@ -9075,6 +9092,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f" dependencies = [ "cfg-if", + "serde", + "serde_json", "wasm-bindgen-macro", ] @@ -9134,6 +9153,30 @@ version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639" +[[package]] +name = "wasm-bindgen-test" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648da3460c6d2aa04b715a936329e2e311180efe650b2127d6267f4193ccac14" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2f86cd78a2aa7b1fb4bb6ed854eccb7f9263089c79542dca1576a1518a8467" +dependencies = [ + "proc-macro2", + "quote 1.0.3", +] + [[package]] name = "wasm-gc-api" version = "0.1.11" diff --git a/Cargo.toml b/Cargo.toml index f5ecad013c..abb0cca39c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "bin/node-template/runtime", "bin/node-template/pallets/template", "bin/node/bench", + "bin/node/browser-testing", "bin/node/cli", "bin/node/executor", "bin/node/primitives", diff --git a/bin/node/browser-testing/Cargo.toml b/bin/node/browser-testing/Cargo.toml new file mode 100644 index 0000000000..4b8d08af90 --- /dev/null +++ b/bin/node/browser-testing/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "node-browser-testing" +version = "2.0.0" +authors = ["Parity Technologies "] +description = "Tests for the in-browser light client." +edition = "2018" +license = "GPL-3.0" + +[dependencies] +futures-timer = "3.0.2" +libp2p = { version = "0.18.0", default-features = false } +jsonrpc-core = "14.0.5" +serde = "1.0.106" +serde_json = "1.0.48" +wasm-bindgen = { version = "0.2.60", features = ["serde-serialize"] } +wasm-bindgen-futures = "0.4.10" +wasm-bindgen-test = "0.3.10" +futures = "0.3.4" + +node-cli = { path = "../cli", default-features = false, features = ["browser"] } +sc-rpc-api = { path = "../../../client/rpc-api" } diff --git a/bin/node/browser-testing/src/lib.rs b/bin/node/browser-testing/src/lib.rs new file mode 100644 index 0000000000..06038f90af --- /dev/null +++ b/bin/node/browser-testing/src/lib.rs @@ -0,0 +1,84 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! # Running +//! Running this test can be done with +//! ```text +//! wasm-pack test --firefox --release --headless bin/node/browser-testing +//! ``` +//! or (without `wasm-pack`) +//! ```text +//! CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasm-bindgen-test-runner WASM_BINDGEN_TEST_TIMEOUT=60 cargo test --target wasm32-unknown-unknown +//! ``` +//! For debug infomation, such as the informant, run without the `--headless` +//! flag and open a browser to the url that `wasm-pack test` outputs. +//! For more infomation see https://rustwasm.github.io/docs/wasm-pack/. + +use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure}; +use wasm_bindgen_futures::JsFuture; +use wasm_bindgen::JsValue; +use jsonrpc_core::types::{MethodCall, Success, Version, Params, Id}; +use serde::de::DeserializeOwned; +use futures_timer::Delay; +use std::time::Duration; +use futures::FutureExt; + +wasm_bindgen_test_configure!(run_in_browser); + +const CHAIN_SPEC: &str = include_str!("../../cli/res/flaming-fir.json"); + +fn rpc_call(method: &str) -> String { + serde_json::to_string(&MethodCall { + jsonrpc: Some(Version::V2), + method: method.into(), + params: Params::None, + id: Id::Num(1) + }).unwrap() +} + +fn deserialize_rpc_result(js_value: JsValue) -> T { + let string = js_value.as_string().unwrap(); + let value = serde_json::from_str::(&string).unwrap().result; + // We need to convert a `Value::Object` into a proper type. + let value_string = serde_json::to_string(&value).unwrap(); + serde_json::from_str(&value_string).unwrap() +} + +#[wasm_bindgen_test] +async fn runs() { + let mut client = node_cli::start_client(CHAIN_SPEC.into(), "info".into()) + .await + .unwrap(); + + let mut test_timeout = Delay::new(Duration::from_secs(45)); + loop { + // Check that timeout hasn't expired. + assert!((&mut test_timeout).now_or_never().is_none(), "Test timed out."); + + // Let the node do a bit of work. + Delay::new(Duration::from_secs(5)).await; + + let state: sc_rpc_api::system::Health = deserialize_rpc_result( + JsFuture::from(client.rpc_send(&rpc_call("system_health"))) + .await + .unwrap() + ); + + if state.should_have_peers && state.peers > 0 && state.is_syncing { + break; + } + } +} diff --git a/bin/node/browser-testing/webdriver.json b/bin/node/browser-testing/webdriver.json new file mode 100644 index 0000000000..417ac35a7b --- /dev/null +++ b/bin/node/browser-testing/webdriver.json @@ -0,0 +1,7 @@ +{ + "goog:chromeOptions": { + "args": [ + "--whitelisted-ips=127.0.0.1" + ] + } +} diff --git a/bin/node/cli/src/browser.rs b/bin/node/cli/src/browser.rs index 6cd98dfe8d..8c4d964d95 100644 --- a/bin/node/cli/src/browser.rs +++ b/bin/node/cli/src/browser.rs @@ -17,7 +17,6 @@ use crate::chain_spec::ChainSpec; use log::info; use wasm_bindgen::prelude::*; -use sc_service::Configuration; use browser_utils::{ Client, browser_configuration, set_console_error_panic_hook, init_console_log, -- GitLab From 89c598442291cf9c8e6621bf004f8f5fa598870a Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 20 Apr 2020 15:05:20 +0200 Subject: [PATCH 273/300] Implement `try_mutate` for storage value and storage double map (#5699) * impl try_mutate for storage value and storage double map * Docs + Reuse `try_mutate` in `mutate` --- frame/support/src/dispatch.rs | 6 +-- frame/support/src/error.rs | 2 +- frame/support/src/lib.rs | 4 ++ .../src/storage/generator/double_map.rs | 18 +++++-- frame/support/src/storage/generator/map.rs | 22 ++------ frame/support/src/storage/generator/mod.rs | 52 +++++++++++++++++++ frame/support/src/storage/generator/value.rs | 19 +++++-- frame/support/src/storage/mod.rs | 26 ++++++++++ 8 files changed, 116 insertions(+), 33 deletions(-) diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index 4287f2c1ce..31e3efb001 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -46,10 +46,6 @@ pub type DispatchResult = Result<(), sp_runtime::DispatchError>; pub type DispatchErrorWithPostInfo = sp_runtime::DispatchErrorWithPostInfo; - -/// A type that cannot be instantiated. -pub enum Never {} - /// Serializable version of Dispatchable. /// This value can be used as a "function" in an extrinsic. pub trait Callable { @@ -1316,7 +1312,7 @@ macro_rules! decl_module { { #[doc(hidden)] #[codec(skip)] - __PhantomItem($crate::sp_std::marker::PhantomData<($trait_instance, $($instance)?)>, $crate::dispatch::Never), + __PhantomItem($crate::sp_std::marker::PhantomData<($trait_instance, $($instance)?)>, $crate::Never), $( $generated_variants )* } }; diff --git a/frame/support/src/error.rs b/frame/support/src/error.rs index a06f468892..2fdba88156 100644 --- a/frame/support/src/error.rs +++ b/frame/support/src/error.rs @@ -89,7 +89,7 @@ macro_rules! decl_error { #[doc(hidden)] __Ignore( $crate::sp_std::marker::PhantomData<($generic, $( $inst_generic)?)>, - $crate::dispatch::Never, + $crate::Never, ), $( $( #[doc = $doc_attr] )* diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 8a88496eda..49ad802d07 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -78,6 +78,10 @@ pub use self::storage::{ pub use self::dispatch::{Parameter, Callable, IsSubType}; pub use sp_runtime::{self, ConsensusEngineId, print, traits::Printable}; +/// A type that cannot be instantiated. +#[derive(Debug)] +pub enum Never {} + /// Macro for easily creating a new implementation of the `Get` trait. Use similarly to /// how you would declare a `const`: /// diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index e23b332383..c7e4c10017 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -17,7 +17,7 @@ use sp_std::prelude::*; use sp_std::borrow::Borrow; use codec::{Ref, FullCodec, FullEncode, Decode, Encode, EncodeLike, EncodeAppend}; -use crate::{storage::{self, unhashed}, traits::Len}; +use crate::{storage::{self, unhashed}, traits::Len, Never}; use crate::hash::{StorageHasher, Twox128, ReversibleStorageHasher}; /// Generator for `StorageDoubleMap` used by `decl_storage`. @@ -223,14 +223,24 @@ impl storage::StorageDoubleMap for G where KArg1: EncodeLike, KArg2: EncodeLike, F: FnOnce(&mut Self::Query) -> R, + { + Self::try_mutate(k1, k2, |v| Ok::(f(v))).expect("`Never` can not be constructed; qed") + } + + fn try_mutate(k1: KArg1, k2: KArg2, f: F) -> Result where + KArg1: EncodeLike, + KArg2: EncodeLike, + F: FnOnce(&mut Self::Query) -> Result, { let final_key = Self::storage_double_map_final_key(k1, k2); let mut val = G::from_optional_value_to_query(unhashed::get(final_key.as_ref())); let ret = f(&mut val); - match G::from_query_to_optional_value(val) { - Some(ref val) => unhashed::put(final_key.as_ref(), val), - None => unhashed::kill(final_key.as_ref()), + if ret.is_ok() { + match G::from_query_to_optional_value(val) { + Some(ref val) => unhashed::put(final_key.as_ref(), val), + None => unhashed::kill(final_key.as_ref()), + } } ret } diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index c29a9a223a..cc871072f5 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -18,7 +18,7 @@ use sp_std::prelude::*; use sp_std::borrow::Borrow; use codec::{FullCodec, FullEncode, Decode, Encode, EncodeLike, Ref, EncodeAppend}; -use crate::{storage::{self, unhashed}, traits::Len}; +use crate::{storage::{self, unhashed}, traits::Len, Never}; use crate::hash::{StorageHasher, Twox128, ReversibleStorageHasher}; /// Generator for `StorageMap` used by `decl_storage`. @@ -229,27 +229,11 @@ impl> storage::StorageMap } fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R { - let final_key = Self::storage_map_final_key(key); - let mut val = G::from_optional_value_to_query(unhashed::get(final_key.as_ref())); - - let ret = f(&mut val); - match G::from_query_to_optional_value(val) { - Some(ref val) => unhashed::put(final_key.as_ref(), &val), - None => unhashed::kill(final_key.as_ref()), - } - ret + Self::try_mutate(key, |v| Ok::(f(v))).expect("`Never` can not be constructed; qed") } fn mutate_exists, R, F: FnOnce(&mut Option) -> R>(key: KeyArg, f: F) -> R { - let final_key = Self::storage_map_final_key(key); - let mut val = unhashed::get(final_key.as_ref()); - - let ret = f(&mut val); - match val { - Some(ref val) => unhashed::put(final_key.as_ref(), &val), - None => unhashed::kill(final_key.as_ref()), - } - ret + Self::try_mutate_exists(key, |v| Ok::(f(v))).expect("`Never` can not be constructed; qed") } fn try_mutate, R, E, F: FnOnce(&mut Self::Query) -> Result>( diff --git a/frame/support/src/storage/generator/mod.rs b/frame/support/src/storage/generator/mod.rs index 687d8a3c93..07e75055f3 100644 --- a/frame/support/src/storage/generator/mod.rs +++ b/frame/support/src/storage/generator/mod.rs @@ -37,6 +37,7 @@ mod tests { use sp_io::TestExternalities; use codec::Encode; use crate::storage::{unhashed, generator::StorageValue, IterableStorageMap}; + use crate::{assert_noop, assert_ok}; struct Runtime {} pub trait Trait { @@ -57,6 +58,7 @@ mod tests { trait Store for Module as Runtime { Value get(fn value) config(): (u64, u64); NumberMap: map hasher(identity) u32 => u64; + DoubleMap: double_map hasher(identity) u32, hasher(identity) u32 => u64; } } @@ -102,4 +104,54 @@ mod tests { ); }) } + + #[test] + fn try_mutate_works() { + let t = GenesisConfig::default().build_storage().unwrap(); + TestExternalities::new(t).execute_with(|| { + assert_eq!(Value::get(), (0, 0)); + assert_eq!(NumberMap::get(0), 0); + assert_eq!(DoubleMap::get(0, 0), 0); + + // `assert_noop` ensures that the state does not change + assert_noop!(Value::try_mutate(|value| -> Result<(), &'static str> { + *value = (2, 2); + Err("don't change value") + }), "don't change value"); + + assert_noop!(NumberMap::try_mutate(0, |value| -> Result<(), &'static str> { + *value = 4; + Err("don't change value") + }), "don't change value"); + + assert_noop!(DoubleMap::try_mutate(0, 0, |value| -> Result<(), &'static str> { + *value = 6; + Err("don't change value") + }), "don't change value"); + + // Showing this explicitly for clarity + assert_eq!(Value::get(), (0, 0)); + assert_eq!(NumberMap::get(0), 0); + assert_eq!(DoubleMap::get(0, 0), 0); + + assert_ok!(Value::try_mutate(|value| -> Result<(), &'static str> { + *value = (2, 2); + Ok(()) + })); + + assert_ok!(NumberMap::try_mutate(0, |value| -> Result<(), &'static str> { + *value = 4; + Ok(()) + })); + + assert_ok!(DoubleMap::try_mutate(0, 0, |value| -> Result<(), &'static str> { + *value = 6; + Ok(()) + })); + + assert_eq!(Value::get(), (2, 2)); + assert_eq!(NumberMap::get(0), 4); + assert_eq!(DoubleMap::get(0, 0), 6); + }); + } } diff --git a/frame/support/src/storage/generator/value.rs b/frame/support/src/storage/generator/value.rs index 9e26131f48..dd9bbded4b 100644 --- a/frame/support/src/storage/generator/value.rs +++ b/frame/support/src/storage/generator/value.rs @@ -17,7 +17,12 @@ #[cfg(not(feature = "std"))] use sp_std::prelude::*; use codec::{FullCodec, Encode, EncodeAppend, EncodeLike, Decode}; -use crate::{storage::{self, unhashed}, hash::{Twox128, StorageHasher}, traits::Len}; +use crate::{ + Never, + storage::{self, unhashed}, + hash::{Twox128, StorageHasher}, + traits::Len +}; /// Generator for `StorageValue` used by `decl_storage`. /// @@ -104,12 +109,18 @@ impl> storage::StorageValue for G { } fn mutate R>(f: F) -> R { + Self::try_mutate(|v| Ok::(f(v))).expect("`Never` can not be constructed; qed") + } + + fn try_mutate Result>(f: F) -> Result { let mut val = G::get(); let ret = f(&mut val); - match G::from_query_to_optional_value(val) { - Some(ref val) => G::put(val), - None => G::kill(), + if ret.is_ok() { + match G::from_query_to_optional_value(val) { + Some(ref val) => G::put(val), + None => G::kill(), + } } ret } diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 47201e22e6..3a811c20e3 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -80,6 +80,9 @@ pub trait StorageValue { /// Mutate the value fn mutate R>(f: F) -> R; + /// Mutate the value if closure returns `Ok` + fn try_mutate Result>(f: F) -> Result; + /// Clear the storage value. fn kill(); @@ -280,21 +283,25 @@ pub trait StorageDoubleMap { /// The type that get/take returns. type Query; + /// Get the storage key used to fetch a value corresponding to a specific key. fn hashed_key_for(k1: KArg1, k2: KArg2) -> Vec where KArg1: EncodeLike, KArg2: EncodeLike; + /// Does the value (explicitly) exist in storage? fn contains_key(k1: KArg1, k2: KArg2) -> bool where KArg1: EncodeLike, KArg2: EncodeLike; + /// Load the value associated with the given key from the double map. fn get(k1: KArg1, k2: KArg2) -> Self::Query where KArg1: EncodeLike, KArg2: EncodeLike; + /// Take a value from storage, removing it afterwards. fn take(k1: KArg1, k2: KArg2) -> Self::Query where KArg1: EncodeLike, @@ -308,28 +315,43 @@ pub trait StorageDoubleMap { YKArg1: EncodeLike, YKArg2: EncodeLike; + /// Store a value to be associated with the given keys from the double map. fn insert(k1: KArg1, k2: KArg2, val: VArg) where KArg1: EncodeLike, KArg2: EncodeLike, VArg: EncodeLike; + /// Remove the value under the given keys. fn remove(k1: KArg1, k2: KArg2) where KArg1: EncodeLike, KArg2: EncodeLike; + /// Remove all values under the first key. fn remove_prefix(k1: KArg1) where KArg1: ?Sized + EncodeLike; + /// Iterate over values that share the first key. fn iter_prefix_values(k1: KArg1) -> PrefixIterator where KArg1: ?Sized + EncodeLike; + /// Mutate the value under the given keys. fn mutate(k1: KArg1, k2: KArg2, f: F) -> R where KArg1: EncodeLike, KArg2: EncodeLike, F: FnOnce(&mut Self::Query) -> R; + /// Mutate the value under the given keys when the closure returns `Ok`. + fn try_mutate(k1: KArg1, k2: KArg2, f: F) -> Result + where + KArg1: EncodeLike, + KArg2: EncodeLike, + F: FnOnce(&mut Self::Query) -> Result; + + /// Append the given item to the value in the storage. + /// + /// `V` is required to implement `codec::EncodeAppend`. fn append( k1: KArg1, k2: KArg2, @@ -344,6 +366,10 @@ pub trait StorageDoubleMap { Items: IntoIterator, Items::IntoIter: ExactSizeIterator; + /// Safely append the given items to the value in the storage. If a codec error occurs, then the + /// old (presumably corrupt) value is replaced with the given `items`. + /// + /// `V` is required to implement `codec::EncodeAppend`. fn append_or_insert( k1: KArg1, k2: KArg2, -- GitLab From fc6e2a625d807509605c8e790ba3f5136236aa12 Mon Sep 17 00:00:00 2001 From: cheme Date: Mon, 20 Apr 2020 15:21:22 +0200 Subject: [PATCH 274/300] Child trie api changes BREAKING (#4857) Co-Authored-By: thiolliere --- Cargo.lock | 21 ++ bin/node/cli/res/flaming-fir.json | 2 +- bin/node/executor/tests/basic.rs | 12 +- bin/node/executor/tests/fees.rs | 2 +- client/api/src/backend.rs | 14 +- client/api/src/light.rs | 11 +- client/api/src/proof_provider.rs | 7 +- client/chain-spec/src/chain_spec.rs | 47 +-- client/db/src/bench.rs | 40 +-- client/db/src/changes_tries_storage.rs | 3 +- client/db/src/lib.rs | 53 ++- client/db/src/storage_cache.rs | 72 ++-- client/executor/src/integration_tests/mod.rs | 4 +- client/network/src/protocol.rs | 71 ++-- .../src/protocol/light_client_handler.rs | 80 ++--- client/network/src/protocol/message.rs | 5 - .../src/protocol/schema/light.v1.proto | 8 +- client/rpc-api/src/child_state/mod.rs | 69 ++++ client/rpc-api/src/lib.rs | 1 + client/rpc-api/src/state/mod.rs | 44 --- client/rpc/src/state/mod.rs | 212 ++++++------ client/rpc/src/state/state_full.rs | 143 ++++---- client/rpc/src/state/state_light.rs | 129 ++++--- client/rpc/src/state/tests.rs | 55 ++- client/service/src/builder.rs | 11 +- client/src/client.rs | 39 +-- client/src/in_mem.rs | 11 +- client/src/light/backend.rs | 37 +- client/src/light/fetcher.rs | 28 +- frame/contracts/src/account_db.rs | 13 +- frame/contracts/src/lib.rs | 39 +-- frame/contracts/src/rent.rs | 10 +- frame/contracts/src/tests.rs | 3 - frame/support/src/storage/child.rs | 195 +++++------ frame/support/test/tests/instance.rs | 2 +- frame/system/src/lib.rs | 2 +- primitives/externalities/src/lib.rs | 36 +- primitives/io/src/lib.rs | 275 +++++++-------- primitives/runtime/src/lib.rs | 8 +- primitives/state-machine/src/backend.rs | 70 ++-- primitives/state-machine/src/basic.rs | 98 +++--- .../state-machine/src/changes_trie/build.rs | 107 +++--- .../src/changes_trie/build_cache.rs | 15 +- .../src/changes_trie/changes_iterator.rs | 26 +- .../state-machine/src/changes_trie/input.rs | 5 +- .../state-machine/src/changes_trie/mod.rs | 3 +- .../state-machine/src/changes_trie/prune.rs | 3 +- .../state-machine/src/changes_trie/storage.rs | 5 +- primitives/state-machine/src/ext.rs | 157 ++++----- .../state-machine/src/in_memory_backend.rs | 86 +++-- primitives/state-machine/src/lib.rs | 58 ++-- .../state-machine/src/overlayed_changes.rs | 98 +++--- .../state-machine/src/proving_backend.rs | 65 ++-- primitives/state-machine/src/testing.rs | 10 +- primitives/state-machine/src/trie_backend.rs | 48 ++- .../state-machine/src/trie_backend_essence.rs | 58 ++-- primitives/storage/Cargo.toml | 1 + primitives/storage/src/lib.rs | 323 ++++++++++-------- primitives/trie/src/lib.rs | 10 +- test-utils/client/src/lib.rs | 18 +- test-utils/runtime/client/src/lib.rs | 21 +- test-utils/runtime/src/genesismap.rs | 4 +- test-utils/runtime/src/lib.rs | 22 +- test-utils/runtime/src/system.rs | 2 +- 64 files changed, 1493 insertions(+), 1634 deletions(-) create mode 100644 client/rpc-api/src/child_state/mod.rs diff --git a/Cargo.lock b/Cargo.lock index fd131ec18f..325d602c8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5536,6 +5536,26 @@ dependencies = [ "rust-argon2", ] +[[package]] +name = "ref-cast" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "077f197a31bfe7e4169145f9eca08d32705c6c6126c139c26793acdf163ac3ef" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c36eb52b69b87c9e3a07387f476c88fd0dba9a1713b38e56617ed66b45392c1f" +dependencies = [ + "proc-macro2", + "quote 1.0.3", + "syn 1.0.17", +] + [[package]] name = "regex" version = "1.3.6" @@ -7715,6 +7735,7 @@ name = "sp-storage" version = "2.0.0-dev" dependencies = [ "impl-serde 0.2.3", + "ref-cast", "serde", "sp-debug-derive", "sp-std", diff --git a/bin/node/cli/res/flaming-fir.json b/bin/node/cli/res/flaming-fir.json index 7ed98239b5..3612d7284f 100644 --- a/bin/node/cli/res/flaming-fir.json +++ b/bin/node/cli/res/flaming-fir.json @@ -134,7 +134,7 @@ "0x5f3e4907f716ac89b6347d15ececedca0b6a45321efae92aea15e0740ec7afe7": "0x00000000", "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade98e54094c2d5af8ae10b91e1288f4f59f2946d7738f2c509b7effd909e5e9ba0ad": "0x00" }, - "children": {} + "childrenDefault": {} } } } diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index 7fdf4e9c59..5b3d8f20e9 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -170,7 +170,7 @@ fn panic_execution_with_foreign_code_gives_error() { vec![0u8; 32] } ], - children: map![], + children_default: map![], }); let r = executor_call:: _>( @@ -206,7 +206,7 @@ fn bad_extrinsic_with_native_equivalent_code_gives_error() { vec![0u8; 32] } ], - children: map![], + children_default: map![], }); let r = executor_call:: _>( @@ -240,7 +240,7 @@ fn successful_execution_with_native_equivalent_code_gives_ok() { }, >::hashed_key_for(0) => vec![0u8; 32] ], - children: map![], + children_default: map![], }); let r = executor_call:: _>( @@ -282,7 +282,7 @@ fn successful_execution_with_foreign_code_gives_ok() { }, >::hashed_key_for(0) => vec![0u8; 32] ], - children: map![], + children_default: map![], }); let r = executor_call:: _>( @@ -704,7 +704,7 @@ fn panic_execution_gives_error() { }, >::hashed_key_for(0) => vec![0u8; 32] ], - children: map![], + children_default: map![], }); let r = executor_call:: _>( @@ -738,7 +738,7 @@ fn successful_execution_gives_ok() { }, >::hashed_key_for(0) => vec![0u8; 32] ], - children: map![], + children_default: map![], }); let r = executor_call:: _>( diff --git a/bin/node/executor/tests/fees.rs b/bin/node/executor/tests/fees.rs index 32fef3b326..91c58d68fc 100644 --- a/bin/node/executor/tests/fees.rs +++ b/bin/node/executor/tests/fees.rs @@ -143,7 +143,7 @@ fn transaction_fee_is_correct_ultimate() { }, >::hashed_key_for(0) => vec![0u8; 32] ], - children: map![], + children_default: map![], }); let tip = 1_000_000; diff --git a/client/api/src/backend.rs b/client/api/src/backend.rs index d10e62cc54..33a370c7cb 100644 --- a/client/api/src/backend.rs +++ b/client/api/src/backend.rs @@ -26,7 +26,7 @@ use sp_state_machine::{ ChangesTrieState, ChangesTrieStorage as StateChangesTrieStorage, ChangesTrieTransaction, StorageCollection, ChildStorageCollection, }; -use sp_storage::{StorageData, StorageKey, ChildInfo}; +use sp_storage::{StorageData, StorageKey, PrefixedStorageKey, ChildInfo}; use crate::{ blockchain::{ Backend as BlockchainBackend, well_known_cache_keys @@ -280,6 +280,7 @@ impl<'a, State, Block> Iterator for KeyIterator<'a, State, Block> where Some(StorageKey(next_key)) } } + /// Provides acess to storage primitives pub trait StorageProvider> { /// Given a `BlockId` and a key, return the value under the key in that block. @@ -310,8 +311,7 @@ pub trait StorageProvider> { fn child_storage( &self, id: &BlockId, - storage_key: &StorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &StorageKey ) -> sp_blockchain::Result>; @@ -319,8 +319,7 @@ pub trait StorageProvider> { fn child_storage_keys( &self, id: &BlockId, - child_storage_key: &StorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key_prefix: &StorageKey ) -> sp_blockchain::Result>; @@ -328,8 +327,7 @@ pub trait StorageProvider> { fn child_storage_hash( &self, id: &BlockId, - storage_key: &StorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &StorageKey ) -> sp_blockchain::Result>; @@ -351,7 +349,7 @@ pub trait StorageProvider> { &self, first: NumberFor, last: BlockId, - storage_key: Option<&StorageKey>, + storage_key: Option<&PrefixedStorageKey>, key: &StorageKey ) -> sp_blockchain::Result, u32)>>; } diff --git a/client/api/src/light.rs b/client/api/src/light.rs index c0bebc1740..30e6d14d55 100644 --- a/client/api/src/light.rs +++ b/client/api/src/light.rs @@ -26,7 +26,7 @@ use sp_runtime::{ }, generic::BlockId }; -use sp_core::ChangesTrieConfigurationRange; +use sp_core::{ChangesTrieConfigurationRange, storage::PrefixedStorageKey}; use sp_state_machine::StorageProof; use sp_blockchain::{ HeaderMetadata, well_known_cache_keys, HeaderBackend, Cache as BlockchainCache, @@ -81,12 +81,7 @@ pub struct RemoteReadChildRequest { /// Header of block at which read is performed. pub header: Header, /// Storage key for child. - pub storage_key: Vec, - /// Child trie source information. - pub child_info: Vec, - /// Child type, its required to resolve `child_info` - /// content and choose child implementation. - pub child_type: u32, + pub storage_key: PrefixedStorageKey, /// Child storage key to read. pub keys: Vec>, /// Number of times to retry request. None means that default RETRY_COUNT is used. @@ -110,7 +105,7 @@ pub struct RemoteChangesRequest { /// Proofs for roots of ascendants of tries_roots.0 are provided by the remote node. pub tries_roots: (Header::Number, Header::Hash, Vec), /// Optional Child Storage key to read. - pub storage_key: Option>, + pub storage_key: Option, /// Storage key to read. pub key: Vec, /// Number of times to retry request. None means that default RETRY_COUNT is used. diff --git a/client/api/src/proof_provider.rs b/client/api/src/proof_provider.rs index 2d9876f7ad..93160855ea 100644 --- a/client/api/src/proof_provider.rs +++ b/client/api/src/proof_provider.rs @@ -19,7 +19,7 @@ use sp_runtime::{ traits::{Block as BlockT}, }; use crate::{StorageProof, ChangesProof}; -use sp_storage::{ChildInfo, StorageKey}; +use sp_storage::{ChildInfo, StorageKey, PrefixedStorageKey}; /// Interface for providing block proving utilities. pub trait ProofProvider { @@ -35,8 +35,7 @@ pub trait ProofProvider { fn read_child_proof( &self, id: &BlockId, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, keys: &mut dyn Iterator, ) -> sp_blockchain::Result; @@ -65,7 +64,7 @@ pub trait ProofProvider { last: Block::Hash, min: Block::Hash, max: Block::Hash, - storage_key: Option<&StorageKey>, + storage_key: Option<&PrefixedStorageKey>, key: &StorageKey, ) -> sp_blockchain::Result>; } diff --git a/client/chain-spec/src/chain_spec.rs b/client/chain-spec/src/chain_spec.rs index 9f3a10ee89..fbe7b7e7a8 100644 --- a/client/chain-spec/src/chain_spec.rs +++ b/client/chain-spec/src/chain_spec.rs @@ -74,17 +74,14 @@ impl BuildStorage for ChainSpec { fn build_storage(&self) -> Result { match self.genesis.resolve()? { Genesis::Runtime(gc) => gc.build_storage(), - Genesis::Raw(RawGenesis { top: map, children: children_map }) => Ok(Storage { + Genesis::Raw(RawGenesis { top: map, children_default: children_map }) => Ok(Storage { top: map.into_iter().map(|(k, v)| (k.0, v.0)).collect(), - children: children_map.into_iter().map(|(sk, child_content)| { - let child_info = ChildInfo::resolve_child_info( - child_content.child_type, - child_content.child_info.as_slice(), - ).expect("chain spec contains correct content").to_owned(); + children_default: children_map.into_iter().map(|(storage_key, child_content)| { + let child_info = ChildInfo::new_default(storage_key.0.as_slice()); ( - sk.0, + storage_key.0, StorageChild { - data: child_content.data.into_iter().map(|(k, v)| (k.0, v.0)).collect(), + data: child_content.into_iter().map(|(k, v)| (k.0, v.0)).collect(), child_info, }, ) @@ -103,22 +100,13 @@ impl BuildStorage for ChainSpec { type GenesisStorage = HashMap; -#[derive(Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -#[serde(deny_unknown_fields)] -struct ChildRawStorage { - data: GenesisStorage, - child_info: Vec, - child_type: u32, -} - #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] #[serde(deny_unknown_fields)] /// Storage content for genesis block. struct RawGenesis { top: GenesisStorage, - children: HashMap, + children_default: HashMap, } #[derive(Serialize, Deserialize)] @@ -291,23 +279,16 @@ impl ChainSpec { let top = storage.top.into_iter() .map(|(k, v)| (StorageKey(k), StorageData(v))) .collect(); - let children = storage.children.into_iter() - .map(|(sk, child)| { - let info = child.child_info.as_ref(); - let (info, ci_type) = info.info(); - ( - StorageKey(sk), - ChildRawStorage { - data: child.data.into_iter() - .map(|(k, v)| (StorageKey(k), StorageData(v))) - .collect(), - child_info: info.to_vec(), - child_type: ci_type, - }, - )}) + let children_default = storage.children_default.into_iter() + .map(|(sk, child)| ( + StorageKey(sk), + child.data.into_iter() + .map(|(k, v)| (StorageKey(k), StorageData(v))) + .collect(), + )) .collect(); - Genesis::Raw(RawGenesis { top, children }) + Genesis::Raw(RawGenesis { top, children_default }) }, (_, genesis) => genesis, }; diff --git a/client/db/src/bench.rs b/client/db/src/bench.rs index ddac2109d7..9d6f595498 100644 --- a/client/db/src/bench.rs +++ b/client/db/src/bench.rs @@ -77,10 +77,9 @@ impl BenchmarkingState { }; state.reopen()?; - let child_delta = genesis.children.into_iter().map(|(storage_key, child_content)| ( - storage_key, + let child_delta = genesis.children_default.into_iter().map(|(_storage_key, child_content)| ( + child_content.child_info, child_content.data.into_iter().map(|(k, v)| (k, Some(v))), - child_content.child_info )); let (root, transaction): (B::Hash, _) = state.state.borrow_mut().as_mut().unwrap().full_storage_root( genesis.top.into_iter().map(|(k, v)| (k, Some(v))), @@ -129,11 +128,10 @@ impl StateBackend> for BenchmarkingState { fn child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result>, Self::Error> { - self.state.borrow().as_ref().ok_or_else(state_err)?.child_storage(storage_key, child_info, key) + self.state.borrow().as_ref().ok_or_else(state_err)?.child_storage(child_info, key) } fn exists_storage(&self, key: &[u8]) -> Result { @@ -142,11 +140,10 @@ impl StateBackend> for BenchmarkingState { fn exists_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result { - self.state.borrow().as_ref().ok_or_else(state_err)?.exists_child_storage(storage_key, child_info, key) + self.state.borrow().as_ref().ok_or_else(state_err)?.exists_child_storage(child_info, key) } fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { @@ -155,11 +152,10 @@ impl StateBackend> for BenchmarkingState { fn next_child_storage_key( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result>, Self::Error> { - self.state.borrow().as_ref().ok_or_else(state_err)?.next_child_storage_key(storage_key, child_info, key) + self.state.borrow().as_ref().ok_or_else(state_err)?.next_child_storage_key(child_info, key) } fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { @@ -176,24 +172,22 @@ impl StateBackend> for BenchmarkingState { fn for_keys_in_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, f: F, ) { if let Some(ref state) = *self.state.borrow() { - state.for_keys_in_child_storage(storage_key, child_info, f) + state.for_keys_in_child_storage(child_info, f) } } fn for_child_keys_with_prefix( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], f: F, ) { if let Some(ref state) = *self.state.borrow() { - state.for_child_keys_with_prefix(storage_key, child_info, prefix, f) + state.for_child_keys_with_prefix(child_info, prefix, f) } } @@ -205,13 +199,12 @@ impl StateBackend> for BenchmarkingState { fn child_storage_root( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, delta: I, ) -> (B::Hash, bool, Self::Transaction) where I: IntoIterator, Option>)>, { - self.state.borrow().as_ref().map_or(Default::default(), |s| s.child_storage_root(storage_key, child_info, delta)) + self.state.borrow().as_ref().map_or(Default::default(), |s| s.child_storage_root(child_info, delta)) } fn pairs(&self) -> Vec<(Vec, Vec)> { @@ -224,11 +217,10 @@ impl StateBackend> for BenchmarkingState { fn child_keys( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], ) -> Vec> { - self.state.borrow().as_ref().map_or(Default::default(), |s| s.child_keys(storage_key, child_info, prefix)) + self.state.borrow().as_ref().map_or(Default::default(), |s| s.child_keys(child_info, prefix)) } fn as_trie_backend(&mut self) diff --git a/client/db/src/changes_tries_storage.rs b/client/db/src/changes_tries_storage.rs index 5447e8b725..985251f403 100644 --- a/client/db/src/changes_tries_storage.rs +++ b/client/db/src/changes_tries_storage.rs @@ -26,6 +26,7 @@ use sp_trie::MemoryDB; use sc_client_api::backend::PrunableStateChangesTrieStorage; use sp_blockchain::{well_known_cache_keys, Cache as BlockchainCache}; use sp_core::{ChangesTrieConfiguration, ChangesTrieConfigurationRange, convert_hash}; +use sp_core::storage::PrefixedStorageKey; use sp_database::Transaction; use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, HashFor, NumberFor, One, Zero, CheckedSub, @@ -482,7 +483,7 @@ where fn with_cached_changed_keys( &self, root: &Block::Hash, - functor: &mut dyn FnMut(&HashMap>, HashSet>>), + functor: &mut dyn FnMut(&HashMap, HashSet>>), ) -> bool { self.build_cache.read().with_changed_keys(root, functor) } diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 782e0f6db2..579ea2db4a 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -159,11 +159,10 @@ impl StateBackend> for RefTrackingState { fn child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result>, Self::Error> { - self.state.child_storage(storage_key, child_info, key) + self.state.child_storage(child_info, key) } fn exists_storage(&self, key: &[u8]) -> Result { @@ -172,11 +171,10 @@ impl StateBackend> for RefTrackingState { fn exists_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result { - self.state.exists_child_storage(storage_key, child_info, key) + self.state.exists_child_storage(child_info, key) } fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { @@ -185,11 +183,10 @@ impl StateBackend> for RefTrackingState { fn next_child_storage_key( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result>, Self::Error> { - self.state.next_child_storage_key(storage_key, child_info, key) + self.state.next_child_storage_key(child_info, key) } fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { @@ -202,21 +199,19 @@ impl StateBackend> for RefTrackingState { fn for_keys_in_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, f: F, ) { - self.state.for_keys_in_child_storage(storage_key, child_info, f) + self.state.for_keys_in_child_storage(child_info, f) } fn for_child_keys_with_prefix( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], f: F, ) { - self.state.for_child_keys_with_prefix(storage_key, child_info, prefix, f) + self.state.for_child_keys_with_prefix(child_info, prefix, f) } fn storage_root(&self, delta: I) -> (B::Hash, Self::Transaction) @@ -228,14 +223,13 @@ impl StateBackend> for RefTrackingState { fn child_storage_root( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, delta: I, ) -> (B::Hash, bool, Self::Transaction) where I: IntoIterator, Option>)>, { - self.state.child_storage_root(storage_key, child_info, delta) + self.state.child_storage_root(child_info, delta) } fn pairs(&self) -> Vec<(Vec, Vec)> { @@ -248,11 +242,10 @@ impl StateBackend> for RefTrackingState { fn child_keys( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], ) -> Vec> { - self.state.child_keys(storage_key, child_info, prefix) + self.state.child_keys(child_info, prefix) } fn as_trie_backend(&mut self) @@ -631,16 +624,10 @@ impl sc_client_api::backend::BlockImportOperation for Bloc return Err(sp_blockchain::Error::GenesisInvalid.into()); } - for child_key in storage.children.keys() { - if !well_known_keys::is_child_storage_key(&child_key) { - return Err(sp_blockchain::Error::GenesisInvalid.into()); - } - } - - let child_delta = storage.children.into_iter().map(|(storage_key, child_content)| ( - storage_key, - child_content.data.into_iter().map(|(k, v)| (k, Some(v))), child_content.child_info), - ); + let child_delta = storage.children_default.into_iter().map(|(_storage_key, child_content)|( + child_content.child_info, + child_content.data.into_iter().map(|(k, v)| (k, Some(v))), + )); let mut changes_trie_config: Option = None; let (root, transaction) = self.old_state.full_storage_root( @@ -1808,7 +1795,7 @@ pub(crate) mod tests { op.reset_storage(Storage { top: storage.iter().cloned().collect(), - children: Default::default(), + children_default: Default::default(), }).unwrap(); op.set_block_data( header.clone(), @@ -1894,7 +1881,7 @@ pub(crate) mod tests { op.reset_storage(Storage { top: storage.iter().cloned().collect(), - children: Default::default(), + children_default: Default::default(), }).unwrap(); key = op.db_updates.insert(EMPTY_PREFIX, b"hello"); diff --git a/client/db/src/storage_cache.rs b/client/db/src/storage_cache.rs index 6326899263..66ac74afa4 100644 --- a/client/db/src/storage_cache.rs +++ b/client/db/src/storage_cache.rs @@ -542,11 +542,10 @@ impl>, B: BlockT> StateBackend> for Cachin fn child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result>, Self::Error> { - let key = (storage_key.to_vec(), key.to_vec()); + let key = (child_info.storage_key().to_vec(), key.to_vec()); let local_cache = self.cache.local_cache.upgradable_read(); if let Some(entry) = local_cache.child_storage.get(&key).cloned() { trace!("Found in local cache: {:?}", key); @@ -564,7 +563,7 @@ impl>, B: BlockT> StateBackend> for Cachin } } trace!("Cache miss: {:?}", key); - let value = self.state.child_storage(storage_key, child_info, &key.1[..])?; + let value = self.state.child_storage(child_info, &key.1[..])?; // just pass it through the usage counter let value = self.usage.tally_child_key_read(&key, value, false); @@ -579,20 +578,18 @@ impl>, B: BlockT> StateBackend> for Cachin fn exists_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result { - self.state.exists_child_storage(storage_key, child_info, key) + self.state.exists_child_storage(child_info, key) } fn for_keys_in_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, f: F, ) { - self.state.for_keys_in_child_storage(storage_key, child_info, f) + self.state.for_keys_in_child_storage(child_info, f) } fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { @@ -601,11 +598,10 @@ impl>, B: BlockT> StateBackend> for Cachin fn next_child_storage_key( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result>, Self::Error> { - self.state.next_child_storage_key(storage_key, child_info, key) + self.state.next_child_storage_key(child_info, key) } fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { @@ -618,12 +614,11 @@ impl>, B: BlockT> StateBackend> for Cachin fn for_child_keys_with_prefix( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], f: F, ) { - self.state.for_child_keys_with_prefix(storage_key, child_info, prefix, f) + self.state.for_child_keys_with_prefix(child_info, prefix, f) } fn storage_root(&self, delta: I) -> (B::Hash, Self::Transaction) @@ -635,14 +630,13 @@ impl>, B: BlockT> StateBackend> for Cachin fn child_storage_root( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, delta: I, ) -> (B::Hash, bool, Self::Transaction) where I: IntoIterator, Option>)>, { - self.state.child_storage_root(storage_key, child_info, delta) + self.state.child_storage_root(child_info, delta) } fn pairs(&self) -> Vec<(Vec, Vec)> { @@ -655,11 +649,10 @@ impl>, B: BlockT> StateBackend> for Cachin fn child_keys( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], ) -> Vec> { - self.state.child_keys(storage_key, child_info, prefix) + self.state.child_keys(child_info, prefix) } fn as_trie_backend(&mut self) -> Option<&TrieBackend>> { @@ -758,11 +751,10 @@ impl>, B: BlockT> StateBackend> for Syncin fn child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result>, Self::Error> { - self.caching_state().child_storage(storage_key, child_info, key) + self.caching_state().child_storage(child_info, key) } fn exists_storage(&self, key: &[u8]) -> Result { @@ -771,20 +763,18 @@ impl>, B: BlockT> StateBackend> for Syncin fn exists_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result { - self.caching_state().exists_child_storage(storage_key, child_info, key) + self.caching_state().exists_child_storage(child_info, key) } fn for_keys_in_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, f: F, ) { - self.caching_state().for_keys_in_child_storage(storage_key, child_info, f) + self.caching_state().for_keys_in_child_storage(child_info, f) } fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { @@ -793,11 +783,10 @@ impl>, B: BlockT> StateBackend> for Syncin fn next_child_storage_key( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result>, Self::Error> { - self.caching_state().next_child_storage_key(storage_key, child_info, key) + self.caching_state().next_child_storage_key(child_info, key) } fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { @@ -810,12 +799,11 @@ impl>, B: BlockT> StateBackend> for Syncin fn for_child_keys_with_prefix( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], f: F, ) { - self.caching_state().for_child_keys_with_prefix(storage_key, child_info, prefix, f) + self.caching_state().for_child_keys_with_prefix(child_info, prefix, f) } fn storage_root(&self, delta: I) -> (B::Hash, Self::Transaction) @@ -827,14 +815,13 @@ impl>, B: BlockT> StateBackend> for Syncin fn child_storage_root( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, delta: I, ) -> (B::Hash, bool, Self::Transaction) where I: IntoIterator, Option>)>, { - self.caching_state().child_storage_root(storage_key, child_info, delta) + self.caching_state().child_storage_root(child_info, delta) } fn pairs(&self) -> Vec<(Vec, Vec)> { @@ -847,11 +834,10 @@ impl>, B: BlockT> StateBackend> for Syncin fn child_keys( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], ) -> Vec> { - self.caching_state().child_keys(storage_key, child_info, prefix) + self.caching_state().child_keys(child_info, prefix) } fn as_trie_backend(&mut self) -> Option<&TrieBackend>> { diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index 72055b7788..e1ef18a085 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -186,7 +186,7 @@ fn storage_should_work(wasm_method: WasmExecutionMethod) { b"foo".to_vec() => b"bar".to_vec(), b"baz".to_vec() => b"bar".to_vec() ], - children: map![], + children_default: map![], }); assert_eq!(ext, expected); } @@ -220,7 +220,7 @@ fn clear_prefix_should_work(wasm_method: WasmExecutionMethod) { b"aab".to_vec() => b"2".to_vec(), b"bbb".to_vec() => b"5".to_vec() ], - children: map![], + children_default: map![], }); assert_eq!(expected, ext); } diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index f59a775216..6ad8259484 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -30,7 +30,7 @@ use libp2p::core::{ConnectedPoint, connection::{ConnectionId, ListenerId}}; use libp2p::swarm::{ProtocolsHandler, IntoProtocolsHandler}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use sp_core::{ - storage::{StorageKey, ChildInfo}, + storage::{StorageKey, PrefixedStorageKey, ChildInfo, ChildType}, hexdisplay::HexDisplay }; use sp_consensus::{ @@ -1522,37 +1522,28 @@ impl Protocol { trace!(target: "sync", "Remote read child request {} from {} ({} {} at {})", request.id, who, HexDisplay::from(&request.storage_key), keys_str(), request.block); - let proof = if let Some(child_info) = ChildInfo::resolve_child_info(request.child_type, &request.child_info[..]) { - match self.context_data.chain.read_child_proof( - &BlockId::Hash(request.block), - &request.storage_key, - child_info, - &mut request.keys.iter().map(AsRef::as_ref), - ) { - Ok(proof) => proof, - Err(error) => { - trace!(target: "sync", "Remote read child request {} from {} ({} {} at {}) failed with: {}", - request.id, - who, - HexDisplay::from(&request.storage_key), - keys_str(), - request.block, - error - ); - StorageProof::empty() - } + let prefixed_key = PrefixedStorageKey::new_ref(&request.storage_key); + let child_info = match ChildType::from_prefixed_key(prefixed_key) { + Some((ChildType::ParentKeyId, storage_key)) => Ok(ChildInfo::new_default(storage_key)), + None => Err("Invalid child storage key".into()), + }; + let proof = match child_info.and_then(|child_info| self.context_data.chain.read_child_proof( + &BlockId::Hash(request.block), + &child_info, + &mut request.keys.iter().map(AsRef::as_ref), + )) { + Ok(proof) => proof, + Err(error) => { + trace!(target: "sync", "Remote read child request {} from {} ({} {} at {}) failed with: {}", + request.id, + who, + HexDisplay::from(&request.storage_key), + keys_str(), + request.block, + error + ); + StorageProof::empty() } - } else { - trace!(target: "sync", "Remote read child request {} from {} ({} {} at {}) failed with: {}", - request.id, - who, - HexDisplay::from(&request.storage_key), - keys_str(), - request.block, - "invalid child info and type", - ); - - StorageProof::empty() }; self.send_message( &who, @@ -1610,14 +1601,16 @@ impl Protocol { request.first, request.last ); - let storage_key = request.storage_key.map(|sk| StorageKey(sk)); let key = StorageKey(request.key); + let prefixed_key = request.storage_key.as_ref() + .map(|storage_key| PrefixedStorageKey::new_ref(storage_key)); + let (first, last, min, max) = (request.first, request.last, request.min, request.max); let proof = match self.context_data.chain.key_changes_proof( - request.first, - request.last, - request.min, - request.max, - storage_key.as_ref(), + first, + last, + min, + max, + prefixed_key, &key, ) { Ok(proof) => proof, @@ -1625,8 +1618,8 @@ impl Protocol { trace!(target: "sync", "Remote changes proof request {} from {} for key {} ({}..{}) failed with: {}", request.id, who, - if let Some(sk) = storage_key { - format!("{} : {}", HexDisplay::from(&sk.0), HexDisplay::from(&key.0)) + if let Some(sk) = request.storage_key.as_ref() { + format!("{} : {}", HexDisplay::from(sk), HexDisplay::from(&key.0)) } else { HexDisplay::from(&key.0).to_string() }, diff --git a/client/network/src/protocol/light_client_handler.rs b/client/network/src/protocol/light_client_handler.rs index 85312b0803..f4e877d675 100644 --- a/client/network/src/protocol/light_client_handler.rs +++ b/client/network/src/protocol/light_client_handler.rs @@ -58,7 +58,7 @@ use sc_client::light::fetcher; use sc_client_api::StorageProof; use sc_peerset::ReputationChange; use sp_core::{ - storage::{ChildInfo, StorageKey}, + storage::{ChildInfo, ChildType,StorageKey, PrefixedStorageKey}, hexdisplay::HexDisplay, }; use smallvec::SmallVec; @@ -617,35 +617,27 @@ where let block = Decode::decode(&mut request.block.as_ref())?; - let proof = - if let Some(info) = ChildInfo::resolve_child_info(request.child_type, &request.child_info[..]) { - match self.chain.read_child_proof( - &BlockId::Hash(block), - &request.storage_key, - info, - &mut request.keys.iter().map(AsRef::as_ref) - ) { - Ok(proof) => proof, - Err(error) => { - log::trace!("remote read child request from {} ({} {} at {:?}) failed with: {}", - peer, - HexDisplay::from(&request.storage_key), - fmt_keys(request.keys.first(), request.keys.last()), - request.block, - error); - StorageProof::empty() - } - } - } else { + let prefixed_key = PrefixedStorageKey::new_ref(&request.storage_key); + let child_info = match ChildType::from_prefixed_key(prefixed_key) { + Some((ChildType::ParentKeyId, storage_key)) => Ok(ChildInfo::new_default(storage_key)), + None => Err("Invalid child storage key".into()), + }; + let proof = match child_info.and_then(|child_info| self.chain.read_child_proof( + &BlockId::Hash(block), + &child_info, + &mut request.keys.iter().map(AsRef::as_ref) + )) { + Ok(proof) => proof, + Err(error) => { log::trace!("remote read child request from {} ({} {} at {:?}) failed with: {}", peer, HexDisplay::from(&request.storage_key), fmt_keys(request.keys.first(), request.keys.last()), request.block, - "invalid child info and type" - ); + error); StorageProof::empty() - }; + } + }; let response = { let r = api::v1::light::RemoteReadResponse { proof: proof.encode() }; @@ -704,23 +696,18 @@ where let min = Decode::decode(&mut request.min.as_ref())?; let max = Decode::decode(&mut request.max.as_ref())?; let key = StorageKey(request.key.clone()); - let storage_key = - if request.storage_key.is_empty() { - None - } else { - Some(StorageKey(request.storage_key.clone())) - }; + let storage_key = if request.storage_key.is_empty() { + None + } else { + Some(PrefixedStorageKey::new_ref(&request.storage_key)) + }; - let proof = match self.chain.key_changes_proof(first, last, min, max, storage_key.as_ref(), &key) { + let proof = match self.chain.key_changes_proof(first, last, min, max, storage_key, &key) { Ok(proof) => proof, Err(error) => { log::trace!("remote changes proof request from {} for key {} ({:?}..{:?}) failed with: {}", peer, - if let Some(sk) = storage_key { - format!("{} : {}", HexDisplay::from(&sk.0), HexDisplay::from(&key.0)) - } else { - HexDisplay::from(&key.0).to_string() - }, + format!("{} : {}", HexDisplay::from(&request.storage_key), HexDisplay::from(&key.0)), request.first, request.last, error); @@ -1092,9 +1079,7 @@ fn serialize_request(request: &Request) -> Result, prost::E Request::ReadChild { request, .. } => { let r = api::v1::light::RemoteReadChildRequest { block: request.block.encode(), - storage_key: request.storage_key.clone(), - child_type: request.child_type.clone(), - child_info: request.child_info.clone(), + storage_key: request.storage_key.clone().into_inner(), keys: request.keys.clone(), }; api::v1::light::request::Request::RemoteReadChildRequest(r) @@ -1113,7 +1098,8 @@ fn serialize_request(request: &Request) -> Result, prost::E last: request.last_block.1.encode(), min: request.tries_roots.1.encode(), max: request.max_block.1.encode(), - storage_key: request.storage_key.clone().unwrap_or_default(), + storage_key: request.storage_key.clone().map(|s| s.into_inner()) + .unwrap_or_default(), key: request.key.clone(), }; api::v1::light::request::Request::RemoteChangesRequest(r) @@ -1343,8 +1329,6 @@ mod tests { use super::{Event, LightClientHandler, Request, Response, OutboundProtocol, PeerStatus}; use void::Void; - const CHILD_INFO: ChildInfo<'static> = ChildInfo::new_default(b"foobarbaz"); - type Block = sp_runtime::generic::Block, substrate_test_runtime::Extrinsic>; type Handler = LightClientHandler; type Swarm = libp2p::swarm::Swarm; @@ -1894,15 +1878,13 @@ mod tests { #[test] fn receives_remote_read_child_response() { - let info = CHILD_INFO.info(); let mut chan = oneshot::channel(); + let child_info = ChildInfo::new_default(&b":child_storage:default:sub"[..]); let request = fetcher::RemoteReadChildRequest { header: dummy_header(), block: Default::default(), - storage_key: b":child_storage:sub".to_vec(), + storage_key: child_info.prefixed_storage_key(), keys: vec![b":key".to_vec()], - child_info: info.0.to_vec(), - child_type: info.1, retry_count: None, }; issue_request(Request::ReadChild { request, sender: chan.0 }); @@ -1997,15 +1979,13 @@ mod tests { #[test] fn send_receive_read_child() { - let info = CHILD_INFO.info(); let chan = oneshot::channel(); + let child_info = ChildInfo::new_default(&b":child_storage:default:sub"[..]); let request = fetcher::RemoteReadChildRequest { header: dummy_header(), block: Default::default(), - storage_key: b":child_storage:sub".to_vec(), + storage_key: child_info.prefixed_storage_key(), keys: vec![b":key".to_vec()], - child_info: info.0.to_vec(), - child_type: info.1, retry_count: None, }; send_receive(Request::ReadChild { request, sender: chan.0 }); diff --git a/client/network/src/protocol/message.rs b/client/network/src/protocol/message.rs index ae83b49e60..8638e9afc5 100644 --- a/client/network/src/protocol/message.rs +++ b/client/network/src/protocol/message.rs @@ -477,11 +477,6 @@ pub mod generic { pub block: H, /// Child Storage key. pub storage_key: Vec, - /// Child trie source information. - pub child_info: Vec, - /// Child type, its required to resolve `child_info` - /// content and choose child implementation. - pub child_type: u32, /// Storage key. pub keys: Vec>, } diff --git a/client/network/src/protocol/schema/light.v1.proto b/client/network/src/protocol/schema/light.v1.proto index 1c98d49730..9b5d47719d 100644 --- a/client/network/src/protocol/schema/light.v1.proto +++ b/client/network/src/protocol/schema/light.v1.proto @@ -67,13 +67,9 @@ message RemoteReadResponse { message RemoteReadChildRequest { // Block at which to perform call. bytes block = 2; - // Child Storage key. + // Child Storage key, this is relative + // to the child type storage location. bytes storage_key = 3; - // Child trie source information. - bytes child_info = 4; - /// Child type, its required to resolve `child_info` - /// content and choose child implementation. - uint32 child_type = 5; // Storage keys. repeated bytes keys = 6; } diff --git a/client/rpc-api/src/child_state/mod.rs b/client/rpc-api/src/child_state/mod.rs new file mode 100644 index 0000000000..a46269cad6 --- /dev/null +++ b/client/rpc-api/src/child_state/mod.rs @@ -0,0 +1,69 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate state API. + +use jsonrpc_derive::rpc; +use sp_core::storage::{StorageKey, PrefixedStorageKey, StorageData}; +use crate::state::error::FutureResult; + +pub use self::gen_client::Client as ChildStateClient; + +/// Substrate child state API +/// +/// Note that all `PrefixedStorageKey` are desierialized +/// from json and not guaranted valid. +#[rpc] +pub trait ChildStateApi { + /// RPC Metadata + type Metadata; + + /// Returns the keys with prefix from a child storage, leave empty to get all the keys + #[rpc(name = "childstate_getKeys")] + fn storage_keys( + &self, + child_storage_key: PrefixedStorageKey, + prefix: StorageKey, + hash: Option + ) -> FutureResult>; + + /// Returns a child storage entry at a specific block's state. + #[rpc(name = "childstate_getStorage")] + fn storage( + &self, + child_storage_key: PrefixedStorageKey, + key: StorageKey, + hash: Option + ) -> FutureResult>; + + /// Returns the hash of a child storage entry at a block's state. + #[rpc(name = "childstate_getStorageHash")] + fn storage_hash( + &self, + child_storage_key: PrefixedStorageKey, + key: StorageKey, + hash: Option + ) -> FutureResult>; + + /// Returns the size of a child storage entry at a block's state. + #[rpc(name = "childstate_getStorageSize")] + fn storage_size( + &self, + child_storage_key: PrefixedStorageKey, + key: StorageKey, + hash: Option + ) -> FutureResult>; +} diff --git a/client/rpc-api/src/lib.rs b/client/rpc-api/src/lib.rs index 2d541be2a7..f742d73b69 100644 --- a/client/rpc-api/src/lib.rs +++ b/client/rpc-api/src/lib.rs @@ -34,4 +34,5 @@ pub mod author; pub mod chain; pub mod offchain; pub mod state; +pub mod child_state; pub mod system; diff --git a/client/rpc-api/src/state/mod.rs b/client/rpc-api/src/state/mod.rs index d29e46a4b5..243a33c18d 100644 --- a/client/rpc-api/src/state/mod.rs +++ b/client/rpc-api/src/state/mod.rs @@ -72,50 +72,6 @@ pub trait StateApi { #[rpc(name = "state_getStorageSize", alias("state_getStorageSizeAt"))] fn storage_size(&self, key: StorageKey, hash: Option) -> FutureResult>; - /// Returns the keys with prefix from a child storage, leave empty to get all the keys - #[rpc(name = "state_getChildKeys")] - fn child_storage_keys( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - prefix: StorageKey, - hash: Option - ) -> FutureResult>; - - /// Returns a child storage entry at a specific block's state. - #[rpc(name = "state_getChildStorage")] - fn child_storage( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - hash: Option - ) -> FutureResult>; - - /// Returns the hash of a child storage entry at a block's state. - #[rpc(name = "state_getChildStorageHash")] - fn child_storage_hash( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - hash: Option - ) -> FutureResult>; - - /// Returns the size of a child storage entry at a block's state. - #[rpc(name = "state_getChildStorageSize")] - fn child_storage_size( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - hash: Option - ) -> FutureResult>; - /// Returns the runtime metadata as an opaque blob. #[rpc(name = "state_getMetadata")] fn metadata(&self, hash: Option) -> FutureResult; diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index 2747405c04..e696282433 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -28,7 +28,7 @@ use rpc::{Result as RpcResult, futures::{Future, future::result}}; use sc_rpc_api::Subscriptions; use sc_client::{light::{blockchain::RemoteBlockchain, fetcher::Fetcher}}; -use sp_core::{Bytes, storage::{StorageKey, StorageData, StorageChangeSet}}; +use sp_core::{Bytes, storage::{StorageKey, PrefixedStorageKey, StorageData, StorageChangeSet}}; use sp_version::RuntimeVersion; use sp_runtime::traits::Block as BlockT; @@ -37,6 +37,7 @@ use sp_api::{Metadata, ProvideRuntimeApi, CallApiAt}; use self::error::{Error, FutureResult}; pub use sc_rpc_api::state::*; +pub use sc_rpc_api::child_state::*; use sc_client_api::{ExecutorProvider, StorageProvider, BlockchainEvents, Backend}; use sp_blockchain::{HeaderMetadata, HeaderBackend}; @@ -103,49 +104,6 @@ pub trait StateBackend: Send + Sync + 'static .map(|x| x.map(|x| x.0.len() as u64))) } - /// Returns the keys with prefix from a child storage, leave empty to get all the keys - fn child_storage_keys( - &self, - block: Option, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - prefix: StorageKey, - ) -> FutureResult>; - - /// Returns a child storage entry at a specific block's state. - fn child_storage( - &self, - block: Option, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult>; - - /// Returns the hash of a child storage entry at a block's state. - fn child_storage_hash( - &self, - block: Option, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult>; - - /// Returns the size of a child storage entry at a block's state. - fn child_storage_size( - &self, - block: Option, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult> { - Box::new(self.child_storage(block, child_storage_key, child_info, child_type, key) - .map(|x| x.map(|x| x.0.len() as u64))) - } - /// Returns the runtime metadata as an opaque blob. fn metadata(&self, block: Option) -> FutureResult; @@ -204,7 +162,7 @@ pub trait StateBackend: Send + Sync + 'static pub fn new_full( client: Arc, subscriptions: Subscriptions, -) -> State +) -> (State, ChildState) where Block: BlockT + 'static, BE: Backend + 'static, @@ -214,9 +172,11 @@ pub fn new_full( + ProvideRuntimeApi + Send + Sync + 'static, Client::Api: Metadata, { - State { - backend: Box::new(self::state_full::FullState::new(client, subscriptions)), - } + let child_backend = Box::new( + self::state_full::FullState::new(client.clone(), subscriptions.clone()) + ); + let backend = Box::new(self::state_full::FullState::new(client, subscriptions)); + (State { backend }, ChildState { backend: child_backend }) } /// Create new state API that works on light node. @@ -225,7 +185,7 @@ pub fn new_light>( subscriptions: Subscriptions, remote_blockchain: Arc>, fetcher: Arc, -) -> State +) -> (State, ChildState) where Block: BlockT + 'static, BE: Backend + 'static, @@ -235,14 +195,20 @@ pub fn new_light>( + Send + Sync + 'static, F: Send + Sync + 'static, { - State { - backend: Box::new(self::state_light::LightState::new( + let child_backend = Box::new(self::state_light::LightState::new( + client.clone(), + subscriptions.clone(), + remote_blockchain.clone(), + fetcher.clone(), + )); + + let backend = Box::new(self::state_light::LightState::new( client, subscriptions, remote_blockchain, fetcher, - )), - } + )); + (State { backend }, ChildState { backend: child_backend }) } /// State API with subscriptions support. @@ -307,50 +273,6 @@ impl StateApi for State self.backend.storage_size(block, key) } - fn child_storage( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - block: Option - ) -> FutureResult> { - self.backend.child_storage(block, child_storage_key, child_info, child_type, key) - } - - fn child_storage_keys( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key_prefix: StorageKey, - block: Option - ) -> FutureResult> { - self.backend.child_storage_keys(block, child_storage_key, child_info, child_type, key_prefix) - } - - fn child_storage_hash( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - block: Option - ) -> FutureResult> { - self.backend.child_storage_hash(block, child_storage_key, child_info, child_type, key) - } - - fn child_storage_size( - &self, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - block: Option - ) -> FutureResult> { - self.backend.child_storage_size(block, child_storage_key, child_info, child_type, key) - } - fn metadata(&self, block: Option) -> FutureResult { self.backend.metadata(block) } @@ -402,12 +324,98 @@ impl StateApi for State } } -fn client_err(err: sp_blockchain::Error) -> Error { - Error::Client(Box::new(err)) +/// Child state backend API. +pub trait ChildStateBackend: Send + Sync + 'static + where + Block: BlockT + 'static, + Client: Send + Sync + 'static, +{ + /// Returns the keys with prefix from a child storage, + /// leave prefix empty to get all the keys. + fn storage_keys( + &self, + block: Option, + storage_key: PrefixedStorageKey, + prefix: StorageKey, + ) -> FutureResult>; + + /// Returns a child storage entry at a specific block's state. + fn storage( + &self, + block: Option, + storage_key: PrefixedStorageKey, + key: StorageKey, + ) -> FutureResult>; + + /// Returns the hash of a child storage entry at a block's state. + fn storage_hash( + &self, + block: Option, + storage_key: PrefixedStorageKey, + key: StorageKey, + ) -> FutureResult>; + + /// Returns the size of a child storage entry at a block's state. + fn storage_size( + &self, + block: Option, + storage_key: PrefixedStorageKey, + key: StorageKey, + ) -> FutureResult> { + Box::new(self.storage(block, storage_key, key) + .map(|x| x.map(|x| x.0.len() as u64))) + } } -const CHILD_RESOLUTION_ERROR: &str = "Unexpected child info and type"; +/// Child state API with subscriptions support. +pub struct ChildState { + backend: Box>, +} + +impl ChildStateApi for ChildState + where + Block: BlockT + 'static, + Client: Send + Sync + 'static, +{ + type Metadata = crate::metadata::Metadata; + + fn storage( + &self, + storage_key: PrefixedStorageKey, + key: StorageKey, + block: Option + ) -> FutureResult> { + self.backend.storage(block, storage_key, key) + } + + fn storage_keys( + &self, + storage_key: PrefixedStorageKey, + key_prefix: StorageKey, + block: Option + ) -> FutureResult> { + self.backend.storage_keys(block, storage_key, key_prefix) + } -fn child_resolution_error() -> sp_blockchain::Error { - sp_blockchain::Error::Msg(CHILD_RESOLUTION_ERROR.to_string()) + fn storage_hash( + &self, + storage_key: PrefixedStorageKey, + key: StorageKey, + block: Option + ) -> FutureResult> { + self.backend.storage_hash(block, storage_key, key) + } + + fn storage_size( + &self, + storage_key: PrefixedStorageKey, + key: StorageKey, + block: Option + ) -> FutureResult> { + self.backend.storage_size(block, storage_key, key) + } +} + +fn client_err(err: sp_blockchain::Error) -> Error { + Error::Client(Box::new(err)) } diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index bf80820543..a9767c34fc 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -29,7 +29,8 @@ use sc_client_api::backend::Backend; use sp_blockchain::{Result as ClientResult, Error as ClientError, HeaderMetadata, CachedHeaderMetadata, HeaderBackend}; use sc_client::BlockchainEvents; use sp_core::{ - Bytes, storage::{well_known_keys, StorageKey, StorageData, StorageChangeSet, ChildInfo}, + Bytes, storage::{well_known_keys, StorageKey, StorageData, StorageChangeSet, + ChildInfo, ChildType, PrefixedStorageKey}, }; use sp_version::RuntimeVersion; use sp_runtime::{ @@ -38,7 +39,7 @@ use sp_runtime::{ use sp_api::{Metadata, ProvideRuntimeApi, CallApiAt}; -use super::{StateBackend, error::{FutureResult, Error, Result}, client_err, child_resolution_error}; +use super::{StateBackend, ChildStateBackend, error::{FutureResult, Error, Result}, client_err}; use std::marker::PhantomData; use sc_client_api::{CallExecutor, StorageProvider, ExecutorProvider}; @@ -308,66 +309,6 @@ impl StateBackend for FullState, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - prefix: StorageKey, - ) -> FutureResult> { - Box::new(result( - self.block_or_best(block) - .and_then(|block| self.client.child_storage_keys( - &BlockId::Hash(block), - &child_storage_key, - ChildInfo::resolve_child_info(child_type, &child_info.0[..]) - .ok_or_else(child_resolution_error)?, - &prefix, - )) - .map_err(client_err))) - } - - fn child_storage( - &self, - block: Option, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult> { - Box::new(result( - self.block_or_best(block) - .and_then(|block| self.client.child_storage( - &BlockId::Hash(block), - &child_storage_key, - ChildInfo::resolve_child_info(child_type, &child_info.0[..]) - .ok_or_else(child_resolution_error)?, - &key, - )) - .map_err(client_err))) - } - - fn child_storage_hash( - &self, - block: Option, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult> { - Box::new(result( - self.block_or_best(block) - .and_then(|block| self.client.child_storage_hash( - &BlockId::Hash(block), - &child_storage_key, - ChildInfo::resolve_child_info(child_type, &child_info.0[..]) - .ok_or_else(child_resolution_error)?, - &key, - )) - .map_err(client_err))) - } - fn metadata(&self, block: Option) -> FutureResult { Box::new(result( self.block_or_best(block) @@ -493,7 +434,7 @@ impl StateBackend for FullState StateBackend for FullState ChildStateBackend for FullState where + Block: BlockT + 'static, + BE: Backend + 'static, + Client: ExecutorProvider + StorageProvider + HeaderBackend + + HeaderMetadata + BlockchainEvents + + CallApiAt + ProvideRuntimeApi + + Send + Sync + 'static, + Client::Api: Metadata, +{ + fn storage_keys( + &self, + block: Option, + storage_key: PrefixedStorageKey, + prefix: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| { + let child_info = match ChildType::from_prefixed_key(&storage_key) { + Some((ChildType::ParentKeyId, storage_key)) => ChildInfo::new_default(storage_key), + None => return Err("Invalid child storage key".into()), + }; + self.client.child_storage_keys( + &BlockId::Hash(block), + &child_info, + &prefix, + ) + }) + .map_err(client_err))) + } + + fn storage( + &self, + block: Option, + storage_key: PrefixedStorageKey, + key: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| { + let child_info = match ChildType::from_prefixed_key(&storage_key) { + Some((ChildType::ParentKeyId, storage_key)) => ChildInfo::new_default(storage_key), + None => return Err("Invalid child storage key".into()), + }; + self.client.child_storage( + &BlockId::Hash(block), + &child_info, + &key, + ) + }) + .map_err(client_err))) + } + + fn storage_hash( + &self, + block: Option, + storage_key: PrefixedStorageKey, + key: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| { + let child_info = match ChildType::from_prefixed_key(&storage_key) { + Some((ChildType::ParentKeyId, storage_key)) => ChildInfo::new_default(storage_key), + None => return Err("Invalid child storage key".into()), + }; + self.client.child_storage_hash( + &BlockId::Hash(block), + &child_info, + &key, + ) + }) + .map_err(client_err))) + } +} + /// Splits passed range into two subranges where: /// - first range has at least one element in it; /// - second range (optionally) starts at given `middle` element. diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index 092419ad01..27adbcd691 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -48,17 +48,19 @@ use sc_client::{ }, }; use sp_core::{ - Bytes, OpaqueMetadata, storage::{StorageKey, StorageData, StorageChangeSet}, + Bytes, OpaqueMetadata, + storage::{StorageKey, PrefixedStorageKey, StorageData, StorageChangeSet}, }; use sp_version::RuntimeVersion; use sp_runtime::{generic::BlockId, traits::{Block as BlockT, HashFor}}; -use super::{StateBackend, error::{FutureResult, Error}, client_err}; +use super::{StateBackend, ChildStateBackend, error::{FutureResult, Error}, client_err}; /// Storage data map of storage keys => (optional) storage value. type StorageMap = HashMap>; /// State API backend for light nodes. +#[derive(Clone)] pub struct LightState, Client> { client: Arc, subscriptions: Subscriptions, @@ -233,69 +235,7 @@ impl StateBackend for LightState, key: StorageKey, ) -> FutureResult> { - Box::new(self - .storage(block, key) - .and_then(|maybe_storage| - result(Ok(maybe_storage.map(|storage| HashFor::::hash(&storage.0)))) - ) - ) - } - - fn child_storage_keys( - &self, - _block: Option, - _child_storage_key: StorageKey, - _child_info: StorageKey, - _child_type: u32, - _prefix: StorageKey, - ) -> FutureResult> { - Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) - } - - fn child_storage( - &self, - block: Option, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult> { - let block = self.block_or_best(block); - let fetcher = self.fetcher.clone(); - let child_storage = resolve_header(&*self.remote_blockchain, &*self.fetcher, block) - .then(move |result| match result { - Ok(header) => Either::Left(fetcher.remote_read_child(RemoteReadChildRequest { - block, - header, - storage_key: child_storage_key.0, - child_info: child_info.0, - child_type, - keys: vec![key.0.clone()], - retry_count: Default::default(), - }).then(move |result| ready(result - .map(|mut data| data - .remove(&key.0) - .expect("successful result has entry for all keys; qed") - .map(StorageData) - ) - .map_err(client_err) - ))), - Err(error) => Either::Right(ready(Err(error))), - }); - - Box::new(child_storage.boxed().compat()) - } - - fn child_storage_hash( - &self, - block: Option, - child_storage_key: StorageKey, - child_info: StorageKey, - child_type: u32, - key: StorageKey, - ) -> FutureResult> { - Box::new(self - .child_storage(block, child_storage_key, child_info, child_type, key) + Box::new(StateBackend::storage(self, block, key) .and_then(|maybe_storage| result(Ok(maybe_storage.map(|storage| HashFor::::hash(&storage.0)))) ) @@ -518,6 +458,65 @@ impl StateBackend for LightState ChildStateBackend for LightState + where + Block: BlockT, + Client: BlockchainEvents + HeaderBackend + Send + Sync + 'static, + F: Fetcher + 'static +{ + fn storage_keys( + &self, + _block: Option, + _storage_key: PrefixedStorageKey, + _prefix: StorageKey, + ) -> FutureResult> { + Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) + } + + fn storage( + &self, + block: Option, + storage_key: PrefixedStorageKey, + key: StorageKey, + ) -> FutureResult> { + let block = self.block_or_best(block); + let fetcher = self.fetcher.clone(); + let child_storage = resolve_header(&*self.remote_blockchain, &*self.fetcher, block) + .then(move |result| match result { + Ok(header) => Either::Left(fetcher.remote_read_child(RemoteReadChildRequest { + block, + header, + storage_key, + keys: vec![key.0.clone()], + retry_count: Default::default(), + }).then(move |result| ready(result + .map(|mut data| data + .remove(&key.0) + .expect("successful result has entry for all keys; qed") + .map(StorageData) + ) + .map_err(client_err) + ))), + Err(error) => Either::Right(ready(Err(error))), + }); + + Box::new(child_storage.boxed().compat()) + } + + fn storage_hash( + &self, + block: Option, + storage_key: PrefixedStorageKey, + key: StorageKey, + ) -> FutureResult> { + Box::new(ChildStateBackend::storage(self, block, storage_key, key) + .and_then(|maybe_storage| + result(Ok(maybe_storage.map(|storage| HashFor::::hash(&storage.0)))) + ) + ) + } +} + /// Resolve header by hash. fn resolve_header>( remote_blockchain: &dyn RemoteBlockchain, diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index 0f2358a3ed..f9c6982929 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -21,7 +21,7 @@ use self::error::Error; use std::sync::Arc; use assert_matches::assert_matches; use futures01::stream::Stream; -use sp_core::{storage::{well_known_keys, ChildInfo}, ChangesTrieConfiguration}; +use sp_core::{storage::ChildInfo, ChangesTrieConfiguration}; use sp_core::hash::H256; use sc_block_builder::BlockBuilderProvider; use sp_io::hashing::blake2_256; @@ -32,26 +32,28 @@ use substrate_test_runtime_client::{ }; use sp_runtime::generic::BlockId; -const CHILD_INFO: ChildInfo<'static> = ChildInfo::new_default(b"unique_id"); +const STORAGE_KEY: &[u8] = b"child"; + +fn prefixed_storage_key() -> PrefixedStorageKey { + let child_info = ChildInfo::new_default(&STORAGE_KEY[..]); + child_info.prefixed_storage_key() +} #[test] fn should_return_storage() { const KEY: &[u8] = b":mock"; const VALUE: &[u8] = b"hello world"; - const STORAGE_KEY: &[u8] = b":child_storage:default:child"; const CHILD_VALUE: &[u8] = b"hello world !"; + let child_info = ChildInfo::new_default(STORAGE_KEY); let mut core = tokio::runtime::Runtime::new().unwrap(); let client = TestClientBuilder::new() .add_extra_storage(KEY.to_vec(), VALUE.to_vec()) - .add_extra_child_storage(STORAGE_KEY.to_vec(), CHILD_INFO, KEY.to_vec(), CHILD_VALUE.to_vec()) + .add_extra_child_storage(&child_info, KEY.to_vec(), CHILD_VALUE.to_vec()) .build(); let genesis_hash = client.genesis_hash(); - let client = new_full(Arc::new(client), Subscriptions::new(Arc::new(core.executor()))); + let (client, child) = new_full(Arc::new(client), Subscriptions::new(Arc::new(core.executor()))); let key = StorageKey(KEY.to_vec()); - let storage_key = StorageKey(STORAGE_KEY.to_vec()); - let (child_info, child_type) = CHILD_INFO.info(); - let child_info = StorageKey(child_info.to_vec()); assert_eq!( client.storage(key.clone(), Some(genesis_hash).into()).wait() @@ -69,7 +71,7 @@ fn should_return_storage() { ); assert_eq!( core.block_on( - client.child_storage(storage_key, child_info, child_type, key, Some(genesis_hash).into()) + child.storage(prefixed_storage_key(), key, Some(genesis_hash).into()) .map(|x| x.map(|x| x.0.len())) ).unwrap().unwrap() as usize, CHILD_VALUE.len(), @@ -79,45 +81,36 @@ fn should_return_storage() { #[test] fn should_return_child_storage() { - let (child_info, child_type) = CHILD_INFO.info(); - let child_info = StorageKey(child_info.to_vec()); + let child_info = ChildInfo::new_default(STORAGE_KEY); let core = tokio::runtime::Runtime::new().unwrap(); let client = Arc::new(substrate_test_runtime_client::TestClientBuilder::new() - .add_child_storage("test", "key", CHILD_INFO, vec![42_u8]) + .add_child_storage(&child_info, "key", vec![42_u8]) .build()); let genesis_hash = client.genesis_hash(); - let client = new_full(client, Subscriptions::new(Arc::new(core.executor()))); - let child_key = StorageKey( - well_known_keys::CHILD_STORAGE_KEY_PREFIX.iter().chain(b"test").cloned().collect() - ); + let (_client, child) = new_full(client, Subscriptions::new(Arc::new(core.executor()))); + let child_key = prefixed_storage_key(); let key = StorageKey(b"key".to_vec()); assert_matches!( - client.child_storage( + child.storage( child_key.clone(), - child_info.clone(), - child_type, key.clone(), Some(genesis_hash).into(), ).wait(), Ok(Some(StorageData(ref d))) if d[0] == 42 && d.len() == 1 ); assert_matches!( - client.child_storage_hash( + child.storage_hash( child_key.clone(), - child_info.clone(), - child_type, key.clone(), Some(genesis_hash).into(), ).wait().map(|x| x.is_some()), Ok(true) ); assert_matches!( - client.child_storage_size( + child.storage_size( child_key.clone(), - child_info.clone(), - child_type, key.clone(), None, ).wait(), @@ -130,7 +123,7 @@ fn should_call_contract() { let core = tokio::runtime::Runtime::new().unwrap(); let client = Arc::new(substrate_test_runtime_client::new()); let genesis_hash = client.genesis_hash(); - let client = new_full(client, Subscriptions::new(Arc::new(core.executor()))); + let (client, _child) = new_full(client, Subscriptions::new(Arc::new(core.executor()))); assert_matches!( client.call("balanceOf".into(), Bytes(vec![1,2,3]), Some(genesis_hash).into()).wait(), @@ -146,7 +139,7 @@ fn should_notify_about_storage_changes() { { let mut client = Arc::new(substrate_test_runtime_client::new()); - let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); + let (api, _child) = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); api.subscribe_storage(Default::default(), subscriber, None.into()); @@ -179,7 +172,7 @@ fn should_send_initial_storage_changes_and_notifications() { { let mut client = Arc::new(substrate_test_runtime_client::new()); - let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); + let (api, _child) = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); let alice_balance_key = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Alice.into())); @@ -215,7 +208,7 @@ fn should_send_initial_storage_changes_and_notifications() { fn should_query_storage() { fn run_tests(mut client: Arc, has_changes_trie_config: bool) { let core = tokio::runtime::Runtime::new().unwrap(); - let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); + let (api, _child) = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); let mut add_block = |nonce| { let mut builder = client.new_block(Default::default()).unwrap(); @@ -434,7 +427,7 @@ fn should_return_runtime_version() { let core = tokio::runtime::Runtime::new().unwrap(); let client = Arc::new(substrate_test_runtime_client::new()); - let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); + let (api, _child) = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); let result = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",3],\ @@ -458,7 +451,7 @@ fn should_notify_on_runtime_version_initially() { { let client = Arc::new(substrate_test_runtime_client::new()); - let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); + let (api, _child) = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); api.subscribe_runtime_version(Default::default(), subscriber); diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 200707dad4..1cdebe8b14 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -1015,7 +1015,7 @@ ServiceBuilder< let subscriptions = sc_rpc::Subscriptions::new(Arc::new(tasks_builder.spawn_handle())); - let (chain, state) = if let (Some(remote_backend), Some(on_demand)) = + let (chain, state, child_state) = if let (Some(remote_backend), Some(on_demand)) = (remote_backend.as_ref(), on_demand.as_ref()) { // Light clients let chain = sc_rpc::chain::new_light( @@ -1024,19 +1024,19 @@ ServiceBuilder< remote_backend.clone(), on_demand.clone() ); - let state = sc_rpc::state::new_light( + let (state, child_state) = sc_rpc::state::new_light( client.clone(), subscriptions.clone(), remote_backend.clone(), on_demand.clone() ); - (chain, state) + (chain, state, child_state) } else { // Full nodes let chain = sc_rpc::chain::new_full(client.clone(), subscriptions.clone()); - let state = sc_rpc::state::new_full(client.clone(), subscriptions.clone()); - (chain, state) + let (state, child_state) = sc_rpc::state::new_full(client.clone(), subscriptions.clone()); + (chain, state, child_state) }; let author = sc_rpc::author::Author::new( @@ -1059,6 +1059,7 @@ ServiceBuilder< sc_rpc_server::rpc_handler(( state::StateApi::to_delegate(state), + state::ChildStateApi::to_delegate(child_state), chain::ChainApi::to_delegate(chain), maybe_offchain_rpc, author::AuthorApi::to_delegate(author), diff --git a/client/src/client.rs b/client/src/client.rs index a71d6bf964..2a8040febf 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -25,8 +25,8 @@ use parking_lot::{Mutex, RwLock}; use codec::{Encode, Decode}; use hash_db::Prefix; use sp_core::{ - ChangesTrieConfiguration, convert_hash, traits::CodeExecutor, - NativeOrEncoded, storage::{StorageKey, StorageData, well_known_keys, ChildInfo}, + ChangesTrieConfiguration, convert_hash, traits::CodeExecutor, NativeOrEncoded, + storage::{StorageKey, PrefixedStorageKey, StorageData, well_known_keys, ChildInfo}, }; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; use sp_runtime::{ @@ -344,7 +344,7 @@ impl Client where last: Block::Hash, min: Block::Hash, max: Block::Hash, - storage_key: Option<&StorageKey>, + storage_key: Option<&PrefixedStorageKey>, key: &StorageKey, cht_size: NumberFor, ) -> sp_blockchain::Result> { @@ -393,7 +393,7 @@ impl Client where fn with_cached_changed_keys( &self, root: &Block::Hash, - functor: &mut dyn FnMut(&HashMap>, HashSet>>), + functor: &mut dyn FnMut(&HashMap, HashSet>>), ) -> bool { self.storage.with_cached_changed_keys(root, functor) } @@ -438,7 +438,7 @@ impl Client where number: last_number, }, max_number, - storage_key.as_ref().map(|x| &x.0[..]), + storage_key, &key.0, ) .map_err(|err| sp_blockchain::Error::ChangesTrieAccessFailed(err))?; @@ -1109,12 +1109,11 @@ impl ProofProvider for Client where fn read_child_proof( &self, id: &BlockId, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, keys: &mut dyn Iterator, ) -> sp_blockchain::Result { self.state_at(id) - .and_then(|state| prove_child_read(state, storage_key, child_info, keys) + .and_then(|state| prove_child_read(state, child_info, keys) .map_err(Into::into)) } @@ -1156,7 +1155,7 @@ impl ProofProvider for Client where last: Block::Hash, min: Block::Hash, max: Block::Hash, - storage_key: Option<&StorageKey>, + storage_key: Option<&PrefixedStorageKey>, key: &StorageKey, ) -> sp_blockchain::Result> { self.key_changes_proof_with_cht_size( @@ -1286,46 +1285,40 @@ impl StorageProvider for Client wher ) } - fn child_storage_keys( &self, id: &BlockId, - child_storage_key: &StorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key_prefix: &StorageKey ) -> sp_blockchain::Result> { let keys = self.state_at(id)? - .child_keys(&child_storage_key.0, child_info, &key_prefix.0) + .child_keys(child_info, &key_prefix.0) .into_iter() .map(StorageKey) .collect(); Ok(keys) } - fn child_storage( &self, id: &BlockId, - storage_key: &StorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &StorageKey ) -> sp_blockchain::Result> { Ok(self.state_at(id)? - .child_storage(&storage_key.0, child_info, &key.0) + .child_storage(child_info, &key.0) .map_err(|e| sp_blockchain::Error::from_state(Box::new(e)))? .map(StorageData)) } - fn child_storage_hash( &self, id: &BlockId, - storage_key: &StorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &StorageKey ) -> sp_blockchain::Result> { Ok(self.state_at(id)? - .child_storage_hash(&storage_key.0, child_info, &key.0) + .child_storage_hash(child_info, &key.0) .map_err(|e| sp_blockchain::Error::from_state(Box::new(e)))? ) } @@ -1361,7 +1354,7 @@ impl StorageProvider for Client wher &self, first: NumberFor, last: BlockId, - storage_key: Option<&StorageKey>, + storage_key: Option<&PrefixedStorageKey>, key: &StorageKey ) -> sp_blockchain::Result, u32)>> { let last_number = self.backend.blockchain().expect_block_number_from_id(&last)?; @@ -1392,7 +1385,7 @@ impl StorageProvider for Client wher range_first, &range_anchor, best_number, - storage_key.as_ref().map(|x| &x.0[..]), + storage_key, &key.0) .and_then(|r| r.map(|r| r.map(|(block, tx)| (block, tx))).collect::>()) .map_err(|err| sp_blockchain::Error::ChangesTrieAccessFailed(err))?; diff --git a/client/src/in_mem.rs b/client/src/in_mem.rs index 3672da1822..20b227e790 100644 --- a/client/src/in_mem.rs +++ b/client/src/in_mem.rs @@ -516,9 +516,9 @@ impl backend::BlockImportOperation for BlockImportOperatio fn reset_storage(&mut self, storage: Storage) -> sp_blockchain::Result { check_genesis_storage(&storage)?; - let child_delta = storage.children.into_iter() - .map(|(storage_key, child_content)| - (storage_key, child_content.data.into_iter().map(|(k, v)| (k, Some(v))), child_content.child_info)); + let child_delta = storage.children_default.into_iter() + .map(|(_storage_key, child_content)| + (child_content.child_info, child_content.data.into_iter().map(|(k, v)| (k, Some(v))))); let (root, transaction) = self.old_state.full_storage_root( storage.top.into_iter().map(|(k, v)| (k, Some(v))), @@ -725,8 +725,9 @@ pub fn check_genesis_storage(storage: &Storage) -> sp_blockchain::Result<()> { return Err(sp_blockchain::Error::GenesisInvalid.into()); } - if storage.children.keys().any(|child_key| !well_known_keys::is_child_storage_key(&child_key)) { - return Err(sp_blockchain::Error::GenesisInvalid.into()); + if storage.children_default.keys() + .any(|child_key| !well_known_keys::is_child_storage_key(&child_key)) { + return Err(sp_blockchain::Error::GenesisInvalid.into()); } Ok(()) diff --git a/client/src/light/backend.rs b/client/src/light/backend.rs index 0b334d48b7..01e9854864 100644 --- a/client/src/light/backend.rs +++ b/client/src/light/backend.rs @@ -24,7 +24,7 @@ use parking_lot::RwLock; use codec::{Decode, Encode}; use sp_core::ChangesTrieConfiguration; -use sp_core::storage::{well_known_keys, ChildInfo, OwnedChildInfo}; +use sp_core::storage::{well_known_keys, ChildInfo}; use sp_core::offchain::storage::InMemOffchainStorage; use sp_state_machine::{ Backend as StateBackend, TrieBackend, InMemoryBackend, ChangesTrieTransaction, @@ -312,17 +312,17 @@ impl BlockImportOperation for ImportOperation self.changes_trie_config_update = Some(changes_trie_config); // this is only called when genesis block is imported => shouldn't be performance bottleneck - let mut storage: HashMap, OwnedChildInfo)>, _> = HashMap::new(); + let mut storage: HashMap, _> = HashMap::new(); storage.insert(None, input.top); // create a list of children keys to re-compute roots for - let child_delta = input.children.iter() - .map(|(storage_key, storage_child)| (storage_key.clone(), None, storage_child.child_info.clone())) + let child_delta = input.children_default.iter() + .map(|(_storage_key, storage_child)| (storage_child.child_info.clone(), None)) .collect::>(); // make sure to persist the child storage - for (child_key, storage_child) in input.children { - storage.insert(Some((child_key, storage_child.child_info)), storage_child.data); + for (_child_key, storage_child) in input.children_default { + storage.insert(Some(storage_child.child_info), storage_child.data); } let storage_update = InMemoryBackend::from(storage); @@ -386,13 +386,12 @@ impl StateBackend for GenesisOrUnavailableState fn child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> ClientResult>> { match *self { GenesisOrUnavailableState::Genesis(ref state) => - Ok(state.child_storage(storage_key, child_info, key).expect(IN_MEMORY_EXPECT_PROOF)), + Ok(state.child_storage(child_info, key).expect(IN_MEMORY_EXPECT_PROOF)), GenesisOrUnavailableState::Unavailable => Err(ClientError::NotAvailableOnLightClient), } } @@ -407,13 +406,12 @@ impl StateBackend for GenesisOrUnavailableState fn next_child_storage_key( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result>, Self::Error> { match *self { GenesisOrUnavailableState::Genesis(ref state) => Ok( - state.next_child_storage_key(storage_key, child_info, key) + state.next_child_storage_key(child_info, key) .expect(IN_MEMORY_EXPECT_PROOF) ), GenesisOrUnavailableState::Unavailable => Err(ClientError::NotAvailableOnLightClient), @@ -436,27 +434,25 @@ impl StateBackend for GenesisOrUnavailableState fn for_keys_in_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, action: A, ) { match *self { GenesisOrUnavailableState::Genesis(ref state) => - state.for_keys_in_child_storage(storage_key, child_info, action), + state.for_keys_in_child_storage(child_info, action), GenesisOrUnavailableState::Unavailable => (), } } fn for_child_keys_with_prefix( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], action: A, ) { match *self { GenesisOrUnavailableState::Genesis(ref state) => - state.for_child_keys_with_prefix(storage_key, child_info, prefix, action), + state.for_child_keys_with_prefix(child_info, prefix, action), GenesisOrUnavailableState::Unavailable => (), } } @@ -474,8 +470,7 @@ impl StateBackend for GenesisOrUnavailableState fn child_storage_root( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, delta: I, ) -> (H::Out, bool, Self::Transaction) where @@ -483,7 +478,7 @@ impl StateBackend for GenesisOrUnavailableState { match *self { GenesisOrUnavailableState::Genesis(ref state) => { - let (root, is_equal, _) = state.child_storage_root(storage_key, child_info, delta); + let (root, is_equal, _) = state.child_storage_root(child_info, delta); (root, is_equal, Default::default()) }, GenesisOrUnavailableState::Unavailable => diff --git a/client/src/light/fetcher.rs b/client/src/light/fetcher.rs index 0ae0e68e0c..ef6a062cf3 100644 --- a/client/src/light/fetcher.rs +++ b/client/src/light/fetcher.rs @@ -23,6 +23,7 @@ use std::marker::PhantomData; use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; use codec::{Decode, Encode}; use sp_core::{convert_hash, traits::CodeExecutor}; +use sp_core::storage::{ChildInfo, ChildType}; use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor, AtLeast32Bit, CheckedConversion, @@ -135,7 +136,7 @@ impl> LightDataChecker { number: request.last_block.0, }, remote_max_block, - request.storage_key.as_ref().map(Vec::as_slice), + request.storage_key.as_ref(), &request.key) .map_err(|err| ClientError::ChangesTrieAccessFailed(err))?; result.extend(result_range); @@ -242,10 +243,14 @@ impl FetchChecker for LightDataChecker request: &RemoteReadChildRequest, remote_proof: StorageProof, ) -> ClientResult, Option>>> { + let child_info = match ChildType::from_prefixed_key(&request.storage_key) { + Some((ChildType::ParentKeyId, storage_key)) => ChildInfo::new_default(storage_key), + None => return Err("Invalid child type".into()), + }; read_child_proof_check::( convert_hash(request.header.state_root()), remote_proof, - &request.storage_key, + &child_info, request.keys.iter(), ).map_err(Into::into) } @@ -360,8 +365,6 @@ pub mod tests { use sc_client_api::{StorageProvider, ProofProvider}; use sc_block_builder::BlockBuilderProvider; - const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_1"); - type TestChecker = LightDataChecker< NativeExecutor, BlakeTwo256, @@ -411,11 +414,12 @@ pub mod tests { fn prepare_for_read_child_proof_check() -> (TestChecker, Header, StorageProof, Vec) { use substrate_test_runtime_client::DefaultTestClientBuilderExt; use substrate_test_runtime_client::TestClientBuilderExt; + let child_info = ChildInfo::new_default(b"child1"); + let child_info = &child_info; // prepare remote client let remote_client = substrate_test_runtime_client::TestClientBuilder::new() .add_extra_child_storage( - b":child_storage:default:child1".to_vec(), - CHILD_INFO_1, + child_info, b"key1".to_vec(), b"value1".to_vec(), ).build(); @@ -428,15 +432,13 @@ pub mod tests { // 'fetch' child read proof from remote node let child_value = remote_client.child_storage( &remote_block_id, - &StorageKey(b":child_storage:default:child1".to_vec()), - CHILD_INFO_1, + child_info, &StorageKey(b"key1".to_vec()), ).unwrap().unwrap().0; assert_eq!(b"value1"[..], child_value[..]); let remote_read_proof = remote_client.read_child_proof( &remote_block_id, - b":child_storage:default:child1", - CHILD_INFO_1, + child_info, &mut std::iter::once("key1".as_bytes()), ).unwrap(); @@ -510,20 +512,18 @@ pub mod tests { #[test] fn storage_child_read_proof_is_generated_and_checked() { + let child_info = ChildInfo::new_default(&b"child1"[..]); let ( local_checker, remote_block_header, remote_read_proof, result, ) = prepare_for_read_child_proof_check(); - let child_infos = CHILD_INFO_1.info(); assert_eq!((&local_checker as &dyn FetchChecker).check_read_child_proof( &RemoteReadChildRequest::

{ block: remote_block_header.hash(), header: remote_block_header, - storage_key: b":child_storage:default:child1".to_vec(), - child_info: child_infos.0.to_vec(), - child_type: child_infos.1, + storage_key: child_info.prefixed_storage_key(), keys: vec![b"key1".to_vec()], retry_count: None, }, diff --git a/frame/contracts/src/account_db.rs b/frame/contracts/src/account_db.rs index 165581e676..aae853d2ff 100644 --- a/frame/contracts/src/account_db.rs +++ b/frame/contracts/src/account_db.rs @@ -128,7 +128,7 @@ impl AccountDb for DirectAccountDb { trie_id: Option<&TrieId>, location: &StorageKey ) -> Option> { - trie_id.and_then(|id| child::get_raw(id, crate::trie_unique_id(&id[..]), &blake2_256(location))) + trie_id.and_then(|id| child::get_raw(&crate::child_trie_info(&id[..]), &blake2_256(location))) } fn get_code_hash(&self, account: &T::AccountId) -> Option> { >::get(account).and_then(|i| i.as_alive().map(|i| i.code_hash)) @@ -167,13 +167,13 @@ impl AccountDb for DirectAccountDb { (false, Some(info), _) => info, // Existing contract is being removed. (true, Some(info), None) => { - child::kill_storage(&info.trie_id, info.child_trie_unique_id()); + child::kill_storage(&info.child_trie_info()); >::remove(&address); continue; } // Existing contract is being replaced by a new one. (true, Some(info), Some(code_hash)) => { - child::kill_storage(&info.trie_id, info.child_trie_unique_id()); + child::kill_storage(&info.child_trie_info()); AliveContractInfo:: { code_hash, storage_size: T::StorageSizeOffset::get(), @@ -212,17 +212,16 @@ impl AccountDb for DirectAccountDb { for (k, v) in changed.storage.into_iter() { if let Some(value) = child::get_raw( - &new_info.trie_id[..], - new_info.child_trie_unique_id(), + &new_info.child_trie_info(), &blake2_256(&k), ) { new_info.storage_size -= value.len() as u32; } if let Some(value) = v { new_info.storage_size += value.len() as u32; - child::put_raw(&new_info.trie_id[..], new_info.child_trie_unique_id(), &blake2_256(&k), &value[..]); + child::put_raw(&new_info.child_trie_info(), &blake2_256(&k), &value[..]); } else { - child::kill(&new_info.trie_id[..], new_info.child_trie_unique_id(), &blake2_256(&k)); + child::kill(&new_info.child_trie_info(), &blake2_256(&k)); } } diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 91f06d5607..00b23cad19 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -125,12 +125,11 @@ use sp_runtime::{ use frame_support::dispatch::{DispatchResult, Dispatchable}; use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; use frame_support::{ - Parameter, decl_module, decl_event, decl_storage, decl_error, storage::child, - parameter_types, IsSubType, + Parameter, decl_module, decl_event, decl_storage, decl_error, + parameter_types, IsSubType, storage::child::{self, ChildInfo}, }; use frame_support::traits::{OnUnbalanced, Currency, Get, Time, Randomness}; use frame_system::{self as system, ensure_signed, RawOrigin, ensure_root}; -use sp_core::storage::well_known_keys::CHILD_STORAGE_KEY_PREFIX; use pallet_contracts_primitives::{RentProjection, ContractAccessError}; pub type CodeHash = ::Hash; @@ -229,15 +228,14 @@ pub struct RawAliveContractInfo { impl RawAliveContractInfo { /// Associated child trie unique id is built from the hash part of the trie id. - pub fn child_trie_unique_id(&self) -> child::ChildInfo { - trie_unique_id(&self.trie_id[..]) + pub fn child_trie_info(&self) -> ChildInfo { + child_trie_info(&self.trie_id[..]) } } /// Associated child trie unique id is built from the hash part of the trie id. -pub(crate) fn trie_unique_id(trie_id: &[u8]) -> child::ChildInfo { - let start = CHILD_STORAGE_KEY_PREFIX.len() + b"default:".len(); - child::ChildInfo::new_default(&trie_id[start ..]) +pub(crate) fn child_trie_info(trie_id: &[u8]) -> ChildInfo { + ChildInfo::new_default(trie_id) } pub type TombstoneContractInfo = @@ -270,10 +268,6 @@ pub trait TrieIdGenerator { /// /// The implementation must ensure every new trie id is unique: two consecutive calls with the /// same parameter needs to return different trie id values. - /// - /// Also, the implementation is responsible for ensuring that `TrieId` starts with - /// `:child_storage:`. - /// TODO: We want to change this, see https://github.com/paritytech/substrate/issues/2325 fn trie_id(account_id: &AccountId) -> TrieId; } @@ -297,13 +291,7 @@ where let mut buf = Vec::new(); buf.extend_from_slice(account_id.as_ref()); buf.extend_from_slice(&new_seed.to_le_bytes()[..]); - - // TODO: see https://github.com/paritytech/substrate/issues/2325 - CHILD_STORAGE_KEY_PREFIX.iter() - .chain(b"default:") - .chain(T::Hashing::hash(&buf[..]).as_ref().iter()) - .cloned() - .collect() + T::Hashing::hash(&buf[..]).as_ref().into() } } @@ -824,13 +812,11 @@ impl Module { let key_values_taken = delta.iter() .filter_map(|key| { child::get_raw( - &origin_contract.trie_id, - origin_contract.child_trie_unique_id(), + &origin_contract.child_trie_info(), &blake2_256(key), ).map(|value| { child::kill( - &origin_contract.trie_id, - origin_contract.child_trie_unique_id(), + &origin_contract.child_trie_info(), &blake2_256(key), ); @@ -842,8 +828,8 @@ impl Module { let tombstone = >::new( // This operation is cheap enough because last_write (delta not included) // is not this block as it has been checked earlier. - &child::child_root( - &origin_contract.trie_id, + &child::root( + &origin_contract.child_trie_info(), )[..], code_hash, ); @@ -851,8 +837,7 @@ impl Module { if tombstone != dest_tombstone { for (key, value) in key_values_taken { child::put_raw( - &origin_contract.trie_id, - origin_contract.child_trie_unique_id(), + &origin_contract.child_trie_info(), &blake2_256(key), &value, ); diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index 8b6825419c..1aa52fff31 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -223,8 +223,7 @@ fn enact_verdict( Verdict::Kill => { >::remove(account); child::kill_storage( - &alive_contract_info.trie_id, - alive_contract_info.child_trie_unique_id(), + &alive_contract_info.child_trie_info(), ); >::deposit_event(RawEvent::Evicted(account.clone(), false)); None @@ -235,7 +234,9 @@ fn enact_verdict( } // Note: this operation is heavy. - let child_storage_root = child::child_root(&alive_contract_info.trie_id); + let child_storage_root = child::root( + &alive_contract_info.child_trie_info(), + ); let tombstone = >::new( &child_storage_root[..], @@ -245,8 +246,7 @@ fn enact_verdict( >::insert(account, &tombstone_info); child::kill_storage( - &alive_contract_info.trie_id, - alive_contract_info.child_trie_unique_id(), + &alive_contract_info.child_trie_info(), ); >::deposit_event(RawEvent::Evicted(account.clone(), true)); diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 2bcd708904..f7170e9172 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -200,10 +200,7 @@ impl TrieIdGenerator for DummyTrieIdGenerator { *v }); - // TODO: see https://github.com/paritytech/substrate/issues/2325 let mut res = vec![]; - res.extend_from_slice(well_known_keys::CHILD_STORAGE_KEY_PREFIX); - res.extend_from_slice(b"default:"); res.extend_from_slice(&new_seed.to_le_bytes()); res.extend_from_slice(&account_id.to_le_bytes()); res diff --git a/frame/support/src/storage/child.rs b/frame/support/src/storage/child.rs index d4d046a9d4..658908d258 100644 --- a/frame/support/src/storage/child.rs +++ b/frame/support/src/storage/child.rs @@ -16,100 +16,90 @@ //! Operation on runtime child storages. //! -//! This module is a currently only a variant of unhashed with additional `storage_key`. -//! Note that `storage_key` must be unique and strong (strong in the sense of being long enough to -//! avoid collision from a resistant hash function (which unique implies)). -//! -//! A **key collision free** unique id is required as parameter to avoid key collision -//! between child tries. -//! This unique id management and generation responsibility is delegated to pallet module. -// NOTE: could replace unhashed by having only one kind of storage (root being null storage key (storage_key can become Option<&[u8]>). +//! This module is a currently only a variant of unhashed with additional `child_info`. +// NOTE: could replace unhashed by having only one kind of storage (top trie being the child info +// of null length parent storage key). use crate::sp_std::prelude::*; use codec::{Codec, Encode, Decode}; -pub use sp_core::storage::ChildInfo; +pub use sp_core::storage::{ChildInfo, ChildType}; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Option { - let (data, child_type) = child_info.info(); - sp_io::storage::child_get( - storage_key, - data, - child_type, - key, - ).and_then(|v| { - Decode::decode(&mut &v[..]).map(Some).unwrap_or_else(|_| { - // TODO #3700: error should be handleable. - runtime_print!("ERROR: Corrupted state in child trie at {:?}/{:?}", storage_key, key); - None - }) - }) + match child_info.child_type() { + ChildType::ParentKeyId => { + let storage_key = child_info.storage_key(); + sp_io::default_child_storage::get( + storage_key, + key, + ).and_then(|v| { + Decode::decode(&mut &v[..]).map(Some).unwrap_or_else(|_| { + // TODO #3700: error should be handleable. + runtime_print!("ERROR: Corrupted state in child trie at {:?}/{:?}", storage_key, key); + None + }) + }) + }, + } } /// Return the value of the item in storage under `key`, or the type's default if there is no /// explicit entry. pub fn get_or_default( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> T { - get(storage_key, child_info, key).unwrap_or_else(Default::default) + get(child_info, key).unwrap_or_else(Default::default) } /// Return the value of the item in storage under `key`, or `default_value` if there is no /// explicit entry. pub fn get_or( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], default_value: T, ) -> T { - get(storage_key, child_info, key).unwrap_or(default_value) + get(child_info, key).unwrap_or(default_value) } /// Return the value of the item in storage under `key`, or `default_value()` if there is no /// explicit entry. pub fn get_or_else T>( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], default_value: F, ) -> T { - get(storage_key, child_info, key).unwrap_or_else(default_value) + get(child_info, key).unwrap_or_else(default_value) } /// Put `value` in storage under `key`. pub fn put( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], value: &T, ) { - let (data, child_type) = child_info.info(); - value.using_encoded(|slice| - sp_io::storage::child_set( - storage_key, - data, - child_type, - key, - slice, - ) - ); + match child_info.child_type() { + ChildType::ParentKeyId => value.using_encoded(|slice| + sp_io::default_child_storage::set( + child_info.storage_key(), + key, + slice, + ) + ), + } } /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. pub fn take( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Option { - let r = get(storage_key, child_info, key); + let r = get(child_info, key); if r.is_some() { - kill(storage_key, child_info, key); + kill(child_info, key); } r } @@ -117,113 +107,106 @@ pub fn take( /// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, /// the default for its type. pub fn take_or_default( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> T { - take(storage_key, child_info, key).unwrap_or_else(Default::default) + take(child_info, key).unwrap_or_else(Default::default) } /// Return the value of the item in storage under `key`, or `default_value` if there is no /// explicit entry. Ensure there is no explicit entry on return. pub fn take_or( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], default_value: T, ) -> T { - take(storage_key, child_info, key).unwrap_or(default_value) + take(child_info, key).unwrap_or(default_value) } /// Return the value of the item in storage under `key`, or `default_value()` if there is no /// explicit entry. Ensure there is no explicit entry on return. pub fn take_or_else T>( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], default_value: F, ) -> T { - take(storage_key, child_info, key).unwrap_or_else(default_value) + take(child_info, key).unwrap_or_else(default_value) } /// Check to see if `key` has an explicit entry in storage. pub fn exists( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> bool { - let (data, child_type) = child_info.info(); - sp_io::storage::child_read( - storage_key, data, child_type, - key, &mut [0;0][..], 0, - ).is_some() + match child_info.child_type() { + ChildType::ParentKeyId => sp_io::default_child_storage::read( + child_info.storage_key(), + key, &mut [0;0][..], 0, + ).is_some(), + } } /// Remove all `storage_key` key/values pub fn kill_storage( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, ) { - let (data, child_type) = child_info.info(); - sp_io::storage::child_storage_kill( - storage_key, - data, - child_type, - ) + match child_info.child_type() { + ChildType::ParentKeyId => sp_io::default_child_storage::storage_kill( + child_info.storage_key(), + ), + } } /// Ensure `key` has no explicit entry in storage. pub fn kill( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) { - let (data, child_type) = child_info.info(); - sp_io::storage::child_clear( - storage_key, - data, - child_type, - key, - ); + match child_info.child_type() { + ChildType::ParentKeyId => { + sp_io::default_child_storage::clear( + child_info.storage_key(), + key, + ); + }, + } } /// Get a Vec of bytes from storage. pub fn get_raw( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Option> { - let (data, child_type) = child_info.info(); - sp_io::storage::child_get( - storage_key, - data, - child_type, - key, - ) + match child_info.child_type() { + ChildType::ParentKeyId => sp_io::default_child_storage::get( + child_info.storage_key(), + key, + ), + } } /// Put a raw byte slice into storage. pub fn put_raw( - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], value: &[u8], ) { - let (data, child_type) = child_info.info(); - sp_io::storage::child_set( - storage_key, - data, - child_type, - key, - value, - ) + match child_info.child_type() { + ChildType::ParentKeyId => sp_io::default_child_storage::set( + child_info.storage_key(), + key, + value, + ), + } } /// Calculate current child root value. -pub fn child_root( - storage_key: &[u8], +pub fn root( + child_info: &ChildInfo, ) -> Vec { - sp_io::storage::child_root( - storage_key, - ) + match child_info.child_type() { + ChildType::ParentKeyId => sp_io::default_child_storage::root( + child_info.storage_key(), + ), + } } diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index 00b110ffb9..779460ce31 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -301,7 +301,7 @@ fn new_test_ext() -> sp_io::TestExternalities { fn storage_instance_independence() { let mut storage = sp_core::storage::Storage { top: std::collections::BTreeMap::new(), - children: std::collections::HashMap::new() + children_default: std::collections::HashMap::new() }; sp_state_machine::BasicExternalities::execute_with_storage(&mut storage, || { module2::Value::::put(0); diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 50f2b089f2..d1bc3c1a51 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -930,7 +930,7 @@ impl Module { >::hashed_key().to_vec() => T::BlockNumber::one().encode(), >::hashed_key().to_vec() => [69u8; 32].encode() ], - children: map![], + children_default: map![], }) } diff --git a/primitives/externalities/src/lib.rs b/primitives/externalities/src/lib.rs index 2c0f50cd74..96f17579a2 100644 --- a/primitives/externalities/src/lib.rs +++ b/primitives/externalities/src/lib.rs @@ -24,7 +24,7 @@ use std::any::{Any, TypeId}; -use sp_storage::{ChildStorageKey, ChildInfo}; +use sp_storage::ChildInfo; pub use scope_limited::{set_and_run_with_externalities, with_externalities}; pub use extensions::{Extension, Extensions, ExtensionStore}; @@ -62,8 +62,7 @@ pub trait Externalities: ExtensionStore { /// Returns an `Option` that holds the SCALE encoded hash. fn child_storage_hash( &self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Option>; @@ -72,8 +71,7 @@ pub trait Externalities: ExtensionStore { /// Returns an `Option` that holds the SCALE encoded hash. fn child_storage( &self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Option>; @@ -85,12 +83,11 @@ pub trait Externalities: ExtensionStore { /// Set child storage entry `key` of current contract being called (effective immediately). fn set_child_storage( &mut self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: Vec, value: Vec, ) { - self.place_child_storage(storage_key, child_info, key, Some(value)) + self.place_child_storage(child_info, key, Some(value)) } /// Clear a storage entry (`key`) of current contract being called (effective immediately). @@ -101,11 +98,10 @@ pub trait Externalities: ExtensionStore { /// Clear a child storage entry (`key`) of current contract being called (effective immediately). fn clear_child_storage( &mut self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) { - self.place_child_storage(storage_key, child_info, key.to_vec(), None) + self.place_child_storage(child_info, key.to_vec(), None) } /// Whether a storage entry exists. @@ -116,11 +112,10 @@ pub trait Externalities: ExtensionStore { /// Whether a child storage entry exists. fn exists_child_storage( &self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> bool { - self.child_storage(storage_key, child_info, key).is_some() + self.child_storage(child_info, key).is_some() } /// Returns the key immediately following the given key, if it exists. @@ -129,13 +124,12 @@ pub trait Externalities: ExtensionStore { /// Returns the key immediately following the given key, if it exists, in child storage. fn next_child_storage_key( &self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Option>; /// Clear an entire child storage. - fn kill_child_storage(&mut self, storage_key: ChildStorageKey, child_info: ChildInfo); + fn kill_child_storage(&mut self, child_info: &ChildInfo); /// Clear storage entries which keys are start with the given prefix. fn clear_prefix(&mut self, prefix: &[u8]); @@ -143,8 +137,7 @@ pub trait Externalities: ExtensionStore { /// Clear child storage entries which keys are start with the given prefix. fn clear_child_prefix( &mut self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], ); @@ -154,8 +147,7 @@ pub trait Externalities: ExtensionStore { /// Set or clear a child storage entry. fn place_child_storage( &mut self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: Vec, value: Option>, ); @@ -178,7 +170,7 @@ pub trait Externalities: ExtensionStore { /// storage map will be removed. fn child_storage_root( &mut self, - storage_key: ChildStorageKey, + child_info: &ChildInfo, ) -> Vec; /// Get the changes trie root of the current storage overlay at a block with given `parent`. diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index ee146dbc29..b582720233 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -37,7 +37,7 @@ use sp_core::{ traits::{KeystoreExt, CallInWasmExt, TaskExecutorExt}, offchain::{OffchainExt, TransactionPoolExt}, hexdisplay::HexDisplay, - storage::{ChildStorageKey, ChildInfo}, + storage::ChildInfo, }; use sp_core::{ @@ -74,19 +74,6 @@ pub enum EcdsaVerifyError { BadSignature, } -/// Returns a `ChildStorageKey` if the given `storage_key` slice is a valid storage -/// key or panics otherwise. -/// -/// Panicking here is aligned with what the `without_std` environment would do -/// in the case of an invalid child storage key. -#[cfg(feature = "std")] -fn child_storage_key_or_panic(storage_key: &[u8]) -> ChildStorageKey { - match ChildStorageKey::from_slice(storage_key) { - Some(storage_key) => storage_key, - None => panic!("child storage key is invalid"), - } -} - /// Interface for accessing the storage from within the runtime. #[runtime_interface] pub trait Storage { @@ -95,30 +82,6 @@ pub trait Storage { self.storage(key).map(|s| s.to_vec()) } - /// All Child api uses : - /// - A `child_storage_key` to define the anchor point for the child proof - /// (commonly the location where the child root is stored in its parent trie). - /// - A `child_storage_types` to identify the kind of the child type and how its - /// `child definition` parameter is encoded. - /// - A `child_definition_parameter` which is the additional information required - /// to use the child trie. For instance defaults child tries requires this to - /// contain a collision free unique id. - /// - /// This function specifically returns the data for `key` in the child storage or `None` - /// if the key can not be found. - fn child_get( - &self, - child_storage_key: &[u8], - child_definition: &[u8], - child_type: u32, - key: &[u8], - ) -> Option> { - let storage_key = child_storage_key_or_panic(child_storage_key); - let child_info = ChildInfo::resolve_child_info(child_type, child_definition) - .expect("Invalid child definition"); - self.child_storage(storage_key, child_info, key).map(|s| s.to_vec()) - } - /// Get `key` from storage, placing the value into `value_out` and return the number of /// bytes that the entry in storage has beyond the offset or `None` if the storage entry /// doesn't exist at all. @@ -134,26 +97,87 @@ pub trait Storage { }) } + /// Set `key` to `value` in the storage. + fn set(&mut self, key: &[u8], value: &[u8]) { + self.set_storage(key.to_vec(), value.to_vec()); + } + + /// Clear the storage of the given `key` and its value. + fn clear(&mut self, key: &[u8]) { + self.clear_storage(key) + } + + /// Check whether the given `key` exists in storage. + fn exists(&self, key: &[u8]) -> bool { + self.exists_storage(key) + } + + /// Clear the storage of each key-value pair where the key starts with the given `prefix`. + fn clear_prefix(&mut self, prefix: &[u8]) { + Externalities::clear_prefix(*self, prefix) + } + + /// "Commit" all existing operations and compute the resulting storage root. + /// + /// The hashing algorithm is defined by the `Block`. + /// + /// Returns the SCALE encoded hash. + fn root(&mut self) -> Vec { + self.storage_root() + } + + /// "Commit" all existing operations and get the resulting storage change root. + /// `parent_hash` is a SCALE encoded hash. + /// + /// The hashing algorithm is defined by the `Block`. + /// + /// Returns an `Some(_)` which holds the SCALE encoded hash or `None` when + /// changes trie is disabled. + fn changes_root(&mut self, parent_hash: &[u8]) -> Option> { + self.storage_changes_root(parent_hash) + .expect("Invalid `parent_hash` given to `changes_root`.") + } + + /// Get the next key in storage after the given one in lexicographic order. + fn next_key(&mut self, key: &[u8]) -> Option> { + self.next_storage_key(&key) + } +} + +/// Interface for accessing the child storage for default child trie, +/// from within the runtime. +#[runtime_interface] +pub trait DefaultChildStorage { + + /// Get a default child storage value for a given key. + /// + /// Parameter `storage_key` is the unprefixed location of the root of the child trie in the parent trie. + /// Result is `None` if the value for `key` in the child storage can not be found. + fn get( + &self, + storage_key: &[u8], + key: &[u8], + ) -> Option> { + let child_info = ChildInfo::new_default(storage_key); + self.child_storage(&child_info, key).map(|s| s.to_vec()) + } + + /// Allocation efficient variant of `get`. + /// /// Get `key` from child storage, placing the value into `value_out` and return the number /// of bytes that the entry in storage has beyond the offset or `None` if the storage entry /// doesn't exist at all. /// If `value_out` length is smaller than the returned length, only `value_out` length bytes /// are copied into `value_out`. - /// - /// See `child_get` for common child api parameters. - fn child_read( + fn read( &self, - child_storage_key: &[u8], - child_definition: &[u8], - child_type: u32, + storage_key: &[u8], key: &[u8], value_out: &mut [u8], value_offset: u32, ) -> Option { - let storage_key = child_storage_key_or_panic(child_storage_key); - let child_info = ChildInfo::resolve_child_info(child_type, child_definition) - .expect("Invalid child definition"); - self.child_storage(storage_key, child_info, key) + let child_info = ChildInfo::new_default(storage_key); + self.child_storage(&child_info, key) .map(|value| { let value_offset = value_offset as usize; let data = &value[value_offset.min(value.len())..]; @@ -163,159 +187,91 @@ pub trait Storage { }) } - /// Set `key` to `value` in the storage. - fn set(&mut self, key: &[u8], value: &[u8]) { - self.set_storage(key.to_vec(), value.to_vec()); - } - - /// Set `key` to `value` in the child storage denoted by `child_storage_key`. + /// Set a child storage value. /// - /// See `child_get` for common child api parameters. - fn child_set( + /// Set `key` to `value` in the child storage denoted by `storage_key`. + fn set( &mut self, - child_storage_key: &[u8], - child_definition: &[u8], - child_type: u32, + storage_key: &[u8], key: &[u8], value: &[u8], ) { - let storage_key = child_storage_key_or_panic(child_storage_key); - let child_info = ChildInfo::resolve_child_info(child_type, child_definition) - .expect("Invalid child definition"); - self.set_child_storage(storage_key, child_info, key.to_vec(), value.to_vec()); + let child_info = ChildInfo::new_default(storage_key); + self.set_child_storage(&child_info, key.to_vec(), value.to_vec()); } - /// Clear the storage of the given `key` and its value. - fn clear(&mut self, key: &[u8]) { - self.clear_storage(key) - } - - /// Clear the given child storage of the given `key` and its value. + /// Clear a child storage key. /// - /// See `child_get` for common child api parameters. - fn child_clear( + /// For the default child storage at `storage_key`, clear value at `key`. + fn clear ( &mut self, - child_storage_key: &[u8], - child_definition: &[u8], - child_type: u32, + storage_key: &[u8], key: &[u8], ) { - let storage_key = child_storage_key_or_panic(child_storage_key); - let child_info = ChildInfo::resolve_child_info(child_type, child_definition) - .expect("Invalid child definition"); - self.clear_child_storage(storage_key, child_info, key); + let child_info = ChildInfo::new_default(storage_key); + self.clear_child_storage(&child_info, key); } /// Clear an entire child storage. /// - /// See `child_get` for common child api parameters. - fn child_storage_kill( + /// If it exists, the child storage for `storage_key` + /// is removed. + fn storage_kill( &mut self, - child_storage_key: &[u8], - child_definition: &[u8], - child_type: u32, + storage_key: &[u8], ) { - let storage_key = child_storage_key_or_panic(child_storage_key); - let child_info = ChildInfo::resolve_child_info(child_type, child_definition) - .expect("Invalid child definition"); - self.kill_child_storage(storage_key, child_info); - } - - /// Check whether the given `key` exists in storage. - fn exists(&self, key: &[u8]) -> bool { - self.exists_storage(key) + let child_info = ChildInfo::new_default(storage_key); + self.kill_child_storage(&child_info); } - /// Check whether the given `key` exists in storage. + /// Check a child storage key. /// - /// See `child_get` for common child api parameters. - fn child_exists( + /// Check whether the given `key` exists in default child defined at `storage_key`. + fn exists( &self, - child_storage_key: &[u8], - child_definition: &[u8], - child_type: u32, + storage_key: &[u8], key: &[u8], ) -> bool { - let storage_key = child_storage_key_or_panic(child_storage_key); - let child_info = ChildInfo::resolve_child_info(child_type, child_definition) - .expect("Invalid child definition"); - self.exists_child_storage(storage_key, child_info, key) - } - - /// Clear the storage of each key-value pair where the key starts with the given `prefix`. - fn clear_prefix(&mut self, prefix: &[u8]) { - Externalities::clear_prefix(*self, prefix) + let child_info = ChildInfo::new_default(storage_key); + self.exists_child_storage(&child_info, key) } - /// Clear the child storage of each key-value pair where the key starts with the given `prefix`. + /// Clear child default key by prefix. /// - /// See `child_get` for common child api parameters. - fn child_clear_prefix( + /// Clear the child storage of each key-value pair where the key starts with the given `prefix`. + fn clear_prefix( &mut self, - child_storage_key: &[u8], - child_definition: &[u8], - child_type: u32, + storage_key: &[u8], prefix: &[u8], ) { - let storage_key = child_storage_key_or_panic(child_storage_key); - let child_info = ChildInfo::resolve_child_info(child_type, child_definition) - .expect("Invalid child definition"); - self.clear_child_prefix(storage_key, child_info, prefix); + let child_info = ChildInfo::new_default(storage_key); + self.clear_child_prefix(&child_info, prefix); } - /// "Commit" all existing operations and compute the resulting storage root. + /// Default child root calculation. /// - /// The hashing algorithm is defined by the `Block`. - /// - /// Returns the SCALE encoded hash. - fn root(&mut self) -> Vec { - self.storage_root() - } - /// "Commit" all existing operations and compute the resulting child storage root. - /// /// The hashing algorithm is defined by the `Block`. /// /// Returns the SCALE encoded hash. - /// - /// See `child_get` for common child api parameters. - fn child_root( + fn root( &mut self, - child_storage_key: &[u8], + storage_key: &[u8], ) -> Vec { - let storage_key = child_storage_key_or_panic(child_storage_key); - self.child_storage_root(storage_key) + let child_info = ChildInfo::new_default(storage_key); + self.child_storage_root(&child_info) } - /// "Commit" all existing operations and get the resulting storage change root. - /// `parent_hash` is a SCALE encoded hash. + /// Child storage key iteration. /// - /// The hashing algorithm is defined by the `Block`. - /// - /// Returns an `Some(_)` which holds the SCALE encoded hash or `None` when - /// changes trie is disabled. - fn changes_root(&mut self, parent_hash: &[u8]) -> Option> { - self.storage_changes_root(parent_hash) - .expect("Invalid `parent_hash` given to `changes_root`.") - } - - /// Get the next key in storage after the given one in lexicographic order. - fn next_key(&mut self, key: &[u8]) -> Option> { - self.next_storage_key(&key) - } - /// Get the next key in storage after the given one in lexicographic order in child storage. - fn child_next_key( + fn next_key( &mut self, - child_storage_key: &[u8], - child_definition: &[u8], - child_type: u32, + storage_key: &[u8], key: &[u8], ) -> Option> { - let storage_key = child_storage_key_or_panic(child_storage_key); - let child_info = ChildInfo::resolve_child_info(child_type, child_definition) - .expect("Invalid child definition"); - self.next_child_storage_key(storage_key, child_info, key) + let child_info = ChildInfo::new_default(storage_key); + self.next_child_storage_key(&child_info, key) } } @@ -1019,6 +975,7 @@ pub type TestExternalities = sp_state_machine::TestExternalities b"bar".to_vec()], - children: map![], + children_default: map![], }); t.execute_with(|| { @@ -1063,7 +1020,7 @@ mod tests { fn read_storage_works() { let mut t = BasicExternalities::new(Storage { top: map![b":test".to_vec() => b"\x0b\0\0\0Hello world".to_vec()], - children: map![], + children_default: map![], }); t.execute_with(|| { @@ -1085,7 +1042,7 @@ mod tests { b":abc".to_vec() => b"\x0b\0\0\0Hello world".to_vec(), b":abdd".to_vec() => b"\x0b\0\0\0Hello world".to_vec() ], - children: map![], + children_default: map![], }); t.execute_with(|| { diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index e69f892626..0f609b0050 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -136,15 +136,15 @@ impl BuildStorage for sp_core::storage::Storage { storage: &mut sp_core::storage::Storage, )-> Result<(), String> { storage.top.extend(self.top.iter().map(|(k, v)| (k.clone(), v.clone()))); - for (k, other_map) in self.children.iter() { + for (k, other_map) in self.children_default.iter() { let k = k.clone(); - if let Some(map) = storage.children.get_mut(&k) { + if let Some(map) = storage.children_default.get_mut(&k) { map.data.extend(other_map.data.iter().map(|(k, v)| (k.clone(), v.clone()))); - if !map.child_info.try_update(other_map.child_info.as_ref()) { + if !map.child_info.try_update(&other_map.child_info) { return Err("Incompatible child info update".to_string()); } } else { - storage.children.insert(k, other_map.clone()); + storage.children_default.insert(k, other_map.clone()); } } Ok(()) diff --git a/primitives/state-machine/src/backend.rs b/primitives/state-machine/src/backend.rs index 94144fdb90..df8f810ceb 100644 --- a/primitives/state-machine/src/backend.rs +++ b/primitives/state-machine/src/backend.rs @@ -20,7 +20,7 @@ use log::warn; use hash_db::Hasher; use codec::{Decode, Encode}; -use sp_core::{traits::RuntimeCode, storage::{ChildInfo, OwnedChildInfo, well_known_keys}}; +use sp_core::{traits::RuntimeCode, storage::{ChildInfo, well_known_keys}}; use sp_trie::{TrieMut, MemoryDB, trie_types::TrieDBMut}; use crate::{ @@ -54,19 +54,17 @@ pub trait Backend: std::fmt::Debug { /// Get keyed child storage or None if there is nothing associated. fn child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result, Self::Error>; /// Get child keyed storage value hash or None if there is nothing associated. fn child_storage_hash( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result, Self::Error> { - self.child_storage(storage_key, child_info, key).map(|v| v.map(|v| H::hash(&v))) + self.child_storage(child_info, key).map(|v| v.map(|v| H::hash(&v))) } /// true if a key exists in storage. @@ -77,11 +75,10 @@ pub trait Backend: std::fmt::Debug { /// true if a key exists in child storage. fn exists_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result { - Ok(self.child_storage(storage_key, child_info, key)?.is_some()) + Ok(self.child_storage(child_info, key)?.is_some()) } /// Return the next key in storage in lexicographic order or `None` if there is no value. @@ -90,16 +87,14 @@ pub trait Backend: std::fmt::Debug { /// Return the next key in child storage in lexicographic order or `None` if there is no value. fn next_child_storage_key( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8] ) -> Result, Self::Error>; /// Retrieve all entries keys of child storage and call `f` for each of those keys. fn for_keys_in_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, f: F, ); @@ -118,8 +113,7 @@ pub trait Backend: std::fmt::Debug { /// call `f` for each of those keys. fn for_child_keys_with_prefix( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], f: F, ); @@ -137,8 +131,7 @@ pub trait Backend: std::fmt::Debug { /// is true if child storage root equals default storage root. fn child_storage_root( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, delta: I, ) -> (H::Out, bool, Self::Transaction) where @@ -158,12 +151,11 @@ pub trait Backend: std::fmt::Debug { /// Get all keys of child storage with given prefix fn child_keys( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], ) -> Vec { let mut all = Vec::new(); - self.for_child_keys_with_prefix(storage_key, child_info, prefix, |k| all.push(k.to_vec())); + self.for_child_keys_with_prefix(child_info, prefix, |k| all.push(k.to_vec())); all } @@ -183,20 +175,21 @@ pub trait Backend: std::fmt::Debug { where I1: IntoIterator)>, I2i: IntoIterator)>, - I2: IntoIterator, + I2: IntoIterator, H::Out: Ord + Encode, { let mut txs: Self::Transaction = Default::default(); let mut child_roots: Vec<_> = Default::default(); // child first - for (storage_key, child_delta, child_info) in child_deltas { + for (child_info, child_delta) in child_deltas { let (child_root, empty, child_txs) = - self.child_storage_root(&storage_key[..], child_info.as_ref(), child_delta); + self.child_storage_root(&child_info, child_delta); + let prefixed_storage_key = child_info.prefixed_storage_key(); txs.consolidate(child_txs); if empty { - child_roots.push((storage_key, None)); + child_roots.push((prefixed_storage_key.into_inner(), None)); } else { - child_roots.push((storage_key, Some(child_root.encode()))); + child_roots.push((prefixed_storage_key.into_inner(), Some(child_root.encode()))); } } let (root, parent_txs) = self.storage_root( @@ -239,20 +232,18 @@ impl<'a, T: Backend, H: Hasher> Backend for &'a T { fn child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result, Self::Error> { - (*self).child_storage(storage_key, child_info, key) + (*self).child_storage(child_info, key) } fn for_keys_in_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, f: F, ) { - (*self).for_keys_in_child_storage(storage_key, child_info, f) + (*self).for_keys_in_child_storage(child_info, f) } fn next_storage_key(&self, key: &[u8]) -> Result, Self::Error> { @@ -261,11 +252,10 @@ impl<'a, T: Backend, H: Hasher> Backend for &'a T { fn next_child_storage_key( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result, Self::Error> { - (*self).next_child_storage_key(storage_key, child_info, key) + (*self).next_child_storage_key(child_info, key) } fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { @@ -274,12 +264,11 @@ impl<'a, T: Backend, H: Hasher> Backend for &'a T { fn for_child_keys_with_prefix( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], f: F, ) { - (*self).for_child_keys_with_prefix(storage_key, child_info, prefix, f) + (*self).for_child_keys_with_prefix(child_info, prefix, f) } fn storage_root(&self, delta: I) -> (H::Out, Self::Transaction) @@ -292,15 +281,14 @@ impl<'a, T: Backend, H: Hasher> Backend for &'a T { fn child_storage_root( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, delta: I, ) -> (H::Out, bool, Self::Transaction) where I: IntoIterator)>, H::Out: Ord, { - (*self).child_storage_root(storage_key, child_info, delta) + (*self).child_storage_root(child_info, delta) } fn pairs(&self) -> Vec<(StorageKey, StorageValue)> { @@ -331,7 +319,7 @@ impl Consolidate for () { } impl Consolidate for Vec<( - Option<(StorageKey, OwnedChildInfo)>, + Option, StorageCollection, )> { fn consolidate(&mut self, mut other: Self) { diff --git a/primitives/state-machine/src/basic.rs b/primitives/state-machine/src/basic.rs index b49913418a..7f26085958 100644 --- a/primitives/state-machine/src/basic.rs +++ b/primitives/state-machine/src/basic.rs @@ -21,11 +21,11 @@ use std::{ }; use crate::{Backend, InMemoryBackend, StorageKey, StorageValue}; use hash_db::Hasher; -use sp_trie::{TrieConfiguration, default_child_trie_root}; +use sp_trie::{TrieConfiguration, empty_child_trie_root}; use sp_trie::trie_types::Layout; use sp_core::{ storage::{ - well_known_keys::is_child_storage_key, ChildStorageKey, Storage, + well_known_keys::is_child_storage_key, Storage, ChildInfo, StorageChild, }, traits::Externalities, Blake2Hasher, @@ -83,7 +83,7 @@ impl BasicExternalities { let mut ext = Self { inner: Storage { top: std::mem::replace(&mut storage.top, Default::default()), - children: std::mem::replace(&mut storage.children, Default::default()), + children_default: std::mem::replace(&mut storage.children_default, Default::default()), }, extensions: Default::default(), }; @@ -111,7 +111,7 @@ impl BasicExternalities { impl PartialEq for BasicExternalities { fn eq(&self, other: &BasicExternalities) -> bool { self.inner.top.eq(&other.inner.top) - && self.inner.children.eq(&other.inner.children) + && self.inner.children_default.eq(&other.inner.children_default) } } @@ -132,7 +132,7 @@ impl From> for BasicExternalities { BasicExternalities { inner: Storage { top: hashmap, - children: Default::default(), + children_default: Default::default(), }, extensions: Default::default(), } @@ -150,20 +150,19 @@ impl Externalities for BasicExternalities { fn child_storage( &self, - storage_key: ChildStorageKey, - _child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Option { - self.inner.children.get(storage_key.as_ref()).and_then(|child| child.data.get(key)).cloned() + self.inner.children_default.get(child_info.storage_key()) + .and_then(|child| child.data.get(key)).cloned() } fn child_storage_hash( &self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Option> { - self.child_storage(storage_key, child_info, key).map(|v| Blake2Hasher::hash(&v).encode()) + self.child_storage(child_info, key).map(|v| Blake2Hasher::hash(&v).encode()) } fn next_storage_key(&self, key: &[u8]) -> Option { @@ -173,12 +172,11 @@ impl Externalities for BasicExternalities { fn next_child_storage_key( &self, - storage_key: ChildStorageKey, - _child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Option { let range = (Bound::Excluded(key), Bound::Unbounded); - self.inner.children.get(storage_key.as_ref()) + self.inner.children_default.get(child_info.storage_key()) .and_then(|child| child.data.range::<[u8], _>(range).next().map(|(k, _)| k).cloned()) } @@ -196,12 +194,11 @@ impl Externalities for BasicExternalities { fn place_child_storage( &mut self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: StorageKey, value: Option, ) { - let child_map = self.inner.children.entry(storage_key.into_owned()) + let child_map = self.inner.children_default.entry(child_info.storage_key().to_vec()) .or_insert_with(|| StorageChild { data: Default::default(), child_info: child_info.to_owned(), @@ -215,10 +212,9 @@ impl Externalities for BasicExternalities { fn kill_child_storage( &mut self, - storage_key: ChildStorageKey, - _child_info: ChildInfo, + child_info: &ChildInfo, ) { - self.inner.children.remove(storage_key.as_ref()); + self.inner.children_default.remove(child_info.storage_key()); } fn clear_prefix(&mut self, prefix: &[u8]) { @@ -243,11 +239,10 @@ impl Externalities for BasicExternalities { fn clear_child_prefix( &mut self, - storage_key: ChildStorageKey, - _child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], ) { - if let Some(child) = self.inner.children.get_mut(storage_key.as_ref()) { + if let Some(child) = self.inner.children_default.get_mut(child_info.storage_key()) { let to_remove = child.data.range::<[u8], _>((Bound::Included(prefix), Bound::Unbounded)) .map(|(k, _)| k) .take_while(|k| k.starts_with(prefix)) @@ -264,20 +259,19 @@ impl Externalities for BasicExternalities { fn storage_root(&mut self) -> Vec { let mut top = self.inner.top.clone(); - let keys: Vec<_> = self.inner.children.keys().map(|k| k.to_vec()).collect(); + let prefixed_keys: Vec<_> = self.inner.children_default.iter().map(|(_k, v)| { + (v.child_info.prefixed_storage_key(), v.child_info.clone()) + }).collect(); // Single child trie implementation currently allows using the same child // empty root for all child trie. Using null storage key until multiple // type of child trie support. - let empty_hash = default_child_trie_root::>(&[]); - for storage_key in keys { - let child_root = self.child_storage_root( - ChildStorageKey::from_slice(storage_key.as_slice()) - .expect("Map only feed by valid keys; qed"), - ); + let empty_hash = empty_child_trie_root::>(); + for (prefixed_storage_key, child_info) in prefixed_keys { + let child_root = self.child_storage_root(&child_info); if &empty_hash[..] == &child_root[..] { - top.remove(storage_key.as_slice()); + top.remove(prefixed_storage_key.as_slice()); } else { - top.insert(storage_key, child_root); + top.insert(prefixed_storage_key.into_inner(), child_root); } } @@ -286,15 +280,15 @@ impl Externalities for BasicExternalities { fn child_storage_root( &mut self, - storage_key: ChildStorageKey, + child_info: &ChildInfo, ) -> Vec { - if let Some(child) = self.inner.children.get(storage_key.as_ref()) { + if let Some(child) = self.inner.children_default.get(child_info.storage_key()) { let delta = child.data.clone().into_iter().map(|(k, v)| (k, Some(v))); InMemoryBackend::::default() - .child_storage_root(storage_key.as_ref(), child.child_info.as_ref(), delta).0 + .child_storage_root(&child.child_info, delta).0 } else { - default_child_trie_root::>(storage_key.as_ref()) + empty_child_trie_root::>() }.encode() } @@ -336,8 +330,6 @@ mod tests { use sp_core::storage::well_known_keys::CODE; use hex_literal::hex; - const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_1"); - #[test] fn commit_should_work() { let mut ext = BasicExternalities::default(); @@ -361,30 +353,28 @@ mod tests { #[test] fn children_works() { - let child_storage = b":child_storage:default:test".to_vec(); - + let child_info = ChildInfo::new_default(b"storage_key"); + let child_info = &child_info; let mut ext = BasicExternalities::new(Storage { top: Default::default(), - children: map![ - child_storage.clone() => StorageChild { - data: map![ b"doe".to_vec() => b"reindeer".to_vec() ], - child_info: CHILD_INFO_1.to_owned(), + children_default: map![ + child_info.storage_key().to_vec() => StorageChild { + data: map![ b"doe".to_vec() => b"reindeer".to_vec() ], + child_info: child_info.to_owned(), } ] }); - let child = || ChildStorageKey::from_vec(child_storage.clone()).unwrap(); - - assert_eq!(ext.child_storage(child(), CHILD_INFO_1, b"doe"), Some(b"reindeer".to_vec())); + assert_eq!(ext.child_storage(child_info, b"doe"), Some(b"reindeer".to_vec())); - ext.set_child_storage(child(), CHILD_INFO_1, b"dog".to_vec(), b"puppy".to_vec()); - assert_eq!(ext.child_storage(child(), CHILD_INFO_1, b"dog"), Some(b"puppy".to_vec())); + ext.set_child_storage(child_info, b"dog".to_vec(), b"puppy".to_vec()); + assert_eq!(ext.child_storage(child_info, b"dog"), Some(b"puppy".to_vec())); - ext.clear_child_storage(child(), CHILD_INFO_1, b"dog"); - assert_eq!(ext.child_storage(child(), CHILD_INFO_1, b"dog"), None); + ext.clear_child_storage(child_info, b"dog"); + assert_eq!(ext.child_storage(child_info, b"dog"), None); - ext.kill_child_storage(child(), CHILD_INFO_1); - assert_eq!(ext.child_storage(child(), CHILD_INFO_1, b"doe"), None); + ext.kill_child_storage(child_info); + assert_eq!(ext.child_storage(child_info, b"doe"), None); } #[test] @@ -392,6 +382,6 @@ mod tests { // Make sure no values are set by default in `BasicExternalities`. let storage = BasicExternalities::new_empty().into_storages(); assert!(storage.top.is_empty()); - assert!(storage.children.is_empty()); + assert!(storage.children_default.is_empty()); } } diff --git a/primitives/state-machine/src/changes_trie/build.rs b/primitives/state-machine/src/changes_trie/build.rs index 39ad81ed59..45535204e0 100644 --- a/primitives/state-machine/src/changes_trie/build.rs +++ b/primitives/state-machine/src/changes_trie/build.rs @@ -32,6 +32,7 @@ use crate::{ input::{InputKey, InputPair, DigestIndex, ExtrinsicIndex, ChildIndex}, }, }; +use sp_core::storage::{ChildInfo, ChildType, PrefixedStorageKey}; /// Prepare input pairs for building a changes trie of given block. /// @@ -105,19 +106,19 @@ fn prepare_extrinsics_input<'a, B, H, Number>( Number: BlockNumber, { - let mut children_keys = BTreeSet::::new(); + let mut children_info = BTreeSet::::new(); let mut children_result = BTreeMap::new(); - for (storage_key, _) in changes.prospective.children.iter() - .chain(changes.committed.children.iter()) { - children_keys.insert(storage_key.clone()); + for (_storage_key, (_map, child_info)) in changes.prospective.children_default.iter() + .chain(changes.committed.children_default.iter()) { + children_info.insert(child_info.clone()); } - for storage_key in children_keys { + for child_info in children_info { let child_index = ChildIndex:: { block: block.clone(), - storage_key: storage_key.clone(), + storage_key: child_info.prefixed_storage_key(), }; - let iter = prepare_extrinsics_input_inner(backend, block, changes, Some(storage_key))?; + let iter = prepare_extrinsics_input_inner(backend, block, changes, Some(child_info))?; children_result.insert(child_index, iter); } @@ -130,22 +131,22 @@ fn prepare_extrinsics_input_inner<'a, B, H, Number>( backend: &'a B, block: &Number, changes: &'a OverlayedChanges, - storage_key: Option, + child_info: Option, ) -> Result> + 'a, String> where B: Backend, H: Hasher, Number: BlockNumber, { - let (committed, prospective, child_info) = if let Some(sk) = storage_key.as_ref() { - let child_info = changes.child_info(sk).cloned(); - ( - changes.committed.children.get(sk).map(|c| &c.0), - changes.prospective.children.get(sk).map(|c| &c.0), - child_info, - ) + let (committed, prospective) = if let Some(child_info) = child_info.as_ref() { + match child_info.child_type() { + ChildType::ParentKeyId => ( + changes.committed.children_default.get(child_info.storage_key()).map(|c| &c.0), + changes.prospective.children_default.get(child_info.storage_key()).map(|c| &c.0), + ), + } } else { - (Some(&changes.committed.top), Some(&changes.prospective.top), None) + (Some(&changes.committed.top), Some(&changes.prospective.top)) }; committed.iter().flat_map(|c| c.iter()) .chain(prospective.iter().flat_map(|c| c.iter())) @@ -155,13 +156,11 @@ fn prepare_extrinsics_input_inner<'a, B, H, Number>( Entry::Vacant(entry) => { // ignore temporary values (values that have null value at the end of operation // AND are not in storage at the beginning of operation - if let Some(sk) = storage_key.as_ref() { - if !changes.child_storage(sk, k).map(|v| v.is_some()).unwrap_or_default() { - if let Some(child_info) = child_info.as_ref() { - if !backend.exists_child_storage(sk, child_info.as_ref(), k) - .map_err(|e| format!("{}", e))? { - return Ok(map); - } + if let Some(child_info) = child_info.as_ref() { + if !changes.child_storage(child_info, k).map(|v| v.is_some()).unwrap_or_default() { + if !backend.exists_child_storage(&child_info, k) + .map_err(|e| format!("{}", e))? { + return Ok(map); } } } else { @@ -281,7 +280,7 @@ fn prepare_digest_input<'a, H, Number>( return Ok((map, child_map)); } - let mut children_roots = BTreeMap::::new(); + let mut children_roots = BTreeMap::::new(); { let trie_storage = TrieBackendEssence::<_, H>::new( crate::changes_trie::TrieBackendStorageAdapter(storage), @@ -344,22 +343,20 @@ mod test { use codec::Encode; use sp_core::Blake2Hasher; use sp_core::storage::well_known_keys::EXTRINSIC_INDEX; - use sp_core::storage::ChildInfo; use crate::InMemoryBackend; use crate::changes_trie::{RootsStorage, Configuration, storage::InMemoryStorage}; use crate::changes_trie::build_cache::{IncompleteCacheAction, IncompleteCachedBuildData}; use crate::overlayed_changes::{OverlayedValue, OverlayedChangeSet}; use super::*; - const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_1"); - const CHILD_INFO_2: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_2"); - fn prepare_for_build(zero: u64) -> ( InMemoryBackend, InMemoryStorage, OverlayedChanges, Configuration, ) { + let child_info_1 = ChildInfo::new_default(b"storage_key1"); + let child_info_2 = ChildInfo::new_default(b"storage_key2"); let backend: InMemoryBackend<_> = vec![ (vec![100], vec![255]), (vec![101], vec![255]), @@ -368,8 +365,9 @@ mod test { (vec![104], vec![255]), (vec![105], vec![255]), ].into_iter().collect::>().into(); - let child_trie_key1 = b"1".to_vec(); - let child_trie_key2 = b"2".to_vec(); + let prefixed_child_trie_key1 = child_info_1.prefixed_storage_key(); + let child_trie_key1 = child_info_1.storage_key().to_vec(); + let child_trie_key2 = child_info_2.storage_key().to_vec(); let storage = InMemoryStorage::with_inputs(vec![ (zero + 1, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![100] }, vec![1, 3]), @@ -403,7 +401,7 @@ mod test { ]), (zero + 9, Vec::new()), (zero + 10, Vec::new()), (zero + 11, Vec::new()), (zero + 12, Vec::new()), (zero + 13, Vec::new()), (zero + 14, Vec::new()), (zero + 15, Vec::new()), - ], vec![(child_trie_key1.clone(), vec![ + ], vec![(prefixed_child_trie_key1.clone(), vec![ (zero + 1, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![100] }, vec![1, 3]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![101] }, vec![0, 2]), @@ -430,19 +428,19 @@ mod test { extrinsics: Some(vec![0, 1].into_iter().collect()) }), ].into_iter().collect(), - children: vec![ + children_default: vec![ (child_trie_key1.clone(), (vec![ (vec![100], OverlayedValue { value: Some(vec![200]), extrinsics: Some(vec![0, 2].into_iter().collect()) }) - ].into_iter().collect(), CHILD_INFO_1.to_owned())), + ].into_iter().collect(), child_info_1.to_owned())), (child_trie_key2, (vec![ (vec![100], OverlayedValue { value: Some(vec![200]), extrinsics: Some(vec![0, 2].into_iter().collect()) }) - ].into_iter().collect(), CHILD_INFO_2.to_owned())), + ].into_iter().collect(), child_info_2.to_owned())), ].into_iter().collect() }, committed: OverlayedChangeSet { top: vec![ @@ -459,13 +457,13 @@ mod test { extrinsics: Some(vec![1].into_iter().collect()) }), ].into_iter().collect(), - children: vec![ + children_default: vec![ (child_trie_key1, (vec![ (vec![100], OverlayedValue { value: Some(vec![202]), extrinsics: Some(vec![3].into_iter().collect()) }) - ].into_iter().collect(), CHILD_INFO_1.to_owned())), + ].into_iter().collect(), child_info_1.to_owned())), ].into_iter().collect(), }, collect_extrinsics: true, @@ -487,6 +485,8 @@ mod test { #[test] fn build_changes_trie_nodes_on_non_digest_block() { fn test_with_zero(zero: u64) { + let child_trie_key1 = ChildInfo::new_default(b"storage_key1").prefixed_storage_key(); + let child_trie_key2 = ChildInfo::new_default(b"storage_key2").prefixed_storage_key(); let (backend, storage, changes, config) = prepare_for_build(zero); let parent = AnchorBlockId { hash: Default::default(), number: zero + 4 }; let changes_trie_nodes = prepare_input( @@ -503,11 +503,11 @@ mod test { ]); assert_eq!(changes_trie_nodes.1.into_iter() .map(|(k,v)| (k, v.collect::>())).collect::>(), vec![ - (ChildIndex { block: zero + 5u64, storage_key: b"1".to_vec() }, + (ChildIndex { block: zero + 5u64, storage_key: child_trie_key1 }, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5u64, key: vec![100] }, vec![0, 2, 3]), ]), - (ChildIndex { block: zero + 5, storage_key: b"2".to_vec() }, + (ChildIndex { block: zero + 5, storage_key: child_trie_key2 }, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5, key: vec![100] }, vec![0, 2]), ]), @@ -523,6 +523,8 @@ mod test { #[test] fn build_changes_trie_nodes_on_digest_block_l1() { fn test_with_zero(zero: u64) { + let child_trie_key1 = ChildInfo::new_default(b"storage_key1").prefixed_storage_key(); + let child_trie_key2 = ChildInfo::new_default(b"storage_key2").prefixed_storage_key(); let (backend, storage, changes, config) = prepare_for_build(zero); let parent = AnchorBlockId { hash: Default::default(), number: zero + 3 }; let changes_trie_nodes = prepare_input( @@ -544,7 +546,7 @@ mod test { ]); assert_eq!(changes_trie_nodes.1.into_iter() .map(|(k,v)| (k, v.collect::>())).collect::>(), vec![ - (ChildIndex { block: zero + 4u64, storage_key: b"1".to_vec() }, + (ChildIndex { block: zero + 4u64, storage_key: child_trie_key1.clone() }, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4u64, key: vec![100] }, vec![0, 2, 3]), @@ -553,7 +555,7 @@ mod test { InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1]), ]), - (ChildIndex { block: zero + 4, storage_key: b"2".to_vec() }, + (ChildIndex { block: zero + 4, storage_key: child_trie_key2.clone() }, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2]), ]), @@ -568,6 +570,8 @@ mod test { #[test] fn build_changes_trie_nodes_on_digest_block_l2() { fn test_with_zero(zero: u64) { + let child_trie_key1 = ChildInfo::new_default(b"storage_key1").prefixed_storage_key(); + let child_trie_key2 = ChildInfo::new_default(b"storage_key2").prefixed_storage_key(); let (backend, storage, changes, config) = prepare_for_build(zero); let parent = AnchorBlockId { hash: Default::default(), number: zero + 15 }; let changes_trie_nodes = prepare_input( @@ -590,13 +594,13 @@ mod test { ]); assert_eq!(changes_trie_nodes.1.into_iter() .map(|(k,v)| (k, v.collect::>())).collect::>(), vec![ - (ChildIndex { block: zero + 16u64, storage_key: b"1".to_vec() }, + (ChildIndex { block: zero + 16u64, storage_key: child_trie_key1.clone() }, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16u64, key: vec![100] }, vec![0, 2, 3]), InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![102] }, vec![zero + 4]), ]), - (ChildIndex { block: zero + 16, storage_key: b"2".to_vec() }, + (ChildIndex { block: zero + 16, storage_key: child_trie_key2.clone() }, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16, key: vec![100] }, vec![0, 2]), ]), @@ -657,6 +661,8 @@ mod test { #[test] fn build_changes_trie_nodes_ignores_temporary_storage_values() { fn test_with_zero(zero: u64) { + let child_trie_key1 = ChildInfo::new_default(b"storage_key1").prefixed_storage_key(); + let child_trie_key2 = ChildInfo::new_default(b"storage_key2").prefixed_storage_key(); let (backend, storage, mut changes, config) = prepare_for_build(zero); // 110: missing from backend, set to None in overlay @@ -685,7 +691,7 @@ mod test { ]); assert_eq!(changes_trie_nodes.1.into_iter() .map(|(k,v)| (k, v.collect::>())).collect::>(), vec![ - (ChildIndex { block: zero + 4u64, storage_key: b"1".to_vec() }, + (ChildIndex { block: zero + 4u64, storage_key: child_trie_key1.clone() }, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4u64, key: vec![100] }, vec![0, 2, 3]), @@ -694,7 +700,7 @@ mod test { InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1]), ]), - (ChildIndex { block: zero + 4, storage_key: b"2".to_vec() }, + (ChildIndex { block: zero + 4, storage_key: child_trie_key2.clone() }, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2]), ]), @@ -709,6 +715,8 @@ mod test { #[test] fn cache_is_used_when_changes_trie_is_built() { + let child_trie_key1 = ChildInfo::new_default(b"storage_key1").prefixed_storage_key(); + let child_trie_key2 = ChildInfo::new_default(b"storage_key2").prefixed_storage_key(); let (backend, mut storage, changes, config) = prepare_for_build(0); let parent = AnchorBlockId { hash: Default::default(), number: 15 }; @@ -728,8 +736,8 @@ mod test { let cached_data4 = IncompleteCacheAction::CacheBuildData(IncompleteCachedBuildData::new()) .set_digest_input_blocks(vec![1, 2, 3]) .insert(None, vec![vec![100], vec![102]].into_iter().collect()) - .insert(Some(b"1".to_vec()), vec![vec![103], vec![104]].into_iter().collect()) - .insert(Some(b"2".to_vec()), vec![vec![105], vec![106]].into_iter().collect()) + .insert(Some(child_trie_key1.clone()), vec![vec![103], vec![104]].into_iter().collect()) + .insert(Some(child_trie_key2.clone()), vec![vec![105], vec![106]].into_iter().collect()) .complete(4, &trie_root4); storage.cache_mut().perform(cached_data4); @@ -755,7 +763,10 @@ mod test { .map(|(k, i)| (k, i.collect::>())) .collect::>(); assert_eq!( - child_changes_tries_nodes.get(&ChildIndex { block: 16u64, storage_key: b"1".to_vec() }).unwrap(), + child_changes_tries_nodes.get(&ChildIndex { + block: 16u64, + storage_key: child_trie_key1.clone(), + }).unwrap(), &vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16u64, key: vec![100] }, vec![0, 2, 3]), @@ -764,7 +775,7 @@ mod test { ], ); assert_eq!( - child_changes_tries_nodes.get(&ChildIndex { block: 16u64, storage_key: b"2".to_vec() }).unwrap(), + child_changes_tries_nodes.get(&ChildIndex { block: 16u64, storage_key: child_trie_key2.clone() }).unwrap(), &vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16u64, key: vec![100] }, vec![0, 2]), diff --git a/primitives/state-machine/src/changes_trie/build_cache.rs b/primitives/state-machine/src/changes_trie/build_cache.rs index 9d0dbb4c1f..aebebf3a17 100644 --- a/primitives/state-machine/src/changes_trie/build_cache.rs +++ b/primitives/state-machine/src/changes_trie/build_cache.rs @@ -19,6 +19,7 @@ use std::collections::{HashMap, HashSet}; use crate::StorageKey; +use sp_core::storage::PrefixedStorageKey; /// Changes trie build cache. /// @@ -38,7 +39,7 @@ pub struct BuildCache { /// The `Option>` in inner `HashMap` stands for the child storage key. /// If it is `None`, then the `HashSet` contains keys changed in top-level storage. /// If it is `Some`, then the `HashSet` contains keys changed in child storage, identified by the key. - changed_keys: HashMap, HashSet>>, + changed_keys: HashMap, HashSet>>, } /// The action to perform when block-with-changes-trie is imported. @@ -56,7 +57,7 @@ pub struct CachedBuildData { block: N, trie_root: H, digest_input_blocks: Vec, - changed_keys: HashMap, HashSet>, + changed_keys: HashMap, HashSet>, } /// The action to perform when block-with-changes-trie is imported. @@ -72,7 +73,7 @@ pub(crate) enum IncompleteCacheAction { #[derive(Debug, PartialEq)] pub(crate) struct IncompleteCachedBuildData { digest_input_blocks: Vec, - changed_keys: HashMap, HashSet>, + changed_keys: HashMap, HashSet>, } impl BuildCache @@ -89,7 +90,7 @@ impl BuildCache } /// Get cached changed keys for changes trie with given root. - pub fn get(&self, root: &H) -> Option<&HashMap, HashSet>> { + pub fn get(&self, root: &H) -> Option<&HashMap, HashSet>> { self.changed_keys.get(&root) } @@ -98,7 +99,7 @@ impl BuildCache pub fn with_changed_keys( &self, root: &H, - functor: &mut dyn FnMut(&HashMap, HashSet>), + functor: &mut dyn FnMut(&HashMap, HashSet>), ) -> bool { match self.changed_keys.get(&root) { Some(changed_keys) => { @@ -164,7 +165,7 @@ impl IncompleteCacheAction { /// Insert changed keys of given storage into cached data. pub(crate) fn insert( self, - storage_key: Option, + storage_key: Option, changed_keys: HashSet, ) -> Self { match self { @@ -200,7 +201,7 @@ impl IncompleteCachedBuildData { fn insert( mut self, - storage_key: Option, + storage_key: Option, changed_keys: HashSet, ) -> Self { self.changed_keys.insert(storage_key, changed_keys); diff --git a/primitives/state-machine/src/changes_trie/changes_iterator.rs b/primitives/state-machine/src/changes_trie/changes_iterator.rs index 685786218c..f5a936069b 100644 --- a/primitives/state-machine/src/changes_trie/changes_iterator.rs +++ b/primitives/state-machine/src/changes_trie/changes_iterator.rs @@ -22,6 +22,7 @@ use std::collections::VecDeque; use codec::{Decode, Encode, Codec}; use hash_db::Hasher; use num_traits::Zero; +use sp_core::storage::PrefixedStorageKey; use sp_trie::Recorder; use crate::changes_trie::{AnchorBlockId, ConfigurationRange, RootsStorage, Storage, BlockNumber}; use crate::changes_trie::input::{DigestIndex, ExtrinsicIndex, DigestIndexValue, ExtrinsicIndexValue}; @@ -40,7 +41,7 @@ pub fn key_changes<'a, H: Hasher, Number: BlockNumber>( begin: Number, end: &'a AnchorBlockId, max: Number, - storage_key: Option<&'a [u8]>, + storage_key: Option<&'a PrefixedStorageKey>, key: &'a [u8], ) -> Result, String> { // we can't query any roots before root @@ -79,7 +80,7 @@ pub fn key_changes_proof<'a, H: Hasher, Number: BlockNumber>( begin: Number, end: &AnchorBlockId, max: Number, - storage_key: Option<&[u8]>, + storage_key: Option<&PrefixedStorageKey>, key: &[u8], ) -> Result>, String> where H::Out: Codec { // we can't query any roots before root @@ -127,7 +128,7 @@ pub fn key_changes_proof_check<'a, H: Hasher, Number: BlockNumber>( begin: Number, end: &AnchorBlockId, max: Number, - storage_key: Option<&[u8]>, + storage_key: Option<&PrefixedStorageKey>, key: &[u8] ) -> Result, String> where H::Out: Encode { key_changes_proof_check_with_db( @@ -150,7 +151,7 @@ pub fn key_changes_proof_check_with_db<'a, H: Hasher, Number: BlockNumber>( begin: Number, end: &AnchorBlockId, max: Number, - storage_key: Option<&[u8]>, + storage_key: Option<&PrefixedStorageKey>, key: &[u8] ) -> Result, String> where H::Out: Encode { // we can't query any roots before root @@ -188,7 +189,7 @@ pub struct DrilldownIteratorEssence<'a, H, Number> Number: BlockNumber, H::Out: 'a, { - storage_key: Option<&'a [u8]>, + storage_key: Option<&'a PrefixedStorageKey>, key: &'a [u8], roots_storage: &'a dyn RootsStorage, storage: &'a dyn Storage, @@ -238,7 +239,7 @@ impl<'a, H, Number> DrilldownIteratorEssence<'a, H, Number> let trie_root = if let Some(storage_key) = self.storage_key { let child_key = ChildIndex { block: block.clone(), - storage_key: storage_key.to_vec(), + storage_key: storage_key.clone(), }.encode(); if let Some(trie_root) = trie_reader(self.storage, trie_root, &child_key)? .and_then(|v| >::decode(&mut &v[..]).ok()) @@ -382,6 +383,11 @@ mod tests { use sp_runtime::traits::BlakeTwo256; use super::*; + fn child_key() -> PrefixedStorageKey { + let child_info = sp_core::storage::ChildInfo::new_default(&b"1"[..]); + child_info.prefixed_storage_key() + } + fn prepare_for_drilldown() -> (Configuration, InMemoryStorage) { let config = Configuration { digest_interval: 4, digest_levels: 2 }; let backend = InMemoryStorage::with_inputs(vec![ @@ -418,7 +424,7 @@ mod tests { (16, vec![ InputPair::DigestIndex(DigestIndex { block: 16, key: vec![42] }, vec![4, 8]), ]), - ], vec![(b"1".to_vec(), vec![ + ], vec![(child_key(), vec![ (1, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 1, key: vec![42] }, vec![0]), ]), @@ -535,7 +541,7 @@ mod tests { 1, &AnchorBlockId { hash: Default::default(), number: 100 }, 1000, - Some(&b"1"[..]), + Some(&child_key()), &[42], ).and_then(|i| i.collect::, _>>()).is_err()); } @@ -577,7 +583,7 @@ mod tests { let (remote_config, remote_storage) = prepare_for_drilldown(); let remote_proof_child = key_changes_proof::( configuration_range(&remote_config, 0), &remote_storage, 1, - &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&b"1"[..]), &[42]).unwrap(); + &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&child_key()), &[42]).unwrap(); // happens on local light node: @@ -592,7 +598,7 @@ mod tests { local_storage.clear_storage(); let local_result_child = key_changes_proof_check::( configuration_range(&local_config, 0), &local_storage, remote_proof_child, 1, - &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&b"1"[..]), &[42]); + &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&child_key()), &[42]); // check that drilldown result is the same as if it was happening at the full node assert_eq!(local_result, Ok(vec![(8, 2), (8, 1), (6, 3), (3, 0)])); diff --git a/primitives/state-machine/src/changes_trie/input.rs b/primitives/state-machine/src/changes_trie/input.rs index 4a1420f848..4f0f3da40c 100644 --- a/primitives/state-machine/src/changes_trie/input.rs +++ b/primitives/state-machine/src/changes_trie/input.rs @@ -21,6 +21,7 @@ use crate::{ StorageKey, StorageValue, changes_trie::BlockNumber }; +use sp_core::storage::PrefixedStorageKey; /// Key of { changed key => set of extrinsic indices } mapping. #[derive(Clone, Debug, PartialEq, Eq)] @@ -49,7 +50,7 @@ pub struct ChildIndex { /// Block at which this key has been inserted in the trie. pub block: Number, /// Storage key this node is responsible for. - pub storage_key: StorageKey, + pub storage_key: PrefixedStorageKey, } /// Value of { changed key => block/digest block numbers } mapping. @@ -178,7 +179,7 @@ impl Decode for InputKey { })), 3 => Ok(InputKey::ChildIndex(ChildIndex { block: Decode::decode(input)?, - storage_key: Decode::decode(input)?, + storage_key: PrefixedStorageKey::new(Decode::decode(input)?), })), _ => Err("Invalid input key variant".into()), } diff --git a/primitives/state-machine/src/changes_trie/mod.rs b/primitives/state-machine/src/changes_trie/mod.rs index d614992df3..ee6c6778e0 100644 --- a/primitives/state-machine/src/changes_trie/mod.rs +++ b/primitives/state-machine/src/changes_trie/mod.rs @@ -71,6 +71,7 @@ use hash_db::{Hasher, Prefix}; use num_traits::{One, Zero}; use codec::{Decode, Encode}; use sp_core; +use sp_core::storage::PrefixedStorageKey; use sp_trie::{MemoryDB, DBValue, TrieMut}; use sp_trie::trie_types::TrieDBMut; use crate::{ @@ -156,7 +157,7 @@ pub trait Storage: RootsStorage { fn with_cached_changed_keys( &self, root: &H::Out, - functor: &mut dyn FnMut(&HashMap, HashSet>), + functor: &mut dyn FnMut(&HashMap, HashSet>), ) -> bool; /// Get a trie node. fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String>; diff --git a/primitives/state-machine/src/changes_trie/prune.rs b/primitives/state-machine/src/changes_trie/prune.rs index 87923dc2f5..05555df305 100644 --- a/primitives/state-machine/src/changes_trie/prune.rs +++ b/primitives/state-machine/src/changes_trie/prune.rs @@ -137,7 +137,8 @@ mod tests { #[test] fn prune_works() { fn prepare_storage() -> InMemoryStorage { - let child_key = ChildIndex { block: 67u64, storage_key: b"1".to_vec() }.encode(); + let child_info = sp_core::storage::ChildInfo::new_default(&b"1"[..]); + let child_key = ChildIndex { block: 67u64, storage_key: child_info.prefixed_storage_key() }.encode(); let mut mdb1 = MemoryDB::::default(); let root1 = insert_into_memory_db::( &mut mdb1, vec![(vec![10], vec![20])]).unwrap(); diff --git a/primitives/state-machine/src/changes_trie/storage.rs b/primitives/state-machine/src/changes_trie/storage.rs index 7fb4186728..81651dd2e7 100644 --- a/primitives/state-machine/src/changes_trie/storage.rs +++ b/primitives/state-machine/src/changes_trie/storage.rs @@ -18,6 +18,7 @@ use std::collections::{BTreeMap, HashSet, HashMap}; use hash_db::{Hasher, Prefix, EMPTY_PREFIX}; +use sp_core::storage::PrefixedStorageKey; use sp_trie::DBValue; use sp_trie::MemoryDB; use parking_lot::RwLock; @@ -96,7 +97,7 @@ impl InMemoryStorage { #[cfg(test)] pub fn with_inputs( mut top_inputs: Vec<(Number, Vec>)>, - children_inputs: Vec<(StorageKey, Vec<(Number, Vec>)>)>, + children_inputs: Vec<(PrefixedStorageKey, Vec<(Number, Vec>)>)>, ) -> Self { let mut mdb = MemoryDB::default(); let mut roots = BTreeMap::new(); @@ -182,7 +183,7 @@ impl Storage for InMemoryStorage, HashSet>), + functor: &mut dyn FnMut(&HashMap, HashSet>), ) -> bool { self.cache.with_changed_keys(root, functor) } diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index 3a6b544290..399bfc69d8 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -24,10 +24,10 @@ use crate::{ use hash_db::Hasher; use sp_core::{ - storage::{ChildStorageKey, well_known_keys::is_child_storage_key, ChildInfo}, + storage::{well_known_keys::is_child_storage_key, ChildInfo}, traits::Externalities, hexdisplay::HexDisplay, }; -use sp_trie::{trie_types::Layout, default_child_trie_root}; +use sp_trie::{trie_types::Layout, empty_child_trie_root}; use sp_externalities::{Extensions, Extension}; use codec::{Decode, Encode}; @@ -181,22 +181,21 @@ where fn child_storage( &self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Option { let _guard = sp_panic_handler::AbortGuard::force_abort(); let result = self.overlay - .child_storage(storage_key.as_ref(), key) + .child_storage(child_info, key) .map(|x| x.map(|x| x.to_vec())) .unwrap_or_else(|| - self.backend.child_storage(storage_key.as_ref(), child_info, key) + self.backend.child_storage(child_info, key) .expect(EXT_NOT_ALLOWED_TO_FAIL) ); trace!(target: "state-trace", "{:04x}: GetChild({}) {}={:?}", self.id, - HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&child_info.storage_key()), HexDisplay::from(&key), result.as_ref().map(HexDisplay::from) ); @@ -206,22 +205,21 @@ where fn child_storage_hash( &self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Option> { let _guard = sp_panic_handler::AbortGuard::force_abort(); let result = self.overlay - .child_storage(storage_key.as_ref(), key) + .child_storage(child_info, key) .map(|x| x.map(|x| H::hash(x))) .unwrap_or_else(|| - self.backend.child_storage_hash(storage_key.as_ref(), child_info, key) + self.backend.child_storage_hash(child_info, key) .expect(EXT_NOT_ALLOWED_TO_FAIL) ); trace!(target: "state-trace", "{:04x}: ChildHash({}) {}={:?}", self.id, - HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&child_info.storage_key()), HexDisplay::from(&key), result, ); @@ -247,22 +245,21 @@ where fn exists_child_storage( &self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> bool { let _guard = sp_panic_handler::AbortGuard::force_abort(); - let result = match self.overlay.child_storage(storage_key.as_ref(), key) { + let result = match self.overlay.child_storage(child_info, key) { Some(x) => x.is_some(), _ => self.backend - .exists_child_storage(storage_key.as_ref(), child_info, key) + .exists_child_storage(child_info, key) .expect(EXT_NOT_ALLOWED_TO_FAIL), }; trace!(target: "state-trace", "{:04x}: ChildExists({}) {}={:?}", self.id, - HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&child_info.storage_key()), HexDisplay::from(&key), result, ); @@ -286,15 +283,14 @@ where fn next_child_storage_key( &self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Option { let next_backend_key = self.backend - .next_child_storage_key(storage_key.as_ref(), child_info, key) + .next_child_storage_key(child_info, key) .expect(EXT_NOT_ALLOWED_TO_FAIL); let next_overlay_key_change = self.overlay.next_child_storage_key_change( - storage_key.as_ref(), + child_info.storage_key(), key ); @@ -305,7 +301,6 @@ where Some(overlay_key.0.to_vec()) } else { self.next_child_storage_key( - storage_key, child_info, &overlay_key.0[..], ) @@ -331,38 +326,36 @@ where fn place_child_storage( &mut self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: StorageKey, value: Option, ) { trace!(target: "state-trace", "{:04x}: PutChild({}) {}={:?}", self.id, - HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&child_info.storage_key()), HexDisplay::from(&key), value.as_ref().map(HexDisplay::from) ); let _guard = sp_panic_handler::AbortGuard::force_abort(); self.mark_dirty(); - self.overlay.set_child_storage(storage_key.into_owned(), child_info, key, value); + self.overlay.set_child_storage(child_info, key, value); } fn kill_child_storage( &mut self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, ) { trace!(target: "state-trace", "{:04x}: KillChild({})", self.id, - HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&child_info.storage_key()), ); let _guard = sp_panic_handler::AbortGuard::force_abort(); self.mark_dirty(); - self.overlay.clear_child_storage(storage_key.as_ref(), child_info); - self.backend.for_keys_in_child_storage(storage_key.as_ref(), child_info, |key| { - self.overlay.set_child_storage(storage_key.as_ref().to_vec(), child_info, key.to_vec(), None); + self.overlay.clear_child_storage(child_info); + self.backend.for_keys_in_child_storage(child_info, |key| { + self.overlay.set_child_storage(child_info, key.to_vec(), None); }); } @@ -386,21 +379,20 @@ where fn clear_child_prefix( &mut self, - storage_key: ChildStorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], ) { trace!(target: "state-trace", "{:04x}: ClearChildPrefix({}) {}", self.id, - HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&child_info.storage_key()), HexDisplay::from(&prefix), ); let _guard = sp_panic_handler::AbortGuard::force_abort(); self.mark_dirty(); - self.overlay.clear_child_prefix(storage_key.as_ref(), child_info, prefix); - self.backend.for_child_keys_with_prefix(storage_key.as_ref(), child_info, prefix, |key| { - self.overlay.set_child_storage(storage_key.as_ref().to_vec(), child_info, key.to_vec(), None); + self.overlay.clear_child_prefix(child_info, prefix); + self.backend.for_child_keys_with_prefix(child_info, prefix, |key| { + self.overlay.set_child_storage(child_info, key.to_vec(), None); }); } @@ -425,37 +417,38 @@ where fn child_storage_root( &mut self, - storage_key: ChildStorageKey, + child_info: &ChildInfo, ) -> Vec { let _guard = sp_panic_handler::AbortGuard::force_abort(); + let storage_key = child_info.storage_key(); + let prefixed_storage_key = child_info.prefixed_storage_key(); if self.storage_transaction_cache.transaction_storage_root.is_some() { let root = self - .storage(storage_key.as_ref()) + .storage(prefixed_storage_key.as_slice()) .and_then(|k| Decode::decode(&mut &k[..]).ok()) .unwrap_or( - default_child_trie_root::>(storage_key.as_ref()) + empty_child_trie_root::>() ); trace!(target: "state-trace", "{:04x}: ChildRoot({}) (cached) {}", self.id, - HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&storage_key), HexDisplay::from(&root.as_ref()), ); root.encode() } else { - let storage_key = storage_key.as_ref(); - if let Some(child_info) = self.overlay.child_info(storage_key).cloned() { + if let Some(child_info) = self.overlay.default_child_info(storage_key).cloned() { let (root, is_empty, _) = { - let delta = self.overlay.committed.children.get(storage_key) + let delta = self.overlay.committed.children_default.get(storage_key) .into_iter() .flat_map(|(map, _)| map.clone().into_iter().map(|(k, v)| (k, v.value))) .chain( - self.overlay.prospective.children.get(storage_key) + self.overlay.prospective.children_default.get(storage_key) .into_iter() .flat_map(|(map, _)| map.clone().into_iter().map(|(k, v)| (k, v.value))) ); - self.backend.child_storage_root(storage_key, child_info.as_ref(), delta) + self.backend.child_storage_root(&child_info, delta) }; let root = root.encode(); @@ -465,9 +458,9 @@ where // A better design would be to manage 'child_storage_transaction' in a // similar way as 'storage_transaction' but for each child trie. if is_empty { - self.overlay.set_storage(storage_key.into(), None); + self.overlay.set_storage(prefixed_storage_key.into_inner(), None); } else { - self.overlay.set_storage(storage_key.into(), Some(root.clone())); + self.overlay.set_storage(prefixed_storage_key.into_inner(), Some(root.clone())); } trace!(target: "state-trace", "{:04x}: ChildRoot({}) {}", @@ -479,10 +472,10 @@ where } else { // empty overlay let root = self - .storage(storage_key.as_ref()) + .storage(prefixed_storage_key.as_slice()) .and_then(|k| Decode::decode(&mut &k[..]).ok()) .unwrap_or( - default_child_trie_root::>(storage_key.as_ref()) + empty_child_trie_root::>() ); trace!(target: "state-trace", "{:04x}: ChildRoot({}) (no change) {}", self.id, @@ -591,11 +584,6 @@ mod tests { type TestBackend = InMemoryBackend; type TestExt<'a> = Ext<'a, Blake2Hasher, u64, TestBackend>; - const CHILD_KEY_1: &[u8] = b":child_storage:default:Child1"; - - const CHILD_UUID_1: &[u8] = b"unique_id_1"; - const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(CHILD_UUID_1); - fn prepare_overlay_with_changes() -> OverlayedChanges { OverlayedChanges { prospective: vec![ @@ -680,7 +668,7 @@ mod tests { vec![20] => vec![20], vec![40] => vec![40] ], - children: map![] + children_default: map![] }.into(); let ext = TestExt::new(&mut overlay, &mut cache, &backend, None, None); @@ -707,26 +695,23 @@ mod tests { #[test] fn next_child_storage_key_works() { - const CHILD_KEY_1: &[u8] = b":child_storage:default:Child1"; - - const CHILD_UUID_1: &[u8] = b"unique_id_1"; - const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(CHILD_UUID_1); + let child_info = ChildInfo::new_default(b"Child1"); + let child_info = &child_info; let mut cache = StorageTransactionCache::default(); - let child = || ChildStorageKey::from_slice(CHILD_KEY_1).unwrap(); let mut overlay = OverlayedChanges::default(); - overlay.set_child_storage(child().as_ref().to_vec(), CHILD_INFO_1, vec![20], None); - overlay.set_child_storage(child().as_ref().to_vec(), CHILD_INFO_1, vec![30], Some(vec![31])); + overlay.set_child_storage(child_info, vec![20], None); + overlay.set_child_storage(child_info, vec![30], Some(vec![31])); let backend = Storage { top: map![], - children: map![ - child().as_ref().to_vec() => StorageChild { + children_default: map![ + child_info.storage_key().to_vec() => StorageChild { data: map![ vec![10] => vec![10], vec![20] => vec![20], vec![40] => vec![40] ], - child_info: CHILD_INFO_1.to_owned(), + child_info: child_info.to_owned(), } ], }.into(); @@ -735,65 +720,65 @@ mod tests { let ext = TestExt::new(&mut overlay, &mut cache, &backend, None, None); // next_backend < next_overlay - assert_eq!(ext.next_child_storage_key(child(), CHILD_INFO_1, &[5]), Some(vec![10])); + assert_eq!(ext.next_child_storage_key(child_info, &[5]), Some(vec![10])); // next_backend == next_overlay but next_overlay is a delete - assert_eq!(ext.next_child_storage_key(child(), CHILD_INFO_1, &[10]), Some(vec![30])); + assert_eq!(ext.next_child_storage_key(child_info, &[10]), Some(vec![30])); // next_overlay < next_backend - assert_eq!(ext.next_child_storage_key(child(), CHILD_INFO_1, &[20]), Some(vec![30])); + assert_eq!(ext.next_child_storage_key(child_info, &[20]), Some(vec![30])); // next_backend exist but next_overlay doesn't exist - assert_eq!(ext.next_child_storage_key(child(), CHILD_INFO_1, &[30]), Some(vec![40])); + assert_eq!(ext.next_child_storage_key(child_info, &[30]), Some(vec![40])); drop(ext); - overlay.set_child_storage(child().as_ref().to_vec(), CHILD_INFO_1, vec![50], Some(vec![50])); + overlay.set_child_storage(child_info, vec![50], Some(vec![50])); let ext = TestExt::new(&mut overlay, &mut cache, &backend, None, None); // next_overlay exist but next_backend doesn't exist - assert_eq!(ext.next_child_storage_key(child(), CHILD_INFO_1, &[40]), Some(vec![50])); + assert_eq!(ext.next_child_storage_key(child_info, &[40]), Some(vec![50])); } #[test] fn child_storage_works() { + let child_info = ChildInfo::new_default(b"Child1"); + let child_info = &child_info; let mut cache = StorageTransactionCache::default(); - let child = || ChildStorageKey::from_slice(CHILD_KEY_1).unwrap(); let mut overlay = OverlayedChanges::default(); - overlay.set_child_storage(child().as_ref().to_vec(), CHILD_INFO_1, vec![20], None); - overlay.set_child_storage(child().as_ref().to_vec(), CHILD_INFO_1, vec![30], Some(vec![31])); + overlay.set_child_storage(child_info, vec![20], None); + overlay.set_child_storage(child_info, vec![30], Some(vec![31])); let backend = Storage { top: map![], - children: map![ - child().as_ref().to_vec() => StorageChild { + children_default: map![ + child_info.storage_key().to_vec() => StorageChild { data: map![ vec![10] => vec![10], vec![20] => vec![20], vec![30] => vec![40] ], - child_info: CHILD_INFO_1.to_owned(), + child_info: child_info.to_owned(), } ], }.into(); let ext = TestExt::new(&mut overlay, &mut cache, &backend, None, None); - assert_eq!(ext.child_storage(child(), CHILD_INFO_1, &[10]), Some(vec![10])); + assert_eq!(ext.child_storage(child_info, &[10]), Some(vec![10])); assert_eq!( - ext.child_storage_hash(child(), CHILD_INFO_1, &[10]), + ext.child_storage_hash(child_info, &[10]), Some(Blake2Hasher::hash(&[10]).as_ref().to_vec()), ); - assert_eq!(ext.child_storage(child(), CHILD_INFO_1, &[20]), None); + assert_eq!(ext.child_storage(child_info, &[20]), None); assert_eq!( - ext.child_storage_hash(child(), CHILD_INFO_1, &[20]), + ext.child_storage_hash(child_info, &[20]), None, ); - assert_eq!(ext.child_storage(child(), CHILD_INFO_1, &[30]), Some(vec![31])); + assert_eq!(ext.child_storage(child_info, &[30]), Some(vec![31])); assert_eq!( - ext.child_storage_hash(child(), CHILD_INFO_1, &[30]), + ext.child_storage_hash(child_info, &[30]), Some(Blake2Hasher::hash(&[31]).as_ref().to_vec()), ); - } } diff --git a/primitives/state-machine/src/in_memory_backend.rs b/primitives/state-machine/src/in_memory_backend.rs index ecd4532cf2..83126abbf7 100644 --- a/primitives/state-machine/src/in_memory_backend.rs +++ b/primitives/state-machine/src/in_memory_backend.rs @@ -25,10 +25,10 @@ use crate::{ use std::{error, fmt, collections::{BTreeMap, HashMap}, marker::PhantomData, ops}; use hash_db::Hasher; use sp_trie::{ - MemoryDB, child_trie_root, default_child_trie_root, TrieConfiguration, trie_types::Layout, + MemoryDB, child_trie_root, empty_child_trie_root, TrieConfiguration, trie_types::Layout, }; use codec::Codec; -use sp_core::storage::{ChildInfo, OwnedChildInfo, Storage}; +use sp_core::storage::{ChildInfo, ChildType, Storage}; /// Error impossible. // FIXME: use `!` type when stabilized. https://github.com/rust-lang/rust/issues/35121 @@ -48,7 +48,7 @@ impl error::Error for Void { /// In-memory backend. Fully recomputes tries each time `as_trie_backend` is called but useful for /// tests and proof checking. pub struct InMemory { - inner: HashMap, BTreeMap>, + inner: HashMap, BTreeMap>, // This field is only needed for returning reference in `as_trie_backend`. trie: Option, H>>, _hasher: PhantomData, @@ -89,7 +89,7 @@ impl PartialEq for InMemory { impl InMemory { /// Copy the state, with applied updates pub fn update< - T: IntoIterator, StorageCollection)> + T: IntoIterator, StorageCollection)> >( &self, changes: T, @@ -108,10 +108,10 @@ impl InMemory { } } -impl From, BTreeMap>> +impl From, BTreeMap>> for InMemory { - fn from(inner: HashMap, BTreeMap>) -> Self { + fn from(inner: HashMap, BTreeMap>) -> Self { InMemory { inner, trie: None, @@ -122,8 +122,8 @@ impl From, BTreeMap From for InMemory { fn from(inners: Storage) -> Self { - let mut inner: HashMap, BTreeMap> - = inners.children.into_iter().map(|(k, c)| (Some((k, c.child_info)), c.data)).collect(); + let mut inner: HashMap, BTreeMap> + = inners.children_default.into_iter().map(|(_k, c)| (Some(c.child_info), c.data)).collect(); inner.insert(None, inners.top); InMemory { inner, @@ -145,12 +145,12 @@ impl From> for InMemory { } } -impl From, StorageCollection)>> +impl From, StorageCollection)>> for InMemory { fn from( - inner: Vec<(Option<(StorageKey, OwnedChildInfo)>, StorageCollection)>, + inner: Vec<(Option, StorageCollection)>, ) -> Self { - let mut expanded: HashMap, BTreeMap> + let mut expanded: HashMap, BTreeMap> = HashMap::new(); for (child_info, key_values) in inner { let entry = expanded.entry(child_info).or_default(); @@ -165,18 +165,16 @@ impl From, StorageCollectio } impl InMemory { - /// child storage key iterator - pub fn child_storage_keys(&self) -> impl Iterator { - self.inner.iter().filter_map(|item| - item.0.as_ref().map(|v|(&v.0[..], v.1.as_ref())) - ) + /// Child storage infos iterator. + pub fn child_storage_infos(&self) -> impl Iterator { + self.inner.iter().filter_map(|item| item.0.as_ref()) } } impl Backend for InMemory where H::Out: Codec { type Error = Void; type Transaction = Vec<( - Option<(StorageKey, OwnedChildInfo)>, + Option, StorageCollection, )>; type TrieBackendStorage = MemoryDB; @@ -187,11 +185,10 @@ impl Backend for InMemory where H::Out: Codec { fn child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result, Self::Error> { - Ok(self.inner.get(&Some((storage_key.to_vec(), child_info.to_owned()))) + Ok(self.inner.get(&Some(child_info.to_owned())) .and_then(|map| map.get(key).map(Clone::clone))) } @@ -211,22 +208,20 @@ impl Backend for InMemory where H::Out: Codec { fn for_keys_in_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, mut f: F, ) { - self.inner.get(&Some((storage_key.to_vec(), child_info.to_owned()))) + self.inner.get(&Some(child_info.to_owned())) .map(|map| map.keys().for_each(|k| f(&k))); } fn for_child_keys_with_prefix( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], f: F, ) { - self.inner.get(&Some((storage_key.to_vec(), child_info.to_owned()))) + self.inner.get(&Some(child_info.to_owned())) .map(|map| map.keys().filter(|key| key.starts_with(prefix)).map(|k| &**k).for_each(f)); } @@ -253,16 +248,15 @@ impl Backend for InMemory where H::Out: Codec { fn child_storage_root( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, delta: I, ) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, H::Out: Ord { - let storage_key = storage_key.to_vec(); - let child_info = Some((storage_key.clone(), child_info.to_owned())); + let child_type = child_info.child_type(); + let child_info = Some(child_info.to_owned()); let existing_pairs = self.inner.get(&child_info) .into_iter() @@ -270,7 +264,6 @@ impl Backend for InMemory where H::Out: Codec { let transaction: Vec<_> = delta.into_iter().collect(); let root = child_trie_root::, _, _, _>( - &storage_key, existing_pairs.chain(transaction.iter().cloned()) .collect::>() .into_iter() @@ -279,7 +272,9 @@ impl Backend for InMemory where H::Out: Codec { let full_transaction = transaction.into_iter().collect(); - let is_default = root == default_child_trie_root::>(&storage_key); + let is_default = match child_type { + ChildType::ParentKeyId => root == empty_child_trie_root::>(), + }; (root, is_default, vec![(child_info, full_transaction)]) } @@ -294,12 +289,11 @@ impl Backend for InMemory where H::Out: Codec { fn next_child_storage_key( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result, Self::Error> { let range = (ops::Bound::Excluded(key), ops::Bound::Unbounded); - let next_key = self.inner.get(&Some((storage_key.to_vec(), child_info.to_owned()))) + let next_key = self.inner.get(&Some(child_info.to_owned())) .and_then(|map| map.range::<[u8], _>(range).next().map(|(k, _)| k).cloned()); Ok(next_key) @@ -321,11 +315,10 @@ impl Backend for InMemory where H::Out: Codec { fn child_keys( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], ) -> Vec { - self.inner.get(&Some((storage_key.to_vec(), child_info.to_owned()))) + self.inner.get(&Some(child_info.to_owned())) .into_iter() .flat_map(|map| map.keys().filter(|k| k.starts_with(prefix)).cloned()) .collect() @@ -336,11 +329,10 @@ impl Backend for InMemory where H::Out: Codec { let mut new_child_roots = Vec::new(); let mut root_map = None; for (child_info, map) in &self.inner { - if let Some((storage_key, _child_info)) = child_info.as_ref() { - // no need to use child_info at this point because we use a MemoryDB for - // proof (with PrefixedMemoryDB it would be needed). + if let Some(child_info) = child_info.as_ref() { + let prefix_storage_key = child_info.prefixed_storage_key(); let ch = insert_into_memory_db::(&mut mdb, map.clone().into_iter())?; - new_child_roots.push((storage_key.clone(), ch.as_ref().into())); + new_child_roots.push((prefix_storage_key.into_inner(), ch.as_ref().into())); } else { root_map = Some(map); } @@ -379,16 +371,18 @@ mod tests { #[test] fn in_memory_with_child_trie_only() { let storage = InMemory::::default(); - let child_info = OwnedChildInfo::new_default(b"unique_id_1".to_vec()); + let child_info = ChildInfo::new_default(b"1"); + let child_info = &child_info; let mut storage = storage.update( vec![( - Some((b"1".to_vec(), child_info.clone())), + Some(child_info.clone()), vec![(b"2".to_vec(), Some(b"3".to_vec()))] )] ); let trie_backend = storage.as_trie_backend().unwrap(); - assert_eq!(trie_backend.child_storage(b"1", child_info.as_ref(), b"2").unwrap(), + assert_eq!(trie_backend.child_storage(child_info, b"2").unwrap(), Some(b"3".to_vec())); - assert!(trie_backend.storage(b"1").unwrap().is_some()); + let storage_key = child_info.prefixed_storage_key(); + assert!(trie_backend.storage(storage_key.as_slice()).unwrap().is_some()); } } diff --git a/primitives/state-machine/src/lib.rs b/primitives/state-machine/src/lib.rs index 9a2dc52cca..1c0007c5f9 100644 --- a/primitives/state-machine/src/lib.rs +++ b/primitives/state-machine/src/lib.rs @@ -606,8 +606,7 @@ where /// Generate child storage read proof. pub fn prove_child_read( mut backend: B, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, keys: I, ) -> Result> where @@ -619,7 +618,7 @@ where { let trie_backend = backend.as_trie_backend() .ok_or_else(|| Box::new(ExecutionError::UnableToGenerateProof) as Box)?; - prove_child_read_on_trie_backend(trie_backend, storage_key, child_info, keys) + prove_child_read_on_trie_backend(trie_backend, child_info, keys) } /// Generate storage read proof on pre-created trie backend. @@ -646,8 +645,7 @@ where /// Generate storage read proof on pre-created trie backend. pub fn prove_child_read_on_trie_backend( trie_backend: &TrieBackend, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, keys: I, ) -> Result> where @@ -660,7 +658,7 @@ where let proving_backend = proving_backend::ProvingBackend::<_, H>::new(trie_backend); for key in keys.into_iter() { proving_backend - .child_storage(storage_key, child_info.clone(), key.as_ref()) + .child_storage(child_info, key.as_ref()) .map_err(|e| Box::new(e) as Box)?; } Ok(proving_backend.extract_proof()) @@ -691,7 +689,7 @@ where pub fn read_child_proof_check( root: H::Out, proof: StorageProof, - storage_key: &[u8], + child_info: &ChildInfo, keys: I, ) -> Result, Option>>, Box> where @@ -705,7 +703,7 @@ where for key in keys.into_iter() { let value = read_child_proof_check_on_proving_backend( &proving_backend, - storage_key, + child_info, key.as_ref(), )?; result.insert(key.as_ref().to_vec(), value); @@ -728,15 +726,14 @@ where /// Check child storage read proof on pre-created proving backend. pub fn read_child_proof_check_on_proving_backend( proving_backend: &TrieBackend, H>, - storage_key: &[u8], + child_info: &ChildInfo, key: &[u8], ) -> Result>, Box> where H: Hasher, H::Out: Ord + Codec, { - // Not a prefixed memory db, using empty unique id and include root resolution. - proving_backend.child_storage(storage_key, ChildInfo::new_default(&[]), key) + proving_backend.child_storage(child_info, key) .map_err(|e| Box::new(e) as Box) } @@ -748,7 +745,7 @@ mod tests { use super::*; use super::ext::Ext; use super::changes_trie::Configuration as ChangesTrieConfig; - use sp_core::{map, traits::{Externalities, RuntimeCode}, storage::ChildStorageKey}; + use sp_core::{map, traits::{Externalities, RuntimeCode}}; use sp_runtime::traits::BlakeTwo256; #[derive(Clone)] @@ -759,8 +756,6 @@ mod tests { fallback_succeeds: bool, } - const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_1"); - impl CodeExecutor for DummyCodeExecutor { type Error = u8; @@ -1003,6 +998,8 @@ mod tests { #[test] fn set_child_storage_works() { + let child_info = ChildInfo::new_default(b"sub1"); + let child_info = &child_info; let mut state = InMemoryBackend::::default(); let backend = state.as_trie_backend().unwrap(); let mut overlay = OverlayedChanges::default(); @@ -1016,27 +1013,23 @@ mod tests { ); ext.set_child_storage( - ChildStorageKey::from_slice(b":child_storage:default:testchild").unwrap(), - CHILD_INFO_1, + child_info, b"abc".to_vec(), b"def".to_vec() ); assert_eq!( ext.child_storage( - ChildStorageKey::from_slice(b":child_storage:default:testchild").unwrap(), - CHILD_INFO_1, + child_info, b"abc" ), Some(b"def".to_vec()) ); ext.kill_child_storage( - ChildStorageKey::from_slice(b":child_storage:default:testchild").unwrap(), - CHILD_INFO_1, + child_info, ); assert_eq!( ext.child_storage( - ChildStorageKey::from_slice(b":child_storage:default:testchild").unwrap(), - CHILD_INFO_1, + child_info, b"abc" ), None @@ -1045,6 +1038,8 @@ mod tests { #[test] fn prove_read_and_proof_check_works() { + let child_info = ChildInfo::new_default(b"sub1"); + let child_info = &child_info; // fetch read proof from 'remote' full node let remote_backend = trie_backend::tests::test_trie(); let remote_root = remote_backend.storage_root(::std::iter::empty()).0; @@ -1071,20 +1066,19 @@ mod tests { let remote_root = remote_backend.storage_root(::std::iter::empty()).0; let remote_proof = prove_child_read( remote_backend, - b":child_storage:default:sub1", - CHILD_INFO_1, + child_info, &[b"value3"], ).unwrap(); let local_result1 = read_child_proof_check::( remote_root, remote_proof.clone(), - b":child_storage:default:sub1", + child_info, &[b"value3"], ).unwrap(); let local_result2 = read_child_proof_check::( remote_root, remote_proof.clone(), - b":child_storage:default:sub1", + child_info, &[b"value2"], ).unwrap(); assert_eq!( @@ -1099,13 +1093,13 @@ mod tests { #[test] fn child_storage_uuid() { - const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_1"); - const CHILD_INFO_2: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_2"); + + let child_info_1 = ChildInfo::new_default(b"sub_test1"); + let child_info_2 = ChildInfo::new_default(b"sub_test2"); + use crate::trie_backend::tests::test_trie; let mut overlay = OverlayedChanges::default(); - let subtrie1 = ChildStorageKey::from_slice(b":child_storage:default:sub_test1").unwrap(); - let subtrie2 = ChildStorageKey::from_slice(b":child_storage:default:sub_test2").unwrap(); let mut transaction = { let backend = test_trie(); let mut cache = StorageTransactionCache::default(); @@ -1116,8 +1110,8 @@ mod tests { changes_trie::disabled_state::<_, u64>(), None, ); - ext.set_child_storage(subtrie1, CHILD_INFO_1, b"abc".to_vec(), b"def".to_vec()); - ext.set_child_storage(subtrie2, CHILD_INFO_2, b"abc".to_vec(), b"def".to_vec()); + ext.set_child_storage(&child_info_1, b"abc".to_vec(), b"def".to_vec()); + ext.set_child_storage(&child_info_2, b"abc".to_vec(), b"def".to_vec()); ext.storage_root(); cache.transaction.unwrap() }; diff --git a/primitives/state-machine/src/overlayed_changes.rs b/primitives/state-machine/src/overlayed_changes.rs index ab50c61391..f57d13ee3f 100644 --- a/primitives/state-machine/src/overlayed_changes.rs +++ b/primitives/state-machine/src/overlayed_changes.rs @@ -29,7 +29,7 @@ use crate::{ use std::iter::FromIterator; use std::collections::{HashMap, BTreeMap, BTreeSet}; use codec::{Decode, Encode}; -use sp_core::storage::{well_known_keys::EXTRINSIC_INDEX, OwnedChildInfo, ChildInfo}; +use sp_core::storage::{well_known_keys::EXTRINSIC_INDEX, ChildInfo}; use std::{mem, ops}; use hash_db::Hasher; @@ -79,8 +79,8 @@ pub struct OverlayedValue { pub struct OverlayedChangeSet { /// Top level storage changes. pub top: BTreeMap, - /// Child storage changes. - pub children: HashMap, OwnedChildInfo)>, + /// Child storage changes. The map key is the child storage key without the common prefix. + pub children_default: HashMap, ChildInfo)>, } /// A storage changes structure that can be generated by the data collected in [`OverlayedChanges`]. @@ -174,7 +174,7 @@ impl FromIterator<(StorageKey, OverlayedValue)> for OverlayedChangeSet { fn from_iter>(iter: T) -> Self { Self { top: iter.into_iter().collect(), - children: Default::default(), + children_default: Default::default(), } } } @@ -182,13 +182,13 @@ impl FromIterator<(StorageKey, OverlayedValue)> for OverlayedChangeSet { impl OverlayedChangeSet { /// Whether the change set is empty. pub fn is_empty(&self) -> bool { - self.top.is_empty() && self.children.is_empty() + self.top.is_empty() && self.children_default.is_empty() } /// Clear the change set. pub fn clear(&mut self) { self.top.clear(); - self.children.clear(); + self.children_default.clear(); } } @@ -219,8 +219,8 @@ impl OverlayedChanges { /// Returns a double-Option: None if the key is unknown (i.e. and the query should be referred /// to the backend); Some(None) if the key has been deleted. Some(Some(...)) for a key whose /// value has been set. - pub fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Option> { - if let Some(map) = self.prospective.children.get(storage_key) { + pub fn child_storage(&self, child_info: &ChildInfo, key: &[u8]) -> Option> { + if let Some(map) = self.prospective.children_default.get(child_info.storage_key()) { if let Some(val) = map.0.get(key) { let size_read = val.value.as_ref().map(|x| x.len() as u64).unwrap_or(0); self.stats.tally_read_modified(size_read); @@ -228,7 +228,7 @@ impl OverlayedChanges { } } - if let Some(map) = self.committed.children.get(storage_key) { + if let Some(map) = self.committed.children_default.get(child_info.storage_key()) { if let Some(val) = map.0.get(key) { let size_read = val.value.as_ref().map(|x| x.len() as u64).unwrap_or(0); self.stats.tally_read_modified(size_read); @@ -260,15 +260,15 @@ impl OverlayedChanges { /// `None` can be used to delete a value specified by the given key. pub(crate) fn set_child_storage( &mut self, - storage_key: StorageKey, - child_info: ChildInfo, + child_info: &ChildInfo, key: StorageKey, val: Option, ) { let size_write = val.as_ref().map(|x| x.len() as u64).unwrap_or(0); self.stats.tally_write_overlay(size_write); let extrinsic_index = self.extrinsic_index(); - let map_entry = self.prospective.children.entry(storage_key) + let storage_key = child_info.storage_key().to_vec(); + let map_entry = self.prospective.children_default.entry(storage_key) .or_insert_with(|| (Default::default(), child_info.to_owned())); let updatable = map_entry.1.try_update(child_info); debug_assert!(updatable); @@ -290,11 +290,11 @@ impl OverlayedChanges { /// [`discard_prospective`]: #method.discard_prospective pub(crate) fn clear_child_storage( &mut self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, ) { let extrinsic_index = self.extrinsic_index(); - let map_entry = self.prospective.children.entry(storage_key.to_vec()) + let storage_key = child_info.storage_key(); + let map_entry = self.prospective.children_default.entry(storage_key.to_vec()) .or_insert_with(|| (Default::default(), child_info.to_owned())); let updatable = map_entry.1.try_update(child_info); debug_assert!(updatable); @@ -308,7 +308,7 @@ impl OverlayedChanges { e.value = None; }); - if let Some((committed_map, _child_info)) = self.committed.children.get(storage_key) { + if let Some((committed_map, _child_info)) = self.committed.children_default.get(storage_key) { for (key, value) in committed_map.iter() { if !map_entry.0.contains_key(key) { map_entry.0.insert(key.clone(), OverlayedValue { @@ -364,12 +364,12 @@ impl OverlayedChanges { pub(crate) fn clear_child_prefix( &mut self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], ) { let extrinsic_index = self.extrinsic_index(); - let map_entry = self.prospective.children.entry(storage_key.to_vec()) + let storage_key = child_info.storage_key(); + let map_entry = self.prospective.children_default.entry(storage_key.to_vec()) .or_insert_with(|| (Default::default(), child_info.to_owned())); let updatable = map_entry.1.try_update(child_info); debug_assert!(updatable); @@ -385,7 +385,7 @@ impl OverlayedChanges { } } - if let Some((child_committed, _child_info)) = self.committed.children.get(storage_key) { + if let Some((child_committed, _child_info)) = self.committed.children_default.get(storage_key) { // Then do the same with keys from committed changes. // NOTE that we are making changes in the prospective change set. for key in child_committed.keys() { @@ -422,8 +422,8 @@ impl OverlayedChanges { .extend(prospective_extrinsics); } } - for (storage_key, (map, child_info)) in self.prospective.children.drain() { - let child_content = self.committed.children.entry(storage_key) + for (storage_key, (map, child_info)) in self.prospective.children_default.drain() { + let child_content = self.committed.children_default.entry(storage_key) .or_insert_with(|| (Default::default(), child_info)); // No update to child info at this point (will be needed for deletion). for (key, val) in map.into_iter() { @@ -445,14 +445,14 @@ impl OverlayedChanges { /// Will panic if there are any uncommitted prospective changes. fn drain_committed(&mut self) -> ( impl Iterator)>, - impl Iterator)>, OwnedChildInfo))>, + impl Iterator)>, ChildInfo))>, ) { assert!(self.prospective.is_empty()); ( std::mem::replace(&mut self.committed.top, Default::default()) .into_iter() .map(|(k, v)| (k, v.value)), - std::mem::replace(&mut self.committed.children, Default::default()) + std::mem::replace(&mut self.committed.children_default, Default::default()) .into_iter() .map(|(sk, (v, ci))| (sk, (v.into_iter().map(|(k, v)| (k, v.value)), ci))), ) @@ -549,21 +549,20 @@ impl OverlayedChanges { ) -> H::Out where H::Out: Ord + Encode, { - let child_storage_keys = self.prospective.children.keys() - .chain(self.committed.children.keys()); + let child_storage_keys = self.prospective.children_default.keys() + .chain(self.committed.children_default.keys()); let child_delta_iter = child_storage_keys.map(|storage_key| ( - storage_key.clone(), - self.committed.children.get(storage_key) + self.default_child_info(storage_key).cloned() + .expect("child info initialized in either committed or prospective"), + self.committed.children_default.get(storage_key) .into_iter() .flat_map(|(map, _)| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))) .chain( - self.prospective.children.get(storage_key) + self.prospective.children_default.get(storage_key) .into_iter() .flat_map(|(map, _)| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))) ), - self.child_info(storage_key).cloned() - .expect("child info initialized in either committed or prospective"), ) ); @@ -610,11 +609,11 @@ impl OverlayedChanges { /// Get child info for a storage key. /// Take the latest value so prospective first. - pub fn child_info(&self, storage_key: &[u8]) -> Option<&OwnedChildInfo> { - if let Some((_, ci)) = self.prospective.children.get(storage_key) { + pub fn default_child_info(&self, storage_key: &[u8]) -> Option<&ChildInfo> { + if let Some((_, ci)) = self.prospective.children_default.get(storage_key) { return Some(&ci); } - if let Some((_, ci)) = self.committed.children.get(storage_key) { + if let Some((_, ci)) = self.committed.children_default.get(storage_key) { return Some(&ci); } None @@ -654,10 +653,10 @@ impl OverlayedChanges { ) -> Option<(&[u8], &OverlayedValue)> { let range = (ops::Bound::Excluded(key), ops::Bound::Unbounded); - let next_prospective_key = self.prospective.children.get(storage_key) + let next_prospective_key = self.prospective.children_default.get(storage_key) .and_then(|(map, _)| map.range::<[u8], _>(range).next().map(|(k, v)| (&k[..], v))); - let next_committed_key = self.committed.children.get(storage_key) + let next_committed_key = self.committed.children_default.get(storage_key) .and_then(|(map, _)| map.range::<[u8], _>(range).next().map(|(k, v)| (&k[..], v))); match (next_committed_key, next_prospective_key) { @@ -866,39 +865,40 @@ mod tests { #[test] fn next_child_storage_key_change_works() { - let child = b"Child1".to_vec(); - let child_info = ChildInfo::new_default(b"uniqueid"); + let child_info = ChildInfo::new_default(b"Child1"); + let child_info = &child_info; + let child = child_info.storage_key(); let mut overlay = OverlayedChanges::default(); - overlay.set_child_storage(child.clone(), child_info, vec![20], Some(vec![20])); - overlay.set_child_storage(child.clone(), child_info, vec![30], Some(vec![30])); - overlay.set_child_storage(child.clone(), child_info, vec![40], Some(vec![40])); + overlay.set_child_storage(child_info, vec![20], Some(vec![20])); + overlay.set_child_storage(child_info, vec![30], Some(vec![30])); + overlay.set_child_storage(child_info, vec![40], Some(vec![40])); overlay.commit_prospective(); - overlay.set_child_storage(child.clone(), child_info, vec![10], Some(vec![10])); - overlay.set_child_storage(child.clone(), child_info, vec![30], None); + overlay.set_child_storage(child_info, vec![10], Some(vec![10])); + overlay.set_child_storage(child_info, vec![30], None); // next_prospective < next_committed - let next_to_5 = overlay.next_child_storage_key_change(&child, &[5]).unwrap(); + let next_to_5 = overlay.next_child_storage_key_change(child, &[5]).unwrap(); assert_eq!(next_to_5.0.to_vec(), vec![10]); assert_eq!(next_to_5.1.value, Some(vec![10])); // next_committed < next_prospective - let next_to_10 = overlay.next_child_storage_key_change(&child, &[10]).unwrap(); + let next_to_10 = overlay.next_child_storage_key_change(child, &[10]).unwrap(); assert_eq!(next_to_10.0.to_vec(), vec![20]); assert_eq!(next_to_10.1.value, Some(vec![20])); // next_committed == next_prospective - let next_to_20 = overlay.next_child_storage_key_change(&child, &[20]).unwrap(); + let next_to_20 = overlay.next_child_storage_key_change(child, &[20]).unwrap(); assert_eq!(next_to_20.0.to_vec(), vec![30]); assert_eq!(next_to_20.1.value, None); // next_committed, no next_prospective - let next_to_30 = overlay.next_child_storage_key_change(&child, &[30]).unwrap(); + let next_to_30 = overlay.next_child_storage_key_change(child, &[30]).unwrap(); assert_eq!(next_to_30.0.to_vec(), vec![40]); assert_eq!(next_to_30.1.value, Some(vec![40])); - overlay.set_child_storage(child.clone(), child_info, vec![50], Some(vec![50])); + overlay.set_child_storage(child_info, vec![50], Some(vec![50])); // next_prospective, no next_committed - let next_to_40 = overlay.next_child_storage_key_change(&child, &[40]).unwrap(); + let next_to_40 = overlay.next_child_storage_key_change(child, &[40]).unwrap(); assert_eq!(next_to_40.0.to_vec(), vec![50]); assert_eq!(next_to_40.1.value, Some(vec![50])); } diff --git a/primitives/state-machine/src/proving_backend.rs b/primitives/state-machine/src/proving_backend.rs index 747872af83..deafeb902d 100644 --- a/primitives/state-machine/src/proving_backend.rs +++ b/primitives/state-machine/src/proving_backend.rs @@ -22,7 +22,7 @@ use codec::{Decode, Codec}; use log::debug; use hash_db::{Hasher, HashDB, EMPTY_PREFIX, Prefix}; use sp_trie::{ - MemoryDB, default_child_trie_root, read_trie_value_with, read_child_trie_value_with, + MemoryDB, empty_child_trie_root, read_trie_value_with, read_child_trie_value_with, record_all_keys, StorageProof, }; pub use sp_trie::Recorder; @@ -67,13 +67,13 @@ impl<'a, S, H> ProvingBackendRecorder<'a, S, H> /// Produce proof for a child key query. pub fn child_storage( &mut self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8] ) -> Result>, String> { + let storage_key = child_info.storage_key(); let root = self.storage(storage_key)? .and_then(|r| Decode::decode(&mut &r[..]).ok()) - .unwrap_or(default_child_trie_root::>(storage_key)); + .unwrap_or(empty_child_trie_root::>()); let mut read_overlay = S::Overlay::default(); let eph = Ephemeral::new( @@ -84,7 +84,6 @@ impl<'a, S, H> ProvingBackendRecorder<'a, S, H> let map_e = |e| format!("Trie lookup error: {}", e); read_child_trie_value_with::, _, _>( - storage_key, child_info.keyspace(), &eph, &root.as_ref(), @@ -201,20 +200,18 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> fn child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result>, Self::Error> { - self.0.child_storage(storage_key, child_info, key) + self.0.child_storage(child_info, key) } fn for_keys_in_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, f: F, ) { - self.0.for_keys_in_child_storage(storage_key, child_info, f) + self.0.for_keys_in_child_storage(child_info, f) } fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { @@ -223,11 +220,10 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> fn next_child_storage_key( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result>, Self::Error> { - self.0.next_child_storage_key(storage_key, child_info, key) + self.0.next_child_storage_key(child_info, key) } fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { @@ -240,12 +236,11 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> fn for_child_keys_with_prefix( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], f: F, ) { - self.0.for_child_keys_with_prefix(storage_key, child_info, prefix, f) + self.0.for_child_keys_with_prefix( child_info, prefix, f) } fn pairs(&self) -> Vec<(Vec, Vec)> { @@ -258,11 +253,10 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> fn child_keys( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], ) -> Vec> { - self.0.child_keys(storage_key, child_info, prefix) + self.0.child_keys(child_info, prefix) } fn storage_root(&self, delta: I) -> (H::Out, Self::Transaction) @@ -273,15 +267,14 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> fn child_storage_root( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, delta: I, ) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, H::Out: Ord { - self.0.child_storage_root(storage_key, child_info, delta) + self.0.child_storage_root(child_info, delta) } fn register_overlay_stats(&mut self, _stats: &crate::stats::StateMachineStats) { } @@ -314,14 +307,10 @@ mod tests { use crate::InMemoryBackend; use crate::trie_backend::tests::test_trie; use super::*; - use sp_core::storage::ChildStorageKey; use crate::proving_backend::create_proof_check_backend; use sp_trie::PrefixedMemoryDB; use sp_runtime::traits::BlakeTwo256; - const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_1"); - const CHILD_INFO_2: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_2"); - fn test_proving<'a>( trie_backend: &'a TrieBackend,BlakeTwo256>, ) -> ProvingBackend<'a, PrefixedMemoryDB, BlakeTwo256> { @@ -389,33 +378,33 @@ mod tests { #[test] fn proof_recorded_and_checked_with_child() { - let subtrie1 = ChildStorageKey::from_slice(b":child_storage:default:sub1").unwrap(); - let subtrie2 = ChildStorageKey::from_slice(b":child_storage:default:sub2").unwrap(); - let own1 = subtrie1.into_owned(); - let own2 = subtrie2.into_owned(); + let child_info_1 = ChildInfo::new_default(b"sub1"); + let child_info_2 = ChildInfo::new_default(b"sub2"); + let child_info_1 = &child_info_1; + let child_info_2 = &child_info_2; let contents = vec![ (None, (0..64).map(|i| (vec![i], Some(vec![i]))).collect()), - (Some((own1.clone(), CHILD_INFO_1.to_owned())), + (Some(child_info_1.clone()), (28..65).map(|i| (vec![i], Some(vec![i]))).collect()), - (Some((own2.clone(), CHILD_INFO_2.to_owned())), + (Some(child_info_2.clone()), (10..15).map(|i| (vec![i], Some(vec![i]))).collect()), ]; let in_memory = InMemoryBackend::::default(); let mut in_memory = in_memory.update(contents); let in_memory_root = in_memory.full_storage_root::<_, Vec<_>, _>( ::std::iter::empty(), - in_memory.child_storage_keys().map(|k|(k.0.to_vec(), Vec::new(), k.1.to_owned())) + in_memory.child_storage_infos().map(|k|(k.to_owned(), Vec::new())) ).0; (0..64).for_each(|i| assert_eq!( in_memory.storage(&[i]).unwrap().unwrap(), vec![i] )); (28..65).for_each(|i| assert_eq!( - in_memory.child_storage(&own1[..], CHILD_INFO_1, &[i]).unwrap().unwrap(), + in_memory.child_storage(child_info_1, &[i]).unwrap().unwrap(), vec![i] )); (10..15).for_each(|i| assert_eq!( - in_memory.child_storage(&own2[..], CHILD_INFO_2, &[i]).unwrap().unwrap(), + in_memory.child_storage(child_info_2, &[i]).unwrap().unwrap(), vec![i] )); @@ -443,7 +432,7 @@ mod tests { assert_eq!(proof_check.storage(&[64]).unwrap(), None); let proving = ProvingBackend::new(trie); - assert_eq!(proving.child_storage(&own1[..], CHILD_INFO_1, &[64]), Ok(Some(vec![64]))); + assert_eq!(proving.child_storage(child_info_1, &[64]), Ok(Some(vec![64]))); let proof = proving.extract_proof(); let proof_check = create_proof_check_backend::( @@ -451,7 +440,7 @@ mod tests { proof ).unwrap(); assert_eq!( - proof_check.child_storage(&own1[..], CHILD_INFO_1, &[64]).unwrap().unwrap(), + proof_check.child_storage(child_info_1, &[64]).unwrap().unwrap(), vec![64] ); } diff --git a/primitives/state-machine/src/testing.rs b/primitives/state-machine/src/testing.rs index 2b971d816a..70a96c623a 100644 --- a/primitives/state-machine/src/testing.rs +++ b/primitives/state-machine/src/testing.rs @@ -93,7 +93,7 @@ impl TestExternalities overlay.set_collect_extrinsics(changes_trie_config.is_some()); assert!(storage.top.keys().all(|key| !is_child_storage_key(key))); - assert!(storage.children.keys().all(|key| is_child_storage_key(key))); + assert!(storage.children_default.keys().all(|key| is_child_storage_key(key))); storage.top.insert(HEAP_PAGES.to_vec(), 8u64.encode()); storage.top.insert(CODE.to_vec(), code.to_vec()); @@ -133,11 +133,11 @@ impl TestExternalities .map(|(k, v)| (k, v.value)).collect(); let mut transaction = vec![(None, top)]; - self.overlay.committed.children.clone().into_iter() - .chain(self.overlay.prospective.children.clone().into_iter()) - .for_each(|(keyspace, (map, child_info))| { + self.overlay.committed.children_default.clone().into_iter() + .chain(self.overlay.prospective.children_default.clone().into_iter()) + .for_each(|(_storage_key, (map, child_info))| { transaction.push(( - Some((keyspace, child_info)), + Some(child_info), map.into_iter() .map(|(k, v)| (k, v.value)) .collect::>(), diff --git a/primitives/state-machine/src/trie_backend.rs b/primitives/state-machine/src/trie_backend.rs index f88e306a2f..08eea29360 100644 --- a/primitives/state-machine/src/trie_backend.rs +++ b/primitives/state-machine/src/trie_backend.rs @@ -18,9 +18,9 @@ use log::{warn, debug}; use hash_db::Hasher; -use sp_trie::{Trie, delta_trie_root, default_child_trie_root, child_delta_trie_root}; +use sp_trie::{Trie, delta_trie_root, empty_child_trie_root, child_delta_trie_root}; use sp_trie::trie_types::{TrieDB, TrieError, Layout}; -use sp_core::storage::ChildInfo; +use sp_core::storage::{ChildInfo, ChildType}; use codec::{Codec, Decode}; use crate::{ StorageKey, StorageValue, Backend, @@ -80,11 +80,10 @@ impl, H: Hasher> Backend for TrieBackend where fn child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result, Self::Error> { - self.essence.child_storage(storage_key, child_info, key) + self.essence.child_storage(child_info, key) } fn next_storage_key(&self, key: &[u8]) -> Result, Self::Error> { @@ -93,11 +92,10 @@ impl, H: Hasher> Backend for TrieBackend where fn next_child_storage_key( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result, Self::Error> { - self.essence.next_child_storage_key(storage_key, child_info, key) + self.essence.next_child_storage_key(child_info, key) } fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { @@ -110,21 +108,19 @@ impl, H: Hasher> Backend for TrieBackend where fn for_keys_in_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, f: F, ) { - self.essence.for_keys_in_child_storage(storage_key, child_info, f) + self.essence.for_keys_in_child_storage(child_info, f) } fn for_child_keys_with_prefix( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], f: F, ) { - self.essence.for_child_keys_with_prefix(storage_key, child_info, prefix, f) + self.essence.for_child_keys_with_prefix(child_info, prefix, f) } fn pairs(&self) -> Vec<(StorageKey, StorageValue)> { @@ -194,18 +190,20 @@ impl, H: Hasher> Backend for TrieBackend where fn child_storage_root( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, delta: I, ) -> (H::Out, bool, Self::Transaction) where I: IntoIterator)>, H::Out: Ord, { - let default_root = default_child_trie_root::>(storage_key); + let default_root = match child_info.child_type() { + ChildType::ParentKeyId => empty_child_trie_root::>() + }; let mut write_overlay = S::Overlay::default(); - let mut root = match self.storage(storage_key) { + let prefixed_storage_key = child_info.prefixed_storage_key(); + let mut root = match self.storage(prefixed_storage_key.as_slice()) { Ok(value) => value.and_then(|r| Decode::decode(&mut &r[..]).ok()).unwrap_or(default_root.clone()), Err(e) => { @@ -221,7 +219,6 @@ impl, H: Hasher> Backend for TrieBackend where ); match child_delta_trie_root::, _, _, _, _, _>( - storage_key, child_info.keyspace(), &mut eph, root, @@ -257,16 +254,14 @@ pub mod tests { use sp_runtime::traits::BlakeTwo256; use super::*; - const CHILD_KEY_1: &[u8] = b":child_storage:default:sub1"; - - const CHILD_UUID_1: &[u8] = b"unique_id_1"; - const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(CHILD_UUID_1); + const CHILD_KEY_1: &[u8] = b"sub1"; fn test_db() -> (PrefixedMemoryDB, H256) { + let child_info = ChildInfo::new_default(CHILD_KEY_1); let mut root = H256::default(); let mut mdb = PrefixedMemoryDB::::default(); { - let mut mdb = KeySpacedDBMut::new(&mut mdb, CHILD_UUID_1); + let mut mdb = KeySpacedDBMut::new(&mut mdb, child_info.keyspace()); let mut trie = TrieDBMut::new(&mut mdb, &mut root); trie.insert(b"value3", &[142]).expect("insert failed"); trie.insert(b"value4", &[124]).expect("insert failed"); @@ -276,7 +271,8 @@ pub mod tests { let mut sub_root = Vec::new(); root.encode_to(&mut sub_root); let mut trie = TrieDBMut::new(&mut mdb, &mut root); - trie.insert(CHILD_KEY_1, &sub_root[..]).expect("insert failed"); + trie.insert(child_info.prefixed_storage_key().as_slice(), &sub_root[..]) + .expect("insert failed"); trie.insert(b"key", b"value").expect("insert failed"); trie.insert(b"value1", &[42]).expect("insert failed"); trie.insert(b"value2", &[24]).expect("insert failed"); @@ -302,7 +298,7 @@ pub mod tests { fn read_from_child_storage_returns_some() { let test_trie = test_trie(); assert_eq!( - test_trie.child_storage(CHILD_KEY_1, CHILD_INFO_1, b"value3").unwrap(), + test_trie.child_storage(&ChildInfo::new_default(CHILD_KEY_1), b"value3").unwrap(), Some(vec![142u8]), ); } diff --git a/primitives/state-machine/src/trie_backend_essence.rs b/primitives/state-machine/src/trie_backend_essence.rs index 125a823f57..28d1c68ca2 100644 --- a/primitives/state-machine/src/trie_backend_essence.rs +++ b/primitives/state-machine/src/trie_backend_essence.rs @@ -22,7 +22,7 @@ use std::sync::Arc; use log::{debug, warn}; use hash_db::{self, Hasher, EMPTY_PREFIX, Prefix}; use sp_trie::{Trie, MemoryDB, PrefixedMemoryDB, DBValue, - default_child_trie_root, read_trie_value, read_child_trie_value, + empty_child_trie_root, read_trie_value, read_child_trie_value, for_keys_in_child_trie, KeySpacedDB, TrieDBIterator}; use sp_trie::trie_types::{TrieDB, TrieError, Layout}; use crate::{backend::Consolidate, StorageKey, StorageValue}; @@ -71,15 +71,19 @@ impl, H: Hasher> TrieBackendEssence where H::Out: self.next_storage_key_from_root(&self.root, None, key) } + /// Access the root of the child storage in its parent trie + fn child_root(&self, child_info: &ChildInfo) -> Result, String> { + self.storage(child_info.prefixed_storage_key().as_slice()) + } + /// Return the next key in the child trie i.e. the minimum key that is strictly superior to /// `key` in lexicographic order. pub fn next_child_storage_key( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result, String> { - let child_root = match self.storage(storage_key)? { + let child_root = match self.child_root(child_info)? { Some(child_root) => child_root, None => return Ok(None), }; @@ -87,7 +91,7 @@ impl, H: Hasher> TrieBackendEssence where H::Out: let mut hash = H::Out::default(); if child_root.len() != hash.as_ref().len() { - return Err(format!("Invalid child storage hash at {:?}", storage_key)); + return Err(format!("Invalid child storage hash at {:?}", child_info.storage_key())); } // note: child_root and hash must be same size, panics otherwise. hash.as_mut().copy_from_slice(&child_root[..]); @@ -99,7 +103,7 @@ impl, H: Hasher> TrieBackendEssence where H::Out: fn next_storage_key_from_root( &self, root: &H::Out, - child_info: Option, + child_info: Option<&ChildInfo>, key: &[u8], ) -> Result, String> { let mut read_overlay = S::Overlay::default(); @@ -161,12 +165,11 @@ impl, H: Hasher> TrieBackendEssence where H::Out: /// Get the value of child storage at given key. pub fn child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, key: &[u8], ) -> Result, String> { - let root = self.storage(storage_key)? - .unwrap_or(default_child_trie_root::>(storage_key).encode()); + let root = self.child_root(child_info)? + .unwrap_or(empty_child_trie_root::>().encode()); let mut read_overlay = S::Overlay::default(); let eph = Ephemeral { @@ -176,19 +179,18 @@ impl, H: Hasher> TrieBackendEssence where H::Out: let map_e = |e| format!("Trie lookup error: {}", e); - read_child_trie_value::, _>(storage_key, child_info.keyspace(), &eph, &root, key) + read_child_trie_value::, _>(child_info.keyspace(), &eph, &root, key) .map_err(map_e) } /// Retrieve all entries keys of child storage and call `f` for each of those keys. pub fn for_keys_in_child_storage( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, f: F, ) { - let root = match self.storage(storage_key) { - Ok(v) => v.unwrap_or(default_child_trie_root::>(storage_key).encode()), + let root = match self.child_root(child_info) { + Ok(v) => v.unwrap_or(empty_child_trie_root::>().encode()), Err(e) => { debug!(target: "trie", "Error while iterating child storage: {}", e); return; @@ -202,7 +204,6 @@ impl, H: Hasher> TrieBackendEssence where H::Out: }; if let Err(e) = for_keys_in_child_trie::, _, Ephemeral>( - storage_key, child_info.keyspace(), &eph, &root, @@ -215,13 +216,12 @@ impl, H: Hasher> TrieBackendEssence where H::Out: /// Execute given closure for all keys starting with prefix. pub fn for_child_keys_with_prefix( &self, - storage_key: &[u8], - child_info: ChildInfo, + child_info: &ChildInfo, prefix: &[u8], mut f: F, ) { - let root_vec = match self.storage(storage_key) { - Ok(v) => v.unwrap_or(default_child_trie_root::>(storage_key).encode()), + let root_vec = match self.child_root(child_info) { + Ok(v) => v.unwrap_or(empty_child_trie_root::>().encode()), Err(e) => { debug!(target: "trie", "Error while iterating child storage: {}", e); return; @@ -242,7 +242,7 @@ impl, H: Hasher> TrieBackendEssence where H::Out: root: &H::Out, prefix: &[u8], mut f: F, - child_info: Option, + child_info: Option<&ChildInfo>, ) { let mut read_overlay = S::Overlay::default(); let eph = Ephemeral { @@ -436,7 +436,8 @@ mod test { #[test] fn next_storage_key_and_next_child_storage_key_work() { - let child_info = ChildInfo::new_default(b"uniqueid"); + let child_info = ChildInfo::new_default(b"MyChild"); + let child_info = &child_info; // Contains values let mut root_1 = H256::default(); // Contains child trie @@ -460,7 +461,8 @@ mod test { } { let mut trie = TrieDBMut::new(&mut mdb, &mut root_2); - trie.insert(b"MyChild", root_1.as_ref()).expect("insert failed"); + trie.insert(child_info.prefixed_storage_key().as_slice(), root_1.as_ref()) + .expect("insert failed"); }; let essence_1 = TrieBackendEssence::new(mdb, root_1); @@ -475,19 +477,19 @@ mod test { let essence_2 = TrieBackendEssence::new(mdb, root_2); assert_eq!( - essence_2.next_child_storage_key(b"MyChild", child_info, b"2"), Ok(Some(b"3".to_vec())) + essence_2.next_child_storage_key(child_info, b"2"), Ok(Some(b"3".to_vec())) ); assert_eq!( - essence_2.next_child_storage_key(b"MyChild", child_info, b"3"), Ok(Some(b"4".to_vec())) + essence_2.next_child_storage_key(child_info, b"3"), Ok(Some(b"4".to_vec())) ); assert_eq!( - essence_2.next_child_storage_key(b"MyChild", child_info, b"4"), Ok(Some(b"6".to_vec())) + essence_2.next_child_storage_key(child_info, b"4"), Ok(Some(b"6".to_vec())) ); assert_eq!( - essence_2.next_child_storage_key(b"MyChild", child_info, b"5"), Ok(Some(b"6".to_vec())) + essence_2.next_child_storage_key(child_info, b"5"), Ok(Some(b"6".to_vec())) ); assert_eq!( - essence_2.next_child_storage_key(b"MyChild", child_info, b"6"), Ok(None) + essence_2.next_child_storage_key(child_info, b"6"), Ok(None) ); } } diff --git a/primitives/storage/Cargo.toml b/primitives/storage/Cargo.toml index d7ae342b2d..76174d13b0 100644 --- a/primitives/storage/Cargo.toml +++ b/primitives/storage/Cargo.toml @@ -16,6 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } impl-serde = { version = "0.2.3", optional = true } +ref-cast = "1.0.0" sp-debug-derive = { version = "2.0.0-dev", path = "../debug-derive" } [features] diff --git a/primitives/storage/src/lib.rs b/primitives/storage/src/lib.rs index 76fd4baac9..d2c4a73e23 100644 --- a/primitives/storage/src/lib.rs +++ b/primitives/storage/src/lib.rs @@ -22,7 +22,9 @@ use serde::{Serialize, Deserialize}; use sp_debug_derive::RuntimeDebug; -use sp_std::{vec::Vec, borrow::Cow}; +use sp_std::vec::Vec; +use sp_std::ops::{Deref, DerefMut}; +use ref_cast::RefCast; /// Storage key. #[derive(PartialEq, Eq, RuntimeDebug)] @@ -32,6 +34,51 @@ pub struct StorageKey( pub Vec, ); +/// Storage key of a child trie, it contains the prefix to the key. +#[derive(PartialEq, Eq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord, Clone))] +#[repr(transparent)] +#[derive(RefCast)] +pub struct PrefixedStorageKey( + #[cfg_attr(feature = "std", serde(with="impl_serde::serialize"))] + Vec, +); + +impl Deref for PrefixedStorageKey { + type Target = Vec; + + fn deref(&self) -> &Vec { + &self.0 + } +} + +impl DerefMut for PrefixedStorageKey { + fn deref_mut(&mut self) -> &mut Vec { + &mut self.0 + } +} + +impl PrefixedStorageKey { + /// Create a prefixed storage key from its byte array + /// representation. + pub fn new(inner: Vec) -> Self { + PrefixedStorageKey(inner) + } + + /// Create a prefixed storage key reference. + pub fn new_ref(inner: &Vec) -> &Self { + PrefixedStorageKey::ref_cast(inner) + } + + /// Get inner key, this should + /// only be needed when writing + /// into parent trie to avoid an + /// allocation. + pub fn into_inner(self) -> Vec { + self.0 + } +} + /// Storage data associated to a [`StorageKey`]. #[derive(PartialEq, Eq, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord, Clone))] @@ -53,7 +100,7 @@ pub struct StorageChild { pub data: StorageMap, /// Associated child info for a child /// trie. - pub child_info: OwnedChildInfo, + pub child_info: ChildInfo, } #[cfg(feature = "std")] @@ -62,8 +109,11 @@ pub struct StorageChild { pub struct Storage { /// Top trie storage data. pub top: StorageMap, - /// Children trie storage data by storage key. - pub children: std::collections::HashMap, StorageChild>, + /// Children trie storage data. + /// The key does not including prefix, for the `default` + /// trie kind, so this is exclusively for the `ChildType::ParentKeyId` + /// tries. + pub children_default: std::collections::HashMap, StorageChild>, } /// Storage change set @@ -106,133 +156,87 @@ pub mod well_known_keys { // Other code might depend on this, so be careful changing this. key.starts_with(CHILD_STORAGE_KEY_PREFIX) } - - /// Determine whether a child trie key is valid. - /// - /// For now, the only valid child trie keys are those starting with `:child_storage:default:`. - /// - /// `child_trie_root` and `child_delta_trie_root` can panic if invalid value is provided to them. - pub fn is_child_trie_key_valid(storage_key: &[u8]) -> bool { - let has_right_prefix = storage_key.starts_with(b":child_storage:default:"); - if has_right_prefix { - // This is an attempt to catch a change of `is_child_storage_key`, which - // just checks if the key has prefix `:child_storage:` at the moment of writing. - debug_assert!( - is_child_storage_key(&storage_key), - "`is_child_trie_key_valid` is a subset of `is_child_storage_key`", - ); - } - has_right_prefix - } -} - -/// A wrapper around a child storage key. -/// -/// This wrapper ensures that the child storage key is correct and properly used. It is -/// impossible to create an instance of this struct without providing a correct `storage_key`. -pub struct ChildStorageKey<'a> { - storage_key: Cow<'a, [u8]>, } -impl<'a> ChildStorageKey<'a> { - /// Create new instance of `Self`. - fn new(storage_key: Cow<'a, [u8]>) -> Option { - if well_known_keys::is_child_trie_key_valid(&storage_key) { - Some(ChildStorageKey { storage_key }) - } else { - None - } - } - - /// Create a new `ChildStorageKey` from a vector. - /// - /// `storage_key` need to start with `:child_storage:default:` - /// See `is_child_trie_key_valid` for more details. - pub fn from_vec(key: Vec) -> Option { - Self::new(Cow::Owned(key)) - } - - /// Create a new `ChildStorageKey` from a slice. - /// - /// `storage_key` need to start with `:child_storage:default:` - /// See `is_child_trie_key_valid` for more details. - pub fn from_slice(key: &'a [u8]) -> Option { - Self::new(Cow::Borrowed(key)) - } - - /// Get access to the byte representation of the storage key. - /// - /// This key is guaranteed to be correct. - pub fn as_ref(&self) -> &[u8] { - &*self.storage_key - } - - /// Destruct this instance into an owned vector that represents the storage key. - /// - /// This key is guaranteed to be correct. - pub fn into_owned(self) -> Vec { - self.storage_key.into_owned() - } -} - -#[derive(Clone, Copy)] /// Information related to a child state. -pub enum ChildInfo<'a> { - Default(ChildTrie<'a>), -} - -/// Owned version of `ChildInfo`. -/// To be use in persistence layers. #[derive(Debug, Clone)] #[cfg_attr(feature = "std", derive(PartialEq, Eq, Hash, PartialOrd, Ord))] -pub enum OwnedChildInfo { - Default(OwnedChildTrie), +pub enum ChildInfo { + /// This is the one used by default. + ParentKeyId(ChildTrieParentKeyId), } -impl<'a> ChildInfo<'a> { - /// Instantiates information for a default child trie. - pub const fn new_default(unique_id: &'a[u8]) -> Self { - ChildInfo::Default(ChildTrie { - data: unique_id, +impl ChildInfo { + /// Instantiates child information for a default child trie + /// of kind `ChildType::ParentKeyId`, using an unprefixed parent + /// storage key. + pub fn new_default(storage_key: &[u8]) -> Self { + let data = storage_key.to_vec(); + ChildInfo::ParentKeyId(ChildTrieParentKeyId { data }) + } + + /// Same as `new_default` but with `Vec` as input. + pub fn new_default_from_vec(storage_key: Vec) -> Self { + ChildInfo::ParentKeyId(ChildTrieParentKeyId { + data: storage_key, }) } - /// Instantiates a owned version of this child info. - pub fn to_owned(&self) -> OwnedChildInfo { + /// Try to update with another instance, return false if both instance + /// are not compatible. + pub fn try_update(&mut self, other: &ChildInfo) -> bool { match self { - ChildInfo::Default(ChildTrie { data }) - => OwnedChildInfo::Default(OwnedChildTrie { - data: data.to_vec(), - }), + ChildInfo::ParentKeyId(child_trie) => child_trie.try_update(other), } } - /// Create child info from a linear byte packed value and a given type. - pub fn resolve_child_info(child_type: u32, data: &'a[u8]) -> Option { - match child_type { - x if x == ChildType::CryptoUniqueId as u32 => Some(ChildInfo::new_default(data)), - _ => None, + /// Returns byte sequence (keyspace) that can be use by underlying db to isolate keys. + /// This is a unique id of the child trie. The collision resistance of this value + /// depends on the type of child info use. For `ChildInfo::Default` it is and need to be. + pub fn keyspace(&self) -> &[u8] { + match self { + ChildInfo::ParentKeyId(..) => self.storage_key(), } } - /// Return a single byte vector containing packed child info content and its child info type. - /// This can be use as input for `resolve_child_info`. - pub fn info(&self) -> (&[u8], u32) { + /// Returns a reference to the location in the direct parent of + /// this trie but without the common prefix for this kind of + /// child trie. + pub fn storage_key(&self) -> &[u8] { match self { - ChildInfo::Default(ChildTrie { + ChildInfo::ParentKeyId(ChildTrieParentKeyId { data, - }) => (data, ChildType::CryptoUniqueId as u32), + }) => &data[..], } } - /// Return byte sequence (keyspace) that can be use by underlying db to isolate keys. - /// This is a unique id of the child trie. The collision resistance of this value - /// depends on the type of child info use. For `ChildInfo::Default` it is and need to be. - pub fn keyspace(&self) -> &[u8] { + /// Return a the full location in the direct parent of + /// this trie. + pub fn prefixed_storage_key(&self) -> PrefixedStorageKey { match self { - ChildInfo::Default(ChildTrie { + ChildInfo::ParentKeyId(ChildTrieParentKeyId { data, - }) => &data[..], + }) => ChildType::ParentKeyId.new_prefixed_key(data.as_slice()), + } + } + + /// Returns a the full location in the direct parent of + /// this trie. + pub fn into_prefixed_storage_key(self) -> PrefixedStorageKey { + match self { + ChildInfo::ParentKeyId(ChildTrieParentKeyId { + mut data, + }) => { + ChildType::ParentKeyId.do_prefix_key(&mut data); + PrefixedStorageKey(data) + }, + } + } + + /// Returns the type for this child info. + pub fn child_type(&self) -> ChildType { + match self { + ChildInfo::ParentKeyId(..) => ChildType::ParentKeyId, } } } @@ -241,65 +245,98 @@ impl<'a> ChildInfo<'a> { /// It does not strictly define different child type, it can also /// be related to technical consideration or api variant. #[repr(u32)] +#[derive(Clone, Copy, PartialEq)] +#[cfg_attr(feature = "std", derive(Debug))] pub enum ChildType { - /// Default, it uses a cryptographic strong unique id as input. - CryptoUniqueId = 1, + /// If runtime module ensures that the child key is a unique id that will + /// only be used once, its parent key is used as a child trie unique id. + ParentKeyId = 1, } -impl OwnedChildInfo { - /// Instantiates info for a default child trie. - pub fn new_default(unique_id: Vec) -> Self { - OwnedChildInfo::Default(OwnedChildTrie { - data: unique_id, +impl ChildType { + /// Try to get a child type from its `u32` representation. + pub fn new(repr: u32) -> Option { + Some(match repr { + r if r == ChildType::ParentKeyId as u32 => ChildType::ParentKeyId, + _ => return None, }) } - /// Try to update with another instance, return false if both instance - /// are not compatible. - pub fn try_update(&mut self, other: ChildInfo) -> bool { - match self { - OwnedChildInfo::Default(owned_child_trie) => owned_child_trie.try_update(other), + /// Transform a prefixed key into a tuple of the child type + /// and the unprefixed representation of the key. + pub fn from_prefixed_key<'a>(storage_key: &'a PrefixedStorageKey) -> Option<(Self, &'a [u8])> { + let match_type = |storage_key: &'a [u8], child_type: ChildType| { + let prefix = child_type.parent_prefix(); + if storage_key.starts_with(prefix) { + Some((child_type, &storage_key[prefix.len()..])) + } else { + None + } + }; + match_type(storage_key, ChildType::ParentKeyId) + } + + /// Produce a prefixed key for a given child type. + fn new_prefixed_key(&self, key: &[u8]) -> PrefixedStorageKey { + let parent_prefix = self.parent_prefix(); + let mut result = Vec::with_capacity(parent_prefix.len() + key.len()); + result.extend_from_slice(parent_prefix); + result.extend_from_slice(key); + PrefixedStorageKey(result) + } + + /// Prefixes a vec with the prefix for this child type. + fn do_prefix_key(&self, key: &mut Vec) { + let parent_prefix = self.parent_prefix(); + let key_len = key.len(); + if parent_prefix.len() > 0 { + key.resize(key_len + parent_prefix.len(), 0); + key.copy_within(..key_len, parent_prefix.len()); + key[..parent_prefix.len()].copy_from_slice(parent_prefix); } } - /// Get `ChildInfo` reference to this owned child info. - pub fn as_ref(&self) -> ChildInfo { + /// Returns the location reserved for this child trie in their parent trie if there + /// is one. + pub fn parent_prefix(&self) -> &'static [u8] { match self { - OwnedChildInfo::Default(OwnedChildTrie { data }) - => ChildInfo::Default(ChildTrie { - data: data.as_slice(), - }), + &ChildType::ParentKeyId => DEFAULT_CHILD_TYPE_PARENT_PREFIX, } } } /// A child trie of default type. -/// Default is the same implementation as the top trie. -/// It share its trie node storage with any kind of key, -/// and its unique id needs to be collision free (eg strong -/// crypto hash). -#[derive(Clone, Copy)] -pub struct ChildTrie<'a> { - /// Data containing unique id. - /// Unique id must but unique and free of any possible key collision - /// (depending on its storage behavior). - data: &'a[u8], -} - -/// Owned version of default child trie `ChildTrie`. +/// It uses the same default implementation as the top trie, +/// top trie being a child trie with no keyspace and no storage key. +/// Its keyspace is the variable (unprefixed) part of its storage key. +/// It shares its trie nodes backend storage with every other +/// child trie, so its storage key needs to be a unique id +/// that will be use only once. +/// Those unique id also required to be long enough to avoid any +/// unique id to be prefixed by an other unique id. #[derive(Debug, Clone)] #[cfg_attr(feature = "std", derive(PartialEq, Eq, Hash, PartialOrd, Ord))] -pub struct OwnedChildTrie { - /// See `ChildTrie` reference field documentation. +pub struct ChildTrieParentKeyId { + /// Data is the storage key without prefix. data: Vec, } -impl OwnedChildTrie { +impl ChildTrieParentKeyId { /// Try to update with another instance, return false if both instance /// are not compatible. - fn try_update(&mut self, other: ChildInfo) -> bool { + fn try_update(&mut self, other: &ChildInfo) -> bool { match other { - ChildInfo::Default(other) => self.data[..] == other.data[..], + ChildInfo::ParentKeyId(other) => self.data[..] == other.data[..], } } } + +const DEFAULT_CHILD_TYPE_PARENT_PREFIX: &'static [u8] = b":child_storage:default:"; + +#[test] +fn test_prefix_default_child_info() { + let child_info = ChildInfo::new_default(b"any key"); + let prefix = child_info.child_type().parent_prefix(); + assert!(prefix.starts_with(well_known_keys::CHILD_STORAGE_KEY_PREFIX)); + assert!(prefix.starts_with(DEFAULT_CHILD_TYPE_PARENT_PREFIX)); +} diff --git a/primitives/trie/src/lib.rs b/primitives/trie/src/lib.rs index 80570a9792..37fe928336 100644 --- a/primitives/trie/src/lib.rs +++ b/primitives/trie/src/lib.rs @@ -211,9 +211,8 @@ pub fn read_trie_value_with< Ok(TrieDB::::new(&*db, root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))?) } -/// Determine the default child trie root. -pub fn default_child_trie_root( - _storage_key: &[u8], +/// Determine the empty child trie root. +pub fn empty_child_trie_root( ) -> ::Out { L::trie_root::<_, Vec, Vec>(core::iter::empty()) } @@ -221,7 +220,6 @@ pub fn default_child_trie_root( /// Determine a child trie root given its ordered contents, closed form. H is the default hasher, /// but a generic implementation may ignore this type parameter and use other hashers. pub fn child_trie_root( - _storage_key: &[u8], input: I, ) -> ::Out where @@ -235,7 +233,6 @@ pub fn child_trie_root( /// Determine a child trie root given a hash DB and delta values. H is the default hasher, /// but a generic implementation may ignore this type parameter and use other hashers. pub fn child_delta_trie_root( - _storage_key: &[u8], keyspace: &[u8], db: &mut DB, root_data: RD, @@ -270,7 +267,6 @@ pub fn child_delta_trie_root( /// Call `f` for all keys in a child trie. pub fn for_keys_in_child_trie( - _storage_key: &[u8], keyspace: &[u8], db: &DB, root_slice: &[u8], @@ -321,7 +317,6 @@ pub fn record_all_keys( /// Read a value from the child trie. pub fn read_child_trie_value( - _storage_key: &[u8], keyspace: &[u8], db: &DB, root_slice: &[u8], @@ -341,7 +336,6 @@ pub fn read_child_trie_value( /// Read a value from the child trie with given query. pub fn read_child_trie_value_with, DB>( - _storage_key: &[u8], keyspace: &[u8], db: &DB, root_slice: &[u8], diff --git a/test-utils/client/src/lib.rs b/test-utils/client/src/lib.rs index d04e85fd10..4880b296c7 100644 --- a/test-utils/client/src/lib.rs +++ b/test-utils/client/src/lib.rs @@ -40,7 +40,7 @@ pub use self::client_ext::{ClientExt, ClientBlockImportExt}; use std::sync::Arc; use std::collections::HashMap; -use sp_core::storage::{well_known_keys, ChildInfo}; +use sp_core::storage::ChildInfo; use sp_runtime::traits::{Block as BlockT, BlakeTwo256}; use sc_client::LocalCallExecutor; @@ -66,6 +66,8 @@ impl GenesisInit for () { pub struct TestClientBuilder { execution_strategies: ExecutionStrategies, genesis_init: G, + /// The key is an unprefixed storage key, this only contains + /// default child trie content. child_storage_extension: HashMap, StorageChild>, backend: Arc, _executor: std::marker::PhantomData, @@ -129,17 +131,17 @@ impl TestClientBuilder, - child_key: impl AsRef<[u8]>, - child_info: ChildInfo, value: impl AsRef<[u8]>, ) -> Self { - let entry = self.child_storage_extension.entry(key.as_ref().to_vec()) + let storage_key = child_info.storage_key(); + let entry = self.child_storage_extension.entry(storage_key.to_vec()) .or_insert_with(|| StorageChild { data: Default::default(), - child_info: child_info.to_owned(), + child_info: child_info.clone(), }); - entry.data.insert(child_key.as_ref().to_vec(), value.as_ref().to_vec()); + entry.data.insert(key.as_ref().to_vec(), value.as_ref().to_vec()); self } @@ -189,8 +191,8 @@ impl TestClientBuilder::Header as HeaderT>::Hashing as HashT>::trie_root( child_content.data.clone().into_iter().collect() ); - (sk.clone(), state_root.encode()) + let prefixed_storage_key = child_content.child_info.prefixed_storage_key(); + (prefixed_storage_key.into_inner(), state_root.encode()) }); let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( storage.top.clone().into_iter().chain(child_roots).collect() @@ -192,22 +193,21 @@ pub trait TestClientBuilderExt: Sized { /// # Panics /// /// Panics if the key is empty. - fn add_extra_child_storage>, K: Into>, V: Into>>( + fn add_extra_child_storage>, V: Into>>( mut self, - storage_key: SK, - child_info: ChildInfo, + child_info: &ChildInfo, key: K, value: V, ) -> Self { - let storage_key = storage_key.into(); + let storage_key = child_info.storage_key().to_vec(); let key = key.into(); assert!(!storage_key.is_empty()); assert!(!key.is_empty()); - self.genesis_init_mut().extra_storage.children + self.genesis_init_mut().extra_storage.children_default .entry(storage_key) .or_insert_with(|| StorageChild { data: Default::default(), - child_info: child_info.to_owned(), + child_info: child_info.clone(), }).data.insert(key, value.into()); self } @@ -311,7 +311,10 @@ impl Fetcher for LightFetcher { unimplemented!() } - fn remote_read_child(&self, _: RemoteReadChildRequest) -> Self::RemoteReadResult { + fn remote_read_child( + &self, + _: RemoteReadChildRequest, + ) -> Self::RemoteReadResult { unimplemented!() } diff --git a/test-utils/runtime/src/genesismap.rs b/test-utils/runtime/src/genesismap.rs index 25d9a807cc..b9de3ab3f4 100644 --- a/test-utils/runtime/src/genesismap.rs +++ b/test-utils/runtime/src/genesismap.rs @@ -73,7 +73,7 @@ impl GenesisConfig { map.extend(self.extra_storage.top.clone().into_iter()); // Assimilate the system genesis config. - let mut storage = Storage { top: map, children: self.extra_storage.children.clone()}; + let mut storage = Storage { top: map, children_default: self.extra_storage.children_default.clone()}; let mut config = system::GenesisConfig::default(); config.authorities = self.authorities.clone(); config.assimilate_storage(&mut storage).expect("Adding `system::GensisConfig` to the genesis"); @@ -85,7 +85,7 @@ impl GenesisConfig { pub fn insert_genesis_block( storage: &mut Storage, ) -> sp_core::hash::H256 { - let child_roots = storage.children.iter().map(|(sk, child_content)| { + let child_roots = storage.children_default.iter().map(|(sk, child_content)| { let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( child_content.data.clone().into_iter().collect(), ); diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 65fbf300bb..cfafb76521 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -50,7 +50,6 @@ use sp_version::NativeVersion; use frame_support::{impl_outer_origin, parameter_types, weights::{Weight, RuntimeDbWeight}}; use sp_inherents::{CheckInherentsResult, InherentData}; use cfg_if::cfg_if; -use sp_core::storage::ChildType; // Ensure Babe and Aura use the same crypto to simplify things a bit. pub use sp_consensus_babe::{AuthorityId, SlotNumber}; @@ -923,22 +922,17 @@ fn test_read_storage() { } fn test_read_child_storage() { - const CHILD_KEY: &[u8] = b":child_storage:default:read_child_storage"; - const UNIQUE_ID: &[u8] = b":unique_id"; + const STORAGE_KEY: &[u8] = b"unique_id_1"; const KEY: &[u8] = b":read_child_storage"; - sp_io::storage::child_set( - CHILD_KEY, - UNIQUE_ID, - ChildType::CryptoUniqueId as u32, + sp_io::default_child_storage::set( + STORAGE_KEY, KEY, b"test", ); let mut v = [0u8; 4]; - let r = sp_io::storage::child_read( - CHILD_KEY, - UNIQUE_ID, - ChildType::CryptoUniqueId as u32, + let r = sp_io::default_child_storage::read( + STORAGE_KEY, KEY, &mut v, 0, @@ -947,10 +941,8 @@ fn test_read_child_storage() { assert_eq!(&v, b"test"); let mut v = [0u8; 4]; - let r = sp_io::storage::child_read( - CHILD_KEY, - UNIQUE_ID, - ChildType::CryptoUniqueId as u32, + let r = sp_io::default_child_storage::read( + STORAGE_KEY, KEY, &mut v, 8, diff --git a/test-utils/runtime/src/system.rs b/test-utils/runtime/src/system.rs index c35850ae95..9cfec187dd 100644 --- a/test-utils/runtime/src/system.rs +++ b/test-utils/runtime/src/system.rs @@ -373,7 +373,7 @@ mod tests { vec![111u8, 0, 0, 0, 0, 0, 0, 0] } ], - children: map![], + children_default: map![], }, ) } -- GitLab From 9a9322fe64cdc947e390d10ad61698378ae3029f Mon Sep 17 00:00:00 2001 From: Vladimir Komendantskiy Date: Mon, 20 Apr 2020 20:05:45 +0100 Subject: [PATCH 275/300] added the Polymath subkey ID (#5705) --- primitives/core/src/crypto.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index 79a36b2ad2..6e29496037 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -455,6 +455,8 @@ ss58_address_format!( (10, "acala", "Acala mainnet, standard account (*25519).") LaminarAccount => (11, "laminar", "Laminar mainnet, standard account (*25519).") + PolymathAccount => + (12, "polymath", "Polymath network, standard account (*25519).") KulupuAccount => (16, "kulupu", "Kulupu mainnet, standard account (*25519).") DarwiniaAccount => -- GitLab From ac6e82ea017bd9df0c602dd938e61c1f0c82f6ba Mon Sep 17 00:00:00 2001 From: Yuanchao Sun Date: Tue, 21 Apr 2020 03:09:55 +0800 Subject: [PATCH 276/300] Add RPC function state_getProof, resolves #1110 (#5649) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add RPC function state_getProof, resolves #1110 * Apply suggestions from code review * Update client/rpc/src/state/state_full.rs Co-Authored-By: Bastian Köcher * Update Cargo.lock * Make block hash optional * Wrap StorageProof as Bytes * Add struct ReadProof * Fix typo Co-authored-by: Bastian Köcher --- client/rpc-api/src/state/helpers.rs | 30 +++++++++++++++++++++++++++++ client/rpc-api/src/state/mod.rs | 6 ++++++ client/rpc/src/state/mod.rs | 17 +++++++++++++--- client/rpc/src/state/state_full.rs | 26 ++++++++++++++++++++++--- client/rpc/src/state/state_light.rs | 10 +++++++++- 5 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 client/rpc-api/src/state/helpers.rs diff --git a/client/rpc-api/src/state/helpers.rs b/client/rpc-api/src/state/helpers.rs new file mode 100644 index 0000000000..516b6c80c4 --- /dev/null +++ b/client/rpc-api/src/state/helpers.rs @@ -0,0 +1,30 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate state API helpers. + +use sp_core::Bytes; +use serde::{Serialize, Deserialize}; + +/// ReadProof struct returned by the RPC +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ReadProof { + /// Block hash used to generate the proof + pub at: Hash, + /// A proof used to prove that storage entries are included in the storage trie + pub proof: Vec, +} diff --git a/client/rpc-api/src/state/mod.rs b/client/rpc-api/src/state/mod.rs index 243a33c18d..3d38a16eb4 100644 --- a/client/rpc-api/src/state/mod.rs +++ b/client/rpc-api/src/state/mod.rs @@ -17,6 +17,7 @@ //! Substrate state API. pub mod error; +pub mod helpers; use jsonrpc_core::Result as RpcResult; use jsonrpc_core::futures::Future; @@ -28,6 +29,7 @@ use sp_version::RuntimeVersion; use self::error::FutureResult; pub use self::gen_client::Client as StateClient; +pub use self::helpers::ReadProof; /// Substrate state API #[rpc] @@ -100,6 +102,10 @@ pub trait StateApi { at: Option, ) -> FutureResult>>; + /// Returns proof of storage entries at a specific block's state. + #[rpc(name = "state_getReadProof")] + fn read_proof(&self, keys: Vec, hash: Option) -> FutureResult>; + /// New runtime version subscription #[pubsub( subscription = "state_runtimeVersion", diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index e696282433..b3ac367422 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -26,7 +26,7 @@ use std::sync::Arc; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use rpc::{Result as RpcResult, futures::{Future, future::result}}; -use sc_rpc_api::Subscriptions; +use sc_rpc_api::{Subscriptions, state::ReadProof}; use sc_client::{light::{blockchain::RemoteBlockchain, fetcher::Fetcher}}; use sp_core::{Bytes, storage::{StorageKey, PrefixedStorageKey, StorageData, StorageChangeSet}}; use sp_version::RuntimeVersion; @@ -38,7 +38,7 @@ use self::error::{Error, FutureResult}; pub use sc_rpc_api::state::*; pub use sc_rpc_api::child_state::*; -use sc_client_api::{ExecutorProvider, StorageProvider, BlockchainEvents, Backend}; +use sc_client_api::{ExecutorProvider, StorageProvider, BlockchainEvents, Backend, ProofProvider}; use sp_blockchain::{HeaderMetadata, HeaderBackend}; const STORAGE_KEYS_PAGED_MAX_COUNT: u32 = 1000; @@ -128,6 +128,13 @@ pub trait StateBackend: Send + Sync + 'static at: Option ) -> FutureResult>>; + /// Returns proof of storage entries at a specific block's state. + fn read_proof( + &self, + block: Option, + keys: Vec, + ) -> FutureResult>; + /// New runtime version subscription fn subscribe_runtime_version( &self, @@ -166,7 +173,7 @@ pub fn new_full( where Block: BlockT + 'static, BE: Backend + 'static, - Client: ExecutorProvider + StorageProvider + HeaderBackend + Client: ExecutorProvider + StorageProvider + ProofProvider + HeaderBackend + HeaderMetadata + BlockchainEvents + CallApiAt + ProvideRuntimeApi + Send + Sync + 'static, @@ -294,6 +301,10 @@ impl StateApi for State self.backend.query_storage_at(keys, at) } + fn read_proof(&self, keys: Vec, block: Option) -> FutureResult> { + self.backend.read_proof(block, keys) + } + fn subscribe_storage( &self, meta: Self::Metadata, diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index a9767c34fc..4546692b7b 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -24,7 +24,7 @@ use log::warn; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use rpc::{Result as RpcResult, futures::{stream, Future, Sink, Stream, future::result}}; -use sc_rpc_api::Subscriptions; +use sc_rpc_api::{Subscriptions, state::ReadProof}; use sc_client_api::backend::Backend; use sp_blockchain::{Result as ClientResult, Error as ClientError, HeaderMetadata, CachedHeaderMetadata, HeaderBackend}; use sc_client::BlockchainEvents; @@ -41,7 +41,7 @@ use sp_api::{Metadata, ProvideRuntimeApi, CallApiAt}; use super::{StateBackend, ChildStateBackend, error::{FutureResult, Error, Result}, client_err}; use std::marker::PhantomData; -use sc_client_api::{CallExecutor, StorageProvider, ExecutorProvider}; +use sc_client_api::{CallExecutor, StorageProvider, ExecutorProvider, ProofProvider}; /// Ranges to query in state_queryStorage. struct QueryStorageRange { @@ -219,7 +219,7 @@ impl FullState impl StateBackend for FullState where Block: BlockT + 'static, BE: Backend + 'static, - Client: ExecutorProvider + StorageProvider + HeaderBackend + Client: ExecutorProvider + StorageProvider + ProofProvider + HeaderBackend + HeaderMetadata + BlockchainEvents + CallApiAt + ProvideRuntimeApi + Send + Sync + 'static, @@ -351,6 +351,26 @@ impl StateBackend for FullState, + keys: Vec, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| { + self.client + .read_proof( + &BlockId::Hash(block), + &mut keys.iter().map(|key| key.0.as_ref()), + ) + .map(|proof| proof.iter_nodes().map(|node| node.into()).collect()) + .map(|proof| ReadProof { at: block, proof }) + }) + .map_err(client_err), + )) + } + fn subscribe_runtime_version( &self, _meta: crate::metadata::Metadata, diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index 27adbcd691..10adab9cc3 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -38,7 +38,7 @@ use rpc::{ futures::stream::Stream, }; -use sc_rpc_api::Subscriptions; +use sc_rpc_api::{Subscriptions, state::ReadProof}; use sp_blockchain::{Error as ClientError, HeaderBackend}; use sc_client::{ BlockchainEvents, @@ -279,6 +279,14 @@ impl StateBackend for LightState, + _keys: Vec, + ) -> FutureResult> { + Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) + } + fn subscribe_storage( &self, _meta: crate::metadata::Metadata, -- GitLab From 99adaeb04f68c3be7f7b66366faaf492c44ec57d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 20 Apr 2020 22:40:44 +0200 Subject: [PATCH 277/300] client/network-gossip: Move sink IO outside of state_machine (#5669) * client/network-gossip: Move sink IO outside of state_machine `ConsensusGossip` is supposed to be a deterministic state machine. `GossipEngine` wrapping `ConsensusGossip` should handle IO operations. This commit moves the `message_sink` IO operations to `GossipEngine`. More specifically on incoming messages a `GossipEngine` calls `ConsensusGossip::on_incoming` to validate and register the messages. `ConsensusGossip` returns the valid messages which are then forwarded by `GossipEngine` to the upper layer via the `message_sinks`. * client/network-gossip: Adjust and extend tests * Update client/network-gossip/src/bridge.rs Co-authored-by: Benjamin Kampmann --- Cargo.lock | 1 + client/network-gossip/Cargo.toml | 1 + client/network-gossip/src/bridge.rs | 190 +++++++++++++++++---- client/network-gossip/src/state_machine.rs | 100 ++++------- 4 files changed, 196 insertions(+), 96 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 325d602c8e..7b36a7d08a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6463,6 +6463,7 @@ dependencies = [ name = "sc-network-gossip" version = "0.8.0-dev" dependencies = [ + "async-std", "futures 0.3.4", "futures-timer 3.0.2", "libp2p", diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index a4b3f72b04..c6714375fe 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -25,4 +25,5 @@ sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } wasm-timer = "0.2" [dev-dependencies] +async-std = "1.5" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } diff --git a/client/network-gossip/src/bridge.rs b/client/network-gossip/src/bridge.rs index b3bfe606ba..a15195111e 100644 --- a/client/network-gossip/src/bridge.rs +++ b/client/network-gossip/src/bridge.rs @@ -21,9 +21,16 @@ use sc_network::{Event, ReputationChange}; use futures::prelude::*; use libp2p::PeerId; +use log::trace; use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; -use std::{borrow::Cow, pin::Pin, sync::Arc, task::{Context, Poll}}; -use sp_utils::mpsc::TracingUnboundedReceiver; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; +use std::{ + borrow::Cow, + collections::{HashMap, hash_map::Entry}, + pin::Pin, + sync::Arc, + task::{Context, Poll}, +}; /// Wraps around an implementation of the `Network` crate and provides gossiping capabilities on /// top of it. @@ -31,8 +38,12 @@ pub struct GossipEngine { state_machine: ConsensusGossip, network: Box + Send>, periodic_maintenance_interval: futures_timer::Delay, - network_event_stream: Pin + Send>>, engine_id: ConsensusEngineId, + + /// Incoming events from the network. + network_event_stream: Pin + Send>>, + /// Outgoing events to the consumer. + message_sinks: HashMap>>, } impl Unpin for GossipEngine {} @@ -54,8 +65,10 @@ impl GossipEngine { state_machine: ConsensusGossip::new(validator, engine_id), network: Box::new(network), periodic_maintenance_interval: futures_timer::Delay::new(PERIODIC_MAINTENANCE_INTERVAL), - network_event_stream, engine_id, + + network_event_stream, + message_sinks: HashMap::new(), } } @@ -85,7 +98,15 @@ impl GossipEngine { pub fn messages_for(&mut self, topic: B::Hash) -> TracingUnboundedReceiver { - self.state_machine.messages_for(topic) + let (tx, rx) = tracing_unbounded("mpsc_gossip_messages_for"); + + for notification in self.state_machine.messages_for(topic) { + tx.unbounded_send(notification).expect("receiver known to be live; qed"); + } + + self.message_sinks.entry(topic).or_default().push(tx); + + rx } /// Send all messages with given topic to a peer. @@ -147,16 +168,40 @@ impl Future for GossipEngine { this.state_machine.peer_disconnected(&mut *this.network, remote); }, Event::NotificationsReceived { remote, messages } => { - let engine_id = this.engine_id.clone(); - this.state_machine.on_incoming( + let messages = messages.into_iter().filter_map(|(engine, data)| { + if engine == this.engine_id { + Some(data.to_vec()) + } else { + None + } + }).collect(); + + let to_forward = this.state_machine.on_incoming( &mut *this.network, remote, - messages.into_iter() - .filter_map(|(engine, data)| if engine == engine_id { - Some(data.to_vec()) - } else { None }) - .collect() + messages, ); + + for (topic, notification) in to_forward.into_iter() { + if let Entry::Occupied(mut entry) = this.message_sinks.entry(topic) { + trace!( + target: "gossip", + "Pushing consensus message to sinks for {}.", topic, + ); + entry.get_mut().retain(move |sink| { + if let Err(e) = sink.unbounded_send(notification.clone()) { + trace!( + target: "gossip", + "Error broadcasting message notification: {:?}", e, + ); + } + !sink.is_closed() + }); + if entry.get().is_empty() { + entry.remove_entry(); + } + } + } }, Event::Dht(_) => {} } @@ -169,6 +214,11 @@ impl Future for GossipEngine { while let Poll::Ready(()) = this.periodic_maintenance_interval.poll_unpin(cx) { this.periodic_maintenance_interval.reset(PERIODIC_MAINTENANCE_INTERVAL); this.state_machine.tick(&mut *this.network); + + this.message_sinks.retain(|_, sinks| { + sinks.retain(|sink| !sink.is_closed()); + !sinks.is_empty() + }); } Poll::Pending @@ -177,23 +227,34 @@ impl Future for GossipEngine { #[cfg(test)] mod tests { - use super::*; + use async_std::task::spawn; use crate::{ValidationResult, ValidatorContext}; + use futures::{channel::mpsc::{channel, Sender}, executor::block_on_stream}; + use sc_network::ObservedRole; + use sp_runtime::{testing::H256, traits::{Block as BlockT}}; + use std::sync::{Arc, Mutex}; use substrate_test_runtime_client::runtime::Block; + use super::*; - struct TestNetwork {} + #[derive(Clone, Default)] + struct TestNetwork { + inner: Arc>, + } + + #[derive(Clone, Default)] + struct TestNetworkInner { + event_senders: Vec>, + } - impl Network for Arc { + impl Network for TestNetwork { fn event_stream(&self) -> Pin + Send>> { - let (_tx, rx) = futures::channel::mpsc::channel(0); + let (tx, rx) = channel(100); + self.inner.lock().unwrap().event_senders.push(tx); - // Return rx and drop tx. Thus the given channel will yield `Poll::Ready(None)` on first - // poll. Box::pin(rx) } fn report_peer(&self, _: PeerId, _: ReputationChange) { - unimplemented!(); } fn disconnect_peer(&self, _: PeerId) { @@ -211,16 +272,15 @@ mod tests { } } - struct TestValidator {} - - impl Validator for TestValidator { + struct AllowAll; + impl Validator for AllowAll { fn validate( &self, - _: &mut dyn ValidatorContext, - _: &PeerId, - _: &[u8] - ) -> ValidationResult { - unimplemented!(); + _context: &mut dyn ValidatorContext, + _sender: &PeerId, + _data: &[u8], + ) -> ValidationResult { + ValidationResult::ProcessAndKeep(H256::default()) } } @@ -230,13 +290,17 @@ mod tests { /// See https://github.com/paritytech/substrate/issues/5000 for details. #[test] fn returns_when_network_event_stream_closes() { + let network = TestNetwork::default(); let mut gossip_engine = GossipEngine::::new( - Arc::new(TestNetwork{}), + network.clone(), [1, 2, 3, 4], "my_protocol".as_bytes(), - Arc::new(TestValidator{}), + Arc::new(AllowAll{}), ); + // Drop network event stream sender side. + drop(network.inner.lock().unwrap().event_senders.pop()); + futures::executor::block_on(futures::future::poll_fn(move |ctx| { if let Poll::Pending = gossip_engine.poll_unpin(ctx) { panic!( @@ -247,4 +311,72 @@ mod tests { Poll::Ready(()) })) } + + #[test] + fn keeps_multiple_subscribers_per_topic_updated_with_both_old_and_new_messages() { + let topic = H256::default(); + let engine_id = [1, 2, 3, 4]; + let remote_peer = PeerId::random(); + let network = TestNetwork::default(); + + let mut gossip_engine = GossipEngine::::new( + network.clone(), + engine_id.clone(), + "my_protocol".as_bytes(), + Arc::new(AllowAll{}), + ); + + let mut event_sender = network.inner.lock() + .unwrap() + .event_senders + .pop() + .unwrap(); + + // Register the remote peer. + event_sender.start_send( + Event::NotificationStreamOpened { + remote: remote_peer.clone(), + engine_id: engine_id.clone(), + role: ObservedRole::Authority, + } + ).unwrap(); + + let messages = vec![vec![1], vec![2]]; + let events = messages.iter().cloned().map(|m| { + Event::NotificationsReceived { + remote: remote_peer.clone(), + messages: vec![(engine_id, m.into())] + } + }).collect::>(); + + // Send first event before subscribing. + event_sender.start_send(events[0].clone()).unwrap(); + + let mut subscribers = vec![]; + for _ in 0..2 { + subscribers.push(gossip_engine.messages_for(topic)); + } + + // Send second event after subscribing. + event_sender.start_send(events[1].clone()).unwrap(); + + spawn(gossip_engine); + + let mut subscribers = subscribers.into_iter() + .map(|s| block_on_stream(s)) + .collect::>(); + + // Expect each subscriber to receive both events. + for message in messages { + for subscriber in subscribers.iter_mut() { + assert_eq!( + subscriber.next(), + Some(TopicNotification { + message: message.clone(), + sender: Some(remote_peer.clone()), + }), + ); + } + } + } } diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index d93003fcfb..53b5b98245 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -16,7 +16,7 @@ use crate::{Network, MessageIntent, Validator, ValidatorContext, ValidationResult}; -use std::collections::{HashMap, HashSet, hash_map::Entry}; +use std::collections::{HashMap, HashSet}; use std::sync::Arc; use std::iter; use std::time; @@ -24,7 +24,6 @@ use log::trace; use lru::LruCache; use libp2p::PeerId; use sp_runtime::traits::{Block as BlockT, Hash, HashFor}; -use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; use sp_runtime::ConsensusEngineId; use sc_network::ObservedRole; use wasm_timer::Instant; @@ -51,7 +50,7 @@ struct PeerConsensus { } /// Topic stream message with sender. -#[derive(Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct TopicNotification { /// Message data. pub message: Vec, @@ -147,7 +146,6 @@ fn propagate<'a, B: BlockT, I>( /// Consensus network protocol handler. Manages statements and candidate requests. pub struct ConsensusGossip { peers: HashMap>, - live_message_sinks: HashMap>>, messages: Vec>, known_messages: LruCache, engine_id: ConsensusEngineId, @@ -160,7 +158,6 @@ impl ConsensusGossip { pub fn new(validator: Arc>, engine_id: ConsensusEngineId) -> Self { ConsensusGossip { peers: HashMap::new(), - live_message_sinks: HashMap::new(), messages: Default::default(), known_messages: LruCache::new(KNOWN_MESSAGES_CACHE_SIZE), engine_id, @@ -256,11 +253,6 @@ impl ConsensusGossip { /// Prune old or no longer relevant consensus messages. Provide a predicate /// for pruning, which returns `false` when the items with a given topic should be pruned. pub fn collect_garbage(&mut self) { - self.live_message_sinks.retain(|_, sinks| { - sinks.retain(|sink| !sink.is_closed()); - !sinks.is_empty() - }); - let known_messages = &mut self.known_messages; let before = self.messages.len(); @@ -278,33 +270,24 @@ impl ConsensusGossip { } } - /// Get data of valid, incoming messages for a topic (but might have expired meanwhile) - pub fn messages_for(&mut self, topic: B::Hash) - -> TracingUnboundedReceiver - { - let (tx, rx) = tracing_unbounded("mpsc_gossip_messages_for"); - for entry in self.messages.iter_mut().filter(|e| e.topic == topic) { - tx.unbounded_send(TopicNotification { - message: entry.message.clone(), - sender: entry.sender.clone(), - }) - .expect("receiver known to be live; qed"); - } - - self.live_message_sinks.entry(topic).or_default().push(tx); - - rx + /// Get valid messages received in the past for a topic (might have expired meanwhile). + pub fn messages_for(&mut self, topic: B::Hash) -> impl Iterator + '_ { + self.messages.iter().filter(move |e| e.topic == topic).map(|entry| TopicNotification { + message: entry.message.clone(), + sender: entry.sender.clone(), + }) } - /// Handle an incoming message for topic by who via protocol. Discard message if topic already - /// known, the message is old, its source peers isn't a registered peer or the connection to - /// them is broken. + /// Register incoming messages and return the ones that are new and valid (according to a gossip + /// validator) and should thus be forwarded to the upper layers. pub fn on_incoming( &mut self, network: &mut dyn Network, who: PeerId, messages: Vec>, - ) { + ) -> Vec<(B::Hash, TopicNotification)> { + let mut to_forward = vec![]; + if !messages.is_empty() { trace!(target: "gossip", "Received {} messages from peer {}", messages.len(), who); } @@ -335,23 +318,19 @@ impl ConsensusGossip { network.report_peer(who.clone(), rep::GOSSIP_SUCCESS); if let Some(ref mut peer) = self.peers.get_mut(&who) { peer.known_messages.insert(message_hash); - if let Entry::Occupied(mut entry) = self.live_message_sinks.entry(topic) { - trace!(target: "gossip", "Pushing consensus message to sinks for {}.", topic); - entry.get_mut().retain(|sink| { - if let Err(e) = sink.unbounded_send(TopicNotification { - message: message.clone(), - sender: Some(who.clone()) - }) { - trace!(target: "gossip", "Error broadcasting message notification: {:?}", e); - } - !sink.is_closed() - }); - if entry.get().is_empty() { - entry.remove_entry(); - } - } + + to_forward.push((topic, TopicNotification { + message: message.clone(), + sender: Some(who.clone()) + })); + if keep { - self.register_message_hashed(message_hash, topic, message, Some(who.clone())); + self.register_message_hashed( + message_hash, + topic, + message, + Some(who.clone()), + ); } } else { trace!(target:"gossip", "Ignored statement from unregistered peer {}", who); @@ -361,6 +340,8 @@ impl ConsensusGossip { trace!(target:"gossip", "Discard message from peer {}", who); } } + + to_forward } /// Send all messages with given topic to a peer. @@ -437,7 +418,6 @@ impl ConsensusGossip { mod tests { use std::sync::Arc; use sp_runtime::testing::{H256, Block as RawBlock, ExtrinsicWrapper}; - use futures::executor::block_on_stream; use super::*; @@ -518,16 +498,18 @@ mod tests { } #[test] - fn message_stream_include_those_sent_before_asking_for_stream() { + fn message_stream_include_those_sent_before_asking() { let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), [0, 0, 0, 0]); + // Register message. let message = vec![4, 5, 6]; let topic = HashFor::::hash(&[1,2,3]); - consensus.register_message(topic, message.clone()); - let mut stream = block_on_stream(consensus.messages_for(topic)); - assert_eq!(stream.next(), Some(TopicNotification { message: message, sender: None })); + assert_eq!( + consensus.messages_for(topic).next(), + Some(TopicNotification { message: message, sender: None }), + ); } #[test] @@ -544,22 +526,6 @@ mod tests { assert_eq!(consensus.messages.len(), 2); } - #[test] - fn can_keep_multiple_subscribers_per_topic() { - let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), [0, 0, 0, 0]); - - let message = vec![4, 5, 6]; - let topic = HashFor::::hash(&[1, 2, 3]); - - consensus.register_message(topic, message.clone()); - - let mut stream1 = block_on_stream(consensus.messages_for(topic)); - let mut stream2 = block_on_stream(consensus.messages_for(topic)); - - assert_eq!(stream1.next(), Some(TopicNotification { message: message.clone(), sender: None })); - assert_eq!(stream2.next(), Some(TopicNotification { message, sender: None })); - } - #[test] fn peer_is_removed_on_disconnect() { struct TestNetwork; -- GitLab From 50c969fbb885fd02a2510c53838f09d0a23c386a Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 21 Apr 2020 10:47:37 +0200 Subject: [PATCH 278/300] Pass an encoded Roles as the notifications protocols handshakes (#5665) --- client/network/src/behaviour.rs | 8 +- client/network/src/lib.rs | 9 +- client/network/src/protocol.rs | 3 +- .../src/protocol/generic_proto/behaviour.rs | 2 + .../protocol/generic_proto/handler/group.rs | 87 +++++++++++-------- 5 files changed, 71 insertions(+), 38 deletions(-) diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index cb9c552115..880b381e66 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -20,6 +20,8 @@ use crate::{ Event, ObservedRole, DhtEvent, ExHashT, }; use crate::protocol::{self, light_client_handler, message::Roles, CustomMessageOutcome, Protocol}; + +use codec::Encode as _; use libp2p::NetworkBehaviour; use libp2p::core::{Multiaddr, PeerId, PublicKey}; use libp2p::kad::record; @@ -135,7 +137,11 @@ impl Behaviour { engine_id: ConsensusEngineId, protocol_name: impl Into>, ) { - let list = self.substrate.register_notifications_protocol(engine_id, protocol_name); + // This is the message that we will send to the remote as part of the initial handshake. + // At the moment, we force this to be an encoded `Roles`. + let handshake_message = Roles::from(&self.role).encode(); + + let list = self.substrate.register_notifications_protocol(engine_id, protocol_name, handshake_message); for (remote, roles) in list { let role = reported_roles_to_observed_role(&self.role, remote, roles); let ev = Event::NotificationStreamOpened { diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index ed96215d20..44bb1516bd 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -210,7 +210,14 @@ //! notifications protocol. //! //! At the moment, for backwards-compatibility, notification protocols are tied to the legacy -//! Substrate substream. In the future, though, it will no longer be the case. +//! Substrate substream. Additionally, the handshake message is hardcoded to be a single 8-bits +//! integer representing the role of the node: +//! +//! - 1 for a full node. +//! - 2 for a light node. +//! - 4 for an authority. +//! +//! In the future, though, these restrictions will be removed. //! //! # Usage //! diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 6ad8259484..42084b7ce3 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -1043,12 +1043,13 @@ impl Protocol { &'a mut self, engine_id: ConsensusEngineId, protocol_name: impl Into>, + handshake_message: Vec, ) -> impl ExactSizeIterator + 'a { let protocol_name = protocol_name.into(); if self.protocol_name_by_engine.insert(engine_id, protocol_name.clone()).is_some() { error!(target: "sub-libp2p", "Notifications protocol already registered: {:?}", protocol_name); } else { - self.behaviour.register_notif_protocol(protocol_name.clone(), Vec::new()); + self.behaviour.register_notif_protocol(protocol_name.clone(), handshake_message); self.legacy_equiv_by_name.insert(protocol_name, Fallback::Consensus(engine_id)); } diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index e62edb3733..35a8b03d36 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -113,6 +113,8 @@ pub struct GenericProto { legacy_protocol: RegisteredProtocol, /// Notification protocols. Entries are only ever added and not removed. + /// Contains, for each protocol, the protocol name and the message to send as part of the + /// initial handshake. notif_protocols: Vec<(Cow<'static, [u8]>, Vec)>, /// Receiver for instructions about who to connect to or disconnect from. diff --git a/client/network/src/protocol/generic_proto/handler/group.rs b/client/network/src/protocol/generic_proto/handler/group.rs index 46b759d458..04293c7c9f 100644 --- a/client/network/src/protocol/generic_proto/handler/group.rs +++ b/client/network/src/protocol/generic_proto/handler/group.rs @@ -75,11 +75,12 @@ use std::{borrow::Cow, error, io, str, task::{Context, Poll}}; /// /// See the documentation at the module level for more information. pub struct NotifsHandlerProto { - /// Prototypes for handlers for inbound substreams. - in_handlers: Vec, + /// Prototypes for handlers for inbound substreams, and the message we respond with in the + /// handshake. + in_handlers: Vec<(NotifsInHandlerProto, Vec)>, - /// Prototypes for handlers for outbound substreams. - out_handlers: Vec, + /// Prototypes for handlers for outbound substreams, and the initial handshake message we send. + out_handlers: Vec<(NotifsOutHandlerProto, Vec)>, /// Prototype for handler for backwards-compatibility. legacy: LegacyProtoHandlerProto, @@ -89,11 +90,11 @@ pub struct NotifsHandlerProto { /// /// See the documentation at the module level for more information. pub struct NotifsHandler { - /// Handlers for inbound substreams. - in_handlers: Vec, + /// Handlers for inbound substreams, and the message we respond with in the handshake. + in_handlers: Vec<(NotifsInHandler, Vec)>, - /// Handlers for outbound substreams. - out_handlers: Vec, + /// Handlers for outbound substreams, and the initial handshake message we send. + out_handlers: Vec<(NotifsOutHandler, Vec)>, /// Handler for backwards-compatibility. legacy: LegacyProtoHandler, @@ -119,7 +120,7 @@ impl IntoProtocolsHandler for NotifsHandlerProto { fn inbound_protocol(&self) -> SelectUpgrade, RegisteredProtocol> { let in_handlers = self.in_handlers.iter() - .map(|h| h.inbound_protocol()) + .map(|(h, _)| h.inbound_protocol()) .collect::>(); SelectUpgrade::new(in_handlers, self.legacy.inbound_protocol()) @@ -129,11 +130,11 @@ impl IntoProtocolsHandler for NotifsHandlerProto { NotifsHandler { in_handlers: self.in_handlers .into_iter() - .map(|p| p.into_handler(remote_peer_id, connected_point)) + .map(|(proto, msg)| (proto.into_handler(remote_peer_id, connected_point), msg)) .collect(), out_handlers: self.out_handlers .into_iter() - .map(|p| p.into_handler(remote_peer_id, connected_point)) + .map(|(proto, msg)| (proto.into_handler(remote_peer_id, connected_point), msg)) .collect(), legacy: self.legacy.into_handler(remote_peer_id, connected_point), enabled: EnabledState::Initial, @@ -232,28 +233,42 @@ pub enum NotifsHandlerOut { impl NotifsHandlerProto { /// Builds a new handler. /// + /// `list` is a list of notification protocols names, and the message to send as part of the + /// handshake. At the moment, the message is always the same whether we open a substream + /// ourselves or respond to handshake from the remote. + /// /// The `queue_size_report` is an optional Prometheus metric that can report the size of the /// messages queue. If passed, it must have one label for the protocol name. - pub fn new(legacy: RegisteredProtocol, list: impl Into, Vec)>>, queue_size_report: Option) -> Self { + pub fn new( + legacy: RegisteredProtocol, + list: impl Into, Vec)>>, + queue_size_report: Option + ) -> Self { let list = list.into(); let out_handlers = list .clone() .into_iter() - .map(|(p, _)| { + .map(|(proto_name, initial_message)| { let queue_size_report = queue_size_report.as_ref().and_then(|qs| { - if let Ok(utf8) = str::from_utf8(&p) { + if let Ok(utf8) = str::from_utf8(&proto_name) { Some(qs.with_label_values(&[utf8])) } else { - log::warn!("Ignoring Prometheus metric because {:?} isn't UTF-8", p); + log::warn!("Ignoring Prometheus metric because {:?} isn't UTF-8", proto_name); None } }); - NotifsOutHandlerProto::new(p, queue_size_report) + + (NotifsOutHandlerProto::new(proto_name, queue_size_report), initial_message) }).collect(); + let in_handlers = list.clone() + .into_iter() + .map(|(proto_name, msg)| (NotifsInHandlerProto::new(proto_name), msg)) + .collect(); + NotifsHandlerProto { - in_handlers: list.clone().into_iter().map(|(p, _)| NotifsInHandlerProto::new(p)).collect(), + in_handlers, out_handlers, legacy: LegacyProtoHandlerProto::new(legacy), } @@ -277,7 +292,7 @@ impl ProtocolsHandler for NotifsHandler { fn listen_protocol(&self) -> SubstreamProtocol { let in_handlers = self.in_handlers.iter() - .map(|h| h.listen_protocol().into_upgrade().1) + .map(|(h, _)| h.listen_protocol().into_upgrade().1) .collect::>(); let proto = SelectUpgrade::new(in_handlers, self.legacy.listen_protocol().into_upgrade().1); @@ -290,7 +305,7 @@ impl ProtocolsHandler for NotifsHandler { ) { match out { EitherOutput::First((out, num)) => - self.in_handlers[num].inject_fully_negotiated_inbound(out), + self.in_handlers[num].0.inject_fully_negotiated_inbound(out), EitherOutput::Second(out) => self.legacy.inject_fully_negotiated_inbound(out), } @@ -303,7 +318,7 @@ impl ProtocolsHandler for NotifsHandler { ) { match (out, num) { (EitherOutput::First(out), Some(num)) => - self.out_handlers[num].inject_fully_negotiated_outbound(out, ()), + self.out_handlers[num].0.inject_fully_negotiated_outbound(out, ()), (EitherOutput::Second(out), None) => self.legacy.inject_fully_negotiated_outbound(out, ()), _ => error!("inject_fully_negotiated_outbound called with wrong parameters"), @@ -318,13 +333,15 @@ impl ProtocolsHandler for NotifsHandler { } self.enabled = EnabledState::Enabled; self.legacy.inject_event(LegacyProtoHandlerIn::Enable); - for handler in &mut self.out_handlers { + for (handler, initial_message) in &mut self.out_handlers { handler.inject_event(NotifsOutHandlerIn::Enable { - initial_message: vec![] + initial_message: initial_message.clone(), }); } for num in self.pending_in.drain(..) { - self.in_handlers[num].inject_event(NotifsInHandlerIn::Accept(vec![])); + let handshake_message = self.in_handlers[num].1.clone(); + self.in_handlers[num].0 + .inject_event(NotifsInHandlerIn::Accept(handshake_message)); } }, NotifsHandlerIn::Disable => { @@ -335,19 +352,19 @@ impl ProtocolsHandler for NotifsHandler { // The notifications protocols start in the disabled state. If we were in the // "Initial" state, then we shouldn't disable the notifications protocols again. if self.enabled != EnabledState::Initial { - for handler in &mut self.out_handlers { + for (handler, _) in &mut self.out_handlers { handler.inject_event(NotifsOutHandlerIn::Disable); } } self.enabled = EnabledState::Disabled; for num in self.pending_in.drain(..) { - self.in_handlers[num].inject_event(NotifsInHandlerIn::Refuse); + self.in_handlers[num].0.inject_event(NotifsInHandlerIn::Refuse); } }, NotifsHandlerIn::SendLegacy { message } => self.legacy.inject_event(LegacyProtoHandlerIn::SendCustomMessage { message }), NotifsHandlerIn::SendNotification { message, encoded_fallback_message, protocol_name } => { - for handler in &mut self.out_handlers { + for (handler, _) in &mut self.out_handlers { if handler.protocol_name() != &protocol_name[..] { continue; } @@ -372,21 +389,21 @@ impl ProtocolsHandler for NotifsHandler { ) { match (err, num) { (ProtocolsHandlerUpgrErr::Timeout, Some(num)) => - self.out_handlers[num].inject_dial_upgrade_error( + self.out_handlers[num].0.inject_dial_upgrade_error( (), ProtocolsHandlerUpgrErr::Timeout ), (ProtocolsHandlerUpgrErr::Timeout, None) => self.legacy.inject_dial_upgrade_error((), ProtocolsHandlerUpgrErr::Timeout), (ProtocolsHandlerUpgrErr::Timer, Some(num)) => - self.out_handlers[num].inject_dial_upgrade_error( + self.out_handlers[num].0.inject_dial_upgrade_error( (), ProtocolsHandlerUpgrErr::Timer ), (ProtocolsHandlerUpgrErr::Timer, None) => self.legacy.inject_dial_upgrade_error((), ProtocolsHandlerUpgrErr::Timer), (ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), Some(num)) => - self.out_handlers[num].inject_dial_upgrade_error( + self.out_handlers[num].0.inject_dial_upgrade_error( (), ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)) ), @@ -396,7 +413,7 @@ impl ProtocolsHandler for NotifsHandler { ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)) ), (ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::A(err))), Some(num)) => - self.out_handlers[num].inject_dial_upgrade_error( + self.out_handlers[num].0.inject_dial_upgrade_error( (), ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)) ), @@ -417,7 +434,7 @@ impl ProtocolsHandler for NotifsHandler { return KeepAlive::Yes; } - for handler in &self.in_handlers { + for (handler, _) in &self.in_handlers { let val = handler.connection_keep_alive(); if val.is_yes() { return KeepAlive::Yes; @@ -425,7 +442,7 @@ impl ProtocolsHandler for NotifsHandler { if ret < val { ret = val; } } - for handler in &self.out_handlers { + for (handler, _) in &self.out_handlers { let val = handler.connection_keep_alive(); if val.is_yes() { return KeepAlive::Yes; @@ -474,7 +491,7 @@ impl ProtocolsHandler for NotifsHandler { } } - for (handler_num, handler) in self.in_handlers.iter_mut().enumerate() { + for (handler_num, (handler, handshake_message)) in self.in_handlers.iter_mut().enumerate() { while let Poll::Ready(ev) = handler.poll(cx) { match ev { ProtocolsHandlerEvent::OutboundSubstreamRequest { .. } => @@ -484,7 +501,7 @@ impl ProtocolsHandler for NotifsHandler { match self.enabled { EnabledState::Initial => self.pending_in.push(handler_num), EnabledState::Enabled => - handler.inject_event(NotifsInHandlerIn::Accept(vec![])), + handler.inject_event(NotifsInHandlerIn::Accept(handshake_message.clone())), EnabledState::Disabled => handler.inject_event(NotifsInHandlerIn::Refuse), }, @@ -504,7 +521,7 @@ impl ProtocolsHandler for NotifsHandler { } } - for (handler_num, handler) in self.out_handlers.iter_mut().enumerate() { + for (handler_num, (handler, _)) in self.out_handlers.iter_mut().enumerate() { while let Poll::Ready(ev) = handler.poll(cx) { match ev { ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol, info: () } => -- GitLab From c5d81172d64cb958c3d61e160563006c72b8b0f4 Mon Sep 17 00:00:00 2001 From: Joshy Orndorff Date: Tue, 21 Apr 2020 04:52:34 -0400 Subject: [PATCH 279/300] Move AuraPair import to new_full_start! macro (#5709) --- bin/node-template/node/src/command.rs | 1 - bin/node-template/node/src/service.rs | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/node-template/node/src/command.rs b/bin/node-template/node/src/command.rs index 7950df9a0b..baac33e9ac 100644 --- a/bin/node-template/node/src/command.rs +++ b/bin/node-template/node/src/command.rs @@ -18,7 +18,6 @@ use crate::chain_spec; use crate::cli::Cli; use crate::service; use sc_cli::SubstrateCli; -use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; impl SubstrateCli for Cli { fn impl_name() -> &'static str { diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index b8e4d73db6..62177608a2 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -26,6 +26,8 @@ native_executor_instance!( macro_rules! new_full_start { ($config:expr) => {{ use std::sync::Arc; + use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; + let mut import_setup = None; let inherent_data_providers = sp_inherents::InherentDataProviders::new(); -- GitLab From ededdc4f131da36f1da8954219fcea8eb513f521 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 21 Apr 2020 10:54:37 +0200 Subject: [PATCH 280/300] client/authority-discovery: Add metric exposing priority group size (#5707) Expose the amount of addresses that are passed from the authority discovery module down to the network peer set manager as a priority group in order to connect to the corresponding nodes. ``` authority_discovery_priority_group_size 10 ``` --- client/authority-discovery/src/lib.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/client/authority-discovery/src/lib.rs b/client/authority-discovery/src/lib.rs index 2cf455f17b..91e8293dec 100644 --- a/client/authority-discovery/src/lib.rs +++ b/client/authority-discovery/src/lib.rs @@ -475,6 +475,10 @@ where fn update_peer_set_priority_group(&self) -> Result<()> { let addresses = self.addr_cache.get_subset(); + if let Some(metrics) = &self.metrics { + metrics.priority_group_size.set(addresses.len().try_into().unwrap_or(std::u64::MAX)); + } + debug!( target: LOG_TARGET, "Applying priority group {:?} to peerset.", addresses, @@ -599,6 +603,7 @@ pub(crate) struct Metrics { amount_last_published: Gauge, request: Counter, dht_event_received: CounterVec, + priority_group_size: Gauge, } impl Metrics { @@ -637,6 +642,13 @@ impl Metrics { )?, registry, )?, + priority_group_size: register( + Gauge::new( + "authority_discovery_priority_group_size", + "Number of addresses passed to the peer set as a priority group." + )?, + registry, + )?, }) } } -- GitLab From b20dc82aedd47538a1f17ff125d58fe4f12e2b7c Mon Sep 17 00:00:00 2001 From: Rakan Alhneiti Date: Tue, 21 Apr 2020 14:55:05 +0200 Subject: [PATCH 281/300] Offchain signing (#5182) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * New approach to offchain signing. * Use in im-online * Rewrite to use Account * DRY signing. * Implement send_raw_unsigned_transaction * WiP * Expunge LocalCall * Expunge LocalCall * Fix compilation. * Solve call. * Make it compile again. * Finalize implementation. * Change CreateTransaction * Clear CreateTransaction. * Add price payload * Send raw transaction * Submit signed payload / unsigned transaction (WIP) * Supertrait requirements on T::Signature * Validate signature of payload on an unsigned transaction * Fix encoding - part 1 * Make it compile. * Fix compilation of unsigned validator. * Pass price payload to the transaction * Make block number part of the signed payload * Send signed transaction * Implement all_accounts, any_account * Fix formatting * Implement submit_transaction * Submit signed transaction (ForAll, ForAny) * Fix formatting * Implement CreateSignedTransaction * Move sign and verify to AppCrypto * Sign transaction * Call `use_encoded` * Remove SubmitAndSignTransaction * Implement runtime using new SigningTypes * Adapt offchain example to changes * Fix im-online pallet * Quick fix: rename AuthorityId2 * Fix offchain example tests * Add a comment on why keystore is required in unsigned transaction test * Use UintAuthorityId instead of u64 * WIP * Remove IdentifyAccount from UintAuthorityId * Implement PublicWrapper type * Fix im-online tests * Fix runtime test * Bump spec version * Fix executor tests * Rename ImOnlineAuthId -> ImOnlineAuthorityId and formatting * Fix merge * Documentation * Revert u64 -> UintAuthorityId conversion * Fix string errors * Document public members in offchain module * Introduce SubmitTransaction * Update pallets to use SubmitTransaction * WIP * Use SubmitTransaction in offchain * Use `submit_unsigned_transaction` * Fix tests * Update docs * Remove SigningTypes requirement from `SendTransactionTypes` * Fix tests * Update frame/system/src/offchain.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/system/src/offchain.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/example-offchain-worker/src/tests.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/system/src/offchain.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/system/src/offchain.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Remove leftover from previous iterations * Change enum to struct * Remove public * Move mock to node/executor/tests * Cleanup test-helpers * Make `application-crypto` `std` feature internal The macros should not generate code that requires that the calling crate has a feature with the name `std` defined. * Revert cargo lock update * Use TestAuthorityId from common * Restore members of account to public * Tidy up imports * Fix benchmarking pallet * Add tests demonstrating ForAll, ForAny on signer * Move definition of AppCrypto in example-offchain-worker from tests to mod::crypto * Cleanup stray comment * Fix ValidTransaction * Re-fix CreateSignedTransaction * Address PR feedback * Add can_sign method to signer * Propagate error * Improve documentation * Fix vec! macro not available * Document SendTransactiontypes * Add some docs. * Split signing examples * Add tests for signing examples * WIP can_sign - PR feedback * WIP * Split for_any / for_all into different calls * Verify payload and signature in test * Fix can_sign implementation * Fix impl_version * Import Box from sp_std * Create issues for TODOs * Ignore doctest. * Add test directly to system. Adjust UintTypes. * Add some tests to account filtering. * Remove code samples and point to example offchain worker * Fix doc links * Fix im-online tests using signatures. Co-authored-by: Tomasz Drwięga Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Bastian Köcher --- bin/node/executor/tests/common.rs | 34 +- bin/node/executor/tests/submit_transaction.rs | 135 ++- bin/node/runtime/src/lib.rs | 127 +- frame/example-offchain-worker/src/lib.rs | 331 +++-- frame/example-offchain-worker/src/tests.rs | 166 ++- frame/im-online/src/lib.rs | 34 +- frame/im-online/src/mock.rs | 20 +- frame/im-online/src/tests.rs | 12 +- frame/session/benchmarking/src/mock.rs | 13 +- frame/staking/src/lib.rs | 9 +- frame/staking/src/mock.rs | 10 +- frame/staking/src/offchain_election.rs | 6 +- frame/system/src/lib.rs | 11 +- frame/system/src/offchain.rs | 1071 ++++++++++++----- primitives/application-crypto/src/lib.rs | 2 +- .../src/generic/unchecked_extrinsic.rs | 23 +- primitives/runtime/src/lib.rs | 21 + primitives/runtime/src/testing.rs | 50 +- 18 files changed, 1469 insertions(+), 606 deletions(-) diff --git a/bin/node/executor/tests/common.rs b/bin/node/executor/tests/common.rs index 6b6ef272f8..5a51e4312c 100644 --- a/bin/node/executor/tests/common.rs +++ b/bin/node/executor/tests/common.rs @@ -15,10 +15,21 @@ // along with Substrate. If not, see . use codec::{Encode, Decode}; +use frame_system::offchain::AppCrypto; use frame_support::Hashable; use sp_state_machine::TestExternalities as CoreTestExternalities; -use sp_core::{NeverNativeValue, NativeOrEncoded, traits::{CodeExecutor, RuntimeCode}}; -use sp_runtime::{ApplyExtrinsicResult, traits::{Header as HeaderT, BlakeTwo256}}; +use sp_core::{ + NeverNativeValue, NativeOrEncoded, + crypto::KeyTypeId, + sr25519::Signature, + traits::{CodeExecutor, RuntimeCode}, +}; +use sp_runtime::{ + ApplyExtrinsicResult, + MultiSigner, + MultiSignature, + traits::{Header as HeaderT, BlakeTwo256}, +}; use sc_executor::{NativeExecutor, WasmExecutionMethod}; use sc_executor::error::Result; @@ -31,6 +42,25 @@ use node_primitives::{Hash, BlockNumber}; use node_testing::keyring::*; use sp_externalities::Externalities; +pub const TEST_KEY_TYPE_ID: KeyTypeId = KeyTypeId(*b"test"); + +pub mod sr25519 { + mod app_sr25519 { + use sp_application_crypto::{app_crypto, sr25519}; + use super::super::TEST_KEY_TYPE_ID; + app_crypto!(sr25519, TEST_KEY_TYPE_ID); + } + + pub type AuthorityId = app_sr25519::Public; +} + +pub struct TestAuthorityId; +impl AppCrypto for TestAuthorityId { + type RuntimeAppPublic = sr25519::AuthorityId; + type GenericSignature = Signature; + type GenericPublic = sp_core::sr25519::Public; +} + /// The wasm runtime code. /// /// `compact` since it is after post-processing with wasm-gc which performs tree-shaking thus diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index d92f3e3202..3a41c3483c 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -15,24 +15,29 @@ // along with Substrate. If not, see . use node_runtime::{ - Call, Executive, Indices, Runtime, TransactionSubmitterOf, UncheckedExtrinsic, + Executive, Indices, Runtime, UncheckedExtrinsic, }; use sp_application_crypto::AppKey; use sp_core::testing::KeyStore; -use sp_core::traits::KeystoreExt; -use sp_core::offchain::{ - TransactionPoolExt, - testing::TestTransactionPoolExt, +use sp_core::{ + offchain::{ + TransactionPoolExt, + testing::TestTransactionPoolExt, + }, + traits::KeystoreExt, +}; +use frame_system::{ + offchain::{ + Signer, + SubmitTransaction, + SendSignedTransaction, + } }; -use frame_system::offchain::{SubmitSignedTransaction, SubmitUnsignedTransaction}; -use pallet_im_online::sr25519::AuthorityPair as Key; use codec::Decode; pub mod common; use self::common::*; -type SubmitTransaction = TransactionSubmitterOf; - #[test] fn should_submit_unsigned_transaction() { let mut t = new_test_ext(COMPACT_CODE, false); @@ -49,8 +54,7 @@ fn should_submit_unsigned_transaction() { }; let call = pallet_im_online::Call::heartbeat(heartbeat_data, signature); - > - ::submit_unsigned(call) + SubmitTransaction::>::submit_unsigned_transaction(call.into()) .unwrap(); assert_eq!(state.read().transactions.len(), 1) @@ -66,23 +70,16 @@ fn should_submit_signed_transaction() { t.register_extension(TransactionPoolExt::new(pool)); let keystore = KeyStore::new(); - keystore.write().sr25519_generate_new(Key::ID, Some(&format!("{}/hunter1", PHRASE))).unwrap(); - keystore.write().sr25519_generate_new(Key::ID, Some(&format!("{}/hunter2", PHRASE))).unwrap(); - keystore.write().sr25519_generate_new(Key::ID, Some(&format!("{}/hunter3", PHRASE))).unwrap(); + keystore.write().sr25519_generate_new(sr25519::AuthorityId::ID, Some(&format!("{}/hunter1", PHRASE))).unwrap(); + keystore.write().sr25519_generate_new(sr25519::AuthorityId::ID, Some(&format!("{}/hunter2", PHRASE))).unwrap(); + keystore.write().sr25519_generate_new(sr25519::AuthorityId::ID, Some(&format!("{}/hunter3", PHRASE))).unwrap(); t.register_extension(KeystoreExt(keystore)); t.execute_with(|| { - let keys = > - ::find_all_local_keys(); - assert_eq!(keys.len(), 3, "Missing keys: {:?}", keys); - - let can_sign = > - ::can_sign(); - assert!(can_sign, "Since there are keys, `can_sign` should return true"); - - let call = pallet_balances::Call::transfer(Default::default(), Default::default()); - let results = - >::submit_signed(call); + let results = Signer::::all_accounts() + .send_signed_transaction(|_| { + pallet_balances::Call::transfer(Default::default(), Default::default()) + }); let len = results.len(); assert_eq!(len, 3); @@ -98,27 +95,26 @@ fn should_submit_signed_twice_from_the_same_account() { t.register_extension(TransactionPoolExt::new(pool)); let keystore = KeyStore::new(); - keystore.write().sr25519_generate_new(Key::ID, Some(&format!("{}/hunter1", PHRASE))).unwrap(); + keystore.write().sr25519_generate_new(sr25519::AuthorityId::ID, Some(&format!("{}/hunter1", PHRASE))).unwrap(); + keystore.write().sr25519_generate_new(sr25519::AuthorityId::ID, Some(&format!("{}/hunter2", PHRASE))).unwrap(); t.register_extension(KeystoreExt(keystore)); t.execute_with(|| { - let call = pallet_balances::Call::transfer(Default::default(), Default::default()); - let results = - >::submit_signed(call); + let result = Signer::::any_account() + .send_signed_transaction(|_| { + pallet_balances::Call::transfer(Default::default(), Default::default()) + }); - let len = results.len(); - assert_eq!(len, 1); - assert_eq!(results.into_iter().filter_map(|x| x.1.ok()).count(), len); + assert!(result.is_some()); assert_eq!(state.read().transactions.len(), 1); // submit another one from the same account. The nonce should be incremented. - let call = pallet_balances::Call::transfer(Default::default(), Default::default()); - let results = - >::submit_signed(call); + let result = Signer::::any_account() + .send_signed_transaction(|_| { + pallet_balances::Call::transfer(Default::default(), Default::default()) + }); - let len = results.len(); - assert_eq!(len, 1); - assert_eq!(results.into_iter().filter_map(|x| x.1.ok()).count(), len); + assert!(result.is_some()); assert_eq!(state.read().transactions.len(), 2); // now check that the transaction nonces are not equal @@ -136,6 +132,60 @@ fn should_submit_signed_twice_from_the_same_account() { }); } +#[test] +fn should_submit_signed_twice_from_all_accounts() { + let mut t = new_test_ext(COMPACT_CODE, false); + let (pool, state) = TestTransactionPoolExt::new(); + t.register_extension(TransactionPoolExt::new(pool)); + + let keystore = KeyStore::new(); + keystore.write().sr25519_generate_new(sr25519::AuthorityId::ID, Some(&format!("{}/hunter1", PHRASE))).unwrap(); + keystore.write().sr25519_generate_new(sr25519::AuthorityId::ID, Some(&format!("{}/hunter2", PHRASE))).unwrap(); + t.register_extension(KeystoreExt(keystore)); + + t.execute_with(|| { + let results = Signer::::all_accounts() + .send_signed_transaction(|_| { + pallet_balances::Call::transfer(Default::default(), Default::default()) + }); + + let len = results.len(); + assert_eq!(len, 2); + assert_eq!(results.into_iter().filter_map(|x| x.1.ok()).count(), len); + assert_eq!(state.read().transactions.len(), 2); + + // submit another one from the same account. The nonce should be incremented. + let results = Signer::::all_accounts() + .send_signed_transaction(|_| { + pallet_balances::Call::transfer(Default::default(), Default::default()) + }); + + let len = results.len(); + assert_eq!(len, 2); + assert_eq!(results.into_iter().filter_map(|x| x.1.ok()).count(), len); + assert_eq!(state.read().transactions.len(), 4); + + // now check that the transaction nonces are not equal + let s = state.read(); + fn nonce(tx: UncheckedExtrinsic) -> frame_system::CheckNonce { + let extra = tx.signature.unwrap().2; + extra.3 + } + let nonce1 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[0]).unwrap()); + let nonce2 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[1]).unwrap()); + let nonce3 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[2]).unwrap()); + let nonce4 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[3]).unwrap()); + assert!( + nonce1 != nonce3, + "Transactions should have different nonces. Got: 1st tx nonce: {:?}, 2nd nonce: {:?}", nonce1, nonce3 + ); + assert!( + nonce2 != nonce4, + "Transactions should have different nonces. Got: 1st tx nonce: {:?}, 2nd tx nonce: {:?}", nonce2, nonce4 + ); + }); +} + #[test] fn submitted_transaction_should_be_valid() { use codec::Encode; @@ -148,13 +198,14 @@ fn submitted_transaction_should_be_valid() { t.register_extension(TransactionPoolExt::new(pool)); let keystore = KeyStore::new(); - keystore.write().sr25519_generate_new(Key::ID, Some(&format!("{}/hunter1", PHRASE))).unwrap(); + keystore.write().sr25519_generate_new(sr25519::AuthorityId::ID, Some(&format!("{}/hunter1", PHRASE))).unwrap(); t.register_extension(KeystoreExt(keystore)); t.execute_with(|| { - let call = pallet_balances::Call::transfer(Default::default(), Default::default()); - let results = - >::submit_signed(call); + let results = Signer::::all_accounts() + .send_signed_transaction(|_| { + pallet_balances::Call::transfer(Default::default(), Default::default()) + }); let len = results.len(); assert_eq!(len, 1); assert_eq!(results.into_iter().filter_map(|x| x.1.ok()).count(), len); diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 337242f884..b1797fffb3 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -46,11 +46,10 @@ use sp_version::NativeVersion; use sp_core::OpaqueMetadata; use pallet_grandpa::AuthorityList as GrandpaAuthorityList; use pallet_grandpa::fg_primitives; -use pallet_im_online::sr25519::{AuthorityId as ImOnlineId}; +use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; use pallet_contracts_rpc_runtime_api::ContractExecResult; -use frame_system::offchain::TransactionSubmitter; use sp_inherents::{InherentData, CheckInherentsResult}; #[cfg(any(feature = "std", test))] @@ -60,6 +59,7 @@ pub use pallet_balances::Call as BalancesCall; pub use pallet_contracts::Gas; pub use frame_support::StorageValue; pub use pallet_staking::StakerStatus; +use codec::Encode; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; @@ -73,50 +73,6 @@ use constants::{time::*, currency::*}; #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -/// A transaction submitter with the given key type. -pub type TransactionSubmitterOf = TransactionSubmitter; - -/// Submits transaction with the node's public and signature type. Adheres to the signed extension -/// format of the chain. -impl frame_system::offchain::CreateTransaction for Runtime { - type Public = ::Signer; - type Signature = Signature; - - fn create_transaction>( - call: Call, - public: Self::Public, - account: AccountId, - index: Index, - ) -> Option<(Call, ::SignaturePayload)> { - // take the biggest period possible. - let period = BlockHashCount::get() - .checked_next_power_of_two() - .map(|c| c / 2) - .unwrap_or(2) as u64; - let current_block = System::block_number() - .saturated_into::() - // The `System::block_number` is initialized with `n+1`, - // so the actual block number is `n`. - .saturating_sub(1); - let tip = 0; - let extra: SignedExtra = ( - frame_system::CheckVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(generic::Era::mortal(period, current_block)), - frame_system::CheckNonce::::from(index), - frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - Default::default(), - ); - let raw_payload = SignedPayload::new(call, extra).map_err(|e| { - debug::warn!("Unable to create signed payload: {:?}", e); - }).ok()?; - let signature = TSigner::sign(public, &raw_payload)?; - let address = Indices::unlookup(account); - let (call, extra, _) = raw_payload.deconstruct(); - Some((call, (address, signature, extra))) - } -} /// Runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { @@ -127,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 243, + spec_version: 244, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -362,7 +318,6 @@ impl pallet_staking::Trait for Runtime { type NextNewSession = Session; type ElectionLookahead = ElectionLookahead; type Call = Call; - type SubmitTransaction = TransactionSubmitterOf<()>; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type UnsignedPriority = StakingUnsignedPriority; } @@ -549,11 +504,63 @@ parameter_types! { pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2; } + +impl frame_system::offchain::CreateSignedTransaction for Runtime where + Call: From, +{ + fn create_transaction>( + call: Call, + public: ::Signer, + account: AccountId, + nonce: Index, + ) -> Option<(Call, ::SignaturePayload)> { + // take the biggest period possible. + let period = BlockHashCount::get() + .checked_next_power_of_two() + .map(|c| c / 2) + .unwrap_or(2) as u64; + let current_block = System::block_number() + .saturated_into::() + // The `System::block_number` is initialized with `n+1`, + // so the actual block number is `n`. + .saturating_sub(1); + let tip = 0; + let extra: SignedExtra = ( + frame_system::CheckVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(generic::Era::mortal(period, current_block)), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + Default::default(), + ); + let raw_payload = SignedPayload::new(call, extra).map_err(|e| { + debug::warn!("Unable to create signed payload: {:?}", e); + }).ok()?; + let signature = raw_payload.using_encoded(|payload| { + C::sign(payload, public) + })?; + let address = Indices::unlookup(account); + let (call, extra, _) = raw_payload.deconstruct(); + Some((call, (address, signature.into(), extra))) + } +} + +impl frame_system::offchain::SigningTypes for Runtime { + type Public = ::Signer; + type Signature = Signature; +} + +impl frame_system::offchain::SendTransactionTypes for Runtime where + Call: From, +{ + type OverarchingCall = Call; + type Extrinsic = UncheckedExtrinsic; +} + impl pallet_im_online::Trait for Runtime { type AuthorityId = ImOnlineId; type Event = Event; - type Call = Call; - type SubmitTransaction = TransactionSubmitterOf; type SessionDuration = SessionDuration; type ReportUnresponsiveness = Offences; type UnsignedPriority = ImOnlineUnsignedPriority; @@ -924,28 +931,14 @@ impl_runtime_apis! { #[cfg(test)] mod tests { use super::*; - use frame_system::offchain::{SignAndSubmitTransaction, SubmitSignedTransaction}; + use frame_system::offchain::CreateSignedTransaction; #[test] fn validate_transaction_submitter_bounds() { fn is_submit_signed_transaction() where - T: SubmitSignedTransaction< - Runtime, - Call, - >, - {} - - fn is_sign_and_submit_transaction() where - T: SignAndSubmitTransaction< - Runtime, - Call, - Extrinsic=UncheckedExtrinsic, - CreateTransaction=Runtime, - Signer=ImOnlineId, - >, + T: CreateSignedTransaction, {} - is_submit_signed_transaction::>(); - is_sign_and_submit_transaction::>(); + is_submit_signed_transaction::(); } } diff --git a/frame/example-offchain-worker/src/lib.rs b/frame/example-offchain-worker/src/lib.rs index 29a4859c78..d2ebd1159e 100644 --- a/frame/example-offchain-worker/src/lib.rs +++ b/frame/example-offchain-worker/src/lib.rs @@ -22,12 +22,12 @@ //! Run `cargo doc --package pallet-example-offchain-worker --open` to view this module's //! documentation. //! -//! - \[`pallet_example_offchain_worker::Trait`](./trait.Trait.html) -//! - \[`Call`](./enum.Call.html) -//! - \[`Module`](./struct.Module.html) +//! - [`pallet_example_offchain_worker::Trait`](./trait.Trait.html) +//! - [`Call`](./enum.Call.html) +//! - [`Module`](./struct.Module.html) //! //! -//! \## Overview +//! ## Overview //! //! In this example we are going to build a very simplistic, naive and definitely NOT //! production-ready oracle for BTC/USD price. @@ -40,15 +40,24 @@ //! one unsigned transaction floating in the network. #![cfg_attr(not(feature = "std"), no_std)] +use frame_system::{ + self as system, + ensure_signed, + ensure_none, + offchain::{ + AppCrypto, CreateSignedTransaction, SendUnsignedTransaction, + SignedPayload, SigningTypes, Signer, SubmitTransaction, + } +}; use frame_support::{ debug, dispatch::DispatchResult, decl_module, decl_storage, decl_event, traits::Get, weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, }; -use frame_system::{self as system, ensure_signed, ensure_none, offchain}; use sp_core::crypto::KeyTypeId; use sp_runtime::{ + RuntimeDebug, offchain::{http, Duration, storage::StorageValueRef}, traits::Zero, transaction_validity::{ @@ -56,6 +65,7 @@ use sp_runtime::{ TransactionPriority, }, }; +use codec::{Encode, Decode}; use sp_std::vec::Vec; use lite_json::json::JsonValue; @@ -76,18 +86,25 @@ pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"btc!"); /// the types with this pallet-specific identifier. pub mod crypto { use super::KEY_TYPE; - use sp_runtime::app_crypto::{app_crypto, sr25519}; + use sp_runtime::{ + app_crypto::{app_crypto, sr25519}, + traits::Verify, + }; + use sp_core::sr25519::Signature as Sr25519Signature; app_crypto!(sr25519, KEY_TYPE); + + pub struct TestAuthId; + impl frame_system::offchain::AppCrypto<::Signer, Sr25519Signature> for TestAuthId { + type RuntimeAppPublic = Public; + type GenericSignature = sp_core::sr25519::Signature; + type GenericPublic = sp_core::sr25519::Public; + } } /// This pallet's configuration trait -pub trait Trait: frame_system::Trait { - /// The type to sign and submit transactions. - type SubmitSignedTransaction: - offchain::SubmitSignedTransaction::Call>; - /// The type to submit unsigned transactions. - type SubmitUnsignedTransaction: - offchain::SubmitUnsignedTransaction::Call>; +pub trait Trait: CreateSignedTransaction> { + /// The identifier type for an offchain worker. + type AuthorityId: AppCrypto; /// The overarching event type. type Event: From> + Into<::Event>; @@ -115,6 +132,21 @@ pub trait Trait: frame_system::Trait { type UnsignedPriority: Get; } +/// Payload used by this example crate to hold price +/// data required to submit a transaction. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] +pub struct PricePayload { + block_number: BlockNumber, + price: u32, + public: Public, +} + +impl SignedPayload for PricePayload { + fn public(&self) -> T::Public { + self.public.clone() + } +} + decl_storage! { trait Store for Module as ExampleOffchainWorker { /// A vector of recently submitted prices. @@ -196,6 +228,22 @@ decl_module! { Ok(()) } + #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + pub fn submit_price_unsigned_with_signed_payload( + origin, + price_payload: PricePayload, + _signature: T::Signature, + ) -> DispatchResult { + // This ensures that the function can only be called via unsigned transaction. + ensure_none(origin)?; + // Add the price to the on-chain list, but mark it as coming from an empty address. + Self::add_price(Default::default(), price_payload.price); + // now increment the block number at which we expect next unsigned transaction. + let current_block = >::block_number(); + >::put(current_block + T::UnsignedInterval::get()); + Ok(()) + } + /// Offchain Worker entry point. /// /// By implementing `fn offchain_worker` within `decl_module!` you declare a new offchain @@ -236,7 +284,9 @@ decl_module! { let should_send = Self::choose_transaction_type(block_number); let res = match should_send { TransactionType::Signed => Self::fetch_price_and_send_signed(), - TransactionType::Unsigned => Self::fetch_price_and_send_unsigned(block_number), + TransactionType::UnsignedForAny => Self::fetch_price_and_send_unsigned_for_any_account(block_number), + TransactionType::UnsignedForAll => Self::fetch_price_and_send_unsigned_for_all_accounts(block_number), + TransactionType::Raw => Self::fetch_price_and_send_raw_unsigned(block_number), TransactionType::None => Ok(()), }; if let Err(e) = res { @@ -248,7 +298,9 @@ decl_module! { enum TransactionType { Signed, - Unsigned, + UnsignedForAny, + UnsignedForAll, + Raw, None, } @@ -311,12 +363,11 @@ impl Module { // transactions in a row. If a strict order is desired, it's better to use // the storage entry for that. (for instance store both block number and a flag // indicating the type of next transaction to send). - let send_signed = block_number % 2.into() == Zero::zero(); - if send_signed { - TransactionType::Signed - } else { - TransactionType::Unsigned - } + let transaction_type = block_number % 3.into(); + if transaction_type == Zero::zero() { TransactionType::Signed } + else if transaction_type == T::BlockNumber::from(1) { TransactionType::UnsignedForAny } + else if transaction_type == T::BlockNumber::from(2) { TransactionType::UnsignedForAll } + else { TransactionType::Raw } }, // We are in the grace period, we should not send a transaction this time. Err(RECENTLY_SENT) => TransactionType::None, @@ -331,44 +382,43 @@ impl Module { /// A helper function to fetch the price and send signed transaction. fn fetch_price_and_send_signed() -> Result<(), &'static str> { - use system::offchain::SubmitSignedTransaction; - // Firstly we check if there are any accounts in the local keystore that are capable of - // signing the transaction. - // If not it doesn't even make sense to make external HTTP requests, since we won't be able - // to put the results back on-chain. - if !T::SubmitSignedTransaction::can_sign() { + use frame_system::offchain::SendSignedTransaction; + + let signer = Signer::::all_accounts(); + if !signer.can_sign() { return Err( "No local accounts available. Consider adding one via `author_insertKey` RPC." )? } - // Make an external HTTP request to fetch the current price. // Note this call will block until response is received. let price = Self::fetch_price().map_err(|_| "Failed to fetch price")?; - // Received price is wrapped into a call to `submit_price` public function of this pallet. - // This means that the transaction, when executed, will simply call that function passing - // `price` as an argument. - let call = Call::submit_price(price); - - // Using `SubmitSignedTransaction` associated type we create and submit a transaction + // Using `send_signed_transaction` associated type we create and submit a transaction // representing the call, we've just created. // Submit signed will return a vector of results for all accounts that were found in the // local keystore with expected `KEY_TYPE`. - let results = T::SubmitSignedTransaction::submit_signed(call); + let results = signer.send_signed_transaction( + |_account| { + // Received price is wrapped into a call to `submit_price` public function of this pallet. + // This means that the transaction, when executed, will simply call that function passing + // `price` as an argument. + Call::submit_price(price) + } + ); + for (acc, res) in &results { match res { - Ok(()) => debug::info!("[{:?}] Submitted price of {} cents", acc, price), - Err(e) => debug::error!("[{:?}] Failed to submit transaction: {:?}", acc, e), + Ok(()) => debug::info!("[{:?}] Submitted price of {} cents", acc.id, price), + Err(e) => debug::error!("[{:?}] Failed to submit transaction: {:?}", acc.id, e), } } Ok(()) } - /// A helper function to fetch the price and send unsigned transaction. - fn fetch_price_and_send_unsigned(block_number: T::BlockNumber) -> Result<(), &'static str> { - use system::offchain::SubmitUnsignedTransaction; + /// A helper function to fetch the price and send a raw unsigned transaction. + fn fetch_price_and_send_raw_unsigned(block_number: T::BlockNumber) -> Result<(), &'static str> { // Make sure we don't fetch the price if unsigned transaction is going to be rejected // anyway. let next_unsigned_at = >::get(); @@ -385,14 +435,101 @@ impl Module { // passing `price` as an argument. let call = Call::submit_price_unsigned(block_number, price); - // Now let's create an unsigned transaction out of this call and submit it to the pool. + // Now let's create a transaction out of this call and submit it to the pool. + // Here we showcase two ways to send an unsigned transaction / unsigned payload (raw) + // // By default unsigned transactions are disallowed, so we need to whitelist this case // by writing `UnsignedValidator`. Note that it's EXTREMELY important to carefuly // implement unsigned validation logic, as any mistakes can lead to opening DoS or spam // attack vectors. See validation logic docs for more details. - T::SubmitUnsignedTransaction::submit_unsigned(call) - .map_err(|()| "Unable to submit unsigned transaction.".into()) + // + SubmitTransaction::>::submit_unsigned_transaction(call.into()) + .map_err(|()| "Unable to submit unsigned transaction.")?; + Ok(()) + } + + /// A helper function to fetch the price, sign payload and send an unsigned transaction + fn fetch_price_and_send_unsigned_for_any_account(block_number: T::BlockNumber) -> Result<(), &'static str> { + // Make sure we don't fetch the price if unsigned transaction is going to be rejected + // anyway. + let next_unsigned_at = >::get(); + if next_unsigned_at > block_number { + return Err("Too early to send unsigned transaction") + } + + // Make an external HTTP request to fetch the current price. + // Note this call will block until response is received. + let price = Self::fetch_price().map_err(|_| "Failed to fetch price")?; + + // Received price is wrapped into a call to `submit_price_unsigned` public function of this + // pallet. This means that the transaction, when executed, will simply call that function + // passing `price` as an argument. + let call = Call::submit_price_unsigned(block_number, price); + + // Now let's create a transaction out of this call and submit it to the pool. + // Here we showcase two ways to send an unsigned transaction with a signed payload + SubmitTransaction::>::submit_unsigned_transaction(call.into()) + .map_err(|()| "Unable to submit unsigned transaction.")?; + + // -- Sign using any account + let (_, result) = Signer::::any_account().send_unsigned_transaction( + |account| PricePayload { + price, + block_number, + public: account.public.clone() + }, + |payload, signature| { + Call::submit_price_unsigned_with_signed_payload(payload, signature) + } + ).ok_or("No local accounts accounts available.")?; + result.map_err(|()| "Unable to submit transaction")?; + + Ok(()) + } + + /// A helper function to fetch the price, sign payload and send an unsigned transaction + fn fetch_price_and_send_unsigned_for_all_accounts(block_number: T::BlockNumber) -> Result<(), &'static str> { + // Make sure we don't fetch the price if unsigned transaction is going to be rejected + // anyway. + let next_unsigned_at = >::get(); + if next_unsigned_at > block_number { + return Err("Too early to send unsigned transaction") + } + + // Make an external HTTP request to fetch the current price. + // Note this call will block until response is received. + let price = Self::fetch_price().map_err(|_| "Failed to fetch price")?; + + // Received price is wrapped into a call to `submit_price_unsigned` public function of this + // pallet. This means that the transaction, when executed, will simply call that function + // passing `price` as an argument. + let call = Call::submit_price_unsigned(block_number, price); + + // Now let's create a transaction out of this call and submit it to the pool. + // Here we showcase two ways to send an unsigned transaction with a signed payload + SubmitTransaction::>::submit_unsigned_transaction(call.into()) + .map_err(|()| "Unable to submit unsigned transaction.")?; + + // -- Sign using all accounts + let transaction_results = Signer::::all_accounts() + .send_unsigned_transaction( + |account| PricePayload { + price, + block_number, + public: account.public.clone() + }, + |payload, signature| { + Call::submit_price_unsigned_with_signed_payload(payload, signature) + } + ); + for (_account_id, result) in transaction_results.into_iter() { + if result.is_err() { + return Err("Unable to submit transaction"); + } + } + + Ok(()) } /// Fetch current price and return the result in cents. @@ -507,6 +644,58 @@ impl Module { Some(prices.iter().fold(0_u32, |a, b| a.saturating_add(*b)) / prices.len() as u32) } } + + fn validate_transaction_parameters( + block_number: &T::BlockNumber, + new_price: &u32, + ) -> TransactionValidity { + // Now let's check if the transaction has any chance to succeed. + let next_unsigned_at = >::get(); + if &next_unsigned_at > block_number { + return InvalidTransaction::Stale.into(); + } + // Let's make sure to reject transactions from the future. + let current_block = >::block_number(); + if ¤t_block < block_number { + return InvalidTransaction::Future.into(); + } + + // We prioritize transactions that are more far away from current average. + // + // Note this doesn't make much sense when building an actual oracle, but this example + // is here mostly to show off offchain workers capabilities, not about building an + // oracle. + let avg_price = Self::average_price() + .map(|price| if &price > new_price { price - new_price } else { new_price - price }) + .unwrap_or(0); + + ValidTransaction::with_tag_prefix("ExampleOffchainWorker") + // We set base priority to 2**20 and hope it's included before any other + // transactions in the pool. Next we tweak the priority depending on how much + // it differs from the current average. (the more it differs the more priority it + // has). + .priority(T::UnsignedPriority::get().saturating_add(avg_price as _)) + // This transaction does not require anything else to go before into the pool. + // In theory we could require `previous_unsigned_at` transaction to go first, + // but it's not necessary in our case. + //.and_requires() + // We set the `provides` tag to be the same as `next_unsigned_at`. This makes + // sure only one transaction produced after `next_unsigned_at` will ever + // get to the transaction pool and will end up in the block. + // We can still have multiple transactions compete for the same "spot", + // and the one with higher priority will replace other one in the pool. + .and_provides(next_unsigned_at) + // The transaction is only valid for next 5 blocks. After that it's + // going to be revalidated by the pool. + .longevity(5) + // It's fine to propagate that transaction to other peers, which means it can be + // created even by nodes that don't produce blocks. + // Note that sometimes it's better to keep it for yourself (if you are the block + // producer), since for instance in some schemes others may copy your solution and + // claim a reward. + .propagate(true) + .build() + } } #[allow(deprecated)] // ValidateUnsigned @@ -523,54 +712,16 @@ impl frame_support::unsigned::ValidateUnsigned for Module { call: &Self::Call, ) -> TransactionValidity { // Firstly let's check that we call the right function. - if let Call::submit_price_unsigned(block_number, new_price) = call { - // Now let's check if the transaction has any chance to succeed. - let next_unsigned_at = >::get(); - if &next_unsigned_at > block_number { - return InvalidTransaction::Stale.into(); - } - // Let's make sure to reject transactions from the future. - let current_block = >::block_number(); - if ¤t_block < block_number { - return InvalidTransaction::Future.into(); + if let Call::submit_price_unsigned_with_signed_payload( + ref payload, ref signature + ) = call { + let signature_valid = SignedPayload::::verify::(payload, signature.clone()); + if !signature_valid { + return InvalidTransaction::BadProof.into(); } - - // We prioritize transactions that are more far away from current average. - // - // Note this doesn't make much sense when building an actual oracle, but this example - // is here mostly to show off offchain workers capabilities, not about building an - // oracle. - let avg_price = Self::average_price() - .map(|price| if &price > new_price { price - new_price } else { new_price - price }) - .unwrap_or(0); - - ValidTransaction::with_tag_prefix("ExampleOffchainWorker") - // We set base priority to 2**20 to make sure it's included before any other - // transactions in the pool. Next we tweak the priority depending on how much - // it differs from the current average. (the more it differs the more priority it - // has). - .priority(T::UnsignedPriority::get().saturating_add(avg_price as _)) - // This transaction does not require anything else to go before into the pool. - // In theory we could require `previous_unsigned_at` transaction to go first, - // but it's not necessary in our case. - //.and_requires() - - // We set the `provides` tag to be the same as `next_unsigned_at`. This makes - // sure only one transaction produced after `next_unsigned_at` will ever - // get to the transaction pool and will end up in the block. - // We can still have multiple transactions compete for the same "spot", - // and the one with higher priority will replace other one in the pool. - .and_provides(next_unsigned_at) - // The transaction is only valid for next 5 blocks. After that it's - // going to be revalidated by the pool. - .longevity(5) - // It's fine to propagate that transaction to other peers, which means it can be - // created even by nodes that don't produce blocks. - // Note that sometimes it's better to keep it for yourself (if you are the block - // producer), since for instance in some schemes others may copy your solution and - // claim a reward. - .propagate(true) - .build() + Self::validate_transaction_parameters(&payload.block_number, &payload.price) + } else if let Call::submit_price_unsigned(block_number, new_price) = call { + Self::validate_transaction_parameters(block_number, new_price) } else { InvalidTransaction::Call.into() } diff --git a/frame/example-offchain-worker/src/tests.rs b/frame/example-offchain-worker/src/tests.rs index 279de7ef4a..aebcbde451 100644 --- a/frame/example-offchain-worker/src/tests.rs +++ b/frame/example-offchain-worker/src/tests.rs @@ -16,7 +16,7 @@ use crate::*; -use codec::Decode; +use codec::{Encode, Decode}; use frame_support::{ assert_ok, impl_outer_origin, parameter_types, weights::Weight, @@ -24,13 +24,17 @@ use frame_support::{ use sp_core::{ H256, offchain::{OffchainExt, TransactionPoolExt, testing}, + sr25519::Signature, testing::KeyStore, traits::KeystoreExt, }; use sp_runtime::{ Perbill, RuntimeAppPublic, testing::{Header, TestXt}, - traits::{BlakeTwo256, IdentityLookup, Extrinsic as ExtrinsicsT}, + traits::{ + BlakeTwo256, IdentityLookup, Extrinsic as ExtrinsicT, + IdentifyAccount, Verify, + }, }; impl_outer_origin! { @@ -40,7 +44,7 @@ impl_outer_origin! { // For testing the module, we construct most of a mock runtime. This means // first constructing a configuration type (`Test`) which `impl`s each of the // configuration traits of modules we want to use. -#[derive(Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq, Encode, Decode)] pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; @@ -72,22 +76,29 @@ impl frame_system::Trait for Test { } type Extrinsic = TestXt, ()>; -type SubmitTransaction = frame_system::offchain::TransactionSubmitter< - crypto::Public, - Test, - Extrinsic ->; - -impl frame_system::offchain::CreateTransaction for Test { - type Public = sp_core::sr25519::Public; - type Signature = sp_core::sr25519::Signature; - - fn create_transaction>( - call: ::Call, - _public: Self::Public, - _account: ::AccountId, - nonce: ::Index, - ) -> Option<(::Call, ::SignaturePayload)> { +type AccountId = <::Signer as IdentifyAccount>::AccountId; + +impl frame_system::offchain::SigningTypes for Test { + type Public = ::Signer; + type Signature = Signature; +} + +impl frame_system::offchain::SendTransactionTypes for Test where + Call: From, +{ + type OverarchingCall = Call; + type Extrinsic = Extrinsic; +} + +impl frame_system::offchain::CreateSignedTransaction for Test where + Call: From, +{ + fn create_transaction>( + call: Call, + _public: ::Signer, + _account: AccountId, + nonce: u64, + ) -> Option<(Call, ::SignaturePayload)> { Some((call, (nonce, ()))) } } @@ -100,9 +111,8 @@ parameter_types! { impl Trait for Test { type Event = (); + type AuthorityId = crypto::TestAuthId; type Call = Call; - type SubmitSignedTransaction = SubmitTransaction; - type SubmitUnsignedTransaction = SubmitTransaction; type GracePeriod = GracePeriod; type UnsignedInterval = UnsignedInterval; type UnsignedPriority = UnsignedPriority; @@ -172,18 +182,128 @@ fn should_submit_signed_transaction_on_chain() { } #[test] -fn should_submit_unsigned_transaction_on_chain() { +fn should_submit_unsigned_transaction_on_chain_for_any_account() { + const PHRASE: &str = "news slush supreme milk chapter athlete soap sausage put clutch what kitten"; let (offchain, offchain_state) = testing::TestOffchainExt::new(); let (pool, pool_state) = testing::TestTransactionPoolExt::new(); + + let keystore = KeyStore::new(); + + keystore.write().sr25519_generate_new( + crate::crypto::Public::ID, + Some(&format!("{}/hunter1", PHRASE)) + ).unwrap(); + let mut t = sp_io::TestExternalities::default(); t.register_extension(OffchainExt::new(offchain)); t.register_extension(TransactionPoolExt::new(pool)); + t.register_extension(KeystoreExt(keystore.clone())); + + price_oracle_response(&mut offchain_state.write()); + + let public_key = keystore.read() + .sr25519_public_keys(crate::crypto::Public::ID) + .get(0) + .unwrap() + .clone(); + + let price_payload = PricePayload { + block_number: 1, + price: 15523, + public: ::Public::from(public_key), + }; + + // let signature = price_payload.sign::().unwrap(); + t.execute_with(|| { + // when + Example::fetch_price_and_send_unsigned_for_any_account(1).unwrap(); + // then + let tx = pool_state.write().transactions.pop().unwrap(); + let tx = Extrinsic::decode(&mut &*tx).unwrap(); + assert_eq!(tx.signature, None); + if let Call::submit_price_unsigned_with_signed_payload(body, signature) = tx.call { + assert_eq!(body, price_payload); + + let signature_valid = ::Public, + ::BlockNumber + > as SignedPayload>::verify::(&price_payload, signature); + + assert!(signature_valid); + } + }); +} + +#[test] +fn should_submit_unsigned_transaction_on_chain_for_all_accounts() { + const PHRASE: &str = "news slush supreme milk chapter athlete soap sausage put clutch what kitten"; + let (offchain, offchain_state) = testing::TestOffchainExt::new(); + let (pool, pool_state) = testing::TestTransactionPoolExt::new(); + + let keystore = KeyStore::new(); + + keystore.write().sr25519_generate_new( + crate::crypto::Public::ID, + Some(&format!("{}/hunter1", PHRASE)) + ).unwrap(); + + let mut t = sp_io::TestExternalities::default(); + t.register_extension(OffchainExt::new(offchain)); + t.register_extension(TransactionPoolExt::new(pool)); + t.register_extension(KeystoreExt(keystore.clone())); + + price_oracle_response(&mut offchain_state.write()); + + let public_key = keystore.read() + .sr25519_public_keys(crate::crypto::Public::ID) + .get(0) + .unwrap() + .clone(); + + let price_payload = PricePayload { + block_number: 1, + price: 15523, + public: ::Public::from(public_key), + }; + + // let signature = price_payload.sign::().unwrap(); + t.execute_with(|| { + // when + Example::fetch_price_and_send_unsigned_for_all_accounts(1).unwrap(); + // then + let tx = pool_state.write().transactions.pop().unwrap(); + let tx = Extrinsic::decode(&mut &*tx).unwrap(); + assert_eq!(tx.signature, None); + if let Call::submit_price_unsigned_with_signed_payload(body, signature) = tx.call { + assert_eq!(body, price_payload); + + let signature_valid = ::Public, + ::BlockNumber + > as SignedPayload>::verify::(&price_payload, signature); + + assert!(signature_valid); + } + }); +} + +#[test] +fn should_submit_raw_unsigned_transaction_on_chain() { + let (offchain, offchain_state) = testing::TestOffchainExt::new(); + let (pool, pool_state) = testing::TestTransactionPoolExt::new(); + + let keystore = KeyStore::new(); + + let mut t = sp_io::TestExternalities::default(); + t.register_extension(OffchainExt::new(offchain)); + t.register_extension(TransactionPoolExt::new(pool)); + t.register_extension(KeystoreExt(keystore)); price_oracle_response(&mut offchain_state.write()); t.execute_with(|| { // when - Example::fetch_price_and_send_unsigned(1).unwrap(); + Example::fetch_price_and_send_raw_unsigned(1).unwrap(); // then let tx = pool_state.write().transactions.pop().unwrap(); assert!(pool_state.read().transactions.is_empty()); diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 1137fc2699..813b11bbc9 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -98,7 +98,10 @@ use frame_support::{ weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, }; use frame_system::{self as system, ensure_none}; -use frame_system::offchain::SubmitUnsignedTransaction; +use frame_system::offchain::{ + SendTransactionTypes, + SubmitTransaction, +}; pub mod sr25519 { mod app_sr25519 { @@ -221,19 +224,13 @@ pub struct Heartbeat pub authority_index: AuthIndex, } -pub trait Trait: frame_system::Trait + pallet_session::historical::Trait { +pub trait Trait: SendTransactionTypes> + pallet_session::historical::Trait { /// The identifier type for an authority. type AuthorityId: Member + Parameter + RuntimeAppPublic + Default + Ord; /// The overarching event type. type Event: From> + Into<::Event>; - /// A dispatchable call type. - type Call: From>; - - /// A transaction submitter. - type SubmitTransaction: SubmitUnsignedTransaction::Call>; - /// An expected duration of the session. /// /// This parameter is used to determine the longevity of `heartbeat` transaction @@ -444,6 +441,7 @@ impl Module { } let session_index = >::current_index(); + Ok(Self::local_authority_keys() .map(move |(authority_index, key)| Self::send_single_heartbeat(authority_index, key, session_index, block_number) @@ -467,7 +465,9 @@ impl Module { session_index, authority_index, }; + let signature = key.sign(&heartbeat_data.encode()).ok_or(OffchainErr::FailedSigning)?; + Ok(Call::heartbeat(heartbeat_data, signature)) }; @@ -492,7 +492,7 @@ impl Module { call, ); - T::SubmitTransaction::submit_unsigned(call) + SubmitTransaction::>::submit_unsigned_transaction(call.into()) .map_err(|_| OffchainErr::SubmitTransaction)?; Ok(()) @@ -501,9 +501,18 @@ impl Module { } fn local_authority_keys() -> impl Iterator { - // we run only when a local authority key is configured + // on-chain storage + // + // At index `idx`: + // 1. A (ImOnline) public key to be used by a validator at index `idx` to send im-online + // heartbeats. let authorities = Keys::::get(); + + // local keystore + // + // All `ImOnline` public (+private) keys currently in the local keystore. let mut local_keys = T::AuthorityId::all(); + local_keys.sort(); authorities.into_iter() @@ -565,6 +574,11 @@ impl Module { Keys::::put(keys); } } + + #[cfg(test)] + fn set_keys(keys: Vec) { + Keys::::put(&keys) + } } impl sp_runtime::BoundToRuntimeAppPublic for Module { diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index d620bb51b7..e9b5ef95ef 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -27,7 +27,6 @@ use sp_runtime::testing::{Header, UintAuthorityId, TestXt}; use sp_runtime::traits::{IdentityLookup, BlakeTwo256, ConvertInto}; use sp_core::H256; use frame_support::{impl_outer_origin, impl_outer_dispatch, parameter_types, weights::Weight}; - use frame_system as system; impl_outer_origin!{ pub enum Origin for Runtime {} @@ -40,7 +39,11 @@ impl_outer_dispatch! { } thread_local! { - pub static VALIDATORS: RefCell>> = RefCell::new(Some(vec![1, 2, 3])); + pub static VALIDATORS: RefCell>> = RefCell::new(Some(vec![ + 1, + 2, + 3, + ])); } pub struct TestSessionManager; @@ -68,7 +71,6 @@ impl pallet_session::historical::SessionManager for TestSessionManager /// An extrinsic type used for tests. pub type Extrinsic = TestXt; -type SubmitTransaction = frame_system::offchain::TransactionSubmitter<(), Call, Extrinsic>; type IdentificationTuple = (u64, u64); type Offence = crate::UnresponsivenessOffence; @@ -90,7 +92,6 @@ pub fn new_test_ext() -> sp_io::TestExternalities { t.into() } - #[derive(Clone, PartialEq, Eq, Debug)] pub struct Runtime; @@ -168,13 +169,18 @@ parameter_types! { impl Trait for Runtime { type AuthorityId = UintAuthorityId; type Event = (); - type Call = Call; - type SubmitTransaction = SubmitTransaction; type ReportUnresponsiveness = OffenceHandler; type SessionDuration = Period; type UnsignedPriority = UnsignedPriority; } +impl frame_system::offchain::SendTransactionTypes for Runtime where + Call: From, +{ + type OverarchingCall = Call; + type Extrinsic = Extrinsic; +} + /// Im Online module. pub type ImOnline = Module; pub type System = frame_system::Module; @@ -184,5 +190,7 @@ pub fn advance_session() { let now = System::block_number().max(1); System::set_block_number(now + 1); Session::rotate_session(); + let keys = Session::validators().into_iter().map(UintAuthorityId).collect(); + ImOnline::set_keys(keys); assert_eq!(Session::current_index(), (now / Period::get()) as u32); } diff --git a/frame/im-online/src/tests.rs b/frame/im-online/src/tests.rs index c7bf2afcca..e49f28f489 100644 --- a/frame/im-online/src/tests.rs +++ b/frame/im-online/src/tests.rs @@ -61,15 +61,15 @@ fn should_report_offline_validators() { let block = 1; System::set_block_number(block); // buffer new validators - Session::rotate_session(); + advance_session(); // enact the change and buffer another one let validators = vec![1, 2, 3, 4, 5, 6]; VALIDATORS.with(|l| *l.borrow_mut() = Some(validators.clone())); - Session::rotate_session(); + advance_session(); // when // we end current session and start the next one - Session::rotate_session(); + advance_session(); // then let offences = OFFENCES.with(|l| l.replace(vec![])); @@ -89,7 +89,7 @@ fn should_report_offline_validators() { for (idx, v) in validators.into_iter().take(4).enumerate() { let _ = heartbeat(block, 3, idx as u32, v.into()).unwrap(); } - Session::rotate_session(); + advance_session(); // then let offences = OFFENCES.with(|l| l.replace(vec![])); @@ -174,7 +174,7 @@ fn late_heartbeat_should_fail() { new_test_ext().execute_with(|| { advance_session(); // given - VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 4, 4, 5, 6])); + VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3, 4, 5, 6])); assert_eq!(Session::validators(), Vec::::new()); // enact the change and buffer another one advance_session(); @@ -315,7 +315,7 @@ fn should_not_send_a_report_if_already_online() { ImOnline::note_uncle(3, 0); // when - UintAuthorityId::set_all_keys(vec![0]); // all authorities use pallet_session key 0 + UintAuthorityId::set_all_keys(vec![1, 2, 3]); // we expect error, since the authority is already online. let mut res = ImOnline::send_heartbeats(4).unwrap(); assert_eq!(res.next().unwrap().unwrap(), ()); diff --git a/frame/session/benchmarking/src/mock.rs b/frame/session/benchmarking/src/mock.rs index 4c022eb8b8..c3863e16bb 100644 --- a/frame/session/benchmarking/src/mock.rs +++ b/frame/session/benchmarking/src/mock.rs @@ -151,11 +151,13 @@ parameter_types! { } pub type Extrinsic = sp_runtime::testing::TestXt; -type SubmitTransaction = frame_system::offchain::TransactionSubmitter< - sp_runtime::testing::UintAuthorityId, - Test, - Extrinsic, ->; + +impl frame_system::offchain::SendTransactionTypes for Test where + Call: From, +{ + type OverarchingCall = Call; + type Extrinsic = Extrinsic; +} impl pallet_staking::Trait for Test { type Currency = Balances; @@ -174,7 +176,6 @@ impl pallet_staking::Trait for Test { type NextNewSession = Session; type ElectionLookahead = (); type Call = Call; - type SubmitTransaction = SubmitTransaction; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type UnsignedPriority = UnsignedPriority; } diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 40fce5b0d4..25d9a10709 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -320,7 +320,7 @@ use sp_staking::{ use sp_runtime::{Serialize, Deserialize}; use frame_system::{ self as system, ensure_signed, ensure_root, ensure_none, - offchain::SubmitUnsignedTransaction, + offchain::SendTransactionTypes, }; use sp_phragmen::{ ExtendedBalance, Assignment, PhragmenScore, PhragmenResult, build_support_map, evaluate_support, @@ -743,7 +743,7 @@ impl SessionInterface<::AccountId> for T whe } } -pub trait Trait: frame_system::Trait { +pub trait Trait: frame_system::Trait + SendTransactionTypes> { /// The staking balance. type Currency: LockableCurrency; @@ -804,10 +804,7 @@ pub trait Trait: frame_system::Trait { /// The overarching call type. type Call: Dispatchable + From> + IsSubType, Self> + Clone; - /// A transaction submitter. - type SubmitTransaction: SubmitUnsignedTransaction::Call>; - - /// The maximum number of nominators rewarded for each validator. + /// The maximum number of nominator rewarded for each validator. /// /// For each validator only the `$MaxNominatorRewardedPerValidator` biggest stakers can claim /// their reward. This used to limit the i/o cost for the nominator payout. diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 20ec6f46a6..cd943abfa3 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -29,7 +29,6 @@ use frame_support::{ traits::{Currency, Get, FindAuthor, OnFinalize, OnInitialize}, weights::Weight, }; -use frame_system::offchain::TransactionSubmitter; use sp_io; use sp_phragmen::{ build_support_map, evaluate_support, reduce, ExtendedBalance, StakedAssignment, PhragmenScore, @@ -309,13 +308,18 @@ impl Trait for Test { type NextNewSession = Session; type ElectionLookahead = ElectionLookahead; type Call = Call; - type SubmitTransaction = SubmitTransaction; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type UnsignedPriority = UnsignedPriority; } +impl frame_system::offchain::SendTransactionTypes for Test where + Call: From, +{ + type OverarchingCall = Call; + type Extrinsic = Extrinsic; +} + pub type Extrinsic = TestXt; -type SubmitTransaction = TransactionSubmitter<(), Test, Extrinsic>; pub struct ExtBuilder { session_length: BlockNumber, diff --git a/frame/staking/src/offchain_election.rs b/frame/staking/src/offchain_election.rs index 4d8ccc6f25..c2383d1eeb 100644 --- a/frame/staking/src/offchain_election.rs +++ b/frame/staking/src/offchain_election.rs @@ -19,7 +19,7 @@ use crate::{ Call, CompactAssignments, Module, NominatorIndex, OffchainAccuracy, Trait, ValidatorIndex, }; -use frame_system::offchain::SubmitUnsignedTransaction; +use frame_system::offchain::SubmitTransaction; use sp_phragmen::{ build_support_map, evaluate_support, reduce, Assignment, ExtendedBalance, PhragmenResult, PhragmenScore, @@ -117,14 +117,14 @@ pub(crate) fn compute_offchain_election() -> Result<(), OffchainElecti let current_era = >::current_era().unwrap_or_default(); // send it. - let call: ::Call = Call::submit_election_solution_unsigned( + let call = Call::submit_election_solution_unsigned( winners, compact, score, current_era, ).into(); - T::SubmitTransaction::submit_unsigned(call) + SubmitTransaction::>::submit_unsigned_transaction(call) .map_err(|_| OffchainElectionError::PoolSubmissionFailed) } diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index d1bc3c1a51..49c404c022 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -1591,7 +1591,7 @@ impl Lookup for ChainContext { } #[cfg(test)] -mod tests { +pub(crate) mod tests { use super::*; use sp_std::cell::RefCell; use sp_core::H256; @@ -1602,7 +1602,7 @@ mod tests { pub enum Origin for Test where system = super {} } - #[derive(Clone, Eq, PartialEq)] + #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; parameter_types! { @@ -1630,8 +1630,9 @@ mod tests { fn on_killed_account(who: &u64) { KILLED.with(|r| r.borrow_mut().push(*who)) } } - #[derive(Debug)] - pub struct Call {} + #[derive(Debug, codec::Encode, codec::Decode)] + pub struct Call; + impl Dispatchable for Call { type Origin = (); type Trait = (); @@ -1679,7 +1680,7 @@ mod tests { type System = Module; - const CALL: &::Call = &Call {}; + const CALL: &::Call = &Call; fn new_test_ext() -> sp_io::TestExternalities { GenesisConfig::default().build_storage::().unwrap().into() diff --git a/frame/system/src/offchain.rs b/frame/system/src/offchain.rs index a3fe3e00ca..04cd3001e4 100644 --- a/frame/system/src/offchain.rs +++ b/frame/system/src/offchain.rs @@ -15,353 +15,832 @@ // along with Substrate. If not, see . //! Module helpers for off-chain calls. +//! +//! ## Overview +//! +//! This module provides transaction related helpers to: +//! - Submit a raw unsigned transaction +//! - Submit an unsigned transaction with a signed payload +//! - Submit a signed transction. +//! +//! ## Usage +//! +//! Please refer to [`example-offchain-worker`](../../pallet_example_offchain_worker/index.html) for +//! a concrete example usage of this crate. +//! +//! ### Submit a raw unsigned transaction +//! +//! To submit a raw unsigned transaction, [`SubmitTransaction`](./struct.SubmitTransaction.html) +//! can be used. +//! +//! ### Signing transactions +//! +//! To be able to use signing, the following trait should be implemented: +//! +//! - [`AppCrypto`](./trait.AppCrypto.html): where an application-specific key +//! is defined and can be used by this module's helpers for signing. +//! - [`CreateSignedTransaction`](./trait.CreateSignedTransaction.html): where +//! the manner in which the transaction is constructed is defined. +//! +//! #### Submit an unsigned transaction with a signed payload +//! +//! Initially, a payload instance that implements the `SignedPayload` trait should be defined. +//! See [`PricePayload`](../../pallet_example_offchain_worker/struct.PricePayload.html) +//! +//! The payload type that is defined defined can then be signed and submitted onchain. +//! +//! #### Submit a signed transaction +//! +//! [`Signer`](./struct.Signer.html) can be used to sign/verify payloads +//! + +#![warn(missing_docs)] use codec::Encode; -use sp_std::convert::TryInto; -use sp_std::prelude::Vec; -use sp_runtime::app_crypto::{RuntimeAppPublic, AppPublic, AppSignature}; +use sp_std::collections::btree_set::BTreeSet; +use sp_std::convert::{TryInto, TryFrom}; +use sp_std::prelude::{Box, Vec}; +use sp_runtime::app_crypto::RuntimeAppPublic; use sp_runtime::traits::{Extrinsic as ExtrinsicT, IdentifyAccount, One}; -use frame_support::{debug, storage::StorageMap}; +use frame_support::{debug, storage::StorageMap, RuntimeDebug}; -/// Creates runtime-specific signed transaction. +/// Marker struct used to flag using all supported keys to sign a payload. +pub struct ForAll {} +/// Marker struct used to flag using any of the supported keys to sign a payload. +pub struct ForAny {} + +/// Provides the ability to directly submit signed and unsigned +/// transaction onchain. /// -/// This trait should be implemented by your `Runtime` to be able -/// to submit `SignedTransaction`s` to the pool from off-chain code. -pub trait CreateTransaction { - /// A `Public` key representing a particular `AccountId`. - type Public: IdentifyAccount + Clone; - /// A `Signature` generated by the `Signer`. - type Signature; +/// For submitting unsigned transactions, `submit_unsigned_transaction` +/// utility function can be used. However, this struct is used by `Signer` +/// to submit a signed transactions providing the signature along with the call. +pub struct SubmitTransaction, OverarchingCall> { + _phantom: sp_std::marker::PhantomData<(T, OverarchingCall)> +} - /// Attempt to create signed extrinsic data that encodes call from given account. - /// - /// Runtime implementation is free to construct the payload to sign and the signature - /// in any way it wants. - /// Returns `None` if signed extrinsic could not be created (either because signing failed - /// or because of any other runtime-specific reason). - fn create_transaction>( - call: Extrinsic::Call, - public: Self::Public, - account: T::AccountId, - nonce: T::Index, - ) -> Option<(Extrinsic::Call, Extrinsic::SignaturePayload)>; +impl SubmitTransaction +where + T: SendTransactionTypes, +{ + /// Submit transaction onchain by providing the call and an optional signature + pub fn submit_transaction( + call: >::OverarchingCall, + signature: Option<::SignaturePayload>, + ) -> Result<(), ()> { + let xt = T::Extrinsic::new(call.into(), signature).ok_or(())?; + sp_io::offchain::submit_transaction(xt.encode()) + } + + /// A convenience method to submit an unsigned transaction onchain. + pub fn submit_unsigned_transaction( + call: >::OverarchingCall, + ) -> Result<(), ()> { + SubmitTransaction::::submit_transaction(call, None) + } } -/// A trait responsible for signing a payload using given account. +/// Provides an implementation for signing transaction payloads. /// -/// This trait is usually going to represent a local public key -/// that has ability to sign arbitrary `Payloads`. +/// Keys used for signing are defined when instantiating the signer object. +/// Signing can be done using: /// -/// NOTE: Most likely you don't need to implement this trait manually. -/// It has a blanket implementation for all `RuntimeAppPublic` types, -/// so it's enough to pass an application-specific crypto type. +/// - All supported keys in the keystore +/// - Any of the supported keys in the keystore +/// - An intersection of in-keystore keys and the list of provided keys /// -/// To easily create `SignedTransaction`s have a look at the -/// [`TransactionSubmitter`] type. -pub trait Signer { - /// Sign any encodable payload with given account and produce a signature. +/// The signer is then able to: +/// - Submit a unsigned transaction with a signed payload +/// - Submit a signed transaction +#[derive(RuntimeDebug)] +pub struct Signer, X = ForAny> { + accounts: Option>, + _phantom: sp_std::marker::PhantomData<(X, C)>, +} + +impl, X> Default for Signer { + fn default() -> Self { + Self { + accounts: Default::default(), + _phantom: Default::default(), + } + } +} + +impl, X> Signer { + /// Use all available keys for signing. + pub fn all_accounts() -> Signer { + Default::default() + } + + /// Use any of the available keys for signing. + pub fn any_account() -> Signer { + Default::default() + } + + /// Use provided `accounts` for signing. /// - /// Returns `Some` if signing succeeded and `None` in case the `account` couldn't - /// be used (for instance we couldn't convert it to required application specific crypto). - fn sign(public: Public, payload: &Payload) -> Option; + /// Note that not all keys will be necessarily used. The provided + /// vector of accounts will be intersected with the supported keys + /// in the keystore and the resulting list will be used for signing. + pub fn with_filter(mut self, accounts: Vec) -> Self { + self.accounts = Some(accounts); + self + } + + /// Check if there are any keys that could be used for signing. + pub fn can_sign(&self) -> bool { + self.accounts_from_keys().count() > 0 + } + + /// Return a vector of the intersection between + /// all available accounts and the provided accounts + /// in `with_filter`. If no accounts are provided, + /// use all accounts by default. + fn accounts_from_keys<'a>(&'a self) -> Box> + 'a> { + let keystore_accounts = self.keystore_accounts(); + match self.accounts { + None => Box::new(keystore_accounts), + Some(ref keys) => { + let keystore_lookup: BTreeSet<::Public> = keystore_accounts + .map(|account| account.public).collect(); + + Box::new(keys.into_iter() + .enumerate() + .map(|(index, key)| { + let account_id = key.clone().into_account(); + Account::new(index, account_id, key.clone()) + }) + .filter(move |account| keystore_lookup.contains(&account.public))) + } + } + } + + fn keystore_accounts(&self) -> impl Iterator> { + C::RuntimeAppPublic::all() + .into_iter() + .enumerate() + .map(|(index, key)| { + let generic_public = C::GenericPublic::from(key); + let public = generic_public.into(); + let account_id = public.clone().into_account(); + Account::new(index, account_id, public.clone()) + }) + } } -/// A `Signer` implementation for any `AppPublic` type. -/// -/// This implementation additionally supports conversion to/from multi-signature/multi-signer -/// wrappers. -/// If the wrapped crypto doesn't match `AppPublic`s crypto `None` is returned. -impl Signer for TAnyAppPublic where - TAnyAppPublic: RuntimeAppPublic - + AppPublic - + From<::Generic>, - ::Signature: AppSignature, - Signature: From< - <::Signature as AppSignature>::Generic - >, - Public: TryInto<::Generic> -{ - fn sign(public: Public, raw_payload: &Payload) -> Option { - raw_payload.using_encoded(|payload| { - let public = public.try_into().ok()?; - TAnyAppPublic::from(public).sign(&payload) - .map( - <::Signature as AppSignature> - ::Generic::from - ) - .map(Signature::from) + +impl> Signer { + fn for_all(&self, f: F) -> Vec<(Account, R)> where + F: Fn(&Account) -> Option, + { + let accounts = self.accounts_from_keys(); + accounts + .into_iter() + .filter_map(|account| { + f(&account).map(|res| (account, res)) + }) + .collect() + } +} + +impl> Signer { + fn for_any(&self, f: F) -> Option<(Account, R)> where + F: Fn(&Account) -> Option, + { + let accounts = self.accounts_from_keys(); + for account in accounts.into_iter() { + let res = f(&account); + if let Some(res) = res { + return Some((account, res)); + } + } + None + } +} + +impl> SignMessage for Signer { + type SignatureData = Vec<(Account, T::Signature)>; + + fn sign_message(&self, message: &[u8]) -> Self::SignatureData { + self.for_all(|account| C::sign(message, account.public.clone())) + } + + fn sign(&self, f: F) -> Self::SignatureData where + F: Fn(&Account) -> TPayload, + TPayload: SignedPayload, + { + self.for_all(|account| f(account).sign::()) + } +} + +impl> SignMessage for Signer { + type SignatureData = Option<(Account, T::Signature)>; + + fn sign_message(&self, message: &[u8]) -> Self::SignatureData { + self.for_any(|account| C::sign(message, account.public.clone())) + } + + fn sign(&self, f: F) -> Self::SignatureData where + F: Fn(&Account) -> TPayload, + TPayload: SignedPayload, + { + self.for_any(|account| f(account).sign::()) + } +} + +impl< + T: CreateSignedTransaction + SigningTypes, + C: AppCrypto, + LocalCall, +> SendSignedTransaction for Signer { + type Result = Option<(Account, Result<(), ()>)>; + + fn send_signed_transaction( + &self, + f: impl Fn(&Account) -> LocalCall, + ) -> Self::Result { + self.for_any(|account| { + let call = f(account); + self.send_single_signed_transaction(account, call) }) } } -/// Retrieves a public key type for given `SignAndSubmitTransaction`. -pub type PublicOf = -< - >::CreateTransaction - as - CreateTransaction>::Extrinsic> ->::Public; +impl< + T: SigningTypes + CreateSignedTransaction, + C: AppCrypto, + LocalCall, +> SendSignedTransaction for Signer { + type Result = Vec<(Account, Result<(), ()>)>; + + fn send_signed_transaction( + &self, + f: impl Fn(&Account) -> LocalCall, + ) -> Self::Result { + self.for_all(|account| { + let call = f(account); + self.send_single_signed_transaction(account, call) + }) + } +} + +impl< + T: SigningTypes + SendTransactionTypes, + C: AppCrypto, + LocalCall, +> SendUnsignedTransaction for Signer { + type Result = Option<(Account, Result<(), ()>)>; + + fn send_unsigned_transaction( + &self, + f: F, + f2: impl Fn(TPayload, T::Signature) -> LocalCall, + ) -> Self::Result + where + F: Fn(&Account) -> TPayload, + TPayload: SignedPayload, + { + self.for_any(|account| { + let payload = f(account); + let signature= payload.sign::()?; + let call = f2(payload, signature); + self.submit_unsigned_transaction(call) + }) + } +} + +impl< + T: SigningTypes + SendTransactionTypes, + C: AppCrypto, + LocalCall, +> SendUnsignedTransaction for Signer { + type Result = Vec<(Account, Result<(), ()>)>; + + fn send_unsigned_transaction( + &self, + f: F, + f2: impl Fn(TPayload, T::Signature) -> LocalCall, + ) -> Self::Result + where + F: Fn(&Account) -> TPayload, + TPayload: SignedPayload { + self.for_all(|account| { + let payload = f(account); + let signature = payload.sign::()?; + let call = f2(payload, signature); + self.submit_unsigned_transaction(call) + }) + } +} + +/// Details of an account for which a private key is contained in the keystore. +#[derive(RuntimeDebug, PartialEq)] +pub struct Account { + /// Index on the provided list of accounts or list of all accounts. + pub index: usize, + /// Runtime-specific `AccountId`. + pub id: T::AccountId, + /// A runtime-specific `Public` key for that key pair. + pub public: T::Public, +} + +impl Account { + /// Create a new Account instance + pub fn new(index: usize, id: T::AccountId, public: T::Public) -> Self { + Self { index, id, public } + } +} + +impl Clone for Account where + T::AccountId: Clone, + T::Public: Clone, +{ + fn clone(&self) -> Self { + Self { + index: self.index, + id: self.id.clone(), + public: self.public.clone(), + } + } +} -/// A trait to sign and submit transactions in off-chain calls. +/// A type binding runtime-level `Public/Signature` pair with crypto wrapped by `RuntimeAppPublic`. /// -/// NOTE: Most likely you should not implement this trait yourself. -/// There is an implementation for -/// [`TransactionSubmitter`] type, which -/// you should use. -pub trait SignAndSubmitTransaction { - /// Unchecked extrinsic type. - type Extrinsic: ExtrinsicT + Encode; - - /// A runtime-specific type to produce signed data for the extrinsic. - type CreateTransaction: CreateTransaction; - - /// A type used to sign transactions created using `CreateTransaction`. - type Signer: Signer< - PublicOf, - >::Signature, - >; - - /// Sign given call and submit it to the transaction pool. - /// - /// Returns `Ok` if the transaction was submitted correctly - /// and `Err` if the key for given `id` was not found or the - /// transaction was rejected from the pool. - fn sign_and_submit(call: impl Into, public: PublicOf) -> Result<(), ()> { - let call = call.into(); - let id = public.clone().into_account(); - let mut account = super::Account::::get(&id); - debug::native::debug!( - target: "offchain", - "Creating signed transaction from account: {:?} (nonce: {:?})", - id, - account.nonce, - ); - let (call, signature_data) = Self::CreateTransaction - ::create_transaction::(call, public, id.clone(), account.nonce) - .ok_or(())?; - // increment the nonce. This is fine, since the code should always - // be running in off-chain context, so we NEVER persists data. - account.nonce += One::one(); - super::Account::::insert(&id, account); - - let xt = Self::Extrinsic::new(call, Some(signature_data)).ok_or(())?; - sp_io::offchain::submit_transaction(xt.encode()) +/// Implementations of this trait should specify the app-specific public/signature types. +/// This is merely a wrapper around an existing `RuntimeAppPublic` type, but with +/// extra non-application-specific crypto type that is being wrapped (e.g. `sr25519`, `ed25519`). +/// This is needed to later on convert into runtime-specific `Public` key, which might support +/// multiple different crypto. +/// The point of this trait is to be able to easily convert between `RuntimeAppPublic`, the wrapped +/// (generic = non application-specific) crypto types and the `Public` type required by the runtime. +/// +/// TODO [#5662] Potentially use `IsWrappedBy` types, or find some other way to make it easy to +/// obtain unwrapped crypto (and wrap it back). +/// +/// Example (pseudo-)implementation: +/// ```ignore +/// // im-online specific crypto +/// type RuntimeAppPublic = ImOnline(sr25519::Public); +/// // wrapped "raw" crypto +/// type GenericPublic = sr25519::Public; +/// type GenericSignature = sr25519::Signature; +/// +/// // runtime-specific public key +/// type Public = MultiSigner: From; +/// type Signature = MulitSignature: From; +/// ``` +pub trait AppCrypto { + /// A application-specific crypto. + type RuntimeAppPublic: RuntimeAppPublic; + + /// A raw crypto public key wrapped by `RuntimeAppPublic`. + type GenericPublic: + From + + Into + + TryFrom + + Into; + + /// A matching raw crypto `Signature` type. + type GenericSignature: + From<::Signature> + + Into<::Signature> + + TryFrom + + Into; + + /// Sign payload with the private key to maps to the provided public key. + fn sign(payload: &[u8], public: Public) -> Option { + let p: Self::GenericPublic = public.try_into().ok()?; + let x = Into::::into(p); + x.sign(&payload) + .map(|x| { + let sig: Self::GenericSignature = x.into(); + sig + }) + .map(Into::into) + } + + /// Verify signature against the provided public key. + fn verify(payload: &[u8], public: Public, signature: Signature) -> bool { + let p: Self::GenericPublic = match public.try_into() { + Ok(a) => a, + _ => return false + }; + let x = Into::::into(p); + let signature: Self::GenericSignature = match signature.try_into() { + Ok(a) => a, + _ => return false + }; + let signature = Into::<< + Self::RuntimeAppPublic as RuntimeAppPublic + >::Signature>::into(signature); + + x.verify(&payload, &signature) } } -/// A trait to submit unsigned transactions in off-chain calls. +/// A wrapper around the types which are used for signing. +/// +/// This trait adds extra bounds to `Public` and `Signature` types of the runtime +/// that are necessary to use these types for signing. /// -/// NOTE: Most likely you should not implement this trait yourself. -/// There is an implementation for -/// [`TransactionSubmitter`] type, which -/// you should use. -pub trait SubmitUnsignedTransaction { - /// Unchecked extrinsic type. - type Extrinsic: ExtrinsicT + Encode; - - /// Submit given call to the transaction pool as unsigned transaction. +/// TODO [#5663] Could this be just `T::Signature as traits::Verify>::Signer`? +/// Seems that this may cause issues with bounds resolution. +pub trait SigningTypes: crate::Trait { + /// A public key that is capable of identifing `AccountId`s. /// - /// Returns `Ok` if the transaction was submitted correctly - /// and `Err` if transaction was rejected from the pool. - fn submit_unsigned(call: impl Into) -> Result<(), ()> { - let xt = Self::Extrinsic::new(call.into(), None).ok_or(())?; - let encoded_xt = xt.encode(); - sp_io::offchain::submit_transaction(encoded_xt) - } + /// Usually that's either a raw crypto public key (e.g. `sr25519::Public`) or + /// an aggregate type for multiple crypto public keys, like `MulitSigner`. + type Public: Clone + + PartialEq + + IdentifyAccount + + core::fmt::Debug + + codec::Codec + + Ord; + + /// A matching `Signature` type. + type Signature: Clone + + PartialEq + + core::fmt::Debug + + codec::Codec; } -/// A utility trait to easily create signed transactions -/// from accounts in node's local keystore. +/// A definition of types required to submit transactions from within the runtime. +pub trait SendTransactionTypes { + /// The extrinsic type expected by the runtime. + type Extrinsic: ExtrinsicT + codec::Encode; + /// The runtime's call type. + /// + /// This has additional bound to be able to be created from pallet-local `Call` types. + type OverarchingCall: From; +} + +/// Create signed transaction. /// -/// NOTE: Most likely you should not implement this trait yourself. -/// There is an implementation for -/// [`TransactionSubmitter`] type, which -/// you should use. -pub trait SubmitSignedTransaction { - /// A `SignAndSubmitTransaction` implementation. - type SignAndSubmit: SignAndSubmitTransaction; - - /// Find local keys that match given list of accounts. +/// This trait is meant to be implemented by the runtime and is responsible for constructing +/// a payload to be signed and contained within the extrinsic. +/// This will most likely include creation of `SignedExtra` (a set of `SignedExtensions`). +/// Note that the result can be altered by inspecting the `Call` (for instance adjusting +/// fees, or mortality depending on the `pallet` being called). +pub trait CreateSignedTransaction: SendTransactionTypes + SigningTypes { + /// Attempt to create signed extrinsic data that encodes call from given account. /// - /// Technically it finds an intersection between given list of `AccountId`s - /// and accounts that are represented by public keys in local keystore. - /// If `None` is passed it returns all accounts in the keystore. + /// Runtime implementation is free to construct the payload to sign and the signature + /// in any way it wants. + /// Returns `None` if signed extrinsic could not be created (either because signing failed + /// or because of any other runtime-specific reason). + fn create_transaction>( + call: Self::OverarchingCall, + public: Self::Public, + account: Self::AccountId, + nonce: Self::Index, + ) -> Option<(Self::OverarchingCall, ::SignaturePayload)>; +} + +/// A message signer. +pub trait SignMessage { + /// A signature data. /// - /// Returns both public keys and `AccountId`s of accounts that are available. - /// Such accounts can later be used to sign a payload or send signed transactions. - fn find_local_keys(accounts: Option>) -> Vec<( - T::AccountId, - PublicOf, - )>; - - /// Find all available local keys. + /// May contain account used for signing and the `Signature` itself. + type SignatureData; + + /// Sign a message. /// - /// This is equivalent of calling `find_local_keys(None)`. - fn find_all_local_keys() -> Vec<(T::AccountId, PublicOf)> { - Self::find_local_keys(None as Option>) - } + /// Implementation of this method should return + /// a result containing the signature. + fn sign_message(&self, message: &[u8]) -> Self::SignatureData; - /// Check if there are keys for any of given accounts that could be used to send a transaction. + /// Construct and sign given payload. /// - /// This check can be used as an early-exit condition to avoid doing too - /// much work, before we actually realise that there are no accounts that you - /// we could use for signing. - fn can_sign_with(accounts: Option>) -> bool { - !Self::find_local_keys(accounts).is_empty() - } + /// This method expects `f` to return a `SignedPayload` + /// object which is then used for signing. + fn sign(&self, f: F) -> Self::SignatureData where + F: Fn(&Account) -> TPayload, + TPayload: SignedPayload, + ; +} - /// Check if there are any keys that could be used for signing. +/// Submit a signed transaction to the transaction pool. +pub trait SendSignedTransaction< + T: SigningTypes + CreateSignedTransaction, + C: AppCrypto, + LocalCall +> { + /// A submission result. /// - /// This is equivalent of calling `can_sign_with(None)`. - fn can_sign() -> bool { - Self::can_sign_with(None as Option>) + /// This should contain an indication of success and the account that was used for signing. + type Result; + + /// Submit a signed transaction to the local pool. + /// + /// Given `f` closure will be called for every requested account and expects a `Call` object + /// to be returned. + /// The call is then wrapped into a transaction (see `#CreateSignedTransaction`), signed and + /// submitted to the pool. + fn send_signed_transaction( + &self, + f: impl Fn(&Account) -> LocalCall, + ) -> Self::Result; + + /// Wraps the call into transaction, signs using given account and submits to the pool. + fn send_single_signed_transaction( + &self, + account: &Account, + call: LocalCall, + ) -> Option> { + let mut account_data = crate::Account::::get(&account.id); + debug::native::debug!( + target: "offchain", + "Creating signed transaction from account: {:?} (nonce: {:?})", + account.id, + account_data.nonce, + ); + let (call, signature) = T::create_transaction::( + call.into(), + account.public.clone(), + account.id.clone(), + account_data.nonce + )?; + let res = SubmitTransaction:: + ::submit_transaction(call, Some(signature)); + + if res.is_ok() { + // increment the nonce. This is fine, since the code should always + // be running in off-chain context, so we NEVER persists data. + account_data.nonce += One::one(); + crate::Account::::insert(&account.id, account_data); + } + + Some(res) } +} - /// Create and submit signed transactions from supported accounts. +/// Submit an unsigned transaction onchain with a signed payload +pub trait SendUnsignedTransaction< + T: SigningTypes + SendTransactionTypes, + LocalCall, +> { + /// A submission result. /// - /// This method should intersect given list of accounts with the ones - /// supported locally and submit signed transaction containing given `Call` - /// with every of them. + /// Should contain the submission result and the account(s) that signed the payload. + type Result; + + /// Send an unsigned transaction with a signed payload. /// - /// Returns a vector of results and account ids that were supported. - #[must_use] - fn submit_signed_from( - call: impl Into + Clone, - accounts: impl IntoIterator, - ) -> Vec<(T::AccountId, Result<(), ()>)> { - let keys = Self::find_local_keys(Some(accounts)); - keys.into_iter().map(|(account, pub_key)| { - let call = call.clone().into(); - ( - account, - Self::SignAndSubmit::sign_and_submit(call, pub_key) - ) - }).collect() - } - - /// Create and submit signed transactions from all local accounts. + /// This method takes `f` and `f2` where: + /// - `f` is called for every account and is expected to return a `SignedPayload` object. + /// - `f2` is then called with the `SignedPayload` returned by `f` and the signature and is + /// expected to return a `Call` object to be embedded into transaction. + fn send_unsigned_transaction( + &self, + f: F, + f2: impl Fn(TPayload, T::Signature) -> LocalCall, + ) -> Self::Result + where + F: Fn(&Account) -> TPayload, + TPayload: SignedPayload; + + /// Submits an unsigned call to the transaction pool. + fn submit_unsigned_transaction( + &self, + call: LocalCall + ) -> Option> { + Some(SubmitTransaction:: + ::submit_unsigned_transaction(call.into())) + } +} + +/// Utility trait to be implemented on payloads that can be signed. +pub trait SignedPayload: Encode { + /// Return a public key that is expected to have a matching key in the keystore, + /// which should be used to sign the payload. + fn public(&self) -> T::Public; + + /// Sign the payload using the implementor's provided public key. /// - /// This method submits a signed transaction from all local accounts - /// for given application crypto. + /// Returns `Some(signature)` if public key is supported. + fn sign>(&self) -> Option { + self.using_encoded(|payload| C::sign(payload, self.public())) + } + + /// Verify signature against payload. /// - /// Returns a vector of results and account ids that were supported. - #[must_use] - fn submit_signed( - call: impl Into + Clone, - ) -> Vec<(T::AccountId, Result<(), ()>)> { - let keys = Self::find_all_local_keys(); - keys.into_iter().map(|(account, pub_key)| { - let call = call.clone().into(); - ( - account, - Self::SignAndSubmit::sign_and_submit(call, pub_key) - ) - }).collect() + /// Returns a bool indicating whether the signature is valid or not. + fn verify>(&self, signature: T::Signature) -> bool { + self.using_encoded(|payload| C::verify(payload, self.public(), signature)) } } -/// A default type used to submit transactions to the pool. -/// -/// This is passed into each runtime as an opaque associated type that can have either of: -/// - [`SignAndSubmitTransaction`] -/// - [`SubmitUnsignedTransaction`] -/// - [`SubmitSignedTransaction`] -/// and used accordingly. -/// -/// This struct should be constructed by providing the following generic parameters: -/// * `Signer` - Usually the application specific key type (see `app_crypto`). -/// * `CreateTransaction` - A type that is able to produce signed transactions, -/// usually it's going to be the entire `Runtime` object. -/// * `Extrinsic` - A runtime-specific type for in-block extrinsics. -/// -/// If you only need the ability to submit unsigned transactions, -/// you may substitute both `Signer` and `CreateTransaction` with any type. -pub struct TransactionSubmitter { - _signer: sp_std::marker::PhantomData<(Signer, CreateTransaction, Extrinsic)>, -} -impl Default for TransactionSubmitter { - fn default() -> Self { - Self { - _signer: Default::default(), - } +#[cfg(test)] +mod tests { + use super::*; + use codec::Decode; + use crate::tests::{Test as TestRuntime, Call}; + use sp_core::offchain::{testing, TransactionPoolExt}; + use sp_runtime::testing::{UintAuthorityId, TestSignature, TestXt}; + + impl SigningTypes for TestRuntime { + type Public = UintAuthorityId; + type Signature = TestSignature; } -} -/// A blanket implementation to simplify creation of transaction signer & submitter in the runtime. -impl SignAndSubmitTransaction for TransactionSubmitter where - T: crate::Trait, - C: CreateTransaction, - S: Signer<>::Public, >::Signature>, - E: ExtrinsicT + Encode, -{ - type Extrinsic = E; - type CreateTransaction = C; - type Signer = S; -} + type Extrinsic = TestXt; -/// A blanket implementation to use the same submitter for unsigned transactions as well. -impl SubmitUnsignedTransaction for TransactionSubmitter where - T: crate::Trait, - E: ExtrinsicT + Encode, -{ - type Extrinsic = E; -} + impl SendTransactionTypes for TestRuntime { + type Extrinsic = Extrinsic; + type OverarchingCall = Call; + } -/// A blanket implementation to support local keystore of application-crypto types. -impl SubmitSignedTransaction for TransactionSubmitter where - T: crate::Trait, - C: CreateTransaction, - E: ExtrinsicT + Encode, - S: Signer<>::Public, >::Signature>, - // Make sure we can unwrap the app crypto key. - S: RuntimeAppPublic + AppPublic + Into<::Generic>, - // Make sure we can convert from wrapped crypto to public key (e.g. `MultiSigner`) - S::Generic: Into>, - // For simplicity we require the same trait to implement `SignAndSubmitTransaction` too. - Self: SignAndSubmitTransaction, -{ - type SignAndSubmit = Self; - - fn find_local_keys(accounts: Option>) -> Vec<( - T::AccountId, - PublicOf, - )> { - // Convert app-specific keys into generic ones. - let local_accounts_and_keys = S::all() - .into_iter() - .map(|app_key| { - // unwrap app-crypto - let generic_pub_key: ::Generic = app_key.into(); - // convert to expected public key type (might be MultiSigner) - let signer_pub_key: PublicOf = generic_pub_key.into(); - // lookup accountid for that pubkey - let account = signer_pub_key.clone().into_account(); - (account, signer_pub_key) - }).collect::>(); - - if let Some(accounts) = accounts { - let mut local_accounts_and_keys = local_accounts_and_keys; - // sort by accountId to allow bin-search. - local_accounts_and_keys.sort_by(|a, b| a.0.cmp(&b.0)); - - // get all the matching accounts - accounts.into_iter().filter_map(|acc| { - let idx = local_accounts_and_keys.binary_search_by(|a| a.0.cmp(&acc)).ok()?; - local_accounts_and_keys.get(idx).cloned() - }).collect() - } else { - // just return all account ids and keys - local_accounts_and_keys - } + #[derive(codec::Encode, codec::Decode)] + struct SimplePayload { + pub public: UintAuthorityId, + pub data: Vec, } - fn can_sign_with(accounts: Option>) -> bool { - // early exit if we care about any account. - if accounts.is_none() { - !S::all().is_empty() - } else { - !Self::find_local_keys(accounts).is_empty() + impl SignedPayload for SimplePayload { + fn public(&self) -> UintAuthorityId { + self.public.clone() } } + + struct DummyAppCrypto; + // Bind together the `SigningTypes` with app-crypto and the wrapper types. + // here the implementation is pretty dummy, because we use the same type for + // both application-specific crypto and the runtime crypto, but in real-life + // runtimes it's going to use different types everywhere. + impl AppCrypto for DummyAppCrypto { + type RuntimeAppPublic = UintAuthorityId; + type GenericPublic = UintAuthorityId; + type GenericSignature = TestSignature; + } + + fn assert_account( + next: Option<(Account, Result<(), ()>)>, + index: usize, + id: u64, + ) { + assert_eq!(next, Some((Account { + index, + id, + public: id.into(), + }, Ok(())))); + } + + #[test] + fn should_send_unsigned_with_signed_payload_with_all_accounts() { + let (pool, pool_state) = testing::TestTransactionPoolExt::new(); + + let mut t = sp_io::TestExternalities::default(); + t.register_extension(TransactionPoolExt::new(pool)); + + // given + UintAuthorityId::set_all_keys(vec![0xf0, 0xf1, 0xf2]); + + t.execute_with(|| { + // when + let result = Signer:: + ::all_accounts() + .send_unsigned_transaction( + |account| SimplePayload { + data: vec![1, 2, 3], + public: account.public.clone() + }, + |_payload, _signature| { + Call + } + ); + + // then + let mut res = result.into_iter(); + assert_account(res.next(), 0, 0xf0); + assert_account(res.next(), 1, 0xf1); + assert_account(res.next(), 2, 0xf2); + assert_eq!(res.next(), None); + + // check the transaction pool content: + let tx1 = pool_state.write().transactions.pop().unwrap(); + let _tx2 = pool_state.write().transactions.pop().unwrap(); + let _tx3 = pool_state.write().transactions.pop().unwrap(); + assert!(pool_state.read().transactions.is_empty()); + let tx1 = Extrinsic::decode(&mut &*tx1).unwrap(); + assert_eq!(tx1.signature, None); + }); + } + + #[test] + fn should_send_unsigned_with_signed_payload_with_any_account() { + let (pool, pool_state) = testing::TestTransactionPoolExt::new(); + + let mut t = sp_io::TestExternalities::default(); + t.register_extension(TransactionPoolExt::new(pool)); + + // given + UintAuthorityId::set_all_keys(vec![0xf0, 0xf1, 0xf2]); + + t.execute_with(|| { + // when + let result = Signer:: + ::any_account() + .send_unsigned_transaction( + |account| SimplePayload { + data: vec![1, 2, 3], + public: account.public.clone() + }, + |_payload, _signature| { + Call + } + ); + + // then + let mut res = result.into_iter(); + assert_account(res.next(), 0, 0xf0); + assert_eq!(res.next(), None); + + // check the transaction pool content: + let tx1 = pool_state.write().transactions.pop().unwrap(); + assert!(pool_state.read().transactions.is_empty()); + let tx1 = Extrinsic::decode(&mut &*tx1).unwrap(); + assert_eq!(tx1.signature, None); + }); + } + + #[test] + fn should_send_unsigned_with_signed_payload_with_all_account_and_filter() { + let (pool, pool_state) = testing::TestTransactionPoolExt::new(); + + let mut t = sp_io::TestExternalities::default(); + t.register_extension(TransactionPoolExt::new(pool)); + + // given + UintAuthorityId::set_all_keys(vec![0xf0, 0xf1, 0xf2]); + + t.execute_with(|| { + // when + let result = Signer:: + ::all_accounts() + .with_filter(vec![0xf2.into(), 0xf1.into()]) + .send_unsigned_transaction( + |account| SimplePayload { + data: vec![1, 2, 3], + public: account.public.clone() + }, + |_payload, _signature| { + Call + } + ); + + // then + let mut res = result.into_iter(); + assert_account(res.next(), 0, 0xf2); + assert_account(res.next(), 1, 0xf1); + assert_eq!(res.next(), None); + + // check the transaction pool content: + let tx1 = pool_state.write().transactions.pop().unwrap(); + let _tx2 = pool_state.write().transactions.pop().unwrap(); + assert!(pool_state.read().transactions.is_empty()); + let tx1 = Extrinsic::decode(&mut &*tx1).unwrap(); + assert_eq!(tx1.signature, None); + }); + } + + #[test] + fn should_send_unsigned_with_signed_payload_with_any_account_and_filter() { + let (pool, pool_state) = testing::TestTransactionPoolExt::new(); + + let mut t = sp_io::TestExternalities::default(); + t.register_extension(TransactionPoolExt::new(pool)); + + // given + UintAuthorityId::set_all_keys(vec![0xf0, 0xf1, 0xf2]); + + t.execute_with(|| { + // when + let result = Signer:: + ::any_account() + .with_filter(vec![0xf2.into(), 0xf1.into()]) + .send_unsigned_transaction( + |account| SimplePayload { + data: vec![1, 2, 3], + public: account.public.clone() + }, + |_payload, _signature| { + Call + } + ); + + // then + let mut res = result.into_iter(); + assert_account(res.next(), 0, 0xf2); + assert_eq!(res.next(), None); + + // check the transaction pool content: + let tx1 = pool_state.write().transactions.pop().unwrap(); + assert!(pool_state.read().transactions.is_empty()); + let tx1 = Extrinsic::decode(&mut &*tx1).unwrap(); + assert_eq!(tx1.signature, None); + }); + } + } diff --git a/primitives/application-crypto/src/lib.rs b/primitives/application-crypto/src/lib.rs index 79572eb49d..8bad474ede 100644 --- a/primitives/application-crypto/src/lib.rs +++ b/primitives/application-crypto/src/lib.rs @@ -25,7 +25,7 @@ pub use sp_core::{self, crypto::{CryptoType, CryptoTypePublicPair, Public, Deriv #[doc(hidden)] #[cfg(feature = "full_crypto")] pub use sp_core::crypto::{SecretStringError, DeriveJunction, Ss58Codec, Pair}; -pub use sp_core::crypto::{CryptoTypeId, KeyTypeId, key_types}; +pub use sp_core::crypto::{KeyTypeId, key_types}; #[doc(hidden)] pub use codec; diff --git a/primitives/runtime/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs index 4aae575b2c..4eb96ff960 100644 --- a/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -320,29 +320,10 @@ mod tests { use super::*; use sp_io::hashing::blake2_256; use crate::codec::{Encode, Decode}; - use crate::traits::{SignedExtension, IdentifyAccount, IdentityLookup}; - use serde::{Serialize, Deserialize}; + use crate::traits::{SignedExtension, IdentityLookup}; + use crate::testing::TestSignature as TestSig; type TestContext = IdentityLookup; - - #[derive(Eq, PartialEq, Clone, Copy, Debug, Serialize, Deserialize, Encode, Decode)] - pub struct TestSigner(pub u64); - impl From for TestSigner { fn from(x: u64) -> Self { Self(x) } } - impl From for u64 { fn from(x: TestSigner) -> Self { x.0 } } - impl IdentifyAccount for TestSigner { - type AccountId = u64; - fn into_account(self) -> u64 { self.into() } - } - - #[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize, Encode, Decode)] - struct TestSig(u64, Vec); - impl traits::Verify for TestSig { - type Signer = TestSigner; - fn verify>(&self, mut msg: L, signer: &u64) -> bool { - signer == &self.0 && msg.get() == &self.1[..] - } - } - type TestAccountId = u64; type TestCall = Vec; diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 0f609b0050..a5b3e71edc 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -182,18 +182,39 @@ impl From for MultiSignature { } } +impl TryFrom for ed25519::Signature { + type Error = (); + fn try_from(m: MultiSignature) -> Result { + if let MultiSignature::Ed25519(x) = m { Ok(x) } else { Err(()) } + } +} + impl From for MultiSignature { fn from(x: sr25519::Signature) -> Self { MultiSignature::Sr25519(x) } } +impl TryFrom for sr25519::Signature { + type Error = (); + fn try_from(m: MultiSignature) -> Result { + if let MultiSignature::Sr25519(x) = m { Ok(x) } else { Err(()) } + } +} + impl From for MultiSignature { fn from(x: ecdsa::Signature) -> Self { MultiSignature::Ecdsa(x) } } +impl TryFrom for ecdsa::Signature { + type Error = (); + fn try_from(m: MultiSignature) -> Result { + if let MultiSignature::Ecdsa(x) = m { Ok(x) } else { Err(()) } + } +} + impl Default for MultiSignature { fn default() -> Self { MultiSignature::Ed25519(Default::default()) diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index 1414a5f4f0..40b4e23e3f 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -17,7 +17,7 @@ //! Testing utilities. use serde::{Serialize, Serializer, Deserialize, de::Error as DeError, Deserializer}; -use std::{fmt::Debug, ops::Deref, fmt, cell::RefCell}; +use std::{fmt::{self, Debug}, ops::Deref, cell::RefCell}; use crate::codec::{Codec, Encode, Decode}; use crate::traits::{ self, Checkable, Applyable, BlakeTwo256, OpaqueKeys, @@ -29,7 +29,12 @@ pub use sp_core::{H256, sr25519}; use sp_core::{crypto::{CryptoType, Dummy, key_types, Public}, U256}; use crate::transaction_validity::{TransactionValidity, TransactionValidityError, TransactionSource}; -/// Authority Id +/// A dummy type which can be used instead of regular cryptographic primitives. +/// +/// 1. Wraps a `u64` `AccountId` and is able to `IdentifyAccount`. +/// 2. Can be converted to any `Public` key. +/// 3. Implements `RuntimeAppPublic` so it can be used instead of regular application-specific +/// crypto. #[derive(Default, PartialEq, Eq, Clone, Encode, Decode, Debug, Hash, Serialize, Deserialize, PartialOrd, Ord)] pub struct UintAuthorityId(pub u64); @@ -82,7 +87,7 @@ impl UintAuthorityId { impl sp_application_crypto::RuntimeAppPublic for UintAuthorityId { const ID: KeyTypeId = key_types::DUMMY; - type Signature = u64; + type Signature = TestSignature; fn all() -> Vec { ALL_KEYS.with(|l| l.borrow().clone()) @@ -94,25 +99,11 @@ impl sp_application_crypto::RuntimeAppPublic for UintAuthorityId { } fn sign>(&self, msg: &M) -> Option { - let mut signature = [0u8; 8]; - msg.as_ref().iter() - .chain(std::iter::repeat(&42u8)) - .take(8) - .enumerate() - .for_each(|(i, v)| { signature[i] = *v; }); - - Some(u64::from_le_bytes(signature)) + Some(TestSignature(self.0, msg.as_ref().to_vec())) } fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { - let mut msg_signature = [0u8; 8]; - msg.as_ref().iter() - .chain(std::iter::repeat(&42)) - .take(8) - .enumerate() - .for_each(|(i, v)| { msg_signature[i] = *v; }); - - u64::from_le_bytes(msg_signature) == *signature + traits::Verify::verify(signature, msg.as_ref(), &self.0) } fn to_raw_vec(&self) -> Vec { @@ -140,6 +131,26 @@ impl crate::BoundToRuntimeAppPublic for UintAuthorityId { type Public = Self; } +impl traits::IdentifyAccount for UintAuthorityId { + type AccountId = u64; + + fn into_account(self) -> Self::AccountId { + self.0 + } +} + +/// A dummy signature type, to match `UintAuthorityId`. +#[derive(Eq, PartialEq, Clone, Debug, Hash, Serialize, Deserialize, Encode, Decode)] +pub struct TestSignature(pub u64, pub Vec); + +impl traits::Verify for TestSignature { + type Signer = UintAuthorityId; + + fn verify>(&self, mut msg: L, signer: &u64) -> bool { + signer == &self.0 && msg.get() == &self.1[..] + } +} + /// Digest item pub type DigestItem = generic::DigestItem; @@ -332,6 +343,7 @@ impl Checkable for TestXt Result { Ok(self) } } + impl traits::Extrinsic for TestXt { type Call = Call; type SignaturePayload = (u64, Extra); -- GitLab From fa7bd73e6af12220f70a6ad7882582ac31b30ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 21 Apr 2020 16:58:57 +0200 Subject: [PATCH 282/300] Require `fn` token in `decl_storage` `get` (#5717) * Require `fn` token in `decl_storage` `get` The `fn` token was already for quite some time as an optional parameter. It was introduced to make these functions better findable. This pr makes the `fn` token required. * Remove `GetterNoFnkeyword` --- frame/democracy/src/lib.rs | 2 +- frame/offences/src/lib.rs | 2 +- frame/society/src/lib.rs | 10 +++++----- frame/support/procedural/src/storage/parse.rs | 2 +- frame/support/src/lib.rs | 11 ----------- 5 files changed, 8 insertions(+), 19 deletions(-) diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index a76567ba27..34287f9bae 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -346,7 +346,7 @@ decl_storage! { /// Accounts for which there are locks in action which may be removed at some point in the /// future. The value is the block number at which the lock expires and may be removed. - pub Locks get(locks): map hasher(twox_64_concat) T::AccountId => Option; + pub Locks get(fn locks): map hasher(twox_64_concat) T::AccountId => Option; /// True if the last referendum tabled was submitted externally. False if it was a public /// proposal. diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index 2b59c5e796..7fa4cd4132 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -69,7 +69,7 @@ decl_storage! { /// Deferred reports that have been rejected by the offence handler and need to be submitted /// at a later time. - DeferredOffences get(deferred_offences): Vec>; + DeferredOffences get(fn deferred_offences): Vec>; /// A vector of reports of the same kind that happened at the same time slot. ConcurrentReportsIndex: diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index f9908f5d9c..0c02c584ba 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -402,18 +402,18 @@ impl BidKind { decl_storage! { trait Store for Module, I: Instance=DefaultInstance> as Society { /// The first member. - pub Founder get(founder) build(|config: &GenesisConfig| config.members.first().cloned()): + pub Founder get(fn founder) build(|config: &GenesisConfig| config.members.first().cloned()): Option; /// A hash of the rules of this society concerning membership. Can only be set once and /// only by the founder. - pub Rules get(rules): Option; + pub Rules get(fn rules): Option; /// The current set of candidates; bidders that are attempting to become members. - pub Candidates get(candidates): Vec>>; + pub Candidates get(fn candidates): Vec>>; /// The set of suspended candidates. - pub SuspendedCandidates get(suspended_candidate): + pub SuspendedCandidates get(fn suspended_candidate): map hasher(twox_64_concat) T::AccountId => Option<(BalanceOf, BidKind>)>; @@ -421,7 +421,7 @@ decl_storage! { pub Pot get(fn pot) config(): BalanceOf; /// The most primary from the most recently approved members. - pub Head get(head) build(|config: &GenesisConfig| config.members.first().cloned()): + pub Head get(fn head) build(|config: &GenesisConfig| config.members.first().cloned()): Option; /// The current set of members, ordered. diff --git a/frame/support/procedural/src/storage/parse.rs b/frame/support/procedural/src/storage/parse.rs index af568c78cc..beb9beff70 100644 --- a/frame/support/procedural/src/storage/parse.rs +++ b/frame/support/procedural/src/storage/parse.rs @@ -166,7 +166,7 @@ struct DeclStorageLine { #[derive(Parse, ToTokens, Debug)] struct DeclStorageGetterBody { - fn_keyword: Option, + fn_keyword: Token![fn], ident: Ident, } diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 49ad802d07..df987e0b0b 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -271,8 +271,6 @@ mod tests { map hasher(identity) T::BlockNumber => T::BlockNumber; pub GenericData2 get(fn generic_data2): map hasher(blake2_128_concat) T::BlockNumber => Option; - pub GetterNoFnKeyword get(no_fn): Option; - pub DataDM config(test_config) build(|_| vec![(15u32, 16u32, 42u64)]): double_map hasher(twox_64_concat) u32, hasher(blake2_128_concat) u32 => u64; pub GenericDataDM: @@ -558,15 +556,6 @@ mod tests { ), documentation: DecodeDifferent::Encode(&[]), }, - StorageEntryMetadata { - name: DecodeDifferent::Encode("GetterNoFnKeyword"), - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")), - default: DecodeDifferent::Encode( - DefaultByteGetter(&__GetByteStructGetterNoFnKeyword(PhantomData::)) - ), - documentation: DecodeDifferent::Encode(&[]), - }, StorageEntryMetadata { name: DecodeDifferent::Encode("DataDM"), modifier: StorageEntryModifier::Default, -- GitLab From 761d3c8ff210a9138a32a9317d31a798c90e22f9 Mon Sep 17 00:00:00 2001 From: pscott <30843220+pscott@users.noreply.github.com> Date: Wed, 22 Apr 2020 00:35:01 +0200 Subject: [PATCH 283/300] Remove TaskManagerBuilder (#5725) * Remove TaskManagerBuilder * Clean up use declaration fo SpawnTaskHandle Co-Authored-By: Pierre Krieger Co-authored-by: Pierre Krieger --- client/service/src/builder.rs | 54 +++++++------- client/service/src/lib.rs | 4 +- client/service/src/task_manager.rs | 116 ++++++----------------------- 3 files changed, 52 insertions(+), 122 deletions(-) diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 1cdebe8b14..b819c47bee 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use crate::{Service, NetworkStatus, NetworkState, error::Error, DEFAULT_PROTOCOL_ID, MallocSizeOfWasm}; -use crate::{TaskManagerBuilder, start_rpc_servers, build_network_future, TransactionPoolAdapter}; +use crate::{start_rpc_servers, build_network_future, TransactionPoolAdapter, TaskManager}; use crate::status_sinks; use crate::config::{Configuration, KeystoreConfig, PrometheusConfig}; use crate::metrics::MetricsService; @@ -81,7 +81,7 @@ pub struct ServiceBuilder, backend: Arc, - tasks_builder: TaskManagerBuilder, + task_manager: TaskManager, keystore: Arc>, fetcher: Option, select_chain: Option, @@ -145,7 +145,7 @@ type TFullParts = ( TFullClient, Arc>, Arc>, - TaskManagerBuilder, + TaskManager, ); /// Creates a new full client for the given config. @@ -172,9 +172,9 @@ fn new_full_parts( KeystoreConfig::InMemory => Keystore::new_in_memory(), }; - let tasks_builder = { + let task_manager = { let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry); - TaskManagerBuilder::new(registry)? + TaskManager::new(config.task_executor.clone(), registry)? }; let executor = NativeExecutor::::new( @@ -213,12 +213,12 @@ fn new_full_parts( fork_blocks, bad_blocks, extensions, - Box::new(tasks_builder.spawn_handle()), + Box::new(task_manager.spawn_handle()), config.prometheus_config.as_ref().map(|config| config.registry.clone()), )? }; - Ok((client, backend, keystore, tasks_builder)) + Ok((client, backend, keystore, task_manager)) } impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { @@ -238,7 +238,7 @@ impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { (), TFullBackend, >, Error> { - let (client, backend, keystore, tasks_builder) = new_full_parts(&config)?; + let (client, backend, keystore, task_manager) = new_full_parts(&config)?; let client = Arc::new(client); @@ -247,7 +247,7 @@ impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { client, backend, keystore, - tasks_builder, + task_manager, fetcher: None, select_chain: None, import_queue: (), @@ -277,9 +277,9 @@ impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { (), TLightBackend, >, Error> { - let tasks_builder = { + let task_manager = { let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry); - TaskManagerBuilder::new(registry)? + TaskManager::new(config.task_executor.clone(), registry)? }; let keystore = match &config.keystore { @@ -311,7 +311,7 @@ impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { sc_client::light::new_fetch_checker::<_, TBl, _>( light_blockchain.clone(), executor.clone(), - Box::new(tasks_builder.spawn_handle()), + Box::new(task_manager.spawn_handle()), ), ); let fetcher = Arc::new(sc_network::config::OnDemand::new(fetch_checker)); @@ -321,7 +321,7 @@ impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { backend.clone(), config.chain_spec.as_storage_builder(), executor, - Box::new(tasks_builder.spawn_handle()), + Box::new(task_manager.spawn_handle()), config.prometheus_config.as_ref().map(|config| config.registry.clone()), )?); @@ -329,7 +329,7 @@ impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { config, client, backend, - tasks_builder, + task_manager, keystore, fetcher: Some(fetcher.clone()), select_chain: None, @@ -402,7 +402,7 @@ impl config: self.config, client: self.client, backend: self.backend, - tasks_builder: self.tasks_builder, + task_manager: self.task_manager, keystore: self.keystore, fetcher: self.fetcher, select_chain, @@ -445,7 +445,7 @@ impl config: self.config, client: self.client, backend: self.backend, - tasks_builder: self.tasks_builder, + task_manager: self.task_manager, keystore: self.keystore, fetcher: self.fetcher, select_chain: self.select_chain, @@ -483,7 +483,7 @@ impl config: self.config, client: self.client, backend: self.backend, - tasks_builder: self.tasks_builder, + task_manager: self.task_manager, keystore: self.keystore, fetcher: self.fetcher, select_chain: self.select_chain, @@ -545,7 +545,7 @@ impl config: self.config, client: self.client, backend: self.backend, - tasks_builder: self.tasks_builder, + task_manager: self.task_manager, keystore: self.keystore, fetcher: self.fetcher, select_chain: self.select_chain, @@ -606,7 +606,7 @@ impl Ok(ServiceBuilder { config: self.config, client: self.client, - tasks_builder: self.tasks_builder, + task_manager: self.task_manager, backend: self.backend, keystore: self.keystore, fetcher: self.fetcher, @@ -635,7 +635,7 @@ impl config: self.config, client: self.client, backend: self.backend, - tasks_builder: self.tasks_builder, + task_manager: self.task_manager, keystore: self.keystore, fetcher: self.fetcher, select_chain: self.select_chain, @@ -745,7 +745,7 @@ ServiceBuilder< marker: _, mut config, client, - tasks_builder, + task_manager, fetcher: on_demand, backend, keystore, @@ -789,7 +789,7 @@ ServiceBuilder< imports_external_transactions: !matches!(config.role, Role::Light), pool: transaction_pool.clone(), client: client.clone(), - executor: tasks_builder.spawn_handle(), + executor: task_manager.spawn_handle(), }); let protocol_id = { @@ -811,7 +811,7 @@ ServiceBuilder< let network_params = sc_network::config::Params { role: config.role.clone(), executor: { - let spawn_handle = tasks_builder.spawn_handle(); + let spawn_handle = task_manager.spawn_handle(); Some(Box::new(move |fut| { spawn_handle.spawn("libp2p-node", fut); })) @@ -845,7 +845,7 @@ ServiceBuilder< _ => None, }; - let spawn_handle = tasks_builder.spawn_handle(); + let spawn_handle = task_manager.spawn_handle(); // Spawn background tasks which were stacked during the // service building. @@ -857,7 +857,7 @@ ServiceBuilder< // block notifications let txpool = Arc::downgrade(&transaction_pool); let offchain = offchain_workers.as_ref().map(Arc::downgrade); - let notifications_spawn_handle = tasks_builder.spawn_handle(); + let notifications_spawn_handle = task_manager.spawn_handle(); let network_state_info: Arc = network.clone(); let is_validator = config.role.is_authority(); @@ -1013,7 +1013,7 @@ ServiceBuilder< chain_type: chain_spec.chain_type().clone(), }; - let subscriptions = sc_rpc::Subscriptions::new(Arc::new(tasks_builder.spawn_handle())); + let subscriptions = sc_rpc::Subscriptions::new(Arc::new(task_manager.spawn_handle())); let (chain, state, child_state) = if let (Some(remote_backend), Some(on_demand)) = (remote_backend.as_ref(), on_demand.as_ref()) { @@ -1145,7 +1145,7 @@ ServiceBuilder< Ok(Service { client, - task_manager: tasks_builder.into_task_manager(config.task_executor), + task_manager, network, network_status_sinks, select_chain, diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 039e0257ab..56fee6b6d7 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -74,7 +74,7 @@ pub use std::{ops::Deref, result::Result, sync::Arc}; #[doc(hidden)] pub use sc_network::config::{FinalityProofProvider, OnDemand, BoxFinalityProofRequestBuilder}; pub use sc_tracing::TracingReceiver; -pub use task_manager::{TaskManagerBuilder, SpawnTaskHandle}; +pub use task_manager::SpawnTaskHandle; use task_manager::TaskManager; const DEFAULT_PROTOCOL_ID: &str = "sup"; @@ -304,8 +304,6 @@ impl Future for } } - this.task_manager.process_receiver(cx); - // The service future never ends. Poll::Pending } diff --git a/client/service/src/task_manager.rs b/client/service/src/task_manager.rs index fd7fc62ab5..e6847d0881 100644 --- a/client/service/src/task_manager.rs +++ b/client/service/src/task_manager.rs @@ -15,13 +15,12 @@ use std::{ pin::Pin, - result::Result, sync::Arc, - task::{Poll, Context}, + result::Result, sync::Arc }; use exit_future::Signal; -use log::{debug, error}; +use log::{debug}; use futures::{ - Future, FutureExt, Stream, + Future, FutureExt, future::select, compat::*, task::{Spawn, FutureObj, SpawnError}, @@ -32,88 +31,17 @@ use prometheus_endpoint::{ CounterVec, HistogramOpts, HistogramVec, Opts, Registry, U64 }; use sc_client_api::CloneableSpawn; -use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; mod prometheus_future; /// Type alias for service task executor (usually runtime). pub type ServiceTaskExecutor = Arc + Send>>) + Send + Sync>; -/// Type alias for the task scheduler. -pub type TaskScheduler = TracingUnboundedSender + Send>>>; - -/// Helper struct to setup background tasks execution for service. -pub struct TaskManagerBuilder { - /// A future that resolves when the service has exited, this is useful to - /// make sure any internally spawned futures stop when the service does. - on_exit: exit_future::Exit, - /// A signal that makes the exit future above resolve, fired on service drop. - signal: Option, - /// Sender for futures that must be spawned as background tasks. - to_spawn_tx: TaskScheduler, - /// Receiver for futures that must be spawned as background tasks. - to_spawn_rx: TracingUnboundedReceiver + Send>>>, - /// Prometheus metrics where to report the stats about tasks. - metrics: Option, -} - -impl TaskManagerBuilder { - /// New asynchronous task manager setup. - /// - /// If a Prometheus registry is passed, it will be used to report statistics about the - /// service tasks. - pub fn new(prometheus_registry: Option<&Registry>) -> Result { - let (signal, on_exit) = exit_future::signal(); - let (to_spawn_tx, to_spawn_rx) = tracing_unbounded("mpsc_task_manager"); - - let metrics = prometheus_registry.map(Metrics::register).transpose()?; - - Ok(Self { - on_exit, - signal: Some(signal), - to_spawn_tx, - to_spawn_rx, - metrics, - }) - } - - /// Get spawn handle. - /// - /// Tasks spawned through this handle will get scheduled once - /// service is up and running. - pub fn spawn_handle(&self) -> SpawnTaskHandle { - SpawnTaskHandle { - on_exit: self.on_exit.clone(), - sender: self.to_spawn_tx.clone(), - metrics: self.metrics.clone(), - } - } - - /// Convert into actual task manager from initial setup. - pub(crate) fn into_task_manager(self, executor: ServiceTaskExecutor) -> TaskManager { - let TaskManagerBuilder { - on_exit, - signal, - to_spawn_rx, - to_spawn_tx, - metrics, - } = self; - TaskManager { - on_exit, - signal, - to_spawn_tx, - to_spawn_rx, - executor, - metrics, - } - } -} - /// An handle for spawning tasks in the service. #[derive(Clone)] pub struct SpawnTaskHandle { - sender: TaskScheduler, on_exit: exit_future::Exit, + executor: ServiceTaskExecutor, metrics: Option, } @@ -152,9 +80,7 @@ impl SpawnTaskHandle { } }; - if self.sender.unbounded_send(Box::pin(future)).is_err() { - error!("Failed to send task to spawn over channel"); - } + (self.executor)(Box::pin(future)); } } @@ -188,11 +114,6 @@ pub struct TaskManager { on_exit: exit_future::Exit, /// A signal that makes the exit future above resolve, fired on service drop. signal: Option, - /// Sender for futures that must be spawned as background tasks. - to_spawn_tx: TaskScheduler, - /// Receiver for futures that must be spawned as background tasks. - /// Note: please read comment on [`SpawnTaskHandle::spawn`] for why this is a `&'static str`. - to_spawn_rx: TracingUnboundedReceiver + Send>>>, /// How to spawn background tasks. executor: ServiceTaskExecutor, /// Prometheus metric where to report the polling times. @@ -200,6 +121,24 @@ pub struct TaskManager { } impl TaskManager { + /// If a Prometheus registry is passed, it will be used to report statistics about the + /// service tasks. + pub(super) fn new( + executor: ServiceTaskExecutor, + prometheus_registry: Option<&Registry> + ) -> Result { + let (signal, on_exit) = exit_future::signal(); + + let metrics = prometheus_registry.map(Metrics::register).transpose()?; + + Ok(Self { + on_exit, + signal: Some(signal), + executor, + metrics, + }) + } + /// Spawn background/async task, which will be aware on exit signal. /// /// See also the documentation of [`SpawnTaskHandler::spawn`]. @@ -210,18 +149,11 @@ impl TaskManager { pub(super) fn spawn_handle(&self) -> SpawnTaskHandle { SpawnTaskHandle { on_exit: self.on_exit.clone(), - sender: self.to_spawn_tx.clone(), + executor: self.executor.clone(), metrics: self.metrics.clone(), } } - /// Process background task receiver. - pub(super) fn process_receiver(&mut self, cx: &mut Context) { - while let Poll::Ready(Some(task_to_spawn)) = Pin::new(&mut self.to_spawn_rx).poll_next(cx) { - (self.executor)(task_to_spawn); - } - } - /// Clone on exit signal. pub(super) fn on_exit(&self) -> exit_future::Exit { self.on_exit.clone() -- GitLab From b17818775f6038a080390e3a63ea5cb11c50721c Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 22 Apr 2020 00:36:12 +0200 Subject: [PATCH 284/300] Fix warning reported in out_events when Registry is None (#5716) --- client/network/src/service/out_events.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/network/src/service/out_events.rs b/client/network/src/service/out_events.rs index 8f9c138095..2d4d7ded21 100644 --- a/client/network/src/service/out_events.rs +++ b/client/network/src/service/out_events.rs @@ -97,10 +97,10 @@ impl Stream for Receiver { fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { if let Some(ev) = ready!(Pin::new(&mut self.inner).poll_next(cx)) { let metrics = self.metrics.lock().clone(); - if let Some(Some(metrics)) = metrics.as_ref().map(|m| &**m) { - metrics.event_out(&ev, self.name); - } else { - log::warn!("Inconsistency in out_events: event happened before sender associated"); + match metrics.as_ref().map(|m| m.as_ref()) { + Some(Some(metrics)) => metrics.event_out(&ev, self.name), + Some(None) => (), // no registry + None => log::warn!("Inconsistency in out_events: event happened before sender associated"), } Poll::Ready(Some(ev)) } else { -- GitLab From 3a36e511a516644c291f99b1ab9a23d097e65c44 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Wed, 22 Apr 2020 09:20:28 +0200 Subject: [PATCH 285/300] Migrate away from `SimpleDispatchInfo` (#5686) * Migrate away from SimpleDispatchInfo * Fix imports * Better doc * Update lib.rs Co-authored-by: Shawn Tabrizi --- bin/node-template/pallets/template/src/lib.rs | 6 +- frame/assets/src/lib.rs | 8 +- frame/authorship/src/lib.rs | 4 +- frame/benchmark/src/lib.rs | 28 +- frame/benchmarking/src/tests.rs | 6 +- frame/collective/src/lib.rs | 12 +- frame/contracts/src/lib.rs | 12 +- frame/democracy/src/lib.rs | 60 ++-- frame/elections-phragmen/src/lib.rs | 15 +- frame/elections/src/lib.rs | 30 +- frame/evm/src/lib.rs | 5 +- frame/example-offchain-worker/src/lib.rs | 8 +- frame/example/src/lib.rs | 10 +- frame/executive/src/lib.rs | 8 +- frame/finality-tracker/src/lib.rs | 8 +- frame/generic-asset/src/lib.rs | 14 +- frame/grandpa/src/lib.rs | 4 +- frame/identity/src/lib.rs | 24 +- frame/im-online/src/lib.rs | 8 +- frame/indices/src/lib.rs | 10 +- frame/membership/src/lib.rs | 15 +- frame/nicks/src/lib.rs | 9 +- frame/randomness-collective-flip/src/lib.rs | 4 +- frame/recovery/src/lib.rs | 18 +- frame/scored-pool/src/lib.rs | 16 +- frame/session/src/lib.rs | 6 +- frame/society/src/lib.rs | 26 +- frame/staking/src/lib.rs | 54 ++-- frame/sudo/src/lib.rs | 8 +- frame/support/src/dispatch.rs | 37 ++- frame/support/src/error.rs | 4 +- frame/support/src/metadata.rs | 4 +- frame/support/src/weights.rs | 302 +++++++++++------- frame/support/test/tests/decl_error.rs | 6 +- frame/support/test/tests/instance.rs | 4 +- .../tests/reserved_keyword/on_initialize.rs | 4 +- frame/system/src/lib.rs | 24 +- frame/timestamp/src/lib.rs | 8 +- frame/treasury/src/lib.rs | 18 +- frame/vesting/src/lib.rs | 8 +- 40 files changed, 454 insertions(+), 401 deletions(-) diff --git a/bin/node-template/pallets/template/src/lib.rs b/bin/node-template/pallets/template/src/lib.rs index adddbac21b..ad721985b2 100644 --- a/bin/node-template/pallets/template/src/lib.rs +++ b/bin/node-template/pallets/template/src/lib.rs @@ -10,7 +10,7 @@ /// https://github.com/paritytech/substrate/blob/master/frame/example/src/lib.rs use frame_support::{decl_module, decl_storage, decl_event, decl_error, dispatch}; -use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +use frame_support::weights::MINIMUM_WEIGHT; use frame_system::{self as system, ensure_signed}; #[cfg(test)] @@ -76,7 +76,7 @@ decl_module! { /// Just a dummy entry point. /// function that can be called by the external world as an extrinsics call /// takes a parameter of the type `AccountId`, stores it, and emits an event - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn do_something(origin, something: u32) -> dispatch::DispatchResult { // Check it was signed and get the signer. See also: ensure_root and ensure_none let who = ensure_signed(origin)?; @@ -92,7 +92,7 @@ decl_module! { /// Another dummy entry point. /// takes no parameters, attempts to increment storage value, and possibly throws an error - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn cause_error(origin) -> dispatch::DispatchResult { // Check it was signed and get the signer. See also: ensure_root and ensure_none let _who = ensure_signed(origin)?; diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 15726c9bcb..60a9ab87a7 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -133,7 +133,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use frame_support::{Parameter, decl_module, decl_event, decl_storage, decl_error, ensure}; -use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +use frame_support::weights::MINIMUM_WEIGHT; use sp_runtime::traits::{Member, AtLeast32Bit, Zero, StaticLookup}; use frame_system::{self as system, ensure_signed}; use sp_runtime::traits::One; @@ -158,7 +158,7 @@ decl_module! { /// Issue a new class of fungible assets. There are, and will only ever be, `total` /// such assets and they'll all belong to the `origin` initially. It will have an /// identifier `AssetId` instance: this will be specified in the `Issued` event. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn issue(origin, #[compact] total: T::Balance) { let origin = ensure_signed(origin)?; @@ -172,7 +172,7 @@ decl_module! { } /// Move some assets from one holder to another. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn transfer(origin, #[compact] id: T::AssetId, target: ::Source, @@ -191,7 +191,7 @@ decl_module! { } /// Destroy any assets of `id` owned by `origin`. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn destroy(origin, #[compact] id: T::AssetId) { let origin = ensure_signed(origin)?; let balance = >::take((id, &origin)); diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index fac4b7d482..a00bfc139f 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -27,7 +27,7 @@ use frame_support::traits::{FindAuthor, VerifySeal, Get}; use codec::{Encode, Decode}; use frame_system::ensure_none; use sp_runtime::traits::{Header as HeaderT, One, Zero}; -use frame_support::weights::{Weight, MINIMUM_WEIGHT, SimpleDispatchInfo}; +use frame_support::weights::{Weight, MINIMUM_WEIGHT, DispatchClass}; use sp_inherents::{InherentIdentifier, ProvideInherent, InherentData}; use sp_authorship::{INHERENT_IDENTIFIER, UnclesInherentData, InherentError}; @@ -207,7 +207,7 @@ decl_module! { } /// Provide a set of uncles. - #[weight = SimpleDispatchInfo::FixedMandatory(MINIMUM_WEIGHT)] + #[weight = (MINIMUM_WEIGHT, DispatchClass::Mandatory)] fn set_uncles(origin, new_uncles: Vec) -> dispatch::DispatchResult { ensure_none(origin)?; ensure!(new_uncles.len() <= MAX_UNCLES, Error::::TooManyUncles); diff --git a/frame/benchmark/src/lib.rs b/frame/benchmark/src/lib.rs index 24b0e43310..61b6ac9415 100644 --- a/frame/benchmark/src/lib.rs +++ b/frame/benchmark/src/lib.rs @@ -21,7 +21,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use frame_support::{decl_module, decl_storage, decl_event, decl_error}; -use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +use frame_support::weights::MINIMUM_WEIGHT; use frame_support::traits::Currency; use frame_system::{self as system, ensure_signed}; use codec::{Encode, Decode}; @@ -71,7 +71,7 @@ decl_module! { fn deposit_event() = default; /// Do nothing. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn do_nothing(_origin, input: u32) { if input > 0 { return Ok(()); @@ -83,7 +83,7 @@ decl_module! { /// storage database, however, the `repeat` calls will all pull from the /// storage overlay cache. You must consider this when analyzing the /// results of the benchmark. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn read_value(_origin, repeat: u32) { for _ in 0..repeat { MyValue::get(); @@ -91,7 +91,7 @@ decl_module! { } /// Put a value into a storage value. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn put_value(_origin, repeat: u32) { for r in 0..repeat { MyValue::put(r); @@ -103,7 +103,7 @@ decl_module! { /// storage database, however, the `repeat` calls will all pull from the /// storage overlay cache. You must consider this when analyzing the /// results of the benchmark. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn exists_value(_origin, repeat: u32) { for _ in 0..repeat { MyValue::exists(); @@ -111,7 +111,7 @@ decl_module! { } /// Remove a value from storage `repeat` number of times. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn remove_value(_origin, repeat: u32) { for r in 0..repeat { MyMap::remove(r); @@ -119,7 +119,7 @@ decl_module! { } /// Read a value from storage map `repeat` number of times. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn read_map(_origin, repeat: u32) { for r in 0..repeat { MyMap::get(r); @@ -127,7 +127,7 @@ decl_module! { } /// Insert a value into a map. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn insert_map(_origin, repeat: u32) { for r in 0..repeat { MyMap::insert(r, r); @@ -135,7 +135,7 @@ decl_module! { } /// Check is a map contains a value `repeat` number of times. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn contains_key_map(_origin, repeat: u32) { for r in 0..repeat { MyMap::contains_key(r); @@ -143,7 +143,7 @@ decl_module! { } /// Read a value from storage `repeat` number of times. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn remove_prefix(_origin, repeat: u32) { for r in 0..repeat { MyDoubleMap::remove_prefix(r); @@ -151,21 +151,21 @@ decl_module! { } /// Add user to the list. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn add_member_list(origin) { let who = ensure_signed(origin)?; MyMemberList::::mutate(|x| x.push(who)); } /// Append user to the list. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn append_member_list(origin) { let who = ensure_signed(origin)?; MyMemberList::::append(&[who])?; } /// Encode a vector of accounts to bytes. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn encode_accounts(_origin, accounts: Vec) { let bytes = accounts.encode(); @@ -177,7 +177,7 @@ decl_module! { } /// Decode bytes into a vector of accounts. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn decode_accounts(_origin, bytes: Vec) { let accounts: Vec = Decode::decode(&mut bytes.as_slice()).map_err(|_| "Could not decode")?; diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index 4b26ec732d..cb8bb8603f 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -24,7 +24,7 @@ use sp_std::prelude::*; use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::{H256, Header}}; use frame_support::{ dispatch::DispatchResult, - weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, + weights::MINIMUM_WEIGHT, decl_module, decl_storage, impl_outer_origin, assert_ok, assert_err, ensure }; use frame_system::{RawOrigin, ensure_signed, ensure_none}; @@ -37,14 +37,14 @@ decl_storage! { decl_module! { pub struct Module for enum Call where origin: T::Origin { - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn set_value(origin, n: u32) -> DispatchResult { let _sender = ensure_signed(origin)?; Value::put(n); Ok(()) } - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn dummy(origin, _n: u32) -> DispatchResult { let _sender = ensure_none(origin)?; Ok(()) diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index b5626ae4a6..19a9a12b34 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -40,11 +40,11 @@ use sp_std::{prelude::*, result}; use sp_core::u32_trait::Value as U32; use sp_runtime::RuntimeDebug; use sp_runtime::traits::Hash; -use frame_support::weights::SimpleDispatchInfo; use frame_support::{ dispatch::{Dispatchable, Parameter}, codec::{Encode, Decode}, traits::{Get, ChangeMembers, InitializeMembers, EnsureOrigin}, decl_module, decl_event, decl_storage, decl_error, ensure, + weights::DispatchClass, }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -187,7 +187,7 @@ decl_module! { /// - `prime`: The prime member whose vote sets the default. /// /// Requires root origin. - #[weight = SimpleDispatchInfo::FixedOperational(100_000_000)] + #[weight = (100_000_000, DispatchClass::Operational)] fn set_members(origin, new_members: Vec, prime: Option) { ensure_root(origin)?; let mut new_members = new_members; @@ -200,7 +200,7 @@ decl_module! { /// Dispatch a proposal from a member using the `Member` origin. /// /// Origin must be a member of the collective. - #[weight = SimpleDispatchInfo::FixedOperational(100_000_000)] + #[weight = (100_000_000, DispatchClass::Operational)] fn execute(origin, proposal: Box<>::Proposal>) { let who = ensure_signed(origin)?; ensure!(Self::is_member(&who), Error::::NotMember); @@ -214,7 +214,7 @@ decl_module! { /// - Bounded storage reads and writes. /// - Argument `threshold` has bearing on weight. /// # - #[weight = SimpleDispatchInfo::FixedOperational(5_000_000_000)] + #[weight = (5_000_000_000, DispatchClass::Operational)] fn propose(origin, #[compact] threshold: MemberCount, proposal: Box<>::Proposal>) { let who = ensure_signed(origin)?; ensure!(Self::is_member(&who), Error::::NotMember); @@ -244,7 +244,7 @@ decl_module! { /// - Bounded storage read and writes. /// - Will be slightly heavier if the proposal is approved / disapproved after the vote. /// # - #[weight = SimpleDispatchInfo::FixedOperational(200_000_000)] + #[weight = (200_000_000, DispatchClass::Operational)] fn vote(origin, proposal: T::Hash, #[compact] index: ProposalIndex, approve: bool) { let who = ensure_signed(origin)?; ensure!(Self::is_member(&who), Error::::NotMember); @@ -303,7 +303,7 @@ decl_module! { /// - `M` is number of members, /// - `P` is number of active proposals, /// - `L` is the encoded length of `proposal` preimage. - #[weight = SimpleDispatchInfo::FixedOperational(200_000_000)] + #[weight = (200_000_000, DispatchClass::Operational)] fn close(origin, proposal: T::Hash, #[compact] index: ProposalIndex) { let _ = ensure_signed(origin)?; diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 00b23cad19..2513f2fb61 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -123,7 +123,7 @@ use sp_runtime::{ RuntimeDebug, }; use frame_support::dispatch::{DispatchResult, Dispatchable}; -use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +use frame_support::weights::MINIMUM_WEIGHT; use frame_support::{ Parameter, decl_module, decl_event, decl_storage, decl_error, parameter_types, IsSubType, storage::child::{self, ChildInfo}, @@ -539,7 +539,7 @@ decl_module! { /// Updates the schedule for metering contracts. /// /// The schedule must have a greater version than the stored schedule. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn update_schedule(origin, schedule: Schedule) -> DispatchResult { ensure_root(origin)?; if >::current_schedule().version >= schedule.version { @@ -554,7 +554,7 @@ decl_module! { /// Stores the given binary Wasm code into the chain's storage and returns its `codehash`. /// You can instantiate contracts only with stored code. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn put_code( origin, #[compact] gas_limit: Gas, @@ -582,7 +582,7 @@ decl_module! { /// * If the account is a regular account, any value will be transferred. /// * If no account exists and the call value is not less than `existential_deposit`, /// a regular account will be created and any value will be transferred. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn call( origin, dest: ::Source, @@ -608,7 +608,7 @@ decl_module! { /// after the execution is saved as the `code` of the account. That code will be invoked /// upon any call received by this account. /// - The contract is initialized. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn instantiate( origin, #[compact] endowment: BalanceOf, @@ -631,7 +631,7 @@ decl_module! { /// /// If contract is not evicted as a result of this call, no actions are taken and /// the sender is not eligible for the reward. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn claim_surcharge(origin, dest: T::AccountId, aux_sender: Option) { let origin = origin.into(); let (signed, rewarded) = match (origin, aux_sender) { diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index 34287f9bae..91fa625c5c 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -171,7 +171,7 @@ use sp_runtime::{ use codec::{Ref, Encode, Decode}; use frame_support::{ decl_module, decl_storage, decl_event, decl_error, ensure, Parameter, - weights::{SimpleDispatchInfo, Weight, MINIMUM_WEIGHT}, + weights::{Weight, MINIMUM_WEIGHT, DispatchClass}, traits::{ Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, OnUnbalanced, BalanceStatus, schedule::Named as ScheduleNamed, EnsureOrigin @@ -546,7 +546,7 @@ decl_module! { /// - P is the number proposals in the `PublicProps` vec. /// - Two DB changes, one DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000_000)] + #[weight = 5_000_000_000] fn propose(origin, proposal_hash: T::Hash, #[compact] value: BalanceOf @@ -577,7 +577,7 @@ decl_module! { /// - S is the number of seconds a proposal already has. /// - One DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000_000)] + #[weight = 5_000_000_000] fn second(origin, #[compact] proposal: PropIndex) { let who = ensure_signed(origin)?; let mut deposit = Self::deposit_of(proposal) @@ -600,7 +600,7 @@ decl_module! { /// - R is the number of referendums the voter has voted on. /// - One DB change, one DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(200_000_000)] + #[weight = 200_000_000] fn vote(origin, #[compact] ref_index: ReferendumIndex, vote: AccountVote>, @@ -621,7 +621,7 @@ decl_module! { /// - `O(1)`. /// - One DB change, one DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(200_000_000)] + #[weight = 200_000_000] fn proxy_vote(origin, #[compact] ref_index: ReferendumIndex, vote: AccountVote>, @@ -641,7 +641,7 @@ decl_module! { /// # /// - `O(1)`. /// # - #[weight = SimpleDispatchInfo::FixedOperational(500_000_000)] + #[weight = (500_000_000, DispatchClass::Operational)] fn emergency_cancel(origin, ref_index: ReferendumIndex) { T::CancellationOrigin::ensure_origin(origin)?; @@ -664,7 +664,7 @@ decl_module! { /// - `O(1)`. /// - One DB change. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000_000)] + #[weight = 5_000_000_000] fn external_propose(origin, proposal_hash: T::Hash) { T::ExternalOrigin::ensure_origin(origin)?; ensure!(!>::exists(), Error::::DuplicateProposal); @@ -691,7 +691,7 @@ decl_module! { /// - `O(1)`. /// - One DB change. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000_000)] + #[weight = 5_000_000_000] fn external_propose_majority(origin, proposal_hash: T::Hash) { T::ExternalMajorityOrigin::ensure_origin(origin)?; >::put((proposal_hash, VoteThreshold::SimpleMajority)); @@ -711,7 +711,7 @@ decl_module! { /// - `O(1)`. /// - One DB change. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000_000)] + #[weight = 5_000_000_000] fn external_propose_default(origin, proposal_hash: T::Hash) { T::ExternalDefaultOrigin::ensure_origin(origin)?; >::put((proposal_hash, VoteThreshold::SuperMajorityAgainst)); @@ -736,7 +736,7 @@ decl_module! { /// - One DB change. /// - One extra DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(200_000_000)] + #[weight = 200_000_000] fn fast_track(origin, proposal_hash: T::Hash, voting_period: T::BlockNumber, @@ -787,7 +787,7 @@ decl_module! { /// be very large. /// - O(log v), v is number of `existing_vetoers` /// # - #[weight = SimpleDispatchInfo::FixedNormal(200_000_000)] + #[weight = 200_000_000] fn veto_external(origin, proposal_hash: T::Hash) { let who = T::VetoOrigin::ensure_origin(origin)?; @@ -820,7 +820,7 @@ decl_module! { /// # /// - `O(1)`. /// # - #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] + #[weight = (MINIMUM_WEIGHT, DispatchClass::Operational)] fn cancel_referendum(origin, #[compact] ref_index: ReferendumIndex) { ensure_root(origin)?; Self::internal_cancel_referendum(ref_index); @@ -836,7 +836,7 @@ decl_module! { /// - One DB change. /// - O(d) where d is the items in the dispatch queue. /// # - #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] + #[weight = (MINIMUM_WEIGHT, DispatchClass::Operational)] fn cancel_queued(origin, which: ReferendumIndex) { ensure_root(origin)?; T::Scheduler::cancel_named((DEMOCRACY_ID, which)) @@ -862,7 +862,7 @@ decl_module! { /// # /// - One extra DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = 100_000_000] fn activate_proxy(origin, proxy: T::AccountId) { let who = ensure_signed(origin)?; Proxy::::try_mutate(&proxy, |a| match a.take() { @@ -885,7 +885,7 @@ decl_module! { /// # /// - One DB clear. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = 100_000_000] fn close_proxy(origin) { let who = ensure_signed(origin)?; Proxy::::mutate(&who, |a| { @@ -909,7 +909,7 @@ decl_module! { /// # /// - One DB clear. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = 100_000_000] fn deactivate_proxy(origin, proxy: T::AccountId) { let who = ensure_signed(origin)?; Proxy::::try_mutate(&proxy, |a| match a.take() { @@ -942,7 +942,7 @@ decl_module! { /// /// # /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] pub fn delegate(origin, to: T::AccountId, conviction: Conviction, balance: BalanceOf) { let who = ensure_signed(origin)?; Self::try_delegate(who, to, conviction, balance)?; @@ -961,7 +961,7 @@ decl_module! { /// # /// - O(1). /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] fn undelegate(origin) { let who = ensure_signed(origin)?; Self::try_undelegate(who)?; @@ -975,7 +975,7 @@ decl_module! { /// - `O(1)`. /// - One DB clear. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn clear_public_proposals(origin) { ensure_root(origin)?; @@ -995,7 +995,7 @@ decl_module! { /// - Dependent on the size of `encoded_proposal` but protected by a /// required deposit. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = 100_000_000] fn note_preimage(origin, encoded_proposal: Vec) { let who = ensure_signed(origin)?; let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); @@ -1030,7 +1030,7 @@ decl_module! { /// # /// - Dependent on the size of `encoded_proposal` and length of dispatch queue. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = 100_000_000] fn note_imminent_preimage(origin, encoded_proposal: Vec) { let who = ensure_signed(origin)?; let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); @@ -1066,7 +1066,7 @@ decl_module! { /// # /// - One DB clear. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn reap_preimage(origin, proposal_hash: T::Hash) { let who = ensure_signed(origin)?; let (provider, deposit, since, expiry) = >::get(&proposal_hash) @@ -1096,7 +1096,7 @@ decl_module! { /// # /// - `O(1)`. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn unlock(origin, target: T::AccountId) { ensure_signed(origin)?; Self::update_lock(&target); @@ -1115,7 +1115,7 @@ decl_module! { /// # /// - One extra DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = 100_000_000] fn open_proxy(origin, target: T::AccountId) { let who = ensure_signed(origin)?; Proxy::::mutate(&who, |a| { @@ -1154,7 +1154,7 @@ decl_module! { /// # /// - `O(R + log R)` where R is the number of referenda that `target` has voted on. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn remove_vote(origin, index: ReferendumIndex) -> DispatchResult { let who = ensure_signed(origin)?; Self::try_remove_vote(&who, index, UnvoteScope::Any) @@ -1176,7 +1176,7 @@ decl_module! { /// # /// - `O(R + log R)` where R is the number of referenda that `target` has voted on. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn remove_other_vote(origin, target: T::AccountId, index: ReferendumIndex) -> DispatchResult { let who = ensure_signed(origin)?; let scope = if target == who { UnvoteScope::Any } else { UnvoteScope::OnlyExpired }; @@ -1207,7 +1207,7 @@ decl_module! { /// /// # /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] pub fn proxy_delegate(origin, to: T::AccountId, conviction: Conviction, @@ -1231,7 +1231,7 @@ decl_module! { /// # /// - O(1). /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] fn proxy_undelegate(origin) { let who = ensure_signed(origin)?; let target = Self::proxy(who).and_then(|a| a.as_active()).ok_or(Error::::NotProxy)?; @@ -1251,7 +1251,7 @@ decl_module! { /// # /// - `O(R + log R)` where R is the number of referenda that `target` has voted on. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn proxy_remove_vote(origin, index: ReferendumIndex) -> DispatchResult { let who = ensure_signed(origin)?; let target = Self::proxy(who).and_then(|a| a.as_active()).ok_or(Error::::NotProxy)?; @@ -1259,7 +1259,7 @@ decl_module! { } /// Enact a proposal from a referendum. For now we just make the weight be the maximum. - #[weight = SimpleDispatchInfo::MaxNormal] + #[weight = Weight::max_value()] fn enact_proposal(origin, proposal_hash: T::Hash, index: ReferendumIndex) -> DispatchResult { ensure_root(origin)?; Self::do_enact_proposal(proposal_hash, index) diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 610f008457..9247d6f321 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -88,7 +88,8 @@ use sp_runtime::{ }; use frame_support::{ decl_storage, decl_event, ensure, decl_module, decl_error, - weights::{SimpleDispatchInfo, Weight, MINIMUM_WEIGHT}, storage::{StorageMap, IterableStorageMap}, + weights::{Weight, MINIMUM_WEIGHT, DispatchClass}, + storage::{StorageMap, IterableStorageMap}, traits::{ Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons, ChangeMembers, OnUnbalanced, WithdrawReason, Contains, BalanceStatus, InitializeMembers, @@ -291,7 +292,7 @@ decl_module! { /// Reads: O(1) /// Writes: O(V) given `V` votes. V is bounded by 16. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = 100_000_000] fn vote(origin, votes: Vec, #[compact] value: BalanceOf) { let who = ensure_signed(origin)?; @@ -336,7 +337,7 @@ decl_module! { /// Reads: O(1) /// Writes: O(1) /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn remove_voter(origin) { let who = ensure_signed(origin)?; @@ -358,7 +359,7 @@ decl_module! { /// Reads: O(NLogM) given M current candidates and N votes for `target`. /// Writes: O(1) /// # - #[weight = SimpleDispatchInfo::FixedNormal(1_000_000_000)] + #[weight = 1_000_000_000] fn report_defunct_voter(origin, target: ::Source) { let reporter = ensure_signed(origin)?; let target = T::Lookup::lookup(target)?; @@ -401,7 +402,7 @@ decl_module! { /// Reads: O(LogN) Given N candidates. /// Writes: O(1) /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] fn submit_candidacy(origin) { let who = ensure_signed(origin)?; @@ -428,7 +429,7 @@ decl_module! { /// - `origin` is a current member. In this case, the bond is unreserved and origin is /// removed as a member, consequently not being a candidate for the next round anymore. /// Similar to [`remove_voter`], if replacement runners exists, they are immediately used. - #[weight = SimpleDispatchInfo::FixedOperational(2_000_000_000)] + #[weight = (2_000_000_000, DispatchClass::Operational)] fn renounce_candidacy(origin) { let who = ensure_signed(origin)?; @@ -487,7 +488,7 @@ decl_module! { /// Reads: O(do_phragmen) /// Writes: O(do_phragmen) /// # - #[weight = SimpleDispatchInfo::FixedOperational(2_000_000_000)] + #[weight = (2_000_000_000, DispatchClass::Operational)] fn remove_member(origin, who: ::Source) -> DispatchResult { ensure_root(origin)?; let who = T::Lookup::lookup(who)?; diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index a2398ad485..a9166af927 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -30,7 +30,7 @@ use sp_runtime::{ }; use frame_support::{ decl_storage, decl_event, ensure, decl_module, decl_error, - weights::{Weight, MINIMUM_WEIGHT, SimpleDispatchInfo}, + weights::{Weight, MINIMUM_WEIGHT, DispatchClass}, traits::{ Currency, ExistenceRequirement, Get, LockableCurrency, LockIdentifier, BalanceStatus, OnUnbalanced, ReservableCurrency, WithdrawReason, WithdrawReasons, ChangeMembers @@ -405,13 +405,13 @@ decl_module! { /// - Two extra DB entries, one DB change. /// - Argument `votes` is limited in length to number of candidates. /// # - #[weight = SimpleDispatchInfo::FixedNormal(2_500_000_000)] + #[weight = 2_500_000_000] fn set_approvals( origin, votes: Vec, #[compact] index: VoteIndex, hint: SetIndex, - #[compact] value: BalanceOf + #[compact] value: BalanceOf, ) -> DispatchResult { let who = ensure_signed(origin)?; Self::do_set_approvals(who, votes, index, hint, value) @@ -423,12 +423,12 @@ decl_module! { /// # /// - Same as `set_approvals` with one additional storage read. /// # - #[weight = SimpleDispatchInfo::FixedNormal(2_500_000_000)] + #[weight = 2_500_000_000] fn proxy_set_approvals(origin, votes: Vec, #[compact] index: VoteIndex, hint: SetIndex, - #[compact] value: BalanceOf + #[compact] value: BalanceOf, ) -> DispatchResult { let who = Self::proxy(ensure_signed(origin)?).ok_or(Error::::NotProxy)?; Self::do_set_approvals(who, votes, index, hint, value) @@ -446,13 +446,13 @@ decl_module! { /// - O(1). /// - Two fewer DB entries, one DB change. /// # - #[weight = SimpleDispatchInfo::FixedNormal(2_500_000_000)] + #[weight = 2_500_000_000] fn reap_inactive_voter( origin, #[compact] reporter_index: u32, who: ::Source, #[compact] who_index: u32, - #[compact] assumed_vote_index: VoteIndex + #[compact] assumed_vote_index: VoteIndex, ) { let reporter = ensure_signed(origin)?; let who = T::Lookup::lookup(who)?; @@ -520,7 +520,7 @@ decl_module! { /// - O(1). /// - Two fewer DB entries, one DB change. /// # - #[weight = SimpleDispatchInfo::FixedNormal(1_250_000_000)] + #[weight = 1_250_000_000] fn retract_voter(origin, #[compact] index: u32) { let who = ensure_signed(origin)?; @@ -548,7 +548,7 @@ decl_module! { /// - Independent of input. /// - Three DB changes. /// # - #[weight = SimpleDispatchInfo::FixedNormal(2_500_000_000)] + #[weight = 2_500_000_000] fn submit_candidacy(origin, #[compact] slot: u32) { let who = ensure_signed(origin)?; @@ -585,12 +585,12 @@ decl_module! { /// - O(voters) compute. /// - One DB change. /// # - #[weight = SimpleDispatchInfo::FixedNormal(10_000_000_000)] + #[weight = 10_000_000_000] fn present_winner( origin, candidate: ::Source, #[compact] total: BalanceOf, - #[compact] index: VoteIndex + #[compact] index: VoteIndex, ) -> DispatchResult { let who = ensure_signed(origin)?; ensure!( @@ -659,7 +659,7 @@ decl_module! { /// Set the desired member count; if lower than the current count, then seats will not be up /// election when they expire. If more, then a new vote will be started if one is not /// already in progress. - #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] + #[weight = (MINIMUM_WEIGHT, DispatchClass::Operational)] fn set_desired_seats(origin, #[compact] count: u32) { ensure_root(origin)?; DesiredSeats::put(count); @@ -669,7 +669,7 @@ decl_module! { /// /// Note: A tally should happen instantly (if not already in a presentation /// period) to fill the seat if removal means that the desired members are not met. - #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] + #[weight = (MINIMUM_WEIGHT, DispatchClass::Operational)] fn remove_member(origin, who: ::Source) { ensure_root(origin)?; let who = T::Lookup::lookup(who)?; @@ -684,7 +684,7 @@ decl_module! { /// Set the presentation duration. If there is currently a vote being presented for, will /// invoke `finalize_vote`. - #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] + #[weight = (MINIMUM_WEIGHT, DispatchClass::Operational)] fn set_presentation_duration(origin, #[compact] count: T::BlockNumber) { ensure_root(origin)?; >::put(count); @@ -692,7 +692,7 @@ decl_module! { /// Set the presentation duration. If there is current a vote being presented for, will /// invoke `finalize_vote`. - #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] + #[weight = (MINIMUM_WEIGHT, DispatchClass::Operational)] fn set_term_duration(origin, #[compact] count: T::BlockNumber) { ensure_root(origin)?; >::put(count); diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index f67ab767ed..48946858df 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -29,7 +29,6 @@ use frame_support::weights::{Weight, MINIMUM_WEIGHT, DispatchClass, FunctionOf}; use frame_support::traits::{Currency, WithdrawReason, ExistenceRequirement}; use frame_system::{self as system, ensure_signed}; use sp_runtime::ModuleId; -use frame_support::weights::SimpleDispatchInfo; use sp_core::{U256, H256, H160, Hasher}; use sp_runtime::{ DispatchResult, traits::{UniqueSaturatedInto, AccountIdConversion, SaturatedConversion}, @@ -191,7 +190,7 @@ decl_module! { fn deposit_event() = default; /// Deposit balance from currency/balances module into EVM. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn deposit_balance(origin, value: BalanceOf) { let sender = ensure_signed(origin)?; @@ -212,7 +211,7 @@ decl_module! { } /// Withdraw balance from EVM into currency/balances module. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn withdraw_balance(origin, value: BalanceOf) { let sender = ensure_signed(origin)?; let address = T::ConvertAccountId::convert_account_id(&sender); diff --git a/frame/example-offchain-worker/src/lib.rs b/frame/example-offchain-worker/src/lib.rs index d2ebd1159e..9936da8818 100644 --- a/frame/example-offchain-worker/src/lib.rs +++ b/frame/example-offchain-worker/src/lib.rs @@ -53,7 +53,7 @@ use frame_support::{ debug, dispatch::DispatchResult, decl_module, decl_storage, decl_event, traits::Get, - weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, + weights::MINIMUM_WEIGHT, }; use sp_core::crypto::KeyTypeId; use sp_runtime::{ @@ -189,7 +189,7 @@ decl_module! { /// working and receives (and provides) meaningful data. /// This example is not focused on correctness of the oracle itself, but rather its /// purpose is to showcase offchain worker capabilities. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn submit_price(origin, price: u32) -> DispatchResult { // Retrieve sender of the transaction. let who = ensure_signed(origin)?; @@ -214,7 +214,7 @@ decl_module! { /// /// This example is not focused on correctness of the oracle itself, but rather its /// purpose is to showcase offchain worker capabilities. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn submit_price_unsigned(origin, _block_number: T::BlockNumber, price: u32) -> DispatchResult { @@ -228,7 +228,7 @@ decl_module! { Ok(()) } - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + #[weight = MINIMUM_WEIGHT] pub fn submit_price_unsigned_with_signed_payload( origin, price_payload: PricePayload, diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 97cad2856a..e7a5a0c02e 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -256,10 +256,7 @@ use sp_std::marker::PhantomData; use frame_support::{ dispatch::DispatchResult, decl_module, decl_storage, decl_event, - weights::{ - SimpleDispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee, - MINIMUM_WEIGHT, - }, + weights::{DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee, MINIMUM_WEIGHT}, }; use sp_std::prelude::*; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -469,7 +466,7 @@ decl_module! { // weight (a numeric representation of pure execution time and difficulty) of the // transaction and the latter demonstrates the [`DispatchClass`] of the call. A higher // weight means a larger transaction (less of which can be placed in a single block). - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn accumulate_dummy(origin, increase_by: T::Balance) -> DispatchResult { // This is a public call, so we ensure that the origin is some signed account. let _sender = ensure_signed(origin)?; @@ -518,8 +515,7 @@ decl_module! { // The signature could also look like: `fn on_initialize()`. // This function could also very well have a weight annotation, similar to any other. The - // only difference being that if it is not annotated, the default is - // `SimpleDispatchInfo::zero()`, which resolves into no weight. + // only difference is that it mut be returned, not annotated. fn on_initialize(_n: T::BlockNumber) -> Weight { // Anything that needs to be done at the start of the block. // We don't do anything here. diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index f3a4388dcf..52ef068b3e 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -411,22 +411,22 @@ mod tests { use hex_literal::hex; mod custom { - use frame_support::weights::{SimpleDispatchInfo, Weight}; + use frame_support::weights::{Weight, DispatchClass}; pub trait Trait: frame_system::Trait {} frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin { - #[weight = SimpleDispatchInfo::FixedNormal(100)] + #[weight = 100] fn some_function(origin) { // NOTE: does not make any different. let _ = frame_system::ensure_signed(origin); } - #[weight = SimpleDispatchInfo::FixedOperational(200)] + #[weight = (200, DispatchClass::Operational)] fn some_root_operation(origin) { let _ = frame_system::ensure_root(origin); } - #[weight = SimpleDispatchInfo::InsecureFreeNormal] + #[weight = 0] fn some_unsigned_message(origin) { let _ = frame_system::ensure_none(origin); } diff --git a/frame/finality-tracker/src/lib.rs b/frame/finality-tracker/src/lib.rs index 54506784a9..72d4d1c916 100644 --- a/frame/finality-tracker/src/lib.rs +++ b/frame/finality-tracker/src/lib.rs @@ -23,7 +23,7 @@ use sp_runtime::traits::{One, Zero, SaturatedConversion}; use sp_std::{prelude::*, result, cmp, vec}; use frame_support::{decl_module, decl_storage, decl_error, ensure}; use frame_support::traits::Get; -use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +use frame_support::weights::{MINIMUM_WEIGHT, DispatchClass}; use frame_system::{ensure_none, Trait as SystemTrait}; use sp_finality_tracker::{INHERENT_IDENTIFIER, FinalizedInherentData}; @@ -77,7 +77,7 @@ decl_module! { /// Hint that the author of this block thinks the best finalized /// block is the given number. - #[weight = SimpleDispatchInfo::FixedMandatory(MINIMUM_WEIGHT)] + #[weight = (MINIMUM_WEIGHT, DispatchClass::Mandatory)] fn final_hint(origin, #[compact] hint: T::BlockNumber) { ensure_none(origin)?; ensure!(!::Update::exists(), Error::::AlreadyUpdated); @@ -212,7 +212,9 @@ mod tests { traits::{BlakeTwo256, IdentityLookup, Header as HeaderT}, }; use frame_support::{ - assert_ok, impl_outer_origin, parameter_types, weights::Weight, traits::OnFinalize + assert_ok, impl_outer_origin, parameter_types, + weights::Weight, + traits::OnFinalize, }; use frame_system as system; use std::cell::RefCell; diff --git a/frame/generic-asset/src/lib.rs b/frame/generic-asset/src/lib.rs index 720ccd85cc..b56c724336 100644 --- a/frame/generic-asset/src/lib.rs +++ b/frame/generic-asset/src/lib.rs @@ -164,7 +164,7 @@ use sp_std::prelude::*; use sp_std::{cmp, result, fmt::Debug}; use frame_support::{ decl_event, decl_module, decl_storage, ensure, decl_error, - weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, + weights::MINIMUM_WEIGHT, traits::{ Currency, ExistenceRequirement, Imbalance, LockIdentifier, LockableCurrency, ReservableCurrency, SignedImbalance, WithdrawReason, WithdrawReasons, TryDrop, BalanceStatus, @@ -361,14 +361,14 @@ decl_module! { fn deposit_event() = default; /// Create a new kind of asset. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn create(origin, options: AssetOptions) -> DispatchResult { let origin = ensure_signed(origin)?; Self::create_asset(None, Some(origin), options) } /// Transfer some liquid free balance to another account. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn transfer(origin, #[compact] asset_id: T::AssetId, to: T::AccountId, #[compact] amount: T::Balance) { let origin = ensure_signed(origin)?; ensure!(!amount.is_zero(), Error::::ZeroAmount); @@ -378,7 +378,7 @@ decl_module! { /// Updates permission for a given `asset_id` and an account. /// /// The `origin` must have `update` permission. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn update_permission( origin, #[compact] asset_id: T::AssetId, @@ -401,7 +401,7 @@ decl_module! { /// Mints an asset, increases its total issuance. /// The origin must have `mint` permissions. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn mint(origin, #[compact] asset_id: T::AssetId, to: T::AccountId, amount: T::Balance) -> DispatchResult { let who = ensure_signed(origin)?; Self::mint_free(&asset_id, &who, &to, &amount)?; @@ -411,7 +411,7 @@ decl_module! { /// Burns an asset, decreases its total issuance. /// The `origin` must have `burn` permissions. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn burn(origin, #[compact] asset_id: T::AssetId, to: T::AccountId, amount: T::Balance) -> DispatchResult { let who = ensure_signed(origin)?; Self::burn_free(&asset_id, &who, &to, &amount)?; @@ -421,7 +421,7 @@ decl_module! { /// Can be used to create reserved tokens. /// Requires Root call. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn create_reserved( origin, asset_id: T::AssetId, diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index 10cc8162db..49326c71cb 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -33,7 +33,7 @@ pub use sp_finality_grandpa as fg_primitives; use sp_std::prelude::*; use codec::{self as codec, Encode, Decode}; use frame_support::{decl_event, decl_storage, decl_module, decl_error, storage}; -use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +use frame_support::weights::MINIMUM_WEIGHT; use sp_runtime::{ DispatchResult, generic::{DigestItem, OpaqueDigestItemId}, traits::Zero, Perbill, }; @@ -185,7 +185,7 @@ decl_module! { fn deposit_event() = default; /// Report some misbehavior. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn report_misbehavior(origin, _report: Vec) { ensure_signed(origin)?; // FIXME: https://github.com/paritytech/substrate/issues/1112 diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index ddb9bdcce2..31eb93f04b 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -74,7 +74,7 @@ use sp_runtime::traits::{StaticLookup, Zero, AppendZerosInput}; use frame_support::{ decl_module, decl_event, decl_storage, ensure, decl_error, traits::{Currency, ReservableCurrency, OnUnbalanced, Get, BalanceStatus, EnsureOrigin}, - weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, + weights::MINIMUM_WEIGHT, }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -474,7 +474,7 @@ decl_module! { /// - One storage mutation (codec `O(R)`). /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn add_registrar(origin, account: T::AccountId) { T::RegistrarOrigin::try_origin(origin) .map(|_| ()) @@ -506,7 +506,7 @@ decl_module! { /// - One storage mutation (codec-read `O(X' + R)`, codec-write `O(X + R)`). /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn set_identity(origin, info: IdentityInfo) { let sender = ensure_signed(origin)?; let extra_fields = info.additional.len() as u32; @@ -552,7 +552,7 @@ decl_module! { /// - At most O(2 * S + 1) storage mutations; codec complexity `O(1 * S + S * 1)`); /// one storage-exists. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn set_subs(origin, subs: Vec<(T::AccountId, Data)>) { let sender = ensure_signed(origin)?; ensure!(>::contains_key(&sender), Error::::NotFound); @@ -599,7 +599,7 @@ decl_module! { /// - `S + 2` storage deletions. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn clear_identity(origin) { let sender = ensure_signed(origin)?; @@ -638,7 +638,7 @@ decl_module! { /// - Storage: 1 read `O(R)`, 1 mutate `O(X + R)`. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn request_judgement(origin, #[compact] reg_index: RegistrarIndex, #[compact] max_fee: BalanceOf, @@ -684,7 +684,7 @@ decl_module! { /// - One storage mutation `O(R + X)`. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn cancel_request(origin, reg_index: RegistrarIndex) { let sender = ensure_signed(origin)?; let mut id = >::get(&sender).ok_or(Error::::NoIdentity)?; @@ -715,7 +715,7 @@ decl_module! { /// - `O(R)`. /// - One storage mutation `O(R)`. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn set_fee(origin, #[compact] index: RegistrarIndex, #[compact] fee: BalanceOf, @@ -742,7 +742,7 @@ decl_module! { /// - `O(R)`. /// - One storage mutation `O(R)`. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn set_account_id(origin, #[compact] index: RegistrarIndex, new: T::AccountId, @@ -769,7 +769,7 @@ decl_module! { /// - `O(R)`. /// - One storage mutation `O(R)`. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn set_fields(origin, #[compact] index: RegistrarIndex, fields: IdentityFields, @@ -803,7 +803,7 @@ decl_module! { /// - Storage: 1 read `O(R)`, 1 mutate `O(R + X)`. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn provide_judgement(origin, #[compact] reg_index: RegistrarIndex, target: ::Source, @@ -852,7 +852,7 @@ decl_module! { /// - `S + 2` storage mutations. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = 100_000_000] fn kill_identity(origin, target: ::Source) { T::ForceOrigin::try_origin(origin) .map(|_| ()) diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 813b11bbc9..188f705676 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -43,7 +43,7 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; -//! use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +//! use frame_support::weights::MINIMUM_WEIGHT; //! use frame_system::{self as system, ensure_signed}; //! use pallet_im_online::{self as im_online}; //! @@ -51,7 +51,7 @@ //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] +//! #[weight = MINIMUM_WEIGHT] //! pub fn is_online(origin, authority_index: u32) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; //! let _is_online = >::is_online(authority_index); @@ -95,7 +95,7 @@ use sp_staking::{ use frame_support::{ decl_module, decl_event, decl_storage, Parameter, debug, decl_error, traits::Get, - weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, + weights::MINIMUM_WEIGHT, }; use frame_system::{self as system, ensure_none}; use frame_system::offchain::{ @@ -315,7 +315,7 @@ decl_module! { fn deposit_event() = default; - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn heartbeat( origin, heartbeat: Heartbeat, diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index 2a66af7e7f..f4f5b69e8c 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -25,7 +25,7 @@ use sp_runtime::traits::{ StaticLookup, Member, LookupError, Zero, One, BlakeTwo256, Hash, Saturating, AtLeast32Bit }; use frame_support::{Parameter, decl_module, decl_error, decl_event, decl_storage, ensure}; -use frame_support::weights::{Weight, MINIMUM_WEIGHT, SimpleDispatchInfo}; +use frame_support::weights::{Weight, MINIMUM_WEIGHT}; use frame_support::dispatch::DispatchResult; use frame_support::traits::{Currency, ReservableCurrency, Get, BalanceStatus::Reserved}; use frame_support::storage::migration::take_storage_value; @@ -121,7 +121,7 @@ decl_module! { /// - One reserve operation. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn claim(origin, index: T::AccountIndex) { let who = ensure_signed(origin)?; @@ -149,7 +149,7 @@ decl_module! { /// - One transfer operation. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn transfer(origin, new: T::AccountId, index: T::AccountIndex) { let who = ensure_signed(origin)?; ensure!(who != new, Error::::NotTransfer); @@ -180,7 +180,7 @@ decl_module! { /// - One reserve operation. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn free(origin, index: T::AccountIndex) { let who = ensure_signed(origin)?; @@ -209,7 +209,7 @@ decl_module! { /// - Up to one reserve operation. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn force_transfer(origin, new: T::AccountId, index: T::AccountIndex) { ensure_root(origin)?; diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index e968be19a6..188a0b268c 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -26,7 +26,6 @@ use sp_std::prelude::*; use frame_support::{ decl_module, decl_storage, decl_event, decl_error, traits::{ChangeMembers, InitializeMembers, EnsureOrigin}, - weights::SimpleDispatchInfo, }; use frame_system::{self as system, ensure_root, ensure_signed}; @@ -118,7 +117,7 @@ decl_module! { /// Add a member `who` to the set. /// /// May only be called from `AddOrigin` or root. - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn add_member(origin, who: T::AccountId) { T::AddOrigin::try_origin(origin) .map(|_| ()) @@ -137,7 +136,7 @@ decl_module! { /// Remove a member `who` from the set. /// /// May only be called from `RemoveOrigin` or root. - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn remove_member(origin, who: T::AccountId) { T::RemoveOrigin::try_origin(origin) .map(|_| ()) @@ -159,7 +158,7 @@ decl_module! { /// May only be called from `SwapOrigin` or root. /// /// Prime membership is *not* passed from `remove` to `add`, if extant. - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn swap_member(origin, remove: T::AccountId, add: T::AccountId) { T::SwapOrigin::try_origin(origin) .map(|_| ()) @@ -188,7 +187,7 @@ decl_module! { /// pass `members` pre-sorted. /// /// May only be called from `ResetOrigin` or root. - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn reset_members(origin, members: Vec) { T::ResetOrigin::try_origin(origin) .map(|_| ()) @@ -211,7 +210,7 @@ decl_module! { /// May only be called from `Signed` origin of a current member. /// /// Prime membership is passed from the origin account to `new`, if extant. - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn change_key(origin, new: T::AccountId) { let remove = ensure_signed(origin)?; @@ -239,7 +238,7 @@ decl_module! { } /// Set the prime member. Must be a current member. - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn set_prime(origin, who: T::AccountId) { T::PrimeOrigin::try_origin(origin) .map(|_| ()) @@ -250,7 +249,7 @@ decl_module! { } /// Remove the prime member if it exists. - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn clear_prime(origin) { T::PrimeOrigin::try_origin(origin) .map(|_| ()) diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index b8a2359450..97a5074046 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -45,7 +45,6 @@ use sp_runtime::{ use frame_support::{ decl_module, decl_event, decl_storage, ensure, decl_error, traits::{Currency, EnsureOrigin, ReservableCurrency, OnUnbalanced, Get}, - weights::SimpleDispatchInfo, }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -141,7 +140,7 @@ decl_module! { /// - One storage read/write. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn set_name(origin, name: Vec) { let sender = ensure_signed(origin)?; @@ -171,7 +170,7 @@ decl_module! { /// - One storage read/write. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(70_000_000)] + #[weight = 70_000_000] fn clear_name(origin) { let sender = ensure_signed(origin)?; @@ -195,7 +194,7 @@ decl_module! { /// - One storage read/write. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(70_000_000)] + #[weight = 70_000_000] fn kill_name(origin, target: ::Source) { T::ForceOrigin::try_origin(origin) .map(|_| ()) @@ -223,7 +222,7 @@ decl_module! { /// - One storage read/write. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(70_000_000)] + #[weight = 70_000_000] fn force_name(origin, target: ::Source, name: Vec) { T::ForceOrigin::try_origin(origin) .map(|_| ()) diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index cf6dadf7cb..b779a2757b 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -36,13 +36,13 @@ //! ### Example - Get random seed for the current block //! //! ``` -//! use frame_support::{decl_module, dispatch, traits::Randomness, weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}}; +//! use frame_support::{decl_module, dispatch, traits::Randomness, weights::MINIMUM_WEIGHT}; //! //! pub trait Trait: frame_system::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] +//! #[weight = MINIMUM_WEIGHT] //! pub fn random_module_example(origin) -> dispatch::DispatchResult { //! let _random_value = >::random(&b"my context"[..]); //! Ok(()) diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index 9f30061f93..e0397cc1a5 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -159,7 +159,7 @@ use codec::{Encode, Decode}; use frame_support::{ decl_module, decl_event, decl_storage, decl_error, ensure, - Parameter, RuntimeDebug, weights::{MINIMUM_WEIGHT, GetDispatchInfo, SimpleDispatchInfo, FunctionOf}, + Parameter, RuntimeDebug, weights::{MINIMUM_WEIGHT, GetDispatchInfo, FunctionOf}, traits::{Currency, ReservableCurrency, Get, BalanceStatus}, dispatch::PostDispatchInfo, }; @@ -365,7 +365,7 @@ decl_module! { /// - One storage write O(1) /// - One event /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn set_recovered(origin, lost: T::AccountId, rescuer: T::AccountId) { ensure_root(origin)?; // Create the recovery storage item. @@ -400,7 +400,7 @@ decl_module! { /// /// Total Complexity: O(F + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = 100_000_000] fn create_recovery(origin, friends: Vec, threshold: u16, @@ -460,7 +460,7 @@ decl_module! { /// /// Total Complexity: O(F + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = 100_000_000] fn initiate_recovery(origin, account: T::AccountId) { let who = ensure_signed(origin)?; // Check that the account is recoverable @@ -506,7 +506,7 @@ decl_module! { /// /// Total Complexity: O(F + logF + V + logV) /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = 100_000_000] fn vouch_recovery(origin, lost: T::AccountId, rescuer: T::AccountId) { let who = ensure_signed(origin)?; // Get the recovery configuration for the lost account. @@ -545,7 +545,7 @@ decl_module! { /// /// Total Complexity: O(F + V) /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = 100_000_000] fn claim_recovery(origin, account: T::AccountId) { let who = ensure_signed(origin)?; // Get the recovery configuration for the lost account @@ -590,7 +590,7 @@ decl_module! { /// /// Total Complexity: O(V + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(30_000_000)] + #[weight = 30_000_000] fn close_recovery(origin, rescuer: T::AccountId) { let who = ensure_signed(origin)?; // Take the active recovery process started by the rescuer for this account. @@ -622,7 +622,7 @@ decl_module! { /// /// Total Complexity: O(F + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(30_000_000)] + #[weight = 30_000_000] fn remove_recovery(origin) { let who = ensure_signed(origin)?; // Check there are no active recoveries @@ -647,7 +647,7 @@ decl_module! { /// # /// - One storage mutation to check account is recovered by `who`. O(1) /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn cancel_recovered(origin, account: T::AccountId) { let who = ensure_signed(origin)?; // Check `who` is allowed to make a call on behalf of `account` diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index eca877f096..8cbf20af80 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -54,7 +54,7 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; -//! use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +//! use frame_support::weights::MINIMUM_WEIGHT; //! use frame_system::{self as system, ensure_signed}; //! use pallet_scored_pool::{self as scored_pool}; //! @@ -62,7 +62,7 @@ //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] +//! #[weight = MINIMUM_WEIGHT] //! pub fn candidate(origin) -> dispatch::DispatchResult { //! let who = ensure_signed(origin)?; //! @@ -98,7 +98,7 @@ use sp_std::{ use frame_support::{ decl_module, decl_storage, decl_event, ensure, decl_error, traits::{EnsureOrigin, ChangeMembers, InitializeMembers, Currency, Get, ReservableCurrency}, - weights::{Weight, MINIMUM_WEIGHT, SimpleDispatchInfo}, + weights::{Weight, MINIMUM_WEIGHT}, }; use frame_system::{self as system, ensure_root, ensure_signed}; use sp_runtime::{ @@ -267,7 +267,7 @@ decl_module! { /// /// The `index` parameter of this function must be set to /// the index of the transactor in the `Pool`. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn submit_candidacy(origin) { let who = ensure_signed(origin)?; ensure!(!>::contains_key(&who), Error::::AlreadyInPool); @@ -297,7 +297,7 @@ decl_module! { /// /// The `index` parameter of this function must be set to /// the index of the transactor in the `Pool`. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn withdraw_candidacy( origin, index: u32 @@ -317,7 +317,7 @@ decl_module! { /// /// The `index` parameter of this function must be set to /// the index of `dest` in the `Pool`. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn kick( origin, dest: ::Source, @@ -342,7 +342,7 @@ decl_module! { /// /// The `index` parameter of this function must be set to /// the index of the `dest` in the `Pool`. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn score( origin, dest: ::Source, @@ -383,7 +383,7 @@ decl_module! { /// (this happens each `Period`). /// /// May only be called from root. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn change_member_count(origin, count: u32) { ensure_root(origin)?; >::put(&count); diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index f539004189..afab71734e 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -110,7 +110,7 @@ use frame_support::{ Get, FindAuthor, ValidatorRegistration, EstimateNextSessionRotation, EstimateNextNewSession, }, dispatch::{self, DispatchResult, DispatchError}, - weights::{Weight, MINIMUM_WEIGHT, SimpleDispatchInfo}, + weights::{Weight, MINIMUM_WEIGHT}, }; use frame_system::{self as system, ensure_signed}; @@ -498,7 +498,7 @@ decl_module! { /// - Increases system account refs by one on success iff there were previously no keys set. /// In this case, purge_keys will need to be called before the account can be removed. /// # - #[weight = SimpleDispatchInfo::FixedNormal(150_000_000)] + #[weight = 150_000_000] pub fn set_keys(origin, keys: T::Keys, proof: Vec) -> dispatch::DispatchResult { let who = ensure_signed(origin)?; @@ -519,7 +519,7 @@ decl_module! { /// - Removes N + 1 DB entries. /// - Reduces system account refs by one on success. /// # - #[weight = SimpleDispatchInfo::FixedNormal(150_000_000)] + #[weight = 150_000_000] pub fn purge_keys(origin) { let who = ensure_signed(origin)?; Self::do_purge_keys(&who)?; diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index 0c02c584ba..2feaab24b1 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -260,7 +260,7 @@ use sp_runtime::{Percent, ModuleId, RuntimeDebug, } }; use frame_support::{decl_error, decl_module, decl_storage, decl_event, ensure, dispatch::DispatchResult}; -use frame_support::weights::{SimpleDispatchInfo, Weight, MINIMUM_WEIGHT}; +use frame_support::weights::{Weight, MINIMUM_WEIGHT}; use frame_support::traits::{ Currency, ReservableCurrency, Randomness, Get, ChangeMembers, BalanceStatus, ExistenceRequirement::AllowDeath, EnsureOrigin @@ -527,7 +527,7 @@ decl_module! { /// /// Total Complexity: O(M + B + C + logM + logB + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] pub fn bid(origin, value: BalanceOf) -> DispatchResult { let who = ensure_signed(origin)?; ensure!(!>::contains_key(&who), Error::::Suspended); @@ -566,7 +566,7 @@ decl_module! { /// /// Total Complexity: O(B + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(20_000_000)] + #[weight = 20_000_000] pub fn unbid(origin, pos: u32) -> DispatchResult { let who = ensure_signed(origin)?; @@ -636,7 +636,7 @@ decl_module! { /// /// Total Complexity: O(M + B + C + logM + logB + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] pub fn vouch(origin, who: T::AccountId, value: BalanceOf, tip: BalanceOf) -> DispatchResult { let voucher = ensure_signed(origin)?; // Check user is not suspended. @@ -677,7 +677,7 @@ decl_module! { /// /// Total Complexity: O(B) /// # - #[weight = SimpleDispatchInfo::FixedNormal(20_000_000)] + #[weight = 20_000_000] pub fn unvouch(origin, pos: u32) -> DispatchResult { let voucher = ensure_signed(origin)?; ensure!(Self::vouching(&voucher) == Some(VouchingStatus::Vouching), Error::::NotVouching); @@ -715,7 +715,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + C) /// # - #[weight = SimpleDispatchInfo::FixedNormal(30_000_000)] + #[weight = 30_000_000] pub fn vote(origin, candidate: ::Source, approve: bool) { let voter = ensure_signed(origin)?; let candidate = T::Lookup::lookup(candidate)?; @@ -746,7 +746,7 @@ decl_module! { /// /// Total Complexity: O(M + logM) /// # - #[weight = SimpleDispatchInfo::FixedNormal(20_000_000)] + #[weight = 20_000_000] pub fn defender_vote(origin, approve: bool) { let voter = ensure_signed(origin)?; let members = >::get(); @@ -778,7 +778,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + P + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(30_000_000)] + #[weight = 30_000_000] pub fn payout(origin) { let who = ensure_signed(origin)?; @@ -820,7 +820,7 @@ decl_module! { /// /// Total Complexity: O(1) /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn found(origin, founder: T::AccountId, max_members: u32, rules: Vec) { T::FounderSetOrigin::ensure_origin(origin)?; ensure!(!>::exists(), Error::::AlreadyFounded); @@ -847,7 +847,7 @@ decl_module! { /// /// Total Complexity: O(1) /// # - #[weight = SimpleDispatchInfo::FixedNormal(20_000_000)] + #[weight = 20_000_000] fn unfound(origin) { let founder = ensure_signed(origin)?; ensure!(Founder::::get() == Some(founder.clone()), Error::::NotFounder); @@ -889,7 +889,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + B) /// # - #[weight = SimpleDispatchInfo::FixedNormal(30_000_000)] + #[weight = 30_000_000] fn judge_suspended_member(origin, who: T::AccountId, forgive: bool) { T::SuspensionJudgementOrigin::ensure_origin(origin)?; ensure!(>::contains_key(&who), Error::::NotSuspended); @@ -960,7 +960,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + B + X) /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn judge_suspended_candidate(origin, who: T::AccountId, judgement: Judgement) { T::SuspensionJudgementOrigin::ensure_origin(origin)?; if let Some((value, kind)) = >::get(&who) { @@ -1020,7 +1020,7 @@ decl_module! { /// /// Total Complexity: O(1) /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn set_max_members(origin, max: u32) { ensure_root(origin)?; ensure!(max > 1, Error::::MaxMembers); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 25d9a10709..34b6a4f795 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -150,7 +150,7 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; -//! use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +//! use frame_support::weights::MINIMUM_WEIGHT; //! use frame_system::{self as system, ensure_signed}; //! use pallet_staking::{self as staking}; //! @@ -159,7 +159,7 @@ //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { //! /// Reward a validator. -//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] +//! #[weight = MINIMUM_WEIGHT] //! pub fn reward_myself(origin) -> dispatch::DispatchResult { //! let reported = ensure_signed(origin)?; //! >::reward_by_ids(vec![(reported, 10)]); @@ -291,7 +291,7 @@ use sp_std::{ use codec::{HasCompact, Encode, Decode}; use frame_support::{ decl_module, decl_event, decl_storage, ensure, decl_error, debug, - weights::{SimpleDispatchInfo, MINIMUM_WEIGHT, Weight}, + weights::{MINIMUM_WEIGHT, Weight, DispatchClass}, storage::IterableStorageMap, dispatch::{IsSubType, DispatchResult}, traits::{ @@ -1268,7 +1268,7 @@ decl_module! { /// NOTE: Two of the storage writes (`Self::bonded`, `Self::payee`) are _never_ cleaned /// unless the `origin` falls below _existential deposit_ and gets removed as dust. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] pub fn bond(origin, controller: ::Source, #[compact] value: BalanceOf, @@ -1332,7 +1332,7 @@ decl_module! { /// - O(1). /// - One DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] fn bond_extra(origin, #[compact] max_additional: BalanceOf) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let stash = ensure_signed(origin)?; @@ -1378,7 +1378,7 @@ decl_module! { /// `withdraw_unbonded`. /// - One DB entry. /// - #[weight = SimpleDispatchInfo::FixedNormal(400_000_000)] + #[weight = 400_000_000] fn unbond(origin, #[compact] value: BalanceOf) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1426,7 +1426,7 @@ decl_module! { /// - Contains a limited number of reads, yet the size of which could be large based on `ledger`. /// - Writes are limited to the `origin` account key. /// # - #[weight = SimpleDispatchInfo::FixedNormal(400_000_000)] + #[weight = 400_000_000] fn withdraw_unbonded(origin) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1469,7 +1469,7 @@ decl_module! { /// - Contains a limited number of reads. /// - Writes are limited to the `origin` account key. /// # - #[weight = SimpleDispatchInfo::FixedNormal(750_000_000)] + #[weight = 750_000_000] pub fn validate(origin, prefs: ValidatorPrefs) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1492,7 +1492,7 @@ decl_module! { /// which is capped at CompactAssignments::LIMIT. /// - Both the reads and writes follow a similar pattern. /// # - #[weight = SimpleDispatchInfo::FixedNormal(750_000_000)] + #[weight = 750_000_000] pub fn nominate(origin, targets: Vec<::Source>) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1527,7 +1527,7 @@ decl_module! { /// - Contains one read. /// - Writes are limited to the `origin` account key. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] fn chill(origin) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1546,7 +1546,7 @@ decl_module! { /// - Contains a limited number of reads. /// - Writes are limited to the `origin` account key. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] fn set_payee(origin, payee: RewardDestination) { let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; @@ -1565,7 +1565,7 @@ decl_module! { /// - Contains a limited number of reads. /// - Writes are limited to the `origin` account key. /// # - #[weight = SimpleDispatchInfo::FixedNormal(750_000_000)] + #[weight = 750_000_000] fn set_controller(origin, controller: ::Source) { let stash = ensure_signed(origin)?; let old_controller = Self::bonded(&stash).ok_or(Error::::NotStash)?; @@ -1582,7 +1582,7 @@ decl_module! { } /// The ideal number of validators. - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] + #[weight = 5_000_000] fn set_validator_count(origin, #[compact] new: u32) { ensure_root(origin)?; ValidatorCount::put(new); @@ -1593,7 +1593,7 @@ decl_module! { /// # /// - No arguments. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] + #[weight = 5_000_000] fn force_no_eras(origin) { ensure_root(origin)?; ForceEra::put(Forcing::ForceNone); @@ -1605,21 +1605,21 @@ decl_module! { /// # /// - No arguments. /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] + #[weight = 5_000_000] fn force_new_era(origin) { ensure_root(origin)?; ForceEra::put(Forcing::ForceNew); } /// Set the validators who cannot be slashed (if any). - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] + #[weight = 5_000_000] fn set_invulnerables(origin, validators: Vec) { ensure_root(origin)?; >::put(validators); } /// Force a current staker to become completely unstaked, immediately. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn force_unstake(origin, stash: T::AccountId) { ensure_root(origin)?; @@ -1635,7 +1635,7 @@ decl_module! { /// # /// - One storage write /// # - #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] + #[weight = 5_000_000] fn force_new_era_always(origin) { ensure_root(origin)?; ForceEra::put(Forcing::ForceAlways); @@ -1648,7 +1648,7 @@ decl_module! { /// # /// - One storage write. /// # - #[weight = SimpleDispatchInfo::FixedNormal(1_000_000_000)] + #[weight = 1_000_000_000] fn cancel_deferred_slash(origin, era: EraIndex, slash_indices: Vec) { T::SlashCancelOrigin::try_origin(origin) .map(|_| ()) @@ -1699,7 +1699,7 @@ decl_module! { /// maximum number of validators that may be nominated by a single nominator, it is /// bounded only economically (all nominators are required to place a minimum stake). /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] fn payout_nominator(origin, era: EraIndex, validators: Vec<(T::AccountId, u32)>) -> DispatchResult { @@ -1726,7 +1726,7 @@ decl_module! { /// - Time complexity: O(1). /// - Contains a limited number of reads and writes. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] fn payout_validator(origin, era: EraIndex) -> DispatchResult { let ctrl = ensure_signed(origin)?; Self::do_payout_validator(ctrl, era) @@ -1747,7 +1747,7 @@ decl_module! { /// - Time complexity: at most O(MaxNominatorRewardedPerValidator). /// - Contains a limited number of reads and writes. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] fn payout_stakers(origin, validator_stash: T::AccountId, era: EraIndex) -> DispatchResult { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); ensure_signed(origin)?; @@ -1763,7 +1763,7 @@ decl_module! { /// - Time complexity: O(1). Bounded by `MAX_UNLOCKING_CHUNKS`. /// - Storage changes: Can't increase storage, only decrease it. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] fn rebond(origin, #[compact] value: BalanceOf) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1777,7 +1777,7 @@ decl_module! { /// Set history_depth value. /// /// Origin must be root. - #[weight = SimpleDispatchInfo::FixedOperational(500_000_000)] + #[weight = (500_000_000, DispatchClass::Operational)] fn set_history_depth(origin, #[compact] new_history_depth: EraIndex) { ensure_root(origin)?; if let Some(current_era) = Self::current_era() { @@ -1799,7 +1799,7 @@ decl_module! { /// This can be called from any origin. /// /// - `stash`: The stash account to reap. Its balance must be zero. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn reap_stash(_origin, stash: T::AccountId) { ensure!(T::Currency::total_balance(&stash).is_zero(), Error::::FundedTarget); Self::kill_stash(&stash)?; @@ -1880,7 +1880,7 @@ decl_module! { /// /// The weight of this call is 1/10th of the blocks total weight. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000_000)] + #[weight = 100_000_000_000] pub fn submit_election_solution( origin, winners: Vec, @@ -1903,7 +1903,7 @@ decl_module! { /// Note that this must pass the [`ValidateUnsigned`] check which only allows transactions /// from the local node to be included. In other words, only the block author can include a /// transaction in the block. - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000_000)] + #[weight = 100_000_000_000] pub fn submit_election_solution_unsigned( origin, winners: Vec, diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index b8cf9a353f..ce0de2027c 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -52,14 +52,14 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; -//! use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +//! use frame_support::weights::MINIMUM_WEIGHT; //! use frame_system::{self as system, ensure_root}; //! //! pub trait Trait: frame_system::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] +//! #[weight = MINIMUM_WEIGHT] //! pub fn privileged_function(origin) -> dispatch::DispatchResult { //! ensure_root(origin)?; //! @@ -93,7 +93,7 @@ use sp_runtime::traits::{StaticLookup, Dispatchable}; use frame_support::{ Parameter, decl_module, decl_event, decl_storage, decl_error, ensure, }; -use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT, GetDispatchInfo, FunctionOf}; +use frame_support::weights::{MINIMUM_WEIGHT, GetDispatchInfo, FunctionOf}; use frame_system::{self as system, ensure_signed}; pub trait Trait: frame_system::Trait { @@ -151,7 +151,7 @@ decl_module! { /// - Limited storage reads. /// - One DB change. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn set_key(origin, new: ::Source) { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index 31e3efb001..e25efec0a9 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -24,8 +24,8 @@ pub use frame_metadata::{ ModuleConstantMetadata, DefaultByte, DefaultByteGetter, ModuleErrorMetadata, ErrorMetadata }; pub use crate::weights::{ - SimpleDispatchInfo, GetDispatchInfo, DispatchInfo, WeighData, ClassifyDispatch, - TransactionPriority, Weight, PaysFee, PostDispatchInfo, WithPostDispatchInfo, + GetDispatchInfo, DispatchInfo, WeighData, ClassifyDispatch, TransactionPriority, Weight, + PaysFee, PostDispatchInfo, WithPostDispatchInfo, }; pub use sp_runtime::{traits::Dispatchable, DispatchError}; pub use crate::traits::{CallMetadata, GetCallMetadata, GetCallName}; @@ -70,14 +70,14 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; -/// # use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +/// # use frame_support::weights::MINIMUM_WEIGHT; /// # use frame_system::{self as system, Trait, ensure_signed}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { /// /// // Private functions are dispatchable, but not available to other /// // FRAME pallets. -/// #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] +/// #[weight = MINIMUM_WEIGHT] /// fn my_function(origin, var: u64) -> dispatch::DispatchResult { /// // Your implementation /// Ok(()) @@ -85,7 +85,7 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// /// // Public functions are both dispatchable and available to other /// // FRAME pallets. -/// #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] +/// #[weight = MINIMUM_WEIGHT] /// pub fn my_public_function(origin) -> dispatch::DispatchResult { /// // Your implementation /// Ok(()) @@ -113,17 +113,17 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; -/// # use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +/// # use frame_support::weights::MINIMUM_WEIGHT; /// # use frame_system::{self as system, Trait, ensure_signed}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { -/// #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] +/// #[weight = MINIMUM_WEIGHT] /// fn my_long_function(origin) -> dispatch::DispatchResult { /// // Your implementation /// Ok(()) /// } /// -/// #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] +/// #[weight = MINIMUM_WEIGHT] /// fn my_short_function(origin) { /// // Your implementation /// } @@ -149,11 +149,10 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch::{DispatchResultWithPostInfo, WithPostDispatchInfo}; -/// # use frame_support::weights::SimpleDispatchInfo; /// # use frame_system::{self as system, Trait, ensure_signed}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { -/// #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] +/// #[weight = 1_000_000] /// fn my_long_function(origin, do_expensive_calc: bool) -> DispatchResultWithPostInfo { /// ensure_signed(origin).map_err(|e| e.with_weight(100_000))?; /// if do_expensive_calc { @@ -178,11 +177,11 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; -/// # use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +/// # use frame_support::weights::MINIMUM_WEIGHT; /// # use frame_system::{self as system, Trait, ensure_signed, ensure_root}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { -/// #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] +/// #[weight = MINIMUM_WEIGHT] /// fn my_privileged_function(origin) -> dispatch::DispatchResult { /// ensure_root(origin)?; /// // Your implementation @@ -2072,25 +2071,25 @@ mod tests { decl_module! { pub struct Module for enum Call where origin: T::Origin, T::AccountId: From { /// Hi, this is a comment. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn aux_0(_origin) -> DispatchResult { unreachable!() } - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn aux_1(_origin, #[compact] _data: u32,) -> DispatchResult { unreachable!() } - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn aux_2(_origin, _data: i32, _data2: String) -> DispatchResult { unreachable!() } - #[weight = SimpleDispatchInfo::FixedNormal(3)] + #[weight = 3] fn aux_3(_origin) -> DispatchResult { unreachable!() } - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn aux_4(_origin, _data: i32) -> DispatchResult { unreachable!() } - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn aux_5(_origin, _data: i32, #[compact] _data2: u32,) -> DispatchResult { unreachable!() } - #[weight = SimpleDispatchInfo::FixedOperational(5)] + #[weight = (5, DispatchClass::Operational)] fn operational(_origin) { unreachable!() } fn on_initialize(n: T::BlockNumber,) -> Weight { if n.into() == 42 { panic!("on_initialize") } 7 } diff --git a/frame/support/src/error.rs b/frame/support/src/error.rs index 2fdba88156..49f1538798 100644 --- a/frame/support/src/error.rs +++ b/frame/support/src/error.rs @@ -35,7 +35,7 @@ pub use frame_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent}; /// /// ``` /// # use frame_support::{decl_error, decl_module}; -/// # use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +/// # use frame_support::weights::MINIMUM_WEIGHT; /// decl_error! { /// /// Errors that can occur in my module. /// pub enum MyError for Module { @@ -55,7 +55,7 @@ pub use frame_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent}; /// pub struct Module for enum Call where origin: T::Origin { /// type Error = MyError; /// -/// #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] +/// #[weight = MINIMUM_WEIGHT] /// fn do_something(origin) -> frame_support::dispatch::DispatchResult { /// Err(MyError::::YouAreNotCoolEnough.into()) /// } diff --git a/frame/support/src/metadata.rs b/frame/support/src/metadata.rs index 6a3e41b809..88fb1f7420 100644 --- a/frame/support/src/metadata.rs +++ b/frame/support/src/metadata.rs @@ -334,7 +334,7 @@ mod tests { mod event_module { use crate::dispatch::DispatchResult; - use crate::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; + use crate::weights::MINIMUM_WEIGHT; pub trait Trait: super::system::Trait { type Balance; @@ -352,7 +352,7 @@ mod tests { pub struct Module for enum Call where origin: T::Origin { type Error = Error; - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn aux_0(_origin) -> DispatchResult { unreachable!() } } } diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index 79cfa1b397..6cf2047cf6 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -16,29 +16,104 @@ //! # Primitives for transaction weighting. //! -//! All dispatchable functions defined in `decl_module!` must provide two trait implementations: -//! - [`WeightData`]: To determine the weight of the dispatch. -//! - [`ClassifyDispatch`]: To determine the class of the dispatch. See the enum definition for -//! more information on dispatch classes. +//! Every dispatchable function is responsible for providing `#[weight = $x]` attribute. In this +//! snipped, `$x` can be any user provided struct that implements the following traits: //! -//! Every dispatchable function is responsible for providing this data via an optional `#[weight = -//! $x]` attribute. In this snipped, `$x` can be any user provided struct that implements the -//! two aforementioned traits. +//! - [`WeighData`]: the weight amount. +//! - [`ClassifyDispatch`]: class of the dispatch. +//! - [`PaysFee`]: weather this weight should be translated to fee and deducted upon dispatch. //! //! Substrate then bundles then output information of the two traits into [`DispatchInfo`] struct -//! and provides it by implementing the [`GetDispatchInfo`] for all `Call` variants, and opaque -//! extrinsic types. +//! and provides it by implementing the [`GetDispatchInfo`] for all `Call` both inner and outer call +//! types. //! -//! If no `#[weight]` is defined, the macro automatically injects the `Default` implementation of -//! the [`SimpleDispatchInfo`]. +//! Substrate provides two pre-defined ways to annotate weight: //! -//! Note that the decl_module macro _cannot_ enforce this and will simply fail if an invalid struct -//! (something that does not implement `Weighable`) is passed in. +//! ### 1. Fixed values +//! +//! This can only be used when all 3 traits can be resolved statically. You have 3 degrees of +//! configuration: +//! +//! 1. Define only weight, **in which case `ClassifyDispatch` will be `Normal` and `PaysFee` will be +//! `true`**. +//! +//! ``` +//! # use frame_system::{self as system, Trait}; +//! frame_support::decl_module! { +//! pub struct Module for enum Call where origin: T::Origin { +//! #[weight = 1000] +//! fn dispatching(origin) { unimplemented!() } +//! } +//! } +//! # fn main() {} +//! ``` +//! +//! 2. Define weight and class, **in which case `PaysFee` would be `true`**. +//! +//! ``` +//! # use frame_system::{self as system, Trait}; +//! # use frame_support::weights::DispatchClass; +//! frame_support::decl_module! { +//! pub struct Module for enum Call where origin: T::Origin { +//! #[weight = (1000, DispatchClass::Operational)] +//! fn dispatching(origin) { unimplemented!() } +//! } +//! } +//! # fn main() {} +//! ``` +//! +//! 3. Define all 3 parameters. +//! +//! ``` +//! # use frame_system::{self as system, Trait}; +//! # use frame_support::weights::DispatchClass; +//! frame_support::decl_module! { +//! pub struct Module for enum Call where origin: T::Origin { +//! #[weight = (1000, DispatchClass::Operational, false)] +//! fn dispatching(origin) { unimplemented!() } +//! } +//! } +//! # fn main() {} +//! ``` +//! +//! ### 2. Define weights as a function of input arguments using `FunctionOf` tuple struct. This struct works +//! in a similar manner as above. 3 items must be provided and each can be either a fixed value or a +//! function/closure with the same parameters list as the dispatchable function itself, wrapper in a +//! tuple. +//! +//! Using this only makes sense if you want to use a function for at least one of the elements. If +//! all 3 are static values, providing a raw tuple is easier. +//! +//! ``` +//! # use frame_system::{self as system, Trait}; +//! # use frame_support::weights::{DispatchClass, FunctionOf}; +//! frame_support::decl_module! { +//! pub struct Module for enum Call where origin: T::Origin { +//! #[weight = FunctionOf( +//! // weight, function. +//! |args: (&u32, &u64)| *args.0 as u64 + args.1, +//! // class, fixed. +//! DispatchClass::Operational, +//! // pays fee, function. +//! |args: (&u32, &u64)| *args.0 > 1000, +//! )] +//! fn dispatching(origin, a: u32, b: u64) { unimplemented!() } +//! } +//! } +//! # fn main() {} +//! ``` +//! FRAME assumes a weight of `1_000_000_000_000` equals 1 second of compute on a standard machine. +//! +//! Latest machine specification used to benchmark are: +//! - Digital Ocean: ubuntu-s-2vcpu-4gb-ams3-01 +//! - 2x Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz +//! - 4GB RAM +//! - Ubuntu 19.10 (GNU/Linux 5.3.0-18-generic x86_64) +//! - rustc 1.42.0 (b8cedc004 2020-03-09) #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use codec::{Encode, Decode}; -use sp_arithmetic::traits::Bounded; use sp_runtime::{ RuntimeDebug, traits::SignedExtension, @@ -50,9 +125,6 @@ use crate::dispatch::{DispatchErrorWithPostInfo, DispatchError}; pub use sp_runtime::transaction_validity::TransactionPriority; /// Numeric range of a transaction weight. -/// -/// FRAME assumes a weight of `1_000_000_000_000` equals 1 second of compute on a standard -/// machine: (TODO: DEFINE STANDARD MACHINE SPECIFICATIONS) pub type Weight = u64; /// The smallest total weight an extrinsic should have. @@ -81,8 +153,7 @@ pub trait PaysFee { } } -/// A generalized group of dispatch types. This is only distinguishing normal, user-triggered transactions -/// (`Normal`) and anything beyond which serves a higher purpose to the system (`Operational`). +/// A generalized group of dispatch types. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, RuntimeDebug)] @@ -108,41 +179,7 @@ pub enum DispatchClass { impl Default for DispatchClass { fn default() -> Self { - DispatchClass::Normal - } -} - -// Implement traits for raw Weight value -impl WeighData for Weight { - fn weigh_data(&self, _: T) -> Weight { - return *self - } -} - -impl ClassifyDispatch for Weight { - fn classify_dispatch(&self, _: T) -> DispatchClass { - DispatchClass::default() - } -} - -impl PaysFee for Weight { - fn pays_fee(&self, _: T) -> bool { - true - } -} - -impl From for DispatchClass { - fn from(tx: SimpleDispatchInfo) -> Self { - match tx { - SimpleDispatchInfo::FixedOperational(_) => DispatchClass::Operational, - SimpleDispatchInfo::MaxOperational => DispatchClass::Operational, - - SimpleDispatchInfo::FixedNormal(_) => DispatchClass::Normal, - SimpleDispatchInfo::MaxNormal => DispatchClass::Normal, - SimpleDispatchInfo::InsecureFreeNormal => DispatchClass::Normal, - - SimpleDispatchInfo::FixedMandatory(_) => DispatchClass::Mandatory, - } + Self::Normal } } @@ -157,6 +194,15 @@ pub struct DispatchInfo { pub pays_fee: bool, } +/// A `Dispatchable` function (aka transaction) that can carry some static information along with +/// it, using the `#[weight]` attribute. +pub trait GetDispatchInfo { + /// Return a `DispatchInfo`, containing relevant information of this dispatch. + /// + /// This is done independently of its encoded size. + fn get_dispatch_info(&self) -> DispatchInfo; +} + /// Weight information that is only available post dispatch. #[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode)] pub struct PostDispatchInfo { @@ -206,7 +252,7 @@ impl sp_runtime::traits::Printable for PostDispatchInfo { } /// Allows easy conversion from `DispatchError` to `DispatchErrorWithPostInfo` for dispatchables -/// that want to return a custom a posteriori weight on error. +/// that want to return a custom a posterior weight on error. pub trait WithPostDispatchInfo { /// Call this on your modules custom errors type in order to return a custom weight on error. /// @@ -230,86 +276,75 @@ impl WithPostDispatchInfo for T where } } -/// A `Dispatchable` function (aka transaction) that can carry some static information along with -/// it, using the `#[weight]` attribute. -pub trait GetDispatchInfo { - /// Return a `DispatchInfo`, containing relevant information of this dispatch. - /// - /// This is done independently of its encoded size. - fn get_dispatch_info(&self) -> DispatchInfo; +impl WeighData for Weight { + fn weigh_data(&self, _: T) -> Weight { + return *self + } } -/// Default type used with the `#[weight = x]` attribute in a substrate chain. -/// -/// A user may pass in any other type that implements the correct traits. If not, the `Default` -/// implementation of [`SimpleDispatchInfo`] is used. -/// -/// For each generalized group (`Normal` and `Operation`): -/// - A `Fixed` variant means weight fee is charged normally and the weight is the number -/// specified in the inner value of the variant. -/// - A `Free` variant is equal to `::Fixed(0)`. Note that this does not guarantee inclusion. -/// - A `Max` variant is equal to `::Fixed(Weight::max_value())`. -/// -/// As for the generalized groups themselves: -/// - `Normal` variants will be assigned a priority proportional to their weight. They can only -/// consume a portion (defined in the system module) of the maximum block resource limits. -/// - `Operational` variants will be assigned the maximum priority. They can potentially consume -/// the entire block resource limit. -#[derive(Clone, Copy)] -pub enum SimpleDispatchInfo { - /// A normal dispatch with fixed weight. - FixedNormal(Weight), - /// A normal dispatch with the maximum weight. - MaxNormal, - /// A normal dispatch with no weight. Base and bytes fees still need to be paid. - InsecureFreeNormal, - /// An operational dispatch with fixed weight. - FixedOperational(Weight), - /// An operational dispatch with the maximum weight. - MaxOperational, - /// A mandatory dispatch with fixed weight. - /// - /// NOTE: Signed transactions may not (directly) dispatch this kind of a call, so the other - /// attributes concerning transactability (e.g. priority, fee paying) are moot. - FixedMandatory(Weight), +impl ClassifyDispatch for Weight { + fn classify_dispatch(&self, _: T) -> DispatchClass { + DispatchClass::Normal + } } -impl WeighData for SimpleDispatchInfo { +impl PaysFee for Weight { + fn pays_fee(&self, _: T) -> bool { + true + } +} + +impl WeighData for (Weight, DispatchClass, bool) { fn weigh_data(&self, _: T) -> Weight { - match self { - SimpleDispatchInfo::FixedNormal(w) => *w, - SimpleDispatchInfo::MaxNormal => Bounded::max_value(), - SimpleDispatchInfo::InsecureFreeNormal => Bounded::min_value(), - SimpleDispatchInfo::FixedOperational(w) => *w, - SimpleDispatchInfo::MaxOperational => Bounded::max_value(), - SimpleDispatchInfo::FixedMandatory(w) => *w, - } + return self.0 } } -impl ClassifyDispatch for SimpleDispatchInfo { +impl ClassifyDispatch for (Weight, DispatchClass, bool) { fn classify_dispatch(&self, _: T) -> DispatchClass { - DispatchClass::from(*self) + self.1 } } -impl PaysFee for SimpleDispatchInfo { +impl PaysFee for (Weight, DispatchClass, bool) { fn pays_fee(&self, _: T) -> bool { - match self { - SimpleDispatchInfo::FixedNormal(_) => true, - SimpleDispatchInfo::MaxNormal => true, - SimpleDispatchInfo::InsecureFreeNormal => true, - SimpleDispatchInfo::FixedOperational(_) => true, - SimpleDispatchInfo::MaxOperational => true, - SimpleDispatchInfo::FixedMandatory(_) => true, - } + self.2 } } -impl SimpleDispatchInfo { - /// An _additive zero_ variant of SimpleDispatchInfo. - pub fn zero() -> Self { - Self::FixedNormal(0) +impl WeighData for (Weight, DispatchClass) { + fn weigh_data(&self, _: T) -> Weight { + return self.0 + } +} + +impl ClassifyDispatch for (Weight, DispatchClass) { + fn classify_dispatch(&self, _: T) -> DispatchClass { + self.1 + } +} + +impl PaysFee for (Weight, DispatchClass) { + fn pays_fee(&self, _: T) -> bool { + true + } +} + +impl WeighData for (Weight, bool) { + fn weigh_data(&self, _: T) -> Weight { + return self.0 + } +} + +impl ClassifyDispatch for (Weight, bool) { + fn classify_dispatch(&self, _: T) -> DispatchClass { + DispatchClass::Normal + } +} + +impl PaysFee for (Weight, bool) { + fn pays_fee(&self, _: T) -> bool { + self.1 } } @@ -463,8 +498,14 @@ mod tests { decl_module! { pub struct Module for enum Call where origin: T::Origin { // no arguments, fixed weight - #[weight = SimpleDispatchInfo::FixedNormal(1000)] - fn f0(_origin) { unimplemented!(); } + #[weight = 1000] + fn f00(_origin) { unimplemented!(); } + + #[weight = (1000, DispatchClass::Mandatory)] + fn f01(_origin) { unimplemented!(); } + + #[weight = (1000, DispatchClass::Operational, false)] + fn f02(_origin) { unimplemented!(); } // weight = a x 10 + b #[weight = FunctionOf(|args: (&u32, &u32)| (args.0 * 10 + args.1) as Weight, DispatchClass::Normal, true)] @@ -484,7 +525,24 @@ mod tests { #[test] fn weights_are_correct() { - assert_eq!(Call::::f0().get_dispatch_info().weight, 1000); + // #[weight = 1000] + let info = Call::::f00().get_dispatch_info(); + assert_eq!(info.weight, 1000); + assert_eq!(info.class, DispatchClass::Normal); + assert_eq!(info.pays_fee, true); + + // #[weight = (1000, DispatchClass::Mandatory)] + let info = Call::::f01().get_dispatch_info(); + assert_eq!(info.weight, 1000); + assert_eq!(info.class, DispatchClass::Mandatory); + assert_eq!(info.pays_fee, true); + + // #[weight = (1000, DispatchClass::Operational, false)] + let info = Call::::f02().get_dispatch_info(); + assert_eq!(info.weight, 1000); + assert_eq!(info.class, DispatchClass::Operational); + assert_eq!(info.pays_fee, false); + assert_eq!(Call::::f11(10, 20).get_dispatch_info().weight, 120); assert_eq!(Call::::f11(10, 20).get_dispatch_info().class, DispatchClass::Normal); assert_eq!(Call::::f12(10, 20).get_dispatch_info().weight, 0); diff --git a/frame/support/test/tests/decl_error.rs b/frame/support/test/tests/decl_error.rs index cf50b009dd..283e747a9e 100644 --- a/frame/support/test/tests/decl_error.rs +++ b/frame/support/test/tests/decl_error.rs @@ -18,7 +18,7 @@ use sp_runtime::{generic, traits::{BlakeTwo256, Block as _, Verify}, DispatchError}; use sp_core::{H256, sr25519}; -use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +use frame_support::weights::MINIMUM_WEIGHT; mod system; @@ -33,7 +33,7 @@ mod module1 { pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: ::Origin { - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn fail(_origin) -> frame_support::dispatch::DispatchResult { Err(Error::::Something.into()) } @@ -60,7 +60,7 @@ mod module2 { pub struct Module for enum Call where origin: ::Origin { - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] pub fn fail(_origin) -> frame_support::dispatch::DispatchResult { Err(Error::::Something.into()) } diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index 779460ce31..37c13c19a3 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -23,7 +23,7 @@ use frame_support::{ DecodeDifferent, StorageMetadata, StorageEntryModifier, StorageEntryType, DefaultByteGetter, StorageEntryMetadata, StorageHasher, }, - weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, + weights::MINIMUM_WEIGHT, StorageValue, StorageMap, StorageDoubleMap, }; use sp_inherents::{ProvideInherent, InherentData, InherentIdentifier, MakeFatalError}; @@ -56,7 +56,7 @@ mod module1 { fn deposit_event() = default; - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn one(origin) { system::ensure_root(origin)?; Self::deposit_event(RawEvent::AnotherVariant(3)); diff --git a/frame/support/test/tests/reserved_keyword/on_initialize.rs b/frame/support/test/tests/reserved_keyword/on_initialize.rs index 00aac51cab..ef19fee0e6 100644 --- a/frame/support/test/tests/reserved_keyword/on_initialize.rs +++ b/frame/support/test/tests/reserved_keyword/on_initialize.rs @@ -2,7 +2,7 @@ macro_rules! reserved { ($($reserved:ident)*) => { $( mod $reserved { - pub use frame_support::{dispatch, weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}}; + pub use frame_support::{dispatch, weights::MINIMUM_WEIGHT}; pub trait Trait { type Origin; @@ -19,7 +19,7 @@ macro_rules! reserved { frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin { - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn $reserved(_origin) -> dispatch::DispatchResult { unreachable!() } } } diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 49c404c022..115b681adc 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -68,14 +68,14 @@ //! ### Example - Get extrinsic count and parent hash for the current block //! //! ``` -//! use frame_support::{decl_module, dispatch, weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}}; +//! use frame_support::{decl_module, dispatch, weights::MINIMUM_WEIGHT}; //! use frame_system::{self as system, ensure_signed}; //! //! pub trait Trait: system::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] +//! #[weight = MINIMUM_WEIGHT] //! pub fn system_module_example(origin) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; //! let _extrinsic_count = >::extrinsic_count(); @@ -120,7 +120,7 @@ use frame_support::{ Contains, Get, ModuleToIndex, OnNewAccount, OnKilledAccount, IsDeadAccount, Happened, StoredMap, EnsureOrigin, }, - weights::{Weight, MINIMUM_WEIGHT, RuntimeDbWeight, DispatchInfo, PostDispatchInfo, DispatchClass, SimpleDispatchInfo, FunctionOf} + weights::{Weight, MINIMUM_WEIGHT, RuntimeDbWeight, DispatchInfo, PostDispatchInfo, DispatchClass, FunctionOf} }; use codec::{Encode, Decode, FullCodec, EncodeLike}; @@ -485,20 +485,20 @@ decl_module! { } /// Make some on-chain remark. - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn remark(origin, _remark: Vec) { ensure_signed(origin)?; } /// Set the number of pages in the WebAssembly environment's heap. - #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] + #[weight = (MINIMUM_WEIGHT, DispatchClass::Operational)] fn set_heap_pages(origin, pages: u64) { ensure_root(origin)?; storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode()); } /// Set the new runtime code. - #[weight = SimpleDispatchInfo::FixedOperational(200_000_000)] + #[weight = (200_000_000, DispatchClass::Operational)] pub fn set_code(origin, code: Vec) { Self::can_set_code(origin, &code)?; @@ -507,7 +507,7 @@ decl_module! { } /// Set the new runtime code without doing any checks of the given `code`. - #[weight = SimpleDispatchInfo::FixedOperational(200_000_000)] + #[weight = (200_000_000, DispatchClass::Operational)] pub fn set_code_without_checks(origin, code: Vec) { ensure_root(origin)?; storage::unhashed::put_raw(well_known_keys::CODE, &code); @@ -515,7 +515,7 @@ decl_module! { } /// Set the new changes trie configuration. - #[weight = SimpleDispatchInfo::FixedOperational(20_000_000)] + #[weight = (20_000_000, DispatchClass::Operational)] pub fn set_changes_trie_config(origin, changes_trie_config: Option) { ensure_root(origin)?; match changes_trie_config.clone() { @@ -533,7 +533,7 @@ decl_module! { } /// Set some items of storage. - #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] + #[weight = (MINIMUM_WEIGHT, DispatchClass::Operational)] fn set_storage(origin, items: Vec) { ensure_root(origin)?; for i in &items { @@ -542,7 +542,7 @@ decl_module! { } /// Kill some items from storage. - #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] + #[weight = (MINIMUM_WEIGHT, DispatchClass::Operational)] fn kill_storage(origin, keys: Vec) { ensure_root(origin)?; for key in &keys { @@ -551,7 +551,7 @@ decl_module! { } /// Kill all storage items with a key that starts with the given prefix. - #[weight = SimpleDispatchInfo::FixedOperational(MINIMUM_WEIGHT)] + #[weight = (MINIMUM_WEIGHT, DispatchClass::Operational)] fn kill_prefix(origin, prefix: Key) { ensure_root(origin)?; storage::unhashed::kill_prefix(&prefix); @@ -559,7 +559,7 @@ decl_module! { /// Kill the sending account, assuming there are no references outstanding and the composite /// data is equal to its default value. - #[weight = SimpleDispatchInfo::FixedOperational(25_000_000)] + #[weight = (25_000_000, DispatchClass::Operational)] fn suicide(origin) { let who = ensure_signed(origin)?; let account = Account::::get(&who); diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 822848bf7d..cffe172c13 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -62,7 +62,7 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; -//! use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +//! use frame_support::weights::MINIMUM_WEIGHT; //! # use pallet_timestamp as timestamp; //! use frame_system::{self as system, ensure_signed}; //! @@ -70,7 +70,7 @@ //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] +//! #[weight = MINIMUM_WEIGHT] //! pub fn get_time(origin) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; //! let _now = >::get(); @@ -101,7 +101,7 @@ use frame_support::debug; use frame_support::{ Parameter, decl_storage, decl_module, traits::{Time, UnixTime, Get}, - weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}, + weights::{MINIMUM_WEIGHT, DispatchClass}, }; use sp_runtime::{ RuntimeString, @@ -148,7 +148,7 @@ decl_module! { /// `MinimumPeriod`. /// /// The dispatch origin for this call must be `Inherent`. - #[weight = SimpleDispatchInfo::FixedMandatory(MINIMUM_WEIGHT)] + #[weight = (MINIMUM_WEIGHT, DispatchClass::Mandatory)] fn set(origin, #[compact] now: T::Moment) { ensure_none(origin)?; assert!(!::DidUpdate::exists(), "Timestamp must be updated only once in the block"); diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index af39985133..2eb0f25fd0 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -98,7 +98,7 @@ use frame_support::traits::{ use sp_runtime::{Permill, ModuleId, Percent, RuntimeDebug, traits::{ Zero, StaticLookup, AccountIdConversion, Saturating, Hash, BadOrigin }}; -use frame_support::weights::{Weight, MINIMUM_WEIGHT, SimpleDispatchInfo}; +use frame_support::weights::{Weight, MINIMUM_WEIGHT, DispatchClass}; use frame_support::traits::{Contains, EnsureOrigin}; use codec::{Encode, Decode}; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -327,7 +327,7 @@ decl_module! { /// - Limited storage reads. /// - One DB change, one extra DB entry. /// # - #[weight = SimpleDispatchInfo::FixedNormal(500_000_000)] + #[weight = 500_000_000] fn propose_spend( origin, #[compact] value: BalanceOf, @@ -354,7 +354,7 @@ decl_module! { /// - Limited storage reads. /// - One DB clear. /// # - #[weight = SimpleDispatchInfo::FixedOperational(100_000_000)] + #[weight = (100_000_000, DispatchClass::Operational)] fn reject_proposal(origin, #[compact] proposal_id: ProposalIndex) { T::RejectOrigin::try_origin(origin) .map(|_| ()) @@ -376,7 +376,7 @@ decl_module! { /// - Limited storage reads. /// - One DB change. /// # - #[weight = SimpleDispatchInfo::FixedOperational(100_000_000)] + #[weight = (100_000_000, DispatchClass::Operational)] fn approve_proposal(origin, #[compact] proposal_id: ProposalIndex) { T::ApproveOrigin::try_origin(origin) .map(|_| ()) @@ -405,7 +405,7 @@ decl_module! { /// - One storage mutation (codec `O(R)`). /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + #[weight = 100_000_000] fn report_awesome(origin, reason: Vec, who: T::AccountId) { let finder = ensure_signed(origin)?; @@ -447,7 +447,7 @@ decl_module! { /// - Two storage removals (one read, codec `O(T)`). /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn retract_tip(origin, hash: T::Hash) { let who = ensure_signed(origin)?; let tip = Tips::::get(&hash).ok_or(Error::::UnknownTip)?; @@ -479,7 +479,7 @@ decl_module! { /// - Two storage insertions (codecs `O(R)`, `O(T)`), one read `O(1)`. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(150_000_000)] + #[weight = 150_000_000] fn tip_new(origin, reason: Vec, who: T::AccountId, tip_value: BalanceOf) { let tipper = ensure_signed(origin)?; ensure!(T::Tippers::contains(&tipper), BadOrigin); @@ -513,7 +513,7 @@ decl_module! { /// - One storage mutation (codec `O(T)`), one storage read `O(1)`. /// - Up to one event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn tip(origin, hash: T::Hash, tip_value: BalanceOf) { let tipper = ensure_signed(origin)?; ensure!(T::Tippers::contains(&tipper), BadOrigin); @@ -539,7 +539,7 @@ decl_module! { /// - One storage retrieval (codec `O(T)`) and two removals. /// - Up to three balance operations. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000_000)] + #[weight = 50_000_000] fn close_tip(origin, hash: T::Hash) { ensure_signed(origin)?; diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index 85545d92b0..6da92ea15a 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -57,7 +57,7 @@ use frame_support::traits::{ Currency, LockableCurrency, VestingSchedule, WithdrawReason, LockIdentifier, ExistenceRequirement, Get }; -use frame_support::weights::{SimpleDispatchInfo, MINIMUM_WEIGHT}; +use frame_support::weights::MINIMUM_WEIGHT; use frame_system::{self as system, ensure_signed}; mod benchmarking; @@ -194,7 +194,7 @@ decl_module! { /// - One storage read (codec `O(1)`) and up to one removal. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn vest(origin) -> DispatchResult { let who = ensure_signed(origin)?; Self::update_lock(who) @@ -216,7 +216,7 @@ decl_module! { /// - One storage read (codec `O(1)`) and up to one removal. /// - One event. /// # - #[weight = SimpleDispatchInfo::FixedNormal(MINIMUM_WEIGHT)] + #[weight = MINIMUM_WEIGHT] fn vest_other(origin, target: ::Source) -> DispatchResult { ensure_signed(origin)?; Self::update_lock(T::Lookup::lookup(target)?) @@ -236,7 +236,7 @@ decl_module! { /// - Creates a new storage entry, but is protected by a minimum transfer /// amount needed to succeed. /// # - #[weight = SimpleDispatchInfo::FixedNormal(1_000_000_000)] + #[weight = 1_000_000_000] pub fn vested_transfer( origin, target: ::Source, -- GitLab From 932f40db7836ca67dd669a10239060653634f152 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 22 Apr 2020 10:20:52 +0200 Subject: [PATCH 286/300] Send a status message on block announce handshake (#5726) * Send a status message on block announce handshake * Make sure to send the handshake to all handlers --- client/network/src/protocol.rs | 34 +++++++++++++- .../src/protocol/generic_proto/behaviour.rs | 44 ++++++++++++++++++- .../protocol/generic_proto/handler/group.rs | 24 ++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 42084b7ce3..c89aa4cf50 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -303,6 +303,31 @@ impl Default for ProtocolConfig { } } +/// Handshake sent when we open a block announces substream. +#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] +struct BlockAnnouncesHandshake { + /// Roles of the node. + roles: Roles, + /// Best block number. + best_number: NumberFor, + /// Best block hash. + best_hash: B::Hash, + /// Genesis block hash. + genesis_hash: B::Hash, +} + +impl BlockAnnouncesHandshake { + fn build(protocol_config: &ProtocolConfig, chain: &Arc>) -> Self { + let info = chain.info(); + BlockAnnouncesHandshake { + genesis_hash: info.genesis_hash, + roles: protocol_config.roles.into(), + best_number: info.best_number, + best_hash: info.best_hash, + } + } +} + /// Fallback mechanism to use to send a notification if no substream is open. #[derive(Debug, Clone, PartialEq, Eq)] enum Fallback { @@ -369,7 +394,10 @@ impl Protocol { proto.extend(b"/block-announces/1"); proto }); - behaviour.register_notif_protocol(block_announces_protocol.clone(), Vec::new()); + behaviour.register_notif_protocol( + block_announces_protocol.clone(), + BlockAnnouncesHandshake::build(&config, &chain).encode() + ); legacy_equiv_by_name.insert(block_announces_protocol.clone(), Fallback::BlockAnnounce); let protocol = Protocol { @@ -1325,6 +1353,10 @@ impl Protocol { pub fn on_block_imported(&mut self, header: &B::Header, is_best: bool) { if is_best { self.sync.update_chain_info(header); + self.behaviour.set_notif_protocol_handshake( + &self.block_announces_protocol, + BlockAnnouncesHandshake::build(&self.config, &self.context_data.chain).encode() + ); } } diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index 35a8b03d36..3ce98dc11e 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -201,7 +201,21 @@ enum PeerState { } impl PeerState { - /// True if there exists an established connection to tbe peer + /// True if there exists any established connection to the peer. + fn is_connected(&self) -> bool { + match self { + PeerState::Disabled { .. } | + PeerState::DisabledPendingEnable { .. } | + PeerState::Enabled { .. } | + PeerState::PendingRequest { .. } | + PeerState::Requested | + PeerState::Incoming { .. } => true, + PeerState::Poisoned | + PeerState::Banned { .. } => false, + } + } + + /// True if there exists an established connection to the peer /// that is open for custom protocol traffic. fn is_open(&self) -> bool { self.get_open().is_some() @@ -338,6 +352,34 @@ impl GenericProto { self.notif_protocols.push((protocol_name.into(), handshake_msg.into())); } + /// Modifies the handshake of the given notifications protocol. + /// + /// Has no effect if the protocol is unknown. + pub fn set_notif_protocol_handshake( + &mut self, + protocol_name: &[u8], + handshake_message: impl Into> + ) { + let handshake_message = handshake_message.into(); + if let Some(protocol) = self.notif_protocols.iter_mut().find(|(name, _)| name == &protocol_name) { + protocol.1 = handshake_message.clone(); + } else { + return; + } + + // Send an event to all the peers we're connected to, updating the handshake message. + for (peer_id, _) in self.peers.iter().filter(|(_, state)| state.is_connected()) { + self.events.push(NetworkBehaviourAction::NotifyHandler { + peer_id: peer_id.clone(), + handler: NotifyHandler::All, + event: NotifsHandlerIn::UpdateHandshake { + protocol_name: Cow::Owned(protocol_name.to_owned()), + handshake_message: handshake_message.clone(), + }, + }); + } + } + /// Returns the number of discovered nodes that we keep in memory. pub fn num_discovered_peers(&self) -> usize { self.peerset.num_discovered_peers() diff --git a/client/network/src/protocol/generic_proto/handler/group.rs b/client/network/src/protocol/generic_proto/handler/group.rs index 04293c7c9f..0e453a368c 100644 --- a/client/network/src/protocol/generic_proto/handler/group.rs +++ b/client/network/src/protocol/generic_proto/handler/group.rs @@ -161,6 +161,18 @@ pub enum NotifsHandlerIn { message: Vec, }, + /// Modifies the handshake message of a notifications protocol. + UpdateHandshake { + /// Name of the protocol for the message. + /// + /// Must match one of the registered protocols. + protocol_name: Cow<'static, [u8]>, + + /// The new handshake message to send if we open a substream or if the remote opens a + /// substream towards us. + handshake_message: Vec, + }, + /// Sends a notifications message. SendNotification { /// Name of the protocol for the message. @@ -363,6 +375,18 @@ impl ProtocolsHandler for NotifsHandler { }, NotifsHandlerIn::SendLegacy { message } => self.legacy.inject_event(LegacyProtoHandlerIn::SendCustomMessage { message }), + NotifsHandlerIn::UpdateHandshake { protocol_name, handshake_message } => { + for (handler, current_handshake) in &mut self.in_handlers { + if handler.protocol_name() == &*protocol_name { + *current_handshake = handshake_message.clone(); + } + } + for (handler, current_handshake) in &mut self.out_handlers { + if handler.protocol_name() == &*protocol_name { + *current_handshake = handshake_message.clone(); + } + } + } NotifsHandlerIn::SendNotification { message, encoded_fallback_message, protocol_name } => { for (handler, _) in &mut self.out_handlers { if handler.protocol_name() != &protocol_name[..] { -- GitLab From 999f4832e715f20a17fc2a3060bbe2ec88e7dbff Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 22 Apr 2020 10:58:26 +0200 Subject: [PATCH 287/300] Add a protocol that answers finality proofs (#5718) * Add a protocol that answers finality proofs * Fix documentation * Use Toggle --- client/network/build.rs | 1 + client/network/src/behaviour.rs | 6 +- client/network/src/protocol.rs | 5 + .../network/src/protocol/finality_requests.rs | 266 ++++++++++++++++++ .../src/protocol/schema/finality.v1.proto | 19 ++ client/network/src/service.rs | 13 +- 6 files changed, 307 insertions(+), 3 deletions(-) create mode 100644 client/network/src/protocol/finality_requests.rs create mode 100644 client/network/src/protocol/schema/finality.v1.proto diff --git a/client/network/build.rs b/client/network/build.rs index 0fd1f12866..991b1cba5d 100644 --- a/client/network/build.rs +++ b/client/network/build.rs @@ -1,5 +1,6 @@ const PROTOS: &[&str] = &[ "src/protocol/schema/api.v1.proto", + "src/protocol/schema/finality.v1.proto", "src/protocol/schema/light.v1.proto" ]; diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index 880b381e66..14b2245be0 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -25,7 +25,7 @@ use codec::Encode as _; use libp2p::NetworkBehaviour; use libp2p::core::{Multiaddr, PeerId, PublicKey}; use libp2p::kad::record; -use libp2p::swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters}; +use libp2p::swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters, toggle::Toggle}; use log::debug; use sp_consensus::{BlockOrigin, import_queue::{IncomingBlock, Origin}}; use sp_runtime::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId, Justification}; @@ -45,6 +45,8 @@ pub struct Behaviour { discovery: DiscoveryBehaviour, /// Block request handling. block_requests: protocol::BlockRequests, + /// Finality proof request handling. + finality_proof_requests: Toggle>, /// Light client request handling. light_client_handler: protocol::LightClientHandler, @@ -75,6 +77,7 @@ impl Behaviour { user_agent: String, local_public_key: PublicKey, block_requests: protocol::BlockRequests, + finality_proof_requests: Option>, light_client_handler: protocol::LightClientHandler, disco_config: DiscoveryConfig, ) -> Self { @@ -83,6 +86,7 @@ impl Behaviour { debug_info: debug_info::DebugInfoBehaviour::new(user_agent, local_public_key.clone()), discovery: disco_config.finish(), block_requests, + finality_proof_requests: From::from(finality_proof_requests), light_client_handler, events: Vec::new(), role, diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index c89aa4cf50..dca74c8d60 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -62,6 +62,9 @@ use wasm_timer::Instant; pub mod api { pub mod v1 { include!(concat!(env!("OUT_DIR"), "/api.v1.rs")); + pub mod finality { + include!(concat!(env!("OUT_DIR"), "/api.v1.finality.rs")); + } pub mod light { include!(concat!(env!("OUT_DIR"), "/api.v1.light.rs")); } @@ -72,12 +75,14 @@ mod generic_proto; mod util; pub mod block_requests; +pub mod finality_requests; pub mod message; pub mod event; pub mod light_client_handler; pub mod sync; pub use block_requests::BlockRequests; +pub use finality_requests::FinalityProofRequests; pub use light_client_handler::LightClientHandler; pub use generic_proto::LegacyConnectionKillError; diff --git a/client/network/src/protocol/finality_requests.rs b/client/network/src/protocol/finality_requests.rs new file mode 100644 index 0000000000..b12b79f41b --- /dev/null +++ b/client/network/src/protocol/finality_requests.rs @@ -0,0 +1,266 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. +// +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! `NetworkBehaviour` implementation which handles incoming finality proof requests. +//! +//! Every request is coming in on a separate connection substream which gets +//! closed after we have sent the response back. Incoming requests are encoded +//! as protocol buffers (cf. `finality.v1.proto`). + +#![allow(unused)] + +use bytes::Bytes; +use codec::{Encode, Decode}; +use crate::{ + chain::FinalityProofProvider, + config::ProtocolId, + protocol::{api, message::BlockAttributes} +}; +use futures::{future::BoxFuture, prelude::*, stream::FuturesUnordered}; +use libp2p::{ + core::{ + ConnectedPoint, + Multiaddr, + PeerId, + connection::ConnectionId, + upgrade::{InboundUpgrade, ReadOneError, UpgradeInfo, Negotiated}, + upgrade::{DeniedUpgrade, read_one, write_one} + }, + swarm::{ + NegotiatedSubstream, + NetworkBehaviour, + NetworkBehaviourAction, + OneShotHandler, + OneShotHandlerConfig, + PollParameters, + SubstreamProtocol + } +}; +use prost::Message; +use sp_runtime::{generic::BlockId, traits::{Block, Header, One, Zero}}; +use std::{ + cmp::min, + io, + iter, + sync::Arc, + time::Duration, + task::{Context, Poll} +}; +use void::{Void, unreachable}; + +// Type alias for convenience. +pub type Error = Box; + +/// Configuration options for `FinalityProofRequests`. +#[derive(Debug, Clone)] +pub struct Config { + max_request_len: usize, + inactivity_timeout: Duration, + protocol: Bytes, +} + +impl Config { + /// Create a fresh configuration with the following options: + /// + /// - max. request size = 1 MiB + /// - inactivity timeout = 15s + pub fn new(id: &ProtocolId) -> Self { + let mut c = Config { + max_request_len: 1024 * 1024, + inactivity_timeout: Duration::from_secs(15), + protocol: Bytes::new(), + }; + c.set_protocol(id); + c + } + + /// Limit the max. length of incoming finality proof request bytes. + pub fn set_max_request_len(&mut self, v: usize) -> &mut Self { + self.max_request_len = v; + self + } + + /// Limit the max. duration the substream may remain inactive before closing it. + pub fn set_inactivity_timeout(&mut self, v: Duration) -> &mut Self { + self.inactivity_timeout = v; + self + } + + /// Set protocol to use for upgrade negotiation. + pub fn set_protocol(&mut self, id: &ProtocolId) -> &mut Self { + let mut v = Vec::new(); + v.extend_from_slice(b"/"); + v.extend_from_slice(id.as_bytes()); + v.extend_from_slice(b"/finality-proof/1"); + self.protocol = v.into(); + self + } +} + +/// The finality proof request handling behaviour. +pub struct FinalityProofRequests { + /// This behaviour's configuration. + config: Config, + /// How to construct finality proofs. + finality_proof_provider: Arc>, + /// Futures sending back the finality proof request responses. + outgoing: FuturesUnordered>, +} + +impl FinalityProofRequests +where + B: Block, +{ + /// Initializes the behaviour. + pub fn new(cfg: Config, finality_proof_provider: Arc>) -> Self { + FinalityProofRequests { + config: cfg, + finality_proof_provider, + outgoing: FuturesUnordered::new(), + } + } + + /// Callback, invoked when a new finality request has been received from remote. + fn on_finality_request(&mut self, peer: &PeerId, request: &api::v1::finality::FinalityProofRequest) + -> Result + { + let block_hash = Decode::decode(&mut request.block_hash.as_ref())?; + + log::trace!(target: "sync", "Finality proof request from {} for {}", peer, block_hash); + + let finality_proof = self.finality_proof_provider + .prove_finality(block_hash, &request.request)? + .unwrap_or(Vec::new()); + // Note that an empty Vec is sent if no proof is available. + + Ok(api::v1::finality::FinalityProofResponse { proof: finality_proof }) + } +} + +impl NetworkBehaviour for FinalityProofRequests +where + B: Block +{ + type ProtocolsHandler = OneShotHandler>; + type OutEvent = Void; + + fn new_handler(&mut self) -> Self::ProtocolsHandler { + let p = Protocol { + max_request_len: self.config.max_request_len, + protocol: self.config.protocol.clone(), + }; + let mut cfg = OneShotHandlerConfig::default(); + cfg.inactive_timeout = self.config.inactivity_timeout; + OneShotHandler::new(SubstreamProtocol::new(p), cfg) + } + + fn addresses_of_peer(&mut self, _: &PeerId) -> Vec { + Vec::new() + } + + fn inject_connected(&mut self, _peer: &PeerId) { + } + + fn inject_disconnected(&mut self, _peer: &PeerId) { + } + + fn inject_event( + &mut self, + peer: PeerId, + connection: ConnectionId, + Request(request, mut stream): Request + ) { + match self.on_finality_request(&peer, &request) { + Ok(res) => { + log::trace!("enqueueing finality response for peer {}", peer); + let mut data = Vec::with_capacity(res.encoded_len()); + if let Err(e) = res.encode(&mut data) { + log::debug!("error encoding finality response for peer {}: {}", peer, e) + } else { + let future = async move { + if let Err(e) = write_one(&mut stream, data).await { + log::debug!("error writing finality response: {}", e) + } + }; + self.outgoing.push(future.boxed()) + } + } + Err(e) => log::debug!("error handling finality request from peer {}: {}", peer, e) + } + } + + fn poll(&mut self, cx: &mut Context, _: &mut impl PollParameters) -> Poll> { + while let Poll::Ready(Some(_)) = self.outgoing.poll_next_unpin(cx) {} + Poll::Pending + } +} + +/// The incoming finality proof request. +/// +/// Holds the protobuf value and the connection substream which made the +/// request and over which to send the response. +#[derive(Debug)] +pub struct Request(api::v1::finality::FinalityProofRequest, T); + +impl From for Request { + fn from(v: Void) -> Self { + unreachable(v) + } +} + +/// Substream upgrade protocol. +/// +/// We attempt to parse an incoming protobuf encoded request (cf. `Request`) +/// which will be handled by the `FinalityProofRequests` behaviour, i.e. the request +/// will become visible via `inject_node_event` which then dispatches to the +/// relevant callback to process the message and prepare a response. +#[derive(Debug, Clone)] +pub struct Protocol { + /// The max. request length in bytes. + max_request_len: usize, + /// The protocol to use during upgrade negotiation. + protocol: Bytes, +} + +impl UpgradeInfo for Protocol { + type Info = Bytes; + type InfoIter = iter::Once; + + fn protocol_info(&self) -> Self::InfoIter { + iter::once(self.protocol.clone()) + } +} + +impl InboundUpgrade for Protocol +where + T: AsyncRead + AsyncWrite + Unpin + Send + 'static +{ + type Output = Request; + type Error = ReadOneError; + type Future = BoxFuture<'static, Result>; + + fn upgrade_inbound(self, mut s: T, _: Self::Info) -> Self::Future { + async move { + let len = self.max_request_len; + let vec = read_one(&mut s, len).await?; + match api::v1::finality::FinalityProofRequest::decode(&vec[..]) { + Ok(r) => Ok(Request(r, s)), + Err(e) => Err(ReadOneError::Io(io::Error::new(io::ErrorKind::Other, e))) + } + }.boxed() + } +} + diff --git a/client/network/src/protocol/schema/finality.v1.proto b/client/network/src/protocol/schema/finality.v1.proto new file mode 100644 index 0000000000..843bc4eca0 --- /dev/null +++ b/client/network/src/protocol/schema/finality.v1.proto @@ -0,0 +1,19 @@ +// Schema definition for finality proof request/responses. + +syntax = "proto3"; + +package api.v1.finality; + +// Request a finality proof from a peer. +message FinalityProofRequest { + // SCALE-encoded hash of the block to request. + bytes block_hash = 1; + // Opaque chain-specific additional request data. + bytes request = 2; +} + +// Response to a finality proof request. +message FinalityProofResponse { + // Opaque chain-specific finality proof. Empty if no such proof exists. + bytes proof = 1; // optional +} diff --git a/client/network/src/service.rs b/client/network/src/service.rs index d29cb94ee8..e360a8defe 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -225,6 +225,12 @@ impl NetworkWorker { let config = protocol::block_requests::Config::new(¶ms.protocol_id); protocol::BlockRequests::new(config, params.chain.clone()) }; + let finality_proof_requests = if let Some(pb) = ¶ms.finality_proof_provider { + let config = protocol::finality_requests::Config::new(¶ms.protocol_id); + Some(protocol::FinalityProofRequests::new(config, pb.clone())) + } else { + None + }; let light_client_handler = { let config = protocol::light_client_handler::Config::new(¶ms.protocol_id); protocol::LightClientHandler::new( @@ -261,6 +267,7 @@ impl NetworkWorker { user_agent, local_public, block_requests, + finality_proof_requests, light_client_handler, discovery_config ); @@ -1113,10 +1120,12 @@ impl Future for NetworkWorker { ConnectionError::IO(_) => metrics.connections_closed_total.with_label_values(&[dir, "transport-error"]).inc(), ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( - EitherError::A(EitherError::B(EitherError::A(PingFailure::Timeout))))))) => + EitherError::A(EitherError::A(EitherError::B( + EitherError::A(PingFailure::Timeout)))))))) => metrics.connections_closed_total.with_label_values(&[dir, "ping-timeout"]).inc(), ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( - EitherError::A(EitherError::A(EitherError::B(LegacyConnectionKillError))))))) => + EitherError::A(EitherError::A(EitherError::A( + EitherError::B(LegacyConnectionKillError)))))))) => metrics.connections_closed_total.with_label_values(&[dir, "force-closed"]).inc(), ConnectionError::Handler(NodeHandlerWrapperError::Handler(_)) => metrics.connections_closed_total.with_label_values(&[dir, "protocol-error"]).inc(), -- GitLab From e60eb97ffce144778ff36da8db99da63fa69cef3 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 22 Apr 2020 14:31:05 +0200 Subject: [PATCH 288/300] Enable yamux flow control by default (#5734) * Enable yamux flow control by default * Tweak description * Apply suggestions from code review --- client/cli/src/params/network_params.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/client/cli/src/params/network_params.rs b/client/cli/src/params/network_params.rs index 635fc51cfd..c08a9e1c93 100644 --- a/client/cli/src/params/network_params.rs +++ b/client/cli/src/params/network_params.rs @@ -85,9 +85,10 @@ pub struct NetworkParams { #[structopt(flatten)] pub node_key_params: NodeKeyParams, - /// Experimental feature flag. - #[structopt(long = "use-yamux-flow-control")] - pub use_yamux_flow_control: bool, + /// Disable the yamux flow control. This option will be removed in the future once there is + /// enough confidence that this feature is properly working. + #[structopt(long)] + pub no_yamux_flow_control: bool, } impl NetworkParams { @@ -137,7 +138,7 @@ impl NetworkParams { enable_mdns: !is_dev && !self.no_mdns, allow_private_ipv4: !self.no_private_ipv4, wasm_external_transport: None, - use_yamux_flow_control: self.use_yamux_flow_control, + use_yamux_flow_control: !self.no_yamux_flow_control, }, max_parallel_downloads: self.max_parallel_downloads, } -- GitLab From 8bcc42c2cafdc3eb9a5c9296846134e7f9f2e9b9 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Wed, 22 Apr 2020 15:50:25 +0200 Subject: [PATCH 289/300] enum Pays for PaysFee (#5733) * enum Pays for PaysFee * Fix doc test * Update bin/node/executor/tests/basic.rs * Update bin/node/executor/tests/basic.rs --- bin/node/executor/tests/basic.rs | 12 +-- frame/balances/src/tests.rs | 2 +- frame/contracts/src/tests.rs | 4 +- frame/evm/src/lib.rs | 23 +++++- frame/example/src/lib.rs | 6 +- frame/recovery/src/lib.rs | 4 +- frame/scheduler/src/lib.rs | 4 +- frame/sudo/src/lib.rs | 6 +- frame/support/src/dispatch.rs | 6 +- frame/support/src/weights.rs | 108 ++++++++++++++++++--------- frame/system/src/lib.rs | 23 ++++-- frame/transaction-payment/src/lib.rs | 25 ++++--- frame/utility/src/lib.rs | 12 +-- 13 files changed, 148 insertions(+), 87 deletions(-) diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index 5b3d8f20e9..758ea1a32e 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -18,7 +18,7 @@ use codec::{Encode, Decode, Joiner}; use frame_support::{ StorageValue, StorageMap, traits::Currency, - weights::{GetDispatchInfo, DispatchInfo, DispatchClass}, + weights::{GetDispatchInfo, DispatchInfo, DispatchClass, Pays}, }; use sp_core::{ NeverNativeValue, map, traits::Externalities, storage::{well_known_keys, Storage}, @@ -338,7 +338,7 @@ fn full_native_block_import_works() { EventRecord { phase: Phase::ApplyExtrinsic(0), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 10_000_000, class: DispatchClass::Mandatory, pays_fee: true } + DispatchInfo { weight: 10_000_000, class: DispatchClass::Mandatory, ..Default::default() } )), topics: vec![], }, @@ -359,7 +359,7 @@ fn full_native_block_import_works() { EventRecord { phase: Phase::ApplyExtrinsic(1), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 200_000_000, class: DispatchClass::Normal, pays_fee: true } + DispatchInfo { weight: 200_000_000, ..Default::default() } )), topics: vec![], }, @@ -391,7 +391,7 @@ fn full_native_block_import_works() { EventRecord { phase: Phase::ApplyExtrinsic(0), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 10_000_000, class: DispatchClass::Mandatory, pays_fee: true } + DispatchInfo { weight: 10_000_000, class: DispatchClass::Mandatory, pays_fee: Pays::Yes } )), topics: vec![], }, @@ -414,7 +414,7 @@ fn full_native_block_import_works() { EventRecord { phase: Phase::ApplyExtrinsic(1), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 200_000_000, class: DispatchClass::Normal, pays_fee: true } + DispatchInfo { weight: 200_000_000, ..Default::default() } )), topics: vec![], }, @@ -437,7 +437,7 @@ fn full_native_block_import_works() { EventRecord { phase: Phase::ApplyExtrinsic(2), event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 200_000_000, class: DispatchClass::Normal, pays_fee: true } + DispatchInfo { weight: 200_000_000, ..Default::default() } )), topics: vec![], }, diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index 7ff7ec0fc4..7663b8922b 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -57,7 +57,7 @@ macro_rules! decl_tests { /// create a transaction info struct from weight. Handy to avoid building the whole struct. pub fn info_from_weight(w: Weight) -> DispatchInfo { - DispatchInfo { weight: w, pays_fee: true, ..Default::default() } + DispatchInfo { weight: w, ..Default::default() } } #[test] diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index f7170e9172..452a4517db 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -35,7 +35,7 @@ use sp_runtime::{ use frame_support::{ assert_ok, assert_err, impl_outer_dispatch, impl_outer_event, impl_outer_origin, parameter_types, storage::child, StorageMap, StorageValue, traits::{Currency, Get}, - weights::{DispatchInfo, DispatchClass, Weight}, + weights::{DispatchInfo, DispatchClass, Weight, Pays}, }; use std::{cell::RefCell, sync::atomic::{AtomicUsize, Ordering}}; use sp_core::storage::well_known_keys; @@ -1630,7 +1630,7 @@ fn cannot_self_destruct_in_constructor() { #[test] fn check_block_gas_limit_works() { ExtBuilder::default().block_gas_limit(50).build().execute_with(|| { - let info = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: true }; + let info = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes }; let check = CheckBlockGasLimit::(Default::default()); let call: Call = crate::Call::put_code(1000, vec![]).into(); diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 48946858df..eec8bc69d7 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -25,7 +25,7 @@ pub use crate::backend::{Account, Log, Vicinity, Backend}; use sp_std::{vec::Vec, marker::PhantomData}; use frame_support::{ensure, decl_module, decl_storage, decl_event, decl_error}; -use frame_support::weights::{Weight, MINIMUM_WEIGHT, DispatchClass, FunctionOf}; +use frame_support::weights::{Weight, MINIMUM_WEIGHT, DispatchClass, FunctionOf, Pays}; use frame_support::traits::{Currency, WithdrawReason, ExistenceRequirement}; use frame_system::{self as system, ensure_signed}; use sp_runtime::ModuleId; @@ -235,7 +235,12 @@ decl_module! { } /// Issue an EVM call operation. This is similar to a message call transaction in Ethereum. - #[weight = FunctionOf(|(_, _, _, gas_limit, gas_price, _): (&H160, &Vec, &U256, &u32, &U256, &Option)| (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight), DispatchClass::Normal, true)] + #[weight = FunctionOf( + |(_, _, _, gas_limit, gas_price, _): (&H160, &Vec, &U256, &u32, &U256, &Option)| + (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight), + DispatchClass::Normal, + Pays::Yes, + )] fn call( origin, target: H160, @@ -266,7 +271,12 @@ decl_module! { /// Issue an EVM create operation. This is similar to a contract creation transaction in /// Ethereum. - #[weight = FunctionOf(|(_, _, gas_limit, gas_price, _): (&Vec, &U256, &u32, &U256, &Option)| (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight), DispatchClass::Normal, true)] + #[weight = FunctionOf( + |(_, _, gas_limit, gas_price, _): (&Vec, &U256, &u32, &U256, &Option)| + (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight), + DispatchClass::Normal, + Pays::Yes, + )] fn create( origin, init: Vec, @@ -301,7 +311,12 @@ decl_module! { } /// Issue an EVM create2 operation. - #[weight = FunctionOf(|(_, _, _, gas_limit, gas_price, _): (&Vec, &H256, &U256, &u32, &U256, &Option)| (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight), DispatchClass::Normal, true)] + #[weight = FunctionOf( + |(_, _, _, gas_limit, gas_price, _): (&Vec, &H256, &U256, &u32, &U256, &Option)| + (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight), + DispatchClass::Normal, + Pays::Yes, + )] fn create2( origin, init: Vec, diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index e7a5a0c02e..cfc313ad49 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -256,7 +256,7 @@ use sp_std::marker::PhantomData; use frame_support::{ dispatch::DispatchResult, decl_module, decl_storage, decl_event, - weights::{DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee, MINIMUM_WEIGHT}, + weights::{DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee, MINIMUM_WEIGHT, Pays}, }; use sp_std::prelude::*; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -305,8 +305,8 @@ impl ClassifyDispatch<(&BalanceOf,)> for WeightFor } impl PaysFee<(&BalanceOf,)> for WeightForSetDummy { - fn pays_fee(&self, _target: (&BalanceOf,)) -> bool { - true + fn pays_fee(&self, _target: (&BalanceOf,)) -> Pays { + Pays::Yes } } diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index e0397cc1a5..213696e5fb 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -159,7 +159,7 @@ use codec::{Encode, Decode}; use frame_support::{ decl_module, decl_event, decl_storage, decl_error, ensure, - Parameter, RuntimeDebug, weights::{MINIMUM_WEIGHT, GetDispatchInfo, FunctionOf}, + Parameter, RuntimeDebug, weights::{MINIMUM_WEIGHT, GetDispatchInfo, FunctionOf, Pays}, traits::{Currency, ReservableCurrency, Get, BalanceStatus}, dispatch::PostDispatchInfo, }; @@ -338,7 +338,7 @@ decl_module! { #[weight = FunctionOf( |args: (&T::AccountId, &Box<::Call>)| args.1.get_dispatch_info().weight + 10_000, |args: (&T::AccountId, &Box<::Call>)| args.1.get_dispatch_info().class, - true + Pays::Yes, )] fn as_recovered(origin, account: T::AccountId, diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index 3e53b7a505..1ff8a7ad79 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -250,7 +250,7 @@ mod tests { use frame_support::{ impl_outer_event, impl_outer_origin, impl_outer_dispatch, parameter_types, assert_ok, traits::{OnInitialize, OnFinalize, schedule::{Anon, Named}}, - weights::{DispatchClass, FunctionOf} + weights::{DispatchClass, FunctionOf, Pays} }; use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures @@ -293,7 +293,7 @@ mod tests { #[weight = FunctionOf( |args: (&u32, &Weight)| *args.1, |_: (&u32, &Weight)| DispatchClass::Normal, - true + Pays::Yes, )] fn log(origin, i: u32, weight: Weight) { ensure_root(origin)?; diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index ce0de2027c..edbdc5b8e0 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -93,7 +93,7 @@ use sp_runtime::traits::{StaticLookup, Dispatchable}; use frame_support::{ Parameter, decl_module, decl_event, decl_storage, decl_error, ensure, }; -use frame_support::weights::{MINIMUM_WEIGHT, GetDispatchInfo, FunctionOf}; +use frame_support::weights::{MINIMUM_WEIGHT, GetDispatchInfo, FunctionOf, Pays}; use frame_system::{self as system, ensure_signed}; pub trait Trait: frame_system::Trait { @@ -124,7 +124,7 @@ decl_module! { #[weight = FunctionOf( |args: (&Box<::Call>,)| args.0.get_dispatch_info().weight + 10_000, |args: (&Box<::Call>,)| args.0.get_dispatch_info().class, - true + Pays::Yes, )] fn sudo(origin, call: Box<::Call>) { // This is a public call, so we ensure that the origin is some signed account. @@ -180,7 +180,7 @@ decl_module! { |args: (&::Source, &Box<::Call>,)| { args.1.get_dispatch_info().class }, - true + Pays::Yes, )] fn sudo_as(origin, who: ::Source, call: Box<::Call>) { // This is a public call, so we ensure that the origin is some signed account. diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index e25efec0a9..6d3027dbd7 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -2045,7 +2045,7 @@ macro_rules! __check_reserved_fn_name { #[allow(dead_code)] mod tests { use super::*; - use crate::weights::{MINIMUM_WEIGHT, DispatchInfo, DispatchClass}; + use crate::weights::{MINIMUM_WEIGHT, DispatchInfo, DispatchClass, Pays}; use crate::traits::{ CallMetadata, GetCallMetadata, GetCallName, OnInitialize, OnFinalize, OnRuntimeUpgrade }; @@ -2248,12 +2248,12 @@ mod tests { // operational. assert_eq!( Call::::operational().get_dispatch_info(), - DispatchInfo { weight: 5, class: DispatchClass::Operational, pays_fee: true }, + DispatchInfo { weight: 5, class: DispatchClass::Operational, pays_fee: Pays::Yes }, ); // custom basic assert_eq!( Call::::aux_3().get_dispatch_info(), - DispatchInfo { weight: 3, class: DispatchClass::Normal, pays_fee: true }, + DispatchInfo { weight: 3, class: DispatchClass::Normal, pays_fee: Pays::Yes }, ); } diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index 6cf2047cf6..cffb4f83a4 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -35,7 +35,7 @@ //! configuration: //! //! 1. Define only weight, **in which case `ClassifyDispatch` will be `Normal` and `PaysFee` will be -//! `true`**. +//! `Yes`**. //! //! ``` //! # use frame_system::{self as system, Trait}; @@ -48,7 +48,7 @@ //! # fn main() {} //! ``` //! -//! 2. Define weight and class, **in which case `PaysFee` would be `true`**. +//! 2.1 Define weight and class, **in which case `PaysFee` would be `Yes`**. //! //! ``` //! # use frame_system::{self as system, Trait}; @@ -62,14 +62,28 @@ //! # fn main() {} //! ``` //! +//! 2.2 Define weight and `PaysFee`, **in which case `ClassifyDispatch` would be `Normal`**. +//! +//! ``` +//! # use frame_system::{self as system, Trait}; +//! # use frame_support::weights::Pays; +//! frame_support::decl_module! { +//! pub struct Module for enum Call where origin: T::Origin { +//! #[weight = (1000, Pays::No)] +//! fn dispatching(origin) { unimplemented!() } +//! } +//! } +//! # fn main() {} +//! ``` +//! //! 3. Define all 3 parameters. //! //! ``` //! # use frame_system::{self as system, Trait}; -//! # use frame_support::weights::DispatchClass; +//! # use frame_support::weights::{DispatchClass, Pays}; //! frame_support::decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = (1000, DispatchClass::Operational, false)] +//! #[weight = (1000, DispatchClass::Operational, Pays::No)] //! fn dispatching(origin) { unimplemented!() } //! } //! } @@ -86,7 +100,7 @@ //! //! ``` //! # use frame_system::{self as system, Trait}; -//! # use frame_support::weights::{DispatchClass, FunctionOf}; +//! # use frame_support::weights::{DispatchClass, FunctionOf, Pays}; //! frame_support::decl_module! { //! pub struct Module for enum Call where origin: T::Origin { //! #[weight = FunctionOf( @@ -95,7 +109,7 @@ //! // class, fixed. //! DispatchClass::Operational, //! // pays fee, function. -//! |args: (&u32, &u64)| *args.0 > 1000, +//! |args: (&u32, &u64)| if *args.0 > 1000 { Pays::Yes } else { Pays::No }, //! )] //! fn dispatching(origin, a: u32, b: u64) { unimplemented!() } //! } @@ -146,10 +160,23 @@ pub trait ClassifyDispatch { } /// Indicates if dispatch function should pay fees or not. -/// If set to false, the block resource limits are applied, yet no fee is deducted. +/// If set to `Pays::No`, the block resource limits are applied, yet no fee is deducted. pub trait PaysFee { - fn pays_fee(&self, _target: T) -> bool { - true + fn pays_fee(&self, _target: T) -> Pays; +} + +/// Explicit enum to denote if a transaction pays fee or not. +#[derive(Clone, Copy, Eq, PartialEq, RuntimeDebug, Encode, Decode)] +pub enum Pays { + /// Transactor will pay related fees. + Yes, + /// Transactor will NOT pay related fees. + No, +} + +impl Default for Pays { + fn default() -> Self { + Self::Yes } } @@ -191,7 +218,7 @@ pub struct DispatchInfo { /// Class of this transaction. pub class: DispatchClass, /// Does this transaction pay fees. - pub pays_fee: bool, + pub pays_fee: Pays, } /// A `Dispatchable` function (aka transaction) that can carry some static information along with @@ -289,25 +316,25 @@ impl ClassifyDispatch for Weight { } impl PaysFee for Weight { - fn pays_fee(&self, _: T) -> bool { - true + fn pays_fee(&self, _: T) -> Pays { + Pays::Yes } } -impl WeighData for (Weight, DispatchClass, bool) { +impl WeighData for (Weight, DispatchClass, Pays) { fn weigh_data(&self, _: T) -> Weight { return self.0 } } -impl ClassifyDispatch for (Weight, DispatchClass, bool) { +impl ClassifyDispatch for (Weight, DispatchClass, Pays) { fn classify_dispatch(&self, _: T) -> DispatchClass { self.1 } } -impl PaysFee for (Weight, DispatchClass, bool) { - fn pays_fee(&self, _: T) -> bool { +impl PaysFee for (Weight, DispatchClass, Pays) { + fn pays_fee(&self, _: T) -> Pays { self.2 } } @@ -325,25 +352,25 @@ impl ClassifyDispatch for (Weight, DispatchClass) { } impl PaysFee for (Weight, DispatchClass) { - fn pays_fee(&self, _: T) -> bool { - true + fn pays_fee(&self, _: T) -> Pays { + Pays::Yes } } -impl WeighData for (Weight, bool) { +impl WeighData for (Weight, Pays) { fn weigh_data(&self, _: T) -> Weight { return self.0 } } -impl ClassifyDispatch for (Weight, bool) { +impl ClassifyDispatch for (Weight, Pays) { fn classify_dispatch(&self, _: T) -> DispatchClass { DispatchClass::Normal } } -impl PaysFee for (Weight, bool) { - fn pays_fee(&self, _: T) -> bool { +impl PaysFee for (Weight, Pays) { + fn pays_fee(&self, _: T) -> Pays { self.1 } } @@ -355,8 +382,8 @@ impl PaysFee for (Weight, bool) { /// argument list as the dispatched, wrapped in a tuple. /// - `CD`: a raw `DispatchClass` value or a closure that returns a `DispatchClass` /// with the same argument list as the dispatched, wrapped in a tuple. -/// - `PF`: a `bool` for whether this dispatch pays fee or not or a closure that -/// returns a bool with the same argument list as the dispatched, wrapped in a tuple. +/// - `PF`: a `Pays` variant for whether this dispatch pays fee or not or a closure that +/// returns a `Pays` variant with the same argument list as the dispatched, wrapped in a tuple. pub struct FunctionOf(pub WD, pub CD, pub PF); // `WeighData` as a raw value @@ -392,17 +419,17 @@ impl ClassifyDispatch for FunctionOf where } // `PaysFee` as a raw value -impl PaysFee for FunctionOf { - fn pays_fee(&self, _: Args) -> bool { +impl PaysFee for FunctionOf { + fn pays_fee(&self, _: Args) -> Pays { self.2 } } // `PaysFee` as a closure impl PaysFee for FunctionOf where - PF : Fn(Args) -> bool + PF : Fn(Args) -> Pays { - fn pays_fee(&self, args: Args) -> bool { + fn pays_fee(&self, args: Args) -> Pays { (self.2)(args) } } @@ -437,7 +464,7 @@ impl GetDispatchInfo for sp_runtime::testing::TestX // for testing: weight == size. DispatchInfo { weight: self.encode().len() as _, - pays_fee: true, + pays_fee: Pays::Yes, ..Default::default() } } @@ -504,14 +531,17 @@ mod tests { #[weight = (1000, DispatchClass::Mandatory)] fn f01(_origin) { unimplemented!(); } - #[weight = (1000, DispatchClass::Operational, false)] + #[weight = (1000, Pays::No)] fn f02(_origin) { unimplemented!(); } + #[weight = (1000, DispatchClass::Operational, Pays::No)] + fn f03(_origin) { unimplemented!(); } + // weight = a x 10 + b - #[weight = FunctionOf(|args: (&u32, &u32)| (args.0 * 10 + args.1) as Weight, DispatchClass::Normal, true)] + #[weight = FunctionOf(|args: (&u32, &u32)| (args.0 * 10 + args.1) as Weight, DispatchClass::Normal, Pays::Yes)] fn f11(_origin, _a: u32, _eb: u32) { unimplemented!(); } - #[weight = FunctionOf(|_: (&u32, &u32)| 0, DispatchClass::Operational, true)] + #[weight = FunctionOf(|_: (&u32, &u32)| 0, DispatchClass::Operational, Pays::Yes)] fn f12(_origin, _a: u32, _eb: u32) { unimplemented!(); } #[weight = T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + 10_000] @@ -529,19 +559,25 @@ mod tests { let info = Call::::f00().get_dispatch_info(); assert_eq!(info.weight, 1000); assert_eq!(info.class, DispatchClass::Normal); - assert_eq!(info.pays_fee, true); + assert_eq!(info.pays_fee, Pays::Yes); // #[weight = (1000, DispatchClass::Mandatory)] let info = Call::::f01().get_dispatch_info(); assert_eq!(info.weight, 1000); assert_eq!(info.class, DispatchClass::Mandatory); - assert_eq!(info.pays_fee, true); + assert_eq!(info.pays_fee, Pays::Yes); - // #[weight = (1000, DispatchClass::Operational, false)] + // #[weight = (1000, Pays::No)] let info = Call::::f02().get_dispatch_info(); assert_eq!(info.weight, 1000); + assert_eq!(info.class, DispatchClass::Normal); + assert_eq!(info.pays_fee, Pays::No); + + // #[weight = (1000, DispatchClass::Operational, Pays::No)] + let info = Call::::f03().get_dispatch_info(); + assert_eq!(info.weight, 1000); assert_eq!(info.class, DispatchClass::Operational); - assert_eq!(info.pays_fee, false); + assert_eq!(info.pays_fee, Pays::No); assert_eq!(Call::::f11(10, 20).get_dispatch_info().weight, 120); assert_eq!(Call::::f11(10, 20).get_dispatch_info().class, DispatchClass::Normal); diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 115b681adc..d9b8b68108 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -120,7 +120,10 @@ use frame_support::{ Contains, Get, ModuleToIndex, OnNewAccount, OnKilledAccount, IsDeadAccount, Happened, StoredMap, EnsureOrigin, }, - weights::{Weight, MINIMUM_WEIGHT, RuntimeDbWeight, DispatchInfo, PostDispatchInfo, DispatchClass, FunctionOf} + weights::{ + Weight, MINIMUM_WEIGHT, RuntimeDbWeight, DispatchInfo, PostDispatchInfo, DispatchClass, + FunctionOf, Pays, + } }; use codec::{Encode, Decode, FullCodec, EncodeLike}; @@ -472,13 +475,19 @@ decl_module! { pub struct Module for enum Call where origin: T::Origin { type Error = Error; + /// The maximum weight of a block. + const MaximumBlockWeight: Weight = T::MaximumBlockWeight::get(); + + /// The maximum length of a block (in bytes). + const MaximumBlockLength: u32 = T::MaximumBlockLength::get(); + /// A dispatch that will fill the block weight up to the given ratio. // TODO: This should only be available for testing, rather than in general usage, but // that's not possible at present (since it's within the decl_module macro). #[weight = FunctionOf( |(ratio,): (&Perbill,)| *ratio * T::MaximumBlockWeight::get(), DispatchClass::Operational, - true, + Pays::Yes, )] fn fill_block(origin, _ratio: Perbill) { ensure_root(origin)?; @@ -1990,7 +1999,7 @@ pub(crate) mod tests { fn signed_ext_check_weight_works_operational_tx() { new_test_ext().execute_with(|| { let normal = DispatchInfo { weight: 100, ..Default::default() }; - let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: true }; + let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: Pays::Yes }; let len = 0_usize; let normal_limit = normal_weight_limit(); @@ -2012,8 +2021,8 @@ pub(crate) mod tests { #[test] fn signed_ext_check_weight_priority_works() { new_test_ext().execute_with(|| { - let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: true }; - let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: true }; + let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes }; + let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: Pays::Yes }; let len = 0_usize; let priority = CheckWeight::(PhantomData) @@ -2046,7 +2055,7 @@ pub(crate) mod tests { reset_check_weight(&normal, normal_limit + 1, true); // Operational ones don't have this limit. - let op = DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: true }; + let op = DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: Pays::Yes }; reset_check_weight(&op, normal_limit, false); reset_check_weight(&op, normal_limit + 100, false); reset_check_weight(&op, 1024, false); @@ -2073,7 +2082,7 @@ pub(crate) mod tests { #[test] fn signed_ext_check_era_should_change_longevity() { new_test_ext().execute_with(|| { - let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: true }; + let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes }; let len = 0_usize; let ext = ( CheckWeight::(PhantomData), diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 75809e0ed6..95845990b8 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -36,7 +36,7 @@ use codec::{Encode, Decode}; use frame_support::{ decl_storage, decl_module, traits::{Currency, Get, OnUnbalanced, ExistenceRequirement, WithdrawReason, Imbalance}, - weights::{Weight, DispatchInfo, PostDispatchInfo, GetDispatchInfo}, + weights::{Weight, DispatchInfo, PostDispatchInfo, GetDispatchInfo, Pays}, dispatch::DispatchResult, }; use sp_runtime::{ @@ -166,7 +166,7 @@ impl Module where info: &DispatchInfoOf, tip: BalanceOf, ) -> BalanceOf { - if info.pays_fee { + if info.pays_fee == Pays::Yes { let len = >::from(len); let per_byte = T::TransactionByteFee::get(); let len_fee = per_byte.saturating_mul(len); @@ -505,7 +505,8 @@ mod tests { /// create a transaction info struct from weight. Handy to avoid building the whole struct. pub fn info_from_weight(w: Weight) -> DispatchInfo { - DispatchInfo { weight: w, pays_fee: true, ..Default::default() } + // pays: yes -- class: normal + DispatchInfo { weight: w, ..Default::default() } } fn post_info_from_weight(w: Weight) -> PostDispatchInfo { @@ -565,7 +566,7 @@ mod tests { let pre = ChargeTransactionPayment::::from(5 /* tipped */) .pre_dispatch(&2, CALL, &info_from_weight(100), len) .unwrap(); - // 5 base fee, 3/2 * 10 byte fee, 3/2 * 100 weight fee, 5 tip + // 5 base fee, 3/2 * 10 byte fee, 3/2 * 100 weight fee, 5 tip assert_eq!(Balances::free_balance(2), 200 - 5 - 15 - 150 - 5); assert!( @@ -617,7 +618,7 @@ mod tests { let operational_transaction = DispatchInfo { weight: 0, class: DispatchClass::Operational, - pays_fee: false, + pays_fee: Pays::No, }; assert!( ChargeTransactionPayment::::from(0) @@ -629,7 +630,7 @@ mod tests { let free_transaction = DispatchInfo { weight: 0, class: DispatchClass::Normal, - pays_fee: true, + pays_fee: Pays::Yes, }; assert!( ChargeTransactionPayment::::from(0) @@ -711,14 +712,14 @@ mod tests { let dispatch_info = DispatchInfo { weight: 0, class: DispatchClass::Operational, - pays_fee: false, + pays_fee: Pays::No, }; assert_eq!(Module::::compute_fee(0, &dispatch_info, 10), 10); // No tip, only base fee works let dispatch_info = DispatchInfo { weight: 0, class: DispatchClass::Operational, - pays_fee: true, + pays_fee: Pays::Yes, }; assert_eq!(Module::::compute_fee(0, &dispatch_info, 0), 100); // Tip + base fee works @@ -729,7 +730,7 @@ mod tests { let dispatch_info = DispatchInfo { weight: 1000, class: DispatchClass::Operational, - pays_fee: true, + pays_fee: Pays::Yes, }; assert_eq!(Module::::compute_fee(0, &dispatch_info, 0), 1100); }); @@ -750,7 +751,7 @@ mod tests { let dispatch_info = DispatchInfo { weight: 0, class: DispatchClass::Operational, - pays_fee: true, + pays_fee: Pays::Yes, }; assert_eq!(Module::::compute_fee(0, &dispatch_info, 0), 100); @@ -758,7 +759,7 @@ mod tests { let dispatch_info = DispatchInfo { weight: 123, class: DispatchClass::Operational, - pays_fee: true, + pays_fee: Pays::Yes, }; // 123 weight, 456 length, 100 base // adjustable fee = (123 * 1) + (456 * 10) = 4683 @@ -781,7 +782,7 @@ mod tests { let dispatch_info = DispatchInfo { weight: Weight::max_value(), class: DispatchClass::Operational, - pays_fee: true, + pays_fee: Pays::Yes, }; assert_eq!( Module::::compute_fee( diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 4a1c36b5ad..0ad35c3e28 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -67,7 +67,7 @@ use sp_core::TypeId; use sp_io::hashing::blake2_256; use frame_support::{decl_module, decl_event, decl_error, decl_storage, Parameter, ensure, RuntimeDebug}; use frame_support::{traits::{Get, ReservableCurrency, Currency}, - weights::{Weight, GetDispatchInfo, DispatchClass, FunctionOf}, + weights::{Weight, GetDispatchInfo, DispatchClass, FunctionOf, Pays}, dispatch::PostDispatchInfo, }; use frame_system::{self as system, ensure_signed}; @@ -242,7 +242,7 @@ decl_module! { DispatchClass::Normal } }, - true + Pays::Yes, )] fn batch(origin, calls: Vec<::Call>) { for (index, call) in calls.into_iter().enumerate() { @@ -265,7 +265,7 @@ decl_module! { #[weight = FunctionOf( |args: (&u16, &Box<::Call>)| args.1.get_dispatch_info().weight + 10_000, |args: (&u16, &Box<::Call>)| args.1.get_dispatch_info().class, - true + Pays::Yes, )] fn as_sub(origin, index: u16, call: Box<::Call>) -> DispatchResult { let who = ensure_signed(origin)?; @@ -322,7 +322,7 @@ decl_module! { |args: (&u16, &Vec, &Option>, &Box<::Call>)| { args.3.get_dispatch_info().class }, - true + Pays::Yes, )] fn as_multi(origin, threshold: u16, @@ -421,7 +421,7 @@ decl_module! { 10_000 * (args.1.len() as Weight + 1) }, DispatchClass::Normal, - true + Pays::Yes, )] fn approve_as_multi(origin, threshold: u16, @@ -496,7 +496,7 @@ decl_module! { 10_000 * (args.1.len() as Weight + 1) }, DispatchClass::Normal, - true + Pays::Yes, )] fn cancel_as_multi(origin, threshold: u16, -- GitLab From 13f9c1f8a5ddc0ce05f6b008c26439dc9e74d278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 22 Apr 2020 15:56:27 +0200 Subject: [PATCH 290/300] Make `version_is_full` test work without `.git` being available (#5737) --- bin/node/cli/tests/version.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/cli/tests/version.rs b/bin/node/cli/tests/version.rs index 5555efd385..6f99d7c24a 100644 --- a/bin/node/cli/tests/version.rs +++ b/bin/node/cli/tests/version.rs @@ -20,7 +20,7 @@ use regex::Regex; use std::process::Command; fn expected_regex() -> Regex { - Regex::new(r"^substrate (\d+\.\d+\.\d+(?:-.+?)?)-([a-f\d]+)-(.+?)-(.+?)(?:-(.+))?$").unwrap() + Regex::new(r"^substrate (\d+\.\d+\.\d+(?:-.+?)?)-([a-f\d]+|unknown-commit)-(.+?)-(.+?)(?:-(.+))?$").unwrap() } #[test] -- GitLab From 68dbd07ba365595ee6303a58062f9eb2585a327a Mon Sep 17 00:00:00 2001 From: Ashley Date: Wed, 22 Apr 2020 16:28:08 +0200 Subject: [PATCH 291/300] Fix the browser tests by not relying on Flaming Fir (#5728) * Fix the browser tests * Mistyping * Fix warnings Co-authored-by: Pierre Krieger --- bin/node/browser-testing/src/lib.rs | 33 ++++++++--------------------- bin/node/cli/src/browser.rs | 11 ++++++---- 2 files changed, 16 insertions(+), 28 deletions(-) diff --git a/bin/node/browser-testing/src/lib.rs b/bin/node/browser-testing/src/lib.rs index 06038f90af..65f1e4620b 100644 --- a/bin/node/browser-testing/src/lib.rs +++ b/bin/node/browser-testing/src/lib.rs @@ -32,14 +32,9 @@ use wasm_bindgen_futures::JsFuture; use wasm_bindgen::JsValue; use jsonrpc_core::types::{MethodCall, Success, Version, Params, Id}; use serde::de::DeserializeOwned; -use futures_timer::Delay; -use std::time::Duration; -use futures::FutureExt; wasm_bindgen_test_configure!(run_in_browser); -const CHAIN_SPEC: &str = include_str!("../../cli/res/flaming-fir.json"); - fn rpc_call(method: &str) -> String { serde_json::to_string(&MethodCall { jsonrpc: Some(Version::V2), @@ -59,26 +54,16 @@ fn deserialize_rpc_result(js_value: JsValue) -> T { #[wasm_bindgen_test] async fn runs() { - let mut client = node_cli::start_client(CHAIN_SPEC.into(), "info".into()) + let mut client = node_cli::start_client(None, "info".into()) .await .unwrap(); - let mut test_timeout = Delay::new(Duration::from_secs(45)); - loop { - // Check that timeout hasn't expired. - assert!((&mut test_timeout).now_or_never().is_none(), "Test timed out."); - - // Let the node do a bit of work. - Delay::new(Duration::from_secs(5)).await; - - let state: sc_rpc_api::system::Health = deserialize_rpc_result( - JsFuture::from(client.rpc_send(&rpc_call("system_health"))) - .await - .unwrap() - ); - - if state.should_have_peers && state.peers > 0 && state.is_syncing { - break; - } - } + // Check that the node handles rpc calls. + // TODO: Re-add the code that checks if the node is syncing. + let chain_name: String = deserialize_rpc_result( + JsFuture::from(client.rpc_send(&rpc_call("system_chain"))) + .await + .unwrap() + ); + assert_eq!(chain_name, "Development"); } diff --git a/bin/node/cli/src/browser.rs b/bin/node/cli/src/browser.rs index 8c4d964d95..861d37c605 100644 --- a/bin/node/cli/src/browser.rs +++ b/bin/node/cli/src/browser.rs @@ -25,17 +25,20 @@ use std::str::FromStr; /// Starts the client. #[wasm_bindgen] -pub async fn start_client(chain_spec: String, log_level: String) -> Result { +pub async fn start_client(chain_spec: Option, log_level: String) -> Result { start_inner(chain_spec, log_level) .await .map_err(|err| JsValue::from_str(&err.to_string())) } -async fn start_inner(chain_spec: String, log_level: String) -> Result> { +async fn start_inner(chain_spec: Option, log_level: String) -> Result> { set_console_error_panic_hook(); init_console_log(log::Level::from_str(&log_level)?)?; - let chain_spec = ChainSpec::from_json_bytes(chain_spec.as_bytes().to_vec()) - .map_err(|e| format!("{:?}", e))?; + let chain_spec = match chain_spec { + Some(chain_spec) => ChainSpec::from_json_bytes(chain_spec.as_bytes().to_vec()) + .map_err(|e| format!("{:?}", e))?, + None => crate::chain_spec::development_config(), + }; let config = browser_configuration(chain_spec).await?; -- GitLab From e6e1f8f9b9ad84dc1124d75b2dc21796e5c111dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Thu, 23 Apr 2020 08:42:53 +0100 Subject: [PATCH 292/300] slots: fix slot lenience methods (#5742) * slots: extract slot lenience from babe and aura * slots: add tests for slot lenience * slots: fix comment in test --- client/consensus/aura/src/lib.rs | 29 ++++---- client/consensus/babe/src/lib.rs | 36 ++++----- client/consensus/slots/src/lib.rs | 117 ++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 37 deletions(-) diff --git a/client/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index 56674546d3..038e9e458c 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -299,27 +299,28 @@ impl sc_consensus_slots::SimpleSlotWorker for AuraW fn proposing_remaining_duration( &self, head: &B::Header, - slot_info: &SlotInfo + slot_info: &SlotInfo, ) -> Option { - // never give more than 20 times more lenience. - const BACKOFF_CAP: u64 = 20; - let slot_remaining = self.slot_remaining_duration(slot_info); + let parent_slot = match find_pre_digest::(head) { Err(_) => return Some(slot_remaining), Ok(d) => d, }; - // we allow a lenience of the number of slots since the head of the - // chain was produced, minus 1 (since there is always a difference of at least 1) - // - // linear back-off. - // in normal cases we only attempt to issue blocks up to the end of the slot. - // when the chain has been stalled for a few slots, we give more lenience. - let slot_lenience = slot_info.number.saturating_sub(parent_slot + 1); - let slot_lenience = std::cmp::min(slot_lenience, BACKOFF_CAP); - let slot_lenience = Duration::from_secs(slot_lenience * slot_info.duration); - Some(slot_lenience + slot_remaining) + if let Some(slot_lenience) = + sc_consensus_slots::slot_lenience_exponential(parent_slot, slot_info) + { + debug!(target: "aura", + "No block for {} slots. Applying linear lenience of {}s", + slot_info.number.saturating_sub(parent_slot + 1), + slot_lenience.as_secs(), + ); + + Some(slot_remaining + slot_lenience) + } else { + Some(slot_remaining) + } } } diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index 092bf8153b..59b4954182 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -510,38 +510,28 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeWork fn proposing_remaining_duration( &self, head: &B::Header, - slot_info: &SlotInfo + slot_info: &SlotInfo, ) -> Option { - // never give more than 2^this times the lenience. - const BACKOFF_CAP: u64 = 8; - - // how many slots it takes before we double the lenience. - const BACKOFF_STEP: u64 = 2; - let slot_remaining = self.slot_remaining_duration(slot_info); + let parent_slot = match find_pre_digest::(head) { Err(_) => return Some(slot_remaining), Ok(d) => d.slot_number(), }; - // we allow a lenience of the number of slots since the head of the - // chain was produced, minus 1 (since there is always a difference of at least 1) - // - // exponential back-off. - // in normal cases we only attempt to issue blocks up to the end of the slot. - // when the chain has been stalled for a few slots, we give more lenience. - let slot_lenience = slot_info.number.saturating_sub(parent_slot + 1); - - let slot_lenience = std::cmp::min(slot_lenience, BACKOFF_CAP); - let slot_duration = slot_info.duration << (slot_lenience / BACKOFF_STEP); + if let Some(slot_lenience) = + sc_consensus_slots::slot_lenience_exponential(parent_slot, slot_info) + { + debug!(target: "babe", + "No block for {} slots. Applying exponential lenience of {}s", + slot_info.number.saturating_sub(parent_slot + 1), + slot_lenience.as_secs(), + ); - if slot_lenience >= 1 { - debug!(target: "babe", "No block for {} slots. Applying 2^({}/{}) lenience", - slot_lenience, slot_lenience, BACKOFF_STEP); + Some(slot_remaining + slot_lenience) + } else { + Some(slot_remaining) } - - let slot_lenience = Duration::from_secs(slot_duration); - Some(slot_lenience + slot_remaining) } } diff --git a/client/consensus/slots/src/lib.rs b/client/consensus/slots/src/lib.rs index 2a0739a831..611e0fbb7b 100644 --- a/client/consensus/slots/src/lib.rs +++ b/client/consensus/slots/src/lib.rs @@ -483,3 +483,120 @@ impl SlotDuration { self.0.clone() } } + +/// Calculate a slot duration lenience based on the number of missed slots from current +/// to parent. If the number of skipped slots is greated than 0 this method will apply +/// an exponential backoff of at most `2^7 * slot_duration`, if no slots were skipped +/// this method will return `None.` +pub fn slot_lenience_exponential(parent_slot: u64, slot_info: &SlotInfo) -> Option { + // never give more than 2^this times the lenience. + const BACKOFF_CAP: u64 = 7; + + // how many slots it takes before we double the lenience. + const BACKOFF_STEP: u64 = 2; + + // we allow a lenience of the number of slots since the head of the + // chain was produced, minus 1 (since there is always a difference of at least 1) + // + // exponential back-off. + // in normal cases we only attempt to issue blocks up to the end of the slot. + // when the chain has been stalled for a few slots, we give more lenience. + let skipped_slots = slot_info.number.saturating_sub(parent_slot + 1); + + if skipped_slots == 0 { + None + } else { + let slot_lenience = skipped_slots / BACKOFF_STEP; + let slot_lenience = std::cmp::min(slot_lenience, BACKOFF_CAP); + let slot_lenience = 1 << slot_lenience; + Some(Duration::from_millis(slot_lenience * slot_info.duration)) + } +} + +/// Calculate a slot duration lenience based on the number of missed slots from current +/// to parent. If the number of skipped slots is greated than 0 this method will apply +/// a linear backoff of at most `20 * slot_duration`, if no slots were skipped +/// this method will return `None.` +pub fn slot_lenience_linear(parent_slot: u64, slot_info: &SlotInfo) -> Option { + // never give more than 20 times more lenience. + const BACKOFF_CAP: u64 = 20; + + // we allow a lenience of the number of slots since the head of the + // chain was produced, minus 1 (since there is always a difference of at least 1) + // + // linear back-off. + // in normal cases we only attempt to issue blocks up to the end of the slot. + // when the chain has been stalled for a few slots, we give more lenience. + let skipped_slots = slot_info.number.saturating_sub(parent_slot + 1); + + if skipped_slots == 0 { + None + } else { + let slot_lenience = std::cmp::min(skipped_slots, BACKOFF_CAP); + Some(Duration::from_millis(slot_lenience * slot_info.duration)) + } +} + +#[cfg(test)] +mod test { + use std::time::{Duration, Instant}; + + const SLOT_DURATION: Duration = Duration::from_millis(6000); + + fn slot(n: u64) -> super::slots::SlotInfo { + super::slots::SlotInfo { + number: n, + last_number: n - 1, + duration: SLOT_DURATION.as_millis() as u64, + timestamp: Default::default(), + inherent_data: Default::default(), + ends_at: Instant::now(), + } + } + + #[test] + fn linear_slot_lenience() { + // if no slots are skipped there should be no lenience + assert_eq!(super::slot_lenience_linear(1, &slot(2)), None); + + // otherwise the lenience is incremented linearly with + // the number of skipped slots. + for n in 3..=22 { + assert_eq!( + super::slot_lenience_linear(1, &slot(n)), + Some(SLOT_DURATION * (n - 2) as u32), + ); + } + + // but we cap it to a maximum of 20 slots + assert_eq!( + super::slot_lenience_linear(1, &slot(23)), + Some(SLOT_DURATION * 20), + ); + } + + #[test] + fn exponential_slot_lenience() { + // if no slots are skipped there should be no lenience + assert_eq!(super::slot_lenience_exponential(1, &slot(2)), None); + + // otherwise the lenience is incremented exponentially every two slots + for n in 3..=17 { + assert_eq!( + super::slot_lenience_exponential(1, &slot(n)), + Some(SLOT_DURATION * 2u32.pow((n / 2 - 1) as u32)), + ); + } + + // but we cap it to a maximum of 14 slots + assert_eq!( + super::slot_lenience_exponential(1, &slot(18)), + Some(SLOT_DURATION * 2u32.pow(7)), + ); + + assert_eq!( + super::slot_lenience_exponential(1, &slot(19)), + Some(SLOT_DURATION * 2u32.pow(7)), + ); + } +} -- GitLab From 435a7108c2a0f2ebb0d753f58725b194dbfb5ae9 Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Thu, 23 Apr 2020 09:52:20 +0200 Subject: [PATCH 293/300] network: Only insert global addresses into the DHT. (#5735) * network: Only insert global addresses into the DHT. Currently every address reported via libp2p-identify is inserted into the DHT which thus contains a multitude of unreachable addresses such as from 127.0.0.0/8 or 10.0.0.0/8. Issue #5099 suggested a dedicated service over UDP to gauge the reachability of an address, which would however incur extra I/O costs and be of limited use. As an alternative and simpler tactic, this PR only allows global IP addresses to be inserted into the DHT unless an explicit command-line flag `--allow-non-global-addresses-in-dht` is given or a node is started with `--dev`. This opt-in behaviour is meant to allow site-local networks to still make use of a DHT. * Enable non-global in more test setups. * Replace command-line option with different name. * Another test fix. --- Cargo.lock | 7 +++++ client/cli/src/params/network_params.rs | 7 +++++ client/network/Cargo.toml | 13 +++++---- client/network/src/config.rs | 5 ++++ client/network/src/discovery.rs | 38 +++++++++++++++++++++++-- client/network/src/service.rs | 1 + client/network/test/src/lib.rs | 2 ++ client/service/test/src/lib.rs | 2 ++ 8 files changed, 67 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b36a7d08a..cc10378401 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2283,6 +2283,12 @@ dependencies = [ "libc", ] +[[package]] +name = "ip_network" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee15951c035f79eddbef745611ec962f63f4558f1dadf98ab723cc603487c6f" + [[package]] name = "ipnet" version = "2.3.0" @@ -6417,6 +6423,7 @@ dependencies = [ "futures-timer 3.0.2", "futures_codec", "hex", + "ip_network", "libp2p", "linked-hash-map", "linked_hash_set", diff --git a/client/cli/src/params/network_params.rs b/client/cli/src/params/network_params.rs index c08a9e1c93..e36bcfca49 100644 --- a/client/cli/src/params/network_params.rs +++ b/client/cli/src/params/network_params.rs @@ -89,6 +89,12 @@ pub struct NetworkParams { /// enough confidence that this feature is properly working. #[structopt(long)] pub no_yamux_flow_control: bool, + + /// Enable peer discovery on local networks. + /// + /// By default this option is true for `--dev` and false otherwise. + #[structopt(long)] + pub discover_local: bool, } impl NetworkParams { @@ -141,6 +147,7 @@ impl NetworkParams { use_yamux_flow_control: !self.no_yamux_flow_control, }, max_parallel_downloads: self.max_parallel_downloads, + allow_non_globals_in_dht: self.discover_local || is_dev } } } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index f8e35a924f..9e5aa51a99 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -27,39 +27,40 @@ erased-serde = "0.3.9" fnv = "1.0.6" fork-tree = { version = "2.0.0-dev", path = "../../utils/fork-tree" } futures = "0.3.4" -futures_codec = "0.3.3" futures-timer = "3.0.1" -wasm-timer = "0.2" +futures_codec = "0.3.3" +hex = "0.4.0" +ip_network = "0.3.4" linked-hash-map = "0.5.2" linked_hash_set = "0.1.3" log = "0.4.8" lru = "0.4.0" nohash-hasher = "0.2.0" parking_lot = "0.10.0" +pin-project = "0.4.6" +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-dev", path = "../../utils/prometheus" } prost = "0.6.1" rand = "0.7.2" -hex = "0.4.0" sc-block-builder = { version = "0.8.0-dev", path = "../block-builder" } sc-client = { version = "0.8.0-dev", path = "../" } sc-client-api = { version = "2.0.0-dev", path = "../api" } sc-peerset = { version = "2.0.0-dev", path = "../peerset" } -pin-project = "0.4.6" serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } slog_derive = "0.2.0" smallvec = "0.6.10" sp-arithmetic = { version = "2.0.0-dev", path = "../../primitives/arithmetic" } -sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } sp-consensus-babe = { version = "0.8.0-dev", path = "../../primitives/consensus/babe" } sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-dev", path = "../../utils/prometheus" } +sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } thiserror = "1" unsigned-varint = { version = "0.3.1", features = ["futures", "futures-codec"] } void = "1.0.2" +wasm-timer = "0.2" zeroize = "1.0.0" [dependencies.libp2p] diff --git a/client/network/src/config.rs b/client/network/src/config.rs index c53d2734d2..84e2da7018 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -398,6 +398,8 @@ pub struct NetworkConfiguration { pub transport: TransportConfig, /// Maximum number of peers to ask the same blocks in parallel. pub max_parallel_downloads: u32, + /// Should we insert non-global addresses into the DHT? + pub allow_non_globals_in_dht: bool } impl NetworkConfiguration { @@ -428,6 +430,7 @@ impl NetworkConfiguration { use_yamux_flow_control: false, }, max_parallel_downloads: 5, + allow_non_globals_in_dht: false } } } @@ -448,6 +451,7 @@ impl NetworkConfiguration { .collect() ]; + config.allow_non_globals_in_dht = true; config } @@ -466,6 +470,7 @@ impl NetworkConfiguration { .collect() ]; + config.allow_non_globals_in_dht = true; config } } diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index f3b9c5cc71..56c08cc56c 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -48,6 +48,7 @@ use crate::config::ProtocolId; use futures::prelude::*; use futures_timer::Delay; +use ip_network::IpNetwork; use libp2p::core::{connection::{ConnectionId, ListenerId}, ConnectedPoint, Multiaddr, PeerId, PublicKey}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters, ProtocolsHandler}; use libp2p::swarm::protocols_handler::multi::MultiHandler; @@ -71,6 +72,7 @@ pub struct DiscoveryConfig { local_peer_id: PeerId, user_defined: Vec<(PeerId, Multiaddr)>, allow_private_ipv4: bool, + allow_non_globals_in_dht: bool, discovery_only_if_under_num: u64, enable_mdns: bool, kademlias: HashMap> @@ -83,6 +85,7 @@ impl DiscoveryConfig { local_peer_id: local_public_key.into_peer_id(), user_defined: Vec::new(), allow_private_ipv4: true, + allow_non_globals_in_dht: false, discovery_only_if_under_num: std::u64::MAX, enable_mdns: false, kademlias: HashMap::new() @@ -123,6 +126,12 @@ impl DiscoveryConfig { self } + /// Should non-global addresses be inserted to the DHT? + pub fn allow_non_globals_in_dht(&mut self, value: bool) -> &mut Self { + self.allow_non_globals_in_dht = value; + self + } + /// Should MDNS discovery be supported? pub fn with_mdns(&mut self, value: bool) -> &mut Self { if value && cfg!(target_os = "unknown") { @@ -190,6 +199,7 @@ impl DiscoveryConfig { } else { None.into() }, + allow_non_globals_in_dht: self.allow_non_globals_in_dht } } } @@ -219,6 +229,8 @@ pub struct DiscoveryBehaviour { allow_private_ipv4: bool, /// Number of active connections over which we interrupt the discovery process. discovery_only_if_under_num: u64, + /// Should non-global addresses be added to the DHT? + allow_non_globals_in_dht: bool } impl DiscoveryBehaviour { @@ -251,8 +263,12 @@ impl DiscoveryBehaviour { /// **Note**: It is important that you call this method, otherwise the discovery mechanism will /// not properly work. pub fn add_self_reported_address(&mut self, peer_id: &PeerId, addr: Multiaddr) { - for k in self.kademlias.values_mut() { - k.add_address(peer_id, addr.clone()) + if self.allow_non_globals_in_dht || self.can_add_to_dht(&addr) { + for k in self.kademlias.values_mut() { + k.add_address(peer_id, addr.clone()) + } + } else { + log::trace!(target: "sub-libp2p", "Ignoring self-reported address {} from {}", addr, peer_id); } } @@ -298,6 +314,23 @@ impl DiscoveryBehaviour { (id, size) }) } + + /// Can the given `Multiaddr` be put into the DHT? + /// + /// This test is successful only for global IP addresses and DNS names. + // + // NB: Currently all DNS names are allowed and no check for TLD suffixes is done + // because the set of valid domains is highly dynamic and would require frequent + // updates, for example by utilising publicsuffix.org or IANA. + pub fn can_add_to_dht(&self, addr: &Multiaddr) -> bool { + let ip = match addr.iter().next() { + Some(Protocol::Ip4(ip)) => IpNetwork::from(ip), + Some(Protocol::Ip6(ip)) => IpNetwork::from(ip), + Some(Protocol::Dns4(_)) | Some(Protocol::Dns6(_)) => return true, + _ => return false + }; + ip.is_global() + } } /// Event generated by the `DiscoveryBehaviour`. @@ -714,6 +747,7 @@ mod tests { let mut config = DiscoveryConfig::new(keypair.public()); config.with_user_defined(user_defined.clone()) .allow_private_ipv4(true) + .allow_non_globals_in_dht(true) .discovery_limit(50); config.finish() }; diff --git a/client/network/src/service.rs b/client/network/src/service.rs index e360a8defe..95d711be73 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -246,6 +246,7 @@ impl NetworkWorker { config.with_user_defined(known_addresses); config.discovery_limit(u64::from(params.network_config.out_peers) + 15); config.add_protocol(params.protocol_id.clone()); + config.allow_non_globals_in_dht(params.network_config.allow_non_globals_in_dht); match params.network_config.transport { TransportConfig::MemoryOnly => { diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 7b070f8041..40b373163b 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -611,6 +611,7 @@ pub trait TestNetFactory: Sized { ); network_config.transport = TransportConfig::MemoryOnly; network_config.listen_addresses = vec![listen_addr.clone()]; + network_config.allow_non_globals_in_dht = true; let network = NetworkWorker::new(sc_network::config::Params { role: Role::Full, @@ -687,6 +688,7 @@ pub trait TestNetFactory: Sized { ); network_config.transport = TransportConfig::MemoryOnly; network_config.listen_addresses = vec![listen_addr.clone()]; + network_config.allow_non_globals_in_dht = true; let network = NetworkWorker::new(sc_network::config::Params { role: Role::Light, diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 9b9140dd8d..810662edb0 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -150,6 +150,8 @@ fn node_config Date: Thu, 23 Apr 2020 09:58:43 +0200 Subject: [PATCH 294/300] client/network-gossip/state_machine: Reduce indentation level (#5714) * client/network-gossip/src/state_machine: Add unit test for on_incoming Add two unit tests to ensure `on_incoming` is ingoring discarded messages and reports and ignores messages from unknown peers. * client/network-gossip/state_machine: Reduce indentation level * client/network-gossip/bridge: Remove unnecessary into_iter * client/network-gossip/state_machine: Report success after register check * client/network-gossip/state_machine: Error not report on unregistered `peers` contains all the peers we're connected to. If we receive a message from a peer not in this list, that means there's an internal problem within the local client. It's not the fault of the peer in question. With the above in mind instead of reducing the reputation of such peer, log an error. --- client/network-gossip/src/bridge.rs | 2 +- client/network-gossip/src/state_machine.rs | 184 +++++++++++++-------- 2 files changed, 119 insertions(+), 67 deletions(-) diff --git a/client/network-gossip/src/bridge.rs b/client/network-gossip/src/bridge.rs index a15195111e..26e49fce8a 100644 --- a/client/network-gossip/src/bridge.rs +++ b/client/network-gossip/src/bridge.rs @@ -182,7 +182,7 @@ impl Future for GossipEngine { messages, ); - for (topic, notification) in to_forward.into_iter() { + for (topic, notification) in to_forward { if let Entry::Occupied(mut entry) = this.message_sinks.entry(topic) { trace!( target: "gossip", diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index 53b5b98245..433457afe7 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -20,7 +20,7 @@ use std::collections::{HashMap, HashSet}; use std::sync::Arc; use std::iter; use std::time; -use log::trace; +use log::{error, trace}; use lru::LruCache; use libp2p::PeerId; use sp_runtime::traits::{Block as BlockT, Hash, HashFor}; @@ -41,8 +41,6 @@ mod rep { pub const GOSSIP_SUCCESS: Rep = Rep::new(1 << 4, "Successfull gossip"); /// Reputation change when a peer sends us a gossip message that we already knew about. pub const DUPLICATE_GOSSIP: Rep = Rep::new(-(1 << 2), "Duplicate gossip"); - /// Reputation change when a peer sends a message from a topic it isn't registered on. - pub const UNREGISTERED_TOPIC: Rep = Rep::new(-(1 << 10), "Unregistered gossip message topic"); } struct PeerConsensus { @@ -308,36 +306,37 @@ impl ConsensusGossip { validator.validate(&mut context, &who, &message) }; - let validation_result = match validation { - ValidationResult::ProcessAndKeep(topic) => Some((topic, true)), - ValidationResult::ProcessAndDiscard(topic) => Some((topic, false)), - ValidationResult::Discard => None, + let (topic, keep) = match validation { + ValidationResult::ProcessAndKeep(topic) => (topic, true), + ValidationResult::ProcessAndDiscard(topic) => (topic, false), + ValidationResult::Discard => { + trace!(target:"gossip", "Discard message from peer {}", who); + continue; + }, }; - if let Some((topic, keep)) = validation_result { - network.report_peer(who.clone(), rep::GOSSIP_SUCCESS); - if let Some(ref mut peer) = self.peers.get_mut(&who) { - peer.known_messages.insert(message_hash); - - to_forward.push((topic, TopicNotification { - message: message.clone(), - sender: Some(who.clone()) - })); - - if keep { - self.register_message_hashed( - message_hash, - topic, - message, - Some(who.clone()), - ); - } - } else { - trace!(target:"gossip", "Ignored statement from unregistered peer {}", who); - network.report_peer(who.clone(), rep::UNREGISTERED_TOPIC); + let peer = match self.peers.get_mut(&who) { + Some(peer) => peer, + None => { + error!(target:"gossip", "Got message from unregistered peer {}", who); + continue; } - } else { - trace!(target:"gossip", "Discard message from peer {}", who); + }; + + network.report_peer(who.clone(), rep::GOSSIP_SUCCESS); + peer.known_messages.insert(message_hash); + to_forward.push((topic, TopicNotification { + message: message.clone(), + sender: Some(who.clone()) + })); + + if keep { + self.register_message_hashed( + message_hash, + topic, + message, + Some(who.clone()), + ); } } @@ -416,9 +415,10 @@ impl ConsensusGossip { #[cfg(test)] mod tests { - use std::sync::Arc; + use futures::prelude::*; + use sc_network::{Event, ReputationChange}; use sp_runtime::testing::{H256, Block as RawBlock, ExtrinsicWrapper}; - + use std::{borrow::Cow, pin::Pin, sync::{Arc, Mutex}}; use super::*; type Block = RawBlock>; @@ -448,6 +448,52 @@ mod tests { } } + struct DiscardAll; + impl Validator for DiscardAll{ + fn validate( + &self, + _context: &mut dyn ValidatorContext, + _sender: &PeerId, + _data: &[u8], + ) -> ValidationResult { + ValidationResult::Discard + } + } + + #[derive(Clone, Default)] + struct NoOpNetwork { + inner: Arc>, + } + + #[derive(Clone, Default)] + struct NoOpNetworkInner { + peer_reports: Vec<(PeerId, ReputationChange)>, + } + + impl Network for NoOpNetwork { + fn event_stream(&self) -> Pin + Send>> { + unimplemented!(); + } + + fn report_peer(&self, peer_id: PeerId, reputation_change: ReputationChange) { + self.inner.lock().unwrap().peer_reports.push((peer_id, reputation_change)); + } + + fn disconnect_peer(&self, _: PeerId) { + unimplemented!(); + } + + fn write_notification(&self, _: PeerId, _: ConsensusEngineId, _: Vec) { + unimplemented!(); + } + + fn register_notifications_protocol(&self, _: ConsensusEngineId, _: Cow<'static, [u8]>) {} + + fn announce(&self, _: B::Hash, _: Vec) { + unimplemented!(); + } + } + #[test] fn collects_garbage() { struct AllowOne; @@ -528,42 +574,9 @@ mod tests { #[test] fn peer_is_removed_on_disconnect() { - struct TestNetwork; - impl Network for TestNetwork { - fn event_stream( - &self, - ) -> std::pin::Pin + Send>> { - unimplemented!("Not required in tests") - } - - fn report_peer(&self, _: PeerId, _: crate::ReputationChange) { - unimplemented!("Not required in tests") - } - - fn disconnect_peer(&self, _: PeerId) { - unimplemented!("Not required in tests") - } - - fn write_notification(&self, _: PeerId, _: crate::ConsensusEngineId, _: Vec) { - unimplemented!("Not required in tests") - } - - fn register_notifications_protocol( - &self, - _: ConsensusEngineId, - _: std::borrow::Cow<'static, [u8]>, - ) { - unimplemented!("Not required in tests") - } - - fn announce(&self, _: H256, _: Vec) { - unimplemented!("Not required in tests") - } - } - let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), [0, 0, 0, 0]); - let mut network = TestNetwork; + let mut network = NoOpNetwork::default(); let peer_id = PeerId::random(); consensus.new_peer(&mut network, peer_id.clone(), ObservedRole::Full); @@ -572,4 +585,43 @@ mod tests { consensus.peer_disconnected(&mut network, peer_id.clone()); assert!(!consensus.peers.contains_key(&peer_id)); } + + #[test] + fn on_incoming_ignores_discarded_messages() { + let to_forward = ConsensusGossip::::new( + Arc::new(DiscardAll), + [0, 0, 0, 0], + ).on_incoming( + &mut NoOpNetwork::default(), + PeerId::random(), + vec![vec![1, 2, 3]], + ); + + assert!( + to_forward.is_empty(), + "Expected `on_incoming` to ignore discarded message but got {:?}", to_forward, + ); + } + + #[test] + fn on_incoming_ignores_unregistered_peer() { + let mut network = NoOpNetwork::default(); + let remote = PeerId::random(); + + let to_forward = ConsensusGossip::::new( + Arc::new(AllowAll), + [0, 0, 0, 0], + ).on_incoming( + &mut network, + // Unregistered peer. + remote.clone(), + vec![vec![1, 2, 3]], + ); + + assert!( + to_forward.is_empty(), + "Expected `on_incoming` to ignore message from unregistered peer but got {:?}", + to_forward, + ); + } } -- GitLab From 52aa0f27c91a375f213bf5ae4b33cd75598882a3 Mon Sep 17 00:00:00 2001 From: cheme Date: Thu, 23 Apr 2020 15:59:59 +0200 Subject: [PATCH 295/300] prototyping changes --- client/db/src/lib.rs | 26 +++++++++++++++----------- primitives/database/src/lib.rs | 28 ++++++++++++++++++++++++++++ primitives/database/src/mem.rs | 1 + 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 686f7f8494..9c66f9a7f2 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -1352,7 +1352,11 @@ fn apply_state_commit(transaction: &mut Transaction, commit: sc_state_db transaction.remove(columns::STATE, &key[..]); } for keyspace in commit.data.deleted_child.into_iter() { - transaction.delete_prefix(columns::STATE, &keyspace[..]); + let child_remove = sp_database::ChildBatchRemove { + root: Default::default(), // TODO EMCH change the commit set to contain childbatchremove + keyspace, + }; + transaction.delete_child(columns::STATE, child_remove); } for (key, val) in commit.meta.inserted.into_iter() { transaction.set_from_vec(columns::STATE_META, &key[..], val); @@ -1361,7 +1365,7 @@ fn apply_state_commit(transaction: &mut Transaction, commit: sc_state_db transaction.remove(columns::STATE_META, &key[..]); } for keyspace in commit.meta.deleted_child.into_iter() { - transaction.delete_prefix(columns::STATE_META, &keyspace[..]); + unimplemented!("TODO remove meta deleted child"); } } @@ -1908,11 +1912,11 @@ pub(crate) mod tests { assert_eq!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key[0], EMPTY_PREFIX) - ).unwrap().unwrap(), &b"hello1"[..]); + ).unwrap(), &b"hello1"[..]); assert_eq!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key[3], (storage_key, None)) - ).unwrap().unwrap(), &b"hello1"[..]); + ).unwrap(), &b"hello1"[..]); hash }; @@ -1952,11 +1956,11 @@ pub(crate) mod tests { assert_eq!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key[0], EMPTY_PREFIX) - ).unwrap().unwrap(), &b"hello1"[..]); + ).unwrap(), &b"hello1"[..]); assert_eq!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key[3], (storage_key, None)) - ).unwrap().unwrap(), &b"hello1"[..]); + ).unwrap(), &b"hello1"[..]); hash }; @@ -1992,11 +1996,11 @@ pub(crate) mod tests { assert_eq!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key[0], EMPTY_PREFIX) - ).unwrap().unwrap(), &b"hello1"[..]); + ).unwrap(), &b"hello1"[..]); assert_eq!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key[3], (storage_key, None)) - ).unwrap().unwrap(), &b"hello1"[..]); + ).unwrap(), &b"hello1"[..]); hash }; @@ -2031,15 +2035,15 @@ pub(crate) mod tests { assert_eq!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key[0], EMPTY_PREFIX) - ).unwrap().unwrap(), &b"hello1"[..]); + ).unwrap(), &b"hello1"[..]); assert!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key[3], (storage_key, None)) - ).unwrap().is_none()); + ).is_none()); assert!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key[4], (storage_key, None)) - ).unwrap().is_none()); + ).is_none()); } #[test] diff --git a/primitives/database/src/lib.rs b/primitives/database/src/lib.rs index bd9bd2eb54..48f3199437 100644 --- a/primitives/database/src/lib.rs +++ b/primitives/database/src/lib.rs @@ -32,6 +32,7 @@ pub enum Change { Remove(ColumnId, Vec), Store(H, Vec), Release(H), + DeleteChild(ColumnId, ChildBatchRemove), } /// An alteration to the database that references the data. @@ -40,6 +41,7 @@ pub enum ChangeRef<'a, H> { Remove(ColumnId, &'a [u8]), Store(H, &'a [u8]), Release(H), + DeleteChild(ColumnId, ChildBatchRemove), } /// A series of changes to the database that can be committed atomically. They do not take effect @@ -47,6 +49,20 @@ pub enum ChangeRef<'a, H> { #[derive(Default, Clone)] pub struct Transaction(pub Vec>); +/// Removing child trie got different +/// implementation depending on database +/// capability. +#[derive(Clone)] +pub struct ChildBatchRemove { + /// For database without key iteration + /// we delete by parsing the whole trie. + pub root: H, + + /// Database that allows iteration can only + /// delete all key using this keyspace. + pub keyspace: Vec, +} + impl Transaction { /// Create a new transaction to be prepared and committed atomically. pub fn new() -> Self { @@ -76,6 +92,10 @@ impl Transaction { pub fn release(&mut self, hash: H) { self.0.push(Change::Release(hash)) } + /// Set the value of `key` in `col` to `value`, replacing anything that is there currently. + pub fn delete_child(&mut self, col: ColumnId, child: ChildBatchRemove) { + self.0.push(Change::DeleteChild(col, child)) + } } pub trait Database: Send + Sync { @@ -88,6 +108,7 @@ pub trait Database: Send + Sync { Change::Remove(col, key) => self.remove(col, &key), Change::Store(hash, preimage) => self.store(&hash, &preimage), Change::Release(hash) => self.release(&hash), + Change::DeleteChild(col, child) => self.delete_child(col, child.clone()), } } } @@ -102,6 +123,7 @@ pub trait Database: Send + Sync { ChangeRef::Remove(col, key) => tx.remove(col, key), ChangeRef::Store(hash, preimage) => tx.store(hash, preimage), ChangeRef::Release(hash) => tx.release(hash), + ChangeRef::DeleteChild(col, child) => tx.delete_child(col, child.clone()), } } self.commit(tx); @@ -162,6 +184,12 @@ pub trait Database: Send + Sync { t.release(hash.clone()); self.commit(t); } + /// Set the value of `key` in `col` to `value`, replacing anything that is there currently. + fn delete_child(&self, col: ColumnId, child: ChildBatchRemove) { + let mut t = Transaction::new(); + t.delete_child(col, child); + self.commit(t); + } } /// Call `f` with the value previously stored against `key` and return the result, or `None` if diff --git a/primitives/database/src/mem.rs b/primitives/database/src/mem.rs index 09d6149bed..fa094fbd55 100644 --- a/primitives/database/src/mem.rs +++ b/primitives/database/src/mem.rs @@ -36,6 +36,7 @@ impl Database for MemDb Change::Remove(col, key) => { s.0.entry(col).or_default().remove(&key); }, Change::Store(hash, preimage) => { s.1.insert(hash, preimage); }, Change::Release(hash) => { s.1.remove(&hash); }, + Change::DeleteChild(col, child) => { unimplemented!("TODO EMCH") }, } } } -- GitLab From eb8a25da501fcdab66d5d3600c1ea4f9f990d6d3 Mon Sep 17 00:00:00 2001 From: cheme Date: Thu, 23 Apr 2020 18:32:57 +0200 Subject: [PATCH 296/300] would need rollback, this is going in a wrong direction --- Cargo.lock | 1 + client/db/src/lib.rs | 3 --- client/state-db/src/lib.rs | 13 +++++++++++-- client/state-db/src/test.rs | 4 ++-- primitives/database/src/kvdb.rs | 1 + primitives/database/src/lib.rs | 13 +++++++++++++ primitives/database/src/mem.rs | 20 ++++++++++++++++---- 7 files changed, 44 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5d5a90ecf..bad050e435 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7432,6 +7432,7 @@ version = "2.0.0-dev" dependencies = [ "kvdb", "parking_lot 0.10.2", + "sp-trie", ] [[package]] diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 9c66f9a7f2..f4d811fc18 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -1364,9 +1364,6 @@ fn apply_state_commit(transaction: &mut Transaction, commit: sc_state_db for key in commit.meta.deleted.into_iter() { transaction.remove(columns::STATE_META, &key[..]); } - for keyspace in commit.meta.deleted_child.into_iter() { - unimplemented!("TODO remove meta deleted child"); - } } impl sc_client_api::backend::AuxStore for Backend where Block: BlockT { diff --git a/client/state-db/src/lib.rs b/client/state-db/src/lib.rs index c949edf543..6c85654051 100644 --- a/client/state-db/src/lib.rs +++ b/client/state-db/src/lib.rs @@ -114,6 +114,15 @@ impl fmt::Debug for Error { } } +/// A set of key value data changes. +#[derive(Default, Debug, Clone)] +pub struct MetaChangeSet { + /// Inserted values. + pub inserted: Vec<(Vec, DBValue)>, + /// Deleted values. + pub deleted: Vec>, +} + /// A set of state node changes. #[derive(Default, Debug, Clone)] pub struct ChangeSet { @@ -132,7 +141,7 @@ pub struct CommitSet { /// State node changes. pub data: ChangeSet, /// Metadata changes. - pub meta: ChangeSet>, + pub meta: MetaChangeSet, } /// Pruning constraints. If none are specified pruning is @@ -249,7 +258,7 @@ impl StateDbSync, ) -> Result, Error> { - let mut meta = ChangeSet::default(); + let mut meta = MetaChangeSet::default(); if number == 0 { // Save pruning mode when writing first block. meta.inserted.push((to_meta_key(PRUNING_MODE, &()), self.mode.id().into())); diff --git a/client/state-db/src/test.rs b/client/state-db/src/test.rs index 84bcd62b38..3d92ccc252 100644 --- a/client/state-db/src/test.rs +++ b/client/state-db/src/test.rs @@ -18,7 +18,7 @@ use std::collections::HashMap; use sp_core::H256; -use crate::{DBValue, ChangeSet, CommitSet, MetaDb, NodeDb}; +use crate::{DBValue, ChangeSet, MetaChangeSet, CommitSet, MetaDb, NodeDb}; #[derive(Default, Debug, Clone, PartialEq, Eq)] pub struct TestDb { @@ -77,7 +77,7 @@ pub fn make_changeset(inserted: &[u64], deleted: &[u64]) -> ChangeSet { pub fn make_commit(inserted: &[u64], deleted: &[u64]) -> CommitSet { CommitSet { data: make_changeset(inserted, deleted), - meta: ChangeSet::default(), + meta: MetaChangeSet::default(), } } diff --git a/primitives/database/src/kvdb.rs b/primitives/database/src/kvdb.rs index 85a324b5c1..a5a24821e8 100644 --- a/primitives/database/src/kvdb.rs +++ b/primitives/database/src/kvdb.rs @@ -43,6 +43,7 @@ impl Database for DbAdapter { match change { Change::Set(col, key, value) => tx.put_vec(col, &key, value), Change::Remove(col, key) => tx.delete(col, &key), + Change::DeleteChild(col, child) => tx.delete_prefix(col, child.keyspace.as_slice()), _ => unimplemented!(), } } diff --git a/primitives/database/src/lib.rs b/primitives/database/src/lib.rs index 48f3199437..607d7c205c 100644 --- a/primitives/database/src/lib.rs +++ b/primitives/database/src/lib.rs @@ -99,8 +99,10 @@ impl Transaction { } pub trait Database: Send + Sync { + /// Commit the `transaction` to the database atomically. Any further calls to `get` or `lookup` /// will reflect the new state. + /// A call back for manual child deletion is provided. fn commit(&self, transaction: Transaction) { for change in transaction.0.into_iter() { match change { @@ -184,6 +186,7 @@ pub trait Database: Send + Sync { t.release(hash.clone()); self.commit(t); } + /// Set the value of `key` in `col` to `value`, replacing anything that is there currently. fn delete_child(&self, col: ColumnId, child: ChildBatchRemove) { let mut t = Transaction::new(); @@ -213,3 +216,13 @@ pub fn with_lookup(db: &dyn Database, hash: &H, mut f: impl FnMu db.with_lookup(hash, &mut adapter); result } + +/// Iterate on key of a state. +pub trait ForKeys { + /// Reset context. + fn init(&mut self, col: ColumnId, root: H); + /// Keys to delete, note that we return an iterator to be able to delete at the same + /// time as parsing. + /// Thus parsing should only access elements once. + fn next_key(&mut self) -> Option>; +} diff --git a/primitives/database/src/mem.rs b/primitives/database/src/mem.rs index fa094fbd55..208dacb7c7 100644 --- a/primitives/database/src/mem.rs +++ b/primitives/database/src/mem.rs @@ -20,10 +20,13 @@ use std::collections::HashMap; use crate::{Database, Transaction, ColumnId, Change}; use parking_lot::RwLock; +type InnerMemDb = RwLock<(HashMap, Vec>>, HashMap>)>; #[derive(Default)] /// This implements `Database` as an in-memory hash map. `commit` is not atomic. -pub struct MemDb - (RwLock<(HashMap, Vec>>, HashMap>)>); +pub struct MemDb ( + InnerMemDb, + fn(&H, +); impl Database for MemDb where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash @@ -36,7 +39,17 @@ impl Database for MemDb Change::Remove(col, key) => { s.0.entry(col).or_default().remove(&key); }, Change::Store(hash, preimage) => { s.1.insert(hash, preimage); }, Change::Release(hash) => { s.1.remove(&hash); }, - Change::DeleteChild(col, child) => { unimplemented!("TODO EMCH") }, + Change::DeleteChild(col, child) => { + let trie = sp_trie::for_keys_in_trie::, _, _> ( + self, + &child.root, + |key: &[u8]| { + self.remove(col, key) + }, + ).map_err(|_e| { + // ignoring + }); + }, } } } @@ -66,4 +79,3 @@ impl MemDb s.0.get(&col).map(|c| c.len()).unwrap_or(0) } } - -- GitLab From c48ea04486b32f065b53fa623613e7f755640509 Mon Sep 17 00:00:00 2001 From: cheme Date: Fri, 24 Apr 2020 10:34:07 +0200 Subject: [PATCH 297/300] might be ok design (could use &mut dyn ptr too, but this seems less impacting for a start). --- Cargo.lock | 1 - primitives/database/src/lib.rs | 43 ++++++++++++++++++++-------- primitives/database/src/mem.rs | 52 +++++++++++++++++++++++----------- 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bad050e435..e5d5a90ecf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7432,7 +7432,6 @@ version = "2.0.0-dev" dependencies = [ "kvdb", "parking_lot 0.10.2", - "sp-trie", ] [[package]] diff --git a/primitives/database/src/lib.rs b/primitives/database/src/lib.rs index 607d7c205c..319c412240 100644 --- a/primitives/database/src/lib.rs +++ b/primitives/database/src/lib.rs @@ -32,7 +32,7 @@ pub enum Change { Remove(ColumnId, Vec), Store(H, Vec), Release(H), - DeleteChild(ColumnId, ChildBatchRemove), + DeleteChild(ColumnId, ChildBatchRemove), } /// An alteration to the database that references the data. @@ -41,7 +41,7 @@ pub enum ChangeRef<'a, H> { Remove(ColumnId, &'a [u8]), Store(H, &'a [u8]), Release(H), - DeleteChild(ColumnId, ChildBatchRemove), + DeleteChild(ColumnId, ChildBatchRemove), } /// A series of changes to the database that can be committed atomically. They do not take effect @@ -53,10 +53,10 @@ pub struct Transaction(pub Vec>); /// implementation depending on database /// capability. #[derive(Clone)] -pub struct ChildBatchRemove { +pub struct ChildBatchRemove { /// For database without key iteration /// we delete by parsing the whole trie. - pub root: H, + pub encoded_root: Vec, /// Database that allows iteration can only /// delete all key using this keyspace. @@ -93,7 +93,7 @@ impl Transaction { self.0.push(Change::Release(hash)) } /// Set the value of `key` in `col` to `value`, replacing anything that is there currently. - pub fn delete_child(&mut self, col: ColumnId, child: ChildBatchRemove) { + pub fn delete_child(&mut self, col: ColumnId, child: ChildBatchRemove) { self.0.push(Change::DeleteChild(col, child)) } } @@ -188,7 +188,7 @@ pub trait Database: Send + Sync { } /// Set the value of `key` in `col` to `value`, replacing anything that is there currently. - fn delete_child(&self, col: ColumnId, child: ChildBatchRemove) { + fn delete_child(&self, col: ColumnId, child: ChildBatchRemove) { let mut t = Transaction::new(); t.delete_child(col, child); self.commit(t); @@ -217,12 +217,31 @@ pub fn with_lookup(db: &dyn Database, hash: &H, mut f: impl FnMu result } +/// To use with state cursor for querying only. +pub trait DatabaseRef { + /// Retrieve the value previously stored against `key` or `None` if + /// `key` is not currently in the database. + fn get(&self, col: ColumnId, key: &[u8]) -> Option>; +} + /// Iterate on key of a state. -pub trait ForKeys { - /// Reset context. - fn init(&mut self, col: ColumnId, root: H); - /// Keys to delete, note that we return an iterator to be able to delete at the same - /// time as parsing. - /// Thus parsing should only access elements once. +pub trait StateCursor: Send + Sync { + /// Define context and clear previous usage state. + fn init(&mut self, db: &DB, col: ColumnId, encoded_root: Vec); + /// Ordered iteration on all state keys. + /// This can be use to delete in a streaming way, so + /// the inner iteration need to query only once its element or + /// buffer its results (allows delete element when and iterating + /// at the same time). fn next_key(&mut self) -> Option>; } + +/// Dummy implementation of state cursor for case +/// where the cursor is not needed. +#[derive(Debug, Clone, Copy, Default)] +pub struct DummyStateCursor; + +impl StateCursor for DummyStateCursor { + fn init(&mut self, _db: &DB, _col: ColumnId, _root: Vec) { } + fn next_key(&mut self) -> Option> { None } +} diff --git a/primitives/database/src/mem.rs b/primitives/database/src/mem.rs index 208dacb7c7..30d3f72117 100644 --- a/primitives/database/src/mem.rs +++ b/primitives/database/src/mem.rs @@ -17,17 +17,31 @@ //! In-memory implementation of `Database` use std::collections::HashMap; -use crate::{Database, Transaction, ColumnId, Change}; +use crate::{Database, DatabaseRef, Transaction, ColumnId, Change}; use parking_lot::RwLock; +use parking_lot::Mutex; type InnerMemDb = RwLock<(HashMap, Vec>>, HashMap>)>; -#[derive(Default)] /// This implements `Database` as an in-memory hash map. `commit` is not atomic. pub struct MemDb ( InnerMemDb, - fn(&H, + Mutex>>>, ); +impl Default for MemDb + where + H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash, +{ + // Memdb is very unlikely to use its state cursor + // so its default implementation is using the dummy cursor. + fn default() -> Self { + MemDb( + InnerMemDb::default(), + Mutex::new(Box::new(crate::DummyStateCursor)), + ) + } +} + impl Database for MemDb where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash { @@ -40,23 +54,22 @@ impl Database for MemDb Change::Store(hash, preimage) => { s.1.insert(hash, preimage); }, Change::Release(hash) => { s.1.remove(&hash); }, Change::DeleteChild(col, child) => { - let trie = sp_trie::for_keys_in_trie::, _, _> ( - self, - &child.root, - |key: &[u8]| { - self.remove(col, key) - }, - ).map_err(|_e| { - // ignoring - }); + let mut cursor = self.1.lock(); + cursor.init(&self.0, col, child.encoded_root); + loop { + if let Some(key) = cursor.next_key() { + self.remove(col, key.as_slice()) + } else { + break; + } + } }, } } } fn get(&self, col: ColumnId, key: &[u8]) -> Option> { - let s = self.0.read(); - s.0.get(&col).and_then(|c| c.get(key).cloned()) + self.0.get(col, key) } fn lookup(&self, hash: &H) -> Option> { @@ -69,8 +82,8 @@ impl MemDb where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash { /// Create a new instance - pub fn new() -> Self { - MemDb::default() + pub fn new> + 'static>(c: C) -> Self { + MemDb(Default::default(), Mutex::new(Box::new(c))) } /// Count number of values in a column @@ -79,3 +92,10 @@ impl MemDb s.0.get(&col).map(|c| c.len()).unwrap_or(0) } } + +impl DatabaseRef for InnerMemDb { + fn get(&self, col: ColumnId, key: &[u8]) -> Option> { + let s = self.read(); + s.0.get(&col).and_then(|c| c.get(key).cloned()) + } +} -- GitLab From 8e636331c752065660c9472b4bcc3d9f47f3a391 Mon Sep 17 00:00:00 2001 From: cheme Date: Fri, 24 Apr 2020 17:41:14 +0200 Subject: [PATCH 298/300] Ok design (no trait an pure fn ptr). Adapt test, do not delete (but we do not pass the root). --- client/db/Cargo.toml | 5 +- client/db/src/lib.rs | 84 ++++++++++++++++++++++++++++++++-- client/db/src/parity_db.rs | 69 ++++++++++++++++++++++++---- client/db/src/subdb.rs | 27 +++++++++-- client/db/src/utils.rs | 5 +- primitives/database/src/lib.rs | 40 ++++++++-------- primitives/database/src/mem.rs | 42 ++++++++--------- primitives/trie/src/lib.rs | 1 + 8 files changed, 209 insertions(+), 64 deletions(-) diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index 10ad5e30f1..cbbcdf413d 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -35,6 +35,7 @@ sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/commo sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } sp-database = { version = "2.0.0-dev", path = "../../primitives/database" } parity-db = { version = "0.1", optional = true } +tempfile = { version = "3", optional = true } prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-dev", path = "../../utils/prometheus" } [dev-dependencies] @@ -46,5 +47,5 @@ kvdb-rocksdb = "0.7" tempfile = "3" [features] -default = [] -test-helpers = [] +default = ["parity-db"] +test-helpers = ["tempfile"] diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index f4d811fc18..bd76400965 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -717,6 +717,55 @@ impl sp_state_machine::Storage> for StorageDb ( + db: &DB, + col: sp_database::ColumnId, + batch: sp_database::ChildBatchRemove, + state: &mut S, + action: fn(db: &DB, col: sp_database::ColumnId, key: &[u8], state: &mut S), +) where + DB: sp_database::DatabaseRef, + H: hash_db::Hasher, + H::Out: Decode, +{ + let mut prefixed_key_buf = Vec::with_capacity(batch.keyspace.len() + 40); + + // we ignore all error here, TODO EMCH we could log it in some db dedicated key (like in meta) + if let Ok(root) = H::Out::decode(&mut batch.encoded_root.as_slice()) { + let ks_db = KeyspacedDB(db, &batch.keyspace, col); + if let Ok(trie) = sp_trie::TrieDB::>::new(&ks_db, &root) { + if let Ok(iter) = sp_trie::TrieDBNodeIterator::new(&trie) { + for x in iter { + if let Ok((prefix, Some(key_hash), _)) = x { + prefixed_key_buf.clear(); + prefixed_key_buf.extend_from_slice(&batch.keyspace[..]); + let trie_key = sp_trie::prefixed_key::(&key_hash, prefix.as_prefix()); + prefixed_key_buf.extend_from_slice(trie_key.as_slice()); + action(db, col, prefixed_key_buf.as_slice(), state); + } + } + } + } + } +} + +struct KeyspacedDB<'a, DB: sp_database::DatabaseRef>(&'a DB, &'a[u8], sp_database::ColumnId); + +impl<'a, H: hash_db::Hasher, DB: sp_database::DatabaseRef> hash_db::HashDBRef> for KeyspacedDB<'a, DB> { + fn get(&self, key: &H::Out, prefix: hash_db::Prefix) -> Option> { + let mut prefixed_key = Vec::with_capacity(self.1.len() + 40); + prefixed_key.extend_from_slice(&self.1[..]); + let trie_key = sp_trie::prefixed_key::(key, prefix); + prefixed_key.extend_from_slice(trie_key.as_slice()); + ::get(self.0, self.2, &prefixed_key) + } + + fn contains(&self, key: &H::Out, prefix: hash_db::Prefix) -> bool { + >>::get(self, key, prefix).is_some() + } +} + impl sc_state_db::NodeDb for StorageDb { type Error = io::Error; type Key = [u8]; @@ -828,6 +877,24 @@ impl Backend { Self::new(db_setting, canonicalization_delay).expect("failed to create test-db") } + /// Create new memory-backed client backend for tests, using + /// parity-db + #[cfg(all(feature = "parity-db", any(test, feature = "test-helpers")))] + pub fn new_test_parity_db(keep_blocks: u32, canonicalization_delay: u64) -> Self { + use tempfile::tempdir; + let base_path = tempdir().expect("could not create a temp dir"); + let db_setting = DatabaseSettings { + state_cache_size: 16777216, + state_cache_child_ratio: Some((50, 100)), + pruning: PruningMode::keep_blocks(keep_blocks), + source: DatabaseSettingsSrc::ParityDb { + path: base_path.path().into(), + }, + }; + Self::new(db_setting, canonicalization_delay).expect("failed to create test-db") + } + + fn from_database( db: Arc>, canonicalization_delay: u64, @@ -1353,7 +1420,7 @@ fn apply_state_commit(transaction: &mut Transaction, commit: sc_state_db } for keyspace in commit.data.deleted_child.into_iter() { let child_remove = sp_database::ChildBatchRemove { - root: Default::default(), // TODO EMCH change the commit set to contain childbatchremove + encoded_root: Default::default(), // TODO EMCH change the commit set to contain childbatchremove keyspace, }; transaction.delete_child(columns::STATE, child_remove); @@ -1855,11 +1922,22 @@ pub(crate) mod tests { } } + #[cfg(feature = "parity-db")] + #[test] + fn bulk_delete_child_trie_parity_db() { + let backend = Backend::::new_test_parity_db(2, 0); + bulk_delete_child_trie_inner(backend); + } + #[test] fn bulk_delete_child_trie() { + let backend = Backend::::new_test(2, 0); + bulk_delete_child_trie_inner(backend); + } + + fn bulk_delete_child_trie_inner(backend: Backend) { let _ = ::env_logger::try_init(); let mut key = Vec::new(); - let backend = Backend::::new_test(2, 0); // This is not collision resistant but enough for the test. let storage_key = b"unique_storage_key"; @@ -1941,7 +2019,7 @@ pub(crate) mod tests { let child = op.db_updates.entry(ChildInfo::new_default(storage_key)) .or_insert_with(Default::default); - child.0 = ChildChange::BulkDeleteByKeyspace; + child.0 = ChildChange::BulkDeleteByKeyspace; op.set_block_data( header, Some(vec![]), diff --git a/client/db/src/parity_db.rs b/client/db/src/parity_db.rs index a4e64d310b..2f5877fdd5 100644 --- a/client/db/src/parity_db.rs +++ b/client/db/src/parity_db.rs @@ -16,9 +16,13 @@ /// A `Database` adapter for parity-db. -use sp_database::{Database, Change, Transaction, ColumnId}; +use sp_database::{Database, DatabaseRef, Change, Transaction, ColumnId, StateCursor}; -struct DbAdapter(parity_db::Db); +/// TODO EMCH make it private again (leaked from open input type) +pub struct DbAdapter( + parity_db::Db, + StateCursor, +); fn handle_err(result: parity_db::Result) -> T { match result { @@ -29,18 +33,61 @@ fn handle_err(result: parity_db::Result) -> T { } } -/// Wrap RocksDb database into a trait object that implements `sp_database::Database` -pub fn open(path: &std::path::Path, num_columns: u32) -> parity_db::Result>> { +/// Wrap ParityDb database into a trait object that implements `sp_database::Database` +pub fn open( + path: &std::path::Path, + num_columns: u32, + cursor: StateCursor, +) -> parity_db::Result>> { let db = parity_db::Db::with_columns(path, num_columns as u8)?; - Ok(std::sync::Arc::new(DbAdapter(db))) + Ok(std::sync::Arc::new(DbAdapter(db, cursor))) } +const BATCH_CHILD_DELETE_SIZE: usize = 256; + +/// TODO EMCH make it private (leaked from open input type) +pub struct BatchChildDelete { + ix: usize, + batch: Vec<(u8, Vec)>, +} impl Database for DbAdapter { fn commit(&self, transaction: Transaction) { - handle_err(self.0.commit(transaction.0.into_iter().map(|change| + transaction.0.iter().for_each(|change| match change { - Change::Set(col, key, value) => (col as u8, key, Some(value)), - Change::Remove(col, key) => (col as u8, key, None), + Change::DeleteChild(col, child) => { + let mut batch = BatchChildDelete { + ix: 0, + batch: vec![(0, Vec::new()); 256], + }; + + fn extract_input(i: &mut (u8, Vec)) -> (u8, Vec, Option>) { + let key = std::mem::replace(&mut i.1, Vec::new()); + (i.0, key, None) + }; + + self.1(&self, *col, child.clone(), &mut batch, |db, col, key, batch| { + batch.batch[batch.ix] = (col as u8, key.to_vec()); + batch.ix += 1; + if batch.ix == BATCH_CHILD_DELETE_SIZE { + handle_err(db.0.commit(batch.batch[..].iter_mut().map(extract_input))); + batch.ix = 0; + } + }); + + if batch.ix > 0 { + handle_err(self.0.commit(batch.batch[..batch.ix].iter_mut().map(extract_input))); + } + + }, + _ => (), + } + ); + + handle_err(self.0.commit(transaction.0.into_iter().filter_map(|change| + match change { + Change::Set(col, key, value) => Some((col as u8, key, Some(value))), + Change::Remove(col, key) => Some((col as u8, key, None)), + Change::DeleteChild(..) => None, _ => unimplemented!(), })) ); @@ -54,3 +101,9 @@ impl Database for DbAdapter { unimplemented!(); } } + +impl DatabaseRef for DbAdapter { + fn get(&self, col: ColumnId, key: &[u8]) -> Option> { + handle_err(self.0.get(col as u8, key)) + } +} diff --git a/client/db/src/subdb.rs b/client/db/src/subdb.rs index 2e436aa2c9..d58216bea8 100644 --- a/client/db/src/subdb.rs +++ b/client/db/src/subdb.rs @@ -17,7 +17,9 @@ /// A `Database` adapter for subdb. use sp_database::{self, ColumnId}; +use sp_database::{DatabaseRef, StateCursor}; use parking_lot::RwLock; +use parking_lot::Mutex; use blake2_rfc::blake2b::blake2b; use codec::Encode; use subdb::{Database, KeyType}; @@ -25,15 +27,20 @@ use subdb::{Database, KeyType}; /// A database hidden behind an RwLock, so that it implements Send + Sync. /// /// Construct by creating a `Database` and then using `.into()`. -pub struct DbAdapter(RwLock>); +pub struct DbAdapter( + RwLock>, + StateCursor, BatchChildDelete>, +); -/// Wrap RocksDb database into a trait object that implements `sp_database::Database` -pub fn open( +/// Wrap SubDb database into a trait object that implements `sp_database::Database` +pub fn open>( path: &std::path::Path, _num_columns: u32, + cursor: C, ) -> Result>, subdb::Error> { let db = subdb::Options::from_path(path.into()).open()?; - Ok(std::sync::Arc::new(DbAdapter(RwLock::new(db)))) + let cursor = Mutex::new(Box::new(cursor)); + Ok(std::sync::Arc::new(DbAdapter(RwLock::new(db)), cursor)) } impl sp_database::Database for DbAdapter { @@ -84,4 +91,16 @@ impl sp_database::Database for DbAdapter { fn release(&self, hash: &H) { let _ = self.0.write().remove(hash); } + + fn delete_child(&self, col: ColumnId, child: ChildBatchRemove) { + self.1(&self, col, child, &mut (), |db, col, key, _state| { + db.remove(col, key.as_slice()) + }); + } +} + +impl sp_database::DatabaseRef for DbAdapter { + fn get(&self, col: ColumnId, key: &[u8]) -> Option> { + >::get(col, key) + } } diff --git a/client/db/src/utils.rs b/client/db/src/utils.rs index 9506dc4e7f..c2bac330ca 100644 --- a/client/db/src/utils.rs +++ b/client/db/src/utils.rs @@ -249,12 +249,13 @@ pub fn open_database( }, #[cfg(feature = "subdb")] DatabaseSettingsSrc::SubDb { path } => { - crate::subdb::open(&path, NUM_COLUMNS) + crate::subdb::open(&path, NUM_COLUMNS, crate::child_trie_cursor) .map_err(|e| sp_blockchain::Error::Backend(format!("{:?}", e)))? }, #[cfg(feature = "parity-db")] DatabaseSettingsSrc::ParityDb { path } => { - crate::parity_db::open(&path, NUM_COLUMNS) + let cursor = crate::child_trie_cursor::<_, sp_runtime::traits::HashFor, _>; + crate::parity_db::open(&path, NUM_COLUMNS, cursor) .map_err(|e| sp_blockchain::Error::Backend(format!("{:?}", e)))? }, DatabaseSettingsSrc::Custom(db) => db.clone(), diff --git a/primitives/database/src/lib.rs b/primitives/database/src/lib.rs index 319c412240..b219247906 100644 --- a/primitives/database/src/lib.rs +++ b/primitives/database/src/lib.rs @@ -218,30 +218,26 @@ pub fn with_lookup(db: &dyn Database, hash: &H, mut f: impl FnMu } /// To use with state cursor for querying only. -pub trait DatabaseRef { +pub trait DatabaseRef: Send { /// Retrieve the value previously stored against `key` or `None` if /// `key` is not currently in the database. fn get(&self, col: ColumnId, key: &[u8]) -> Option>; } - -/// Iterate on key of a state. -pub trait StateCursor: Send + Sync { - /// Define context and clear previous usage state. - fn init(&mut self, db: &DB, col: ColumnId, encoded_root: Vec); - /// Ordered iteration on all state keys. - /// This can be use to delete in a streaming way, so - /// the inner iteration need to query only once its element or - /// buffer its results (allows delete element when and iterating - /// at the same time). - fn next_key(&mut self) -> Option>; -} -/// Dummy implementation of state cursor for case -/// where the cursor is not needed. -#[derive(Debug, Clone, Copy, Default)] -pub struct DummyStateCursor; - -impl StateCursor for DummyStateCursor { - fn init(&mut self, _db: &DB, _col: ColumnId, _root: Vec) { } - fn next_key(&mut self) -> Option> { None } -} +/// Iterate on key of a state. +pub type StateCursor = fn( + db: &DB, + col: ColumnId, + batch: ChildBatchRemove, + state: &mut S, + action: fn(db: &DB, col: ColumnId, key: &[u8], state: &mut S), +); + +/// Define context and clear previous usage state. +pub fn dummy_state_cursor( + _db: &DB, + _col: ColumnId, + _batch: ChildBatchRemove, + _state: &mut S, + _action: fn(db: &DB, col: ColumnId, key: &[u8], state: &mut S), +) { } diff --git a/primitives/database/src/mem.rs b/primitives/database/src/mem.rs index 30d3f72117..c4a3198ee7 100644 --- a/primitives/database/src/mem.rs +++ b/primitives/database/src/mem.rs @@ -19,15 +19,15 @@ use std::collections::HashMap; use crate::{Database, DatabaseRef, Transaction, ColumnId, Change}; use parking_lot::RwLock; -use parking_lot::Mutex; -type InnerMemDb = RwLock<(HashMap, Vec>>, HashMap>)>; /// This implements `Database` as an in-memory hash map. `commit` is not atomic. pub struct MemDb ( InnerMemDb, - Mutex>>>, + crate::StateCursor, ()>, ); +type InnerMemDb = RwLock<(HashMap, Vec>>, HashMap>)>; + impl Default for MemDb where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash, @@ -37,7 +37,7 @@ impl Default for MemDb fn default() -> Self { MemDb( InnerMemDb::default(), - Mutex::new(Box::new(crate::DummyStateCursor)), + crate::dummy_state_cursor, ) } } @@ -46,30 +46,24 @@ impl Database for MemDb where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash { fn commit(&self, transaction: Transaction) { - let mut s = self.0.write(); + let s = || self.0.write(); for change in transaction.0.into_iter() { match change { - Change::Set(col, key, value) => { s.0.entry(col).or_default().insert(key, value); }, - Change::Remove(col, key) => { s.0.entry(col).or_default().remove(&key); }, - Change::Store(hash, preimage) => { s.1.insert(hash, preimage); }, - Change::Release(hash) => { s.1.remove(&hash); }, + Change::Set(col, key, value) => { s().0.entry(col).or_default().insert(key, value); }, + Change::Remove(col, key) => { s().0.entry(col).or_default().remove(&key); }, + Change::Store(hash, preimage) => { s().1.insert(hash, preimage); }, + Change::Release(hash) => { s().1.remove(&hash); }, Change::DeleteChild(col, child) => { - let mut cursor = self.1.lock(); - cursor.init(&self.0, col, child.encoded_root); - loop { - if let Some(key) = cursor.next_key() { - self.remove(col, key.as_slice()) - } else { - break; - } - } + self.1(&self, col, child, &mut (), |db, col, key, _state| { + db.0.write().0.entry(col).or_default().remove(key); + }); }, } } } fn get(&self, col: ColumnId, key: &[u8]) -> Option> { - self.0.get(col, key) + ::get(self, col, key) } fn lookup(&self, hash: &H) -> Option> { @@ -82,8 +76,8 @@ impl MemDb where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash { /// Create a new instance - pub fn new> + 'static>(c: C) -> Self { - MemDb(Default::default(), Mutex::new(Box::new(c))) + pub fn new(c: crate::StateCursor, ()>) -> Self { + MemDb(Default::default(), c) } /// Count number of values in a column @@ -93,9 +87,11 @@ impl MemDb } } -impl DatabaseRef for InnerMemDb { +impl DatabaseRef for MemDb + where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash +{ fn get(&self, col: ColumnId, key: &[u8]) -> Option> { - let s = self.read(); + let s = self.0.read(); s.0.get(&col).and_then(|c| c.get(key).cloned()) } } diff --git a/primitives/trie/src/lib.rs b/primitives/trie/src/lib.rs index 25b743dc64..db3a644045 100644 --- a/primitives/trie/src/lib.rs +++ b/primitives/trie/src/lib.rs @@ -29,6 +29,7 @@ use sp_std::marker::PhantomData; use sp_std::vec::Vec; use sp_core::{Hasher, InnerHasher}; use trie_db::proof::{generate_proof, verify_proof}; +pub use trie_db::TrieDBNodeIterator; pub use trie_db::proof::VerifyError; /// Our `NodeCodec`-specific error. pub use error::Error; -- GitLab From 7afbe6ae71cf61d5781c36964c7aaa4a47c2f920 Mon Sep 17 00:00:00 2001 From: cheme Date: Mon, 27 Apr 2020 12:19:48 +0200 Subject: [PATCH 299/300] add root to child change --- Cargo.lock | 1 + client/api/src/notifications.rs | 2 +- client/db/src/bench.rs | 4 +- client/db/src/lib.rs | 18 +++++---- client/db/src/parity_db.rs | 1 + client/db/src/storage_cache.rs | 6 +-- client/src/light/backend.rs | 9 +++-- client/state-db/src/lib.rs | 4 +- client/state-db/src/noncanonical.rs | 4 +- client/state-db/src/pruning.rs | 6 +-- primitives/runtime/src/lib.rs | 6 +-- primitives/state-machine/src/backend.rs | 6 +-- primitives/state-machine/src/basic.rs | 2 +- .../state-machine/src/changes_trie/build.rs | 11 ++++-- .../state-machine/src/changes_trie/input.rs | 33 +--------------- primitives/state-machine/src/ext.rs | 12 ++++-- .../state-machine/src/in_memory_backend.rs | 24 ++++++------ .../state-machine/src/overlayed_changes.rs | 39 ++++++++++++------- .../state-machine/src/proving_backend.rs | 6 +-- primitives/state-machine/src/testing.rs | 16 ++++---- primitives/state-machine/src/trie_backend.rs | 8 ++-- primitives/storage/Cargo.toml | 3 +- primitives/storage/src/lib.rs | 34 +++++++--------- 23 files changed, 126 insertions(+), 129 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5d5a90ecf..5e07fb90d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7732,6 +7732,7 @@ name = "sp-storage" version = "2.0.0-dev" dependencies = [ "impl-serde 0.2.3", + "parity-scale-codec", "ref-cast", "serde", "sp-debug-derive", diff --git a/client/api/src/notifications.rs b/client/api/src/notifications.rs index 2ad1bce770..f9b282c857 100644 --- a/client/api/src/notifications.rs +++ b/client/api/src/notifications.rs @@ -51,7 +51,7 @@ impl StorageChangeSet { .filter_map(move |(sk, change, changes)| { if let Some(cf) = self.child_filters.as_ref() { if let Some(filter) = cf.get(sk) { - let bulk_delete = change == &ChildChange::BulkDeleteByKeyspace; + let bulk_delete = matches!(change, ChildChange::BulkDeleteByKeyspace(..)); Some(changes .iter() .filter(move |&(key, _)| if bulk_delete { diff --git a/client/db/src/bench.rs b/client/db/src/bench.rs index a186635e8c..6ddcb44152 100644 --- a/client/db/src/bench.rs +++ b/client/db/src/bench.rs @@ -219,7 +219,7 @@ impl StateBackend> for BenchmarkingState { fn child_storage_root( &self, child_info: &ChildInfo, - child_change: ChildChange, + child_change: &ChildChange, delta: I, ) -> (B::Hash, bool, Self::Transaction) where I: IntoIterator, Option>)>, @@ -266,7 +266,7 @@ impl StateBackend> for BenchmarkingState { info.child_type(), ); } - if change == ChildChange::BulkDeleteByKeyspace { + if let ChildChange::BulkDeleteByKeyspace(..) = change { db_transaction.delete_prefix(0, info.keyspace()); } else { keyspace.change_keyspace(info.keyspace()); diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index bd76400965..6e00aaa607 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -224,7 +224,7 @@ impl StateBackend> for RefTrackingState { fn child_storage_root( &self, child_info: &ChildInfo, - child_change: ChildChange, + child_change: &ChildChange, delta: I, ) -> (B::Hash, bool, Self::Transaction) where @@ -1184,8 +1184,8 @@ impl Backend { info.child_type(), ))); } - if change == ChildChange::BulkDeleteByKeyspace { - state_db_changeset.deleted_child.push(info.keyspace().to_vec()); + if let ChildChange::BulkDeleteByKeyspace(encoded_root) = change { + state_db_changeset.deleted_child.push((info.keyspace().to_vec(), encoded_root)); } else { keyspace.change_keyspace(info.keyspace()); for (key, (val, rc)) in updates.drain() { @@ -1418,9 +1418,9 @@ fn apply_state_commit(transaction: &mut Transaction, commit: sc_state_db for key in commit.data.deleted.into_iter() { transaction.remove(columns::STATE, &key[..]); } - for keyspace in commit.data.deleted_child.into_iter() { + for (keyspace, encoded_root) in commit.data.deleted_child.into_iter() { let child_remove = sp_database::ChildBatchRemove { - encoded_root: Default::default(), // TODO EMCH change the commit set to contain childbatchremove + encoded_root, keyspace, }; transaction.delete_child(columns::STATE, child_remove); @@ -2017,9 +2017,13 @@ pub(crate) mod tests { ).0.into(); let hash = header.hash(); - let child = op.db_updates.entry(ChildInfo::new_default(storage_key)) + let child_info = ChildInfo::new_default(storage_key); + let child_root = op.old_state.storage(&child_info.prefixed_storage_key()) + .unwrap() + .expect("Some child content in previous state").clone(); + let child = op.db_updates.entry(child_info) .or_insert_with(Default::default); - child.0 = ChildChange::BulkDeleteByKeyspace; + child.0 = ChildChange::BulkDeleteByKeyspace(child_root); op.set_block_data( header, Some(vec![]), diff --git a/client/db/src/parity_db.rs b/client/db/src/parity_db.rs index 2f5877fdd5..6a912749f0 100644 --- a/client/db/src/parity_db.rs +++ b/client/db/src/parity_db.rs @@ -50,6 +50,7 @@ pub struct BatchChildDelete { ix: usize, batch: Vec<(u8, Vec)>, } + impl Database for DbAdapter { fn commit(&self, transaction: Transaction) { transaction.0.iter().for_each(|change| diff --git a/client/db/src/storage_cache.rs b/client/db/src/storage_cache.rs index 519aabb280..22ec944d50 100644 --- a/client/db/src/storage_cache.rs +++ b/client/db/src/storage_cache.rs @@ -422,7 +422,7 @@ impl CacheChanges { } child_modifications.insert(k); }, - ChildChange::BulkDeleteByKeyspace => { + ChildChange::BulkDeleteByKeyspace(..) => { // Note that this is a rather costy operation. cache.lru_child_storage.remove_by_storage_key(child_info.storage_key()); deleted_child.insert(child_info.storage_key().to_vec()); @@ -671,7 +671,7 @@ impl>, B: BlockT> StateBackend> for Cachin fn child_storage_root( &self, child_info: &ChildInfo, - child_change: ChildChange, + child_change: &ChildChange, delta: I, ) -> (B::Hash, bool, Self::Transaction) where @@ -857,7 +857,7 @@ impl>, B: BlockT> StateBackend> for Syncin fn child_storage_root( &self, child_info: &ChildInfo, - child_change: ChildChange, + child_change: &ChildChange, delta: I, ) -> (B::Hash, bool, Self::Transaction) where diff --git a/client/src/light/backend.rs b/client/src/light/backend.rs index bca46cc9dd..bf27d44e32 100644 --- a/client/src/light/backend.rs +++ b/client/src/light/backend.rs @@ -317,8 +317,11 @@ impl BlockImportOperation for ImportOperation // create a list of children keys to re-compute roots for let child_delta = input.children_default.iter() - .map(|(_storage_key, storage_child)| (storage_child.child_info.clone(), storage_child.child_change, None)) - .collect::>(); + .map(|(_storage_key, storage_child)| ( + storage_child.child_info.clone(), + storage_child.child_change.clone(), + None, + )).collect::>(); // make sure to persist the child storage for (_child_key, storage_child) in input.children_default { @@ -471,7 +474,7 @@ impl StateBackend for GenesisOrUnavailableState fn child_storage_root( &self, child_info: &ChildInfo, - child_change: ChildChange, + child_change: &ChildChange, delta: I, ) -> (H::Out, bool, Self::Transaction) where diff --git a/client/state-db/src/lib.rs b/client/state-db/src/lib.rs index 6c85654051..f7809be4e1 100644 --- a/client/state-db/src/lib.rs +++ b/client/state-db/src/lib.rs @@ -131,8 +131,8 @@ pub struct ChangeSet { /// Deleted nodes. pub deleted: Vec, /// Bulk deletion of child trie, contains - /// its unique identifier. - pub deleted_child: Vec>, + /// its unique identifier and its encoded root. + pub deleted_child: Vec<(Vec, Vec)>, } /// A set of changes to the backing database. diff --git a/client/state-db/src/noncanonical.rs b/client/state-db/src/noncanonical.rs index 4097ecb9e9..60eb80c578 100644 --- a/client/state-db/src/noncanonical.rs +++ b/client/state-db/src/noncanonical.rs @@ -59,7 +59,7 @@ struct JournalRecordV1 { parent_hash: BlockHash, inserted: Vec<(Key, DBValue)>, deleted: Vec, - deleted_child: Vec>, + deleted_child: Vec<(Vec, Vec)>, } impl From> for JournalRecordV1 { @@ -89,7 +89,7 @@ struct BlockOverlay { journal_key: Vec, inserted: Vec, deleted: Vec, - deleted_child: Vec>, + deleted_child: Vec<(Vec, Vec)>, } fn insert_values(values: &mut HashMap, inserted: Vec<(Key, DBValue)>) { diff --git a/client/state-db/src/pruning.rs b/client/state-db/src/pruning.rs index 0fca575a7e..fa3b0bdabd 100644 --- a/client/state-db/src/pruning.rs +++ b/client/state-db/src/pruning.rs @@ -53,7 +53,7 @@ struct DeathRow { hash: BlockHash, journal_key: Vec, deleted: HashSet, - deleted_child: HashSet>, + deleted_child: HashSet<(Vec, Vec)>, } #[derive(Encode, Decode)] @@ -68,7 +68,7 @@ struct JournalRecordV1 { hash: BlockHash, inserted: Vec, deleted: Vec, - deleted_child: Vec>, + deleted_child: Vec<(Vec, Vec)>, } fn to_old_journal_key(block: u64) -> Vec { @@ -134,7 +134,7 @@ impl RefWindow { journal_key: Vec, inserted: I, deleted: Vec, - deleted_child: Vec>, + deleted_child: Vec<(Vec, Vec)>, ) { // remove all re-inserted keys from death rows for k in inserted { diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 229cafc7ad..b6b2ee3511 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -141,12 +141,12 @@ impl BuildStorage for sp_core::storage::Storage { if let Some(map) = storage.children_default.get_mut(&k) { match map.child_info.try_update(&map.child_change, &other_map.child_info) { ChildUpdate::Merge => { - match other_map.child_change { + match &other_map.child_change { ChildChange::Update => map.data.extend( other_map.data.iter().map(|(k, v)| (k.clone(), v.clone())) ), - ChildChange::BulkDeleteByKeyspace => { - map.child_change = ChildChange::BulkDeleteByKeyspace; + ChildChange::BulkDeleteByKeyspace(encoded_root) => { + map.child_change = ChildChange::BulkDeleteByKeyspace(encoded_root.clone()); map.data.clear(); }, } diff --git a/primitives/state-machine/src/backend.rs b/primitives/state-machine/src/backend.rs index 11d03fcf38..a2fb1eb76f 100644 --- a/primitives/state-machine/src/backend.rs +++ b/primitives/state-machine/src/backend.rs @@ -132,7 +132,7 @@ pub trait Backend: std::fmt::Debug { fn child_storage_root( &self, child_info: &ChildInfo, - child_change: ChildChange, + child_change: &ChildChange, delta: I, ) -> (H::Out, bool, Self::Transaction) where @@ -186,7 +186,7 @@ pub trait Backend: std::fmt::Debug { // child first for (child_info, child_change, child_delta) in child_deltas { let (child_root, empty, child_txs) = - self.child_storage_root(&child_info, child_change, child_delta); + self.child_storage_root(&child_info, &child_change, child_delta); let prefixed_storage_key = child_info.prefixed_storage_key(); txs.consolidate(child_txs); if empty { @@ -293,7 +293,7 @@ impl<'a, T: Backend, H: Hasher> Backend for &'a T { fn child_storage_root( &self, child_info: &ChildInfo, - child_change: ChildChange, + child_change: &ChildChange, delta: I, ) -> (H::Out, bool, Self::Transaction) where diff --git a/primitives/state-machine/src/basic.rs b/primitives/state-machine/src/basic.rs index ce72975d74..32faa32b3f 100644 --- a/primitives/state-machine/src/basic.rs +++ b/primitives/state-machine/src/basic.rs @@ -287,7 +287,7 @@ impl Externalities for BasicExternalities { let delta = child.data.clone().into_iter().map(|(k, v)| (k, Some(v))); InMemoryBackend::::default() - .child_storage_root(&child.child_info, child.child_change, delta).0 + .child_storage_root(&child.child_info, &child.child_change, delta).0 } else { empty_child_trie_root::>() }.encode() diff --git a/primitives/state-machine/src/changes_trie/build.rs b/primitives/state-machine/src/changes_trie/build.rs index 9595c26812..95780be3df 100644 --- a/primitives/state-machine/src/changes_trie/build.rs +++ b/primitives/state-machine/src/changes_trie/build.rs @@ -149,13 +149,16 @@ fn prepare_extrinsics_input_inner<'a, B, H, Number>( ), } } else { - (Some(((ChildChange::Update, None), &changes.committed.top)), Some(((ChildChange::Update, None), &changes.prospective.top))) + ( + Some(((ChildChange::Update, None), &changes.committed.top)), + Some(((ChildChange::Update, None), &changes.prospective.top)), + ) }; let mut change = (ChildChange::Update, None); if let Some((child_change, _)) = prospective.as_ref().or_else(|| committed.as_ref()) { - match child_change.0 { - ChildChange::BulkDeleteByKeyspace => { - change.0 = ChildChange::BulkDeleteByKeyspace; + match &child_change.0 { + ChildChange::BulkDeleteByKeyspace(encoded_root) => { + change.0 = ChildChange::BulkDeleteByKeyspace(encoded_root.clone()); change.1 = child_change.1; }, ChildChange::Update => (), diff --git a/primitives/state-machine/src/changes_trie/input.rs b/primitives/state-machine/src/changes_trie/input.rs index c026fd809f..5b68c4aee9 100644 --- a/primitives/state-machine/src/changes_trie/input.rs +++ b/primitives/state-machine/src/changes_trie/input.rs @@ -16,7 +16,7 @@ //! Different types of changes trie input pairs. -use codec::{Decode, Encode, Input, Output, Error, Compact}; +use codec::{Decode, Encode, Input, Output, Error}; use crate::{ StorageKey, StorageValue, changes_trie::BlockNumber @@ -58,7 +58,7 @@ pub type DigestIndexValue = Vec; /// Value of { changed key => block/digest block numbers } mapping. /// That is the . -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Encode, Decode)] pub struct ChildIndexValue { /// Root of the child change trie. pub changes_root: Option>, @@ -66,35 +66,6 @@ pub struct ChildIndexValue { pub child_change: Vec<(ChildChange, u32)>, } -impl Decode for ChildIndexValue { - fn decode(input: &mut I) -> Result { - let changes_root = Decode::decode(input)?; - let nb_changes = >::decode(input)?.0; - let mut child_change = Vec::with_capacity(nb_changes as usize); - for _ in 0..nb_changes { - let change = match ChildChange::from_u8(input.read_byte()?) { - Some(change) => change, - None => return Err("Invalid child change".into()), - }; - let ext_index = Decode::decode(input)?; - child_change.push((change, ext_index)); - } - - Ok(ChildIndexValue { changes_root, child_change }) - } -} - -impl Encode for ChildIndexValue { - fn encode_to(&self, dest: &mut W) { - self.changes_root.encode_to(dest); - >::encode_to(&(self.child_change.len() as u32).into(), dest); - for c in self.child_change.iter() { - dest.push_byte(c.0 as u8); - c.1.encode_to(dest); - } - } -} - /// Single input pair of changes trie. #[derive(Clone, Debug, PartialEq, Eq)] pub enum InputPair { diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index d507480f11..9b71dfb956 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -372,7 +372,14 @@ where let _guard = sp_panic_handler::AbortGuard::force_abort(); self.mark_dirty(); - self.overlay.kill_child_storage(child_info); + match self.backend.storage(&child_info.prefixed_storage_key()) { + Ok(o_encoded_root) => self.overlay.kill_child_storage(child_info, o_encoded_root), + Err(e) => trace!( + target: "state-trace", + "kill_child_storage could not access child trie root {}", + e, + ), + } } fn clear_prefix(&mut self, prefix: &[u8]) { @@ -456,9 +463,8 @@ where ); root } else { - if let Some((child_info, child_change)) = self.overlay.default_child_info(storage_key) { - if child_change == ChildChange::BulkDeleteByKeyspace { + if let ChildChange::BulkDeleteByKeyspace(..) = child_change { return empty_child_trie_root::>().encode(); } let (root, _is_empty, _) = { diff --git a/primitives/state-machine/src/in_memory_backend.rs b/primitives/state-machine/src/in_memory_backend.rs index 20c9ae9536..fd64d34ee5 100644 --- a/primitives/state-machine/src/in_memory_backend.rs +++ b/primitives/state-machine/src/in_memory_backend.rs @@ -185,7 +185,7 @@ impl Backend for InMemory where H::Out: Codec { fn storage(&self, key: &[u8]) -> Result, Self::Error> { Ok(self.inner.get(&None).and_then(|(change, map)| { - debug_assert!(change != &ChildChange::BulkDeleteByKeyspace); + debug_assert!(!matches!(change, ChildChange::BulkDeleteByKeyspace(..))); map.get(key).map(Clone::clone) })) } @@ -196,7 +196,7 @@ impl Backend for InMemory where H::Out: Codec { key: &[u8], ) -> Result, Self::Error> { Ok(self.inner.get(&Some(child_info.to_owned())) - .filter(|(change, _)| change != &ChildChange::BulkDeleteByKeyspace) + .filter(|(change, _)| !matches!(change, ChildChange::BulkDeleteByKeyspace(..))) .and_then(|(_, map)| map.get(key).map(Clone::clone))) } @@ -220,7 +220,7 @@ impl Backend for InMemory where H::Out: Codec { mut f: F, ) { self.inner.get(&Some(child_info.to_owned())) - .filter(|(change, _)| change != &ChildChange::BulkDeleteByKeyspace) + .filter(|(change, _)| !matches!(change, ChildChange::BulkDeleteByKeyspace(..))) .map(|(_, map)| map.keys().for_each(|k| f(&k))); } @@ -231,7 +231,7 @@ impl Backend for InMemory where H::Out: Codec { f: F, ) { self.inner.get(&Some(child_info.to_owned())) - .filter(|(change, _)| change != &ChildChange::BulkDeleteByKeyspace) + .filter(|(change, _)| !matches!(change, ChildChange::BulkDeleteByKeyspace(..))) .map(|(_, map)| map.keys().filter(|key| key.starts_with(prefix)).map(|k| &**k).for_each(f)); } @@ -259,7 +259,7 @@ impl Backend for InMemory where H::Out: Codec { fn child_storage_root( &self, child_info: &ChildInfo, - child_change: ChildChange, + child_change: &ChildChange, delta: I, ) -> (H::Out, bool, Self::Transaction) where @@ -268,13 +268,13 @@ impl Backend for InMemory where H::Out: Codec { { let child_type = child_info.child_type(); let child_info = Some(child_info.to_owned()); - let (root, full_transaction, is_default) = if child_change == ChildChange::BulkDeleteByKeyspace { + let (root, full_transaction, is_default) = if let ChildChange::BulkDeleteByKeyspace(..) = child_change { let root = empty_child_trie_root::>(); (root, Default::default(), true) } else { let existing_pairs = self.inner.get(&child_info) .map(|(change, map)| { - debug_assert!(change != &ChildChange::BulkDeleteByKeyspace); + debug_assert!(!matches!(change, ChildChange::BulkDeleteByKeyspace(..))); (change, map) }) .into_iter() @@ -296,7 +296,7 @@ impl Backend for InMemory where H::Out: Codec { }; - (root, is_default, vec![(child_info, child_change, full_transaction)]) + (root, is_default, vec![(child_info, child_change.clone(), full_transaction)]) } fn next_storage_key(&self, key: &[u8]) -> Result, Self::Error> { @@ -314,7 +314,7 @@ impl Backend for InMemory where H::Out: Codec { ) -> Result, Self::Error> { let range = (ops::Bound::Excluded(key), ops::Bound::Unbounded); let next_key = self.inner.get(&Some(child_info.to_owned())) - .filter(|(change, _)| change != &ChildChange::BulkDeleteByKeyspace) + .filter(|(change, _)| !matches!(change, ChildChange::BulkDeleteByKeyspace(..))) .and_then(|(_, map)| map.range::<[u8], _>(range).next().map(|(k, _)| k).cloned()); Ok(next_key) @@ -340,7 +340,7 @@ impl Backend for InMemory where H::Out: Codec { prefix: &[u8], ) -> Vec { self.inner.get(&Some(child_info.to_owned())) - .filter(|(change, _)| change != &ChildChange::BulkDeleteByKeyspace) + .filter(|(change, _)| !matches!(change, ChildChange::BulkDeleteByKeyspace(..))) .into_iter() .flat_map(|(_, map)| map.keys().filter(|k| k.starts_with(prefix)).cloned()) .collect() @@ -352,7 +352,7 @@ impl Backend for InMemory where H::Out: Codec { let mut root_map = None; for (child_info, (child_change, map)) in &self.inner { if let Some(child_info) = child_info.as_ref() { - if child_change == &ChildChange::BulkDeleteByKeyspace { + if let ChildChange::BulkDeleteByKeyspace(..) = child_change { // we do not need to delete the existing root because we start from // an empty db and there is no possible existing value for it. } else { @@ -361,7 +361,7 @@ impl Backend for InMemory where H::Out: Codec { new_child_roots.push((prefix_storage_key.into_inner(), ch.as_ref().into())); } } else { - debug_assert!(child_change != &ChildChange::BulkDeleteByKeyspace); + debug_assert!(!matches!(child_change, ChildChange::BulkDeleteByKeyspace(..))); root_map = Some(map); } } diff --git a/primitives/state-machine/src/overlayed_changes.rs b/primitives/state-machine/src/overlayed_changes.rs index b32d8c6b44..b4285e140c 100644 --- a/primitives/state-machine/src/overlayed_changes.rs +++ b/primitives/state-machine/src/overlayed_changes.rs @@ -241,7 +241,7 @@ impl OverlayedChanges { /// value has been set. pub fn child_storage(&self, child_info: &ChildInfo, key: &[u8]) -> Option> { if let Some(child) = self.prospective.children_default.get(child_info.storage_key()) { - if child.change.0 == ChildChange::BulkDeleteByKeyspace { + if let ChildChange::BulkDeleteByKeyspace(..) = child.change.0 { return Some(None); } if let Some(val) = child.values.get(key) { @@ -252,7 +252,7 @@ impl OverlayedChanges { } if let Some(child) = self.committed.children_default.get(child_info.storage_key()) { - if child.change.0 == ChildChange::BulkDeleteByKeyspace { + if let ChildChange::BulkDeleteByKeyspace(..) = child.change.0 { return Some(None); } if let Some(val) = child.values.get(key) { @@ -311,6 +311,13 @@ impl OverlayedChanges { /// Clear child storage of given storage key. /// + /// If encoded child root is undefined, this indicates that the child trie only + /// exists in the overlay storage. The deletion is therefore stored with an + /// empty root to allow reverting a freshly created child, but those value needs + /// to be filtered from the resulting transactions (in root building and drain content). + /// Note that it will still be use by change trie (change trie do not use the previous + /// root). + /// /// NOTE that this doesn't take place immediately but written into the prospective /// change set, and still can be reverted by [`discard_prospective`]. /// @@ -318,6 +325,7 @@ impl OverlayedChanges { pub(crate) fn kill_child_storage( &mut self, child_info: &ChildInfo, + encoded_child_root: Option>, ) { let extrinsic_index = self.extrinsic_index(); @@ -328,8 +336,11 @@ impl OverlayedChanges { return; } - map_entry.change = (ChildChange::BulkDeleteByKeyspace, extrinsic_index); - // drop value to reclaim some memory, keep change trie if there is some. + if let Some(encoded_child_root) = encoded_child_root { + map_entry.change = (ChildChange::BulkDeleteByKeyspace(encoded_child_root), extrinsic_index); + } else { + map_entry.change = (ChildChange::BulkDeleteByKeyspace(Vec::new()), extrinsic_index); + } if !extrinsic_index.is_some() { map_entry.values.clear(); } @@ -441,7 +452,7 @@ impl OverlayedChanges { let child_committed = self.committed.children_default.entry(storage_key) .or_insert_with(|| ChildChangeSet { info: child.info.clone(), - change: child.change, + change: child.change.clone(), values: Default::default() }); child_committed.change = child.change; @@ -474,6 +485,7 @@ impl OverlayedChanges { .map(|(k, v)| (k, v.value)), std::mem::replace(&mut self.committed.children_default, Default::default()) .into_iter() + .filter(|(_sk, child)| !matches!(&child.change.0, ChildChange::BulkDeleteByKeyspace(root) if root.is_empty())) .map(|(_sk, child)| (child.info, child.change.0, child.values.into_iter().map(|(k, v)| (k, v.value)))), ) } @@ -577,7 +589,7 @@ impl OverlayedChanges { .expect("child info initialized in either committed or prospective"); ( child_info.clone(), - child_change, + child_change.clone(), self.committed.children_default.get(storage_key) .into_iter() .flat_map(|child| child.values.iter().map(|(k, v)| (k.clone(), v.value.clone()))) @@ -587,7 +599,8 @@ impl OverlayedChanges { .flat_map(|child| child.values.iter().map(|(k, v)| (k.clone(), v.value.clone()))) ), ) - }); + }) + .filter(|(_, child_change, _)| !matches!(&child_change, ChildChange::BulkDeleteByKeyspace(root) if root.is_empty())); // compute and memoize let delta = self.committed.top.iter().map(|(k, v)| (k.clone(), v.value.clone())) @@ -633,12 +646,12 @@ impl OverlayedChanges { /// Get child info for a storage key. /// Take the latest value so prospective first. - pub fn default_child_info(&self, storage_key: &[u8]) -> Option<(&ChildInfo, ChildChange)> { + pub fn default_child_info(&self, storage_key: &[u8]) -> Option<(&ChildInfo, &ChildChange)> { if let Some(child) = self.prospective.children_default.get(storage_key) { - return Some((&child.info, child.change.0)); + return Some((&child.info, &child.change.0)); } if let Some(child) = self.committed.children_default.get(storage_key) { - return Some((&child.info, child.change.0)); + return Some((&child.info, &child.change.0)); } None } @@ -678,7 +691,7 @@ impl OverlayedChanges { let range = (ops::Bound::Excluded(key), ops::Bound::Unbounded); let prospective = self.prospective.children_default.get(storage_key); - if prospective.map(|child| child.change.0) == Some(ChildChange::BulkDeleteByKeyspace) { + if let Some(ChildChange::BulkDeleteByKeyspace(..)) = prospective.map(|child| &child.change.0) { return None; } @@ -686,7 +699,7 @@ impl OverlayedChanges { .and_then(|child| child.values.range::<[u8], _>(range).next().map(|(k, v)| (&k[..], v))); let committed = self.committed.children_default.get(storage_key); - if committed.map(|child| child.change.0) == Some(ChildChange::BulkDeleteByKeyspace) { + if let Some(ChildChange::BulkDeleteByKeyspace(..)) = committed.map(|child| &child.change.0) { return None; } @@ -712,7 +725,7 @@ impl OverlayedChanges { .or_insert(ChildChangeSet { info: child_info.to_owned(), change: committed.children_default.get(child_info.storage_key()) - .map(|child| (child.change.0, None)) + .map(|child| (child.change.0.clone(), None)) .unwrap_or(Default::default()), values: Default::default(), }) diff --git a/primitives/state-machine/src/proving_backend.rs b/primitives/state-machine/src/proving_backend.rs index e40f817ebf..269de26eca 100644 --- a/primitives/state-machine/src/proving_backend.rs +++ b/primitives/state-machine/src/proving_backend.rs @@ -281,7 +281,7 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> fn child_storage_root( &self, child_info: &ChildInfo, - child_change: ChildChange, + child_change: &ChildChange, delta: I, ) -> (H::Out, bool, Self::Transaction) where @@ -292,7 +292,7 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> if let Some((change, tx)) = tx.remove(child_info) { match change { ChildChange::Update => (root, is_empty, Some(tx)), - ChildChange::BulkDeleteByKeyspace => { + ChildChange::BulkDeleteByKeyspace(_encoded_root) => { // no need to keep change trie info contained in tx (root, true, Some(Default::default())) }, @@ -377,7 +377,7 @@ mod tests { let (proving_root, proving_mdb) = proving_backend.storage_root(::std::iter::empty()); assert_eq!(trie_root, proving_root); let trie_mdb = trie_mdb.remove(&ChildInfo::top_trie()).unwrap(); - let mut trie_mdb = if trie_mdb.0 == ChildChange::BulkDeleteByKeyspace { + let mut trie_mdb = if let ChildChange::BulkDeleteByKeyspace(..) = trie_mdb.0 { Default::default() } else { trie_mdb.1 diff --git a/primitives/state-machine/src/testing.rs b/primitives/state-machine/src/testing.rs index 1c1c9fc335..08e204110a 100644 --- a/primitives/state-machine/src/testing.rs +++ b/primitives/state-machine/src/testing.rs @@ -136,16 +136,18 @@ impl TestExternalities self.overlay.committed.children_default.clone().into_iter() .chain(self.overlay.prospective.children_default.clone().into_iter()) .for_each(|(_storage_key, child)| { + let data = match child.change.0 { + ChildChange::Update => child.values.into_iter() + .map(|(k, v)| (k, v.value)) + .collect::>(), + // no need for change trie content + ChildChange::BulkDeleteByKeyspace(..) => Vec::new(), + }; + transaction.push(( Some(child.info), child.change.0, - match child.change.0 { - ChildChange::Update => child.values.into_iter() - .map(|(k, v)| (k, v.value)) - .collect::>(), - // no need for change trie content - ChildChange::BulkDeleteByKeyspace => Vec::new(), - } + data, )) }); diff --git a/primitives/state-machine/src/trie_backend.rs b/primitives/state-machine/src/trie_backend.rs index 24b436dd46..957372d86c 100644 --- a/primitives/state-machine/src/trie_backend.rs +++ b/primitives/state-machine/src/trie_backend.rs @@ -207,7 +207,7 @@ impl, H: Hasher> Backend for TrieBackend where fn child_storage_root( &self, child_info: &ChildInfo, - child_change: ChildChange, + child_change: &ChildChange, delta: I, ) -> (H::Out, bool, Self::Transaction) where @@ -218,9 +218,9 @@ impl, H: Hasher> Backend for TrieBackend where ChildType::ParentKeyId => empty_child_trie_root::>() }; - if child_change == ChildChange::BulkDeleteByKeyspace { + if let ChildChange::BulkDeleteByKeyspace(_encoded_root) = &child_change { let mut tx = ChildrenMap::default(); - tx.insert(child_info.clone(), (child_change, Default::default())); + tx.insert(child_info.clone(), (child_change.clone(), Default::default())); (default_root, true, tx) } else { let mut write_overlay = S::Overlay::default(); @@ -256,7 +256,7 @@ impl, H: Hasher> Backend for TrieBackend where let is_default = root == default_root; let mut tx = ChildrenMap::default(); - tx.insert(child_info.clone(), (child_change, write_overlay)); + tx.insert(child_info.clone(), (child_change.clone(), write_overlay)); (root, is_default, tx) } } diff --git a/primitives/storage/Cargo.toml b/primitives/storage/Cargo.toml index 76174d13b0..069353d16c 100644 --- a/primitives/storage/Cargo.toml +++ b/primitives/storage/Cargo.toml @@ -18,7 +18,8 @@ serde = { version = "1.0.101", optional = true, features = ["derive"] } impl-serde = { version = "0.2.3", optional = true } ref-cast = "1.0.0" sp-debug-derive = { version = "2.0.0-dev", path = "../debug-derive" } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } [features] default = [ "std" ] -std = [ "sp-std/std", "serde", "impl-serde" ] +std = [ "sp-std/std", "codec/std", "serde", "impl-serde" ] diff --git a/primitives/storage/src/lib.rs b/primitives/storage/src/lib.rs index 4310f5d5b8..f767bde81b 100644 --- a/primitives/storage/src/lib.rs +++ b/primitives/storage/src/lib.rs @@ -27,6 +27,7 @@ use sp_debug_derive::RuntimeDebug; use sp_std::vec::Vec; use sp_std::ops::{Deref, DerefMut}; use ref_cast::RefCast; +use codec::{Encode, Decode}; /// Storage key. #[derive(PartialEq, Eq, RuntimeDebug)] @@ -201,12 +202,11 @@ impl ChildInfo { }) } - /// Try to update with another instance, return false if both instance - /// are not compatible. + /// Try to update with another instance. /// Passing current child change as parameter is needed pub fn try_update(&mut self, self_change: &ChildChange, other: &ChildInfo) -> ChildUpdate { match (self, self_change) { - (_, ChildChange::BulkDeleteByKeyspace) => ChildUpdate::Ignore, + (_, ChildChange::BulkDeleteByKeyspace(_encoded_root)) => ChildUpdate::Ignore, (ChildInfo::ParentKeyId(child_trie), ChildChange::Update) => child_trie.try_update(other), } } @@ -277,9 +277,9 @@ impl ChildInfo { /// Return `ChildChange` applicable for this state in the case of a bulk /// content deletion. - pub fn bulk_delete_change(&self) -> ChildChange { + pub fn bulk_delete_change(&self, encoded_root: Vec) -> ChildChange { match self { - ChildInfo::ParentKeyId(..) => ChildChange::BulkDeleteByKeyspace, + ChildInfo::ParentKeyId(..) => ChildChange::BulkDeleteByKeyspace(encoded_root), } } } @@ -472,15 +472,16 @@ impl IntoIterator for ChildrenMap { const DEFAULT_CHILD_TYPE_PARENT_PREFIX: &'static [u8] = b":child_storage:default:"; /// Information related to change to apply on a whole child trie. -#[repr(u8)] -#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] #[cfg_attr(feature = "std", derive(Hash, PartialOrd, Ord))] pub enum ChildChange { /// Update to content of child trie. - Update = 0, - /// The child trie allow to delete base on keyspace only. - /// This deletion means that any joined key delta will be ignored. - BulkDeleteByKeyspace = 1, + Update, + /// The child trie allow bulk trie delete. + /// The inner data is the encoded root at the state where + /// it is been bulk deleted. + /// TODO EMCH rename to BulkDelete + BulkDeleteByKeyspace(Vec), } impl ChildChange { @@ -491,19 +492,10 @@ impl ChildChange { if other != *self { match self { ChildChange::Update => *self = other, - ChildChange::BulkDeleteByKeyspace => panic!("Bulk delete cannot be overwritten"), + ChildChange::BulkDeleteByKeyspace(..) => panic!("Bulk delete cannot be overwritten"), } } } - - /// Get a child change from its u8 representation - pub fn from_u8(repr: u8) -> Option { - match repr { - 0 => Some(ChildChange::Update), - 1 => Some(ChildChange::BulkDeleteByKeyspace), - _ => None, - } - } } impl Default for ChildChange { -- GitLab From 03dae51307e7313328588982e4d1ac4bfa2e7345 Mon Sep 17 00:00:00 2001 From: cheme Date: Mon, 27 Apr 2020 20:02:12 +0200 Subject: [PATCH 300/300] got the method test in parity-db non rc version (the reference db trick to check node count is rather awkward, even require unsafe). --- client/api/src/notifications.rs | 2 +- client/db/src/bench.rs | 2 +- client/db/src/lib.rs | 271 ++++++++++++++++-- client/db/src/storage_cache.rs | 2 +- primitives/runtime/src/lib.rs | 4 +- .../state-machine/src/changes_trie/build.rs | 4 +- primitives/state-machine/src/ext.rs | 2 +- .../state-machine/src/in_memory_backend.rs | 20 +- .../state-machine/src/overlayed_changes.rs | 16 +- .../state-machine/src/proving_backend.rs | 4 +- primitives/state-machine/src/testing.rs | 2 +- primitives/state-machine/src/trie_backend.rs | 2 +- primitives/storage/src/lib.rs | 9 +- test-utils/client/src/lib.rs | 15 + 14 files changed, 300 insertions(+), 55 deletions(-) diff --git a/client/api/src/notifications.rs b/client/api/src/notifications.rs index f9b282c857..106a2c9059 100644 --- a/client/api/src/notifications.rs +++ b/client/api/src/notifications.rs @@ -51,7 +51,7 @@ impl StorageChangeSet { .filter_map(move |(sk, change, changes)| { if let Some(cf) = self.child_filters.as_ref() { if let Some(filter) = cf.get(sk) { - let bulk_delete = matches!(change, ChildChange::BulkDeleteByKeyspace(..)); + let bulk_delete = matches!(change, ChildChange::BulkDelete(..)); Some(changes .iter() .filter(move |&(key, _)| if bulk_delete { diff --git a/client/db/src/bench.rs b/client/db/src/bench.rs index 6ddcb44152..75d5310ff2 100644 --- a/client/db/src/bench.rs +++ b/client/db/src/bench.rs @@ -266,7 +266,7 @@ impl StateBackend> for BenchmarkingState { info.child_type(), ); } - if let ChildChange::BulkDeleteByKeyspace(..) = change { + if let ChildChange::BulkDelete(..) = change { db_transaction.delete_prefix(0, info.keyspace()); } else { keyspace.change_keyspace(info.keyspace()); diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 6e00aaa607..ddc2c7a7de 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -866,6 +866,16 @@ impl Backend { #[cfg(any(test, feature = "test-helpers"))] pub fn new_test(keep_blocks: u32, canonicalization_delay: u64) -> Self { let db = kvdb_memorydb::create(crate::utils::NUM_COLUMNS); + Self::new_test_memorydb(db, keep_blocks, canonicalization_delay) + } + + /// Create new memory-backed client backend for tests. + #[cfg(any(test, feature = "test-helpers"))] + fn new_test_memorydb( + db: kvdb_memorydb::InMemory, + keep_blocks: u32, + canonicalization_delay: u64, + ) -> Self { let db = sp_database::as_database(db); let db_setting = DatabaseSettings { state_cache_size: 16777216, @@ -877,6 +887,7 @@ impl Backend { Self::new(db_setting, canonicalization_delay).expect("failed to create test-db") } + /// Create new memory-backed client backend for tests, using /// parity-db #[cfg(all(feature = "parity-db", any(test, feature = "test-helpers")))] @@ -894,7 +905,6 @@ impl Backend { Self::new(db_setting, canonicalization_delay).expect("failed to create test-db") } - fn from_database( db: Arc>, canonicalization_delay: u64, @@ -1184,7 +1194,7 @@ impl Backend { info.child_type(), ))); } - if let ChildChange::BulkDeleteByKeyspace(encoded_root) = change { + if let ChildChange::BulkDelete(encoded_root) = change { state_db_changeset.deleted_child.push((info.keyspace().to_vec(), encoded_root)); } else { keyspace.change_keyspace(info.keyspace()); @@ -1924,18 +1934,240 @@ pub(crate) mod tests { #[cfg(feature = "parity-db")] #[test] - fn bulk_delete_child_trie_parity_db() { - let backend = Backend::::new_test_parity_db(2, 0); - bulk_delete_child_trie_inner(backend); + fn bulk_delete_child_trie_non_iterable_db() { + use kvdb::KeyValueDB; + let db = Backend::::new_test_parity_db(3, 0); + + let mut count = 0; + let in_mem_ref_db = kvdb_memorydb::create(crate::utils::NUM_COLUMNS); + // implementing KeyValueDB for Arc could avoid using + // this unsafe pointer. + let in_mem_ref: *const kvdb_memorydb::InMemory = &in_mem_ref_db; + let db_ref = Backend::::new_test_memorydb(in_mem_ref_db, 3, 0); + + let child_info = sp_core::storage::ChildInfo::new_default(b"key1"); + + let (hash, child_root) = { + let mut op = db.begin_operation().unwrap(); + let mut op_ref = db_ref.begin_operation().unwrap(); + db.begin_state_operation(&mut op, BlockId::Hash(Default::default())).unwrap(); + db_ref.begin_state_operation(&mut op_ref, BlockId::Hash(Default::default())).unwrap(); + let mut header = Header { + number: 0, + parent_hash: Default::default(), + state_root: Default::default(), + digest: Default::default(), + extrinsics_root: Default::default(), + }; + + let storage = vec![]; + + let child_storage = vec![ + (vec![2, 3, 5], Some(vec![4, 4, 6])), + (vec![2, 2, 3], Some(vec![7, 9, 9])), + (vec![1, 2, 3], Some(vec![7, 9, 8])), + ]; + + header.state_root = op.old_state.full_storage_root(storage + .iter() + .cloned() + .map(|(x, y)| (x, Some(y))), + vec![(child_info.clone(), ChildChange::Update, child_storage.clone())], + false, + ).0.into(); + let hash = header.hash(); + + let mut children_default = HashMap::default(); + children_default.insert(child_info.storage_key().to_vec(), sp_core::storage::StorageChild { + child_info: child_info.clone(), + child_change: Default::default(), + data: child_storage.iter().map(|(k, v)| (k.clone(), v.clone().unwrap())).collect(), + }); + op.reset_storage(Storage { + top: storage.iter().cloned().collect(), + children_default: children_default.clone(), + }).unwrap(); + op.set_block_data( + header.clone(), + Some(vec![]), + None, + NewBlockState::Best, + ).unwrap(); + db.commit_operation(op).unwrap(); + + op_ref.reset_storage(Storage { + top: storage.iter().cloned().collect(), + children_default, + }).unwrap(); + op_ref.set_block_data( + header.clone(), + Some(vec![]), + None, + NewBlockState::Best, + ).unwrap(); + db_ref.commit_operation(op_ref).unwrap(); + + let state = db.state_at(BlockId::Number(0)).unwrap(); + + let child_root = state.storage(&child_info.prefixed_storage_key()[..]) + .unwrap().unwrap(); + assert_eq!( + state.child_storage(&child_info, &[2, 3, 5]).unwrap(), + Some(vec![4, 4, 6]), + ); + assert_eq!( + state.child_storage(&child_info, &[2, 2, 3]).unwrap(), + Some(vec![7, 9, 9]), + ); + assert_eq!( + state.child_storage(&child_info, &[2, 3, 5]).unwrap(), + Some(vec![4, 4, 6]), + ); + + for key in unsafe { in_mem_ref.as_ref() }.unwrap().iter(columns::STATE) { + assert!(db.storage.db.get( + columns::STATE, + &key.0 + ).is_some()); + count += 1; + } + assert!(count > 0); + (hash, child_root) + }; + let assert_count = |count_ref: usize, count: &mut usize| { + let mut new_count = 0; + for key in unsafe { in_mem_ref.as_ref() }.unwrap().iter(columns::STATE) { + assert!(db.storage.db.get( + columns::STATE, + &key.0 + ).is_some()); + new_count += 1; + } + assert_eq!(new_count, count_ref); + *count = new_count; + }; + let hash = { + let mut op = db.begin_operation().unwrap(); + let mut op_ref = db_ref.begin_operation().unwrap(); + db.begin_state_operation(&mut op, BlockId::Number(0)).unwrap(); + db_ref.begin_state_operation(&mut op_ref, BlockId::Number(0)).unwrap(); + let mut header = Header { + number: 1, + parent_hash: hash, + state_root: Default::default(), + digest: Default::default(), + extrinsics_root: Default::default(), + }; + let storage = vec![]; + + let child_storage = vec![( + child_info.clone(), + ChildChange::BulkDelete(child_root), + vec![], + )]; + let (root, overlay, _) = op.old_state.full_storage_root(storage + .iter() + .cloned(), + child_storage.clone(), + false, + ); + op.update_db_storage(overlay.clone()).unwrap(); + op_ref.update_db_storage(overlay).unwrap(); + header.state_root = root.into(); + op.update_storage(storage.clone(), child_storage.clone()).unwrap(); + op_ref.update_storage(storage, child_storage).unwrap(); + + let hash = header.hash(); + + op.set_block_data( + header.clone(), + Some(vec![]), + None, + NewBlockState::Best, + ).unwrap(); + + db.commit_operation(op).unwrap(); + + op_ref.set_block_data( + header, + Some(vec![]), + None, + NewBlockState::Best, + ).unwrap(); + + db_ref.commit_operation(op_ref).unwrap(); + + let state = db.state_at(BlockId::Number(1)).unwrap(); + + assert_eq!( + state.child_storage(&child_info, &[2, 3, 5]).unwrap(), + None, + ); + assert_eq!( + state.child_storage(&child_info, &[2, 2, 3]).unwrap(), + None, + ); + + let mut new_count = 0; + for key in unsafe { in_mem_ref.as_ref() }.unwrap().iter(columns::STATE) { + assert!(db.storage.db.get( + columns::STATE, + &key.0 + ).is_some()); + new_count += 1; + } + // new state is empty root so it is not stored and keep count constant. + assert_count(count, &mut count); + + hash + }; + + let next_block = |number, parent_hash| { + let mut op = db.begin_operation().unwrap(); + let mut op_ref = db_ref.begin_operation().unwrap(); + db.begin_state_operation(&mut op, BlockId::Number(number)).unwrap(); + db_ref.begin_state_operation(&mut op_ref, BlockId::Number(number)).unwrap(); + let header = Header { + number: number + 1, + parent_hash, + state_root: Default::default(), + digest: Default::default(), + extrinsics_root: Default::default(), + }; + + let hash = header.hash(); + op.set_block_data( + header.clone(), + Some(vec![]), + None, + NewBlockState::Best, + ).unwrap(); + + db.commit_operation(op).unwrap(); + + op_ref.set_block_data( + header, + Some(vec![]), + None, + NewBlockState::Best, + ).unwrap(); + + db_ref.commit_operation(op_ref).unwrap(); + + hash + }; + let hash = next_block(1, hash); + assert_count(count, &mut count); + let hash = next_block(2, hash); + assert_count(count, &mut count); + next_block(3, hash); + assert_count(0, &mut count); } + #[test] - fn bulk_delete_child_trie() { + fn bulk_delete_child_trie_iterable_db() { let backend = Backend::::new_test(2, 0); - bulk_delete_child_trie_inner(backend); - } - - fn bulk_delete_child_trie_inner(backend: Backend) { let _ = ::env_logger::try_init(); let mut key = Vec::new(); // This is not collision resistant but enough for the test. @@ -1973,9 +2205,9 @@ pub(crate) mod tests { key.push(top.1.insert(EMPTY_PREFIX, b"hello3")); let child = op.db_updates.entry(ChildInfo::new_default(storage_key)) .or_insert_with(Default::default); - key.push(child.1.insert(EMPTY_PREFIX, b"hello1")); - key.push(child.1.insert(EMPTY_PREFIX, b"hello2")); - key.push(child.1.insert(EMPTY_PREFIX, b"hello3")); + key.push(child.1.insert(EMPTY_PREFIX, b"hello4")); + key.push(child.1.insert(EMPTY_PREFIX, b"hello5")); + key.push(child.1.insert(EMPTY_PREFIX, b"hello6")); op.set_block_data( header, Some(vec![]), @@ -1991,7 +2223,7 @@ pub(crate) mod tests { assert_eq!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key[3], (storage_key, None)) - ).unwrap(), &b"hello1"[..]); + ).unwrap(), &b"hello4"[..]); hash }; @@ -2018,12 +2250,11 @@ pub(crate) mod tests { let hash = header.hash(); let child_info = ChildInfo::new_default(storage_key); - let child_root = op.old_state.storage(&child_info.prefixed_storage_key()) - .unwrap() - .expect("Some child content in previous state").clone(); let child = op.db_updates.entry(child_info) .or_insert_with(Default::default); - child.0 = ChildChange::BulkDeleteByKeyspace(child_root); + // this test bulk deletion on by keyspace, the root in parameter + // is unused. + child.0 = ChildChange::BulkDelete(Default::default()); op.set_block_data( header, Some(vec![]), @@ -2039,7 +2270,7 @@ pub(crate) mod tests { assert_eq!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key[3], (storage_key, None)) - ).unwrap(), &b"hello1"[..]); + ).unwrap(), &b"hello4"[..]); hash }; @@ -2079,7 +2310,7 @@ pub(crate) mod tests { assert_eq!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key[3], (storage_key, None)) - ).unwrap(), &b"hello1"[..]); + ).unwrap(), &b"hello4"[..]); hash }; diff --git a/client/db/src/storage_cache.rs b/client/db/src/storage_cache.rs index 22ec944d50..dd79029f9d 100644 --- a/client/db/src/storage_cache.rs +++ b/client/db/src/storage_cache.rs @@ -422,7 +422,7 @@ impl CacheChanges { } child_modifications.insert(k); }, - ChildChange::BulkDeleteByKeyspace(..) => { + ChildChange::BulkDelete(..) => { // Note that this is a rather costy operation. cache.lru_child_storage.remove_by_storage_key(child_info.storage_key()); deleted_child.insert(child_info.storage_key().to_vec()); diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index b6b2ee3511..2fc4eee5e0 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -145,8 +145,8 @@ impl BuildStorage for sp_core::storage::Storage { ChildChange::Update => map.data.extend( other_map.data.iter().map(|(k, v)| (k.clone(), v.clone())) ), - ChildChange::BulkDeleteByKeyspace(encoded_root) => { - map.child_change = ChildChange::BulkDeleteByKeyspace(encoded_root.clone()); + ChildChange::BulkDelete(encoded_root) => { + map.child_change = ChildChange::BulkDelete(encoded_root.clone()); map.data.clear(); }, } diff --git a/primitives/state-machine/src/changes_trie/build.rs b/primitives/state-machine/src/changes_trie/build.rs index 95780be3df..60dd538c42 100644 --- a/primitives/state-machine/src/changes_trie/build.rs +++ b/primitives/state-machine/src/changes_trie/build.rs @@ -157,8 +157,8 @@ fn prepare_extrinsics_input_inner<'a, B, H, Number>( let mut change = (ChildChange::Update, None); if let Some((child_change, _)) = prospective.as_ref().or_else(|| committed.as_ref()) { match &child_change.0 { - ChildChange::BulkDeleteByKeyspace(encoded_root) => { - change.0 = ChildChange::BulkDeleteByKeyspace(encoded_root.clone()); + ChildChange::BulkDelete(encoded_root) => { + change.0 = ChildChange::BulkDelete(encoded_root.clone()); change.1 = child_change.1; }, ChildChange::Update => (), diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index 9b71dfb956..516dfe816e 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -464,7 +464,7 @@ where root } else { if let Some((child_info, child_change)) = self.overlay.default_child_info(storage_key) { - if let ChildChange::BulkDeleteByKeyspace(..) = child_change { + if let ChildChange::BulkDelete(..) = child_change { return empty_child_trie_root::>().encode(); } let (root, _is_empty, _) = { diff --git a/primitives/state-machine/src/in_memory_backend.rs b/primitives/state-machine/src/in_memory_backend.rs index fd64d34ee5..d7cdd5e6a3 100644 --- a/primitives/state-machine/src/in_memory_backend.rs +++ b/primitives/state-machine/src/in_memory_backend.rs @@ -185,7 +185,7 @@ impl Backend for InMemory where H::Out: Codec { fn storage(&self, key: &[u8]) -> Result, Self::Error> { Ok(self.inner.get(&None).and_then(|(change, map)| { - debug_assert!(!matches!(change, ChildChange::BulkDeleteByKeyspace(..))); + debug_assert!(!matches!(change, ChildChange::BulkDelete(..))); map.get(key).map(Clone::clone) })) } @@ -196,7 +196,7 @@ impl Backend for InMemory where H::Out: Codec { key: &[u8], ) -> Result, Self::Error> { Ok(self.inner.get(&Some(child_info.to_owned())) - .filter(|(change, _)| !matches!(change, ChildChange::BulkDeleteByKeyspace(..))) + .filter(|(change, _)| !matches!(change, ChildChange::BulkDelete(..))) .and_then(|(_, map)| map.get(key).map(Clone::clone))) } @@ -220,7 +220,7 @@ impl Backend for InMemory where H::Out: Codec { mut f: F, ) { self.inner.get(&Some(child_info.to_owned())) - .filter(|(change, _)| !matches!(change, ChildChange::BulkDeleteByKeyspace(..))) + .filter(|(change, _)| !matches!(change, ChildChange::BulkDelete(..))) .map(|(_, map)| map.keys().for_each(|k| f(&k))); } @@ -231,7 +231,7 @@ impl Backend for InMemory where H::Out: Codec { f: F, ) { self.inner.get(&Some(child_info.to_owned())) - .filter(|(change, _)| !matches!(change, ChildChange::BulkDeleteByKeyspace(..))) + .filter(|(change, _)| !matches!(change, ChildChange::BulkDelete(..))) .map(|(_, map)| map.keys().filter(|key| key.starts_with(prefix)).map(|k| &**k).for_each(f)); } @@ -268,13 +268,13 @@ impl Backend for InMemory where H::Out: Codec { { let child_type = child_info.child_type(); let child_info = Some(child_info.to_owned()); - let (root, full_transaction, is_default) = if let ChildChange::BulkDeleteByKeyspace(..) = child_change { + let (root, full_transaction, is_default) = if let ChildChange::BulkDelete(..) = child_change { let root = empty_child_trie_root::>(); (root, Default::default(), true) } else { let existing_pairs = self.inner.get(&child_info) .map(|(change, map)| { - debug_assert!(!matches!(change, ChildChange::BulkDeleteByKeyspace(..))); + debug_assert!(!matches!(change, ChildChange::BulkDelete(..))); (change, map) }) .into_iter() @@ -314,7 +314,7 @@ impl Backend for InMemory where H::Out: Codec { ) -> Result, Self::Error> { let range = (ops::Bound::Excluded(key), ops::Bound::Unbounded); let next_key = self.inner.get(&Some(child_info.to_owned())) - .filter(|(change, _)| !matches!(change, ChildChange::BulkDeleteByKeyspace(..))) + .filter(|(change, _)| !matches!(change, ChildChange::BulkDelete(..))) .and_then(|(_, map)| map.range::<[u8], _>(range).next().map(|(k, _)| k).cloned()); Ok(next_key) @@ -340,7 +340,7 @@ impl Backend for InMemory where H::Out: Codec { prefix: &[u8], ) -> Vec { self.inner.get(&Some(child_info.to_owned())) - .filter(|(change, _)| !matches!(change, ChildChange::BulkDeleteByKeyspace(..))) + .filter(|(change, _)| !matches!(change, ChildChange::BulkDelete(..))) .into_iter() .flat_map(|(_, map)| map.keys().filter(|k| k.starts_with(prefix)).cloned()) .collect() @@ -352,7 +352,7 @@ impl Backend for InMemory where H::Out: Codec { let mut root_map = None; for (child_info, (child_change, map)) in &self.inner { if let Some(child_info) = child_info.as_ref() { - if let ChildChange::BulkDeleteByKeyspace(..) = child_change { + if let ChildChange::BulkDelete(..) = child_change { // we do not need to delete the existing root because we start from // an empty db and there is no possible existing value for it. } else { @@ -361,7 +361,7 @@ impl Backend for InMemory where H::Out: Codec { new_child_roots.push((prefix_storage_key.into_inner(), ch.as_ref().into())); } } else { - debug_assert!(!matches!(child_change, ChildChange::BulkDeleteByKeyspace(..))); + debug_assert!(!matches!(child_change, ChildChange::BulkDelete(..))); root_map = Some(map); } } diff --git a/primitives/state-machine/src/overlayed_changes.rs b/primitives/state-machine/src/overlayed_changes.rs index b4285e140c..c042dd33cb 100644 --- a/primitives/state-machine/src/overlayed_changes.rs +++ b/primitives/state-machine/src/overlayed_changes.rs @@ -241,7 +241,7 @@ impl OverlayedChanges { /// value has been set. pub fn child_storage(&self, child_info: &ChildInfo, key: &[u8]) -> Option> { if let Some(child) = self.prospective.children_default.get(child_info.storage_key()) { - if let ChildChange::BulkDeleteByKeyspace(..) = child.change.0 { + if let ChildChange::BulkDelete(..) = child.change.0 { return Some(None); } if let Some(val) = child.values.get(key) { @@ -252,7 +252,7 @@ impl OverlayedChanges { } if let Some(child) = self.committed.children_default.get(child_info.storage_key()) { - if let ChildChange::BulkDeleteByKeyspace(..) = child.change.0 { + if let ChildChange::BulkDelete(..) = child.change.0 { return Some(None); } if let Some(val) = child.values.get(key) { @@ -337,9 +337,9 @@ impl OverlayedChanges { } if let Some(encoded_child_root) = encoded_child_root { - map_entry.change = (ChildChange::BulkDeleteByKeyspace(encoded_child_root), extrinsic_index); + map_entry.change = (ChildChange::BulkDelete(encoded_child_root), extrinsic_index); } else { - map_entry.change = (ChildChange::BulkDeleteByKeyspace(Vec::new()), extrinsic_index); + map_entry.change = (ChildChange::BulkDelete(Vec::new()), extrinsic_index); } if !extrinsic_index.is_some() { map_entry.values.clear(); @@ -485,7 +485,7 @@ impl OverlayedChanges { .map(|(k, v)| (k, v.value)), std::mem::replace(&mut self.committed.children_default, Default::default()) .into_iter() - .filter(|(_sk, child)| !matches!(&child.change.0, ChildChange::BulkDeleteByKeyspace(root) if root.is_empty())) + .filter(|(_sk, child)| !matches!(&child.change.0, ChildChange::BulkDelete(root) if root.is_empty())) .map(|(_sk, child)| (child.info, child.change.0, child.values.into_iter().map(|(k, v)| (k, v.value)))), ) } @@ -600,7 +600,7 @@ impl OverlayedChanges { ), ) }) - .filter(|(_, child_change, _)| !matches!(&child_change, ChildChange::BulkDeleteByKeyspace(root) if root.is_empty())); + .filter(|(_, child_change, _)| !matches!(&child_change, ChildChange::BulkDelete(root) if root.is_empty())); // compute and memoize let delta = self.committed.top.iter().map(|(k, v)| (k.clone(), v.value.clone())) @@ -691,7 +691,7 @@ impl OverlayedChanges { let range = (ops::Bound::Excluded(key), ops::Bound::Unbounded); let prospective = self.prospective.children_default.get(storage_key); - if let Some(ChildChange::BulkDeleteByKeyspace(..)) = prospective.map(|child| &child.change.0) { + if let Some(ChildChange::BulkDelete(..)) = prospective.map(|child| &child.change.0) { return None; } @@ -699,7 +699,7 @@ impl OverlayedChanges { .and_then(|child| child.values.range::<[u8], _>(range).next().map(|(k, v)| (&k[..], v))); let committed = self.committed.children_default.get(storage_key); - if let Some(ChildChange::BulkDeleteByKeyspace(..)) = committed.map(|child| &child.change.0) { + if let Some(ChildChange::BulkDelete(..)) = committed.map(|child| &child.change.0) { return None; } diff --git a/primitives/state-machine/src/proving_backend.rs b/primitives/state-machine/src/proving_backend.rs index 269de26eca..40d476ecfe 100644 --- a/primitives/state-machine/src/proving_backend.rs +++ b/primitives/state-machine/src/proving_backend.rs @@ -292,7 +292,7 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> if let Some((change, tx)) = tx.remove(child_info) { match change { ChildChange::Update => (root, is_empty, Some(tx)), - ChildChange::BulkDeleteByKeyspace(_encoded_root) => { + ChildChange::BulkDelete(_encoded_root) => { // no need to keep change trie info contained in tx (root, true, Some(Default::default())) }, @@ -377,7 +377,7 @@ mod tests { let (proving_root, proving_mdb) = proving_backend.storage_root(::std::iter::empty()); assert_eq!(trie_root, proving_root); let trie_mdb = trie_mdb.remove(&ChildInfo::top_trie()).unwrap(); - let mut trie_mdb = if let ChildChange::BulkDeleteByKeyspace(..) = trie_mdb.0 { + let mut trie_mdb = if let ChildChange::BulkDelete(..) = trie_mdb.0 { Default::default() } else { trie_mdb.1 diff --git a/primitives/state-machine/src/testing.rs b/primitives/state-machine/src/testing.rs index 08e204110a..7dce37b7fc 100644 --- a/primitives/state-machine/src/testing.rs +++ b/primitives/state-machine/src/testing.rs @@ -141,7 +141,7 @@ impl TestExternalities .map(|(k, v)| (k, v.value)) .collect::>(), // no need for change trie content - ChildChange::BulkDeleteByKeyspace(..) => Vec::new(), + ChildChange::BulkDelete(..) => Vec::new(), }; transaction.push(( diff --git a/primitives/state-machine/src/trie_backend.rs b/primitives/state-machine/src/trie_backend.rs index 957372d86c..f8e57e8bbc 100644 --- a/primitives/state-machine/src/trie_backend.rs +++ b/primitives/state-machine/src/trie_backend.rs @@ -218,7 +218,7 @@ impl, H: Hasher> Backend for TrieBackend where ChildType::ParentKeyId => empty_child_trie_root::>() }; - if let ChildChange::BulkDeleteByKeyspace(_encoded_root) = &child_change { + if let ChildChange::BulkDelete(_encoded_root) = &child_change { let mut tx = ChildrenMap::default(); tx.insert(child_info.clone(), (child_change.clone(), Default::default())); (default_root, true, tx) diff --git a/primitives/storage/src/lib.rs b/primitives/storage/src/lib.rs index f767bde81b..5fb8097833 100644 --- a/primitives/storage/src/lib.rs +++ b/primitives/storage/src/lib.rs @@ -206,7 +206,7 @@ impl ChildInfo { /// Passing current child change as parameter is needed pub fn try_update(&mut self, self_change: &ChildChange, other: &ChildInfo) -> ChildUpdate { match (self, self_change) { - (_, ChildChange::BulkDeleteByKeyspace(_encoded_root)) => ChildUpdate::Ignore, + (_, ChildChange::BulkDelete(_encoded_root)) => ChildUpdate::Ignore, (ChildInfo::ParentKeyId(child_trie), ChildChange::Update) => child_trie.try_update(other), } } @@ -279,7 +279,7 @@ impl ChildInfo { /// content deletion. pub fn bulk_delete_change(&self, encoded_root: Vec) -> ChildChange { match self { - ChildInfo::ParentKeyId(..) => ChildChange::BulkDeleteByKeyspace(encoded_root), + ChildInfo::ParentKeyId(..) => ChildChange::BulkDelete(encoded_root), } } } @@ -480,8 +480,7 @@ pub enum ChildChange { /// The child trie allow bulk trie delete. /// The inner data is the encoded root at the state where /// it is been bulk deleted. - /// TODO EMCH rename to BulkDelete - BulkDeleteByKeyspace(Vec), + BulkDelete(Vec), } impl ChildChange { @@ -492,7 +491,7 @@ impl ChildChange { if other != *self { match self { ChildChange::Update => *self = other, - ChildChange::BulkDeleteByKeyspace(..) => panic!("Bulk delete cannot be overwritten"), + ChildChange::BulkDelete(..) => panic!("Bulk delete cannot be overwritten"), } } } diff --git a/test-utils/client/src/lib.rs b/test-utils/client/src/lib.rs index a8438edba3..b74d642bb4 100644 --- a/test-utils/client/src/lib.rs +++ b/test-utils/client/src/lib.rs @@ -90,11 +90,26 @@ impl TestClientBuilder Self { + let backend = Arc::new(Backend::new_test_parity_db(std::u32::MAX, std::u64::MAX)); + Self::with_backend(backend) + } + /// Create new `TestClientBuilder` with default backend and pruning window size pub fn with_pruning_window(keep_blocks: u32) -> Self { let backend = Arc::new(Backend::new_test(keep_blocks, 0)); Self::with_backend(backend) } + + /// Create new `TestClientBuilder` with parity-db backend and pruning window size + #[cfg(feature = "parity-db")] + pub fn with_pruning_window_and_parity_db(keep_blocks: u32) -> Self { + let backend = Arc::new(Backend::new_test_parity_db(keep_blocks, 0)); + Self::with_backend(backend) + } + } impl TestClientBuilder { -- GitLab

> for Author .map_err(error::Error::from)?; Ok( self.pool - .submit_and_watch(&generic::BlockId::hash(best_block_hash), dxt) + .submit_and_watch(&generic::BlockId::hash(best_block_hash), TX_SOURCE, dxt) .map_err(|e| e.into_pool_error() .map(error::Error::from) .unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into()) diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index 75ce4ed9c3..c7b5f88215 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -403,7 +403,7 @@ fn should_return_runtime_version() { let result = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",2],\ - [\"0x37e397fc7c91f5e4\",1],[\"0xd2bc9897eed08f15\",1],[\"0x40fe3ad401f8959a\",4],\ + [\"0x37e397fc7c91f5e4\",1],[\"0xd2bc9897eed08f15\",2],[\"0x40fe3ad401f8959a\",4],\ [\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",1],\ [\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],[\"0xbc9d89904f5b923f\",1]]}"; diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 74f6ee4917..db9bccf0bf 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -621,7 +621,8 @@ where match Decode::decode(&mut &encoded[..]) { Ok(uxt) => { let best_block_id = BlockId::hash(self.client.info().best_hash); - let import_future = self.pool.submit_one(&best_block_id, uxt); + let source = sp_transaction_pool::TransactionSource::External; + let import_future = self.pool.submit_one(&best_block_id, source, uxt); let import_future = import_future .map(move |import_result| { match import_result { @@ -674,6 +675,7 @@ mod tests { Default::default(), Arc::new(FullChainApi::new(client.clone())), ).0); + let source = sp_runtime::transaction_validity::TransactionSource::External; let best = longest_chain.best_chain().unwrap(); let transaction = Transfer { amount: 5, @@ -681,8 +683,12 @@ mod tests { from: AccountKeyring::Alice.into(), to: Default::default(), }.into_signed_tx(); - block_on(pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); - block_on(pool.submit_one(&BlockId::hash(best.hash()), Extrinsic::IncludeData(vec![1]))).unwrap(); + block_on(pool.submit_one( + &BlockId::hash(best.hash()), source, transaction.clone()), + ).unwrap(); + block_on(pool.submit_one( + &BlockId::hash(best.hash()), source, Extrinsic::IncludeData(vec![1])), + ).unwrap(); assert_eq!(pool.status().ready, 2); // when diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 537d446477..3e1eda3795 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -482,9 +482,10 @@ pub fn sync( let first_user_data = &network.full_nodes[0].2; let best_block = BlockId::number(first_service.get().client().chain_info().best_number); let extrinsic = extrinsic_factory(&first_service.get(), first_user_data); + let source = sp_transaction_pool::TransactionSource::External; futures::executor::block_on( - first_service.get().transaction_pool().submit_one(&best_block, extrinsic) + first_service.get().transaction_pool().submit_one(&best_block, source, extrinsic) ).expect("failed to submit extrinsic"); network.run_until_all_full( diff --git a/client/transaction-pool/graph/benches/basics.rs b/client/transaction-pool/graph/benches/basics.rs index 6f5d39f09f..23b4dba348 100644 --- a/client/transaction-pool/graph/benches/basics.rs +++ b/client/transaction-pool/graph/benches/basics.rs @@ -18,12 +18,14 @@ use criterion::{criterion_group, criterion_main, Criterion}; use futures::{future::{ready, Ready}, executor::block_on}; use sc_transaction_graph::*; -use sp_runtime::transaction_validity::{ValidTransaction, InvalidTransaction}; use codec::Encode; use substrate_test_runtime::{Block, Extrinsic, Transfer, H256, AccountId}; use sp_runtime::{ generic::BlockId, - transaction_validity::{TransactionValidity, TransactionTag as Tag}, + transaction_validity::{ + ValidTransaction, InvalidTransaction, TransactionValidity, TransactionTag as Tag, + TransactionSource, + }, }; use sp_core::blake2_256; @@ -55,6 +57,7 @@ impl ChainApi for TestApi { fn validate_transaction( &self, at: &BlockId, + _source: TransactionSource, uxt: ExtrinsicFor, ) -> Self::ValidationFuture { let nonce = uxt.transfer().nonce; @@ -121,6 +124,7 @@ fn uxt(transfer: Transfer) -> Extrinsic { } fn bench_configured(pool: Pool, number: u64) { + let source = TransactionSource::External; let mut futures = Vec::new(); let mut tags = Vec::new(); @@ -133,7 +137,7 @@ fn bench_configured(pool: Pool, number: u64) { }); tags.push(to_tag(nonce, AccountId::from_h256(H256::from_low_u64_be(1)))); - futures.push(pool.submit_one(&BlockId::Number(1), xt)); + futures.push(pool.submit_one(&BlockId::Number(1), source, xt)); } let res = block_on(futures::future::join_all(futures.into_iter())); diff --git a/client/transaction-pool/graph/src/base_pool.rs b/client/transaction-pool/graph/src/base_pool.rs index 33b7a51f94..38151e9bfd 100644 --- a/client/transaction-pool/graph/src/base_pool.rs +++ b/client/transaction-pool/graph/src/base_pool.rs @@ -33,6 +33,7 @@ use sp_runtime::transaction_validity::{ TransactionTag as Tag, TransactionLongevity as Longevity, TransactionPriority as Priority, + TransactionSource as Source, }; use sp_transaction_pool::{error, PoolStatus, InPoolTransaction}; @@ -102,6 +103,8 @@ pub struct Transaction { pub provides: Vec, /// Should that transaction be propagated. pub propagate: bool, + /// Source of that transaction. + pub source: Source, } impl AsRef for Transaction { @@ -155,6 +158,7 @@ impl Transaction { bytes: self.bytes.clone(), hash: self.hash.clone(), priority: self.priority.clone(), + source: self.source, valid_till: self.valid_till.clone(), requires: self.requires.clone(), provides: self.provides.clone(), @@ -185,6 +189,7 @@ impl fmt::Debug for Transaction where write!(fmt, "valid_till: {:?}, ", &self.valid_till)?; write!(fmt, "bytes: {:?}, ", &self.bytes)?; write!(fmt, "propagate: {:?}, ", &self.propagate)?; + write!(fmt, "source: {:?}, ", &self.source)?; write!(fmt, "requires: [")?; print_tags(fmt, &self.requires)?; write!(fmt, "], provides: [")?; @@ -556,6 +561,7 @@ mod tests { requires: vec![], provides: vec![vec![1]], propagate: true, + source: Source::External, }).unwrap(); // then @@ -578,6 +584,7 @@ mod tests { requires: vec![], provides: vec![vec![1]], propagate: true, + source: Source::External, }).unwrap(); pool.import(Transaction { data: vec![1u8], @@ -588,6 +595,7 @@ mod tests { requires: vec![], provides: vec![vec![1]], propagate: true, + source: Source::External, }).unwrap_err(); // then @@ -611,6 +619,7 @@ mod tests { requires: vec![vec![0]], provides: vec![vec![1]], propagate: true, + source: Source::External, }).unwrap(); assert_eq!(pool.ready().count(), 0); assert_eq!(pool.ready.len(), 0); @@ -623,6 +632,7 @@ mod tests { requires: vec![], provides: vec![vec![0]], propagate: true, + source: Source::External, }).unwrap(); // then @@ -645,6 +655,7 @@ mod tests { requires: vec![vec![0]], provides: vec![vec![1]], propagate: true, + source: Source::External, }).unwrap(); pool.import(Transaction { data: vec![3u8], @@ -655,6 +666,7 @@ mod tests { requires: vec![vec![2]], provides: vec![], propagate: true, + source: Source::External, }).unwrap(); pool.import(Transaction { data: vec![2u8], @@ -665,6 +677,7 @@ mod tests { requires: vec![vec![1]], provides: vec![vec![3], vec![2]], propagate: true, + source: Source::External, }).unwrap(); pool.import(Transaction { data: vec![4u8], @@ -675,6 +688,7 @@ mod tests { requires: vec![vec![3], vec![4]], provides: vec![], propagate: true, + source: Source::External, }).unwrap(); assert_eq!(pool.ready().count(), 0); assert_eq!(pool.ready.len(), 0); @@ -688,6 +702,7 @@ mod tests { requires: vec![], provides: vec![vec![0], vec![4]], propagate: true, + source: Source::External, }).unwrap(); // then @@ -720,6 +735,7 @@ mod tests { requires: vec![vec![0]], provides: vec![vec![1]], propagate: true, + source: Source::External, }).unwrap(); pool.import(Transaction { data: vec![3u8], @@ -730,6 +746,7 @@ mod tests { requires: vec![vec![1]], provides: vec![vec![2]], propagate: true, + source: Source::External, }).unwrap(); assert_eq!(pool.ready().count(), 0); assert_eq!(pool.ready.len(), 0); @@ -744,6 +761,7 @@ mod tests { requires: vec![vec![2]], provides: vec![vec![0]], propagate: true, + source: Source::External, }).unwrap(); // then @@ -764,6 +782,7 @@ mod tests { requires: vec![], provides: vec![vec![0]], propagate: true, + source: Source::External, }).unwrap(); let mut it = pool.ready().into_iter().map(|tx| tx.data[0]); assert_eq!(it.next(), Some(4)); @@ -792,6 +811,7 @@ mod tests { requires: vec![vec![0]], provides: vec![vec![1]], propagate: true, + source: Source::External, }).unwrap(); pool.import(Transaction { data: vec![3u8], @@ -802,6 +822,7 @@ mod tests { requires: vec![vec![1]], provides: vec![vec![2]], propagate: true, + source: Source::External, }).unwrap(); assert_eq!(pool.ready().count(), 0); assert_eq!(pool.ready.len(), 0); @@ -816,6 +837,7 @@ mod tests { requires: vec![vec![2]], provides: vec![vec![0]], propagate: true, + source: Source::External, }).unwrap(); // then @@ -836,6 +858,7 @@ mod tests { requires: vec![], provides: vec![vec![0]], propagate: true, + source: Source::External, }).unwrap_err(); let mut it = pool.ready().into_iter().map(|tx| tx.data[0]); assert_eq!(it.next(), None); @@ -859,6 +882,7 @@ mod tests { requires: vec![], provides: vec![vec![0], vec![4]], propagate: true, + source: Source::External, }).expect("import 1 should be ok"); pool.import(Transaction { data: vec![3u8; 1024], @@ -869,6 +893,7 @@ mod tests { requires: vec![], provides: vec![vec![2], vec![7]], propagate: true, + source: Source::External, }).expect("import 2 should be ok"); assert!(parity_util_mem::malloc_size(&pool) > 5000); @@ -887,6 +912,7 @@ mod tests { requires: vec![], provides: vec![vec![0], vec![4]], propagate: true, + source: Source::External, }).unwrap(); pool.import(Transaction { data: vec![1u8], @@ -897,6 +923,7 @@ mod tests { requires: vec![vec![0]], provides: vec![vec![1]], propagate: true, + source: Source::External, }).unwrap(); pool.import(Transaction { data: vec![3u8], @@ -907,6 +934,7 @@ mod tests { requires: vec![vec![2]], provides: vec![], propagate: true, + source: Source::External, }).unwrap(); pool.import(Transaction { data: vec![2u8], @@ -917,6 +945,7 @@ mod tests { requires: vec![vec![1]], provides: vec![vec![3], vec![2]], propagate: true, + source: Source::External, }).unwrap(); pool.import(Transaction { data: vec![4u8], @@ -927,6 +956,7 @@ mod tests { requires: vec![vec![3], vec![4]], provides: vec![], propagate: true, + source: Source::External, }).unwrap(); // future pool.import(Transaction { @@ -938,6 +968,7 @@ mod tests { requires: vec![vec![11]], provides: vec![], propagate: true, + source: Source::External, }).unwrap(); assert_eq!(pool.ready().count(), 5); assert_eq!(pool.future.len(), 1); @@ -964,6 +995,7 @@ mod tests { requires: vec![vec![0]], provides: vec![vec![100]], propagate: true, + source: Source::External, }).unwrap(); // ready pool.import(Transaction { @@ -975,6 +1007,7 @@ mod tests { requires: vec![], provides: vec![vec![1]], propagate: true, + source: Source::External, }).unwrap(); pool.import(Transaction { data: vec![2u8], @@ -985,6 +1018,7 @@ mod tests { requires: vec![vec![2]], provides: vec![vec![3]], propagate: true, + source: Source::External, }).unwrap(); pool.import(Transaction { data: vec![3u8], @@ -995,6 +1029,7 @@ mod tests { requires: vec![vec![1]], provides: vec![vec![2]], propagate: true, + source: Source::External, }).unwrap(); pool.import(Transaction { data: vec![4u8], @@ -1005,6 +1040,7 @@ mod tests { requires: vec![vec![3], vec![2]], provides: vec![vec![4]], propagate: true, + source: Source::External, }).unwrap(); assert_eq!(pool.ready().count(), 4); @@ -1040,10 +1076,11 @@ mod tests { requires: vec![vec![3], vec![2]], provides: vec![vec![4]], propagate: true, + source: Source::External, }), "Transaction { \ hash: 4, priority: 1000, valid_till: 64, bytes: 1, propagate: true, \ -requires: [03,02], provides: [04], data: [4]}".to_owned() +source: TransactionSource::External, requires: [03,02], provides: [04], data: [4]}".to_owned() ); } @@ -1058,6 +1095,7 @@ requires: [03,02], provides: [04], data: [4]}".to_owned() requires: vec![vec![3], vec![2]], provides: vec![vec![4]], propagate: true, + source: Source::External, }.is_propagable(), true); assert_eq!(Transaction { @@ -1069,6 +1107,7 @@ requires: [03,02], provides: [04], data: [4]}".to_owned() requires: vec![vec![3], vec![2]], provides: vec![vec![4]], propagate: false, + source: Source::External, }.is_propagable(), false); } @@ -1090,6 +1129,7 @@ requires: [03,02], provides: [04], data: [4]}".to_owned() requires: vec![vec![0]], provides: vec![], propagate: true, + source: Source::External, }); if let Err(error::Error::RejectedFutureTransaction) = err { @@ -1113,6 +1153,7 @@ requires: [03,02], provides: [04], data: [4]}".to_owned() requires: vec![vec![0]], provides: vec![], propagate: true, + source: Source::External, }).unwrap(); // then @@ -1142,6 +1183,7 @@ requires: [03,02], provides: [04], data: [4]}".to_owned() requires: vec![vec![0]], provides: vec![], propagate: true, + source: Source::External, }).unwrap(); flag diff --git a/client/transaction-pool/graph/src/future.rs b/client/transaction-pool/graph/src/future.rs index a84a5fbe68..76181c837f 100644 --- a/client/transaction-pool/graph/src/future.rs +++ b/client/transaction-pool/graph/src/future.rs @@ -249,6 +249,7 @@ impl FutureTransactions { #[cfg(test)] mod tests { use super::*; + use sp_runtime::transaction_validity::TransactionSource; #[test] fn can_track_heap_size() { @@ -263,6 +264,7 @@ mod tests { requires: vec![vec![1], vec![2]], provides: vec![vec![3], vec![4]], propagate: true, + source: TransactionSource::External, }.into(), missing_tags: vec![vec![1u8], vec![2u8]].into_iter().collect(), imported_at: std::time::Instant::now(), diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index f0bf17dcb8..a7e4ab554d 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -31,7 +31,9 @@ use futures::{ use sp_runtime::{ generic::BlockId, traits::{self, SaturatedConversion}, - transaction_validity::{TransactionValidity, TransactionTag as Tag, TransactionValidityError}, + transaction_validity::{ + TransactionValidity, TransactionTag as Tag, TransactionValidityError, TransactionSource, + }, }; use sp_transaction_pool::error; use wasm_timer::Instant; @@ -76,6 +78,7 @@ pub trait ChainApi: Send + Sync { fn validate_transaction( &self, at: &BlockId, + source: TransactionSource, uxt: ExtrinsicFor, ) -> Self::ValidationFuture; @@ -144,12 +147,17 @@ impl Pool { } /// Imports a bunch of unverified extrinsics to the pool - pub async fn submit_at(&self, at: &BlockId, xts: T, force: bool) - -> Result, B::Error>>, B::Error> - where - T: IntoIterator> + pub async fn submit_at( + &self, + at: &BlockId, + source: TransactionSource, + xts: T, + force: bool, + ) -> Result, B::Error>>, B::Error> where + T: IntoIterator>, { let validated_pool = self.validated_pool.clone(); + let xts = xts.into_iter().map(|xt| (source, xt)); self.verify(at, xts, force) .map(move |validated_transactions| validated_transactions .map(|validated_transactions| validated_pool.submit(validated_transactions @@ -162,9 +170,10 @@ impl Pool { pub async fn submit_one( &self, at: &BlockId, + source: TransactionSource, xt: ExtrinsicFor, ) -> Result, B::Error> { - self.submit_at(at, std::iter::once(xt), false) + self.submit_at(at, source, std::iter::once(xt), false) .map(|import_result| import_result.and_then(|mut import_result| import_result .pop() .expect("One extrinsic passed; one result returned; qed") @@ -176,10 +185,13 @@ impl Pool { pub async fn submit_and_watch( &self, at: &BlockId, + source: TransactionSource, xt: ExtrinsicFor, ) -> Result, BlockHash>, B::Error> { let block_number = self.resolve_block_number(at)?; - let (_, tx) = self.verify_one(at, block_number, xt, false).await; + let (_, tx) = self.verify_one( + at, block_number, source, xt, false + ).await; self.validated_pool.submit_and_watch(tx) } @@ -249,7 +261,7 @@ impl Pool { // to get validity info and tags that the extrinsic provides. None => { let validity = self.validated_pool.api() - .validate_transaction(parent, extrinsic.clone()) + .validate_transaction(parent, TransactionSource::InBlock, extrinsic.clone()) .await; if let Ok(Ok(validity)) = validity { @@ -303,8 +315,12 @@ impl Pool { // Try to re-validate pruned transactions since some of them might be still valid. // note that `known_imported_hashes` will be rejected here due to temporary ban. - let pruned_hashes = prune_status.pruned.iter().map(|tx| tx.hash.clone()).collect::>(); - let pruned_transactions = prune_status.pruned.into_iter().map(|tx| tx.data.clone()); + let pruned_hashes = prune_status.pruned + .iter() + .map(|tx| tx.hash.clone()).collect::>(); + let pruned_transactions = prune_status.pruned + .into_iter() + .map(|tx| (tx.source, tx.data.clone())); let reverified_transactions = self.verify(at, pruned_transactions, false).await?; @@ -335,7 +351,7 @@ impl Pool { async fn verify( &self, at: &BlockId, - xts: impl IntoIterator>, + xts: impl IntoIterator)>, force: bool, ) -> Result, ValidatedTransactionFor>, B::Error> { // we need a block number to compute tx validity @@ -345,7 +361,7 @@ impl Pool { for (hash, validated_tx) in futures::future::join_all( xts.into_iter() - .map(|xt| self.verify_one(at, block_number, xt, force)) + .map(|(source, xt)| self.verify_one(at, block_number, source, xt, force)) ) .await { @@ -360,6 +376,7 @@ impl Pool { &self, block_id: &BlockId, block_number: NumberFor, + source: TransactionSource, xt: ExtrinsicFor, force: bool, ) -> (ExHash, ValidatedTransactionFor) { @@ -371,7 +388,11 @@ impl Pool { ) } - let validation_result = self.validated_pool.api().validate_transaction(block_id, xt.clone()).await; + let validation_result = self.validated_pool.api().validate_transaction( + block_id, + source, + xt.clone(), + ).await; let status = match validation_result { Ok(status) => status, @@ -386,6 +407,7 @@ impl Pool { ValidatedTransaction::valid_at( block_number.saturated_into::(), hash.clone(), + source, xt, bytes, validity, @@ -422,7 +444,7 @@ mod tests { use futures::executor::block_on; use super::*; use sp_transaction_pool::TransactionStatus; - use sp_runtime::transaction_validity::{ValidTransaction, InvalidTransaction}; + use sp_runtime::transaction_validity::{ValidTransaction, InvalidTransaction, TransactionSource}; use codec::Encode; use substrate_test_runtime::{Block, Extrinsic, Transfer, H256, AccountId}; use assert_matches::assert_matches; @@ -430,6 +452,7 @@ mod tests { use crate::base_pool::Limit; const INVALID_NONCE: u64 = 254; + const SOURCE: TransactionSource = TransactionSource::External; #[derive(Clone, Debug, Default)] struct TestApi { @@ -450,6 +473,7 @@ mod tests { fn validate_transaction( &self, at: &BlockId, + _source: TransactionSource, uxt: ExtrinsicFor, ) -> Self::ValidationFuture { let hash = self.hash_and_length(&uxt).0; @@ -541,7 +565,7 @@ mod tests { let pool = pool(); // when - let hash = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, @@ -565,7 +589,7 @@ mod tests { // when pool.validated_pool.rotator().ban(&Instant::now(), vec![pool.hash_of(&uxt)]); - let res = block_on(pool.submit_one(&BlockId::Number(0), uxt)); + let res = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt)); assert_eq!(pool.validated_pool().status().ready, 0); assert_eq!(pool.validated_pool().status().future, 0); @@ -581,20 +605,20 @@ mod tests { let stream = pool.validated_pool().import_notification_stream(); // when - let _hash = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let _hash = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, }))).unwrap(); - let _hash = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let _hash = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 1, }))).unwrap(); // future doesn't count - let _hash = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let _hash = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, @@ -617,19 +641,19 @@ mod tests { fn should_clear_stale_transactions() { // given let pool = pool(); - let hash1 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash1 = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, }))).unwrap(); - let hash2 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash2 = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 1, }))).unwrap(); - let hash3 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash3 = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, @@ -653,7 +677,7 @@ mod tests { fn should_ban_mined_transactions() { // given let pool = pool(); - let hash1 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash1 = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, @@ -680,7 +704,7 @@ mod tests { ..Default::default() }, TestApi::default().into()); - let hash1 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash1 = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, @@ -689,7 +713,7 @@ mod tests { assert_eq!(pool.validated_pool().status().future, 1); // when - let hash2 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash2 = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(2)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, @@ -716,7 +740,7 @@ mod tests { }, TestApi::default().into()); // when - block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, @@ -734,7 +758,7 @@ mod tests { let pool = pool(); // when - let err = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let err = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, @@ -754,7 +778,7 @@ mod tests { fn should_trigger_ready_and_finalized() { // given let pool = pool(); - let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, @@ -778,7 +802,7 @@ mod tests { fn should_trigger_ready_and_finalized_when_pruning_via_hash() { // given let pool = pool(); - let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, @@ -802,7 +826,7 @@ mod tests { fn should_trigger_future_and_ready_after_promoted() { // given let pool = pool(); - let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, @@ -812,7 +836,7 @@ mod tests { assert_eq!(pool.validated_pool().status().future, 1); // when - block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { + block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, @@ -836,7 +860,7 @@ mod tests { amount: 5, nonce: 0, }); - let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt)).unwrap(); + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), SOURCE, uxt)).unwrap(); assert_eq!(pool.validated_pool().status().ready, 1); // when @@ -860,7 +884,7 @@ mod tests { amount: 5, nonce: 0, }); - let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt)).unwrap(); + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), SOURCE, uxt)).unwrap(); assert_eq!(pool.validated_pool().status().ready, 1); // when @@ -895,7 +919,7 @@ mod tests { amount: 5, nonce: 0, }); - let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), xt)).unwrap(); + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), SOURCE, xt)).unwrap(); assert_eq!(pool.validated_pool().status().ready, 1); // when @@ -905,7 +929,7 @@ mod tests { amount: 4, nonce: 1, }); - block_on(pool.submit_one(&BlockId::Number(1), xt)).unwrap(); + block_on(pool.submit_one(&BlockId::Number(1), SOURCE, xt)).unwrap(); assert_eq!(pool.validated_pool().status().ready, 1); // then @@ -934,7 +958,7 @@ mod tests { // This transaction should go to future, since we use `nonce: 1` let pool2 = pool.clone(); std::thread::spawn(move || { - block_on(pool2.submit_one(&BlockId::Number(0), xt)).unwrap(); + block_on(pool2.submit_one(&BlockId::Number(0), SOURCE, xt)).unwrap(); ready.send(()).unwrap(); }); @@ -948,7 +972,7 @@ mod tests { }); // The tag the above transaction provides (TestApi is using just nonce as u8) let provides = vec![0_u8]; - block_on(pool.submit_one(&BlockId::Number(0), xt)).unwrap(); + block_on(pool.submit_one(&BlockId::Number(0), SOURCE, xt)).unwrap(); assert_eq!(pool.validated_pool().status().ready, 1); // Now block import happens before the second transaction is able to finish verification. diff --git a/client/transaction-pool/graph/src/ready.rs b/client/transaction-pool/graph/src/ready.rs index 23f0d49a93..c856535a61 100644 --- a/client/transaction-pool/graph/src/ready.rs +++ b/client/transaction-pool/graph/src/ready.rs @@ -545,6 +545,7 @@ fn remove_item(vec: &mut Vec, item: &T) { #[cfg(test)] mod tests { use super::*; + use sp_runtime::transaction_validity::TransactionSource as Source; fn tx(id: u8) -> Transaction> { Transaction { @@ -556,6 +557,7 @@ mod tests { requires: vec![vec![1], vec![2]], provides: vec![vec![3], vec![4]], propagate: true, + source: Source::External, } } @@ -656,6 +658,7 @@ mod tests { requires: vec![tx1.provides[0].clone()], provides: vec![], propagate: true, + source: Source::External, }; // when @@ -688,6 +691,7 @@ mod tests { requires: vec![], provides: vec![], propagate: true, + source: Source::External, }; import(&mut ready, tx).unwrap(); diff --git a/client/transaction-pool/graph/src/rotator.rs b/client/transaction-pool/graph/src/rotator.rs index 55a9230522..be96174d1d 100644 --- a/client/transaction-pool/graph/src/rotator.rs +++ b/client/transaction-pool/graph/src/rotator.rs @@ -100,6 +100,7 @@ impl PoolRotator { #[cfg(test)] mod tests { use super::*; + use sp_runtime::transaction_validity::TransactionSource; type Hash = u64; type Ex = (); @@ -122,6 +123,7 @@ mod tests { requires: vec![], provides: vec![], propagate: true, + source: TransactionSource::External, }; (hash, tx) @@ -188,6 +190,7 @@ mod tests { requires: vec![], provides: vec![], propagate: true, + source: TransactionSource::External, } } diff --git a/client/transaction-pool/graph/src/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index 3a6573d9bd..b63e56e481 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -32,7 +32,7 @@ use parking_lot::{Mutex, RwLock}; use sp_runtime::{ generic::BlockId, traits::{self, SaturatedConversion}, - transaction_validity::{TransactionTag as Tag, ValidTransaction}, + transaction_validity::{TransactionTag as Tag, ValidTransaction, TransactionSource}, }; use sp_transaction_pool::{error, PoolStatus}; use wasm_timer::Instant; @@ -58,6 +58,7 @@ impl ValidatedTransaction { pub fn valid_at( at: u64, hash: Hash, + source: TransactionSource, data: Ex, bytes: usize, validity: ValidTransaction, @@ -66,6 +67,7 @@ impl ValidatedTransaction { data, bytes, hash, + source, priority: validity.priority, requires: validity.requires, provides: validity.provides, diff --git a/client/transaction-pool/src/api.rs b/client/transaction-pool/src/api.rs index a8888baa48..bf104c8d78 100644 --- a/client/transaction-pool/src/api.rs +++ b/client/transaction-pool/src/api.rs @@ -29,10 +29,10 @@ use sc_client_api::{ }; use sp_runtime::{ generic::BlockId, traits::{self, Block as BlockT, BlockIdTo, Header as HeaderT, Hash as HashT}, - transaction_validity::TransactionValidity, + transaction_validity::{TransactionValidity, TransactionSource}, }; use sp_transaction_pool::runtime_api::TaggedTransactionQueue; -use sp_api::ProvideRuntimeApi; +use sp_api::{ProvideRuntimeApi, ApiExt}; use crate::error::{self, Error}; @@ -81,6 +81,7 @@ impl sc_transaction_graph::ChainApi for FullChainApi, + source: TransactionSource, uxt: sc_transaction_graph::ExtrinsicFor, ) -> Self::ValidationFuture { let (tx, rx) = oneshot::channel(); @@ -88,8 +89,19 @@ impl sc_transaction_graph::ChainApi for FullChainApi, _>( + &at, |v| v >= 2, + ) + .unwrap_or_default(); + let res = if has_v2 { + runtime_api.validate_transaction(&at, source, uxt) + } else { + #[allow(deprecated)] // old validate_transaction + runtime_api.validate_transaction_before_version_2(&at, uxt) + }; + let res = res.map_err(|e| Error::RuntimeApi(format!("{:?}", e))); if let Err(e) = tx.send(res) { log::warn!("Unable to send a validate transaction result: {:?}", e); } @@ -160,6 +172,7 @@ impl sc_transaction_graph::ChainApi for LightChainApi, + source: TransactionSource, uxt: sc_transaction_graph::ExtrinsicFor, ) -> Self::ValidationFuture { let header_hash = self.client.expect_block_hash_from_id(at); @@ -174,7 +187,7 @@ impl sc_transaction_graph::ChainApi for LightChainApi TransactionPool for BasicPool fn submit_at( &self, at: &BlockId, + source: TransactionSource, xts: Vec>, ) -> PoolFuture, Self::Error>>, Self::Error> { let pool = self.pool.clone(); let at = *at; async move { - pool.submit_at(&at, xts, false).await + pool.submit_at(&at, source, xts, false).await }.boxed() } fn submit_one( &self, at: &BlockId, + source: TransactionSource, xt: TransactionFor, ) -> PoolFuture, Self::Error> { let pool = self.pool.clone(); let at = *at; async move { - pool.submit_one(&at, xt).await + pool.submit_one(&at, source, xt).await }.boxed() } fn submit_and_watch( &self, at: &BlockId, + source: TransactionSource, xt: TransactionFor, ) -> PoolFuture>, Self::Error> { let at = *at; let pool = self.pool.clone(); async move { - pool.submit_and_watch(&at, xt) + pool.submit_and_watch(&at, source, xt) .map(|result| result.map(|watcher| Box::new(watcher.into_stream()) as _)) .await }.boxed() @@ -437,7 +441,14 @@ impl MaintainedTransactionPool for BasicPool resubmit_transactions.extend(block_transactions); } - if let Err(e) = pool.submit_at(&id, resubmit_transactions, true).await { + if let Err(e) = pool.submit_at( + &id, + // These transactions are coming from retracted blocks, we should + // simply consider them external. + TransactionSource::External, + resubmit_transactions, + true + ).await { log::debug!( target: "txpool", "[{:?}] Error re-submitting transactions: {:?}", id, e diff --git a/client/transaction-pool/src/revalidation.rs b/client/transaction-pool/src/revalidation.rs index 4b3f9955ca..ee0aa1ab2d 100644 --- a/client/transaction-pool/src/revalidation.rs +++ b/client/transaction-pool/src/revalidation.rs @@ -78,7 +78,7 @@ async fn batch_revalidate( None => continue, }; - match api.validate_transaction(&BlockId::Number(at), ext.data.clone()).await { + match api.validate_transaction(&BlockId::Number(at), ext.source, ext.data.clone()).await { Ok(Err(TransactionValidityError::Invalid(err))) => { log::debug!(target: "txpool", "[{:?}]: Revalidation: invalid {:?}", ext_hash, err); invalid_hashes.push(ext_hash); @@ -94,6 +94,7 @@ async fn batch_revalidate( ValidatedTransaction::valid_at( at.saturated_into::(), ext_hash, + ext.source, ext.data.clone(), api.hash_and_length(&ext.data).1, validity, @@ -312,9 +313,9 @@ where #[cfg(test)] mod tests { - use super::*; use sc_transaction_graph::Pool; + use sp_transaction_pool::TransactionSource; use substrate_test_runtime_transaction_pool::{TestApi, uxt}; use futures::executor::block_on; use substrate_test_runtime_client::{ @@ -334,7 +335,9 @@ mod tests { let queue = Arc::new(RevalidationQueue::new(api.clone(), pool.clone())); let uxt = uxt(Alice, 0); - let uxt_hash = block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).expect("Should be valid"); + let uxt_hash = block_on( + pool.submit_one(&BlockId::number(0), TransactionSource::External, uxt.clone()) + ).expect("Should be valid"); block_on(queue.revalidate_later(0, vec![uxt_hash])); @@ -343,4 +346,4 @@ mod tests { // number of ready assert_eq!(pool.validated_pool().status().ready, 1); } -} \ No newline at end of file +} diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index fe777c9e67..7dbb8e6158 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -20,7 +20,7 @@ use futures::executor::block_on; use txpool::{self, Pool}; use sp_runtime::{ generic::BlockId, - transaction_validity::{ValidTransaction, InvalidTransaction}, + transaction_validity::{ValidTransaction, InvalidTransaction, TransactionSource}, }; use substrate_test_runtime_client::{ runtime::{Block, Hash, Index, Header, Extrinsic, Transfer}, @@ -53,10 +53,12 @@ fn header(number: u64) -> Header { } } +const SOURCE: TransactionSource = TransactionSource::External; + #[test] fn submission_should_work() { let pool = pool(); - block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 209))).unwrap(); let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209]); @@ -65,8 +67,8 @@ fn submission_should_work() { #[test] fn multiple_submission_should_work() { let pool = pool(); - block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); - block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 209))).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 210))).unwrap(); let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); @@ -75,7 +77,7 @@ fn multiple_submission_should_work() { #[test] fn early_nonce_should_be_culled() { let pool = pool(); - block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 208))).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 208))).unwrap(); let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); @@ -85,11 +87,11 @@ fn early_nonce_should_be_culled() { fn late_nonce_should_be_queued() { let pool = pool(); - block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 210))).unwrap(); let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); - block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 209))).unwrap(); let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); } @@ -97,8 +99,8 @@ fn late_nonce_should_be_queued() { #[test] fn prune_tags_should_work() { let pool = pool(); - let hash209 = block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); - block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap(); + let hash209 = block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 209))).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 210))).unwrap(); let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); @@ -119,16 +121,16 @@ fn prune_tags_should_work() { fn should_ban_invalid_transactions() { let pool = pool(); let uxt = uxt(Alice, 209); - let hash = block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap(); + let hash = block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt.clone())).unwrap(); pool.validated_pool().remove_invalid(&[hash]); - block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap_err(); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt.clone())).unwrap_err(); // when let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); // then - block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap_err(); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt.clone())).unwrap_err(); } #[test] @@ -139,7 +141,7 @@ fn should_correctly_prune_transactions_providing_more_than_one_tag() { })); let pool = Pool::new(Default::default(), api.clone()); let xt = uxt(Alice, 209); - block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); assert_eq!(pool.validated_pool().status().ready, 1); // remove the transaction that just got imported. @@ -152,7 +154,7 @@ fn should_correctly_prune_transactions_providing_more_than_one_tag() { // so now let's insert another transaction that also provides the 155 api.increment_nonce(Alice.into()); let xt = uxt(Alice, 211); - block_on(pool.submit_one(&BlockId::number(2), xt.clone())).expect("2. Imported"); + block_on(pool.submit_one(&BlockId::number(2), SOURCE, xt.clone())).expect("2. Imported"); assert_eq!(pool.validated_pool().status().ready, 1); assert_eq!(pool.validated_pool().status().future, 1); let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); @@ -190,7 +192,7 @@ fn should_prune_old_during_maintenance() { let (pool, _guard) = maintained_pool(); - block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); pool.api.push_block(1, vec![xt.clone()]); @@ -205,8 +207,8 @@ fn should_revalidate_during_maintenance() { let xt2 = uxt(Alice, 210); let (pool, _guard) = maintained_pool(); - block_on(pool.submit_one(&BlockId::number(0), xt1.clone())).expect("1. Imported"); - block_on(pool.submit_one(&BlockId::number(0), xt2.clone())).expect("2. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt1.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt2.clone())).expect("2. Imported"); assert_eq!(pool.status().ready, 2); assert_eq!(pool.api.validation_requests().len(), 2); @@ -230,7 +232,7 @@ fn should_resubmit_from_retracted_during_maintenance() { let (pool, _guard) = maintained_pool(); - block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); pool.api.push_block(1, vec![]); @@ -249,7 +251,7 @@ fn should_not_retain_invalid_hashes_from_retracted() { let (pool, _guard) = maintained_pool(); - block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); pool.api.push_block(1, vec![]); @@ -275,7 +277,7 @@ fn should_revalidate_transaction_multiple_times() { let (pool, _guard) = maintained_pool(); - block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); pool.api.push_block(1, vec![xt.clone()]); @@ -284,7 +286,7 @@ fn should_revalidate_transaction_multiple_times() { block_on(pool.maintain(block_event(1))); block_on(futures_timer::Delay::new(BACKGROUND_REVALIDATION_INTERVAL*2)); - block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); pool.api.push_block(2, vec![]); @@ -305,8 +307,8 @@ fn should_revalidate_across_many_blocks() { let (pool, _guard) = maintained_pool(); - block_on(pool.submit_one(&BlockId::number(1), xt1.clone())).expect("1. Imported"); - block_on(pool.submit_one(&BlockId::number(1), xt2.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(1), SOURCE, xt1.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(1), SOURCE, xt2.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 2); pool.api.push_block(1, vec![]); @@ -314,7 +316,7 @@ fn should_revalidate_across_many_blocks() { block_on(futures_timer::Delay::new(BACKGROUND_REVALIDATION_INTERVAL*2)); - block_on(pool.submit_one(&BlockId::number(2), xt3.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(2), SOURCE, xt3.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 3); pool.api.push_block(2, vec![xt1.clone()]); @@ -337,15 +339,25 @@ fn should_push_watchers_during_maintaince() { let (pool, _guard) = maintained_pool(); let tx0 = alice_uxt(0); - let watcher0 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx0.clone())).unwrap(); + let watcher0 = block_on( + pool.submit_and_watch(&BlockId::Number(0), SOURCE, tx0.clone()) + ).unwrap(); let tx1 = alice_uxt(1); - let watcher1 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx1.clone())).unwrap(); + let watcher1 = block_on( + pool.submit_and_watch(&BlockId::Number(0), SOURCE, tx1.clone()) + ).unwrap(); let tx2 = alice_uxt(2); - let watcher2 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx2.clone())).unwrap(); + let watcher2 = block_on( + pool.submit_and_watch(&BlockId::Number(0), SOURCE, tx2.clone()) + ).unwrap(); let tx3 = alice_uxt(3); - let watcher3 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx3.clone())).unwrap(); + let watcher3 = block_on( + pool.submit_and_watch(&BlockId::Number(0), SOURCE, tx3.clone()) + ).unwrap(); let tx4 = alice_uxt(4); - let watcher4 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx4.clone())).unwrap(); + let watcher4 = block_on( + pool.submit_and_watch(&BlockId::Number(0), SOURCE, tx4.clone()) + ).unwrap(); assert_eq!(pool.status().ready, 5); // when @@ -398,10 +410,10 @@ fn should_push_watchers_during_maintaince() { #[test] fn can_track_heap_size() { let (pool, _guard) = maintained_pool(); - block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).expect("1. Imported"); - block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).expect("1. Imported"); - block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 211))).expect("1. Imported"); - block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 212))).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 209))).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 210))).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 211))).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 212))).expect("1. Imported"); assert!(parity_util_mem::malloc_size(&pool) > 3000); } @@ -412,7 +424,9 @@ fn finalization() { let api = TestApi::with_alice_nonce(209); api.push_block(1, vec![]); let (pool, _background) = BasicPool::new(Default::default(), api.into()); - let watcher = block_on(pool.submit_and_watch(&BlockId::number(1), xt.clone())).expect("1. Imported"); + let watcher = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, xt.clone()) + ).expect("1. Imported"); pool.api.push_block(2, vec![xt.clone()]); let header = pool.api.chain().read().header_by_number.get(&2).cloned().unwrap(); @@ -462,7 +476,9 @@ fn fork_aware_finalization() { // block B1 { - let watcher = block_on(pool.submit_and_watch(&BlockId::number(1), from_alice.clone())).expect("1. Imported"); + let watcher = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, from_alice.clone()) + ).expect("1. Imported"); let header = pool.api.push_block(2, vec![from_alice.clone()]); canon_watchers.push((watcher, header.hash())); assert_eq!(pool.status().ready, 1); @@ -483,8 +499,9 @@ fn fork_aware_finalization() { // block C2 { let header = pool.api.push_fork_block_with_parent(b1, vec![from_dave.clone()]); - from_dave_watcher = block_on(pool.submit_and_watch(&BlockId::number(1), from_dave.clone())) - .expect("1. Imported"); + from_dave_watcher = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, from_dave.clone()) + ).expect("1. Imported"); assert_eq!(pool.status().ready, 1); let event = ChainEvent::NewBlock { id: BlockId::Hash(header.hash()), @@ -499,7 +516,9 @@ fn fork_aware_finalization() { // block D2 { - from_bob_watcher = block_on(pool.submit_and_watch(&BlockId::number(1), from_bob.clone())).expect("1. Imported"); + from_bob_watcher = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, from_bob.clone()) + ).expect("1. Imported"); assert_eq!(pool.status().ready, 1); let header = pool.api.push_fork_block_with_parent(c2, vec![from_bob.clone()]); @@ -516,7 +535,9 @@ fn fork_aware_finalization() { // block C1 { - let watcher = block_on(pool.submit_and_watch(&BlockId::number(1), from_charlie.clone())).expect("1.Imported"); + let watcher = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, from_charlie.clone()) + ).expect("1.Imported"); assert_eq!(pool.status().ready, 1); let header = pool.api.push_block(3, vec![from_charlie.clone()]); @@ -536,7 +557,9 @@ fn fork_aware_finalization() { // block D1 { let xt = uxt(Eve, 0); - let w = block_on(pool.submit_and_watch(&BlockId::number(1), xt.clone())).expect("1. Imported"); + let w = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, xt.clone()) + ).expect("1. Imported"); assert_eq!(pool.status().ready, 3); let header = pool.api.push_block(4, vec![xt.clone()]); canon_watchers.push((w, header.hash())); @@ -608,7 +631,7 @@ fn fork_aware_finalization() { fn ready_set_should_not_resolve_before_block_update() { let (pool, _guard) = maintained_pool(); let xt1 = uxt(Alice, 209); - block_on(pool.submit_one(&BlockId::number(1), xt1.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(1), SOURCE, xt1.clone())).expect("1. Imported"); assert!(pool.ready_at(1).now_or_never().is_none()); } @@ -620,7 +643,7 @@ fn ready_set_should_resolve_after_block_update() { let xt1 = uxt(Alice, 209); - block_on(pool.submit_one(&BlockId::number(1), xt1.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(1), SOURCE, xt1.clone())).expect("1. Imported"); block_on(pool.maintain(block_event(1))); assert!(pool.ready_at(1).now_or_never().is_some()); @@ -633,7 +656,7 @@ fn ready_set_should_eventually_resolve_when_block_update_arrives() { let xt1 = uxt(Alice, 209); - block_on(pool.submit_one(&BlockId::number(1), xt1.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(1), SOURCE, xt1.clone())).expect("1. Imported"); let noop_waker = futures::task::noop_waker(); let mut context = futures::task::Context::from_waker(&noop_waker); @@ -681,7 +704,7 @@ fn should_not_accept_old_signatures() { let xt = Extrinsic::Transfer { transfer, signature: old_singature, exhaust_resources_when_not_first: false }; assert_matches::assert_matches!( - block_on(pool.submit_one(&BlockId::number(0), xt.clone())), + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())), Err(error::Error::Pool( sp_transaction_pool::error::Error::InvalidTransaction(InvalidTransaction::BadProof) )), diff --git a/frame/example-offchain-worker/src/lib.rs b/frame/example-offchain-worker/src/lib.rs index 5a417fa078..e64b3dfa77 100644 --- a/frame/example-offchain-worker/src/lib.rs +++ b/frame/example-offchain-worker/src/lib.rs @@ -51,7 +51,9 @@ use sp_core::crypto::KeyTypeId; use sp_runtime::{ offchain::{http, Duration, storage::StorageValueRef}, traits::Zero, - transaction_validity::{InvalidTransaction, ValidTransaction, TransactionValidity}, + transaction_validity::{ + InvalidTransaction, ValidTransaction, TransactionValidity, TransactionSource, + }, }; use sp_std::{vec, vec::Vec}; use lite_json::json::JsonValue; @@ -509,7 +511,10 @@ impl frame_support::unsigned::ValidateUnsigned for Module { /// By default unsigned transactions are disallowed, but implementing the validator /// here we make sure that some particular calls (the ones produced by offchain worker) /// are being whitelisted and marked as valid. - fn validate_unsigned(call: &Self::Call) -> TransactionValidity { + fn validate_unsigned( + _source: TransactionSource, + call: &Self::Call, + ) -> TransactionValidity { // Firstly let's check that we call the right function. if let Call::submit_price_unsigned(block_number, new_price) = call { // Now let's check if the transaction has any chance to succeed. diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index caab493cb1..d30b66e083 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -59,12 +59,14 @@ //! # pub type Balances = u64; //! # pub type AllModules = u64; //! # pub enum Runtime {}; -//! # use sp_runtime::transaction_validity::{TransactionValidity, UnknownTransaction}; +//! # use sp_runtime::transaction_validity::{ +//! TransactionValidity, UnknownTransaction, TransactionSource, +//! # }; //! # use sp_runtime::traits::ValidateUnsigned; //! # impl ValidateUnsigned for Runtime { //! # type Call = (); //! # -//! # fn validate_unsigned(_call: &Self::Call) -> TransactionValidity { +//! # fn validate_unsigned(_source: TransactionSource, _call: &Self::Call) -> TransactionValidity { //! # UnknownTransaction::NoUnsignedValidator.into() //! # } //! # } @@ -85,7 +87,7 @@ use sp_runtime::{ self, Header, Zero, One, Checkable, Applyable, CheckEqual, ValidateUnsigned, NumberFor, Block as BlockT, Dispatchable, Saturating, }, - transaction_validity::TransactionValidity, + transaction_validity::{TransactionValidity, TransactionSource}, }; use codec::{Codec, Encode}; use frame_system::{extrinsics_root, DigestOf}; @@ -338,12 +340,15 @@ where /// side-effects; it merely checks whether the transaction would panic if it were included or not. /// /// Changes made to storage should be discarded. - pub fn validate_transaction(uxt: Block::Extrinsic) -> TransactionValidity { + pub fn validate_transaction( + source: TransactionSource, + uxt: Block::Extrinsic, + ) -> TransactionValidity { let encoded_len = uxt.using_encoded(|d| d.len()); let xt = uxt.check(&Default::default())?; let dispatch_info = xt.get_dispatch_info(); - xt.validate::(dispatch_info, encoded_len) + xt.validate::(source, dispatch_info, encoded_len) } /// Start an offchain worker and generate extrinsics. @@ -511,7 +516,10 @@ mod tests { Ok(()) } - fn validate_unsigned(call: &Self::Call) -> TransactionValidity { + fn validate_unsigned( + _source: TransactionSource, + call: &Self::Call, + ) -> TransactionValidity { match call { Call::Balances(BalancesCall::set_balance(_, _, _)) => Ok(Default::default()), _ => UnknownTransaction::NoUnsignedValidator.into(), @@ -725,7 +733,10 @@ mod tests { let mut t = new_test_ext(1); t.execute_with(|| { - assert_eq!(Executive::validate_transaction(xt.clone()), Ok(Default::default())); + assert_eq!( + Executive::validate_transaction(TransactionSource::InBlock, xt.clone()), + Ok(Default::default()), + ); assert_eq!(Executive::apply_extrinsic(xt), Ok(Err(DispatchError::BadOrigin))); }); } diff --git a/frame/im-online/src/benchmarking.rs b/frame/im-online/src/benchmarking.rs index 1269328634..973bd0c361 100644 --- a/frame/im-online/src/benchmarking.rs +++ b/frame/im-online/src/benchmarking.rs @@ -24,6 +24,7 @@ use frame_system::RawOrigin; use frame_benchmarking::benchmarks; use sp_core::offchain::{OpaquePeerId, OpaqueMultiaddr}; use sp_runtime::traits::{ValidateUnsigned, Zero}; +use sp_runtime::transaction_validity::TransactionSource; use crate::Module as ImOnline; @@ -72,7 +73,7 @@ benchmarks! { let (input_heartbeat, signature) = create_heartbeat::(k, e)?; let call = Call::heartbeat(input_heartbeat, signature); }: { - ImOnline::::validate_unsigned(&call)?; + ImOnline::::validate_unsigned(TransactionSource::InBlock, &call)?; } } diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 861c57e5b6..a164c379fb 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -82,7 +82,7 @@ use sp_runtime::{ RuntimeDebug, traits::{Convert, Member, Saturating, AtLeast32Bit}, Perbill, PerThing, transaction_validity::{ - TransactionValidity, ValidTransaction, InvalidTransaction, + TransactionValidity, ValidTransaction, InvalidTransaction, TransactionSource, TransactionPriority, }, }; @@ -624,7 +624,10 @@ impl pallet_session::OneSessionHandler for Module { impl frame_support::unsigned::ValidateUnsigned for Module { type Call = Call; - fn validate_unsigned(call: &Self::Call) -> TransactionValidity { + fn validate_unsigned( + _source: TransactionSource, + call: &Self::Call, + ) -> TransactionValidity { if let Call::heartbeat(heartbeat, signature) = call { if >::is_online(heartbeat.authority_index) { // we already received a heartbeat for this authority diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index 942a47a533..b74a27e7ba 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -89,7 +89,7 @@ fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result Result( diff --git a/frame/support/src/unsigned.rs b/frame/support/src/unsigned.rs index 4289e4e474..3bc6f692af 100644 --- a/frame/support/src/unsigned.rs +++ b/frame/support/src/unsigned.rs @@ -18,7 +18,7 @@ pub use crate::sp_runtime::traits::ValidateUnsigned; #[doc(hidden)] pub use crate::sp_runtime::transaction_validity::{ - TransactionValidity, UnknownTransaction, TransactionValidityError, + TransactionValidity, UnknownTransaction, TransactionValidityError, TransactionSource, }; @@ -34,7 +34,8 @@ pub use crate::sp_runtime::transaction_validity::{ /// # impl frame_support::unsigned::ValidateUnsigned for Module { /// # type Call = Call; /// # -/// # fn validate_unsigned(call: &Self::Call) -> frame_support::unsigned::TransactionValidity { +/// # fn validate_unsigned(_source: frame_support::unsigned::TransactionSource, _call: &Self::Call) +/// -> frame_support::unsigned::TransactionValidity { /// # unimplemented!(); /// # } /// # } @@ -78,10 +79,14 @@ macro_rules! impl_outer_validate_unsigned { } } - fn validate_unsigned(call: &Self::Call) -> $crate::unsigned::TransactionValidity { + fn validate_unsigned( + #[allow(unused_variables)] + source: $crate::unsigned::TransactionSource, + call: &Self::Call, + ) -> $crate::unsigned::TransactionValidity { #[allow(unreachable_patterns)] match call { - $( Call::$module(inner_call) => $module::validate_unsigned(inner_call), )* + $( Call::$module(inner_call) => $module::validate_unsigned(source, inner_call), )* _ => $crate::unsigned::UnknownTransaction::NoUnsignedValidator.into(), } } @@ -110,7 +115,10 @@ mod test_partial_and_full_call { impl super::super::ValidateUnsigned for Module { type Call = Call; - fn validate_unsigned(_call: &Self::Call) -> super::super::TransactionValidity { + fn validate_unsigned( + _source: super::super::TransactionSource, + _call: &Self::Call + ) -> super::super::TransactionValidity { unimplemented!(); } } diff --git a/primitives/runtime/src/generic/checked_extrinsic.rs b/primitives/runtime/src/generic/checked_extrinsic.rs index 25a8274354..911a1131bb 100644 --- a/primitives/runtime/src/generic/checked_extrinsic.rs +++ b/primitives/runtime/src/generic/checked_extrinsic.rs @@ -21,7 +21,7 @@ use crate::traits::{ self, Member, MaybeDisplay, SignedExtension, Dispatchable, }; use crate::traits::ValidateUnsigned; -use crate::transaction_validity::TransactionValidity; +use crate::transaction_validity::{TransactionValidity, TransactionSource}; /// Definition of something that the external world might want to say; its /// existence implies that it has been checked and is good, particularly with @@ -50,6 +50,9 @@ where fn validate>( &self, + // TODO [#5006;ToDr] should source be passed to `SignedExtension`s? + // Perhaps a change for 2.0 to avoid breaking too much APIs? + source: TransactionSource, info: Self::DispatchInfo, len: usize, ) -> TransactionValidity { @@ -57,7 +60,7 @@ where Extra::validate(extra, id, &self.function, info.clone(), len) } else { let valid = Extra::validate_unsigned(&self.function, info, len)?; - let unsigned_validation = U::validate_unsigned(&self.function)?; + let unsigned_validation = U::validate_unsigned(source, &self.function)?; Ok(valid.combine_with(unsigned_validation)) } } diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index 2439070054..b3139828c1 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -27,7 +27,7 @@ use crate::traits::ValidateUnsigned; use crate::{generic, KeyTypeId, ApplyExtrinsicResult}; pub use sp_core::{H256, sr25519}; use sp_core::{crypto::{CryptoType, Dummy, key_types, Public}, U256}; -use crate::transaction_validity::{TransactionValidity, TransactionValidityError}; +use crate::transaction_validity::{TransactionValidity, TransactionValidityError, TransactionSource}; /// Authority Id #[derive(Default, PartialEq, Eq, Clone, Encode, Decode, Debug, Hash, Serialize, Deserialize, PartialOrd, Ord)] @@ -357,6 +357,7 @@ impl Applyable for TestXt where /// Checks to see if this is a valid *transaction*. It returns information on it if so. fn validate>( &self, + _source: TransactionSource, _info: Self::DispatchInfo, _len: usize, ) -> TransactionValidity { diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 2f4727a394..51ea4b4a38 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -28,7 +28,8 @@ use serde::{Serialize, Deserialize, de::DeserializeOwned}; use sp_core::{self, Hasher, TypeId, RuntimeDebug}; use crate::codec::{Codec, Encode, Decode}; use crate::transaction_validity::{ - ValidTransaction, TransactionValidity, TransactionValidityError, UnknownTransaction, + ValidTransaction, TransactionSource, TransactionValidity, TransactionValidityError, + UnknownTransaction, }; use crate::generic::{Digest, DigestItem}; pub use sp_arithmetic::traits::{ @@ -851,6 +852,7 @@ pub trait Applyable: Sized + Send + Sync { /// Checks to see if this is a valid *transaction*. It returns information on it if so. fn validate>( &self, + source: TransactionSource, info: Self::DispatchInfo, len: usize, ) -> TransactionValidity; @@ -897,7 +899,7 @@ pub trait ValidateUnsigned { /// /// Changes made to storage WILL be persisted if the call returns `Ok`. fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { - Self::validate_unsigned(call) + Self::validate_unsigned(TransactionSource::InBlock, call) .map(|_| ()) .map_err(Into::into) } @@ -908,7 +910,7 @@ pub trait ValidateUnsigned { /// whether the transaction would panic if it were included or not. /// /// Changes made to storage should be discarded by caller. - fn validate_unsigned(call: &Self::Call) -> TransactionValidity; + fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity; } /// Opaque data type that may be destructured into a series of raw byte slices (which represent diff --git a/primitives/runtime/src/transaction_validity.rs b/primitives/runtime/src/transaction_validity.rs index 6dfb80b6d7..78f724b4d2 100644 --- a/primitives/runtime/src/transaction_validity.rs +++ b/primitives/runtime/src/transaction_validity.rs @@ -161,6 +161,35 @@ impl Into for UnknownTransaction { } } +/// The source of the transaction. +/// +/// Depending on the source we might apply different validation schemes. +/// For instance we can disallow specific kinds of transactions if they were not produced +/// by our local node (for instance off-chain workers). +#[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, parity_util_mem::MallocSizeOf)] +pub enum TransactionSource { + /// Transaction is already included in block. + /// + /// This means that we can't really tell where the transaction is coming from, + /// since it's already in the received block. Note that the custom validation logic + /// using either `Local` or `External` should most likely just allow `InBlock` + /// transactions as well. + InBlock, + + /// Transaction is coming from a local source. + /// + /// This means that the transaction was produced internally by the node + /// (for instance an Off-Chain Worker, or an Off-Chain Call), as opposed + /// to being received over the network. + Local, + + /// Transaction has been received externally. + /// + /// This means the transaction has been received from (usually) "untrusted" source, + /// for instance received over the network or RPC. + External, +} + /// Information concerning a valid transaction. #[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] pub struct ValidTransaction { diff --git a/primitives/transaction-pool/src/lib.rs b/primitives/transaction-pool/src/lib.rs index 9abbcfbdf2..e4498bd024 100644 --- a/primitives/transaction-pool/src/lib.rs +++ b/primitives/transaction-pool/src/lib.rs @@ -29,5 +29,5 @@ mod pool; pub use pool::*; pub use sp_runtime::transaction_validity::{ - TransactionLongevity, TransactionPriority, TransactionTag, + TransactionLongevity, TransactionPriority, TransactionTag, TransactionSource, }; diff --git a/primitives/transaction-pool/src/pool.rs b/primitives/transaction-pool/src/pool.rs index cad0667964..2c9d0e33e8 100644 --- a/primitives/transaction-pool/src/pool.rs +++ b/primitives/transaction-pool/src/pool.rs @@ -31,7 +31,7 @@ use sp_runtime::{ generic::BlockId, traits::{Block as BlockT, Member, NumberFor}, transaction_validity::{ - TransactionLongevity, TransactionPriority, TransactionTag, + TransactionLongevity, TransactionPriority, TransactionTag, TransactionSource, }, }; @@ -192,6 +192,7 @@ pub trait TransactionPool: Send + Sync { fn submit_at( &self, at: &BlockId, + source: TransactionSource, xts: Vec>, ) -> PoolFuture, Self::Error>>, Self::Error>; @@ -199,6 +200,7 @@ pub trait TransactionPool: Send + Sync { fn submit_one( &self, at: &BlockId, + source: TransactionSource, xt: TransactionFor, ) -> PoolFuture, Self::Error>; @@ -206,6 +208,7 @@ pub trait TransactionPool: Send + Sync { fn submit_and_watch( &self, at: &BlockId, + source: TransactionSource, xt: TransactionFor, ) -> PoolFuture>, Self::Error>; @@ -299,7 +302,9 @@ impl OffchainSubmitTransaction for TPool { extrinsic ); - let result = futures::executor::block_on(self.submit_one(&at, extrinsic)); + let result = futures::executor::block_on(self.submit_one( + &at, TransactionSource::Local, extrinsic, + )); result.map(|_| ()) .map_err(|e| log::warn!( diff --git a/primitives/transaction-pool/src/runtime_api.rs b/primitives/transaction-pool/src/runtime_api.rs index e30ce7c828..fa2e51653b 100644 --- a/primitives/transaction-pool/src/runtime_api.rs +++ b/primitives/transaction-pool/src/runtime_api.rs @@ -16,13 +16,27 @@ //! Tagged Transaction Queue Runtime API. -use sp_runtime::transaction_validity::TransactionValidity; +use sp_runtime::transaction_validity::{TransactionValidity, TransactionSource}; use sp_runtime::traits::Block as BlockT; sp_api::decl_runtime_apis! { /// The `TaggedTransactionQueue` api trait for interfering with the transaction queue. + #[api_version(2)] pub trait TaggedTransactionQueue { - /// Validate the given transaction. + /// Validate the transaction. + #[changed_in(2)] fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity; + + /// Validate the transaction. + /// + /// This method is invoked by the transaction pool to learn details about given transaction. + /// The implementation should make sure to verify the correctness of the transaction + /// against current state. + /// Note that this call may be performed by the pool multiple times and transactions + /// might be verified in any possible order. + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + ) -> TransactionValidity; } } diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 59955cce48..f3efb4bea7 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -36,6 +36,7 @@ use sp_runtime::{ ApplyExtrinsicResult, create_runtime_str, Perbill, impl_opaque_keys, transaction_validity::{ TransactionValidity, ValidTransaction, TransactionValidityError, InvalidTransaction, + TransactionSource, }, traits::{ BlindCheckable, BlakeTwo256, Block as BlockT, Extrinsic as ExtrinsicT, @@ -492,7 +493,10 @@ cfg_if! { } impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction(utx: ::Extrinsic) -> TransactionValidity { + fn validate_transaction( + _source: TransactionSource, + utx: ::Extrinsic, + ) -> TransactionValidity { if let Extrinsic::IncludeData(data) = utx { return Ok(ValidTransaction { priority: data.len() as u64, @@ -679,7 +683,10 @@ cfg_if! { } impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction(utx: ::Extrinsic) -> TransactionValidity { + fn validate_transaction( + _source: TransactionSource, + utx: ::Extrinsic, + ) -> TransactionValidity { if let Extrinsic::IncludeData(data) = utx { return Ok(ValidTransaction{ priority: data.len() as u64, diff --git a/test-utils/runtime/transaction-pool/src/lib.rs b/test-utils/runtime/transaction-pool/src/lib.rs index 8cd4e58954..432c9e520d 100644 --- a/test-utils/runtime/transaction-pool/src/lib.rs +++ b/test-utils/runtime/transaction-pool/src/lib.rs @@ -25,6 +25,7 @@ use sp_runtime::{ traits::{BlakeTwo256, Hash as HashT}, transaction_validity::{ TransactionValidity, ValidTransaction, TransactionValidityError, InvalidTransaction, + TransactionSource, }, }; use std::collections::{HashSet, HashMap}; @@ -180,6 +181,7 @@ impl sc_transaction_graph::ChainApi for TestApi { fn validate_transaction( &self, _at: &BlockId, + _source: TransactionSource, uxt: sc_transaction_graph::ExtrinsicFor, ) -> Self::ValidationFuture { self.validation_requests.write().push(uxt.clone()); diff --git a/utils/frame/rpc/system/src/lib.rs b/utils/frame/rpc/system/src/lib.rs index e6214c73d6..c73ddfe93e 100644 --- a/utils/frame/rpc/system/src/lib.rs +++ b/utils/frame/rpc/system/src/lib.rs @@ -239,6 +239,7 @@ mod tests { BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))).0 ); + let source = sp_runtime::transaction_validity::TransactionSource::External; let new_transaction = |nonce: u64| { let t = Transfer { from: AccountKeyring::Alice.into(), @@ -250,9 +251,9 @@ mod tests { }; // Populate the pool let ext0 = new_transaction(0); - block_on(pool.submit_one(&BlockId::number(0), ext0)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), source, ext0)).unwrap(); let ext1 = new_transaction(1); - block_on(pool.submit_one(&BlockId::number(0), ext1)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), source, ext1)).unwrap(); let accounts = FullSystem::new(client, pool); -- GitLab From dae24b768471b15be8e48c5de8d793e871c3332a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 25 Mar 2020 14:02:39 +0000 Subject: [PATCH 071/300] Internal version dependencies cleanup (#5401) * always depend on latest alpha version * integrate arithmetic fuzzer into root workspace --- .gitignore | 2 + Cargo.lock | 40 +- Cargo.toml | 1 + client/network/Cargo.toml | 8 +- client/rpc/Cargo.toml | 4 +- frame/treasury/Cargo.toml | 2 +- primitives/arithmetic/fuzzer/.gitignore | 2 - primitives/arithmetic/fuzzer/Cargo.lock | 403 ------------------ primitives/arithmetic/fuzzer/Cargo.toml | 6 +- .../test-wasm-deprecated/Cargo.toml | 8 +- 10 files changed, 55 insertions(+), 421 deletions(-) delete mode 100644 primitives/arithmetic/fuzzer/.gitignore delete mode 100644 primitives/arithmetic/fuzzer/Cargo.lock diff --git a/.gitignore b/.gitignore index aadaa13912..6398c09fe7 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ rls*.log *.rej **/wip/*.stderr .local +**/hfuzz_target/ +**/hfuzz_workspace/ diff --git a/Cargo.lock b/Cargo.lock index b57b403707..f10f19f080 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,6 +125,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arbitrary" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75153c95fdedd7db9732dfbfc3702324a1627eec91ba56e37cd0ac78314ab2ed" + [[package]] name = "arc-swap" version = "0.4.4" @@ -2072,6 +2078,17 @@ dependencies = [ "hmac", ] +[[package]] +name = "honggfuzz" +version = "0.5.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3de2c3273ef7735df1c5a72128ca85b1d20105b9aac643cdfd7a6e581311150" +dependencies = [ + "arbitrary", + "lazy_static", + "memmap", +] + [[package]] name = "http" version = "0.1.21" @@ -3183,6 +3200,16 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +dependencies = [ + "libc", + "winapi 0.3.8", +] + [[package]] name = "memoffset" version = "0.5.3" @@ -7105,6 +7132,17 @@ dependencies = [ "sp-std", ] +[[package]] +name = "sp-arithmetic-fuzzer" +version = "2.0.0-alpha.5" +dependencies = [ + "honggfuzz", + "num-bigint", + "num-traits", + "primitive-types", + "sp-arithmetic", +] + [[package]] name = "sp-authority-discovery" version = "2.0.0-alpha.5" @@ -8676,7 +8714,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" dependencies = [ - "rand 0.6.5", + "rand 0.7.3", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d86bab8abd..37726e88ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -142,6 +142,7 @@ members = [ "primitives/api/proc-macro", "primitives/api/test", "primitives/arithmetic", + "primitives/arithmetic/fuzzer", "primitives/io", "primitives/runtime", "primitives/sandbox", diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index a5f71d87d5..bb326cbefa 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -36,10 +36,10 @@ parking_lot = "0.10.0" prost = "0.6.1" rand = "0.7.2" hex = "0.4.0" -sc-block-builder = { version = "0.8.0-alpha.4", path = "../block-builder" } -sc-client = { version = "0.8.0-alpha.4", path = "../" } -sc-client-api = { version = "2.0.0-alpha.4", path = "../api" } -sc-peerset = { version = "2.0.0-alpha.4", path = "../peerset" } +sc-block-builder = { version = "0.8.0-alpha.5", path = "../block-builder" } +sc-client = { version = "0.8.0-alpha.5", path = "../" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } +sc-peerset = { version = "2.0.0-alpha.5", path = "../peerset" } pin-project = "0.4.6" serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index cea58e31bf..cd4dd166f5 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -37,8 +37,8 @@ parking_lot = "0.10.0" [dev-dependencies] assert_matches = "1.3.0" futures01 = { package = "futures", version = "0.1.29" } -sc-network = { version = "0.8.0-alpha.4", path = "../network" } -sp-io = { version = "2.0.0-alpha.4", path = "../../primitives/io" } +sc-network = { version = "0.8.0-alpha.5", path = "../network" } +sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } tokio = "0.1.22" sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../transaction-pool" } diff --git a/frame/treasury/Cargo.toml b/frame/treasury/Cargo.toml index a673c7ce81..def7ffcb0c 100644 --- a/frame/treasury/Cargo.toml +++ b/frame/treasury/Cargo.toml @@ -17,7 +17,7 @@ frame-support = { version = "2.0.0-alpha.5", default-features = false, path = ". frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } pallet-balances = { version = "2.0.0-alpha.5", default-features = false, path = "../balances" } -frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] sp-io ={ version = "2.0.0-alpha.5", path = "../../primitives/io" } diff --git a/primitives/arithmetic/fuzzer/.gitignore b/primitives/arithmetic/fuzzer/.gitignore deleted file mode 100644 index 3ebcb104d4..0000000000 --- a/primitives/arithmetic/fuzzer/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -hfuzz_target -hfuzz_workspace diff --git a/primitives/arithmetic/fuzzer/Cargo.lock b/primitives/arithmetic/fuzzer/Cargo.lock deleted file mode 100644 index b196418375..0000000000 --- a/primitives/arithmetic/fuzzer/Cargo.lock +++ /dev/null @@ -1,403 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "arbitrary" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cf76cb6e2222ed0ea86b2b0ee2f71c96ec6edd5af42e84d59160e91b836ec4" - -[[package]] -name = "arrayvec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" - -[[package]] -name = "autocfg" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" - -[[package]] -name = "bitvec" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" - -[[package]] -name = "byte-slice-cast" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" - -[[package]] -name = "byteorder" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" - -[[package]] -name = "c2-chacha" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" -dependencies = [ - "ppv-lite86", -] - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "fixed-hash" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" -dependencies = [ - "byteorder", - "rand", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "getrandom" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "honggfuzz" -version = "0.5.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24c27b4aa3049d6d10d8e33d52c9d03ca9aec18f8a449b246f8c4a5b0c10fb34" -dependencies = [ - "arbitrary", - "lazy_static", - "memmap", -] - -[[package]] -name = "impl-codec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "integer-sqrt" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" - -[[package]] -name = "memmap" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" -dependencies = [ - "autocfg", -] - -[[package]] -name = "parity-scale-codec" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f747c06d9f3b2ad387ac881b9667298c81b1243aa9833f086e05996937c35507" -dependencies = [ - "arrayvec", - "bitvec", - "byte-slice-cast", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34e513ff3e406f3ede6796dcdc83d0b32ffb86668cea1ccf7363118abeb00476" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" - -[[package]] -name = "primitive-types" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" -dependencies = [ - "fixed-hash", - "impl-codec", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" -dependencies = [ - "toml", -] - -[[package]] -name = "proc-macro2" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom", - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" -dependencies = [ - "c2-chacha", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core", -] - -[[package]] -name = "rustc-hex" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" - -[[package]] -name = "serde" -version = "1.0.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sp-arithmetic" -version = "2.0.0" -dependencies = [ - "integer-sqrt", - "num-traits", - "parity-scale-codec", - "serde", - "sp-debug-derive", - "sp-std", -] - -[[package]] -name = "sp-arithmetic-fuzzer" -version = "2.0.0" -dependencies = [ - "honggfuzz", - "num-bigint", - "num-traits", - "primitive-types", - "sp-arithmetic", -] - -[[package]] -name = "sp-debug-derive" -version = "2.0.0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sp-std" -version = "2.0.0" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "syn" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "toml" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" -dependencies = [ - "serde", -] - -[[package]] -name = "uint" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" -dependencies = [ - "byteorder", - "crunchy", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "unicode-xid" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "winapi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/primitives/arithmetic/fuzzer/Cargo.toml b/primitives/arithmetic/fuzzer/Cargo.toml index ea129906ea..c47e398a87 100644 --- a/primitives/arithmetic/fuzzer/Cargo.toml +++ b/primitives/arithmetic/fuzzer/Cargo.toml @@ -1,19 +1,17 @@ [package] name = "sp-arithmetic-fuzzer" -version = "2.0.0" +version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" [dependencies] -sp-arithmetic = { version = "2.0.0", path = ".." } +sp-arithmetic = { version = "2.0.0-alpha.5", path = ".." } honggfuzz = "0.5" primitive-types = "0.7.0" num-bigint = "0.2" num-traits = "0.2" -[workspace] - [[bin]] name = "biguint" path = "src/biguint.rs" diff --git a/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml index 128f6c9acc..b91a304c72 100644 --- a/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml +++ b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml @@ -10,10 +10,10 @@ repository = "https://github.com/paritytech/substrate/" publish = false [dependencies] -sp-runtime-interface = { version = "2.0.0-alpha.2", default-features = false, path = "../" } -sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../std" } -sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../io" } -sp-core = { version = "2.0.0-alpha.2", default-features = false, path = "../../core" } +sp-runtime-interface = { version = "2.0.0-alpha.5", default-features = false, path = "../" } +sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../std" } +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../io" } +sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../core" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } -- GitLab From 547baa09a56dea7443505218529cac5783c88421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 25 Mar 2020 18:42:25 +0000 Subject: [PATCH 072/300] primitives: add missing cargo metadata to sp-arithmetic-fuzzer (#5402) * primitives: add missing cargo metadata to sp-arithmetic-fuzzer * ci: add sp-arithmetic-fuzzer to unleash skip list --- .gitlab-ci.yml | 2 +- primitives/arithmetic/fuzzer/Cargo.toml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 549e8f42fb..12baa3978a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -39,7 +39,7 @@ variables: ARCH: "x86_64" # FIXME set to release CARGO_UNLEASH_INSTALL_PARAMS: "--version 1.0.0-alpha.10" - CARGO_UNLEASH_PKG_DEF: "--skip node node-* pallet-template pallet-example pallet-example-* subkey chain-spec-builder" + CARGO_UNLEASH_PKG_DEF: "--skip node node-* pallet-template pallet-example pallet-example-* subkey chain-spec-builder sp-arithmetic-fuzzer" .collect-artifacts: &collect-artifacts diff --git a/primitives/arithmetic/fuzzer/Cargo.toml b/primitives/arithmetic/fuzzer/Cargo.toml index c47e398a87..895ee60bd8 100644 --- a/primitives/arithmetic/fuzzer/Cargo.toml +++ b/primitives/arithmetic/fuzzer/Cargo.toml @@ -4,6 +4,10 @@ version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "Fuzzer for fixed point arithmetic primitives." +documentation = "https://docs.rs/sp-arithmetic-fuzzer" [dependencies] sp-arithmetic = { version = "2.0.0-alpha.5", path = ".." } -- GitLab From 7188e463b7272f079837773ca825706dcfe986b8 Mon Sep 17 00:00:00 2001 From: Joshy Orndorff Date: Wed, 25 Mar 2020 14:44:13 -0400 Subject: [PATCH 073/300] Remove package aliases from node template (#5389) * delias outer node template * dealias pallet template * Fix mock * attempt to fix warning * Revert "attempt to fix warning" This reverts commit 3d39142b877fb7ae2bd9bd0b31442a00d4c8f0bf. * Add call to test interface. --- bin/node-template/node/Cargo.toml | 4 ++-- bin/node-template/node/src/chain_spec.rs | 2 +- bin/node-template/node/src/service.rs | 16 ++++++++-------- bin/node-template/pallets/template/Cargo.toml | 5 ++--- bin/node-template/pallets/template/src/lib.rs | 2 +- bin/node-template/pallets/template/src/mock.rs | 1 + client/executor/src/native_executor.rs | 2 ++ 7 files changed, 17 insertions(+), 15 deletions(-) diff --git a/bin/node-template/node/Cargo.toml b/bin/node-template/node/Cargo.toml index 201909bfd0..d545943de9 100644 --- a/bin/node-template/node/Cargo.toml +++ b/bin/node-template/node/Cargo.toml @@ -27,8 +27,8 @@ sc-network = { version = "0.8.0-alpha.5", path = "../../../client/network" } sc-consensus-aura = { version = "0.8.0-alpha.5", path = "../../../client/consensus/aura" } sp-consensus-aura = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/aura" } sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } -grandpa = { version = "0.8.0-alpha.5", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } -grandpa-primitives = { version = "2.0.0-alpha.5", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } +sc-finality-grandpa = { version = "0.8.0-alpha.5", path = "../../../client/finality-grandpa" } +sp-finality-grandpa = { version = "2.0.0-alpha.5", path = "../../../primitives/finality-grandpa" } sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } diff --git a/bin/node-template/node/src/chain_spec.rs b/bin/node-template/node/src/chain_spec.rs index f1a7e29d44..b57000fed7 100644 --- a/bin/node-template/node/src/chain_spec.rs +++ b/bin/node-template/node/src/chain_spec.rs @@ -4,7 +4,7 @@ use node_template_runtime::{ SudoConfig, SystemConfig, WASM_BINARY, Signature }; use sp_consensus_aura::sr25519::{AuthorityId as AuraId}; -use grandpa_primitives::{AuthorityId as GrandpaId}; +use sp_finality_grandpa::{AuthorityId as GrandpaId}; use sc_service; use sp_runtime::traits::{Verify, IdentifyAccount}; diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index 4b66f90fbb..8269017072 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -10,7 +10,7 @@ use sp_inherents::InherentDataProviders; use sc_executor::native_executor_instance; pub use sc_executor::NativeExecutor; use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair}; -use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider}; +use sc_finality_grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider}; // Our native executor instance. native_executor_instance!( @@ -44,7 +44,7 @@ macro_rules! new_full_start { .ok_or_else(|| sc_service::Error::SelectChainRequired)?; let (grandpa_block_import, grandpa_link) = - grandpa::block_import(client.clone(), &(client.clone() as Arc<_>), select_chain)?; + sc_finality_grandpa::block_import(client.clone(), &(client.clone() as Arc<_>), select_chain)?; let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new( grandpa_block_import.clone(), client.clone(), @@ -135,7 +135,7 @@ pub fn new_full(config: Configuration) None }; - let grandpa_config = grandpa::Config { + let grandpa_config = sc_finality_grandpa::Config { // FIXME #1578 make this available through chainspec gossip_duration: Duration::from_millis(333), justification_period: 512, @@ -153,13 +153,13 @@ pub fn new_full(config: Configuration) // and vote data availability than the observer. The observer has not // been tested extensively yet and having most nodes in a network run it // could lead to finality stalls. - let grandpa_config = grandpa::GrandpaParams { + let grandpa_config = sc_finality_grandpa::GrandpaParams { config: grandpa_config, link: grandpa_link, network: service.network(), inherent_data_providers: inherent_data_providers.clone(), telemetry_on_connect: Some(service.telemetry_on_connect_stream()), - voting_rule: grandpa::VotingRulesBuilder::default().build(), + voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(), prometheus_registry: service.prometheus_registry() }; @@ -167,10 +167,10 @@ pub fn new_full(config: Configuration) // if it fails we take down the service with it. service.spawn_essential_task( "grandpa-voter", - grandpa::run_grandpa_voter(grandpa_config)? + sc_finality_grandpa::run_grandpa_voter(grandpa_config)? ); } else { - grandpa::setup_disabled_grandpa( + sc_finality_grandpa::setup_disabled_grandpa( service.client(), &inherent_data_providers, service.network(), @@ -204,7 +204,7 @@ pub fn new_light(config: Configuration) let fetch_checker = fetcher .map(|fetcher| fetcher.checker().clone()) .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; - let grandpa_block_import = grandpa::light_block_import( + let grandpa_block_import = sc_finality_grandpa::light_block_import( client.clone(), backend, &(client.clone() as Arc<_>), diff --git a/bin/node-template/pallets/template/Cargo.toml b/bin/node-template/pallets/template/Cargo.toml index 285d05b560..c28636cd61 100644 --- a/bin/node-template/pallets/template/Cargo.toml +++ b/bin/node-template/pallets/template/Cargo.toml @@ -17,9 +17,8 @@ default-features = false version = "2.0.0-alpha.5" path = "../../../../frame/support" -[dependencies.system] +[dependencies.frame-system] default-features = false -package = 'frame-system' version = "2.0.0-alpha.5" path = "../../../../frame/system" [dev-dependencies.sp-core] @@ -44,5 +43,5 @@ std = [ 'codec/std', 'frame-support/std', 'safe-mix/std', - 'system/std' + 'frame-system/std' ] diff --git a/bin/node-template/pallets/template/src/lib.rs b/bin/node-template/pallets/template/src/lib.rs index 892778adeb..e910def236 100644 --- a/bin/node-template/pallets/template/src/lib.rs +++ b/bin/node-template/pallets/template/src/lib.rs @@ -10,7 +10,7 @@ /// https://github.com/paritytech/substrate/blob/master/frame/example/src/lib.rs use frame_support::{decl_module, decl_storage, decl_event, decl_error, dispatch}; -use system::ensure_signed; +use frame_system::{self as system, ensure_signed}; #[cfg(test)] mod mock; diff --git a/bin/node-template/pallets/template/src/mock.rs b/bin/node-template/pallets/template/src/mock.rs index 2ea81ffb45..a93ac0359e 100644 --- a/bin/node-template/pallets/template/src/mock.rs +++ b/bin/node-template/pallets/template/src/mock.rs @@ -6,6 +6,7 @@ use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, testing::Header, Perbill, }; +use frame_system as system; impl_outer_origin! { pub enum Origin for Test {} diff --git a/client/executor/src/native_executor.rs b/client/executor/src/native_executor.rs index 5641755ef1..778bc80800 100644 --- a/client/executor/src/native_executor.rs +++ b/client/executor/src/native_executor.rs @@ -483,5 +483,7 @@ mod tests { 2, ); }); + + my_interface::say_hello_world("hey"); } } -- GitLab From e5dbd82c962e9c3099ef82321607ab98983c2dac Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 25 Mar 2020 19:45:04 +0100 Subject: [PATCH 074/300] client/finality-grandpa/src/until_imported: Refactor BlockGlobalMessage (#5390) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * client/finality-grandpa/src/until_imported: Refactor BlockGlobalMessage `BlockGlobalMessage` owns an `inner` which contains (1) a count for the amount of outstanding blocks to be waited on and (2) the message itself. Given that both is already wrapped in an `Arc` there is no need to keep track of the outstanding blocks, given that it simply corresponds to the amount of strong reference counts on the `Arc` itself. This commit removes the atomic counter within `inner` and piggy backs on the `Arc` reference counter instead. * client/finality-grandpa/src/until_imported: Remove useless match * client/finality-grandpa/src/until_imported.rs: Remove unused var Co-Authored-By: André Silva * client/finality-grandpa/src/until_imported: Address comment suggestion Co-authored-by: André Silva --- client/finality-grandpa/src/until_imported.rs | 105 ++++++++++++++---- 1 file changed, 81 insertions(+), 24 deletions(-) diff --git a/client/finality-grandpa/src/until_imported.rs b/client/finality-grandpa/src/until_imported.rs index c3a52fcf56..c3804e1272 100644 --- a/client/finality-grandpa/src/until_imported.rs +++ b/client/finality-grandpa/src/until_imported.rs @@ -40,7 +40,7 @@ use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use std::collections::{HashMap, VecDeque}; use std::pin::Pin; -use std::sync::{atomic::{AtomicUsize, Ordering}, Arc}; +use std::sync::Arc; use std::task::{Context, Poll}; use std::time::{Duration, Instant}; use sp_finality_grandpa::AuthorityId; @@ -307,8 +307,12 @@ pub(crate) type UntilVoteTargetImported { - inner: Arc<(AtomicUsize, Mutex>>)>, + inner: Arc>>>, target_number: NumberFor, } @@ -416,7 +420,7 @@ impl BlockUntilImported for BlockGlobalMessage { return Ok(()) } - let locked_global = Arc::new((AtomicUsize::new(unknown_count), Mutex::new(Some(input)))); + let locked_global = Arc::new(Mutex::new(Some(input))); // schedule waits for all unknown messages. // when the last one of these has `wait_completed` called on it, @@ -438,30 +442,20 @@ impl BlockUntilImported for BlockGlobalMessage { fn wait_completed(self, canon_number: NumberFor) -> Option { if self.target_number != canon_number { - // if we return without deducting the counter, then none of the other - // handles can return the commit message. + // Delete the inner message so it won't ever be forwarded. Future calls to + // `wait_completed` on the same `inner` will ignore it. + *self.inner.lock() = None; return None; } - let mut last_count = self.inner.0.load(Ordering::Acquire); - - // CAS loop to ensure that we always have a last reader. - loop { - if last_count == 1 { // we are the last one left. - return self.inner.1.lock().take(); - } - - let prev_value = self.inner.0.compare_and_swap( - last_count, - last_count - 1, - Ordering::SeqCst, - ); - - if prev_value == last_count { - return None; - } else { - last_count = prev_value; - } + match Arc::try_unwrap(self.inner) { + // This is the last reference and thus the last outstanding block to be awaited. `inner` + // is either `Some(_)` or `None`. The latter implies that a previous `wait_completed` + // call witnessed a block number mismatch (see above). + Ok(inner) => Mutex::into_inner(inner), + // There are still other strong references to this `Arc`, thus the message is blocked on + // other blocks to be imported. + Err(_) => None, } } } @@ -941,4 +935,67 @@ mod tests { futures::executor::block_on(test); } + + fn test_catch_up() -> Arc>>> { + let header = make_header(5); + + let unknown_catch_up = finality_grandpa::CatchUp { + round_number: 1, + precommits: vec![], + prevotes: vec![], + base_hash: header.hash(), + base_number: *header.number(), + }; + + let catch_up = voter::CommunicationIn::CatchUp( + unknown_catch_up.clone(), + voter::Callback::Blank, + ); + + Arc::new(Mutex::new(Some(catch_up))) + } + + #[test] + fn block_global_message_wait_completed_return_when_all_awaited() { + let msg_inner = test_catch_up(); + + let waiting_block_1 = BlockGlobalMessage:: { + inner: msg_inner.clone(), + target_number: 1, + }; + + let waiting_block_2 = BlockGlobalMessage:: { + inner: msg_inner, + target_number: 2, + }; + + // waiting_block_2 is still waiting for block 2, thus this should return `None`. + assert!(waiting_block_1.wait_completed(1).is_none()); + + // Message only depended on block 1 and 2. Both have been imported, thus this should yield + // the message. + assert!(waiting_block_2.wait_completed(2).is_some()); + } + + #[test] + fn block_global_message_wait_completed_return_none_on_block_number_missmatch() { + let msg_inner = test_catch_up(); + + let waiting_block_1 = BlockGlobalMessage:: { + inner: msg_inner.clone(), + target_number: 1, + }; + + let waiting_block_2 = BlockGlobalMessage:: { + inner: msg_inner, + target_number: 2, + }; + + // Calling wait_completed with wrong block number should yield None. + assert!(waiting_block_1.wait_completed(1234).is_none()); + + // All blocks, that the message depended on, have been imported. Still, given the above + // block number mismatch this should return None. + assert!(waiting_block_2.wait_completed(2).is_none()); + } } -- GitLab From fe23d880234da58b9099515e3257f24d53fbce9e Mon Sep 17 00:00:00 2001 From: pscott <30843220+pscott@users.noreply.github.com> Date: Thu, 26 Mar 2020 09:02:38 +0100 Subject: [PATCH 075/300] TelemetryEndpoints must be valid MutliAddr URL (#5069) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Check for url validity when creating TelemetryEndpoints * Update code that used TelemetryEndpoints::new() * Update commennts that referred to TelemetryEndpoints::new() * Add tests for telemetry * Fix typo and fix code in docs * Return error on failing to override telemetry * Use expect instead of suppressing errors on must-be-valid telemetry endpoints * Update telemetry unit tests to use expect instead of unwrap * Implement custom deserializer for TelemetryEndpoints * Fix typo * Apply suggestions from code review Co-authored-by: Bastian Köcher --- bin/node/cli/src/chain_spec.rs | 3 +- client/cli/src/commands/runcmd.rs | 5 +- client/telemetry/src/lib.rs | 107 +++++++++++++++++++++--------- 3 files changed, 80 insertions(+), 35 deletions(-) diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index 1ef481fb7c..7036a73dc0 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -159,7 +159,8 @@ pub fn staging_testnet_config() -> ChainSpec { "staging_testnet", staging_testnet_config_genesis, boot_nodes, - Some(TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)])), + Some(TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)]) + .expect("Staging telemetry url is valid; qed")), None, None, Default::default(), diff --git a/client/cli/src/commands/runcmd.rs b/client/cli/src/commands/runcmd.rs index c8af14359c..030d952ec1 100644 --- a/client/cli/src/commands/runcmd.rs +++ b/client/cli/src/commands/runcmd.rs @@ -419,7 +419,7 @@ impl RunCmd { config.telemetry_endpoints = None; } else if !self.telemetry_endpoints.is_empty() { config.telemetry_endpoints = Some( - TelemetryEndpoints::new(self.telemetry_endpoints.clone()) + TelemetryEndpoints::new(self.telemetry_endpoints.clone()).map_err(|e| e.to_string())? ); } @@ -689,7 +689,8 @@ mod tests { "test-id", || (), vec!["boo".to_string()], - Some(TelemetryEndpoints::new(vec![("foo".to_string(), 42)])), + Some(TelemetryEndpoints::new(vec![("wss://foo/bar".to_string(), 42)]) + .expect("provided url should be valid")), None, None, None::<()>, diff --git a/client/telemetry/src/lib.rs b/client/telemetry/src/lib.rs index f8ca6d5c73..6c90d6bbcc 100644 --- a/client/telemetry/src/lib.rs +++ b/client/telemetry/src/lib.rs @@ -22,7 +22,7 @@ //! `slog_scope::with_logger` followed with `slog_log!`. //! //! Note that you are supposed to only ever use `telemetry!` and not `slog_scope::with_logger` at -//! the moment. Substate may eventually be reworked to get proper `slog` support, including sending +//! the moment. Substrate may eventually be reworked to get proper `slog` support, including sending //! information to the telemetry. //! //! The [`Telemetry`] struct implements `Stream` and must be polled regularly (or sent to a @@ -41,7 +41,7 @@ //! endpoints: sc_telemetry::TelemetryEndpoints::new(vec![ //! // The `0` is the maximum verbosity level of messages to send to this endpoint. //! ("wss://example.com".into(), 0) -//! ]), +//! ]).expect("Invalid URL or multiaddr provided"), //! // Can be used to pass an external implementation of WebSockets. //! wasm_external_transport: None, //! }); @@ -62,7 +62,7 @@ use futures::{prelude::*, channel::mpsc}; use libp2p::{Multiaddr, wasm_ext}; use log::{error, warn}; use parking_lot::Mutex; -use serde::{Serialize, Deserialize}; +use serde::{Serialize, Deserialize, Deserializer}; use std::{pin::Pin, sync::Arc, task::{Context, Poll}, time::Duration}; use wasm_timer::Instant; @@ -96,12 +96,47 @@ pub struct TelemetryConfig { /// /// The URL string can be either a URL or a multiaddress. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct TelemetryEndpoints(Vec<(String, u8)>); +pub struct TelemetryEndpoints( + #[serde(deserialize_with = "url_or_multiaddr_deser")] + Vec<(Multiaddr, u8)> +); + +/// Custom deserializer for TelemetryEndpoints, used to convert urls or multiaddr to multiaddr. +fn url_or_multiaddr_deser<'de, D>(deserializer: D) -> Result, D::Error> + where D: Deserializer<'de> +{ + Vec::<(String, u8)>::deserialize(deserializer)? + .iter() + .map(|e| Ok((url_to_multiaddr(&e.0) + .map_err(serde::de::Error::custom)?, e.1))) + .collect() +} impl TelemetryEndpoints { - pub fn new(endpoints: Vec<(String, u8)>) -> Self { - TelemetryEndpoints(endpoints) + pub fn new(endpoints: Vec<(String, u8)>) -> Result { + let endpoints: Result, libp2p::multiaddr::Error> = endpoints.iter() + .map(|e| Ok((url_to_multiaddr(&e.0)?, e.1))) + .collect(); + endpoints.map(Self) + } +} + +/// Parses a WebSocket URL into a libp2p `Multiaddr`. +fn url_to_multiaddr(url: &str) -> Result { + // First, assume that we have a `Multiaddr`. + let parse_error = match url.parse() { + Ok(ma) => return Ok(ma), + Err(err) => err, + }; + + // If not, try the `ws://path/url` format. + if let Ok(ma) = libp2p::multiaddr::from_url(url) { + return Ok(ma) } + + // If we have no clue about the format of that string, assume that we were expecting a + // `Multiaddr`. + Err(parse_error) } /// Log levels. @@ -149,13 +184,7 @@ struct TelemetryDrain { /// doesn't provide any way of knowing whether a global logger has already been registered. pub fn init_telemetry(config: TelemetryConfig) -> Telemetry { // Build the list of telemetry endpoints. - let mut endpoints = Vec::new(); - for &(ref url, verbosity) in &config.endpoints.0 { - match url_to_multiaddr(url) { - Ok(addr) => endpoints.push((addr, verbosity)), - Err(err) => warn!(target: "telemetry", "Invalid telemetry URL {}: {}", url, err), - } - } + let (endpoints, wasm_external_transport) = (config.endpoints.0, config.wasm_external_transport); let (sender, receiver) = mpsc::channel(16); let guard = { @@ -164,7 +193,7 @@ pub fn init_telemetry(config: TelemetryConfig) -> Telemetry { slog_scope::set_global_logger(root) }; - let worker = match worker::TelemetryWorker::new(endpoints, config.wasm_external_transport) { + let worker = match worker::TelemetryWorker::new(endpoints, wasm_external_transport) { Ok(w) => Some(w), Err(err) => { error!(target: "telemetry", "Failed to initialize telemetry worker: {:?}", err); @@ -271,24 +300,6 @@ impl slog::Drain for TelemetryDrain { } } -/// Parses a WebSocket URL into a libp2p `Multiaddr`. -fn url_to_multiaddr(url: &str) -> Result { - // First, assume that we have a `Multiaddr`. - let parse_error = match url.parse() { - Ok(ma) => return Ok(ma), - Err(err) => err, - }; - - // If not, try the `ws://path/url` format. - if let Ok(ma) = libp2p::multiaddr::from_url(url) { - return Ok(ma) - } - - // If we have no clue about the format of that string, assume that we were expecting a - // `Multiaddr`. - Err(parse_error) -} - /// Translates to `slog_scope::info`, but contains an additional verbosity /// parameter which the log record is tagged with. Additionally the verbosity /// parameter is added to the record as a key-value pair. @@ -300,3 +311,35 @@ macro_rules! telemetry { }) } } + +#[cfg(test)] +mod telemetry_endpoints_tests { + use libp2p::Multiaddr; + use super::TelemetryEndpoints; + use super::url_to_multiaddr; + + #[test] + fn valid_endpoints() { + let endp = vec![("wss://telemetry.polkadot.io/submit/".into(), 3), ("/ip4/80.123.90.4/tcp/5432".into(), 4)]; + let telem = TelemetryEndpoints::new(endp.clone()).expect("Telemetry endpoint should be valid"); + let mut res: Vec<(Multiaddr, u8)> = vec![]; + for (a, b) in endp.iter() { + res.push((url_to_multiaddr(a).expect("provided url should be valid"), *b)) + } + assert_eq!(telem.0, res); + } + + #[test] + fn invalid_endpoints() { + let endp = vec![("/ip4/...80.123.90.4/tcp/5432".into(), 3), ("/ip4/no:!?;rlkqre;;::::///tcp/5432".into(), 4)]; + let telem = TelemetryEndpoints::new(endp); + assert!(telem.is_err()); + } + + #[test] + fn valid_and_invalid_endpoints() { + let endp = vec![("/ip4/80.123.90.4/tcp/5432".into(), 3), ("/ip4/no:!?;rlkqre;;::::///tcp/5432".into(), 4)]; + let telem = TelemetryEndpoints::new(endp); + assert!(telem.is_err()); + } +} -- GitLab From 3f5b56dcc2bb11a3a068659182e31a3e345ef2d5 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Thu, 26 Mar 2020 09:13:09 +0100 Subject: [PATCH 076/300] Allow syncing to peers with finalized common block (#5408) * Allow syncing to peers with finalized common block * Added test --- client/network/src/protocol/sync.rs | 18 ++++++++++++------ client/network/test/src/sync.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index 683f3c3139..e8629b4fdf 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -1108,10 +1108,12 @@ impl ChainSync { } // If the announced block is the best they have and is not ahead of us, our common number // is either one further ahead or it's the one they just announced, if we know about it. - if is_best && self.best_queued_number >= number { - if known { + if is_best { + if known && self.best_queued_number >= number { peer.common_number = number - } else if header.parent_hash() == &self.best_queued_hash || known_parent { + } else if header.parent_hash() == &self.best_queued_hash + || known_parent && self.best_queued_number >= number + { peer.common_number = number - One::one(); } } @@ -1320,13 +1322,17 @@ fn peer_block_request( finalized: NumberFor, best_num: NumberFor, ) -> Option<(Range>, BlockRequest)> { - if peer.common_number < finalized { - return None; - } if best_num >= peer.best_number { // Will be downloaded as alternative fork instead. return None; } + if peer.common_number < finalized { + trace!( + target: "sync", + "Requesting pre-finalized chain from {:?}, common={}, finalized={}, peer best={}, our best={}", + id, finalized, peer.common_number, peer.best_number, best_num, + ); + } if let Some(range) = blocks.needed_blocks( id.clone(), MAX_BLOCKS_TO_REQUEST, diff --git a/client/network/test/src/sync.rs b/client/network/test/src/sync.rs index 5453747220..785b71cb79 100644 --- a/client/network/test/src/sync.rs +++ b/client/network/test/src/sync.rs @@ -694,3 +694,32 @@ fn imports_stale_once() { assert_eq!(net.peer(1).num_processed_blocks(), 2); } +#[test] +fn can_sync_to_peers_with_wrong_common_block() { + let _ = ::env_logger::try_init(); + let mut net = TestNet::new(2); + + net.peer(0).push_blocks(2, true); + net.peer(1).push_blocks(2, true); + let fork_hash = net.peer(0).push_blocks_at(BlockId::Number(0), 2, false); + net.peer(1).push_blocks_at(BlockId::Number(0), 2, false); + // wait for connection + block_on(futures::future::poll_fn::<(), _>(|cx| { + net.poll(cx); + if net.peer(0).num_peers() == 0 || net.peer(1).num_peers() == 0 { + Poll::Pending + } else { + Poll::Ready(()) + } + })); + + // both peers re-org to the same fork without notifying each other + net.peer(0).client().finalize_block(BlockId::Hash(fork_hash), Some(Vec::new()), true).unwrap(); + net.peer(1).client().finalize_block(BlockId::Hash(fork_hash), Some(Vec::new()), true).unwrap(); + let final_hash = net.peer(0).push_blocks(1, false); + + net.block_until_sync(); + + assert!(net.peer(1).client().header(&BlockId::Hash(final_hash)).unwrap().is_some()); +} + -- GitLab From 4e196982fc4f7287df51bb4e46a5491d65c725c5 Mon Sep 17 00:00:00 2001 From: Spencer Judge Date: Thu, 26 Mar 2020 01:17:17 -0700 Subject: [PATCH 077/300] Make AccountId32 hashable (#5405) * Make AccountId32 hashable * Only implement Hash in std Co-Authored-By: Nikolay Volf Co-authored-by: Nikolay Volf --- primitives/core/src/crypto.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index 259c3c5f9a..a9c118ce8f 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -554,6 +554,7 @@ pub trait Public: AsRef<[u8]> + AsMut<[u8]> + Default + Derive + CryptoType + Pa /// An opaque 32-byte cryptographic identifier. #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Default, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Hash))] pub struct AccountId32([u8; 32]); impl UncheckedFrom for AccountId32 { -- GitLab From 383340d6de9e3befa1eb98d2391a295695914106 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 26 Mar 2020 10:44:11 +0100 Subject: [PATCH 078/300] Update CODEOWNERS (#5409) --- docs/CODEOWNERS | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index b4f1b64c4b..d440434629 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -66,9 +66,14 @@ # Inflation points /frame/staking/src/inflation.rs @thiolliere -# NPoS and Governance +# NPoS and Governance and Phragmén /frame/staking/ @kianenigma /frame/elections/ @kianenigma +/frame/elections-phragmen/ @kianenigma +/primitives/phragmen/ @kianenigma + +# Fixed point arithmetic +/primitives/sp-arithmetic/ @kianenigma @thiolliere # End to end testing of substrate node /bin/node/executor/ @kianenigma -- GitLab From 43c716b27272e12821a6a679235e468da483b282 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 26 Mar 2020 11:04:52 +0100 Subject: [PATCH 079/300] Make Staking pallet using a proper Time module. (#4662) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add new trait, still migration to make * Apply suggestions from code review Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * implement migration * better naming * fix test * no longer require DeprecatedTime * add test * fix version * upgrade only from kusama * add test * fix test * Update frame/timestamp/src/lib.rs Co-Authored-By: Bastian Köcher Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Bastian Köcher --- Cargo.lock | 1 + bin/node/runtime/src/lib.rs | 2 +- frame/staking/Cargo.toml | 1 + frame/staking/src/lib.rs | 45 ++++++++++++++++++++------------- frame/staking/src/mock.rs | 4 +-- frame/staking/src/tests.rs | 11 ++++++-- frame/support/src/traits.rs | 6 +++++ frame/timestamp/src/lib.rs | 27 +++++++++++++++++--- primitives/timestamp/src/lib.rs | 1 + 9 files changed, 72 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f10f19f080..1ff0c1d2b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4514,6 +4514,7 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "hex", "pallet-authorship", "pallet-balances", "pallet-session", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 2330c89a86..8e64ee7a93 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -283,7 +283,7 @@ parameter_types! { impl pallet_staking::Trait for Runtime { type Currency = Balances; - type Time = Timestamp; + type UnixTime = Timestamp; type CurrencyToVote = CurrencyToVoteHandler; type RewardRemainder = Treasury; type Event = Event; diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index 82409b9cb4..d4da59617a 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -33,6 +33,7 @@ pallet-staking-reward-curve = { version = "2.0.0-alpha.5", path = "../staking/r substrate-test-utils = { version = "2.0.0-alpha.5", path = "../../test-utils" } frame-benchmarking = { version = "2.0.0-alpha.5", path = "../benchmarking" } rand_chacha = { version = "0.2" } +hex = "0.4" [features] default = ["std"] diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 53ef7b41e4..7becaf87f9 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -262,11 +262,12 @@ pub mod inflation; use sp_std::{prelude::*, result, collections::btree_map::BTreeMap}; use codec::{HasCompact, Encode, Decode}; use frame_support::{ - decl_module, decl_event, decl_storage, ensure, decl_error, weights::SimpleDispatchInfo, + decl_module, decl_event, decl_storage, ensure, decl_error, dispatch::DispatchResult, storage::IterableStorageMap, traits::{ Currency, LockIdentifier, LockableCurrency, WithdrawReasons, OnUnbalanced, Imbalance, Get, - Time - } + UnixTime + }, + weights::{SimpleDispatchInfo, Weight}, }; use pallet_session::historical::SessionManager; use sp_runtime::{ @@ -300,14 +301,14 @@ pub type RewardPoint = u32; /// Information regarding the active era (era in used in session). #[derive(Encode, Decode, RuntimeDebug)] -pub struct ActiveEraInfo { +pub struct ActiveEraInfo { /// Index of era. index: EraIndex, - /// Moment of start + /// Moment of start expresed as millisecond from `$UNIX_EPOCH`. /// /// Start can be none if start hasn't been set for the era yet, /// Start is set on the first on_finalize of the era to guarantee usage of `Time`. - start: Option, + start: Option, } /// Reward points of an era. Used to split era total payout between validators. @@ -564,7 +565,6 @@ type PositiveImbalanceOf = <::Currency as Currency<::AccountId>>::PositiveImbalance; type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; -type MomentOf = <::Time as Time>::Moment; /// Means for interacting with a specialized version of the `session` trait. /// @@ -613,7 +613,7 @@ pub trait Trait: frame_system::Trait { /// /// It is guaranteed to start being called from the first `on_finalize`. Thus value at genesis /// is not used. - type Time: Time; + type UnixTime: UnixTime; /// Convert a balance into a number used for election calculation. /// This must fit into a `u64` but is allowed to be sensibly lossy. @@ -686,11 +686,12 @@ impl Default for Forcing { enum Releases { V1_0_0Ancient, V2_0_0, + V3_0_0, } impl Default for Releases { fn default() -> Self { - Releases::V2_0_0 + Releases::V3_0_0 } } @@ -746,7 +747,7 @@ decl_storage! { /// /// The active era is the era currently rewarded. /// Validator set of this era must be equal to `SessionInterface::validators`. - pub ActiveEra get(fn active_era): Option>>; + pub ActiveEra get(fn active_era): Option; /// The session index at which the era start for the last `HISTORY_DEPTH` eras pub ErasStartSessionIndex get(fn eras_start_session_index): @@ -850,8 +851,8 @@ decl_storage! { /// Storage version of the pallet. /// - /// This is set to v2.0.0 for new networks. - StorageVersion build(|_: &GenesisConfig| Releases::V2_0_0): Releases; + /// This is set to v3.0.0 for new networks. + StorageVersion build(|_: &GenesisConfig| Releases::V3_0_0): Releases; } add_extra_genesis { config(stakers): @@ -959,12 +960,20 @@ decl_module! { // Set the start of the first era. if let Some(mut active_era) = Self::active_era() { if active_era.start.is_none() { - active_era.start = Some(T::Time::now()); - >::put(active_era); + let now_as_millis_u64 = T::UnixTime::now().as_millis().saturated_into::(); + active_era.start = Some(now_as_millis_u64); + ActiveEra::put(active_era); } } } + fn on_runtime_upgrade() -> Weight { + // For Kusama the type hasn't actually changed as Moment was u64 and was the number of + // millisecond since unix epoch. + StorageVersion::put(Releases::V3_0_0); + 0 + } + /// Take the origin account as a stash and lock up `value` of its balance. `controller` will /// be the account that controls it. /// @@ -1696,7 +1705,7 @@ impl Module { /// * reset `active_era.start`, /// * update `BondedEras` and apply slashes. fn start_era(start_session: SessionIndex) { - let active_era = >::mutate(|active_era| { + let active_era = ActiveEra::mutate(|active_era| { let new_index = active_era.as_ref().map(|info| info.index + 1).unwrap_or(0); *active_era = Some(ActiveEraInfo { index: new_index, @@ -1734,12 +1743,12 @@ impl Module { } /// Compute payout for era. - fn end_era(active_era: ActiveEraInfo>, _session_index: SessionIndex) { + fn end_era(active_era: ActiveEraInfo, _session_index: SessionIndex) { // Note: active_era_start can be None if end era is called during genesis config. if let Some(active_era_start) = active_era.start { - let now = T::Time::now(); + let now_as_millis_u64 = T::UnixTime::now().as_millis().saturated_into::(); - let era_duration = now - active_era_start; + let era_duration = now_as_millis_u64 - active_era_start; let (total_payout, _max_payout) = inflation::compute_total_payout( &T::RewardCurve::get(), Self::eras_total_stake(&active_era.index), diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index d4add81168..3e2b72dedf 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -201,8 +201,8 @@ parameter_types! { pub const MaxNominatorRewardedPerValidator: u32 = 64; } impl Trait for Test { - type Currency = pallet_balances::Module; - type Time = pallet_timestamp::Module; + type Currency = Balances; + type UnixTime = Timestamp; type CurrencyToVote = CurrencyToVoteHandler; type RewardRemainder = (); type Event = (); diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index d97982db12..6687b83f05 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -21,9 +21,8 @@ use mock::*; use sp_runtime::{assert_eq_error_rate, traits::BadOrigin}; use sp_staking::offence::OffenceDetails; use frame_support::{ - assert_ok, assert_noop, + assert_ok, assert_noop, StorageMap, traits::{Currency, ReservableCurrency, OnInitialize}, - StorageMap, }; use pallet_balances::Error as BalancesError; use substrate_test_utils::assert_eq_uvec; @@ -3039,3 +3038,11 @@ fn set_history_depth_works() { assert!(!::ErasTotalStake::contains_key(10 - 5)); }); } + +#[test] +fn assert_migration_is_noop() { + let kusama_active_era = "4a0200000190e2721171010000"; + let era = ActiveEraInfo::decode(&mut &hex::decode(kusama_active_era).unwrap()[..]).unwrap(); + assert_eq!(era.index, 586); + assert_eq!(era.start, Some(1585135674000)); +} diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index bd1534bac5..507cda53ed 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -858,6 +858,12 @@ pub trait Time { fn now() -> Self::Moment; } +/// Trait to deal with unix time. +pub trait UnixTime { + /// Return duration since `SystemTime::UNIX_EPOCH`. + fn now() -> core::time::Duration; +} + impl WithdrawReasons { /// Choose all variants except for `one`. /// diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 2a37dfdddb..cb220f4333 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -95,15 +95,17 @@ mod benchmarking; use sp_std::{result, cmp}; use sp_inherents::{ProvideInherent, InherentData, InherentIdentifier}; -use frame_support::{Parameter, decl_storage, decl_module}; -use frame_support::traits::{Time, Get}; +use frame_support::{ + Parameter, decl_storage, decl_module, debug, + traits::{Time, UnixTime, Get}, + weights::SimpleDispatchInfo, +}; use sp_runtime::{ RuntimeString, traits::{ AtLeast32Bit, Zero, SaturatedConversion, Scale } }; -use frame_support::weights::SimpleDispatchInfo; use frame_system::ensure_none; use sp_timestamp::{ InherentError, INHERENT_IDENTIFIER, InherentType, @@ -239,6 +241,25 @@ impl Time for Module { } } +/// Before the timestamp inherent is applied, it returns the time of previous block. +/// +/// On genesis the time returned is not valid. +impl UnixTime for Module { + fn now() -> core::time::Duration { + // now is duration since unix epoch in millisecond as documented in + // `sp_timestamp::InherentDataProvider`. + let now = Self::now(); + sp_std::if_std! { + if now == T::Moment::zero() { + debug::error!( + "`pallet_timestamp::UnixTime::now` is called at genesis, invalid value returned: 0" + ); + } + } + core::time::Duration::from_millis(now.saturated_into::()) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/primitives/timestamp/src/lib.rs b/primitives/timestamp/src/lib.rs index 979b98b495..f1fd06a44a 100644 --- a/primitives/timestamp/src/lib.rs +++ b/primitives/timestamp/src/lib.rs @@ -77,6 +77,7 @@ impl TimestampInherentData for InherentData { } } +/// Provide duration since unix epoch in millisecond for timestamp inherent. #[cfg(feature = "std")] pub struct InherentDataProvider; -- GitLab From 58439b555f49491dac26772eaeeb5f28941dc1de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Thu, 26 Mar 2020 11:16:24 +0100 Subject: [PATCH 080/300] contracts: Remove OnKilledAccount implementation (#5397) * contracts: Remove OnKilledAccount implementation Contracts now longer rely on this callback to tell them when they are removed. Instead, they can only self destruct using `ext_terminate`. * Fix account removal test * Fix account storage removal --- frame/contracts/src/account_db.rs | 8 -------- frame/contracts/src/lib.rs | 14 +------------- frame/contracts/src/tests.rs | 22 +++++++++++++++------- 3 files changed, 16 insertions(+), 28 deletions(-) diff --git a/frame/contracts/src/account_db.rs b/frame/contracts/src/account_db.rs index 374c55c374..165581e676 100644 --- a/frame/contracts/src/account_db.rs +++ b/frame/contracts/src/account_db.rs @@ -146,16 +146,8 @@ impl AccountDb for DirectAccountDb { let mut total_imbalance = SignedImbalance::zero(); for (address, changed) in s.into_iter() { if let Some(balance) = changed.balance() { - let existed = !T::Currency::total_balance(&address).is_zero(); let imbalance = T::Currency::make_free_balance_be(&address, balance); - let exists = !T::Currency::total_balance(&address).is_zero(); total_imbalance = total_imbalance.merge(imbalance); - if existed && !exists { - // Account killed. This will ultimately lead to calling `OnKilledAccount` callback - // which will make removal of CodeHashOf and AccountStorage for this account. - // In order to avoid writing over the deleted properties we `continue` here. - continue; - } } if changed.code_hash().is_some() diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index eeaa35a53d..0ca4215582 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -125,7 +125,7 @@ use frame_support::{ parameter_types, IsSubType, weights::DispatchInfo, }; -use frame_support::traits::{OnKilledAccount, OnUnbalanced, Currency, Get, Time, Randomness}; +use frame_support::traits::{OnUnbalanced, Currency, Get, Time, Randomness}; use frame_system::{self as system, ensure_signed, RawOrigin, ensure_root}; use sp_core::storage::well_known_keys::CHILD_STORAGE_KEY_PREFIX; use pallet_contracts_primitives::{RentProjection, ContractAccessError}; @@ -941,18 +941,6 @@ decl_storage! { } } -// TODO: this should be removed in favour of a self-destruct contract host function allowing the -// contract to delete all storage and the `ContractInfoOf` key and transfer remaining balance to -// some other account. As it stands, it's an economic insecurity on any smart-contract chain. -// https://github.com/paritytech/substrate/issues/4952 -impl OnKilledAccount for Module { - fn on_killed_account(who: &T::AccountId) { - if let Some(ContractInfo::Alive(info)) = >::take(who) { - child::kill_storage(&info.trie_id, info.child_trie_unique_id()); - } - } -} - /// In-memory cache of configuration values. /// /// We assume that these values can't be changed in the diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 2fcd2e58fb..3c6cd62a44 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -117,7 +117,7 @@ impl frame_system::Trait for Test { type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; type OnNewAccount = (); - type OnKilledAccount = Contracts; + type OnKilledAccount = (); } impl pallet_balances::Trait for Test { type Balance = u64; @@ -308,7 +308,7 @@ fn refunds_unused_gas() { } #[test] -fn account_removal_removes_storage() { +fn account_removal_does_not_remove_storage() { ExtBuilder::default().existential_deposit(100).build().execute_with(|| { let trie_id1 = ::TrieIdGenerator::trie_id(&1); let trie_id2 = ::TrieIdGenerator::trie_id(&2); @@ -351,14 +351,22 @@ fn account_removal_removes_storage() { // Transfer funds from account 1 of such amount that after this transfer // the balance of account 1 will be below the existential threshold. // - // This should lead to the removal of all storage associated with this account. + // This does not remove the contract storage as we are not notified about a + // account removal. This cannot happen in reality because a contract can only + // remove itself by `ext_terminate`. There is no external event that can remove + // the account appart from that. assert_ok!(Balances::transfer(Origin::signed(1), 2, 20)); - // Verify that all entries from account 1 is removed, while - // entries from account 2 is in place. + // Verify that no entries are removed. { - assert!(>::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key1).is_none()); - assert!(>::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key2).is_none()); + assert_eq!( + >::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key1), + Some(b"1".to_vec()) + ); + assert_eq!( + >::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key2), + Some(b"2".to_vec()) + ); assert_eq!( >::get_storage(&DirectAccountDb, &2, Some(&trie_id2), key1), -- GitLab From 9e1973967cf313f8f304217989ce94916ccdb967 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 26 Mar 2020 11:17:05 +0100 Subject: [PATCH 081/300] Mandate weight annotation (#5357) * Disallow default weight * Fix build and test * Fix tests * Fix another beloved ui test. * fix beloved trybuild tests * fix treasury? * Final test fix * Fix build * Fix another one * Fix * More doctest fix --- bin/node-template/pallets/template/src/lib.rs | 2 + bin/node/runtime/src/lib.rs | 1 - frame/assets/src/lib.rs | 3 + frame/benchmark/src/lib.rs | 21 +++++-- frame/benchmarking/src/tests.rs | 2 + frame/contracts/src/lib.rs | 5 ++ frame/finality-tracker/src/lib.rs | 1 + frame/generic-asset/src/lib.rs | 6 ++ frame/grandpa/src/lib.rs | 1 + frame/im-online/src/lib.rs | 2 + frame/indices/src/lib.rs | 4 ++ frame/nicks/src/lib.rs | 1 + frame/randomness-collective-flip/src/lib.rs | 3 +- frame/recovery/src/lib.rs | 1 + frame/scored-pool/src/lib.rs | 6 ++ frame/staking/src/lib.rs | 2 + frame/sudo/src/lib.rs | 6 +- frame/support/src/dispatch.rs | 56 +++++++++---------- frame/support/src/error.rs | 2 + frame/support/src/metadata.rs | 2 + frame/support/test/tests/decl_error.rs | 2 + frame/support/test/tests/instance.rs | 1 + .../tests/reserved_keyword/on_initialize.rs | 1 + .../reserved_keyword/on_initialize.stderr | 22 ++++---- frame/system/src/lib.rs | 3 +- frame/timestamp/src/lib.rs | 1 + frame/vesting/src/lib.rs | 2 + 27 files changed, 111 insertions(+), 48 deletions(-) diff --git a/bin/node-template/pallets/template/src/lib.rs b/bin/node-template/pallets/template/src/lib.rs index e910def236..a0daecfb72 100644 --- a/bin/node-template/pallets/template/src/lib.rs +++ b/bin/node-template/pallets/template/src/lib.rs @@ -75,6 +75,7 @@ decl_module! { /// Just a dummy entry point. /// function that can be called by the external world as an extrinsics call /// takes a parameter of the type `AccountId`, stores it, and emits an event + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn do_something(origin, something: u32) -> dispatch::DispatchResult { // Check it was signed and get the signer. See also: ensure_root and ensure_none let who = ensure_signed(origin)?; @@ -90,6 +91,7 @@ decl_module! { /// Another dummy entry point. /// takes no parameters, attempts to increment storage value, and possibly throws an error + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn cause_error(origin) -> dispatch::DispatchResult { // Check it was signed and get the signer. See also: ensure_root and ensure_none let _who = ensure_signed(origin)?; diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 8e64ee7a93..40d66367ed 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -938,7 +938,6 @@ impl_runtime_apis! { mod tests { use super::*; use frame_system::offchain::{SignAndSubmitTransaction, SubmitSignedTransaction}; - use frame_support::traits::OnInitialize; #[test] fn validate_transaction_submitter_bounds() { diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 838d21a462..388eb7780b 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -157,6 +157,7 @@ decl_module! { /// Issue a new class of fungible assets. There are, and will only ever be, `total` /// such assets and they'll all belong to the `origin` initially. It will have an /// identifier `AssetId` instance: this will be specified in the `Issued` event. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn issue(origin, #[compact] total: T::Balance) { let origin = ensure_signed(origin)?; @@ -170,6 +171,7 @@ decl_module! { } /// Move some assets from one holder to another. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn transfer(origin, #[compact] id: T::AssetId, target: ::Source, @@ -188,6 +190,7 @@ decl_module! { } /// Destroy any assets of `id` owned by `origin`. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn destroy(origin, #[compact] id: T::AssetId) { let origin = ensure_signed(origin)?; let balance = >::take((id, &origin)); diff --git a/frame/benchmark/src/lib.rs b/frame/benchmark/src/lib.rs index ec21f437d5..4ac0539eff 100644 --- a/frame/benchmark/src/lib.rs +++ b/frame/benchmark/src/lib.rs @@ -71,6 +71,7 @@ decl_module! { fn deposit_event() = default; /// Do nothing. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn do_nothing(_origin, input: u32) { if input > 0 { return Ok(()); @@ -82,6 +83,7 @@ decl_module! { /// storage database, however, the `repeat` calls will all pull from the /// storage overlay cache. You must consider this when analyzing the /// results of the benchmark. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn read_value(_origin, repeat: u32) { for _ in 0..repeat { MyValue::get(); @@ -89,6 +91,7 @@ decl_module! { } /// Put a value into a storage value. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn put_value(_origin, repeat: u32) { for r in 0..repeat { MyValue::put(r); @@ -100,6 +103,7 @@ decl_module! { /// storage database, however, the `repeat` calls will all pull from the /// storage overlay cache. You must consider this when analyzing the /// results of the benchmark. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn exists_value(_origin, repeat: u32) { for _ in 0..repeat { MyValue::exists(); @@ -107,6 +111,7 @@ decl_module! { } /// Remove a value from storage `repeat` number of times. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn remove_value(_origin, repeat: u32) { for r in 0..repeat { MyMap::remove(r); @@ -114,6 +119,7 @@ decl_module! { } /// Read a value from storage map `repeat` number of times. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn read_map(_origin, repeat: u32) { for r in 0..repeat { MyMap::get(r); @@ -121,6 +127,7 @@ decl_module! { } /// Insert a value into a map. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn insert_map(_origin, repeat: u32) { for r in 0..repeat { MyMap::insert(r, r); @@ -128,6 +135,7 @@ decl_module! { } /// Check is a map contains a value `repeat` number of times. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn contains_key_map(_origin, repeat: u32) { for r in 0..repeat { MyMap::contains_key(r); @@ -135,25 +143,29 @@ decl_module! { } /// Read a value from storage `repeat` number of times. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn remove_prefix(_origin, repeat: u32) { for r in 0..repeat { MyDoubleMap::remove_prefix(r); } } - // Add user to the list. + /// Add user to the list. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn add_member_list(origin) { let who = ensure_signed(origin)?; MyMemberList::::mutate(|x| x.push(who)); } - // Append user to the list. + /// Append user to the list. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn append_member_list(origin) { let who = ensure_signed(origin)?; MyMemberList::::append(&[who])?; } - // Encode a vector of accounts to bytes. + /// Encode a vector of accounts to bytes. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn encode_accounts(_origin, accounts: Vec) { let bytes = accounts.encode(); @@ -164,7 +176,8 @@ decl_module! { } } - // Decode bytes into a vector of accounts. + /// Decode bytes into a vector of accounts. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn decode_accounts(_origin, bytes: Vec) { let accounts: Vec = Decode::decode(&mut bytes.as_slice()).map_err(|_| "Could not decode")?; diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index 4327476c4a..b3537617c7 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -27,11 +27,13 @@ use frame_system::{RawOrigin, ensure_signed, ensure_none}; decl_module! { pub struct Module for enum Call where origin: T::Origin { + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn dummy(origin, _n: u32) -> DispatchResult { let _sender = ensure_signed(origin)?; Ok(()) } + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn other_dummy(origin, _n: u32) -> DispatchResult { let _sender = ensure_none(origin)?; Ok(()) diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 0ca4215582..090b345099 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -548,6 +548,7 @@ decl_module! { /// Updates the schedule for metering contracts. /// /// The schedule must have a greater version than the stored schedule. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn update_schedule(origin, schedule: Schedule) -> DispatchResult { ensure_root(origin)?; if >::current_schedule().version >= schedule.version { @@ -562,6 +563,7 @@ decl_module! { /// Stores the given binary Wasm code into the chain's storage and returns its `codehash`. /// You can instantiate contracts only with stored code. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn put_code( origin, #[compact] gas_limit: Gas, @@ -589,6 +591,7 @@ decl_module! { /// * If the account is a regular account, any value will be transferred. /// * If no account exists and the call value is not less than `existential_deposit`, /// a regular account will be created and any value will be transferred. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn call( origin, dest: ::Source, @@ -614,6 +617,7 @@ decl_module! { /// after the execution is saved as the `code` of the account. That code will be invoked /// upon any call received by this account. /// - The contract is initialized. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn instantiate( origin, #[compact] endowment: BalanceOf, @@ -636,6 +640,7 @@ decl_module! { /// /// If contract is not evicted as a result of this call, no actions are taken and /// the sender is not eligible for the reward. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn claim_surcharge(origin, dest: T::AccountId, aux_sender: Option) { let origin = origin.into(); let (signed, rewarded) = match (origin, aux_sender) { diff --git a/frame/finality-tracker/src/lib.rs b/frame/finality-tracker/src/lib.rs index d3bd2d18ad..4a6e2392f2 100644 --- a/frame/finality-tracker/src/lib.rs +++ b/frame/finality-tracker/src/lib.rs @@ -76,6 +76,7 @@ decl_module! { /// Hint that the author of this block thinks the best finalized /// block is the given number. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn final_hint(origin, #[compact] hint: T::BlockNumber) { ensure_none(origin)?; ensure!(!::Update::exists(), Error::::AlreadyUpdated); diff --git a/frame/generic-asset/src/lib.rs b/frame/generic-asset/src/lib.rs index 3cb48ad18a..b16666cb6b 100644 --- a/frame/generic-asset/src/lib.rs +++ b/frame/generic-asset/src/lib.rs @@ -360,12 +360,14 @@ decl_module! { fn deposit_event() = default; /// Create a new kind of asset. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn create(origin, options: AssetOptions) -> DispatchResult { let origin = ensure_signed(origin)?; Self::create_asset(None, Some(origin), options) } /// Transfer some liquid free balance to another account. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn transfer(origin, #[compact] asset_id: T::AssetId, to: T::AccountId, #[compact] amount: T::Balance) { let origin = ensure_signed(origin)?; ensure!(!amount.is_zero(), Error::::ZeroAmount); @@ -375,6 +377,7 @@ decl_module! { /// Updates permission for a given `asset_id` and an account. /// /// The `origin` must have `update` permission. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn update_permission( origin, #[compact] asset_id: T::AssetId, @@ -397,6 +400,7 @@ decl_module! { /// Mints an asset, increases its total issuance. /// The origin must have `mint` permissions. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn mint(origin, #[compact] asset_id: T::AssetId, to: T::AccountId, amount: T::Balance) -> DispatchResult { let who = ensure_signed(origin)?; Self::mint_free(&asset_id, &who, &to, &amount)?; @@ -406,6 +410,7 @@ decl_module! { /// Burns an asset, decreases its total issuance. /// The `origin` must have `burn` permissions. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn burn(origin, #[compact] asset_id: T::AssetId, to: T::AccountId, amount: T::Balance) -> DispatchResult { let who = ensure_signed(origin)?; Self::burn_free(&asset_id, &who, &to, &amount)?; @@ -415,6 +420,7 @@ decl_module! { /// Can be used to create reserved tokens. /// Requires Root call. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn create_reserved( origin, asset_id: T::AssetId, diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index dd0101e5f6..9635bba2d1 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -184,6 +184,7 @@ decl_module! { fn deposit_event() = default; /// Report some misbehavior. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn report_misbehavior(origin, _report: Vec) { ensure_signed(origin)?; // FIXME: https://github.com/paritytech/substrate/issues/1112 diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index a164c379fb..59f2c681b3 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -50,6 +50,7 @@ //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { +//! #[weight = frame_support::weights::SimpleDispatchInfo::default()] //! pub fn is_online(origin, authority_index: u32) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; //! let _is_online = >::is_online(authority_index); @@ -309,6 +310,7 @@ decl_module! { fn deposit_event() = default; + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn heartbeat( origin, heartbeat: Heartbeat, diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index e3e74e6e9e..d2ba664d42 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -121,6 +121,7 @@ decl_module! { /// - One reserve operation. /// - One event. /// # + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn claim(origin, index: T::AccountIndex) { let who = ensure_signed(origin)?; @@ -148,6 +149,7 @@ decl_module! { /// - One transfer operation. /// - One event. /// # + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn transfer(origin, new: T::AccountId, index: T::AccountIndex) { let who = ensure_signed(origin)?; ensure!(who != new, Error::::NotTransfer); @@ -178,6 +180,7 @@ decl_module! { /// - One reserve operation. /// - One event. /// # + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn free(origin, index: T::AccountIndex) { let who = ensure_signed(origin)?; @@ -206,6 +209,7 @@ decl_module! { /// - Up to one reserve operation. /// - One event. /// # + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn force_transfer(origin, new: T::AccountId, index: T::AccountIndex) { ensure_root(origin)?; diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 2ab1789d39..125d1fd198 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -171,6 +171,7 @@ decl_module! { /// - One storage read/write. /// - One event. /// # + #[weight = SimpleDispatchInfo::FixedNormal(70_000)] fn clear_name(origin) { let sender = ensure_signed(origin)?; diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index 323af78793..fdc465b4dc 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -35,12 +35,13 @@ //! ### Example - Get random seed for the current block //! //! ``` -//! use frame_support::{decl_module, dispatch, traits::Randomness}; +//! use frame_support::{decl_module, dispatch, traits::Randomness, weights::SimpleDispatchInfo}; //! //! pub trait Trait: frame_system::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { +//! #[weight = SimpleDispatchInfo::default()] //! pub fn random_module_example(origin) -> dispatch::DispatchResult { //! let _random_seed = >::random_seed(); //! Ok(()) diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index d7f5127ee3..c59ba85bdc 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -645,6 +645,7 @@ decl_module! { /// # /// - One storage mutation to check account is recovered by `who`. O(1) /// # + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn cancel_recovered(origin, account: T::AccountId) { let who = ensure_signed(origin)?; // Check `who` is allowed to make a call on behalf of `account` diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index 9ebac91e93..2c2bfc6a12 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -61,6 +61,7 @@ //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { +//! #[weight = frame_support::weights::SimpleDispatchInfo::default()] //! pub fn candidate(origin) -> dispatch::DispatchResult { //! let who = ensure_signed(origin)?; //! @@ -265,6 +266,7 @@ decl_module! { /// /// The `index` parameter of this function must be set to /// the index of the transactor in the `Pool`. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn submit_candidacy(origin) { let who = ensure_signed(origin)?; ensure!(!>::contains_key(&who), Error::::AlreadyInPool); @@ -294,6 +296,7 @@ decl_module! { /// /// The `index` parameter of this function must be set to /// the index of the transactor in the `Pool`. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn withdraw_candidacy( origin, index: u32 @@ -313,6 +316,7 @@ decl_module! { /// /// The `index` parameter of this function must be set to /// the index of `dest` in the `Pool`. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn kick( origin, dest: ::Source, @@ -337,6 +341,7 @@ decl_module! { /// /// The `index` parameter of this function must be set to /// the index of the `dest` in the `Pool`. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn score( origin, dest: ::Source, @@ -377,6 +382,7 @@ decl_module! { /// (this happens each `Period`). /// /// May only be called from root. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn change_member_count(origin, count: u32) { ensure_root(origin)?; >::put(&count); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 7becaf87f9..31cbf3b8db 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -157,6 +157,7 @@ //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { //! /// Reward a validator. +//! #[weight = frame_support::weights::SimpleDispatchInfo::default()] //! pub fn reward_myself(origin) -> dispatch::DispatchResult { //! let reported = ensure_signed(origin)?; //! >::reward_by_ids(vec![(reported, 10)]); @@ -1476,6 +1477,7 @@ decl_module! { /// This can be called from any origin. /// /// - `stash`: The stash account to reap. Its balance must be zero. + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn reap_stash(_origin, stash: T::AccountId) { ensure!(T::Currency::total_balance(&stash).is_zero(), Error::::FundedTarget); Self::kill_stash(&stash)?; diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index 8ee09ba223..462a84c0a1 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -58,6 +58,7 @@ //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { +//! #[weight = frame_support::weights::SimpleDispatchInfo::default()] //! pub fn privileged_function(origin) -> dispatch::DispatchResult { //! ensure_root(origin)?; //! @@ -120,7 +121,7 @@ decl_module! { /// - Weight of derivative `call` execution + 10,000. /// # #[weight = FunctionOf( - |args: (&Box<::Call>,)| args.0.get_dispatch_info().weight + 10_000, + |args: (&Box<::Call>,)| args.0.get_dispatch_info().weight + 10_000, |args: (&Box<::Call>,)| args.0.get_dispatch_info().class, true )] @@ -150,6 +151,7 @@ decl_module! { /// - Limited storage reads. /// - One DB change. /// # + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn set_key(origin, new: ::Source) { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; @@ -174,7 +176,7 @@ decl_module! { #[weight = FunctionOf( |args: (&::Source, &Box<::Call>,)| { args.1.get_dispatch_info().weight + 10_000 - }, + }, |args: (&::Source, &Box<::Call>,)| { args.1.get_dispatch_info().class }, diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index 75d4428797..dadeb5cf82 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -57,12 +57,14 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; +/// # use frame_support::weights::SimpleDispatchInfo; /// # use frame_system::{self as system, Trait, ensure_signed}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { /// /// // Private functions are dispatchable, but not available to other /// // FRAME pallets. +/// #[weight = SimpleDispatchInfo::default()] /// fn my_function(origin, var: u64) -> dispatch::DispatchResult { /// // Your implementation /// Ok(()) @@ -70,6 +72,7 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// /// // Public functions are both dispatchable and available to other /// // FRAME pallets. +/// #[weight = SimpleDispatchInfo::default()] /// pub fn my_public_function(origin) -> dispatch::DispatchResult { /// // Your implementation /// Ok(()) @@ -97,15 +100,17 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; +/// # use frame_support::weights::SimpleDispatchInfo; /// # use frame_system::{self as system, Trait, ensure_signed}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { -/// +/// #[weight = SimpleDispatchInfo::default()] /// fn my_long_function(origin) -> dispatch::DispatchResult { /// // Your implementation /// Ok(()) /// } /// +/// #[weight = SimpleDispatchInfo::default()] /// fn my_short_function(origin) { /// // Your implementation /// } @@ -122,9 +127,11 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; +/// # use frame_support::weights::SimpleDispatchInfo; /// # use frame_system::{self as system, Trait, ensure_signed, ensure_root}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { +/// #[weight = SimpleDispatchInfo::default()] /// fn my_privileged_function(origin) -> dispatch::DispatchResult { /// ensure_root(origin)?; /// // Your implementation @@ -807,27 +814,10 @@ macro_rules! decl_module { ) $( -> $result:ty )* { $( $impl:tt )* } $($rest:tt)* ) => { - $crate::decl_module!(@normalize - $(#[$attr])* - pub struct $mod_type< - $trait_instance: $trait_name$(, $instance: $instantiable $(= $module_default_instance)?)? - > - for enum $call_type where origin: $origin_type, system = $system - { $( $other_where_bounds )* } - { $( $deposit_event )* } - { $( $on_initialize )* } - { $( $on_runtime_upgrade )* } - { $( $on_finalize )* } - { $( $offchain )* } - { $( $constants )* } - { $( $error_type )* } - [ $( $dispatchables )* ] - $(#[doc = $doc_attr])* - #[weight = $crate::dispatch::SimpleDispatchInfo::default()] - $fn_vis fn $fn_name( - $from $(, $(#[$codec_attr])* $param_name : $param )* - ) $( -> $result )* { $( $impl )* } - $($rest)* + compile_error!(concat!( + "Missing weight for ", stringify!($ident), + ". Every dispatchable must have a #[weight] attribute." + ) ); }; // Ignore any ident which is not `origin` with type `T::Origin`. @@ -1444,9 +1434,9 @@ macro_rules! decl_module { &$weight, ($( $param_name, )*) ); - $crate::dispatch::DispatchInfo { - weight, - class, + $crate::dispatch::DispatchInfo { + weight, + class, pays_fee, } }, @@ -2063,21 +2053,31 @@ mod tests { decl_module! { pub struct Module for enum Call where origin: T::Origin, T::AccountId: From { /// Hi, this is a comment. + #[weight = SimpleDispatchInfo::default()] fn aux_0(_origin) -> DispatchResult { unreachable!() } + + #[weight = SimpleDispatchInfo::default()] fn aux_1(_origin, #[compact] _data: u32,) -> DispatchResult { unreachable!() } + + #[weight = SimpleDispatchInfo::default()] fn aux_2(_origin, _data: i32, _data2: String) -> DispatchResult { unreachable!() } + #[weight = SimpleDispatchInfo::FixedNormal(3)] fn aux_3(_origin) -> DispatchResult { unreachable!() } + + #[weight = SimpleDispatchInfo::default()] fn aux_4(_origin, _data: i32) -> DispatchResult { unreachable!() } + + #[weight = SimpleDispatchInfo::default()] fn aux_5(_origin, _data: i32, #[compact] _data2: u32,) -> DispatchResult { unreachable!() } + #[weight = SimpleDispatchInfo::FixedOperational(5)] + fn operational(_origin) { unreachable!() } + fn on_initialize(n: T::BlockNumber,) -> Weight { if n.into() == 42 { panic!("on_initialize") } 7 } fn on_finalize(n: T::BlockNumber,) { if n.into() == 42 { panic!("on_finalize") } } fn on_runtime_upgrade() -> Weight { 10 } fn offchain_worker() {} - - #[weight = SimpleDispatchInfo::FixedOperational(5)] - fn operational(_origin,) { unreachable!() } } } diff --git a/frame/support/src/error.rs b/frame/support/src/error.rs index 3b105e979d..f619250726 100644 --- a/frame/support/src/error.rs +++ b/frame/support/src/error.rs @@ -35,6 +35,7 @@ pub use frame_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent}; /// /// ``` /// # use frame_support::{decl_error, decl_module}; +/// # use frame_support::weights::SimpleDispatchInfo; /// decl_error! { /// /// Errors that can occur in my module. /// pub enum MyError for Module { @@ -54,6 +55,7 @@ pub use frame_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent}; /// pub struct Module for enum Call where origin: T::Origin { /// type Error = MyError; /// +/// #[weight = SimpleDispatchInfo::default()] /// fn do_something(origin) -> frame_support::dispatch::DispatchResult { /// Err(MyError::::YouAreNotCoolEnough.into()) /// } diff --git a/frame/support/src/metadata.rs b/frame/support/src/metadata.rs index 46662e5354..d9c8136d3c 100644 --- a/frame/support/src/metadata.rs +++ b/frame/support/src/metadata.rs @@ -336,6 +336,7 @@ mod tests { mod event_module { use crate::dispatch::DispatchResult; + use crate::weights::SimpleDispatchInfo; pub trait Trait: super::system::Trait { type Balance; @@ -353,6 +354,7 @@ mod tests { pub struct Module for enum Call where origin: T::Origin { type Error = Error; + #[weight = SimpleDispatchInfo::default()] fn aux_0(_origin) -> DispatchResult { unreachable!() } } } diff --git a/frame/support/test/tests/decl_error.rs b/frame/support/test/tests/decl_error.rs index 39d7dbdb96..4191e79f24 100644 --- a/frame/support/test/tests/decl_error.rs +++ b/frame/support/test/tests/decl_error.rs @@ -32,6 +32,7 @@ mod module1 { pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: ::Origin { + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn fail(_origin) -> frame_support::dispatch::DispatchResult { Err(Error::::Something.into()) } @@ -58,6 +59,7 @@ mod module2 { pub struct Module for enum Call where origin: ::Origin { + #[weight = frame_support::weights::SimpleDispatchInfo::default()] pub fn fail(_origin) -> frame_support::dispatch::DispatchResult { Err(Error::::Something.into()) } diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index 92281ef131..ea5d32fea3 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -55,6 +55,7 @@ mod module1 { fn deposit_event() = default; + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn one(origin) { system::ensure_root(origin)?; Self::deposit_event(RawEvent::AnotherVariant(3)); diff --git a/frame/support/test/tests/reserved_keyword/on_initialize.rs b/frame/support/test/tests/reserved_keyword/on_initialize.rs index 84feb2d93f..8eacc836c4 100644 --- a/frame/support/test/tests/reserved_keyword/on_initialize.rs +++ b/frame/support/test/tests/reserved_keyword/on_initialize.rs @@ -19,6 +19,7 @@ macro_rules! reserved { frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin { + #[weight = frame_support::weights::SimpleDispatchInfo::default()] fn $reserved(_origin) -> dispatch::DispatchResult { unreachable!() } } } diff --git a/frame/support/test/tests/reserved_keyword/on_initialize.stderr b/frame/support/test/tests/reserved_keyword/on_initialize.stderr index d20a6e1145..e899ef5d78 100644 --- a/frame/support/test/tests/reserved_keyword/on_initialize.stderr +++ b/frame/support/test/tests/reserved_keyword/on_initialize.stderr @@ -1,39 +1,39 @@ error: Invalid call fn name: `on_finalize`, name is reserved and doesn't match expected signature, please refer to `decl_module!` documentation to see the appropriate usage, or rename it to an unreserved keyword. - --> $DIR/on_initialize.rs:30:1 + --> $DIR/on_initialize.rs:31:1 | -30 | reserved!(on_finalize on_initialize on_runtime_upgrade offchain_worker deposit_event); +31 | reserved!(on_finalize on_initialize on_runtime_upgrade offchain_worker deposit_event); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: Invalid call fn name: `on_initialize`, name is reserved and doesn't match expected signature, please refer to `decl_module!` documentation to see the appropriate usage, or rename it to an unreserved keyword. - --> $DIR/on_initialize.rs:30:1 + --> $DIR/on_initialize.rs:31:1 | -30 | reserved!(on_finalize on_initialize on_runtime_upgrade offchain_worker deposit_event); +31 | reserved!(on_finalize on_initialize on_runtime_upgrade offchain_worker deposit_event); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: Invalid call fn name: `on_runtime_upgrade`, name is reserved and doesn't match expected signature, please refer to `decl_module!` documentation to see the appropriate usage, or rename it to an unreserved keyword. - --> $DIR/on_initialize.rs:30:1 + --> $DIR/on_initialize.rs:31:1 | -30 | reserved!(on_finalize on_initialize on_runtime_upgrade offchain_worker deposit_event); +31 | reserved!(on_finalize on_initialize on_runtime_upgrade offchain_worker deposit_event); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: Invalid call fn name: `offchain_worker`, name is reserved and doesn't match expected signature, please refer to `decl_module!` documentation to see the appropriate usage, or rename it to an unreserved keyword. - --> $DIR/on_initialize.rs:30:1 + --> $DIR/on_initialize.rs:31:1 | -30 | reserved!(on_finalize on_initialize on_runtime_upgrade offchain_worker deposit_event); +31 | reserved!(on_finalize on_initialize on_runtime_upgrade offchain_worker deposit_event); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: `deposit_event` function is reserved and must follow the syntax: `$vis:vis fn deposit_event() = default;` - --> $DIR/on_initialize.rs:30:1 +error: Invalid call fn name: `deposit_event`, name is reserved and doesn't match expected signature, please refer to `decl_module!` documentation to see the appropriate usage, or rename it to an unreserved keyword. + --> $DIR/on_initialize.rs:31:1 | -30 | reserved!(on_finalize on_initialize on_runtime_upgrade offchain_worker deposit_event); +31 | reserved!(on_finalize on_initialize on_runtime_upgrade offchain_worker deposit_event); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 138a151427..34adf69fa5 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -68,13 +68,14 @@ //! ### Example - Get extrinsic count and parent hash for the current block //! //! ``` -//! use frame_support::{decl_module, dispatch}; +//! use frame_support::{decl_module, dispatch, weights::SimpleDispatchInfo}; //! use frame_system::{self as system, ensure_signed}; //! //! pub trait Trait: system::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { +//! #[weight = SimpleDispatchInfo::default()] //! pub fn system_module_example(origin) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; //! let _extrinsic_count = >::extrinsic_count(); diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index cb220f4333..d64b43ac17 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -69,6 +69,7 @@ //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { +//! #[weight = frame_support::weights::SimpleDispatchInfo::default()] //! pub fn get_time(origin) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; //! let _now = >::get(); diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index 94a70b7ef1..3f7cdf3170 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -195,6 +195,7 @@ decl_module! { /// - One storage read (codec `O(1)`) and up to one removal. /// - One event. /// # + #[weight = SimpleDispatchInfo::default()] fn vest(origin) -> DispatchResult { let who = ensure_signed(origin)?; Self::update_lock(who) @@ -216,6 +217,7 @@ decl_module! { /// - One storage read (codec `O(1)`) and up to one removal. /// - One event. /// # + #[weight = SimpleDispatchInfo::default()] fn vest_other(origin, target: ::Source) -> DispatchResult { ensure_signed(origin)?; Self::update_lock(T::Lookup::lookup(target)?) -- GitLab From 2b89e83d8b3abc95a9b3ec40c81ed60f4f15e215 Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Thu, 26 Mar 2020 11:18:24 +0100 Subject: [PATCH 082/300] Benchmark Democracy Pallet (#5257) * Add origin bounds to benchmark macro. * Add democracy benchmark. * Fix tests * Remove collective from frame/benchmarking, partially use EnsureOrigin. * Remove collective stuff. * Make previous benches compile again. * Remove comments. * Make prev bench to work again. * Add remove votes. * Add new proxy calls. * Add runtime-benchmarks guard to EnsureOrigin and implementations. * Refactor. * Add missing import. * Remove duplicated import * Fix features. * Add some missing features. * Update frame/collective/Cargo.toml Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/democracy/src/benchmarking.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/democracy/src/benchmarking.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Add referendums to state. * populate vecs before call * Update weight docs * More fixes and weight docs * More updates Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Shawn Tabrizi --- Cargo.lock | 1 + bin/node/runtime/Cargo.toml | 6 +- bin/node/runtime/src/lib.rs | 7 + frame/collective/Cargo.toml | 7 +- frame/collective/src/lib.rs | 22 +- frame/democracy/Cargo.toml | 7 + frame/democracy/src/benchmarking.rs | 456 ++++++++++++++++++++++++++++ frame/democracy/src/lib.rs | 18 +- frame/society/Cargo.toml | 4 + frame/society/src/lib.rs | 6 + frame/staking/Cargo.toml | 1 - frame/support/Cargo.toml | 2 +- frame/system/Cargo.toml | 2 +- frame/system/src/lib.rs | 31 +- frame/vesting/Cargo.toml | 2 +- primitives/runtime/Cargo.toml | 1 + primitives/runtime/src/traits.rs | 6 + 17 files changed, 564 insertions(+), 15 deletions(-) create mode 100644 frame/democracy/src/benchmarking.rs diff --git a/Cargo.lock b/Cargo.lock index 1ff0c1d2b2..2e1cd47e0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4170,6 +4170,7 @@ dependencies = [ name = "pallet-democracy" version = "2.0.0-alpha.5" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", "hex-literal", diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 24ae560607..34f2e381c2 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -134,16 +134,20 @@ std = [ runtime-benchmarks = [ "frame-benchmarking", "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-collective/runtime-benchmarks", "pallet-elections-phragmen/runtime-benchmarks", "pallet-identity/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", - "pallet-session-benchmarking", "pallet-staking/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", "pallet-collective/runtime-benchmarks", "pallet-session-benchmarking", "pallet-staking/runtime-benchmarks", + "pallet-society/runtime-benchmarks", "pallet-im-online/runtime-benchmarks", + "pallet-democracy/runtime-benchmarks", ] diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 40d66367ed..5c61eadf15 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -919,6 +919,13 @@ impl_runtime_apis! { steps, repeat, ), + b"pallet-democracy" | b"democracy" => Democracy::run_benchmark( + extrinsic, + lowest_range_values, + highest_range_values, + steps, + repeat, + ), b"pallet-collective" | b"collective" => Council::run_benchmark( extrinsic, lowest_range_values, diff --git a/frame/collective/Cargo.toml b/frame/collective/Cargo.toml index 353a3873d5..018340341f 100644 --- a/frame/collective/Cargo.toml +++ b/frame/collective/Cargo.toml @@ -31,9 +31,12 @@ std = [ "sp-std/std", "serde", "sp-io/std", - "frame-benchmarking/std", "frame-support/std", "sp-runtime/std", "frame-system/std", ] -runtime-benchmarks = ["frame-benchmarking"] +runtime-benchmarks = [ + "frame-benchmarking", + "sp-runtime/runtime-benchmarks", + "frame-system/runtime-benchmarks", +] diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 84bb76cfd0..5afdcd2b42 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -434,7 +434,7 @@ where pub struct EnsureMember(sp_std::marker::PhantomData<(AccountId, I)>); impl< O: Into, O>> + From>, - AccountId, + AccountId: Default, I, > EnsureOrigin for EnsureMember { type Success = AccountId; @@ -444,6 +444,11 @@ impl< r => Err(O::from(r)), }) } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + O::from(RawOrigin::Member(Default::default())) + } } pub struct EnsureMembers(sp_std::marker::PhantomData<(N, AccountId, I)>); @@ -460,6 +465,11 @@ impl< r => Err(O::from(r)), }) } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + O::from(RawOrigin::Members(N::VALUE, N::VALUE)) + } } pub struct EnsureProportionMoreThan( @@ -479,6 +489,11 @@ impl< r => Err(O::from(r)), }) } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + O::from(RawOrigin::Members(1u32, 0u32)) + } } pub struct EnsureProportionAtLeast( @@ -498,6 +513,11 @@ impl< r => Err(O::from(r)), }) } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + O::from(RawOrigin::Members(0u32, 0u32)) + } } #[cfg(test)] diff --git a/frame/democracy/Cargo.toml b/frame/democracy/Cargo.toml index f7dd0b7f0a..6e7aa60e79 100644 --- a/frame/democracy/Cargo.toml +++ b/frame/democracy/Cargo.toml @@ -14,6 +14,7 @@ codec = { package = "parity-scale-codec", version = "1.2.0", default-features = sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } @@ -30,7 +31,13 @@ std = [ "codec/std", "sp-std/std", "sp-io/std", + "frame-benchmarking/std", "frame-support/std", "sp-runtime/std", "frame-system/std", ] +runtime-benchmarks = [ + "frame-benchmarking", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] diff --git a/frame/democracy/src/benchmarking.rs b/frame/democracy/src/benchmarking.rs new file mode 100644 index 0000000000..2429edbefd --- /dev/null +++ b/frame/democracy/src/benchmarking.rs @@ -0,0 +1,456 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Democracy pallet benchmarking. + +use super::*; + +use frame_benchmarking::{benchmarks, account}; +use frame_support::traits::{Currency, Get}; +use frame_system::{RawOrigin, Module as System, self}; +use sp_runtime::traits::{Bounded, EnsureOrigin, One}; + +use crate::Module as Democracy; + +const SEED: u32 = 0; +const MAX_USERS: u32 = 1000; +const MAX_REFERENDUMS: u32 = 100; +const MAX_PROPOSALS: u32 = 100; + +fn funded_account(name: &'static str, index: u32) -> T::AccountId { + let caller: T::AccountId = account(name, index, SEED); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + caller +} + +fn add_proposal(n: u32) -> Result { + let other = funded_account::("proposer", n); + let value = T::MinimumDeposit::get(); + let proposal_hash: T::Hash = T::Hashing::hash_of(&n); + + Democracy::::propose(RawOrigin::Signed(other).into(), proposal_hash, value.into())?; + + Ok(proposal_hash) +} + +fn add_referendum(n: u32) -> Result { + let proposal_hash = add_proposal::(n)?; + let vote_threshold = VoteThreshold::SimpleMajority; + + Democracy::::inject_referendum( + 0.into(), + proposal_hash, + vote_threshold, + 0.into(), + ); + let referendum_index: ReferendumIndex = ReferendumCount::get() - 1; + Ok(referendum_index) +} + +fn account_vote() -> AccountVote> { + let v = Vote { + aye: true, + conviction: Conviction::Locked1x, + }; + + AccountVote::Standard { + vote: v, + balance: BalanceOf::::one(), + } +} + +fn open_activate_proxy(u: u32) -> Result { + let caller = funded_account::("caller", u); + let proxy = funded_account::("proxy", u); + + Democracy::::open_proxy(RawOrigin::Signed(proxy.clone()).into(), caller.clone())?; + Democracy::::activate_proxy(RawOrigin::Signed(caller).into(), proxy.clone())?; + + Ok(proxy) +} + +benchmarks! { + _ { } + + propose { + let p in 1 .. MAX_PROPOSALS; + + // Add p proposals + for i in 0..p { + add_proposal::(i)?; + } + + let caller = funded_account::("caller", 0); + let proposal_hash: T::Hash = T::Hashing::hash_of(&p); + let value = T::MinimumDeposit::get(); + }: _(RawOrigin::Signed(caller), proposal_hash, value.into()) + + second { + let s in 0 .. 100; + + // Create s existing "seconds" + for i in 0..s { + let seconder = funded_account::("seconder", i); + Democracy::::second(RawOrigin::Signed(seconder).into(), 0)?; + } + + let caller = funded_account::("caller", 0); + let proposal_hash = add_proposal::(s)?; + }: _(RawOrigin::Signed(caller), 0) + + vote { + let r in 1 .. MAX_REFERENDUMS; + + let caller = funded_account::("caller", 0); + let account_vote = account_vote::(); + + for i in 0 .. r { + let ref_idx = add_referendum::(i)?; + Democracy::::vote(RawOrigin::Signed(caller.clone()).into(), ref_idx, account_vote.clone())?; + } + + let referendum_index = r - 1; + + }: _(RawOrigin::Signed(caller), referendum_index, account_vote) + + proxy_vote { + let r in 1 .. MAX_REFERENDUMS; + + let caller = funded_account::("caller", r); + let proxy = open_activate_proxy::(r)?; + let account_vote = account_vote::(); + + for i in 0 .. r { + let ref_idx = add_referendum::(i)?; + Democracy::::vote(RawOrigin::Signed(caller.clone()).into(), ref_idx, account_vote.clone())?; + } + + let referendum_index = r - 1; + + }: _(RawOrigin::Signed(proxy), referendum_index, account_vote) + + emergency_cancel { + let u in 1 .. MAX_USERS; + + let referendum_index = add_referendum::(u)?; + let origin = T::CancellationOrigin::successful_origin(); + let call = Call::::emergency_cancel(referendum_index); + }: { + let _ = call.dispatch(origin)?; + } + + external_propose { + let u in 1 .. MAX_USERS; + + let origin = T::ExternalOrigin::successful_origin(); + let proposal_hash = T::Hashing::hash_of(&u); + let call = Call::::external_propose(proposal_hash); + }: { + let _ = call.dispatch(origin)?; + } + + external_propose_majority { + let u in 1 .. MAX_USERS; + + let origin = T::ExternalMajorityOrigin::successful_origin(); + let proposal_hash = T::Hashing::hash_of(&u); + let call = Call::::external_propose_majority(proposal_hash); + + }: { + let _ = call.dispatch(origin)?; + } + + external_propose_default { + let u in 1 .. MAX_USERS; + + let origin = T::ExternalDefaultOrigin::successful_origin(); + let proposal_hash = T::Hashing::hash_of(&u); + let call = Call::::external_propose_default(proposal_hash); + + }: { + let _ = call.dispatch(origin)?; + } + + fast_track { + let u in 1 .. MAX_USERS; + + let origin_propose = T::ExternalDefaultOrigin::successful_origin(); + let proposal_hash: T::Hash = T::Hashing::hash_of(&u); + Democracy::::external_propose_default(origin_propose, proposal_hash.clone())?; + + let origin_fast_track = T::FastTrackOrigin::successful_origin(); + let voting_period = T::FastTrackVotingPeriod::get(); + let delay = 0; + let call = Call::::fast_track(proposal_hash, voting_period.into(), delay.into()); + + }: { + let _ = call.dispatch(origin_fast_track)?; + } + + veto_external { + // Existing veto-ers + let v in 0 .. 100; + + let proposal_hash: T::Hash = T::Hashing::hash_of(&v); + + let origin_propose = T::ExternalDefaultOrigin::successful_origin(); + Democracy::::external_propose_default(origin_propose, proposal_hash.clone())?; + + let mut vetoers: Vec = Vec::new(); + for i in 0..v { + vetoers.push(account("vetoer", i, SEED)); + } + Blacklist::::insert(proposal_hash, (T::BlockNumber::zero(), vetoers)); + + let call = Call::::veto_external(proposal_hash); + let origin = T::VetoOrigin::successful_origin(); + }: { + let _ = call.dispatch(origin)?; + } + + cancel_referendum { + let u in 1 .. MAX_USERS; + + let referendum_index = add_referendum::(u)?; + }: _(RawOrigin::Root, referendum_index) + + cancel_queued { + let d in 0 .. 100; + + let referendum_index = add_referendum::(d)?; + let block_number: T::BlockNumber = 0.into(); + let hash: T::Hash = T::Hashing::hash_of(&d); + >::put(vec![(block_number, hash, referendum_index.clone()); d as usize]); + }: _(RawOrigin::Root, referendum_index) + + open_proxy { + let u in 1 .. MAX_USERS; + + let caller: T::AccountId = funded_account::("caller", u); + let proxy: T::AccountId = funded_account::("proxy", u); + + }: _(RawOrigin::Signed(proxy), caller) + + activate_proxy { + let u in 1 .. MAX_USERS; + + let caller: T::AccountId = funded_account::("caller", u); + let proxy: T::AccountId = funded_account::("proxy", u); + Democracy::::open_proxy(RawOrigin::Signed(proxy.clone()).into(), caller.clone())?; + + }: _(RawOrigin::Signed(caller), proxy) + + close_proxy { + let u in 1 .. MAX_USERS; + + let proxy = open_activate_proxy::(u)?; + + }: _(RawOrigin::Signed(proxy)) + + deactivate_proxy { + let u in 1 .. MAX_USERS; + + let caller = funded_account::("caller", u); + let proxy = open_activate_proxy::(u)?; + + }: _(RawOrigin::Signed(caller), proxy) + + delegate { + let u in 1 .. MAX_USERS; + + let caller = funded_account::("caller", u); + let d: T::AccountId = funded_account::("delegate", u); + let balance = 1u32; + + }: _(RawOrigin::Signed(caller), d.into(), Conviction::Locked1x, balance.into()) + + undelegate { + let r in 1 .. MAX_REFERENDUMS; + + let other = funded_account::("other", 0); + let account_vote = account_vote::(); + + for i in 0 .. r { + let ref_idx = add_referendum::(i)?; + Democracy::::vote(RawOrigin::Signed(other.clone()).into(), ref_idx, account_vote.clone())?; + } + + let delegator = funded_account::("delegator", r); + let conviction = Conviction::Locked1x; + let balance = 1u32; + + Democracy::::delegate(RawOrigin::Signed(delegator.clone()).into(), other.clone().into(), conviction, balance.into())?; + + }: _(RawOrigin::Signed(delegator)) + + clear_public_proposals { + let p in 0 .. 100; + for i in 0 .. p { + add_proposal::(i)?; + } + }: _(RawOrigin::Root) + + note_preimage { + // Num of bytes in encoded proposal + let b in 0 .. 16_384; + + let caller = funded_account::("caller", b); + let encoded_proposal = vec![0; b as usize]; + }: _(RawOrigin::Signed(caller), encoded_proposal) + + note_imminent_preimage { + // Num of bytes in encoded proposal + let b in 0 .. 16_384; + // Length of dispatch queue + let d in 0 .. 100; + + let mut dispatch_queue = Vec::new(); + // d + 1 to include the one we are testing + for i in 0 .. d + 1 { + let encoded_proposal = vec![0; i as usize]; + let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); + let block_number = T::BlockNumber::zero(); + let referendum_index: ReferendumIndex = 0; + dispatch_queue.push((block_number, proposal_hash, referendum_index)) + } + >::put(dispatch_queue); + + let caller = funded_account::("caller", b); + let encoded_proposal = vec![0; d as usize]; + }: _(RawOrigin::Signed(caller), encoded_proposal) + + reap_preimage { + // Num of bytes in encoded proposal + let b in 0 .. 16_384; + // Length of dispatch queue + let d in 0 .. 100; + + let mut dispatch_queue = Vec::new(); + for i in 0 .. d { + let encoded_proposal = vec![0; i as usize]; + let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); + let block_number = T::BlockNumber::zero(); + let referendum_index: ReferendumIndex = 0; + dispatch_queue.push((block_number, proposal_hash, referendum_index)) + } + >::put(dispatch_queue); + + let caller = funded_account::("caller", d); + let encoded_proposal = vec![0; d as usize]; + Democracy::::note_preimage(RawOrigin::Signed(caller.clone()).into(), encoded_proposal.clone())?; + + // We need to set this otherwise we get `Early` error. + let block_number = T::VotingPeriod::get() + T::EnactmentPeriod::get() + T::BlockNumber::one(); + System::::set_block_number(block_number.into()); + + let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); + + }: _(RawOrigin::Signed(caller), proposal_hash) + + unlock { + let u in 1 .. MAX_USERS; + + let caller = funded_account::("caller", u); + let locked_until = T::BlockNumber::zero(); + Locks::::insert(&caller, locked_until); + + T::Currency::extend_lock( + DEMOCRACY_ID, + &caller, + Bounded::max_value(), + WithdrawReason::Transfer.into() + ); + + let other = caller.clone(); + + }: _(RawOrigin::Signed(caller), other) + + remove_vote { + let r in 1 .. MAX_REFERENDUMS; + + let caller = funded_account::("caller", 0); + let account_vote = account_vote::(); + + for i in 0 .. r { + let ref_idx = add_referendum::(i)?; + Democracy::::vote(RawOrigin::Signed(caller.clone()).into(), ref_idx, account_vote.clone())?; + } + + let referendum_index = r - 1; + + }: _(RawOrigin::Signed(caller), referendum_index) + + remove_other_vote { + let r in 1 .. MAX_REFERENDUMS; + + let other = funded_account::("other", r); + let account_vote = account_vote::(); + + for i in 0 .. r { + let ref_idx = add_referendum::(i)?; + Democracy::::vote(RawOrigin::Signed(other.clone()).into(), ref_idx, account_vote.clone())?; + } + + let referendum_index = r - 1; + ReferendumInfoOf::::insert( + referendum_index, + ReferendumInfo::Finished { end: T::BlockNumber::zero(), approved: true } + ); + let caller = funded_account::("caller", r); + + System::::set_block_number(T::EnactmentPeriod::get() * 10u32.into()); + + }: _(RawOrigin::Signed(caller), other, referendum_index) + + proxy_delegate { + let u in 1 .. MAX_USERS; + + let other: T::AccountId = account("other", u, SEED); + let proxy = open_activate_proxy::(u)?; + let conviction = Conviction::Locked1x; + let balance = 1u32; + + }: _(RawOrigin::Signed(proxy), other, conviction, balance.into()) + + proxy_undelegate { + let r in 1 .. MAX_REFERENDUMS; + + let other = funded_account::("other", 0); + let account_vote = account_vote::(); + + for i in 0 .. r { + let ref_idx = add_referendum::(i)?; + Democracy::::vote(RawOrigin::Signed(other.clone()).into(), ref_idx, account_vote.clone())?; + } + + let proxy = open_activate_proxy::(r)?; + let conviction = Conviction::Locked1x; + let balance = 1u32; + Democracy::::proxy_delegate(RawOrigin::Signed(proxy.clone()).into(), other, conviction, balance.into())?; + + }: _(RawOrigin::Signed(proxy)) + + proxy_remove_vote { + let u in 1 .. MAX_USERS; + + let referendum_index = add_referendum::(u)?; + let account_vote = account_vote::(); + let proxy = open_activate_proxy::(u)?; + + Democracy::::proxy_vote(RawOrigin::Signed(proxy.clone()).into(), referendum_index, account_vote)?; + + }: _(RawOrigin::Signed(proxy), referendum_index) +} diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index a4366c4ef2..7223b66a4e 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -190,6 +190,9 @@ pub use types::{ReferendumInfo, ReferendumStatus, ProxyState, Tally, UnvoteScope #[cfg(test)] mod tests; +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking; + const DEMOCRACY_ID: LockIdentifier = *b"democrac"; /// A proposal index. @@ -516,7 +519,8 @@ decl_module! { /// Emits `Proposed`. /// /// # - /// - `O(1)`. + /// - `O(P)` + /// - P is the number proposals in the `PublicProps` vec. /// - Two DB changes, one DB entry. /// # #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] @@ -546,7 +550,8 @@ decl_module! { /// - `proposal`: The index of the proposal to second. /// /// # - /// - `O(1)`. + /// - `O(S)`. + /// - S is the number of seconds a proposal already has. /// - One DB entry. /// # #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] @@ -568,7 +573,8 @@ decl_module! { /// - `vote`: The vote configuration. /// /// # - /// - `O(1)`. + /// - `O(R)`. + /// - R is the number of referendums the voter has voted on. /// - One DB change, one DB entry. /// # #[weight = SimpleDispatchInfo::FixedNormal(200_000)] @@ -610,7 +616,7 @@ decl_module! { /// -`ref_index`: The index of the referendum to cancel. /// /// # - /// - Depends on size of storage vec `VotersFor` for this referendum. + /// - `O(1)`. /// # #[weight = SimpleDispatchInfo::FixedOperational(500_000)] fn emergency_cancel(origin, ref_index: ReferendumIndex) { @@ -756,6 +762,7 @@ decl_module! { /// - One DB clear. /// - Performs a binary search on `existing_vetoers` which should not /// be very large. + /// - O(log v), v is number of `existing_vetoers` /// # #[weight = SimpleDispatchInfo::FixedNormal(200_000)] fn veto_external(origin, proposal_hash: T::Hash) { @@ -804,6 +811,7 @@ decl_module! { /// /// # /// - One DB change. + /// - O(d) where d is the items in the dispatch queue. /// # #[weight = SimpleDispatchInfo::FixedOperational(10_000)] fn cancel_queued(origin, which: ReferendumIndex) { @@ -993,7 +1001,7 @@ decl_module! { /// Emits `PreimageNoted`. /// /// # - /// - Dependent on the size of `encoded_proposal`. + /// - Dependent on the size of `encoded_proposal` and length of dispatch queue. /// # #[weight = SimpleDispatchInfo::FixedNormal(100_000)] fn note_imminent_preimage(origin, encoded_proposal: Vec) { diff --git a/frame/society/Cargo.toml b/frame/society/Cargo.toml index 5130536ffd..f2aaccaeb3 100644 --- a/frame/society/Cargo.toml +++ b/frame/society/Cargo.toml @@ -34,3 +34,7 @@ std = [ "frame-support/std", "frame-system/std", ] +runtime-benchmarks = [ + "sp-runtime/runtime-benchmarks", + "frame-system/runtime-benchmarks", +] diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index b4896b8dd9..49f48697f9 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -1145,6 +1145,12 @@ impl EnsureOrigin for EnsureFounder { (r, _) => Err(T::Origin::from(r)), }) } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> T::Origin { + let founder = Founder::::get().expect("society founder should exist"); + T::Origin::from(system::RawOrigin::Signed(founder)) + } } /// Pick an item at pseudo-random from the slice, given the `rng`. `None` iff the slice is empty. diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index d4da59617a..7ea72b3d7a 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -54,5 +54,4 @@ std = [ runtime-benchmarks = [ "rand_chacha", "frame-benchmarking", - "frame-system/runtime-benchmarks", ] diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index fc7fbb4835..0e904a78a4 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -14,7 +14,7 @@ serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } frame-metadata = { version = "11.0.0-alpha.5", default-features = false, path = "../metadata" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } -sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} +sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } sp-arithmetic = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/arithmetic" } diff --git a/frame/system/Cargo.toml b/frame/system/Cargo.toml index 92b7655566..7f2e38d176 100644 --- a/frame/system/Cargo.toml +++ b/frame/system/Cargo.toml @@ -36,7 +36,7 @@ std = [ "sp-runtime/std", "sp-version/std", ] -runtime-benchmarks = [] +runtime-benchmarks = ["sp-runtime/runtime-benchmarks"] [[bench]] name = "bench" diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 34adf69fa5..92948544ce 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -578,12 +578,17 @@ impl< r => Err(O::from(r)), }) } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + O::from(RawOrigin::Root) + } } pub struct EnsureSigned(sp_std::marker::PhantomData); impl< O: Into, O>> + From>, - AccountId, + AccountId: Default, > EnsureOrigin for EnsureSigned { type Success = AccountId; fn try_origin(o: O) -> Result { @@ -592,13 +597,18 @@ impl< r => Err(O::from(r)), }) } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + O::from(RawOrigin::Signed(Default::default())) + } } pub struct EnsureSignedBy(sp_std::marker::PhantomData<(Who, AccountId)>); impl< O: Into, O>> + From>, Who: Contains, - AccountId: PartialEq + Clone + Ord, + AccountId: PartialEq + Clone + Ord + Default, > EnsureOrigin for EnsureSignedBy { type Success = AccountId; fn try_origin(o: O) -> Result { @@ -607,6 +617,13 @@ impl< r => Err(O::from(r)), }) } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + let caller: AccountId = Default::default(); + // Who::add(&caller); + O::from(RawOrigin::Signed(caller)) + } } pub struct EnsureNone(sp_std::marker::PhantomData); @@ -621,6 +638,11 @@ impl< r => Err(O::from(r)), }) } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + O::from(RawOrigin::None) + } } pub struct EnsureNever(sp_std::marker::PhantomData); @@ -629,6 +651,11 @@ impl EnsureOrigin for EnsureNever { fn try_origin(o: O) -> Result { Err(o) } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + unimplemented!() + } } /// Ensure that the origin `o` represents a signed extrinsic (i.e. transaction). diff --git a/frame/vesting/Cargo.toml b/frame/vesting/Cargo.toml index c8d46855c5..c66d7da0e8 100644 --- a/frame/vesting/Cargo.toml +++ b/frame/vesting/Cargo.toml @@ -36,4 +36,4 @@ std = [ "frame-support/std", "frame-system/std", ] -runtime-benchmarks = ["frame-benchmarking", "frame-system/runtime-benchmarks"] +runtime-benchmarks = ["frame-benchmarking"] diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index 743748fc10..e44a778fdd 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -32,6 +32,7 @@ rand = "0.7.2" [features] bench = [] +runtime-benchmarks = [] default = ["std"] std = [ "sp-application-crypto/std", diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 51ea4b4a38..0ddb5c4dbf 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -157,6 +157,12 @@ pub trait EnsureOrigin { } /// Perform the origin check. fn try_origin(o: OuterOrigin) -> result::Result; + + /// Returns an outer origin capable of passing `try_origin` check. + /// + /// ** Should be used for benchmarking only!!! ** + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> OuterOrigin; } /// An error that indicates that a lookup failed. -- GitLab From f121937ac68c80e9fccf5cb9788cbb134f0270a6 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 26 Mar 2020 12:26:30 +0100 Subject: [PATCH 083/300] Improve sc-network's documentation for network protocols (#5364) * Improve sc-network's documentation for network protocols * Add note about protocol id * Apply suggestions from code review Co-Authored-By: Max Inden Co-authored-by: Max Inden --- client/network/src/lib.rs | 107 ++++++++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 22 deletions(-) diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index f29fb00a4f..a5107a0255 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -90,23 +90,49 @@ //! ## Substreams //! //! Once a connection has been established and uses multiplexing, substreams can be opened. When -//! a substream is open, the **multistream-select** protocol is used to negotiate which protocol to -//! use on that given substream. In practice, Substrate opens the following substreams: -//! -//! - We periodically open an ephemeral substream in order to ping the remote and check whether the -//! connection is still alive. Failure for the remote to reply leads to a disconnection. This uses -//! the libp2p ping protocol. -//! - We periodically open an ephemeral substream in order to ask information from the remote. This -//! is called [the `identify` protocol](https://github.com/libp2p/specs/tree/master/identify). -//! - We periodically open ephemeral substreams for Kademlia random walk queries. Each Kademlia -//! query is done in a new separate substream. This uses the -//! [standard libp2p Kademlia protocol](https://github.com/libp2p/specs/pull/108). -//! - We optionally keep a substream alive for all Substrate-based communications. The name of the -//! protocol negotiated is based on the *protocol ID* passed as part of the network configuration. -//! This protocol ID should be unique for each chain and prevents nodes from different chains from -//! connecting to each other. More information below. -//! -//! ## The Substrate substream +//! a substream is open, the **multistream-select** protocol is used to negotiate which protocol +//! to use on that given substream. +//! +//! Protocols that are specific to a certain chain have a `` in their name. This +//! "protocol ID" is defined in the chain specifications. For example, the protocol ID of Polkadot +//! is "dot". In the protocol names below, `` must be replaced with the corresponding +//! protocol ID. +//! +//! > **Note**: It is possible for the same connection to be used for multiple chains. For example, +//! > one can use both the `/dot/sync/2` and `/sub/sync/2` protocols on the same +//! > connection, provided that the remote supports them. +//! +//! Substrate uses the following standard libp2p protocols: +//! +//! - **`/ipfs/ping/1.0.0`**. We periodically open an ephemeral substream in order to ping the +//! remote and check whether the connection is still alive. Failure for the remote to reply leads +//! to a disconnection. +//! - **[`/ipfs/id/1.0.0`](https://github.com/libp2p/specs/tree/master/identify)**. We +//! periodically open an ephemeral substream in order to ask information from the remote. +//! - **[`/ipfs/kad/1.0.0`](https://github.com/libp2p/specs/pull/108)**. We periodically open +//! ephemeral substreams for Kademlia random walk queries. Each Kademlia query is done in a +//! separate substream. +//! +//! Additionally, Substrate uses the following non-libp2p-standard protocols: +//! +//! - **`/substrate//`** (where `` must be replaced with the +//! protocol ID of the targeted chain, and `` is a number between 2 and 6). For each +//! connection we optionally keep an additional substream for all Substrate-based communications alive. +//! This protocol is considered legacy, and is progressively being replaced with alternatives. +//! This is designated as "The legacy Substrate substream" in this documentation. See below for +//! more details. +//! - **`//sync/2`** is a request-response protocol (see below) that lets one perform +//! requests for information about blocks. Each request is the encoding of a `BlockRequest` and +//! each response is the encoding of a `BlockResponse`, as defined in the `api.v1.proto` file in +//! this source tree. +//! - **`//light/2`** is a request-response protocol (see below) that lets one perform +//! light-client-related requests for information about the state. Each request is the encoding of +//! a `light::Request` and each response is the encoding of a `light::Response`, as defined in the +//! `light.v1.proto` file in this source tree. +//! - Notifications protocols that are registered using the `register_notifications_protocol` +//! method. For example: `/paritytech/grandpa/1`. See below for more information. +//! +//! ## The legacy Substrate substream //! //! Substrate uses a component named the **peerset manager (PSM)**. Through the discovery //! mechanism, the PSM is aware of the nodes that are part of the network and decides which nodes @@ -119,8 +145,8 @@ //! Note that at the moment there is no mechanism in place to solve the issues that arise where the //! two sides of a connection open the unique substream simultaneously. In order to not run into //! issues, only the dialer of a connection is allowed to open the unique substream. When the -//! substream is closed, the entire connection is closed as well. This is a bug, and should be -//! fixed by improving the protocol. +//! substream is closed, the entire connection is closed as well. This is a bug that will be +//! resolved by deprecating the protocol entirely. //! //! Within the unique Substrate substream, messages encoded using //! [*parity-scale-codec*](https://github.com/paritytech/parity-scale-codec) are exchanged. @@ -137,9 +163,46 @@ //! substream open with is chosen, and the information is requested from it. //! - Gossiping. Used for example by grandpa. //! -//! It is intended that in the future each of these components gets more isolated, so that they -//! are free to open and close their own substreams, and so that syncing and light client requests -//! are able to communicate with nodes outside of the range of the PSM. +//! ## Request-response protocols +//! +//! A so-called request-response protocol is defined as follow: +//! +//! - When a substream is opened, the opening side sends a message whose content is +//! protocol-specific. The message must be prefixed with an +//! [LEB128-encoded number](https://en.wikipedia.org/wiki/LEB128) indicating its length. After the +//! message has been sent, the writing side is closed. +//! - The remote sends back the response prefixed with a LEB128-encoded length, and closes its +//! side as well. +//! +//! Each request is performed in a new separate substream. +//! +//! ## Notifications protocols +//! +//! A so-called notifications protocol is defined as follow: +//! +//! - When a substream is opened, the opening side sends a handshake message whose content is +//! protocol-specific. The handshake message must be prefixed with an +//! [LEB128-encoded number](https://en.wikipedia.org/wiki/LEB128) indicating its length. The +//! handshake message can be of length 0, in which case the sender has to send a single `0`. +//! - The receiver then either immediately closes the substream, or answers with its own +//! LEB128-prefixed protocol-specific handshake response. The message can be of length 0, in which +//! case a single `0` has to be sent back. The receiver is then encouraged to close its sending +//! side. +//! - Once the handshake has completed, the notifications protocol is unidirectional. Only the +//! node which initiated the substream can push notifications. If the remote wants to send +//! notifications as well, it has to open its own undirectional substream. +//! - Each notification must be prefixed with an LEB128-encoded length. The encoding of the +//! messages is specific to each protocol. +//! +//! The API of `sc-network` allows one to register user-defined notification protocols. +//! `sc-network` automatically tries to open a substream towards each node for which the legacy +//! Substream substream is open. The handshake is then performed automatically. +//! +//! For example, the `sc-finality-grandpa` crate registers the `/paritytech/grandpa/1` +//! notifications protocol. +//! +//! At the moment, for backwards-compatibility, notification protocols are tied to the legacy +//! Substrate substream. In the future, though, it will no longer be the case. //! //! # Usage //! -- GitLab From f0c36f56cf4f23a6532b0bfdd5ae820b3a75acbc Mon Sep 17 00:00:00 2001 From: gabriel klawitter Date: Thu, 26 Mar 2020 16:57:55 +0530 Subject: [PATCH 084/300] ci: check_polkadot: accept linking to polkadot pr (#5410) --- .maintain/gitlab/check_polkadot.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.maintain/gitlab/check_polkadot.sh b/.maintain/gitlab/check_polkadot.sh index 6087d86cde..1d5bba98af 100755 --- a/.maintain/gitlab/check_polkadot.sh +++ b/.maintain/gitlab/check_polkadot.sh @@ -50,7 +50,10 @@ then boldprint "this is pull request no ${CI_COMMIT_REF_NAME}" # get the last reference to a pr in polkadot comppr="$(curl -H "${github_header}" -s ${github_api_substrate_pull_url}/${CI_COMMIT_REF_NAME} \ - | sed -n -r 's;^[[:space:]]+"body":[[:space:]]+".*polkadot companion: paritytech/polkadot#([0-9]+).*"[^"]+$;\1;p;$!d')" + | sed -n -r \ + -e 's;^[[:space:]]+"body":[[:space:]]+".*polkadot companion: paritytech/polkadot#([0-9]+).*"[^"]+$;\1;p' \ + -e 's;^[[:space:]]+"body":[[:space:]]+".*polkadot companion: https://github.com/paritytech/polkadot/pull/([0-9]+).*"[^"]+$;\1;p' \ + | tail -n 1)" if [ "${comppr}" ] then boldprint "companion pr specified: #${comppr}" -- GitLab From 93bfd26db6782416ed22eab351a760892063a855 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 26 Mar 2020 13:49:45 +0100 Subject: [PATCH 085/300] client/finality-grandpa/src/until_imported: Refactor schedule_wait (#5386) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * client/finality-grandpa/src/until_imported: Refactor schedule_wait Previously `BlockUntilImported::schedule_wait` took two closures, one to report ready items and one to report items to await. None of the implementors of `BlockUntilImported` call both closures. From a symantic perspective it would as well not make sense to both await something and state that it is ready. Instead with this commit `BlockUntilImported::schedule_wait` simply returns whether the given item needs waiting or is ready to be passed on. This reduces complexity by: - Removing side effects through the two closures. - Reducing borrowing given that `UntilImported` `ready` and `pending` don't need to be borrowed from within the two closures. - Removes the need for trait bounds for the two closures. * client/finality-grandpa/src/until_imported: Fix comments Co-Authored-By: André Silva Co-authored-by: André Silva --- client/finality-grandpa/src/until_imported.rs | 122 ++++++++---------- 1 file changed, 55 insertions(+), 67 deletions(-) diff --git a/client/finality-grandpa/src/until_imported.rs b/client/finality-grandpa/src/until_imported.rs index c3804e1272..223078ec92 100644 --- a/client/finality-grandpa/src/until_imported.rs +++ b/client/finality-grandpa/src/until_imported.rs @@ -47,30 +47,36 @@ use sp_finality_grandpa::AuthorityId; const LOG_PENDING_INTERVAL: Duration = Duration::from_secs(15); -// something which will block until imported. +/// Something that needs to be withheld until specific blocks are available. +/// +/// For example a GRANDPA commit message which is not of any use without the corresponding block +/// that it commits on. pub(crate) trait BlockUntilImported: Sized { - // the type that is blocked on. + /// The type that is blocked on. type Blocked; - /// new incoming item. For all internal items, - /// check if they require to be waited for. - /// if so, call the `Wait` closure. - /// if they are ready, call the `Ready` closure. - fn schedule_wait( + /// Check if a new incoming item needs awaiting until a block(s) is imported. + fn needs_waiting>( input: Self::Blocked, status_check: &S, - wait: Wait, - ready: Ready, - ) -> Result<(), Error> where - S: BlockStatusT, - Wait: FnMut(Block::Hash, NumberFor, Self), - Ready: FnMut(Self::Blocked); + ) -> Result, Error>; /// called when the wait has completed. The canonical number is passed through /// for further checks. fn wait_completed(self, canon_number: NumberFor) -> Option; } +/// Describes whether a given [`BlockUntilImported`] (a) should be discarded, (b) is waiting for +/// specific blocks to be imported or (c) is ready to be used. +/// +/// A reason for discarding a [`BlockUntilImported`] would be if a referenced block is perceived +/// under a different number than specified in the message. +pub(crate) enum DiscardWaitOrReady { + Discard, + Wait(Vec<(Block::Hash, NumberFor, W)>), + Ready(R), +} + /// Buffering imported messages until blocks with given hashes are imported. #[pin_project::pin_project] pub(crate) struct UntilImported> { @@ -149,18 +155,19 @@ impl Stream for UntilImported { // new input: schedule wait of any parts which require // blocks to be known. - let ready = &mut this.ready; - let pending = &mut this.pending; - M::schedule_wait( - input, - this.status_check, - |target_hash, target_number, wait| pending - .entry(target_hash) - .or_insert_with(|| (target_number, Instant::now(), Vec::new())) - .2 - .push(wait), - |ready_item| ready.push_back(ready_item), - )?; + match M::needs_waiting(input, this.status_check)? { + DiscardWaitOrReady::Discard => {}, + DiscardWaitOrReady::Wait(items) => { + for (target_hash, target_number, wait) in items { + this.pending + .entry(target_hash) + .or_insert_with(|| (target_number, Instant::now(), Vec::new())) + .2 + .push(wait) + } + }, + DiscardWaitOrReady::Ready(item) => this.ready.push_back(item), + } } Poll::Pending => break, } @@ -255,29 +262,22 @@ fn warn_authority_wrong_target(hash: H, id: AuthorityId) impl BlockUntilImported for SignedMessage { type Blocked = Self; - fn schedule_wait( + fn needs_waiting>( msg: Self::Blocked, status_check: &BlockStatus, - mut wait: Wait, - mut ready: Ready, - ) -> Result<(), Error> where - BlockStatus: BlockStatusT, - Wait: FnMut(Block::Hash, NumberFor, Self), - Ready: FnMut(Self::Blocked), - { + ) -> Result, Error> { let (&target_hash, target_number) = msg.target(); if let Some(number) = status_check.block_number(target_hash)? { if number != target_number { warn_authority_wrong_target(target_hash, msg.id); + return Ok(DiscardWaitOrReady::Discard); } else { - ready(msg); + return Ok(DiscardWaitOrReady::Ready(msg)); } - } else { - wait(target_hash, target_number, msg) } - Ok(()) + return Ok(DiscardWaitOrReady::Wait(vec![(target_hash, target_number, msg)])) } fn wait_completed(self, canon_number: NumberFor) -> Option { @@ -321,16 +321,10 @@ impl Unpin for BlockGlobalMessage {} impl BlockUntilImported for BlockGlobalMessage { type Blocked = CommunicationIn; - fn schedule_wait( + fn needs_waiting>( input: Self::Blocked, status_check: &BlockStatus, - mut wait: Wait, - mut ready: Ready, - ) -> Result<(), Error> where - BlockStatus: BlockStatusT, - Wait: FnMut(Block::Hash, NumberFor, Self), - Ready: FnMut(Self::Blocked), - { + ) -> Result, Error> { use std::collections::hash_map::Entry; enum KnownOrUnknown { @@ -348,7 +342,6 @@ impl BlockUntilImported for BlockGlobalMessage { } let mut checked_hashes: HashMap<_, KnownOrUnknown>> = HashMap::new(); - let mut unknown_count = 0; { // returns false when should early exit. @@ -363,7 +356,6 @@ impl BlockUntilImported for BlockGlobalMessage { } else { entry.insert(KnownOrUnknown::Unknown(perceived_number)); - unknown_count += 1; perceived_number } } @@ -388,7 +380,7 @@ impl BlockUntilImported for BlockGlobalMessage { for (target_number, target_hash) in precommit_targets { if !query_known(target_hash, target_number)? { - return Ok(()) + return Ok(DiscardWaitOrReady::Discard); } } }, @@ -406,38 +398,34 @@ impl BlockUntilImported for BlockGlobalMessage { for (target_number, target_hash) in targets { if !query_known(target_hash, target_number)? { - return Ok(()) + return Ok(DiscardWaitOrReady::Discard); } } }, }; } - // none of the hashes in the global message were unknown. - // we can just return the message directly. - if unknown_count == 0 { - ready(input); - return Ok(()) + let unknown_hashes = checked_hashes.into_iter().filter_map(|(hash, num)| match num { + KnownOrUnknown::Unknown(number) => Some((hash, number)), + KnownOrUnknown::Known(_) => None, + }).collect::>(); + + if unknown_hashes.is_empty() { + // none of the hashes in the global message were unknown. + // we can just return the message directly. + return Ok(DiscardWaitOrReady::Ready(input)); } let locked_global = Arc::new(Mutex::new(Some(input))); + let items_to_await = unknown_hashes.into_iter().map(|(hash, target_number)| { + (hash, target_number, BlockGlobalMessage { inner: locked_global.clone(), target_number }) + }).collect(); + // schedule waits for all unknown messages. // when the last one of these has `wait_completed` called on it, // the global message will be returned. - // - // in the future, we may want to issue sync requests to the network - // if this is taking a long time. - for (hash, is_known) in checked_hashes { - if let KnownOrUnknown::Unknown(target_number) = is_known { - wait(hash, target_number, BlockGlobalMessage { - inner: locked_global.clone(), - target_number, - }) - } - } - - Ok(()) + Ok(DiscardWaitOrReady::Wait(items_to_await)) } fn wait_completed(self, canon_number: NumberFor) -> Option { -- GitLab From d1238423a3093eb64df90c0eebdbf504c8df56dd Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 26 Mar 2020 15:37:40 +0100 Subject: [PATCH 086/300] =?UTF-8?q?Offchain=20Phragm=C3=A9n=20BREAKING.=20?= =?UTF-8?q?(#4517)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial skeleton for offchain phragmen * Basic compact encoding decoding for results * add compact files * Bring back Self::ensure_storage_upgraded(); * Make staking use compact stuff. * First seemingly working version of reduce, full of todos * Everything phragmen related works again. * Signing made easier, still issues. * Signing from offchain compile fine 😎 * make compact work with staked asssignment * Evaluation basics are in place. * Move reduce into crate. Document stuff * move reduce into no_std * Add files * Remove other std deps. Runtime compiles * Seemingly it is al stable; cycle implemented but not integrated. * Add fuzzing code. * Cleanup reduce a bit more. * a metric ton of tests for staking; wip 🔨 * Implement a lot more of the tests. * wip getting the unsigned stuff to work * A bit gleanup for unsigned debug * Clean and finalize compact code. * Document reduce. * Still problems with signing * We officaly duct taped the transaction submission stuff. 🤓 * Deadlock with keys again * Runtime builds * Unsigned test works 🙌 * Some cleanups * Make all the tests compile and stuff * Minor cleanup * fix more merge stuff * Most tests work again. * a very nasty bug in reduce * Fix all integrations * Fix more todos * Revamp everything and everything * Remove bogus test * Some review grumbles. * Some fixes * Fix doc test * loop for submission * Fix cli, keyring etc. * some cleanup * Fix staking tests again * fix per-things; bring patches from benchmarking * better score prediction * Add fuzzer, more patches. * Some fixes * More docs * Remove unused generics * Remove max-nominator footgun * Better fuzzer * Disable it ❌ * Bump. * Another round of self-review * Refactor a lot * More major fixes in perThing * Add new fuzz file * Update lock * fix fuzzing code. * Fix nominator retain test * Add slashing check * Update frame/staking/src/tests.rs Co-Authored-By: Joshy Orndorff * Some formatting nits * Review comments. * Fix cargo file * Almost all tests work again * Update frame/staking/src/tests.rs Co-Authored-By: thiolliere * Fix review comments * More review stuff * Some nits * Fix new staking / session / babe relation * Update primitives/phragmen/src/lib.rs Co-Authored-By: thiolliere * Update primitives/phragmen/src/lib.rs Co-Authored-By: thiolliere * Update primitives/phragmen/compact/src/lib.rs Co-Authored-By: thiolliere * Some doc updates to slashing * Fix derive * Remove imports * Remove unimplemented tests * nits * Remove dbg * Better fuzzing params * Remove unused pref map * Deferred Slashing/Offence for offchain Phragmen (#5151) * Some boilerplate * Add test * One more test * Review comments * Fix build * review comments * fix more * fix build * Some cleanups and self-reviews * More minor self reviews * Final nits * Some merge fixes. * opt comment * Fix build * Fix build again. * Update frame/staking/fuzz/fuzz_targets/submit_solution.rs Co-Authored-By: Gavin Wood * Update frame/staking/src/slashing.rs Co-Authored-By: Gavin Wood * Update frame/staking/src/offchain_election.rs Co-Authored-By: Gavin Wood * Fix review comments * fix test * === 🔑 Revamp without staking key. * final round of changes. * Fix cargo-deny * Update frame/staking/src/lib.rs Co-Authored-By: Gavin Wood Co-authored-by: Joshy Orndorff Co-authored-by: thiolliere Co-authored-by: Gavin Wood --- Cargo.lock | 240 +- Cargo.toml | 1 + bin/node/cli/Cargo.toml | 1 + bin/node/cli/src/chain_spec.rs | 16 +- bin/node/cli/src/factory_impl.rs | 3 +- bin/node/cli/src/service.rs | 3 +- bin/node/executor/tests/submit_transaction.rs | 4 +- bin/node/runtime/src/lib.rs | 106 +- bin/node/testing/src/keyring.rs | 1 + bin/utils/subkey/src/main.rs | 2 + frame/authority-discovery/src/lib.rs | 1 + frame/babe/Cargo.toml | 5 - frame/babe/src/lib.rs | 41 +- frame/babe/src/mock.rs | 61 +- frame/babe/src/tests.rs | 44 +- frame/elections-phragmen/src/lib.rs | 16 +- frame/im-online/src/mock.rs | 1 + frame/offences/src/lib.rs | 73 +- frame/offences/src/mock.rs | 23 +- frame/offences/src/tests.rs | 58 +- frame/session/src/lib.rs | 44 +- frame/session/src/mock.rs | 1 + frame/staking/Cargo.toml | 20 +- frame/staking/fuzz/.gitignore | 4 + frame/staking/fuzz/Cargo.lock | 2189 +++++++++++++++++ frame/staking/fuzz/Cargo.toml | 35 + frame/staking/fuzz/fuzz_targets/mock.rs | 182 ++ .../fuzz/fuzz_targets/submit_solution.rs | 130 + frame/staking/src/benchmarking.rs | 6 +- frame/staking/src/lib.rs | 1170 +++++++-- frame/staking/src/mock.rs | 546 +++- frame/staking/src/offchain_election.rs | 219 ++ frame/staking/src/slashing.rs | 16 +- frame/staking/src/testing_utils.rs | 340 +++ frame/staking/src/tests.rs | 1206 ++++++++- frame/support/src/traits.rs | 33 +- frame/system/src/offchain.rs | 16 +- frame/transaction-payment/src/lib.rs | 10 +- primitives/arithmetic/fuzzer/Cargo.lock | 401 +++ primitives/arithmetic/fuzzer/Cargo.toml | 4 + .../fuzzer/src/per_thing_rational.rs | 123 + primitives/arithmetic/src/lib.rs | 16 +- primitives/arithmetic/src/per_things.rs | 405 ++- primitives/consensus/vrf/src/schnorrkel.rs | 4 +- primitives/core/src/crypto.rs | 2 + primitives/phragmen/Cargo.toml | 10 +- primitives/phragmen/benches/phragmen.rs | 1 + primitives/phragmen/compact/Cargo.toml | 18 + primitives/phragmen/compact/src/assignment.rs | 210 ++ primitives/phragmen/compact/src/lib.rs | 219 ++ primitives/phragmen/compact/src/staked.rs | 208 ++ primitives/phragmen/fuzzer/.gitignore | 2 + primitives/phragmen/fuzzer/Cargo.lock | 1602 ++++++++++++ primitives/phragmen/fuzzer/Cargo.toml | 16 + primitives/phragmen/fuzzer/src/reduce.rs | 145 ++ primitives/phragmen/src/helpers.rs | 94 + primitives/phragmen/src/lib.rs | 385 ++- primitives/phragmen/src/mock.rs | 33 +- primitives/phragmen/src/node.rs | 287 +++ primitives/phragmen/src/reduce.rs | 1076 ++++++++ primitives/phragmen/src/tests.rs | 619 ++++- primitives/runtime/src/lib.rs | 5 +- primitives/runtime/src/traits.rs | 2 +- primitives/staking/src/offence.rs | 15 +- 64 files changed, 11915 insertions(+), 854 deletions(-) create mode 100644 frame/staking/fuzz/.gitignore create mode 100644 frame/staking/fuzz/Cargo.lock create mode 100644 frame/staking/fuzz/Cargo.toml create mode 100644 frame/staking/fuzz/fuzz_targets/mock.rs create mode 100644 frame/staking/fuzz/fuzz_targets/submit_solution.rs create mode 100644 frame/staking/src/offchain_election.rs create mode 100644 frame/staking/src/testing_utils.rs create mode 100644 primitives/arithmetic/fuzzer/Cargo.lock create mode 100644 primitives/arithmetic/fuzzer/src/per_thing_rational.rs create mode 100644 primitives/phragmen/compact/Cargo.toml create mode 100644 primitives/phragmen/compact/src/assignment.rs create mode 100644 primitives/phragmen/compact/src/lib.rs create mode 100644 primitives/phragmen/compact/src/staked.rs create mode 100644 primitives/phragmen/fuzzer/.gitignore create mode 100644 primitives/phragmen/fuzzer/Cargo.lock create mode 100644 primitives/phragmen/fuzzer/Cargo.toml create mode 100644 primitives/phragmen/fuzzer/src/reduce.rs create mode 100644 primitives/phragmen/src/helpers.rs create mode 100644 primitives/phragmen/src/node.rs create mode 100644 primitives/phragmen/src/reduce.rs diff --git a/Cargo.lock b/Cargo.lock index 2e1cd47e0a..36846702a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,12 +70,11 @@ dependencies = [ [[package]] name = "alga" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658f9468113d34781f6ca9d014d174c74b73de870f1e0e3ad32079bbab253b19" +checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2" dependencies = [ "approx", - "libm", "num-complex", "num-traits", ] @@ -100,9 +99,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" +checksum = "013a6e0a2cbe3d20f9c60b65458f7a7f7a5e636c5d0f45a5a6aee5d4b1f01785" [[package]] name = "app_dirs" @@ -133,9 +132,9 @@ checksum = "75153c95fdedd7db9732dfbfc3702324a1627eec91ba56e37cd0ac78314ab2ed" [[package]] name = "arc-swap" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" +checksum = "d663a8e9a99154b5fb793032533f6328da35e23aac63d5c152279aa8ba356825" [[package]] name = "arrayref" @@ -179,9 +178,9 @@ dependencies = [ [[package]] name = "assert_cmd" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6283bac8dd7226470d491bc4737816fea4ca1fba7a2847f2e9097fd6bfb4624c" +checksum = "35ad62275a8bda1c2c9a9303aea121eb04204272d3be0735d5dc1f49eb9ff9a9" dependencies = [ "doc-comment", "escargot", @@ -269,9 +268,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.45" +version = "0.3.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad235dabf00f36301792cfe82499880ba54c6486be094d1047b02bacb67c14e8" +checksum = "b1e692897359247cc6bb902933361652380af0f1b7651ae5c5013407f30e109e" dependencies = [ "backtrace-sys", "cfg-if", @@ -281,9 +280,9 @@ dependencies = [ [[package]] name = "backtrace-sys" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca797db0057bae1a7aa2eef3283a874695455cecf08a43bfb8507ee0ebc1ed69" +checksum = "7de8aba10a69c8e8d7622c5710229485ec32e9d55fdad160ea559c086fdcd118" dependencies = [ "cc", "libc", @@ -457,9 +456,9 @@ checksum = "b170cd256a3f9fa6b9edae3e44a7dfdfc77e8124dbc3e2612d75f9c3e2396dae" [[package]] name = "bstr" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502ae1441a0a5adb8fbd38a5955a6416b9493e92b465de5e4a9bde6a539c2c48" +checksum = "2889e6d50f394968c8bf4240dc3f2a7eb4680844d27308f798229ac9d4725f41" dependencies = [ "lazy_static", "memchr", @@ -1109,9 +1108,9 @@ dependencies = [ [[package]] name = "doc-comment" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "807e5847c39ad6a11eac66de492ed1406f76a260eb8656e8740cad9eabc69c27" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "ed25519-dalek" @@ -1411,9 +1410,9 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" +checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" dependencies = [ "cfg-if", "crc32fast", @@ -1917,9 +1916,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "globset" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" +checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120" dependencies = [ "aho-corasick", "bstr", @@ -1972,16 +1971,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5c295d1c0c68e4e42003d75f908f5e16a1edd1cbe0b0d02e4dc2006a384f47" +checksum = "7938e6aa2a31df4e21f224dc84704bd31c089a6d1355c535b03667371cccc843" dependencies = [ "bytes 0.5.4", "fnv", "futures-core", "futures-sink", "futures-util", - "http 0.2.0", + "http 0.2.1", "indexmap", "log 0.4.8", "slab", @@ -2102,9 +2101,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" +checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" dependencies = [ "bytes 0.5.4", "fnv", @@ -2130,7 +2129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" dependencies = [ "bytes 0.5.4", - "http 0.2.0", + "http 0.2.1", ] [[package]] @@ -2199,16 +2198,16 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7b15203263d1faa615f9337d79c1d37959439dc46c2b4faab33286fadc2a1c5" +checksum = "ed6081100e960d9d74734659ffc9cc91daf1c0fc7aceb8eaa94ee1a3f5046f2e" dependencies = [ "bytes 0.5.4", "futures-channel", "futures-core", "futures-util", - "h2 0.2.2", - "http 0.2.0", + "h2 0.2.3", + "http 0.2.1", "http-body 0.3.1", "httparse", "itoa", @@ -2230,7 +2229,7 @@ dependencies = [ "bytes 0.5.4", "ct-logs", "futures-util", - "hyper 0.13.3", + "hyper 0.13.4", "log 0.4.8", "rustls 0.17.0", "rustls-native-certs", @@ -2353,9 +2352,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a859057dc563d1388c1e816f98a1892629075fc046ed06e845b883bb8b2916fb" +checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" [[package]] name = "itertools" @@ -2383,9 +2382,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cb931d43e71f560c81badb0191596562bafad2be06a3f9025b845c847c60df5" +checksum = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055" dependencies = [ "wasm-bindgen", ] @@ -2620,9 +2619,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" [[package]] name = "libc" -version = "0.2.67" +version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" +checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" [[package]] name = "libloading" @@ -2636,9 +2635,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.1.4" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" +checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" @@ -3212,11 +3211,11 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" +checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" dependencies = [ - "rustc_version", + "autocfg 1.0.0", ] [[package]] @@ -3439,6 +3438,7 @@ dependencies = [ "pallet-contracts", "pallet-im-online", "pallet-indices", + "pallet-staking", "pallet-timestamp", "pallet-transaction-payment", "parity-scale-codec", @@ -3834,9 +3834,9 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4dc79f9e6c81bef96148c8f6b8e72ad4541caa4a24373e900a36da07de03a3" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" dependencies = [ "autocfg 1.0.0", "num-bigint", @@ -3851,6 +3851,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" dependencies = [ "autocfg 1.0.0", + "libm", ] [[package]] @@ -4035,12 +4036,9 @@ version = "2.0.0-alpha.5" dependencies = [ "frame-support", "frame-system", - "hex-literal", - "lazy_static", "pallet-session", "pallet-timestamp", "parity-scale-codec", - "parking_lot 0.10.0", "serde", "sp-consensus-babe", "sp-consensus-vrf", @@ -4051,8 +4049,6 @@ dependencies = [ "sp-staking", "sp-std", "sp-timestamp", - "sp-version", - "substrate-test-runtime", ] [[package]] @@ -4512,25 +4508,30 @@ dependencies = [ name = "pallet-staking" version = "2.0.0-alpha.5" dependencies = [ + "env_logger 0.7.1", "frame-benchmarking", "frame-support", "frame-system", "hex", "pallet-authorship", "pallet-balances", + "pallet-indices", "pallet-session", "pallet-staking-reward-curve", "pallet-timestamp", "parity-scale-codec", + "parking_lot 0.10.0", + "rand 0.7.3", "rand_chacha 0.2.2", "serde", + "sp-application-crypto", "sp-core", "sp-io", - "sp-keyring", "sp-phragmen", "sp-runtime", "sp-staking", "sp-std", + "static_assertions", "substrate-test-utils", ] @@ -4845,9 +4846,9 @@ dependencies = [ [[package]] name = "paste" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e1afe738d71b1ebab5f1207c055054015427dbfc7bbe9ee1266894156ec046" +checksum = "8292c1e1e81ddb552c4c90c36af201a0ce7e34995f55f0480f01052f242811c9" dependencies = [ "paste-impl", "proc-macro-hack", @@ -4855,9 +4856,9 @@ dependencies = [ [[package]] name = "paste-impl" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d4dc4a7f6f743211c5aab239640a65091535d97d43d92a52bca435a640892bb" +checksum = "5e9c43f2645f06ee452544ad032886a75f3d1797b9487dcadcae9100ba58a51c" dependencies = [ "proc-macro-hack", "proc-macro2", @@ -5033,9 +5034,9 @@ dependencies = [ [[package]] name = "proc-macro-error" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7959c6467d962050d639361f7703b2051c43036d03493c36f01d440fdd3138a" +checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7" dependencies = [ "proc-macro-error-attr", "proc-macro2", @@ -5046,9 +5047,9 @@ dependencies = [ [[package]] name = "proc-macro-error-attr" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4002d9f55991d5e019fb940a90e1a95eb80c24e77cb2462dd4dc869604d543a" +checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de" dependencies = [ "proc-macro2", "quote", @@ -5059,20 +5060,15 @@ dependencies = [ [[package]] name = "proc-macro-hack" -version = "0.5.11" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "fcfdefadc3d57ca21cf17990a28ef4c0f7c61383a28cb7604cf4a18e6ede1420" [[package]] name = "proc-macro-nested" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" +checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" [[package]] name = "proc-macro2" @@ -5150,9 +5146,9 @@ dependencies = [ [[package]] name = "protobuf" -version = "2.10.2" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a5325d019a4d837d3abde0a836920f959e33d350f77b5f1e289e061e774942" +checksum = "fc1b4a8efc42cf150049e8a490f618c7c60e82332405065f202a7e33aa5a1f06" [[package]] name = "pwasm-utils" @@ -5466,9 +5462,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.3.4" +version = "1.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" +checksum = "7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3" dependencies = [ "aho-corasick", "memchr", @@ -5487,9 +5483,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.16" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1132f845907680735a84409c3bebc64d1364a5683ffbce899550cd09d5eaefc1" +checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" [[package]] name = "region" @@ -5529,9 +5525,9 @@ dependencies = [ [[package]] name = "rlp" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a44d5ae8afcb238af8b75640907edc6c931efcfab2c854e81ed35fa080f84cd" +checksum = "4a7d3f9bed94764eac15b8f14af59fac420c236adaff743b7bcc88e265cb4345" dependencies = [ "rustc-hex", ] @@ -5657,9 +5653,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" +checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76" [[package]] name = "safe-mix" @@ -6412,7 +6408,7 @@ dependencies = [ "fnv", "futures 0.3.4", "futures-timer 3.0.2", - "hyper 0.13.3", + "hyper 0.13.4", "hyper-rustls", "log 0.4.8", "num_cpus", @@ -6705,9 +6701,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507a9e6e8ffe0a4e0ebb9a10293e62fdf7657c06f1b8bb07a8fcf697d2abf295" +checksum = "039c25b130bd8c1321ee2d7de7fde2659fa9c2744e4bb29711cfc852ea53cd19" dependencies = [ "lazy_static", "winapi 0.3.8", @@ -7031,7 +7027,7 @@ dependencies = [ "bytes 0.5.4", "flate2", "futures 0.3.4", - "http 0.2.0", + "http 0.2.1", "httparse", "log 0.4.8", "rand 0.7.3", @@ -7405,14 +7401,26 @@ dependencies = [ name = "sp-phragmen" version = "2.0.0-alpha.5" dependencies = [ + "parity-scale-codec", "rand 0.7.3", "serde", - "sp-io", + "sp-phragmen", + "sp-phragmen-compact", "sp-runtime", "sp-std", "substrate-test-utils", ] +[[package]] +name = "sp-phragmen-compact" +version = "2.0.0-dev" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "sp-rpc" version = "2.0.0-alpha.5" @@ -7722,9 +7730,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe43617218c0805c6eb37160119dc3c548110a67786da7218d1c6555212f073" +checksum = "c8faa2719539bbe9d77869bfb15d4ee769f99525e707931452c97b693b3f159d" dependencies = [ "clap", "lazy_static", @@ -7733,9 +7741,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e79c80e0f4efd86ca960218d4e056249be189ff1c42824dcd9a7f51a56f0bd" +checksum = "3f88b8e18c69496aad6f9ddf4630dd7d585bcaf765786cb415b9aec2fe5a0430" dependencies = [ "heck", "proc-macro-error", @@ -7881,7 +7889,7 @@ dependencies = [ "async-std", "derive_more", "futures-util", - "hyper 0.13.3", + "hyper 0.13.4", "log 0.4.8", "prometheus", "tokio 0.2.13", @@ -8086,9 +8094,9 @@ checksum = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" [[package]] name = "syn" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" +checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" dependencies = [ "proc-macro2", "quote", @@ -8198,18 +8206,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee14bf8e6767ab4c687c9e8bc003879e042a96fd67a3ba5934eadb6536bef4db" +checksum = "e3711fd1c4e75b3eff12ba5c40dba762b6b65c5476e8174c1a664772060c49bf" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4" +checksum = "ae2b85ba4c9aa32dd3343bd80eb8d22e9b54b7688c17ea3907f236885353b233" dependencies = [ "proc-macro2", "quote", @@ -8247,9 +8255,9 @@ dependencies = [ [[package]] name = "tiny-bip39" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6848cd8f566953ce1e8faeba12ee23cbdbb0437754792cd857d44628b5685e3" +checksum = "e255ec4f7d4aaccbede17dffcfb2e71434d17f5c921d5a06823b8e58a2bcd468" dependencies = [ "failure", "hmac", @@ -8897,9 +8905,9 @@ dependencies = [ [[package]] name = "wabt-sys" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af5d153dc96aad7dc13ab90835b892c69867948112d95299e522d370c4e13a08" +checksum = "23d7043ebb3e5d96fad7a8d3ca22ee9880748ff8c3e18092cfb2a49d3b8f9084" dependencies = [ "cc", "cmake", @@ -8946,9 +8954,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" -version = "0.2.59" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3557c397ab5a8e347d434782bcd31fc1483d927a6826804cec05cc792ee2519d" +checksum = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -8956,9 +8964,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.59" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0da9c9a19850d3af6df1cb9574970b566d617ecfaf36eb0b706b6f3ef9bd2f8" +checksum = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd" dependencies = [ "bumpalo", "lazy_static", @@ -8971,9 +8979,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "457414a91863c0ec00090dba537f88ab955d93ca6555862c29b6d860990b8a8a" +checksum = "7add542ea1ac7fdaa9dc25e031a6af33b7d63376292bd24140c637d00d1c312a" dependencies = [ "cfg-if", "js-sys", @@ -8983,9 +8991,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.59" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f6fde1d36e75a714b5fe0cffbb78978f222ea6baebb726af13c78869fdb4205" +checksum = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -8993,9 +9001,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.59" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bda4168030a6412ea8a047e27238cadf56f0e53516e1e83fec0a8b7c786f6d" +checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931" dependencies = [ "proc-macro2", "quote", @@ -9006,9 +9014,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.59" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc9f36ad51f25b0219a3d4d13b90eb44cd075dff8b6280cca015775d7acaddd8" +checksum = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639" [[package]] name = "wasm-gc-api" @@ -9130,27 +9138,27 @@ dependencies = [ [[package]] name = "wast" -version = "10.0.0" +version = "11.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4efb62ecebf5cc9dbf2954309a20d816289c6550c0597a138b9e811cefc05007" +checksum = "df4d67ba9266f4fcaf2e8a1afadc5e2a959e51aecc07b1ecbdf85a6ddaf08bde" dependencies = [ "leb128", ] [[package]] name = "wat" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdea5e25273cc3a62f3ae3a1a4c7d7996625875b50c0b4475fee6698c2b069c" +checksum = "9a9400dc1c8512087b2d974b1b9b0a6c4e6e26e7e8acf629e3e351165a1ed301" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721c6263e2c66fd44501cc5efbfa2b7dfa775d13e4ea38c46299646ed1f9c70a" +checksum = "2d6f51648d8c56c366144378a33290049eafdd784071077f6fe37dae64c1c4cb" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index 37726e88ba..39a6ff1f2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -130,6 +130,7 @@ members = [ "primitives/offchain", "primitives/panic-handler", "primitives/phragmen", + "primitives/phragmen/compact", "primitives/rpc", "primitives/runtime-interface", "primitives/runtime-interface/proc-macro", diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index 9a286c5880..d45f5d7848 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -82,6 +82,7 @@ pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../../../frame frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/support" } pallet-im-online = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/im-online" } pallet-authority-discovery = { version = "2.0.0-alpha.5", path = "../../../frame/authority-discovery" } +pallet-staking = { version = "2.0.0-alpha.5", path = "../../../frame/staking" } # node-specific dependencies node-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index 7036a73dc0..45cb01b0ba 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -202,7 +202,14 @@ pub fn get_authority_keys_from_seed(seed: &str) -> ( /// Helper function to create GenesisConfig for testing pub fn testnet_genesis( - initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId)>, + initial_authorities: Vec<( + AccountId, + AccountId, + GrandpaId, + BabeId, + ImOnlineId, + AuthorityDiscoveryId, + )>, root_key: AccountId, endowed_accounts: Option>, enable_println: bool, @@ -244,7 +251,12 @@ pub fn testnet_genesis( }), pallet_session: Some(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())) + (x.0.clone(), x.0.clone(), session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + )) }).collect::>(), }), pallet_staking: Some(StakingConfig { diff --git a/bin/node/cli/src/factory_impl.rs b/bin/node/cli/src/factory_impl.rs index 1d1eabe29c..cd7e3022e0 100644 --- a/bin/node/cli/src/factory_impl.rs +++ b/bin/node/cli/src/factory_impl.rs @@ -58,6 +58,7 @@ impl FactoryState { frame_system::CheckWeight::new(), pallet_transaction_payment::ChargeTransactionPayment::from(0), Default::default(), + Default::default(), ) } } @@ -122,7 +123,7 @@ impl RuntimeAdapter for FactoryState { (*amount).into() ) ) - }, key, (version, genesis_hash.clone(), prior_block_hash.clone(), (), (), (), ())) + }, key, (version, genesis_hash.clone(), prior_block_hash.clone(), (), (), (), (), ())) } fn inherent_extrinsics(&self) -> InherentData { diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index d81ec5f031..452b1fa3e6 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -624,11 +624,12 @@ mod tests { check_weight, payment, Default::default(), + Default::default(), ); let raw_payload = SignedPayload::from_raw( function, extra, - (version, genesis_hash, genesis_hash, (), (), (), ()) + (version, genesis_hash, genesis_hash, (), (), (), (), ()) ); let signature = raw_payload.using_encoded(|payload| { signer.sign(payload) diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index 5e5be5bade..784b140a13 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use node_runtime::{ - Call, Executive, Indices, Runtime, SubmitTransaction, UncheckedExtrinsic, + Call, Executive, Indices, Runtime, TransactionSubmitterOf, UncheckedExtrinsic, }; use sp_application_crypto::AppKey; use sp_core::testing::KeyStore; @@ -31,6 +31,8 @@ use codec::Decode; pub mod common; use self::common::*; +type SubmitTransaction = TransactionSubmitterOf; + #[test] fn should_submit_unsigned_transaction() { let mut t = new_test_ext(COMPACT_CODE, false); diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 5c61eadf15..8868f28557 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -59,7 +59,7 @@ pub use pallet_timestamp::Call as TimestampCall; pub use pallet_balances::Call as BalancesCall; pub use pallet_contracts::Gas; pub use frame_support::StorageValue; -pub use pallet_staking::StakerStatus; +pub use pallet_staking::{StakerStatus, LockStakingStatus}; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; @@ -73,6 +73,52 @@ use constants::{time::*, currency::*}; #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +/// A transaction submitter with the given key type. +pub type TransactionSubmitterOf = TransactionSubmitter; + +/// Submits transaction with the node's public and signature type. Adheres to the signed extension +/// format of the chain. +impl frame_system::offchain::CreateTransaction for Runtime { + type Public = ::Signer; + type Signature = Signature; + + fn create_transaction>( + call: Call, + public: Self::Public, + account: AccountId, + index: Index, + ) -> Option<(Call, ::SignaturePayload)> { + // take the biggest period possible. + let period = BlockHashCount::get() + .checked_next_power_of_two() + .map(|c| c / 2) + .unwrap_or(2) as u64; + let current_block = System::block_number() + .saturated_into::() + // The `System::block_number` is initialized with `n+1`, + // so the actual block number is `n`. + .saturating_sub(1); + let tip = 0; + let extra: SignedExtra = ( + frame_system::CheckVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(generic::Era::mortal(period, current_block)), + frame_system::CheckNonce::::from(index), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + Default::default(), + Default::default(), + ); + let raw_payload = SignedPayload::new(call, extra).map_err(|e| { + debug::warn!("Unable to create signed payload: {:?}", e); + }).ok()?; + let signature = TSigner::sign(public, &raw_payload)?; + let address = Indices::unlookup(account); + let (call, extra, _) = raw_payload.deconstruct(); + Some((call, (address, signature, extra))) + } +} + /// Runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("node"), @@ -255,6 +301,7 @@ impl pallet_session::Trait for Runtime { type SessionHandler = ::KeyTypeIdProviders; type Keys = SessionKeys; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type NextSessionRotation = Babe; } impl pallet_session::historical::Trait for Runtime { @@ -278,6 +325,7 @@ parameter_types! { pub const BondingDuration: pallet_staking::EraIndex = 24 * 28; pub const SlashDeferDuration: pallet_staking::EraIndex = 24 * 7; // 1/4 the bonding duration. pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; + pub const ElectionLookahead: BlockNumber = 25; // 10 minutes per session => 100 block. pub const MaxNominatorRewardedPerValidator: u32 = 64; } @@ -296,6 +344,10 @@ impl pallet_staking::Trait for Runtime { type SlashCancelOrigin = pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>; type SessionInterface = Self; type RewardCurve = RewardCurve; + type NextNewSession = Session; + type ElectionLookahead = ElectionLookahead; + type Call = Call; + type SubmitTransaction = TransactionSubmitterOf<()>; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; } @@ -470,9 +522,6 @@ impl pallet_sudo::Trait for Runtime { type Call = Call; } -/// A runtime transaction submitter. -pub type SubmitTransaction = TransactionSubmitter; - parameter_types! { pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_SLOTS as _; } @@ -481,7 +530,7 @@ impl pallet_im_online::Trait for Runtime { type AuthorityId = ImOnlineId; type Event = Event; type Call = Call; - type SubmitTransaction = SubmitTransaction; + type SubmitTransaction = TransactionSubmitterOf; type SessionDuration = SessionDuration; type ReportUnresponsiveness = Offences; } @@ -530,46 +579,6 @@ impl pallet_identity::Trait for Runtime { type RegistrarOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; } -impl frame_system::offchain::CreateTransaction for Runtime { - type Public = ::Signer; - type Signature = Signature; - - fn create_transaction>( - call: Call, - public: Self::Public, - account: AccountId, - index: Index, - ) -> Option<(Call, ::SignaturePayload)> { - // take the biggest period possible. - let period = BlockHashCount::get() - .checked_next_power_of_two() - .map(|c| c / 2) - .unwrap_or(2) as u64; - let current_block = System::block_number() - .saturated_into::() - // The `System::block_number` is initialized with `n+1`, - // so the actual block number is `n`. - .saturating_sub(1); - let tip = 0; - let extra: SignedExtra = ( - frame_system::CheckVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(generic::Era::mortal(period, current_block)), - frame_system::CheckNonce::::from(index), - frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - Default::default(), - ); - let raw_payload = SignedPayload::new(call, extra).map_err(|e| { - debug::warn!("Unable to create signed payload: {:?}", e); - }).ok()?; - let signature = TSigner::sign(public, &raw_payload)?; - let address = Indices::unlookup(account); - let (call, extra, _) = raw_payload.deconstruct(); - Some((call, (address, signature, extra))) - } -} - parameter_types! { pub const ConfigDepositBase: Balance = 5 * DOLLARS; pub const FriendDepositFactor: Balance = 50 * CENTS; @@ -638,7 +647,7 @@ construct_runtime!( Indices: pallet_indices::{Module, Call, Storage, Config, Event}, Balances: pallet_balances::{Module, Call, Storage, Config, Event}, TransactionPayment: pallet_transaction_payment::{Module, Storage}, - Staking: pallet_staking::{Module, Call, Config, Storage, Event}, + Staking: pallet_staking::{Module, Call, Config, Storage, Event, ValidateUnsigned}, Session: pallet_session::{Module, Call, Storage, Event, Config}, Democracy: pallet_democracy::{Module, Call, Storage, Config, Event}, Council: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, @@ -680,6 +689,7 @@ pub type SignedExtra = ( frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, pallet_contracts::CheckBlockGasLimit, + pallet_staking::LockStakingStatus, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; @@ -965,7 +975,7 @@ mod tests { >, {} - is_submit_signed_transaction::(); - is_sign_and_submit_transaction::(); + is_submit_signed_transaction::>(); + is_sign_and_submit_transaction::>(); } } diff --git a/bin/node/testing/src/keyring.rs b/bin/node/testing/src/keyring.rs index 6b0d06875d..5fa1e48b03 100644 --- a/bin/node/testing/src/keyring.rs +++ b/bin/node/testing/src/keyring.rs @@ -75,6 +75,7 @@ pub fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra { frame_system::CheckWeight::new(), pallet_transaction_payment::ChargeTransactionPayment::from(extra_fee), Default::default(), + Default::default(), ) } diff --git a/bin/utils/subkey/src/main.rs b/bin/utils/subkey/src/main.rs index bc7d7a602a..8f0f96c39e 100644 --- a/bin/utils/subkey/src/main.rs +++ b/bin/utils/subkey/src/main.rs @@ -683,6 +683,7 @@ fn create_extrinsic( frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(f), Default::default(), + Default::default(), ) }; let raw_payload = SignedPayload::from_raw( @@ -696,6 +697,7 @@ fn create_extrinsic( (), (), (), + (), ), ); let signature = raw_payload.using_encoded(|payload| signer.sign(payload)).into_runtime(); diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index 8ee4931e48..b8f28b432b 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -121,6 +121,7 @@ mod tests { type ValidatorId = AuthorityId; type ValidatorIdOf = ConvertInto; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type NextSessionRotation = pallet_session::PeriodicSessions; } impl pallet_session::historical::Trait for Test { diff --git a/frame/babe/Cargo.toml b/frame/babe/Cargo.toml index e4acd52ed3..8790b3775c 100644 --- a/frame/babe/Cargo.toml +++ b/frame/babe/Cargo.toml @@ -9,7 +9,6 @@ repository = "https://github.com/paritytech/substrate/" description = "Consensus extension module for BABE consensus. Collects on-chain randomness from VRF outputs and manages epoch transitions." [dependencies] -hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } @@ -26,11 +25,7 @@ sp-consensus-vrf = { version = "0.8.0-alpha.5", default-features = false, path = sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} [dev-dependencies] -lazy_static = "1.4.0" -parking_lot = "0.10.0" -sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/version" } sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } [features] default = ["std"] diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 29b6eb00a3..7315d17618 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -19,8 +19,8 @@ #![cfg_attr(not(feature = "std"), no_std)] #![forbid(unused_must_use, unsafe_code, unused_variables, unused_must_use)] -#![deny(unused_imports)] -pub use pallet_timestamp; + +use pallet_timestamp; use sp_std::{result, prelude::*}; use frame_support::{ @@ -29,7 +29,7 @@ use frame_support::{ }; use sp_timestamp::OnTimestampSet; use sp_runtime::{generic::DigestItem, ConsensusEngineId, Perbill, PerThing}; -use sp_runtime::traits::{IsMember, SaturatedConversion, Saturating, Hash}; +use sp_runtime::traits::{IsMember, SaturatedConversion, Saturating, Hash, One}; use sp_staking::{ SessionIndex, offence::{Offence, Kind}, @@ -307,12 +307,34 @@ impl Module { // epoch 0 as having started at the slot of block 1. We want to use // the same randomness and validator set as signalled in the genesis, // so we don't rotate the epoch. - now != sp_runtime::traits::One::one() && { + now != One::one() && { let diff = CurrentSlot::get().saturating_sub(Self::current_epoch_start()); diff >= T::EpochDuration::get() } } + /// Return the _best guess_ block number, at which the next epoch change is predicted to happen. + /// + /// Returns None if the prediction is in the past; This implies an error internally in the Babe + /// and should not happen under normal circumstances. + /// + /// In other word, this is only accurate if no slots are missed. Given missed slots, the slot + /// number will grow while the block number will not. Hence, the result can be interpreted as an + /// upper bound. + // -------------- IMPORTANT NOTE -------------- + // This implementation is linked to how [`should_epoch_change`] is working. This might need to + // be updated accordingly, if the underlying mechanics of slot and epochs change. + pub fn next_expected_epoch_change(now: T::BlockNumber) -> Option { + let next_slot = Self::current_epoch_start().saturating_add(T::EpochDuration::get()); + next_slot + .checked_sub(CurrentSlot::get()) + .map(|slots_remaining| { + // This is a best effort guess. Drifts in the slot/block ratio will cause errors here. + let blocks_remaining: T::BlockNumber = slots_remaining.saturated_into(); + now.saturating_add(blocks_remaining) + }) + } + /// DANGEROUS: Enact an epoch change. Should be done on every block where `should_epoch_change` has returned `true`, /// and the caller is the only caller of this function. /// @@ -324,10 +346,7 @@ impl Module { ) { // PRECONDITION: caller has done initialization and is guaranteed // by the session module to be called before this. - #[cfg(debug_assertions)] - { - assert!(Self::initialized().is_some()) - } + debug_assert!(Self::initialized().is_some()); // Update epoch index let epoch_index = EpochIndex::get() @@ -473,6 +492,12 @@ impl OnTimestampSet for Module { fn on_timestamp_set(_moment: T::Moment) { } } +impl frame_support::traits::EstimateNextSessionRotation for Module { + fn estimate_next_session_rotation(now: T::BlockNumber) -> Option { + Self::next_expected_epoch_change(now) + } +} + impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = AuthorityId; } diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index 2ec083728e..ea802b268e 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -16,14 +16,22 @@ //! Test utilities -use super::{Trait, Module, GenesisConfig}; +use codec::Encode; +use super::{Trait, Module, GenesisConfig, CurrentSlot}; use sp_runtime::{ - traits::IdentityLookup, Perbill, testing::{Header, UintAuthorityId}, impl_opaque_keys, + Perbill, impl_opaque_keys, + testing::{Header, UintAuthorityId, Digest, DigestItem}, + traits::IdentityLookup, +}; +use frame_system::InitKind; +use frame_support::{ + impl_outer_origin, parameter_types, StorageValue, + traits::OnInitialize, + weights::Weight, }; -use sp_version::RuntimeVersion; -use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; use sp_io; use sp_core::H256; +use sp_consensus_vrf::schnorrkel::{RawVRFOutput, RawVRFProof}; impl_outer_origin!{ pub enum Origin for Test where system = frame_system {} @@ -43,7 +51,6 @@ parameter_types! { pub const MinimumPeriod: u64 = 1; pub const EpochDuration: u64 = 3; pub const ExpectedBlockTime: u64 = 1; - pub const Version: RuntimeVersion = substrate_test_runtime::VERSION; pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(16); } @@ -53,7 +60,7 @@ impl frame_system::Trait for Test { type BlockNumber = u64; type Call = (); type Hash = H256; - type Version = Version; + type Version = (); type Hashing = sp_runtime::traits::BlakeTwo256; type AccountId = DummyValidatorId; type Lookup = IdentityLookup; @@ -79,11 +86,12 @@ impl pallet_session::Trait for Test { type Event = (); type ValidatorId = ::AccountId; type ShouldEndSession = Babe; - type SessionHandler = (Babe,Babe,); + type SessionHandler = (Babe,); type SessionManager = (); type ValidatorIdOf = (); type Keys = MockSessionKeys; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type NextSessionRotation = Babe; } impl pallet_timestamp::Trait for Test { @@ -106,5 +114,44 @@ pub fn new_test_ext(authorities: Vec) -> sp_io::TestExternalit t.into() } +pub fn go_to_block(n: u64, s: u64) { + let pre_digest = make_pre_digest(0, s, RawVRFOutput([1; 32]), RawVRFProof([0xff; 64])); + System::initialize(&n, &Default::default(), &Default::default(), &pre_digest, InitKind::Full); + System::set_block_number(n); + if s > 1 { + CurrentSlot::put(s); + } + // includes a call into `Babe::do_initialize`. + Session::on_initialize(n); +} + +/// Slots will grow accordingly to blocks +pub fn progress_to_block(n: u64) { + let mut slot = Babe::current_slot() + 1; + for i in System::block_number()+1..=n { + go_to_block(i, slot); + slot += 1; + } +} + +pub fn make_pre_digest( + authority_index: sp_consensus_babe::AuthorityIndex, + slot_number: sp_consensus_babe::SlotNumber, + vrf_output: RawVRFOutput, + vrf_proof: RawVRFProof, +) -> Digest { + let digest_data = sp_consensus_babe::digests::RawPreDigest::Primary( + sp_consensus_babe::digests::RawPrimaryPreDigest { + authority_index, + slot_number, + vrf_output, + vrf_proof, + } + ); + let log = DigestItem::PreRuntime(sp_consensus_babe::BABE_ENGINE_ID, digest_data.encode()); + Digest { logs: vec![log] } +} + pub type System = frame_system::Module; pub type Babe = Module; +pub type Session = pallet_session::Module; diff --git a/frame/babe/src/tests.rs b/frame/babe/src/tests.rs index 5769b1235c..24aba10017 100644 --- a/frame/babe/src/tests.rs +++ b/frame/babe/src/tests.rs @@ -17,11 +17,10 @@ //! Consensus extension module tests for BABE consensus. use super::*; +use mock::*; use frame_support::traits::OnFinalize; -use mock::{new_test_ext, Babe, System}; -use sp_runtime::testing::{Digest, DigestItem}; -use sp_consensus_vrf::schnorrkel::{RawVRFOutput, RawVRFProof}; use pallet_session::ShouldEndSession; +use sp_consensus_vrf::schnorrkel::{RawVRFOutput, RawVRFProof}; const EMPTY_RANDOMNESS: [u8; 32] = [ 74, 25, 49, 128, 53, 97, 244, 49, @@ -30,24 +29,6 @@ const EMPTY_RANDOMNESS: [u8; 32] = [ 217, 153, 138, 37, 48, 192, 248, 0, ]; -fn make_pre_digest( - authority_index: sp_consensus_babe::AuthorityIndex, - slot_number: sp_consensus_babe::SlotNumber, - vrf_output: RawVRFOutput, - vrf_proof: RawVRFProof, -) -> Digest { - let digest_data = sp_consensus_babe::digests::RawPreDigest::Primary( - sp_consensus_babe::digests::RawPrimaryPreDigest { - authority_index, - slot_number, - vrf_output, - vrf_proof, - } - ); - let log = DigestItem::PreRuntime(sp_consensus_babe::BABE_ENGINE_ID, digest_data.encode()); - Digest { logs: vec![log] } -} - #[test] fn empty_randomness_is_correct() { let s = compute_randomness([0; RANDOMNESS_LENGTH], 0, std::iter::empty(), None); @@ -132,3 +113,24 @@ fn authority_index() { "Trivially invalid authorities are ignored") }) } + +#[test] +fn can_predict_next_epoch_change() { + new_test_ext(vec![]).execute_with(|| { + assert_eq!(::EpochDuration::get(), 3); + // this sets the genesis slot to 6; + go_to_block(1, 6); + assert_eq!(Babe::genesis_slot(), 6); + assert_eq!(Babe::current_slot(), 6); + assert_eq!(Babe::epoch_index(), 0); + + progress_to_block(5); + + assert_eq!(Babe::epoch_index(), 5 / 3); + assert_eq!(Babe::current_slot(), 10); + + // next epoch change will be at + assert_eq!(Babe::current_epoch_start(), 9); // next change will be 12, 2 slots from now + assert_eq!(Babe::next_expected_epoch_change(System::block_number()), Some(5 + 2)); + }) +} diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 0030f2608f..9a9e3c3143 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -94,7 +94,7 @@ use frame_support::{ ChangeMembers, OnUnbalanced, WithdrawReason, Contains, BalanceStatus } }; -use sp_phragmen::ExtendedBalance; +use sp_phragmen::{build_support_map, ExtendedBalance}; use frame_system::{self as system, ensure_signed, ensure_root}; const MODULE_ID: LockIdentifier = *b"phrelect"; @@ -692,12 +692,18 @@ impl Module { .filter_map(|(m, a)| if a.is_zero() { None } else { Some(m) } ) .collect::>(); - let support_map = sp_phragmen::build_support_map::<_, _, _, T::CurrencyToVote, Perbill>( - &new_set, - &phragmen_result.assignments, - Self::locked_stake_of, + let stake_of = |who: &T::AccountId| -> ExtendedBalance { + , u64>>::convert( + Self::locked_stake_of(who) + ) as ExtendedBalance + }; + let staked_assignments = sp_phragmen::assignment_ratio_to_staked( + phragmen_result.assignments, + stake_of, ); + let (support_map, _) = build_support_map::(&new_set, &staked_assignments); + let to_balance = |e: ExtendedBalance| >>::convert(e); let new_set_with_stake = new_set diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 78b6409d54..1fd1bcbdfe 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -141,6 +141,7 @@ impl pallet_session::Trait for Runtime { type Keys = UintAuthorityId; type Event = (); type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type NextSessionRotation = pallet_session::PeriodicSessions; } impl pallet_session::historical::Trait for Runtime { diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index 3e7f8c9537..0ba7cd87f2 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -26,11 +26,12 @@ mod tests; use sp_std::vec::Vec; use frame_support::{ - decl_module, decl_event, decl_storage, Parameter, + decl_module, decl_event, decl_storage, Parameter, debug, weights::{Weight, SimpleDispatchInfo, WeighData}, }; -use sp_runtime::traits::Hash; +use sp_runtime::{traits::Hash, Perbill}; use sp_staking::{ + SessionIndex, offence::{Offence, ReportOffence, Kind, OnOffenceHandler, OffenceDetails, OffenceError}, }; use codec::{Encode, Decode}; @@ -42,6 +43,13 @@ type OpaqueTimeSlot = Vec; /// A type alias for a report identifier. type ReportIdOf = ::Hash; +/// Type of data stored as a deferred offence +type DeferredOffenceOf = ( + Vec::AccountId, ::IdentificationTuple>>, + Vec, + SessionIndex, +); + /// Offences trait pub trait Trait: frame_system::Trait { /// The overarching event type. @@ -59,6 +67,10 @@ decl_storage! { map hasher(twox_64_concat) ReportIdOf => Option>; + /// Deferred reports that have been rejected by the offence handler and need to be submitted + /// at a later time. + DeferredOffences get(deferred_offences): Vec>; + /// A vector of reports of the same kind that happened at the same time slot. ConcurrentReportsIndex: double_map hasher(twox_64_concat) Kind, hasher(twox_64_concat) OpaqueTimeSlot @@ -77,13 +89,13 @@ decl_storage! { decl_event!( pub enum Event { /// There is an offence reported of the given `kind` happened at the `session_index` and - /// (kind-specific) time slot. This event is not deposited for duplicate slashes. - Offence(Kind, OpaqueTimeSlot), + /// (kind-specific) time slot. This event is not deposited for duplicate slashes. last + /// element indicates of the offence was applied (true) or queued (false). + Offence(Kind, OpaqueTimeSlot, bool), } ); decl_module! { - /// Offences module, currently just responsible for taking offence reports. pub struct Module for enum Call where origin: T::Origin { fn deposit_event() = default; @@ -94,6 +106,27 @@ decl_module! { SimpleDispatchInfo::default().weigh_data(()) } + + fn on_initialize(now: T::BlockNumber) -> Weight { + // only decode storage if we can actually submit anything again. + if T::OnOffenceHandler::can_report() { + >::mutate(|deferred| { + // keep those that fail to be reported again. An error log is emitted here; this + // should not happen if staking's `can_report` is implemented properly. + deferred.retain(|(o, p, s)| { + T::OnOffenceHandler::on_offence(&o, &p, *s).map_err(|_| { + debug::native::error!( + target: "pallet-offences", + "re-submitting a deferred slash returned Err at {}. This should not happen with pallet-staking", + now, + ); + }).is_err() + }) + }) + } + + SimpleDispatchInfo::default().weigh_data(()) + } } } @@ -119,9 +152,6 @@ where None => return Err(OffenceError::DuplicateReport), }; - // Deposit the event. - Self::deposit_event(Event::Offence(O::ID, time_slot.encode())); - let offenders_count = concurrent_offenders.len() as u32; // The amount new offenders are slashed @@ -130,17 +160,42 @@ where let slash_perbill: Vec<_> = (0..concurrent_offenders.len()) .map(|_| new_fraction.clone()).collect(); - T::OnOffenceHandler::on_offence( + let applied = Self::report_or_store_offence( &concurrent_offenders, &slash_perbill, offence.session_index(), ); + // Deposit the event. + Self::deposit_event(Event::Offence(O::ID, time_slot.encode(), applied)); + Ok(()) } } impl Module { + /// Tries (without checking) to report an offence. Stores them in [`DeferredOffences`] in case + /// it fails. Returns false in case it has to store the offence. + fn report_or_store_offence( + concurrent_offenders: &[OffenceDetails], + slash_perbill: &[Perbill], + session_index: SessionIndex, + ) -> bool { + match T::OnOffenceHandler::on_offence( + &concurrent_offenders, + &slash_perbill, + session_index, + ) { + Ok(_) => true, + Err(_) => { + >::mutate(|d| + d.push((concurrent_offenders.to_vec(), slash_perbill.to_vec(), session_index)) + ); + false + } + } + } + /// Compute the ID for the given report properties. /// /// The report id depends on the offence kind, time slot and the id of offender. diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index a003ad6915..7ddbc6726d 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -43,6 +43,7 @@ pub struct OnOffenceHandler; thread_local! { pub static ON_OFFENCE_PERBILL: RefCell> = RefCell::new(Default::default()); + pub static CAN_REPORT: RefCell = RefCell::new(true); } impl offence::OnOffenceHandler for OnOffenceHandler { @@ -50,11 +51,25 @@ impl offence::OnOffenceHandler for OnOff _offenders: &[OffenceDetails], slash_fraction: &[Perbill], _offence_session: SessionIndex, - ) { - ON_OFFENCE_PERBILL.with(|f| { - *f.borrow_mut() = slash_fraction.to_vec(); - }); + ) -> Result<(), ()> { + if >::can_report() { + ON_OFFENCE_PERBILL.with(|f| { + *f.borrow_mut() = slash_fraction.to_vec(); + }); + + Ok(()) + } else { + Err(()) + } } + + fn can_report() -> bool { + CAN_REPORT.with(|c| *c.borrow()) + } +} + +pub fn set_can_report(can_report: bool) { + CAN_REPORT.with(|c| *c.borrow_mut() = can_report); } pub fn with_on_offence_fractions) -> R>(f: F) -> R { diff --git a/frame/offences/src/tests.rs b/frame/offences/src/tests.rs index 7e9c3986ed..3179a07523 100644 --- a/frame/offences/src/tests.rs +++ b/frame/offences/src/tests.rs @@ -21,9 +21,10 @@ use super::*; use crate::mock::{ Offences, System, Offence, TestEvent, KIND, new_test_ext, with_on_offence_fractions, - offence_reports, + offence_reports, set_can_report, }; use sp_runtime::Perbill; +use frame_support::traits::OnInitialize; use frame_system::{EventRecord, Phase}; #[test] @@ -130,7 +131,7 @@ fn should_deposit_event() { System::events(), vec![EventRecord { phase: Phase::Initialization, - event: TestEvent::offences(crate::Event::Offence(KIND, time_slot.encode())), + event: TestEvent::offences(crate::Event::Offence(KIND, time_slot.encode(), true)), topics: vec![], }] ); @@ -165,7 +166,7 @@ fn doesnt_deposit_event_for_dups() { System::events(), vec![EventRecord { phase: Phase::Initialization, - event: TestEvent::offences(crate::Event::Offence(KIND, time_slot.encode())), + event: TestEvent::offences(crate::Event::Offence(KIND, time_slot.encode(), true)), topics: vec![], }] ); @@ -212,3 +213,54 @@ fn should_properly_count_offences() { ); }); } + +#[test] +fn should_queue_and_resubmit_rejected_offence() { + new_test_ext().execute_with(|| { + set_can_report(false); + + // will get deferred + let offence = Offence { + validator_set_count: 5, + time_slot: 42, + offenders: vec![5], + }; + Offences::report_offence(vec![], offence).unwrap(); + assert_eq!(Offences::deferred_offences().len(), 1); + // event also indicates unapplied. + assert_eq!( + System::events(), + vec![EventRecord { + phase: Phase::Initialization, + event: TestEvent::offences(crate::Event::Offence(KIND, 42u128.encode(), false)), + topics: vec![], + }] + ); + + // will not dequeue + Offences::on_initialize(2); + + // again + let offence = Offence { + validator_set_count: 5, + time_slot: 62, + offenders: vec![5], + }; + Offences::report_offence(vec![], offence).unwrap(); + assert_eq!(Offences::deferred_offences().len(), 2); + + set_can_report(true); + + // can be submitted + let offence = Offence { + validator_set_count: 5, + time_slot: 72, + offenders: vec![5], + }; + Offences::report_offence(vec![], offence).unwrap(); + assert_eq!(Offences::deferred_offences().len(), 2); + + Offences::on_initialize(3); + assert_eq!(Offences::deferred_offences().len(), 0); + }) +} diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index b11ae1d818..9346b060fa 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -102,13 +102,15 @@ use sp_std::{prelude::*, marker::PhantomData, ops::{Sub, Rem}}; use codec::Decode; use sp_runtime::{KeyTypeId, Perbill, RuntimeAppPublic, BoundToRuntimeAppPublic}; -use sp_runtime::traits::{Convert, Zero, Member, OpaqueKeys}; +use sp_runtime::traits::{Convert, Zero, Member, OpaqueKeys, Saturating}; use sp_staking::SessionIndex; use frame_support::{ ensure, decl_module, decl_event, decl_storage, decl_error, ConsensusEngineId, Parameter, - weights::{Weight, SimpleDispatchInfo, WeighData}, - traits::{Get, FindAuthor, ValidatorRegistration}, + traits::{ + Get, FindAuthor, ValidatorRegistration, EstimateNextSessionRotation, EstimateNextNewSession, + }, dispatch::{self, DispatchResult, DispatchError}, + weights::{Weight, SimpleDispatchInfo, WeighData}, }; use frame_system::{self as system, ensure_signed}; @@ -147,6 +149,29 @@ impl< } } +impl< + BlockNumber: Rem + Sub + Zero + PartialOrd + Saturating + Clone, + Period: Get, + Offset: Get, +> EstimateNextSessionRotation for PeriodicSessions { + fn estimate_next_session_rotation(now: BlockNumber) -> Option { + let offset = Offset::get(); + let period = Period::get(); + Some(if now > offset { + let block_after_last_session = (now.clone() - offset) % period.clone(); + if block_after_last_session > Zero::zero() { + now.saturating_add( + period.saturating_sub(block_after_last_session) + ) + } else { + Zero::zero() + } + } else { + offset + }) + } +} + /// A trait for managing creation of new validator set. pub trait SessionManager { /// Plan a new session, and optionally provide the new validator set. @@ -330,6 +355,11 @@ pub trait Trait: frame_system::Trait { /// Indicator for when to end the session. type ShouldEndSession: ShouldEndSession; + /// Something that can predict the next session rotation. This should typically come from the + /// same logical unit that provides [`ShouldEndSession`], yet, it gives a best effort estimate. + /// It is helpful to implement [`EstimateNextNewSession`]. + type NextSessionRotation: EstimateNextSessionRotation; + /// Handler for managing new session. type SessionManager: SessionManager; @@ -735,3 +765,11 @@ impl> FindAuthor validators.get(i as usize).map(|k| k.clone()) } } + +impl EstimateNextNewSession for Module { + /// This session module always calls new_session and next_session at the same time, hence we + /// do a simple proxy and pass the function to next rotation. + fn estimate_next_new_session(now: T::BlockNumber) -> Option { + T::NextSessionRotation::estimate_next_session_rotation(now) + } +} diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index 9d64285b90..dd28d35749 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -205,6 +205,7 @@ impl Trait for Test { type Keys = MockSessionKeys; type Event = (); type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type NextSessionRotation = (); } #[cfg(feature = "historical")] diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index 7ea72b3d7a..8a9310e223 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -11,7 +11,6 @@ description = "FRAME pallet staking" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } -sp-keyring = { version = "2.0.0-alpha.5", optional = true, path = "../../primitives/keyring" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-phragmen = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/phragmen" } sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} @@ -21,7 +20,15 @@ frame-support = { version = "2.0.0-alpha.5", default-features = false, path = ". frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } pallet-session = { version = "2.0.0-alpha.5", features = ["historical"], path = "../session", default-features = false } pallet-authorship = { version = "2.0.0-alpha.5", default-features = false, path = "../authorship" } +sp-application-crypto = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/application-crypto" } +static_assertions = "1.1.0" +# Optional imports for tesing-utils feature +pallet-indices = { version = "2.0.0-alpha.4", optional = true, path = "../indices", default-features = false } +sp-core = { version = "2.0.0-alpha.4", optional = true, path = "../../primitives/core", default-features = false } +rand = { version = "0.7.3", optional = true, default-features = false } + +# Optional imports for benchmarking frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } rand_chacha = { version = "0.2", default-features = false, optional = true } @@ -33,13 +40,20 @@ pallet-staking-reward-curve = { version = "2.0.0-alpha.5", path = "../staking/r substrate-test-utils = { version = "2.0.0-alpha.5", path = "../../test-utils" } frame-benchmarking = { version = "2.0.0-alpha.5", path = "../benchmarking" } rand_chacha = { version = "0.2" } +parking_lot = "0.10.0" +env_logger = "0.7.1" hex = "0.4" [features] +testing-utils = [ + "std", + "pallet-indices/std", + "sp-core/std", + "rand/std", +] default = ["std"] std = [ "serde", - "sp-keyring", "codec/std", "sp-std/std", "sp-phragmen/std", @@ -50,6 +64,8 @@ std = [ "pallet-session/std", "frame-system/std", "pallet-authorship/std", + "sp-application-crypto/std", + "sp-core/std", ] runtime-benchmarks = [ "rand_chacha", diff --git a/frame/staking/fuzz/.gitignore b/frame/staking/fuzz/.gitignore new file mode 100644 index 0000000000..572e03bdf3 --- /dev/null +++ b/frame/staking/fuzz/.gitignore @@ -0,0 +1,4 @@ + +target +corpus +artifacts diff --git a/frame/staking/fuzz/Cargo.lock b/frame/staking/fuzz/Cargo.lock new file mode 100644 index 0000000000..e8469483db --- /dev/null +++ b/frame/staking/fuzz/Cargo.lock @@ -0,0 +1,2189 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "ahash" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3" +dependencies = [ + "const-random", +] + +[[package]] +name = "aho-corasick" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" +dependencies = [ + "memchr", +] + +[[package]] +name = "arbitrary" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16971f2f0ce65c5cf2a1546cc6a0af102ecb11e265ddaa9433fb3e5bfdf676a4" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" + +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" + +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" + +[[package]] +name = "backtrace" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad235dabf00f36301792cfe82499880ba54c6486be094d1047b02bacb67c14e8" +dependencies = [ + "backtrace-sys", + "cfg-if", + "libc", + "rustc-demangle", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17b52e737c40a7d75abca20b29a19a0eb7ba9fc72c5a72dd282a0a3c2c0dc35" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "base58" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bitmask" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" + +[[package]] +name = "bitvec" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" + +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +dependencies = [ + "arrayvec 0.4.12", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "bumpalo" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742" + +[[package]] +name = "byte-slice-cast" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "c2-chacha" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" +dependencies = [ + "ppv-lite86", +] + +[[package]] +name = "cc" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "clear_on_drop" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" +dependencies = [ + "cc", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "const-random" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a" +dependencies = [ + "const-random-macro", + "proc-macro-hack", +] + +[[package]] +name = "const-random-macro" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a" +dependencies = [ + "getrandom", + "proc-macro-hack", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array", + "subtle 1.0.0", +] + +[[package]] +name = "curve25519-dalek" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d" +dependencies = [ + "byteorder", + "clear_on_drop", + "digest", + "rand_core 0.3.1", + "subtle 2.2.2", +] + +[[package]] +name = "curve25519-dalek" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839" +dependencies = [ + "byteorder", + "digest", + "rand_core 0.5.1", + "subtle 2.2.2", + "zeroize 1.1.0", +] + +[[package]] +name = "derive_more" +version = "0.99.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a806e96c59a76a5ba6e18735b6cf833344671e61e7863f2edb5c518ea2cac95c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.0-pre.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978710b352437433c97b2bff193f2fb1dfd58a093f863dd95e225a19baa599a2" +dependencies = [ + "clear_on_drop", + "curve25519-dalek 2.0.0", + "rand 0.7.3", + "sha2", +] + +[[package]] +name = "environmental" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516aa8d7a71cb00a1c4146f0798549b93d083d4f189b3ced8f3de6b8f11ee6c4" + +[[package]] +name = "failure" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8529c2421efa3066a5cbd8063d2244603824daccb6936b079010bb2aa89464b" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fixed-hash" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" +dependencies = [ + "byteorder", + "libc", + "rand 0.7.3", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "frame-benchmarking" +version = "2.0.0-alpha.3" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "sp-api", + "sp-io", + "sp-runtime", + "sp-runtime-interface", + "sp-std", +] + +[[package]] +name = "frame-metadata" +version = "11.0.0-alpha.3" +dependencies = [ + "parity-scale-codec", + "serde", + "sp-core", + "sp-std", +] + +[[package]] +name = "frame-support" +version = "2.0.0-alpha.3" +dependencies = [ + "bitmask", + "frame-metadata", + "frame-support-procedural", + "impl-trait-for-tuples", + "log", + "once_cell", + "parity-scale-codec", + "paste", + "serde", + "sp-arithmetic", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-std", + "tracing", +] + +[[package]] +name = "frame-support-procedural" +version = "2.0.0-alpha.3" +dependencies = [ + "frame-support-procedural-tools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "frame-support-procedural-tools" +version = "2.0.0-alpha.3" +dependencies = [ + "frame-support-procedural-tools-derive", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "frame-support-procedural-tools-derive" +version = "2.0.0-alpha.3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "frame-system" +version = "2.0.0-alpha.3" +dependencies = [ + "frame-support", + "impl-trait-for-tuples", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-version", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "futures" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c329ae8753502fb44ae4fc2b622fa2a94652c41e795143765ba0927f92ab780" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c77d04ce8edd9cb903932b608268b3fffec4163dc053b3b402bf47eac1f1a8" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a" + +[[package]] +name = "futures-executor" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f674f3e1bcb15b37284a90cedf55afdba482ab061c407a9c0ebbd0f3109741ba" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6" + +[[package]] +name = "futures-macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3466821b4bc114d95b087b850a724c6f83115e929bc88f1fa98a3304a944c8a6" + +[[package]] +name = "futures-task" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27" + +[[package]] +name = "futures-util" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +dependencies = [ + "typenum", +] + +[[package]] +name = "getrandom" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hash-db" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" + +[[package]] +name = "hash256-std-hasher" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead" +dependencies = [ + "ahash", + "autocfg 0.1.7", +] + +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hex" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" + +[[package]] +name = "hmac" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +dependencies = [ + "crypto-mac", + "digest", +] + +[[package]] +name = "hmac-drbg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" +dependencies = [ + "digest", + "generic-array", + "hmac", +] + +[[package]] +name = "impl-codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-serde" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e3cae7e99c7ff5a995da2cf78dd0a5383740eda71d98cf7b1910c301ac69b8" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-serde" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bbe9ea9b182f0fb1cabbd61f4ff9b7b7b9197955e95a7e4c27de5055eb29ff8" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "integer-sqrt" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" + +[[package]] +name = "js-sys" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cb931d43e71f560c81badb0191596562bafad2be06a3f9025b845c847c60df5" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" + +[[package]] +name = "libfuzzer-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb789afcc589a08928d1e466087445ab740a0f70a2ee23d9349a0e3723d65e1b" +dependencies = [ + "arbitrary", + "cc", +] + +[[package]] +name = "libsecp256k1" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" +dependencies = [ + "arrayref", + "crunchy", + "digest", + "hmac-drbg", + "rand 0.7.3", + "sha2", + "subtle 2.2.2", + "typenum", +] + +[[package]] +name = "lock_api" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" + +[[package]] +name = "memory-db" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "198831fe8722331a395bc199a5d08efbc197497ef354cb4c77b969c02ffc0fc4" +dependencies = [ + "ahash", + "hash-db", + "hashbrown", + "parity-util-mem", +] + +[[package]] +name = "memory_units" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" + +[[package]] +name = "merlin" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b0942b357c1b4d0dc43ba724674ec89c3218e6ca2b3e8269e7cb53bcecd2f6e" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.4.2", + "zeroize 1.1.0", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg 1.0.0", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +dependencies = [ + "autocfg 1.0.0", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da4dc79f9e6c81bef96148c8f6b8e72ad4541caa4a24373e900a36da07de03a3" +dependencies = [ + "autocfg 1.0.0", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +dependencies = [ + "autocfg 1.0.0", +] + +[[package]] +name = "once_cell" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" +dependencies = [ + "parking_lot 0.9.0", +] + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "pallet-authorship" +version = "2.0.0-alpha.3" +dependencies = [ + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-authorship", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-balances" +version = "2.0.0-alpha.3" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "serde", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-indices" +version = "2.0.0-alpha.3" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-keyring", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-session" +version = "2.0.0-alpha.3" +dependencies = [ + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "pallet-timestamp", + "parity-scale-codec", + "serde", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", + "sp-trie", +] + +[[package]] +name = "pallet-staking" +version = "2.0.0-alpha.3" +dependencies = [ + "frame-support", + "frame-system", + "pallet-authorship", + "pallet-indices", + "pallet-session", + "parity-scale-codec", + "rand 0.7.3", + "serde", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-phragmen", + "sp-runtime", + "sp-staking", + "sp-std", + "static_assertions", +] + +[[package]] +name = "pallet-staking-fuzz" +version = "0.0.0" +dependencies = [ + "frame-support", + "frame-system", + "libfuzzer-sys", + "pallet-balances", + "pallet-indices", + "pallet-session", + "pallet-staking", + "pallet-staking-reward-curve", + "pallet-timestamp", + "parity-scale-codec", + "rand 0.7.3", + "sp-core", + "sp-io", + "sp-phragmen", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-staking-reward-curve" +version = "2.0.0-alpha.3" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pallet-timestamp" +version = "2.0.0-alpha.3" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "parity-scale-codec", + "serde", + "sp-inherents", + "sp-runtime", + "sp-std", + "sp-timestamp", +] + +[[package]] +name = "parity-scale-codec" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f509c5e67ca0605ee17dcd3f91ef41cadd685c75a298fb6261b781a5acb3f910" +dependencies = [ + "arrayvec 0.5.1", + "bitvec", + "byte-slice-cast", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parity-util-mem" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1476e40bf8f5c6776e9600983435821ca86eb9819d74a6207cca69d091406a" +dependencies = [ + "cfg-if", + "impl-trait-for-tuples", + "parity-util-mem-derive", + "parking_lot 0.10.0", + "primitive-types", + "winapi", +] + +[[package]] +name = "parity-util-mem-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" +dependencies = [ + "proc-macro2", + "syn", + "synstructure", +] + +[[package]] +name = "parity-wasm" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" + +[[package]] +name = "parking_lot" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" +dependencies = [ + "lock_api", + "parking_lot_core 0.6.2", + "rustc_version", +] + +[[package]] +name = "parking_lot" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" +dependencies = [ + "lock_api", + "parking_lot_core 0.7.0", +] + +[[package]] +name = "parking_lot_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" +dependencies = [ + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "rustc_version", + "smallvec 0.6.13", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" +dependencies = [ + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "smallvec 1.2.0", + "winapi", +] + +[[package]] +name = "paste" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e1afe738d71b1ebab5f1207c055054015427dbfc7bbe9ee1266894156ec046" +dependencies = [ + "paste-impl", + "proc-macro-hack", +] + +[[package]] +name = "paste-impl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d4dc4a7f6f743211c5aab239640a65091535d97d43d92a52bca435a640892bb" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pbkdf2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +dependencies = [ + "byteorder", + "crypto-mac", +] + +[[package]] +name = "pin-utils" +version = "0.1.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" + +[[package]] +name = "ppv-lite86" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" + +[[package]] +name = "primitive-types" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-serde 0.3.0", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro-nested" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" + +[[package]] +name = "proc-macro2" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.7", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha 0.2.1", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" +dependencies = [ + "c2-chacha", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" + +[[package]] +name = "regex" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1132f845907680735a84409c3bebc64d1364a5683ffbce899550cd09d5eaefc1" + +[[package]] +name = "rustc-demangle" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "schnorrkel" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" +dependencies = [ + "curve25519-dalek 1.2.3", + "failure", + "merlin", + "rand 0.6.5", + "rand_core 0.4.2", + "rand_os", + "sha2", + "subtle 2.2.2", + "zeroize 0.9.3", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "send_wrapper" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" + +[[package]] +name = "serde" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" +dependencies = [ + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", +] + +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + +[[package]] +name = "smallvec" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" +dependencies = [ + "maybe-uninit", +] + +[[package]] +name = "smallvec" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" + +[[package]] +name = "sp-api" +version = "2.0.0-alpha.3" +dependencies = [ + "hash-db", + "parity-scale-codec", + "sp-api-proc-macro", + "sp-core", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-version", +] + +[[package]] +name = "sp-api-proc-macro" +version = "2.0.0-alpha.3" +dependencies = [ + "blake2-rfc", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-application-crypto" +version = "2.0.0-alpha.3" +dependencies = [ + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-std", +] + +[[package]] +name = "sp-arithmetic" +version = "2.0.0-alpha.3" +dependencies = [ + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "serde", + "sp-debug-derive", + "sp-std", +] + +[[package]] +name = "sp-authorship" +version = "2.0.0-alpha.3" +dependencies = [ + "parity-scale-codec", + "sp-inherents", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "sp-core" +version = "2.0.0-alpha.3" +dependencies = [ + "base58", + "blake2-rfc", + "byteorder", + "ed25519-dalek", + "hash-db", + "hash256-std-hasher", + "hex", + "impl-serde 0.3.0", + "lazy_static", + "libsecp256k1", + "log", + "num-traits", + "parity-scale-codec", + "parity-util-mem", + "parking_lot 0.10.0", + "primitive-types", + "rand 0.7.3", + "regex", + "rustc-hex", + "schnorrkel", + "serde", + "sha2", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", + "sp-std", + "sp-storage", + "substrate-bip39", + "tiny-bip39", + "tiny-keccak", + "twox-hash", + "wasmi", + "zeroize 1.1.0", +] + +[[package]] +name = "sp-debug-derive" +version = "2.0.0-alpha.3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-externalities" +version = "0.8.0-alpha.3" +dependencies = [ + "environmental", + "sp-std", + "sp-storage", +] + +[[package]] +name = "sp-inherents" +version = "2.0.0-alpha.3" +dependencies = [ + "derive_more", + "parity-scale-codec", + "parking_lot 0.10.0", + "sp-core", + "sp-std", +] + +[[package]] +name = "sp-io" +version = "2.0.0-alpha.3" +dependencies = [ + "hash-db", + "libsecp256k1", + "log", + "parity-scale-codec", + "sp-core", + "sp-externalities", + "sp-runtime-interface", + "sp-state-machine", + "sp-std", + "sp-trie", + "sp-wasm-interface", +] + +[[package]] +name = "sp-keyring" +version = "2.0.0-alpha.3" +dependencies = [ + "lazy_static", + "sp-core", + "sp-runtime", + "strum", +] + +[[package]] +name = "sp-panic-handler" +version = "2.0.0-alpha.3" +dependencies = [ + "backtrace", + "log", +] + +[[package]] +name = "sp-phragmen" +version = "2.0.0-alpha.3" +dependencies = [ + "parity-scale-codec", + "serde", + "sp-core", + "sp-phragmen-compact", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "sp-phragmen-compact" +version = "2.0.0-dev" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-runtime" +version = "2.0.0-alpha.3" +dependencies = [ + "hash256-std-hasher", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "parity-util-mem", + "paste", + "rand 0.7.3", + "serde", + "sp-application-crypto", + "sp-arithmetic", + "sp-core", + "sp-inherents", + "sp-io", + "sp-std", +] + +[[package]] +name = "sp-runtime-interface" +version = "2.0.0-alpha.3" +dependencies = [ + "parity-scale-codec", + "primitive-types", + "sp-externalities", + "sp-runtime-interface-proc-macro", + "sp-std", + "sp-wasm-interface", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "2.0.0-alpha.3" +dependencies = [ + "Inflector", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-staking" +version = "2.0.0-alpha.3" +dependencies = [ + "parity-scale-codec", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "sp-state-machine" +version = "0.8.0-alpha.3" +dependencies = [ + "hash-db", + "log", + "num-traits", + "parity-scale-codec", + "parking_lot 0.10.0", + "rand 0.7.3", + "sp-core", + "sp-externalities", + "sp-panic-handler", + "sp-trie", + "trie-db", + "trie-root", +] + +[[package]] +name = "sp-std" +version = "2.0.0-alpha.3" + +[[package]] +name = "sp-storage" +version = "2.0.0-alpha.3" +dependencies = [ + "impl-serde 0.2.3", + "serde", + "sp-debug-derive", + "sp-std", +] + +[[package]] +name = "sp-timestamp" +version = "2.0.0-alpha.3" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-api", + "sp-inherents", + "sp-runtime", + "sp-std", + "wasm-timer", +] + +[[package]] +name = "sp-trie" +version = "2.0.0-alpha.3" +dependencies = [ + "hash-db", + "memory-db", + "parity-scale-codec", + "sp-core", + "sp-std", + "trie-db", + "trie-root", +] + +[[package]] +name = "sp-version" +version = "2.0.0-alpha.3" +dependencies = [ + "impl-serde 0.2.3", + "parity-scale-codec", + "serde", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "sp-wasm-interface" +version = "2.0.0-alpha.3" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-std", + "wasmi", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strum" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6138f8f88a16d90134763314e3fc76fa3ed6a7db4725d6acf9a3ef95a3188d22" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "substrate-bip39" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" +dependencies = [ + "hmac", + "pbkdf2", + "schnorrkel", + "sha2", +] + +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + +[[package]] +name = "subtle" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" + +[[package]] +name = "syn" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tiny-bip39" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6848cd8f566953ce1e8faeba12ee23cbdbb0437754792cd857d44628b5685e3" +dependencies = [ + "failure", + "hmac", + "once_cell", + "pbkdf2", + "rand 0.7.3", + "rustc-hash", + "sha2", + "unicode-normalization", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2953ca5148619bc99695c1274cb54c5275bbb913c6adad87e72eaf8db9787f69" +dependencies = [ + "crunchy", +] + +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1721cc8cf7d770cc4257872507180f35a4797272f5962f24c806af9e7faf52ab" +dependencies = [ + "cfg-if", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fbad39da2f9af1cae3016339ad7f2c7a9e870f12e8fd04c4fd7ef35b30c0d2b" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aa83a9a47081cd522c09c81b31aec2c9273424976f922ad61c053b58350b715" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "trie-db" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de9222c50cc325855621271157c973da27a0dcd26fa06f8edf81020bd2333df0" +dependencies = [ + "hash-db", + "hashbrown", + "log", + "rustc-hex", + "smallvec 1.2.0", +] + +[[package]] +name = "trie-root" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "652931506d2c1244d7217a70b99f56718a7b4161b37f04e7cd868072a99f68cd" +dependencies = [ + "hash-db", +] + +[[package]] +name = "twox-hash" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" +dependencies = [ + "rand 0.7.3", +] + +[[package]] +name = "typenum" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" + +[[package]] +name = "uint" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" +dependencies = [ + "byteorder", + "crunchy", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" +dependencies = [ + "smallvec 1.2.0", +] + +[[package]] +name = "unicode-segmentation" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasm-bindgen" +version = "0.2.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3557c397ab5a8e347d434782bcd31fc1483d927a6826804cec05cc792ee2519d" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0da9c9a19850d3af6df1cb9574970b566d617ecfaf36eb0b706b6f3ef9bd2f8" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "457414a91863c0ec00090dba537f88ab955d93ca6555862c29b6d860990b8a8a" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f6fde1d36e75a714b5fe0cffbb78978f222ea6baebb726af13c78869fdb4205" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bda4168030a6412ea8a047e27238cadf56f0e53516e1e83fec0a8b7c786f6d" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc9f36ad51f25b0219a3d4d13b90eb44cd075dff8b6280cca015775d7acaddd8" + +[[package]] +name = "wasm-timer" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "324c5e65a08699c9c4334ba136597ab22b85dccd4b65dd1e36ccf8f723a95b54" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.9.0", + "pin-utils", + "send_wrapper", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasmi" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" +dependencies = [ + "libc", + "memory_units", + "num-rational", + "num-traits", + "parity-wasm", + "wasmi-validation", +] + +[[package]] +name = "wasmi-validation" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93" +dependencies = [ + "parity-wasm", +] + +[[package]] +name = "web-sys" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721c6263e2c66fd44501cc5efbfa2b7dfa775d13e4ea38c46299646ed1f9c70a" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "zeroize" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" + +[[package]] +name = "zeroize" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/frame/staking/fuzz/Cargo.toml b/frame/staking/fuzz/Cargo.toml new file mode 100644 index 0000000000..e4e08a065c --- /dev/null +++ b/frame/staking/fuzz/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "pallet-staking-fuzz" +version = "0.0.0" +authors = ["Automatically generated"] +publish = false +edition = "2018" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.3" +codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +pallet-staking = { version = "2.0.0-alpha.2", path = "..", features = ["testing-utils"] } +pallet-staking-reward-curve = { version = "2.0.0-alpha.2", path = "../reward-curve" } +pallet-session = { version = "2.0.0-alpha.2", path = "../../session" } +pallet-indices = { version = "2.0.0-alpha.2", path = "../../indices" } +pallet-balances = { version = "2.0.0-alpha.2", path = "../../balances" } +pallet-timestamp = { version = "2.0.0-alpha.2", path = "../../timestamp" } +frame-system = { version = "2.0.0-alpha.2", path = "../../system" } +frame-support = { version = "2.0.0-alpha.2", path = "../../support" } +sp-std = { version = "2.0.0-alpha.2", path = "../../../primitives/std" } +sp-io ={ version = "2.0.0-alpha.2", path = "../../../primitives/io" } +sp-core = { version = "2.0.0-alpha.2", path = "../../../primitives/core" } +sp-phragmen = { version = "2.0.0-alpha.2", path = "../../../primitives/phragmen" } +sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" } +rand = "0.7.3" + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[[bin]] +name = "submit_solution" +path = "fuzz_targets/submit_solution.rs" diff --git a/frame/staking/fuzz/fuzz_targets/mock.rs b/frame/staking/fuzz/fuzz_targets/mock.rs new file mode 100644 index 0000000000..4bb3437f92 --- /dev/null +++ b/frame/staking/fuzz/fuzz_targets/mock.rs @@ -0,0 +1,182 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Mock file for staking fuzzing. + +use sp_runtime::traits::{Convert, SaturatedConversion}; +use frame_support::{impl_outer_origin, impl_outer_dispatch, parameter_types}; + +type AccountId = u64; +type AccountIndex = u32; +type BlockNumber = u64; +type Balance = u64; + +type System = frame_system::Module; +type Balances = pallet_balances::Module; +type Staking = pallet_staking::Module; +type Indices = pallet_indices::Module; +type Session = pallet_session::Module; + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + staking::Staking, + } +} + +pub struct CurrencyToVoteHandler; +impl Convert for CurrencyToVoteHandler { + fn convert(x: u64) -> u64 { + x + } +} +impl Convert for CurrencyToVoteHandler { + fn convert(x: u128) -> u64 { + x.saturated_into() + } +} + +#[derive(Clone, Eq, PartialEq, Debug)] +pub struct Test; + +impl frame_system::Trait for Test { + type Origin = Origin; + type Index = AccountIndex; + type BlockNumber = BlockNumber; + type Call = Call; + type Hash = sp_core::H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = Indices; + type Header = sp_runtime::testing::Header; + type Event = (); + type BlockHashCount = (); + type MaximumBlockWeight = (); + type AvailableBlockRatio = (); + type MaximumBlockLength = (); + type Version = (); + type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (Balances,); +} +parameter_types! { + pub const ExistentialDeposit: Balance = 10; +} +impl pallet_balances::Trait for Test { + type Balance = Balance; + type Event = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; +} +impl pallet_indices::Trait for Test { + type AccountIndex = AccountIndex; + type Event = (); + type Currency = Balances; + type Deposit = (); +} +parameter_types! { + pub const MinimumPeriod: u64 = 5; +} +impl pallet_timestamp::Trait for Test { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; +} +impl pallet_session::historical::Trait for Test { + type FullIdentification = pallet_staking::Exposure; + type FullIdentificationOf = pallet_staking::ExposureOf; +} + +sp_runtime::impl_opaque_keys! { + pub struct SessionKeys { + pub foo: sp_runtime::testing::UintAuthorityId, + } +} + +pub struct TestSessionHandler; +impl pallet_session::SessionHandler for TestSessionHandler { + const KEY_TYPE_IDS: &'static [sp_runtime::KeyTypeId] = &[]; + + fn on_genesis_session(_validators: &[(AccountId, Ks)]) {} + + fn on_new_session( + _: bool, + _: &[(AccountId, Ks)], + _: &[(AccountId, Ks)], + ) {} + + fn on_disabled(_: usize) {} +} + +impl pallet_session::Trait for Test { + type SessionManager = pallet_session::historical::NoteHistoricalRoot; + type Keys = SessionKeys; + type ShouldEndSession = pallet_session::PeriodicSessions<(), ()>; + type NextSessionRotation = pallet_session::PeriodicSessions<(), ()>; + type SessionHandler = TestSessionHandler; + type Event = (); + type ValidatorId = AccountId; + type ValidatorIdOf = pallet_staking::StashOf; + type DisabledValidatorsThreshold = (); +} +pallet_staking_reward_curve::build! { + const I_NPOS: sp_runtime::curve::PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); +} +parameter_types! { + pub const RewardCurve: &'static sp_runtime::curve::PiecewiseLinear<'static> = &I_NPOS; + pub const MaxNominatorRewardedPerValidator: u32 = 64; +} + +pub type Extrinsic = sp_runtime::testing::TestXt; +type SubmitTransaction = frame_system::offchain::TransactionSubmitter< + sp_runtime::testing::UintAuthorityId, + Test, + Extrinsic, +>; + +impl pallet_staking::Trait for Test { + type Currency = Balances; + type Time = pallet_timestamp::Module; + type CurrencyToVote = CurrencyToVoteHandler; + type RewardRemainder = (); + type Event = (); + type Slash = (); + type Reward = (); + type SessionsPerEra = (); + type SlashDeferDuration = (); + type SlashCancelOrigin = frame_system::EnsureRoot; + type BondingDuration = (); + type SessionInterface = Self; + type RewardCurve = RewardCurve; + type NextNewSession = Session; + type ElectionLookahead = (); + type Call = Call; + type SubmitTransaction = SubmitTransaction; + type KeyType = sp_runtime::testing::UintAuthorityId; + type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; +} diff --git a/frame/staking/fuzz/fuzz_targets/submit_solution.rs b/frame/staking/fuzz/fuzz_targets/submit_solution.rs new file mode 100644 index 0000000000..5d1fcf1d7e --- /dev/null +++ b/frame/staking/fuzz/fuzz_targets/submit_solution.rs @@ -0,0 +1,130 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Fuzzing for staking pallet. + +#![no_main] +use libfuzzer_sys::fuzz_target; +use mock::Test; +use pallet_staking::testing_utils::{ + self, USER, get_seq_phragmen_solution, get_weak_solution, setup_chain_stakers, + set_validator_count, signed_account, +}; +use frame_support::assert_ok; +use sp_runtime::{traits::Dispatchable, DispatchError}; + +mod mock; + +#[repr(u32)] +#[allow(dead_code)] +#[derive(Debug, Clone, Copy)] +enum Mode { + /// Initial submission. This will be rather cheap. + InitialSubmission, + /// A better submission that will replace the previous ones. This is the most expensive. + StrongerSubmission, + /// A weak submission that will be rejected. This will be rather cheap. + WeakerSubmission, +} + +pub fn new_test_ext() -> Result { + frame_system::GenesisConfig::default().build_storage::().map(Into::into) +} + +fuzz_target!(|do_reduce: bool| { + let ext = new_test_ext(); + let mode: Mode = unsafe { std::mem::transmute(testing_utils::random(0, 2)) }; + let num_validators = testing_utils::random(50, 500); + let num_nominators = testing_utils::random(200, 2000); + let edge_per_voter = testing_utils::random(1, 16); + let to_elect = testing_utils::random(10, num_validators); + + println!("+++ instance with params {} / {} / {} / {:?} / {}", + num_nominators, + num_validators, + edge_per_voter, + mode, + to_elect, + ); + + ext.unwrap_or_default().execute_with(|| { + // initial setup + set_validator_count::(to_elect); + setup_chain_stakers::( + num_validators, + num_nominators, + edge_per_voter, + ); + + println!("++ Chain setup done."); + + // stuff to submit + let (winners, compact, score) = match mode { + Mode::InitialSubmission => { + /* No need to setup anything */ + get_seq_phragmen_solution::(do_reduce) + }, + Mode::StrongerSubmission => { + let (winners, compact, score) = get_weak_solution::(false); + assert_ok!( + >::submit_election_solution( + signed_account::(USER), + winners, + compact, + score, + ) + ); + get_seq_phragmen_solution::(do_reduce) + }, + Mode::WeakerSubmission => { + let (winners, compact, score) = get_seq_phragmen_solution::(do_reduce); + assert_ok!( + >::submit_election_solution( + signed_account::(USER), + winners, + compact, + score, + ) + ); + get_weak_solution::(false) + } + }; + + println!("++ Submission ready."); + + // must have chosen correct number of winners. + assert_eq!(winners.len() as u32, >::validator_count()); + + // final call and origin + let call = pallet_staking::Call::::submit_election_solution( + winners, + compact, + score, + ); + let caller = signed_account::(USER); + + // actually submit + match mode { + Mode::WeakerSubmission => { + assert_eq!( + call.dispatch(caller.into()).unwrap_err(), + DispatchError::Module { index: 0, error: 11, message: Some("PhragmenWeakSubmission") }, + ); + }, + _ => assert_ok!(call.dispatch(caller.into())), + }; + }) +}); diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index 300e77bbda..a88c00c144 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -402,7 +402,7 @@ mod tests { #[test] fn create_validators_with_nominators_for_era_works() { - ExtBuilder::default().stakers(false).build().execute_with(|| { + ExtBuilder::default().has_stakers(false).build().execute_with(|| { let v = 10; let n = 100; @@ -418,7 +418,7 @@ mod tests { #[test] fn create_validator_with_nominators_works() { - ExtBuilder::default().stakers(false).build().execute_with(|| { + ExtBuilder::default().has_stakers(false).build().execute_with(|| { let n = 10; let validator = create_validator_with_nominators::( @@ -441,7 +441,7 @@ mod tests { #[test] fn create_nominator_with_validators_works() { - ExtBuilder::default().stakers(false).build().execute_with(|| { + ExtBuilder::default().has_stakers(false).build().execute_with(|| { let v = 5; let (nominator, validators) = create_nominator_with_validators::(v).unwrap(); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 31cbf3b8db..b19caec258 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -72,8 +72,8 @@ //! There are three possible roles that any staked account pair can be in: `Validator`, `Nominator` //! and `Idle` (defined in [`StakerStatus`](./enum.StakerStatus.html)). There are three //! corresponding instructions to change between roles, namely: -//! [`validate`](./enum.Call.html#variant.validate), [`nominate`](./enum.Call.html#variant.nominate), -//! and [`chill`](./enum.Call.html#variant.chill). +//! [`validate`](./enum.Call.html#variant.validate), +//! [`nominate`](./enum.Call.html#variant.nominate), and [`chill`](./enum.Call.html#variant.chill). //! //! #### Validating //! @@ -184,8 +184,8 @@ //! [`reward_by_indices`](./enum.Call.html#variant.reward_by_indices). //! //! [`Module`](./struct.Module.html) implements -//! [`pallet_authorship::EventHandler`](../pallet_authorship/trait.EventHandler.html) to add reward points -//! to block producer and block producer of referenced uncles. +//! [`pallet_authorship::EventHandler`](../pallet_authorship/trait.EventHandler.html) to add reward +//! points to block producer and block producer of referenced uncles. //! //! The validator and its nominator split their reward as following: //! @@ -244,40 +244,55 @@ //! ## Related Modules //! //! - [Balances](../pallet_balances/index.html): Used to manage values at stake. -//! - [Session](../pallet_session/index.html): Used to manage sessions. Also, a list of new validators -//! is stored in the Session module's `Validators` at the end of each era. +//! - [Session](../pallet_session/index.html): Used to manage sessions. Also, a list of new +//! validators is stored in the Session module's `Validators` at the end of each era. -#![recursion_limit="128"] +#![recursion_limit = "128"] #![cfg_attr(not(feature = "std"), no_std)] #[cfg(test)] mod mock; #[cfg(test)] mod tests; -mod slashing; +#[cfg(feature = "testing-utils")] +pub mod testing_utils; #[cfg(any(feature = "runtime-benchmarks", test))] pub mod benchmarking; +pub mod slashing; +pub mod offchain_election; pub mod inflation; -use sp_std::{prelude::*, result, collections::btree_map::BTreeMap}; +use sp_std::{ + result, + prelude::*, + collections::btree_map::BTreeMap, + convert::{TryInto, From}, + mem::size_of, +}; use codec::{HasCompact, Encode, Decode}; use frame_support::{ - decl_module, decl_event, decl_storage, ensure, decl_error, - dispatch::DispatchResult, storage::IterableStorageMap, traits::{ - Currency, LockIdentifier, LockableCurrency, WithdrawReasons, OnUnbalanced, Imbalance, Get, - UnixTime - }, + decl_module, decl_event, decl_storage, ensure, decl_error, debug, weights::{SimpleDispatchInfo, Weight}, + storage::IterableStorageMap, + dispatch::{IsSubType, DispatchResult}, + traits::{ + Currency, LockIdentifier, LockableCurrency, WithdrawReasons, OnUnbalanced, Imbalance, Get, + UnixTime, EstimateNextNewSession, + } }; -use pallet_session::historical::SessionManager; +use pallet_session::historical; use sp_runtime::{ - Perbill, PerThing, RuntimeDebug, + Perbill, PerU16, PerThing, RuntimeDebug, curve::PiecewiseLinear, traits::{ - Convert, Zero, StaticLookup, CheckedSub, Saturating, SaturatedConversion, - AtLeast32Bit, EnsureOrigin, - } + Convert, Zero, StaticLookup, CheckedSub, Saturating, SaturatedConversion, AtLeast32Bit, + EnsureOrigin, SignedExtension, + }, + transaction_validity::{ + TransactionValidityError, TransactionValidity, ValidTransaction, InvalidTransaction, + TransactionSource, + }, }; use sp_staking::{ SessionIndex, @@ -285,14 +300,33 @@ use sp_staking::{ }; #[cfg(feature = "std")] use sp_runtime::{Serialize, Deserialize}; -use frame_system::{self as system, ensure_signed, ensure_root}; - -use sp_phragmen::ExtendedBalance; +use frame_system::{ + self as system, ensure_signed, ensure_root, ensure_none, + offchain::SubmitUnsignedTransaction, +}; +use sp_phragmen::{ + ExtendedBalance, Assignment, PhragmenScore, PhragmenResult, build_support_map, evaluate_support, + elect, generate_compact_solution_type, is_score_better, VotingLimit, SupportMap, +}; const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4; -pub const MAX_NOMINATIONS: usize = 16; -const MAX_UNLOCKING_CHUNKS: usize = 32; const STAKING_ID: LockIdentifier = *b"staking "; +pub const MAX_UNLOCKING_CHUNKS: usize = 32; +pub const MAX_NOMINATIONS: usize = ::LIMIT; + +/// Data type used to index nominators in the compact type +pub type NominatorIndex = u32; + +/// Data type used to index validators in the compact type. +pub type ValidatorIndex = u16; + +// Ensure the size of both ValidatorIndex and NominatorIndex. They both need to be well below usize. +static_assertions::const_assert!(size_of::() <= size_of::()); +static_assertions::const_assert!(size_of::() <= size_of::()); + +/// Maximum number of stakers that can be stored in a snapshot. +pub(crate) const MAX_VALIDATORS: usize = ValidatorIndex::max_value() as usize; +pub(crate) const MAX_NOMINATORS: usize = NominatorIndex::max_value() as usize; /// Counter for the number of eras that have passed. pub type EraIndex = u32; @@ -300,6 +334,9 @@ pub type EraIndex = u32; /// Counter for the number of "reward" points earned by a given validator. pub type RewardPoint = u32; +// Note: Maximum nomination limit is set here -- 16. +generate_compact_solution_type!(pub GenericCompactAssignments, 16); + /// Information regarding the active era (era in used in session). #[derive(Encode, Decode, RuntimeDebug)] pub struct ActiveEraInfo { @@ -312,6 +349,25 @@ pub struct ActiveEraInfo { start: Option, } +/// Accuracy used for on-chain phragmen. +pub type ChainAccuracy = Perbill; + +/// Accuracy used for off-chain phragmen. This better be small. +pub type OffchainAccuracy = PerU16; + +/// The balance type of this module. +pub type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + +/// The compact type for election solutions. +pub type CompactAssignments = + GenericCompactAssignments; + +type PositiveImbalanceOf = + <::Currency as Currency<::AccountId>>::PositiveImbalance; +type NegativeImbalanceOf = + <::Currency as Currency<::AccountId>>::NegativeImbalance; + /// Reward points of an era. Used to split era total payout between validators. /// /// This points will be used to reward validators and their respective nominators. @@ -560,12 +616,61 @@ pub struct UnappliedSlash { payout: Balance, } -pub type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; -type PositiveImbalanceOf = - <::Currency as Currency<::AccountId>>::PositiveImbalance; -type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; +/// Indicate how an election round was computed. +#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, RuntimeDebug)] +pub enum ElectionCompute { + /// Result was forcefully computed on chain at the end of the session. + OnChain, + /// Result was submitted and accepted to the chain via a signed transaction. + Signed, + /// Result was submitted and accepted to the chain via an unsigned transaction (by an + /// authority). + Unsigned, +} + +/// The result of an election round. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub struct ElectionResult { + /// Flat list of validators who have been elected. + elected_stashes: Vec, + /// Flat list of new exposures, to be updated in the [`Exposure`] storage. + exposures: Vec<(AccountId, Exposure)>, + /// Type of the result. This is kept on chain only to track and report the best score's + /// submission type. An optimisation could remove this. + compute: ElectionCompute, +} + +/// The status of the upcoming (offchain) election. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub enum ElectionStatus { + /// Nothing has and will happen for now. submission window is not open. + Closed, + /// The submission window has been open since the contained block number. + Open(BlockNumber), +} + +impl ElectionStatus { + fn is_open_at(&self, n: BlockNumber) -> bool { + *self == Self::Open(n) + } + + fn is_closed(&self) -> bool { + match self { + Self::Closed => true, + _ => false + } + } + + fn is_open(&self) -> bool { + !self.is_closed() + } +} + +impl Default for ElectionStatus { + fn default() -> Self { + Self::Closed + } +} /// Means for interacting with a specialized version of the `session` trait. /// @@ -591,7 +696,8 @@ impl SessionInterface<::AccountId> for T whe >, T::SessionHandler: pallet_session::SessionHandler<::AccountId>, T::SessionManager: pallet_session::SessionManager<::AccountId>, - T::ValidatorIdOf: Convert<::AccountId, Option<::AccountId>> + T::ValidatorIdOf: + Convert<::AccountId, Option<::AccountId>>, { fn disable_validator(validator: &::AccountId) -> Result { >::disable(validator) @@ -655,6 +761,20 @@ pub trait Trait: frame_system::Trait { /// The NPoS reward curve to use. type RewardCurve: Get<&'static PiecewiseLinear<'static>>; + /// Something that can estimate the next session change, accurately or as a best effort guess. + type NextNewSession: EstimateNextNewSession; + + /// How many blocks ahead of the era, within the last do we try to run the phragmen offchain? + /// Setting this to zero will disable the offchain compute and only on-chain seq-phragmen will + /// be used. + type ElectionLookahead: Get; + + /// The overarching call type. + type Call: From> + IsSubType, Self> + Clone; + + /// A transaction submitter. + type SubmitTransaction: SubmitUnsignedTransaction::Call>; + /// The maximum number of nominator rewarded for each validator. /// /// For each validator only the `$MaxNominatorRewardedPerValidator` biggest stakers can claim @@ -805,7 +925,7 @@ decl_storage! { pub ErasTotalStake get(fn eras_total_stake): map hasher(twox_64_concat) EraIndex => BalanceOf; - /// True if the next session change will be a new era regardless of index. + /// Mode of era forcing. pub ForceEra get(fn force_era) config(): Forcing; /// The percentage of the slash that is distributed to reporters. @@ -850,6 +970,30 @@ decl_storage! { /// The earliest era for which we have a pending, unapplied slash. EarliestUnappliedSlash: Option; + /// Snapshot of validators at the beginning of the current election window. This should only + /// have a value when [`EraElectionStatus`] == `ElectionStatus::Open(_)`. + pub SnapshotValidators get(fn snapshot_validators): Option>; + + /// Snapshot of nominators at the beginning of the current election window. This should only + /// have a value when [`EraElectionStatus`] == `ElectionStatus::Open(_)`. + pub SnapshotNominators get(fn snapshot_nominators): Option>; + + /// The next validator set. At the end of an era, if this is available (potentially from the + /// result of an offchain worker), it is immediately used. Otherwise, the on-chain election + /// is executed. + pub QueuedElected get(fn queued_elected): Option>>; + + /// The score of the current [`QueuedElected`]. + pub QueuedScore get(fn queued_score): Option; + + /// Flag to control the execution of the offchain election. When `Open(_)`, we accept + /// solutions to be submitted. + pub EraElectionStatus get(fn era_election_status): ElectionStatus; + + /// True if the current planned session is final. + pub IsCurrentSessionFinal get(fn is_current_session_final): bool = false; + + /// True if network has been upgraded to this version. /// Storage version of the pallet. /// /// This is set to v3.0.0 for new networks. @@ -898,6 +1042,8 @@ decl_event!( /// An old slashing report from a prior era was discarded because it could /// not be processed. OldSlashingReportDiscarded(SessionIndex), + /// A new set of stakers was elected with the given computation method. + StakingElection(ElectionCompute), /// An account has bonded this amount. /// /// NOTE: This event is only emitted when funds are bonded via a dispatchable. Notably, @@ -942,6 +1088,33 @@ decl_error! { InvalidNumberOfNominations, /// Items are not sorted and unique. NotSortedAndUnique, + /// The submitted result is received out of the open window. + PhragmenEarlySubmission, + /// The submitted result is not as good as the one stored on chain. + PhragmenWeakSubmission, + /// The snapshot data of the current window is missing. + SnapshotUnavailable, + /// Incorrect number of winners were presented. + PhragmenBogusWinnerCount, + /// One of the submitted winners is not an active candidate on chain (index is out of range + /// in snapshot). + PhragmenBogusWinner, + /// Error while building the assignment type from the compact. This can happen if an index + /// is invalid, or if the weights _overflow_. + PhragmenBogusCompact, + /// One of the submitted nominators is not an active nominator on chain. + PhragmenBogusNominator, + /// One of the submitted nominators has an edge to which they have not voted on chain. + PhragmenBogusNomination, + /// One of the submitted nominators has an edge which is submitted before the last non-zero + /// slash of the target. + PhragmenSlashedNomination, + /// A self vote must only be originated from a validator to ONLY themselves. + PhragmenBogusSelfVote, + /// The submitted result has unknown edges that are not among the presented winners. + PhragmenBogusEdge, + /// The claimed score does not match with the one computed from the data. + PhragmenBogusScore, } } @@ -957,6 +1130,84 @@ decl_module! { fn deposit_event() = default; + /// sets `ElectionStatus` to `Open(now)` where `now` is the block number at which the + /// election window has opened, if we are at the last session and less blocks than + /// `T::ElectionLookahead` is remaining until the next new session schedule. The offchain + /// worker, if applicable, will execute at the end of the current block, and solutions may + /// be submitted. + fn on_initialize(now: T::BlockNumber) -> Weight { + if + // if we don't have any ongoing offchain compute. + Self::era_election_status().is_closed() && + Self::is_current_session_final() + { + if let Some(next_session_change) = T::NextNewSession::estimate_next_new_session(now){ + if let Some(remaining) = next_session_change.checked_sub(&now) { + if remaining <= T::ElectionLookahead::get() && !remaining.is_zero() { + // create snapshot. + if Self::create_stakers_snapshot() { + // Set the flag to make sure we don't waste any compute here in the same era + // after we have triggered the offline compute. + >::put( + ElectionStatus::::Open(now) + ); + debug::native::info!( + target: "staking", + "Election window is Open({:?}). Snapshot created", + now, + ); + } else { + debug::native::warn!( + target: "staking", + "Failed to create snapshot at {:?}. Election window will remain closed.", + now, + ); + } + + } + } + } else { + debug::native::warn!( + target: "staking", + "estimate_next_new_session() failed to execute. Election status cannot be changed.", + ); + } + } + + // weight + 50_000 + } + + /// Check if the current block number is the one at which the election window has been set + /// to open. If so, it runs the offchain worker code. + fn offchain_worker(now: T::BlockNumber) { + use offchain_election::{set_check_offchain_execution_status, compute_offchain_election}; + + if Self::era_election_status().is_open_at(now) { + let offchain_status = set_check_offchain_execution_status::(now); + if let Err(why) = offchain_status { + debug::native::warn!( + target: "staking", + "skipping offchain worker in open election window due to [{}]", + why, + ); + } else { + if let Err(e) = compute_offchain_election::() { + debug::native::warn!( + target: "staking", + "Error in phragmen offchain worker: {:?}", + e, + ); + } else { + debug::native::debug!( + target: "staking", + "Executed offchain worker thread without errors. Transaction submitted to the pool.", + ); + } + } + } + } + fn on_finalize() { // Set the start of the first era. if let Some(mut active_era) = Self::active_era() { @@ -989,14 +1240,14 @@ decl_module! { /// - O(1). /// - Three extra DB entries. /// - /// NOTE: Two of the storage writes (`Self::bonded`, `Self::payee`) are _never_ cleaned unless - /// the `origin` falls below _existential deposit_ and gets removed as dust. + /// NOTE: Two of the storage writes (`Self::bonded`, `Self::payee`) are _never_ cleaned + /// unless the `origin` falls below _existential deposit_ and gets removed as dust. /// # #[weight = SimpleDispatchInfo::FixedNormal(500_000)] fn bond(origin, controller: ::Source, #[compact] value: BalanceOf, - payee: RewardDestination + payee: RewardDestination, ) { let stash = ensure_signed(origin)?; @@ -1199,7 +1450,7 @@ decl_module! { /// /// # /// - The transaction's complexity is proportional to the size of `targets`, - /// which is capped at `MAX_NOMINATIONS`. + /// which is capped at CompactAssignments::LIMIT. /// - Both the reads and writes follow a similar pattern. /// # #[weight = SimpleDispatchInfo::FixedNormal(750_000)] @@ -1209,7 +1460,7 @@ decl_module! { let stash = &ledger.stash; ensure!(!targets.is_empty(), Error::::EmptyTargets); let targets = targets.into_iter() - .take(MAX_NOMINATIONS) + .take(::LIMIT) .map(|t| T::Lookup::lookup(t)) .collect::, _>>()?; @@ -1483,18 +1734,179 @@ decl_module! { Self::kill_stash(&stash)?; T::Currency::remove_lock(STAKING_ID, &stash); } + + /// Submit a phragmen result to the chain. If the solution: + /// + /// 1. is valid. + /// 2. has a better score than a potentially existing solution on chain. + /// + /// then, it will be _put_ on chain. + /// + /// A solution consists of two pieces of data: + /// + /// 1. `winners`: a flat vector of all the winners of the round. + /// 2. `assignments`: the compact version of an assignment vector that encodes the edge + /// weights. + /// + /// Both of which may be computed using [`phragmen`], or any other algorithm. + /// + /// Additionally, the submitter must provide: + /// + /// - The `score` that they claim their solution has. + /// + /// Both validators and nominators will be represented by indices in the solution. The + /// indices should respect the corresponding types ([`ValidatorIndex`] and + /// [`NominatorIndex`]). Moreover, they should be valid when used to index into + /// [`SnapshotValidators`] and [`SnapshotNominators`]. Any invalid index will cause the + /// solution to be rejected. These two storage items are set during the election window and + /// may be used to determine the indices. + /// + /// A solution is valid if: + /// + /// 0. It is submitted when [`EraElectionStatus`] is `Open`. + /// 1. Its claimed score is equal to the score computed on-chain. + /// 2. Presents the correct number of winners. + /// 3. All indexes must be value according to the snapshot vectors. All edge values must + /// also be correct and should not overflow the granularity of the ratio type (i.e. 256 + /// or billion). + /// 4. For each edge, all targets are actually nominated by the voter. + /// 5. Has correct self-votes. + /// + /// A solutions score is consisted of 3 parameters: + /// + /// 1. `min { support.total }` for each support of a winner. This value should be maximized. + /// 2. `sum { support.total }` for each support of a winner. This value should be minimized. + /// 3. `sum { support.total^2 }` for each support of a winner. This value should be + /// minimized (to ensure less variance) + /// + /// # + /// E: number of edges. m: size of winner committee. n: number of nominators. d: edge degree + /// (16 for now) v: number of on-chain validator candidates. + /// + /// NOTE: given a solution which is reduced, we can enable a new check the ensure `|E| < n + + /// m`. We don't do this _yet_, but our offchain worker code executes it nonetheless. + /// + /// major steps (all done in `check_and_replace_solution`): + /// + /// - Storage: O(1) read `ElectionStatus`. + /// - Storage: O(1) read `PhragmenScore`. + /// - Storage: O(1) read `ValidatorCount`. + /// - Storage: O(1) length read from `SnapshotValidators`. + /// + /// - Storage: O(v) reads of `AccountId` to fetch `snapshot_validators`. + /// - Memory: O(m) iterations to map winner index to validator id. + /// - Storage: O(n) reads `AccountId` to fetch `snapshot_nominators`. + /// - Memory: O(n + m) reads to map index to `AccountId` for un-compact. + /// + /// - Storage: O(e) accountid reads from `Nomination` to read correct nominations. + /// - Storage: O(e) calls into `slashable_balance_of_extended` to convert ratio to staked. + /// + /// - Memory: build_support_map. O(e). + /// - Memory: evaluate_support: O(E). + /// + /// - Storage: O(e) writes to `QueuedElected`. + /// - Storage: O(1) write to `QueuedScore` + /// + /// The weight of this call is 1/10th of the blocks total weight. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + pub fn submit_election_solution( + origin, + winners: Vec, + compact_assignments: CompactAssignments, + score: PhragmenScore, + era: EraIndex, + ) { + let _who = ensure_signed(origin)?; + Self::check_and_replace_solution( + winners, + compact_assignments, + ElectionCompute::Signed, + score, + era, + )? + } + + /// Unsigned version of `submit_election_solution`. + /// + /// Note that this must pass the [`ValidateUnsigned`] check which only allows transactions + /// from the local node to be included. In other words, only the block author can include a + /// transaction in the block. + #[weight = SimpleDispatchInfo::FixedNormal(100_000_000)] + pub fn submit_election_solution_unsigned( + origin, + winners: Vec, + compact_assignments: CompactAssignments, + score: PhragmenScore, + era: EraIndex, + ) { + ensure_none(origin)?; + Self::check_and_replace_solution( + winners, + compact_assignments, + ElectionCompute::Unsigned, + score, + era, + )? + // TODO: instead of returning an error, panic. This makes the entire produced block + // invalid. + // This ensures that block authors will not ever try and submit a solution which is not + // an improvement, since they will lose their authoring points/rewards. + } } } impl Module { - // PUBLIC IMMUTABLES - /// The total balance that can be slashed from a stash account as of right now. pub fn slashable_balance_of(stash: &T::AccountId) -> BalanceOf { Self::bonded(stash).and_then(Self::ledger).map(|l| l.active).unwrap_or_default() } - // MUTABLES (DANGEROUS) + /// internal impl of [`slashable_balance_of`] that returns [`ExtendedBalance`]. + fn slashable_balance_of_extended(stash: &T::AccountId) -> ExtendedBalance { + , u64>>::convert( + Self::slashable_balance_of(stash) + ) as ExtendedBalance + } + + /// Dump the list of validators and nominators into vectors and keep them on-chain. + /// + /// This data is used to efficiently evaluate election results. returns `true` if the operation + /// is successful. + fn create_stakers_snapshot() -> bool { + let validators = >::iter().map(|(v, _)| v).collect::>(); + let mut nominators = >::iter().map(|(n, _)| n).collect::>(); + + let num_validators = validators.len(); + let num_nominators = nominators.len(); + if + num_validators > MAX_VALIDATORS || + num_nominators.saturating_add(num_validators) > MAX_NOMINATORS + { + debug::native::warn!( + target: "staking", + "Snapshot size too big [{} <> {}][{} <> {}].", + num_validators, + MAX_VALIDATORS, + num_nominators, + MAX_NOMINATORS, + ); + false + } else { + // all validators nominate themselves; + nominators.extend(validators.clone()); + + >::put(validators); + >::put(nominators); + true + } + } + + /// Clears both snapshots of stakers. + fn kill_stakers_snapshot() { + >::kill(); + >::kill(); + } fn do_payout_nominator(who: T::AccountId, era: EraIndex, validators: Vec<(T::AccountId, u32)>) -> DispatchResult @@ -1663,9 +2075,17 @@ impl Module { Forcing::ForceNew => ForceEra::kill(), Forcing::ForceAlways => (), Forcing::NotForcing if era_length >= T::SessionsPerEra::get() => (), - _ => return None, + _ => { + // not forcing, not a new era either. If final, set the flag. + if era_length + 1 >= T::SessionsPerEra::get() { + IsCurrentSessionFinal::put(true); + } + return None + }, } + // new era. + IsCurrentSessionFinal::put(false); Self::new_era(session_index) } else { // Set initial era @@ -1673,6 +2093,188 @@ impl Module { } } + /// Basic and cheap checks that we perform in validate unsigned, and in the execution. + pub fn pre_dispatch_checks(score: PhragmenScore, era: EraIndex) -> Result<(), Error> { + // discard solutions that are not in-time + // check window open + ensure!( + Self::era_election_status().is_open(), + Error::::PhragmenEarlySubmission, + ); + + // check current era. + if let Some(current_era) = Self::active_era().map(|e| e.index) { + ensure!( + current_era == era, + Error::::PhragmenEarlySubmission, + ) + } + + // assume the given score is valid. Is it better than what we have on-chain, if we have any? + if let Some(queued_score) = Self::queued_score() { + ensure!( + is_score_better(queued_score, score), + Error::::PhragmenWeakSubmission, + ) + } + + Ok(()) + } + + /// Checks a given solution and if correct and improved, writes it on chain as the queued result + /// of the next round. This may be called by both a signed and an unsigned transaction. + pub fn check_and_replace_solution( + winners: Vec, + compact_assignments: CompactAssignments, + compute: ElectionCompute, + claimed_score: PhragmenScore, + era: EraIndex, + ) -> Result<(), Error> { + // Do the basic checks. era, claimed score and window open. + Self::pre_dispatch_checks(claimed_score, era)?; + + // Check that the number of presented winners is sane. Most often we have more candidates + // that we need. Then it should be Self::validator_count(). Else it should be all the + // candidates. + let snapshot_length = >::decode_len() + .map_err(|_| Error::::SnapshotUnavailable)?; + let desired_winners = Self::validator_count().min(snapshot_length as u32); + ensure!(winners.len() as u32 == desired_winners, Error::::PhragmenBogusWinnerCount); + + // decode snapshot validators. + let snapshot_validators = Self::snapshot_validators() + .ok_or(Error::::SnapshotUnavailable)?; + + // check if all winners were legit; this is rather cheap. Replace with accountId. + let winners = winners.into_iter().map(|widx| { + // NOTE: at the moment, since staking is explicitly blocking any offence until election + // is closed, we don't check here if the account id at `snapshot_validators[widx]` is + // actually a validator. If this ever changes, this loop needs to also check this. + snapshot_validators.get(widx as usize).cloned().ok_or(Error::::PhragmenBogusWinner) + }).collect::, Error>>()?; + + // decode the rest of the snapshot. + let snapshot_nominators = >::snapshot_nominators() + .ok_or(Error::::SnapshotUnavailable)?; + + // helpers + let nominator_at = |i: NominatorIndex| -> Option { + snapshot_nominators.get(i as usize).cloned() + }; + let validator_at = |i: ValidatorIndex| -> Option { + snapshot_validators.get(i as usize).cloned() + }; + + // un-compact. + let assignments = compact_assignments.into_assignment( + nominator_at, + validator_at, + ).map_err(|e| { + // log the error since it is not propagated into the runtime error. + debug::native::warn!( + target: "staking", + "un-compacting solution failed due to {:?}", + e, + ); + Error::::PhragmenBogusCompact + })?; + + // check all nominators actually including the claimed vote. Also check correct self votes. + // Note that we assume all validators and nominators in `assignments` are properly bonded, + // because they are coming from the snapshot via a given index. + for Assignment { who, distribution } in assignments.iter() { + let is_validator = >::contains_key(&who); + let maybe_nomination = Self::nominators(&who); + + if !(maybe_nomination.is_some() ^ is_validator) { + // all of the indices must map to either a validator or a nominator. If this is ever + // not the case, then the locking system of staking is most likely faulty, or we + // have bigger problems. + debug::native::error!( + target: "staking", + "detected an error in the staking locking and snapshot." + ); + // abort. + return Err(Error::::PhragmenBogusNominator); + } + + if !is_validator { + // a normal vote + let nomination = maybe_nomination.expect( + "exactly one of `maybe_validator` and `maybe_nomination.is_some` is true. \ + is_validator is false; maybe_nomination is some; qed" + ); + + // NOTE: we don't really have to check here if the sum of all edges are the + // nominator correct. Un-compacting assures this by definition. + + for (t, _) in distribution { + // each target in the provided distribution must be actually nominated by the + // nominator after the last non-zero slash. + if nomination.targets.iter().find(|&tt| tt == t).is_none() { + return Err(Error::::PhragmenBogusNomination); + } + + if ::SlashingSpans::get(&t).map_or( + false, + |spans| nomination.submitted_in < spans.last_nonzero_slash(), + ) { + return Err(Error::::PhragmenSlashedNomination); + } + } + } else { + // a self vote + ensure!(distribution.len() == 1, Error::::PhragmenBogusSelfVote); + ensure!(distribution[0].0 == *who, Error::::PhragmenBogusSelfVote); + // defensive only. A compact assignment of length one does NOT encode the weight and + // it is always created to be 100%. + ensure!( + distribution[0].1 == OffchainAccuracy::one(), + Error::::PhragmenBogusSelfVote, + ); + } + } + + // convert into staked assignments. + let staked_assignments = sp_phragmen::assignment_ratio_to_staked( + assignments, + Self::slashable_balance_of_extended, + ); + + // build the support map thereof in order to evaluate. + // OPTIMIZATION: loop to create the staked assignments but it would bloat the code. Okay for + // now as it does not add to the complexity order. + let (supports, num_error) = build_support_map::( + &winners, + &staked_assignments, + ); + // This technically checks that all targets in all nominators were among the winners. + ensure!(num_error == 0, Error::::PhragmenBogusEdge); + + // Check if the score is the same as the claimed one. + let submitted_score = evaluate_support(&supports); + ensure!(submitted_score == claimed_score, Error::::PhragmenBogusScore); + + // At last, alles Ok. Exposures and store the result. + let exposures = Self::collect_exposure(supports); + debug::native::info!( + target: "staking", + "A better solution (with compute {:?}) has been validated and stored on chain.", + compute, + ); + + // write new results. + >::put(ElectionResult { + elected_stashes: winners, + compute, + exposures, + }); + QueuedScore::put(submitted_score); + + Ok(()) + + } + /// Start a session potentially starting an era. fn start_session(start_session: SessionIndex) { let next_active_era = Self::active_era().map(|e| e.index + 1).unwrap_or(0); @@ -1779,55 +2381,160 @@ impl Module { } // Set staking information for new era. - let maybe_new_validators = Self::select_validators(current_era); + let maybe_new_validators = Self::select_and_update_validators(current_era); maybe_new_validators } - /// Clear all era information for given era. - fn clear_era_information(era_index: EraIndex) { - >::remove_prefix(era_index); - >::remove_prefix(era_index); - >::remove_prefix(era_index); - >::remove(era_index); - >::remove(era_index); - >::remove(era_index); - ErasStartSessionIndex::remove(era_index); - } + /// Select the new validator set at the end of the era. + /// + /// Runs [`try_do_phragmen`] and updates the following storage items: + /// - [`EraElectionStatus`]: with `None`. + /// - [`ErasStakers`]: with the new staker set. + /// - [`ErasStakersClipped`]. + /// - [`ErasValidatorPrefs`]. + /// - [`ErasTotalStake`]: with the new total stake. + /// - [`SnapshotValidators`] and [`SnapshotNominators`] are both removed. + /// + /// Internally, [`QueuedElected`], snapshots and [`QueuedScore`] are also consumed. + /// + /// If the election has been successful, It passes the new set upwards. + /// + /// This should only be called at the end of an era. + fn select_and_update_validators(current_era: EraIndex) -> Option> { + if let Some(ElectionResult::> { + elected_stashes, + exposures, + compute, + }) = Self::try_do_phragmen() { + // We have chosen the new validator set. Submission is no longer allowed. + >::put(ElectionStatus::Closed); + + // kill the snapshots. + Self::kill_stakers_snapshot(); + + // Populate Stakers and write slot stake. + let mut total_stake: BalanceOf = Zero::zero(); + exposures.into_iter().for_each(|(stash, exposure)| { + total_stake = total_stake.saturating_add(exposure.total); + >::insert(current_era, &stash, &exposure); - /// Apply previously-unapplied slashes on the beginning of a new era, after a delay. - fn apply_unapplied_slashes(active_era: EraIndex) { - let slash_defer_duration = T::SlashDeferDuration::get(); - ::EarliestUnappliedSlash::mutate(|earliest| if let Some(ref mut earliest) = earliest { - let keep_from = active_era.saturating_sub(slash_defer_duration); - for era in (*earliest)..keep_from { - let era_slashes = ::UnappliedSlashes::take(&era); - for slash in era_slashes { - slashing::apply_slash::(slash); + let mut exposure_clipped = exposure; + let clipped_max_len = T::MaxNominatorRewardedPerValidator::get() as usize; + if exposure_clipped.others.len() > clipped_max_len { + exposure_clipped.others.sort_unstable_by(|a, b| a.value.cmp(&b.value).reverse()); + exposure_clipped.others.truncate(clipped_max_len); } + >::insert(¤t_era, &stash, exposure_clipped); + }); + + // Insert current era staking information + >::insert(¤t_era, total_stake); + + // collect the pref of all winners + for stash in &elected_stashes { + let pref = Self::validators(stash); + >::insert(¤t_era, stash, pref); } - *earliest = (*earliest).max(keep_from) - }) + // emit event + Self::deposit_event(RawEvent::StakingElection(compute)); + + debug::native::info!( + target: "staking", + "new validator set of size {:?} has been elected via {:?} for era {:?}", + elected_stashes.len(), + compute, + current_era, + ); + + Some(elected_stashes) + } else { + None + } + } + + /// Select a new validator set from the assembled stakers and their role preferences. It tries + /// first to peek into [`QueuedElected`]. Otherwise, it runs a new phragmen. + /// + /// If [`QueuedElected`] and [`QueuedScore`] exists, they are both removed. No further storage + /// is updated. + fn try_do_phragmen() -> Option>> { + // a phragmen result from either a stored submission or locally executed one. + let next_result = >::take().or_else(|| + Self::do_phragmen_with_post_processing::(ElectionCompute::OnChain) + ); + + // either way, kill this. We remove it here to make sure it always has the exact same + // lifetime as `QueuedElected`. + QueuedScore::kill(); + + next_result } - /// Select a new validator set from the assembled stakers and their role preferences, and store - /// staking information for the new current era. + /// Execute phragmen and return the new results. The edge weights are processed into support + /// values. + /// + /// This is basically a wrapper around [`do_phragmen`] which translates `PhragmenResult` into + /// `ElectionResult`. /// - /// Fill the storages `ErasStakers`, `ErasStakersClipped`, `ErasValidatorPrefs` and - /// `ErasTotalStake` for current era. + /// No storage item is updated. + fn do_phragmen_with_post_processing(compute: ElectionCompute) + -> Option>> + where + Accuracy: sp_std::ops::Mul, + ExtendedBalance: From<::Inner>, + { + if let Some(phragmen_result) = Self::do_phragmen::() { + let elected_stashes = phragmen_result.winners.iter() + .map(|(s, _)| s.clone()) + .collect::>(); + let assignments = phragmen_result.assignments; + + let staked_assignments = sp_phragmen::assignment_ratio_to_staked( + assignments, + Self::slashable_balance_of_extended, + ); + + let (supports, _) = build_support_map::( + &elected_stashes, + &staked_assignments, + ); + + // collect exposures + let exposures = Self::collect_exposure(supports); + + // In order to keep the property required by `on_session_ending` that we must return the + // new validator set even if it's the same as the old, as long as any underlying + // economic conditions have changed, we don't attempt to do any optimization where we + // compare against the prior set. + Some(ElectionResult::> { + elected_stashes, + exposures, + compute, + }) + } else { + // There were not enough candidates for even our minimal level of functionality. This is + // bad. We should probably disable all functionality except for block production and let + // the chain keep producing blocks until we can decide on a sufficiently substantial + // set. TODO: #2494 + None + } + } + + /// Execute phragmen and return the new results. No post-processing is applied and the raw edge + /// weights are returned. /// - /// Returns a set of newly selected _stash_ IDs. + /// Self votes are added and nominations before the most recent slashing span are reaped. /// - /// Assumes storage is coherent with the declaration. - fn select_validators(current_era: EraIndex) -> Option> { + /// No storage item is updated. + fn do_phragmen() -> Option> { let mut all_nominators: Vec<(T::AccountId, BalanceOf, Vec)> = Vec::new(); - let mut all_validators_and_prefs = BTreeMap::new(); let mut all_validators = Vec::new(); - for (validator, preference) in >::iter() { + for (validator, _) in >::iter() { + // append self vote let self_vote = (validator.clone(), Self::slashable_balance_of(&validator), vec![validator.clone()]); all_nominators.push(self_vote); - all_validators_and_prefs.insert(validator.clone(), preference); all_validators.push(validator); } @@ -1835,7 +2542,7 @@ impl Module { let Nominations { submitted_in, mut targets, suppressed: _ } = nominations; // Filter out nomination targets which were nominated before the most recent - // non-zero slash. + // slashing span. targets.retain(|stash| { ::SlashingSpans::get(&stash).map_or( true, @@ -1850,92 +2557,44 @@ impl Module { (n, s, ns) })); - let maybe_phragmen_result = sp_phragmen::elect::<_, _, T::CurrencyToVote, Perbill>( + elect::<_, _, T::CurrencyToVote, Accuracy>( Self::validator_count() as usize, Self::minimum_validator_count().max(1) as usize, all_validators, all_nominators, - ); - - if let Some(phragmen_result) = maybe_phragmen_result { - let elected_stashes = phragmen_result.winners.into_iter() - .map(|(s, _)| s) - .collect::>(); - let assignments = phragmen_result.assignments; - - let to_balance = |e: ExtendedBalance| - >>::convert(e); - - let supports = sp_phragmen::build_support_map::<_, _, _, T::CurrencyToVote, Perbill>( - &elected_stashes, - &assignments, - Self::slashable_balance_of, - ); - - // Populate stakers information and figure out the total stake. - let mut total_staked = BalanceOf::::zero(); - for (c, s) in supports.into_iter() { - // build `struct exposure` from `support` - let mut others = Vec::new(); - let mut own: BalanceOf = Zero::zero(); - let mut total: BalanceOf = Zero::zero(); - s.voters - .into_iter() - .map(|(who, value)| (who, to_balance(value))) - .for_each(|(who, value)| { - if who == c { - own = own.saturating_add(value); - } else { - others.push(IndividualExposure { who, value }); - } - total = total.saturating_add(value); - }); - - total_staked = total_staked.saturating_add(total); - - let exposure = Exposure { - own, - others, - // This might reasonably saturate and we cannot do much about it. The sum of - // someone's stake might exceed the balance type if they have the maximum amount - // of balance and receive some support. This is super unlikely to happen, yet - // we simulate it in some tests. - total, - }; - >::insert(¤t_era, &c, &exposure); + ) + } - let mut exposure_clipped = exposure; - let clipped_max_len = T::MaxNominatorRewardedPerValidator::get() as usize; - if exposure_clipped.others.len() > clipped_max_len { - exposure_clipped.others.sort_unstable_by(|a, b| a.value.cmp(&b.value).reverse()); - exposure_clipped.others.truncate(clipped_max_len); - } - >::insert(¤t_era, &c, exposure_clipped); - } + /// Consume a set of [`Supports`] from [`sp_phragmen`] and collect them into a [`Exposure`] + fn collect_exposure(supports: SupportMap) -> Vec<(T::AccountId, Exposure>)> { + let to_balance = |e: ExtendedBalance| + >>::convert(e); + + supports.into_iter().map(|(validator, support)| { + // build `struct exposure` from `support` + let mut others = Vec::new(); + let mut own: BalanceOf = Zero::zero(); + let mut total: BalanceOf = Zero::zero(); + support.voters + .into_iter() + .map(|(nominator, weight)| (nominator, to_balance(weight))) + .for_each(|(nominator, stake)| { + if nominator == validator { + own = own.saturating_add(stake); + } else { + others.push(IndividualExposure { who: nominator, value: stake }); + } + total = total.saturating_add(stake); + }); - // Insert current era staking informations - >::insert(¤t_era, total_staked); - let default_pref = ValidatorPrefs::default(); - for stash in &elected_stashes { - let pref = all_validators_and_prefs.get(stash) - .unwrap_or(&default_pref); // Must never happen, but better to be safe. - >::insert(¤t_era, stash, pref); - } + let exposure = Exposure { + own, + others, + total, + }; - // In order to keep the property required by `n_session_ending` - // that we must return the new validator set even if it's the same as the old, - // as long as any underlying economic conditions have changed, we don't attempt - // to do any optimization where we compare against the prior set. - Some(elected_stashes) - } else { - // There were not enough candidates for even our minimal level of functionality. - // This is bad. - // We should probably disable all functionality except for block production - // and let the chain keep producing blocks until we can decide on a sufficiently - // substantial set. - // TODO: #2494 - None - } + (validator, exposure) + }).collect::)>>() } /// Remove all associated data of a stash account from the staking system. @@ -1960,6 +2619,33 @@ impl Module { Ok(()) } + /// Clear all era information for given era. + fn clear_era_information(era_index: EraIndex) { + >::remove_prefix(era_index); + >::remove_prefix(era_index); + >::remove_prefix(era_index); + >::remove(era_index); + >::remove(era_index); + >::remove(era_index); + ErasStartSessionIndex::remove(era_index); + } + + /// Apply previously-unapplied slashes on the beginning of a new era, after a delay. + fn apply_unapplied_slashes(active_era: EraIndex) { + let slash_defer_duration = T::SlashDeferDuration::get(); + ::EarliestUnappliedSlash::mutate(|earliest| if let Some(ref mut earliest) = earliest { + let keep_from = active_era.saturating_sub(slash_defer_duration); + for era in (*earliest)..keep_from { + let era_slashes = ::UnappliedSlashes::take(&era); + for slash in era_slashes { + slashing::apply_slash::(slash); + } + } + + *earliest = (*earliest).max(keep_from) + }) + } + /// Add reward points to validators using their stash account ID. /// /// Validators are keyed by stash account ID and must be in the current elected set. @@ -2011,9 +2697,7 @@ impl pallet_session::SessionManager for Module { } } -/// This implementation has the same constrains as the implementation of -/// `pallet_session::SessionManager`. -impl SessionManager>> for Module { +impl historical::SessionManager>> for Module { fn new_session(new_index: SessionIndex) -> Option>)>> { @@ -2099,15 +2783,20 @@ impl OnOffenceHandler>], slash_fraction: &[Perbill], slash_session: SessionIndex, - ) { + ) -> Result<(), ()> { + if !Self::can_report() { + return Err(()) + } + let reward_proportion = SlashRewardFraction::get(); let active_era = { let active_era = Self::active_era(); if active_era.is_none() { - return + // this offence need not be re-submitted. + return Ok(()) } - active_era.unwrap().index + active_era.expect("value checked not to be `None`; qed").index }; let active_era_start_session_index = Self::eras_start_session_index(active_era) .unwrap_or_else(|| { @@ -2126,7 +2815,7 @@ impl OnOffenceHandler return, // before bonding period. defensive - should be filtered out. + None => return Ok(()), // before bonding period. defensive - should be filtered out. Some(&(ref slash_era, _)) => *slash_era, } }; @@ -2140,8 +2829,7 @@ impl OnOffenceHandler OnOffenceHandler bool { + Self::era_election_status().is_closed() } } @@ -2202,6 +2896,158 @@ impl ReportOffence } } +/// Disallows any transactions that change the election result to be submitted after the election +/// window is open. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct LockStakingStatus(sp_std::marker::PhantomData); + +impl sp_std::fmt::Debug for LockStakingStatus { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "LockStakingStatus") + } +} + +impl LockStakingStatus { + /// Create new `LockStakingStatus`. + pub fn new() -> Self { + Self(sp_std::marker::PhantomData) + } +} + +impl Default for LockStakingStatus { + fn default() -> Self { + Self::new() + } +} + +impl SignedExtension for LockStakingStatus { + const IDENTIFIER: &'static str = "LockStakingStatus"; + type AccountId = T::AccountId; + type Call = ::Call; + type AdditionalSigned = (); + type DispatchInfo = frame_support::weights::DispatchInfo; + type Pre = (); + + fn additional_signed(&self) -> Result<(), TransactionValidityError> { Ok(()) } + + fn validate( + &self, + _who: &Self::AccountId, + call: &Self::Call, + _info: Self::DispatchInfo, + _len: usize, + ) -> TransactionValidity { + if let Some(inner_call) = call.is_sub_type() { + if let ElectionStatus::Open(_) = >::era_election_status() { + match inner_call { + Call::::set_payee(..) | + Call::::set_controller(..) | + Call::::set_validator_count(..) | + Call::::force_no_eras(..) | + Call::::force_new_era(..) | + Call::::set_invulnerables(..) | + Call::::force_unstake(..) | + Call::::force_new_era_always(..) | + Call::::cancel_deferred_slash(..) | + Call::::set_history_depth(..) | + Call::::reap_stash(..) | + Call::::submit_election_solution(..) | + Call::::submit_election_solution_unsigned(..) => { + // These calls are allowed. Nothing. + } + _ => { + return Err(InvalidTransaction::Stale.into()); + } + } + } + } + + Ok(Default::default()) + } +} + +impl From> for InvalidTransaction { + fn from(e: Error) -> Self { + match e { + >::PhragmenEarlySubmission => InvalidTransaction::Future, + _ => InvalidTransaction::Custom(e.as_u8()), + } + } +} + +#[allow(deprecated)] +impl frame_support::unsigned::ValidateUnsigned for Module { + type Call = Call; + fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity { + if let Call::submit_election_solution_unsigned( + _, + _, + score, + era, + ) = call { + use offchain_election::DEFAULT_LONGEVITY; + + // discard solution not coming from the local OCW. + match source { + TransactionSource::Local | TransactionSource::InBlock => { /* allowed */ } + _ => { + debug::native::debug!( + target: "staking", + "rejecting unsigned transaction because it is not local/in-block." + ); + return InvalidTransaction::Call.into(); + } + } + + if let Err(e) = Self::pre_dispatch_checks(*score, *era) { + debug::native::debug!( + target: "staking", + "validate unsigned failed due to {:?}.", + e, + ); + let invalid: InvalidTransaction = e.into(); + return invalid.into(); + } + + debug::native::debug!( + target: "staking", + "Validated an unsigned transaction from the local node for era {}.", + era, + ); + + Ok(ValidTransaction { + // The higher the score[0], the better a solution is. + priority: score[0].saturated_into(), + // no requires. + requires: vec![], + // Defensive only. A single solution can exist in the pool per era. Each validator + // will run OCW at most once per era, hence there should never exist more than one + // transaction anyhow. + provides: vec![("StakingOffchain", era).encode()], + // Note: this can be more accurate in the future. We do something like + // `era_end_block - current_block` but that is not needed now as we eagerly run + // offchain workers now and the above should be same as `T::ElectionLookahead` + // without the need to query more storage in the validation phase. If we randomize + // offchain worker, then we might re-consider this. + longevity: TryInto::::try_into(T::ElectionLookahead::get()).unwrap_or(DEFAULT_LONGEVITY), + // We don't propagate this. This can never the validated at a remote node. + propagate: false, + }) + } else { + InvalidTransaction::Call.into() + } + } + + fn pre_dispatch(_: &Self::Call) -> Result<(), TransactionValidityError> { + // IMPORTANT NOTE: By default, a sane `pre-dispatch` should always do the same checks as + // `validate_unsigned` and overriding this should be done with care. this module has only + // one unsigned entry point, in which we call into `>::pre_dispatch_checks()` + // which is all the important checks that we do in `validate_unsigned`. Hence, we can safely + // override this to save some time. + Ok(()) + } +} + /// Check that list is sorted and has no duplicates. fn is_sorted_and_unique(list: &[u32]) -> bool { list.windows(2).all(|w| w[0] < w[1]) diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 3e2b72dedf..0045e96b3e 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -17,57 +17,74 @@ //! Test utilities use std::{collections::{HashSet, HashMap}, cell::RefCell}; -use sp_runtime::{Perbill, KeyTypeId}; +use sp_runtime::Perbill; use sp_runtime::curve::PiecewiseLinear; -use sp_runtime::traits::{IdentityLookup, Convert, OpaqueKeys, SaturatedConversion}; -use sp_runtime::testing::{Header, UintAuthorityId}; +use sp_runtime::traits::{IdentityLookup, Convert, SaturatedConversion, Zero}; +use sp_runtime::testing::{Header, UintAuthorityId, TestXt}; use sp_staking::{SessionIndex, offence::{OffenceDetails, OnOffenceHandler}}; -use sp_core::{H256, crypto::key_types}; -use sp_io; +use sp_core::H256; use frame_support::{ - assert_ok, impl_outer_origin, parameter_types, StorageValue, StorageMap, - StorageDoubleMap, IterableStorageMap, - traits::{Currency, Get, FindAuthor, OnFinalize, OnInitialize}, weights::Weight, + assert_ok, impl_outer_origin, parameter_types, impl_outer_dispatch, impl_outer_event, + StorageValue, StorageMap, StorageDoubleMap, IterableStorageMap, + traits::{Currency, Get, FindAuthor, OnFinalize, OnInitialize}, + weights::Weight, +}; +use frame_system::offchain::TransactionSubmitter; +use sp_io; +use sp_phragmen::{ + build_support_map, evaluate_support, reduce, ExtendedBalance, StakedAssignment, PhragmenScore, }; use crate::{ EraIndex, GenesisConfig, Module, Trait, StakerStatus, ValidatorPrefs, RewardDestination, - Nominators, inflation, SessionInterface, Exposure, ErasStakers, ErasRewardPoints + Nominators, inflation, SessionInterface, Exposure, ErasStakers, ErasRewardPoints, + CompactAssignments, ValidatorIndex, NominatorIndex, Validators, OffchainAccuracy, }; /// The AccountId alias in this test module. -pub type AccountId = u64; -pub type BlockNumber = u64; -pub type Balance = u64; +pub(crate) type AccountId = u64; +pub(crate) type AccountIndex = u64; +pub(crate) type BlockNumber = u64; +pub(crate) type Balance = u64; /// Simple structure that exposes how u64 currency can be represented as... u64. pub struct CurrencyToVoteHandler; impl Convert for CurrencyToVoteHandler { - fn convert(x: u64) -> u64 { x } + fn convert(x: u64) -> u64 { + x + } } impl Convert for CurrencyToVoteHandler { - fn convert(x: u128) -> u64 { x.saturated_into() } + fn convert(x: u128) -> u64 { + x.saturated_into() + } } thread_local! { static SESSION: RefCell<(Vec, HashSet)> = RefCell::new(Default::default()); + static SESSION_PER_ERA: RefCell = RefCell::new(3); static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); static SLASH_DEFER_DURATION: RefCell = RefCell::new(0); + static ELECTION_LOOKAHEAD: RefCell = RefCell::new(0); + static PERIOD: RefCell = RefCell::new(1); } -pub struct TestSessionHandler; -impl pallet_session::SessionHandler for TestSessionHandler { - const KEY_TYPE_IDS: &'static [KeyTypeId] = &[key_types::DUMMY]; +/// Another session handler struct to test on_disabled. +pub struct OtherSessionHandler; +impl pallet_session::OneSessionHandler for OtherSessionHandler { + type Key = UintAuthorityId; - fn on_genesis_session(_validators: &[(AccountId, Ks)]) {} + fn on_genesis_session<'a, I: 'a>(_: I) + where I: Iterator, AccountId: 'a {} - fn on_new_session( - _changed: bool, - validators: &[(AccountId, Ks)], - _queued_validators: &[(AccountId, Ks)], - ) { - SESSION.with(|x| - *x.borrow_mut() = (validators.iter().map(|x| x.0.clone()).collect(), HashSet::new()) - ); + fn on_new_session<'a, I: 'a>(_: bool, validators: I, _: I,) + where I: Iterator, AccountId: 'a + { + SESSION.with(|x| { + *x.borrow_mut() = ( + validators.map(|x| x.0.clone()).collect(), + HashSet::new(), + ) + }); } fn on_disabled(validator_index: usize) { @@ -79,6 +96,10 @@ impl pallet_session::SessionHandler for TestSessionHandler { } } +impl sp_runtime::BoundToRuntimeAppPublic for OtherSessionHandler { + type Public = UintAuthorityId; +} + pub fn is_disabled(controller: AccountId) -> bool { let stash = Staking::ledger(&controller).unwrap().stash; SESSION.with(|d| d.borrow().1.contains(&stash)) @@ -91,6 +112,32 @@ impl Get for ExistentialDeposit { } } +pub struct SessionsPerEra; +impl Get for SessionsPerEra { + fn get() -> SessionIndex { + SESSION_PER_ERA.with(|v| *v.borrow()) + } +} +impl Get for SessionsPerEra { + fn get() -> BlockNumber { + SESSION_PER_ERA.with(|v| *v.borrow() as BlockNumber) + } +} + +pub struct ElectionLookahead; +impl Get for ElectionLookahead { + fn get() -> BlockNumber { + ELECTION_LOOKAHEAD.with(|v| *v.borrow()) + } +} + +pub struct Period; +impl Get for Period { + fn get() -> BlockNumber { + PERIOD.with(|v| *v.borrow()) + } +} + pub struct SlashDeferDuration; impl Get for SlashDeferDuration { fn get() -> EraIndex { @@ -98,23 +145,47 @@ impl Get for SlashDeferDuration { } } -impl_outer_origin!{ +impl_outer_origin! { pub enum Origin for Test where system = frame_system {} } +impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + staking::Staking, + } +} + +mod staking { + // Re-export needed for `impl_outer_event!`. + pub use super::super::*; +} +use frame_system as system; +use pallet_balances as balances; +use pallet_session as session; + +impl_outer_event! { + pub enum MetaEvent for Test { + system, + balances, + session, + staking, + } +} + /// Author of block is always 11 pub struct Author11; impl FindAuthor for Author11 { fn find_author<'a, I>(_digests: I) -> Option - where I: 'a + IntoIterator + where I: 'a + IntoIterator, { Some(11) } } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; + parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaximumBlockWeight: Weight = 1024; @@ -123,15 +194,15 @@ parameter_types! { } impl frame_system::Trait for Test { type Origin = Origin; - type Index = u64; + type Index = AccountIndex; type BlockNumber = BlockNumber; - type Call = (); + type Call = Call; type Hash = H256; type Hashing = ::sp_runtime::traits::BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; - type Event = (); + type Event = MetaEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; @@ -144,26 +215,31 @@ impl frame_system::Trait for Test { } impl pallet_balances::Trait for Test { type Balance = Balance; + type Event = MetaEvent; type DustRemoval = (); - type Event = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; } parameter_types! { - pub const Period: BlockNumber = 1; pub const Offset: BlockNumber = 0; pub const UncleGenerations: u64 = 0; pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(25); } +sp_runtime::impl_opaque_keys! { + pub struct SessionKeys { + pub other: OtherSessionHandler, + } +} impl pallet_session::Trait for Test { - type Event = (); + type SessionManager = pallet_session::historical::NoteHistoricalRoot; + type Keys = SessionKeys; + type ShouldEndSession = pallet_session::PeriodicSessions; + type SessionHandler = (OtherSessionHandler,); + type Event = MetaEvent; type ValidatorId = AccountId; type ValidatorIdOf = crate::StashOf; - type ShouldEndSession = pallet_session::PeriodicSessions; - type SessionManager = pallet_session::historical::NoteHistoricalRoot; - type SessionHandler = TestSessionHandler; - type Keys = UintAuthorityId; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type NextSessionRotation = pallet_session::PeriodicSessions; } impl pallet_session::historical::Trait for Test { @@ -195,17 +271,17 @@ pallet_staking_reward_curve::build! { ); } parameter_types! { - pub const SessionsPerEra: SessionIndex = 3; pub const BondingDuration: EraIndex = 3; pub const RewardCurve: &'static PiecewiseLinear<'static> = &I_NPOS; pub const MaxNominatorRewardedPerValidator: u32 = 64; } + impl Trait for Test { type Currency = Balances; type UnixTime = Timestamp; type CurrencyToVote = CurrencyToVoteHandler; type RewardRemainder = (); - type Event = (); + type Event = MetaEvent; type Slash = (); type Reward = (); type SessionsPerEra = SessionsPerEra; @@ -214,11 +290,21 @@ impl Trait for Test { type BondingDuration = BondingDuration; type SessionInterface = Self; type RewardCurve = RewardCurve; + type NextNewSession = Session; + type ElectionLookahead = ElectionLookahead; + type Call = Call; + type SubmitTransaction = SubmitTransaction; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; } +pub type Extrinsic = TestXt; +type SubmitTransaction = TransactionSubmitter<(), Test, Extrinsic>; + pub struct ExtBuilder { - existential_deposit: u64, + session_length: BlockNumber, + election_lookahead: BlockNumber, + session_per_era: SessionIndex, + existential_deposit: Balance, validator_pool: bool, nominate: bool, validator_count: u32, @@ -226,13 +312,16 @@ pub struct ExtBuilder { slash_defer_duration: EraIndex, fair: bool, num_validators: Option, - invulnerables: Vec, - stakers: bool, + invulnerables: Vec, + has_stakers: bool, } impl Default for ExtBuilder { fn default() -> Self { Self { + session_length: 1, + election_lookahead: 0, + session_per_era: 3, existential_deposit: 1, validator_pool: false, nominate: true, @@ -242,7 +331,7 @@ impl Default for ExtBuilder { fair: true, num_validators: None, invulnerables: vec![], - stakers: true, + has_stakers: true, } } } @@ -284,18 +373,40 @@ impl ExtBuilder { self.invulnerables = invulnerables; self } - pub fn set_associated_consts(&self) { - EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); - SLASH_DEFER_DURATION.with(|v| *v.borrow_mut() = self.slash_defer_duration); + pub fn session_per_era(mut self, length: SessionIndex) -> Self { + self.session_per_era = length; + self } - - pub fn stakers(mut self, has_stakers: bool) -> Self { - self.stakers = has_stakers; + pub fn election_lookahead(mut self, look: BlockNumber) -> Self { + self.election_lookahead = look; + self + } + pub fn session_length(mut self, length: BlockNumber) -> Self { + self.session_length = length; + self + } + pub fn has_stakers(mut self, has: bool) -> Self { + self.has_stakers = has; self } + pub fn offchain_phragmen_ext(self) -> Self { + self.session_per_era(4) + .session_length(5) + .election_lookahead(3) + } + pub fn set_associated_constants(&self) { + EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); + SLASH_DEFER_DURATION.with(|v| *v.borrow_mut() = self.slash_defer_duration); + SESSION_PER_ERA.with(|v| *v.borrow_mut() = self.session_per_era); + ELECTION_LOOKAHEAD.with(|v| *v.borrow_mut() = self.election_lookahead); + PERIOD.with(|v| *v.borrow_mut() = self.session_length); + } pub fn build(self) -> sp_io::TestExternalities { - self.set_associated_consts(); - let mut storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); + let _ = env_logger::try_init(); + self.set_associated_constants(); + let mut storage = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); let balance_factor = if self.existential_deposit > 1 { 256 } else { @@ -307,7 +418,7 @@ impl ExtBuilder { .map(|x| ((x + 1) * 10 + 1) as u64) .collect::>(); - let _ = pallet_balances::GenesisConfig::{ + let _ = pallet_balances::GenesisConfig:: { balances: vec![ (1, 10 * balance_factor), (2, 20 * balance_factor), @@ -329,7 +440,7 @@ impl ExtBuilder { }.assimilate_storage(&mut storage); let mut stakers = vec![]; - if self.stakers { + if self.has_stakers { let stake_21 = if self.fair { 1000 } else { 2000 }; let stake_31 = if self.validator_pool { balance_factor * 1000 } else { 1 }; let status_41 = if self.validator_pool { @@ -355,18 +466,21 @@ impl ExtBuilder { invulnerables: self.invulnerables, slash_reward_fraction: Perbill::from_percent(10), ..Default::default() - }.assimilate_storage(&mut storage); + } + .assimilate_storage(&mut storage); let _ = pallet_session::GenesisConfig:: { - keys: validators.iter().map(|x| (*x, *x, UintAuthorityId(*x))).collect(), + keys: validators.iter().map(|x| ( + *x, + *x, + SessionKeys { other: UintAuthorityId(*x) } + )).collect(), }.assimilate_storage(&mut storage); let mut ext = sp_io::TestExternalities::from(storage); ext.execute_with(|| { let validators = Session::validators(); - SESSION.with(|x| - *x.borrow_mut() = (validators.clone(), HashSet::new()) - ); + SESSION.with(|x| *x.borrow_mut() = (validators.clone(), HashSet::new())); }); ext } @@ -378,6 +492,10 @@ pub type Session = pallet_session::Module; pub type Timestamp = pallet_timestamp::Module; pub type Staking = Module; +pub fn active_era() -> EraIndex { + Staking::active_era().unwrap().index +} + pub fn check_exposure_all(era: EraIndex) { ErasStakers::::iter_prefix(era).for_each(check_exposure) } @@ -390,8 +508,9 @@ pub fn check_nominator_all(era: EraIndex) { /// Check for each selected validator: expo.total = Sum(expo.other) + expo.own pub fn check_exposure(expo: Exposure) { assert_eq!( - expo.total as u128, expo.own as u128 + expo.others.iter().map(|e| e.value as u128).sum::(), - "wrong total exposure {:?}", expo, + expo.total as u128, + expo.own as u128 + expo.others.iter().map(|e| e.value as u128).sum::(), + "wrong total exposure", ); } @@ -400,17 +519,18 @@ pub fn check_exposure(expo: Exposure) { pub fn check_nominator_exposure(era: EraIndex, stash: AccountId) { assert_is_stash(stash); let mut sum = 0; - ErasStakers::::iter_prefix(era) - .for_each(|exposure| { - exposure.others.iter() - .filter(|i| i.who == stash) - .for_each(|i| sum += i.value) - }); + Session::validators() + .iter() + .map(|v| Staking::eras_stakers(era, v)) + .for_each(|e| e.others.iter().filter(|i| i.who == stash).for_each(|i| sum += i.value)); let nominator_stake = Staking::slashable_balance_of(&stash); // a nominator cannot over-spend. assert!( nominator_stake >= sum, - "failed: Nominator({}) stake({}) >= sum divided({})", stash, nominator_stake, sum, + "failed: Nominator({}) stake({}) >= sum divided({})", + stash, + nominator_stake, + sum, ); } @@ -426,20 +546,41 @@ pub fn assert_ledger_consistent(stash: AccountId) { assert_eq!(real_total, ledger.total); } -pub fn bond_validator(acc: u64, val: u64) { - // a = controller - // a + 1 = stash - let _ = Balances::make_free_balance_be(&(acc + 1), val); - assert_ok!(Staking::bond(Origin::signed(acc + 1), acc, val, RewardDestination::Controller)); - assert_ok!(Staking::validate(Origin::signed(acc), ValidatorPrefs::default())); -} - -pub fn bond_nominator(acc: u64, val: u64, target: Vec) { - // a = controller - // a + 1 = stash - let _ = Balances::make_free_balance_be(&(acc + 1), val); - assert_ok!(Staking::bond(Origin::signed(acc + 1), acc, val, RewardDestination::Controller)); - assert_ok!(Staking::nominate(Origin::signed(acc), target)); +pub fn bond_validator(stash: u64, ctrl: u64, val: u64) { + let _ = Balances::make_free_balance_be(&stash, val); + assert_ok!(Staking::bond( + Origin::signed(stash), + ctrl, + val, + RewardDestination::Controller, + )); + assert_ok!(Staking::validate( + Origin::signed(ctrl), + ValidatorPrefs::default() + )); +} + +pub fn bond_nominator(stash: u64, ctrl: u64, val: u64, target: Vec) { + let _ = Balances::make_free_balance_be(&stash, val); + assert_ok!(Staking::bond( + Origin::signed(stash), + ctrl, + val, + RewardDestination::Controller, + )); + assert_ok!(Staking::nominate(Origin::signed(ctrl), target)); +} + +pub fn run_to_block(n: BlockNumber) { + Staking::on_finalize(System::block_number()); + for b in System::block_number() + 1..=n { + System::set_block_number(b); + Session::on_initialize(b); + Staking::on_initialize(b); + if b != n { + Staking::on_finalize(System::block_number()); + } + } } pub fn advance_session() { @@ -448,19 +589,21 @@ pub fn advance_session() { } pub fn start_session(session_index: SessionIndex) { + assert_eq!(>::get(), 1, "start_session can only be used with session length 1."); for i in Session::current_index()..session_index { Staking::on_finalize(System::block_number()); System::set_block_number((i + 1).into()); Timestamp::set_timestamp(System::block_number() * 1000); Session::on_initialize(System::block_number()); + Staking::on_initialize(System::block_number()); } assert_eq!(Session::current_index(), session_index); } pub fn start_era(era_index: EraIndex) { - start_session((era_index * 3).into()); - assert_eq!(Staking::active_era().unwrap().index, era_index); + start_session((era_index * >::get()).into()); + assert_eq!(Staking::current_era().unwrap(), era_index); } pub fn current_total_payout_for_duration(duration: u64) -> u64 { @@ -473,33 +616,45 @@ pub fn current_total_payout_for_duration(duration: u64) -> u64 { } pub fn reward_all_elected() { - let rewards = ::SessionInterface::validators().into_iter() + let rewards = ::SessionInterface::validators() + .into_iter() .map(|v| (v, 1)); >::reward_by_ids(rewards) } pub fn validator_controllers() -> Vec { - Session::validators().into_iter().map(|s| Staking::bonded(&s).expect("no controller for validator")).collect() + Session::validators() + .into_iter() + .map(|s| Staking::bonded(&s).expect("no controller for validator")) + .collect() } pub fn on_offence_in_era( - offenders: &[OffenceDetails>], + offenders: &[OffenceDetails< + AccountId, + pallet_session::historical::IdentificationTuple, + >], slash_fraction: &[Perbill], era: EraIndex, ) { let bonded_eras = crate::BondedEras::get(); for &(bonded_era, start_session) in bonded_eras.iter() { if bonded_era == era { - Staking::on_offence(offenders, slash_fraction, start_session); - return + let _ = Staking::on_offence(offenders, slash_fraction, start_session).unwrap(); + return; } else if bonded_era > era { - break + break; } } if Staking::active_era().unwrap().index == era { - Staking::on_offence(offenders, slash_fraction, Staking::eras_start_session_index(era).unwrap()); + let _ = + Staking::on_offence( + offenders, + slash_fraction, + Staking::eras_start_session_index(era).unwrap() + ).unwrap(); } else { panic!("cannot slash in era {}", era); } @@ -513,6 +668,193 @@ pub fn on_offence_now( on_offence_in_era(offenders, slash_fraction, now) } +// winners will be chosen by simply their unweighted total backing stake. Nominator stake is +// distributed evenly. +pub fn horrible_phragmen_with_post_processing( + do_reduce: bool, +) -> (CompactAssignments, Vec, PhragmenScore) { + use std::collections::BTreeMap; + + let mut backing_stake_of: BTreeMap = BTreeMap::new(); + + // self stake + >::iter().for_each(|(who, _p)| { + *backing_stake_of.entry(who).or_insert(Zero::zero()) += Staking::slashable_balance_of(&who) + }); + + // add nominator stuff + >::iter().for_each(|(who, nomination)| { + nomination.targets.iter().for_each(|v| { + *backing_stake_of.entry(*v).or_insert(Zero::zero()) += + Staking::slashable_balance_of(&who) + }) + }); + + // elect winners + let mut sorted: Vec = backing_stake_of.keys().cloned().collect(); + sorted.sort_by_key(|x| backing_stake_of.get(x).unwrap()); + let winners: Vec = sorted + .iter() + .cloned() + .take(Staking::validator_count() as usize) + .collect(); + + // create assignments + let mut staked_assignment: Vec> = Vec::new(); + >::iter().for_each(|(who, nomination)| { + let mut dist: Vec<(AccountId, ExtendedBalance)> = Vec::new(); + nomination.targets.iter().for_each(|v| { + if winners.iter().find(|w| *w == v).is_some() { + dist.push((*v, ExtendedBalance::zero())); + } + }); + + if dist.len() == 0 { + return; + } + + // assign real stakes. just split the stake. + let stake = Staking::slashable_balance_of(&who) as ExtendedBalance; + let mut sum: ExtendedBalance = Zero::zero(); + let dist_len = dist.len(); + { + dist.iter_mut().for_each(|(_, w)| { + let partial = stake / (dist_len as ExtendedBalance); + *w = partial; + sum += partial; + }); + } + + // assign the leftover to last. + { + let leftover = stake - sum; + let last = dist.last_mut().unwrap(); + last.1 += leftover; + } + + staked_assignment.push(StakedAssignment { + who, + distribution: dist, + }); + }); + + // Ensure that this result is worse than seq-phragmen. Otherwise, it should not have been used + // for testing. + let score = { + let (_, _, better_score) = prepare_submission_with(true, |_| {}); + + let support = build_support_map::(&winners, &staked_assignment).0; + let score = evaluate_support(&support); + + assert!(sp_phragmen::is_score_better(score, better_score)); + + score + }; + + if do_reduce { + reduce(&mut staked_assignment); + } + + let snapshot_validators = Staking::snapshot_validators().unwrap(); + let snapshot_nominators = Staking::snapshot_nominators().unwrap(); + let nominator_index = |a: &AccountId| -> Option { + snapshot_nominators.iter().position(|x| x == a).map(|i| i as NominatorIndex) + }; + let validator_index = |a: &AccountId| -> Option { + snapshot_validators.iter().position(|x| x == a).map(|i| i as ValidatorIndex) + }; + + // convert back to ratio assignment. This takes less space. + let assignments_reduced = + sp_phragmen::assignment_staked_to_ratio::(staked_assignment); + + let compact = + CompactAssignments::from_assignment(assignments_reduced, nominator_index, validator_index) + .unwrap(); + + // winner ids to index + let winners = winners.into_iter().map(|w| validator_index(&w).unwrap()).collect::>(); + + (compact, winners, score) +} + +// Note: this should always logically reproduce [`offchain_election::prepare_submission`], yet we +// cannot do it since we want to have `tweak` injected into the process. +pub fn prepare_submission_with( + do_reduce: bool, + tweak: impl FnOnce(&mut Vec>), +) -> (CompactAssignments, Vec, PhragmenScore) { + // run phragmen on the default stuff. + let sp_phragmen::PhragmenResult { + winners, + assignments, + } = Staking::do_phragmen::().unwrap(); + let winners = winners.into_iter().map(|(w, _)| w).collect::>(); + + let stake_of = |who: &AccountId| -> ExtendedBalance { + >::convert( + Staking::slashable_balance_of(&who) + ) as ExtendedBalance + }; + let mut staked = sp_phragmen::assignment_ratio_to_staked(assignments, stake_of); + + // apply custom tweaks. awesome for testing. + tweak(&mut staked); + + if do_reduce { + reduce(&mut staked); + } + + // convert back to ratio assignment. This takes less space. + let snapshot_validators = Staking::snapshot_validators().expect("snapshot not created."); + let snapshot_nominators = Staking::snapshot_nominators().expect("snapshot not created."); + let nominator_index = |a: &AccountId| -> Option { + snapshot_nominators + .iter() + .position(|x| x == a) + .map_or_else( + || { println!("unable to find nominator index for {:?}", a); None }, + |i| Some(i as NominatorIndex), + ) + }; + let validator_index = |a: &AccountId| -> Option { + snapshot_validators + .iter() + .position(|x| x == a) + .map_or_else( + || { println!("unable to find validator index for {:?}", a); None }, + |i| Some(i as ValidatorIndex), + ) + }; + + let assignments_reduced = sp_phragmen::assignment_staked_to_ratio(staked); + + // re-compute score by converting, yet again, into staked type + let score = { + let staked = sp_phragmen::assignment_ratio_to_staked( + assignments_reduced.clone(), + Staking::slashable_balance_of_extended, + ); + + let (support_map, _) = build_support_map::( + winners.as_slice(), + staked.as_slice(), + ); + evaluate_support::(&support_map) + }; + + let compact = + CompactAssignments::from_assignment(assignments_reduced, nominator_index, validator_index) + .map_err(|e| { println!("error in compact: {:?}", e); e }) + .expect("Failed to create compact"); + + + // winner ids to index + let winners = winners.into_iter().map(|w| validator_index(&w).unwrap()).collect::>(); + + (compact, winners, score) +} + /// Make all validator and nominator request their payment pub fn make_all_reward_payment(era: EraIndex) { let validators_with_reward = ErasRewardPoints::::get(era).individual.keys() @@ -544,3 +886,23 @@ pub fn make_all_reward_payment(era: EraIndex) { assert_ok!(Staking::payout_validator(Origin::signed(validator_controller), era)); } } + +#[macro_export] +macro_rules! assert_session_era { + ($session:expr, $era:expr) => { + assert_eq!( + Session::current_index(), + $session, + "wrong session {} != {}", + Session::current_index(), + $session, + ); + assert_eq!( + Staking::active_era().unwrap().index, + $era, + "wrong active era {} != {}", + Staking::active_era().unwrap().index, + $era, + ); + }; +} diff --git a/frame/staking/src/offchain_election.rs b/frame/staking/src/offchain_election.rs new file mode 100644 index 0000000000..0d4cf49f10 --- /dev/null +++ b/frame/staking/src/offchain_election.rs @@ -0,0 +1,219 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Helpers for offchain worker election. + +use crate::{ + Call, CompactAssignments, Module, NominatorIndex, OffchainAccuracy, Trait, ValidatorIndex, +}; +use frame_system::offchain::SubmitUnsignedTransaction; +use sp_phragmen::{ + build_support_map, evaluate_support, reduce, Assignment, ExtendedBalance, PhragmenResult, + PhragmenScore, +}; +use sp_runtime::offchain::storage::StorageValueRef; +use sp_runtime::PerThing; +use sp_runtime::RuntimeDebug; +use sp_std::{convert::TryInto, prelude::*}; + +/// Error types related to the offchain election machinery. +#[derive(RuntimeDebug)] +pub enum OffchainElectionError { + /// Phragmen election returned None. This means less candidate that minimum number of needed + /// validators were present. The chain is in trouble and not much that we can do about it. + ElectionFailed, + /// Submission to the transaction pool failed. + PoolSubmissionFailed, + /// The snapshot data is not available. + SnapshotUnavailable, + /// Error from phragmen crate. This usually relates to compact operation. + PhragmenError(sp_phragmen::Error), + /// One of the computed winners is invalid. + InvalidWinner, +} + +impl From for OffchainElectionError { + fn from(e: sp_phragmen::Error) -> Self { + Self::PhragmenError(e) + } +} + +/// Storage key used to store the persistent offchain worker status. +pub(crate) const OFFCHAIN_HEAD_DB: &[u8] = b"parity/staking-election/"; +/// The repeat threshold of the offchain worker. This means we won't run the offchain worker twice +/// within a window of 5 blocks. +pub(crate) const OFFCHAIN_REPEAT: u32 = 5; +/// Default number of blocks for which the unsigned transaction should stay in the pool +pub(crate) const DEFAULT_LONGEVITY: u64 = 25; + +/// Checks if an execution of the offchain worker is permitted at the given block number, or not. +/// +/// This essentially makes sure that we don't run on previous blocks in case of a re-org, and we +/// don't run twice within a window of length [`OFFCHAIN_REPEAT`]. +/// +/// Returns `Ok(())` if offchain worker should happen, `Err(reason)` otherwise. +pub(crate) fn set_check_offchain_execution_status( + now: T::BlockNumber, +) -> Result<(), &'static str> { + let storage = StorageValueRef::persistent(&OFFCHAIN_HEAD_DB); + let threshold = T::BlockNumber::from(OFFCHAIN_REPEAT); + + let mutate_stat = + storage.mutate::<_, &'static str, _>(|maybe_head: Option>| { + match maybe_head { + Some(Some(head)) if now < head => Err("fork."), + Some(Some(head)) if now >= head && now <= head + threshold => { + Err("recently executed.") + } + Some(Some(head)) if now > head + threshold => { + // we can run again now. Write the new head. + Ok(now) + } + _ => { + // value doesn't exists. Probably this node just booted up. Write, and run + Ok(now) + } + } + }); + + match mutate_stat { + // all good + Ok(Ok(_)) => Ok(()), + // failed to write. + Ok(Err(_)) => Err("failed to write to offchain db."), + // fork etc. + Err(why) => Err(why), + } +} + +/// The internal logic of the offchain worker of this module. This runs the phragmen election, +/// compacts and reduces the solution, computes the score and submits it back to the chain as an +/// unsigned transaction, without any signature. +pub(crate) fn compute_offchain_election() -> Result<(), OffchainElectionError> { + // compute raw solution. Note that we use `OffchainAccuracy`. + let PhragmenResult { + winners, + assignments, + } = >::do_phragmen::() + .ok_or(OffchainElectionError::ElectionFailed)?; + + // process and prepare it for submission. + let (winners, compact, score) = prepare_submission::(assignments, winners, true)?; + + // defensive-only: active era can never be none except genesis. + let era = >::active_era().map(|e| e.index).unwrap_or_default(); + + // send it. + let call: ::Call = Call::submit_election_solution_unsigned( + winners, + compact, + score, + era, + ).into(); + + T::SubmitTransaction::submit_unsigned(call) + .map_err(|_| OffchainElectionError::PoolSubmissionFailed) +} + +/// Takes a phragmen result and spits out some data that can be submitted to the chain. +/// +/// This does a lot of stuff; read the inline comments. +pub fn prepare_submission( + assignments: Vec>, + winners: Vec<(T::AccountId, ExtendedBalance)>, + do_reduce: bool, +) -> Result<(Vec, CompactAssignments, PhragmenScore), OffchainElectionError> where + ExtendedBalance: From<::Inner>, +{ + // make sure that the snapshot is available. + let snapshot_validators = + >::snapshot_validators().ok_or(OffchainElectionError::SnapshotUnavailable)?; + let snapshot_nominators = + >::snapshot_nominators().ok_or(OffchainElectionError::SnapshotUnavailable)?; + + // all helper closures + let nominator_index = |a: &T::AccountId| -> Option { + snapshot_nominators + .iter() + .position(|x| x == a) + .and_then(|i| >::try_into(i).ok()) + }; + let validator_index = |a: &T::AccountId| -> Option { + snapshot_validators + .iter() + .position(|x| x == a) + .and_then(|i| >::try_into(i).ok()) + }; + + // Clean winners. + let winners = winners + .into_iter() + .map(|(w, _)| w) + .collect::>(); + + // convert into absolute value and to obtain the reduced version. + let mut staked = sp_phragmen::assignment_ratio_to_staked( + assignments, + >::slashable_balance_of_extended, + ); + + if do_reduce { + reduce(&mut staked); + } + + // Convert back to ratio assignment. This takes less space. + let low_accuracy_assignment = sp_phragmen::assignment_staked_to_ratio(staked); + + // convert back to staked to compute the score in the receiver's accuracy. This can be done + // nicer, for now we do it as such since this code is not time-critical. This ensure that the + // score _predicted_ here is the same as the one computed on chain and you will not get a + // `PhragmenBogusScore` error. This is totally NOT needed if we don't do reduce. This whole + // _accuracy glitch_ happens because reduce breaks that assumption of rounding and **scale**. + // The initial phragmen results are computed in `OffchainAccuracy` and the initial `staked` + // assignment set is also all multiples of this value. After reduce, this no longer holds. Hence + // converting to ratio thereafter is not trivially reversible. + let score = { + let staked = sp_phragmen::assignment_ratio_to_staked( + low_accuracy_assignment.clone(), + >::slashable_balance_of_extended, + ); + + let (support_map, _) = build_support_map::(&winners, &staked); + evaluate_support::(&support_map) + }; + + // compact encode the assignment. + let compact = CompactAssignments::from_assignment( + low_accuracy_assignment, + nominator_index, + validator_index, + ).map_err(|e| OffchainElectionError::from(e))?; + + // winners to index. Use a simple for loop for a more expressive early exit in case of error. + let mut winners_indexed: Vec = Vec::with_capacity(winners.len()); + for w in winners { + if let Some(idx) = snapshot_validators.iter().position(|v| *v == w) { + let compact_index: ValidatorIndex = idx + .try_into() + .map_err(|_| OffchainElectionError::InvalidWinner)?; + winners_indexed.push(compact_index); + } else { + return Err(OffchainElectionError::InvalidWinner); + } + } + + Ok((winners_indexed, compact, score)) +} diff --git a/frame/staking/src/slashing.rs b/frame/staking/src/slashing.rs index 160c08246a..3d5ea3bad5 100644 --- a/frame/staking/src/slashing.rs +++ b/frame/staking/src/slashing.rs @@ -16,11 +16,11 @@ //! A slashing implementation for NPoS systems. //! -//! For the purposes of the economic model, it is easiest to think of each validator -//! of a nominator which nominates only its own identity. +//! For the purposes of the economic model, it is easiest to think of each validator as a nominator +//! which nominates only its own identity. //! -//! The act of nomination signals intent to unify economic identity with the validator - to take part in the -//! rewards of a job well done, and to take part in the punishment of a job done badly. +//! The act of nomination signals intent to unify economic identity with the validator - to take +//! part in the rewards of a job well done, and to take part in the punishment of a job done badly. //! //! There are 3 main difficulties to account for with slashing in NPoS: //! - A nominator can nominate multiple validators and be slashed via any of them. @@ -52,7 +52,7 @@ use super::{ EraIndex, Trait, Module, Store, BalanceOf, Exposure, Perbill, SessionInterface, NegativeImbalanceOf, UnappliedSlash, }; -use sp_runtime::{traits::{Zero, Saturating}, PerThing}; +use sp_runtime::{traits::{Zero, Saturating}, PerThing, RuntimeDebug}; use frame_support::{ StorageMap, StorageDoubleMap, traits::{Currency, OnUnbalanced, Imbalance}, @@ -65,7 +65,7 @@ use codec::{Encode, Decode}; const REWARD_F1: Perbill = Perbill::from_percent(50); /// The index of a slashing span - unique to each stash. -pub(crate) type SpanIndex = u32; +pub type SpanIndex = u32; // A range of start..end eras for a slashing span. #[derive(Encode, Decode)] @@ -83,7 +83,7 @@ impl SlashingSpan { } /// An encoding of all of a nominator's slashing spans. -#[derive(Encode, Decode)] +#[derive(Encode, Decode, RuntimeDebug)] pub struct SlashingSpans { // the index of the current slashing span of the nominator. different for // every stash, resets when the account hits free balance 0. @@ -143,7 +143,7 @@ impl SlashingSpans { } /// Yields the era index where the most recent non-zero slash occurred. - pub(crate) fn last_nonzero_slash(&self) -> EraIndex { + pub fn last_nonzero_slash(&self) -> EraIndex { self.last_nonzero_slash } diff --git a/frame/staking/src/testing_utils.rs b/frame/staking/src/testing_utils.rs new file mode 100644 index 0000000000..29a395b89d --- /dev/null +++ b/frame/staking/src/testing_utils.rs @@ -0,0 +1,340 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Testing utils for staking. Needs the `testing-utils` feature to be enabled. +//! +//! Note that these helpers should NOT be used with the actual crate tests, but are rather designed +//! for when the module is being externally tested (i.e. fuzzing, benchmarking, e2e tests). Enabling +//! this feature in the current crate's Cargo.toml will leak the all of this into a normal release +//! build. Just don't do it. + +use crate::*; +use codec::{Decode, Encode}; +use frame_support::assert_ok; +use frame_system::RawOrigin; +use pallet_indices::address::Address; +use rand::Rng; +use sp_core::hashing::blake2_256; +use sp_phragmen::{ + build_support_map, evaluate_support, reduce, Assignment, PhragmenScore, StakedAssignment, +}; + +const CTRL_PREFIX: u32 = 1000; +const NOMINATOR_PREFIX: u32 = 1_000_000; + +/// A dummy suer. +pub const USER: u32 = 999_999_999; + +/// Address type of the `T` +pub type AddressOf = Address<::AccountId, u32>; + +/// Random number in the range `[a, b]`. +pub fn random(a: u32, b: u32) -> u32 { + rand::thread_rng().gen_range(a, b) +} + +/// Set the desired validator count, with related storage items. +pub fn set_validator_count(to_elect: u32) { + ValidatorCount::put(to_elect); + MinimumValidatorCount::put(to_elect / 2); + >::put(ElectionStatus::Open(T::BlockNumber::from(1u32))); +} + +/// Build an account with the given index. +pub fn account(index: u32) -> T::AccountId { + let entropy = (b"benchmark/staking", index).using_encoded(blake2_256); + T::AccountId::decode(&mut &entropy[..]).unwrap_or_default() +} + +/// Build an address given Index +pub fn address(index: u32) -> AddressOf { + pallet_indices::address::Address::Id(account::(index)) +} + +/// Generate signed origin from `who`. +pub fn signed(who: T::AccountId) -> T::Origin { + RawOrigin::Signed(who).into() +} + +/// Generate signed origin from `index`. +pub fn signed_account(index: u32) -> T::Origin { + signed::(account::(index)) +} + +/// Bond a validator. +pub fn bond_validator(stash: T::AccountId, ctrl: u32, val: BalanceOf) +where + T::Lookup: StaticLookup>, +{ + let _ = T::Currency::make_free_balance_be(&stash, val); + assert_ok!(>::bond( + signed::(stash), + address::(ctrl), + val, + RewardDestination::Controller + )); + assert_ok!(>::validate( + signed_account::(ctrl), + ValidatorPrefs::default() + )); +} + +pub fn bond_nominator( + stash: T::AccountId, + ctrl: u32, + val: BalanceOf, + target: Vec>, +) where + T::Lookup: StaticLookup>, +{ + let _ = T::Currency::make_free_balance_be(&stash, val); + assert_ok!(>::bond( + signed::(stash), + address::(ctrl), + val, + RewardDestination::Controller + )); + assert_ok!(>::nominate(signed_account::(ctrl), target)); +} + +/// Bond `nun_validators` validators and `num_nominator` nominators with `edge_per_voter` random +/// votes per nominator. +pub fn setup_chain_stakers(num_validators: u32, num_voters: u32, edge_per_voter: u32) +where + T::Lookup: StaticLookup>, +{ + (0..num_validators).for_each(|i| { + bond_validator::( + account::(i), + i + CTRL_PREFIX, + >::from(random(1, 1000)) * T::Currency::minimum_balance(), + ); + }); + + (0..num_voters).for_each(|i| { + let mut targets: Vec> = Vec::with_capacity(edge_per_voter as usize); + let mut all_targets = (0..num_validators) + .map(|t| address::(t)) + .collect::>(); + assert!(num_validators >= edge_per_voter); + (0..edge_per_voter).for_each(|_| { + let target = all_targets.remove(random(0, all_targets.len() as u32 - 1) as usize); + targets.push(target); + }); + bond_nominator::( + account::(i + NOMINATOR_PREFIX), + i + NOMINATOR_PREFIX + CTRL_PREFIX, + >::from(random(1, 1000)) * T::Currency::minimum_balance(), + targets, + ); + }); + + >::create_stakers_snapshot(); +} + +/// Build a _really bad_ but acceptable solution for election. This should always yield a solution +/// which has a less score than the seq-phragmen. +pub fn get_weak_solution( + do_reduce: bool, +) -> (Vec, CompactAssignments, PhragmenScore) { + let mut backing_stake_of: BTreeMap> = BTreeMap::new(); + + // self stake + >::enumerate().for_each(|(who, _p)| { + *backing_stake_of.entry(who.clone()).or_insert(Zero::zero()) += + >::slashable_balance_of(&who) + }); + + // add nominator stuff + >::enumerate().for_each(|(who, nomination)| { + nomination.targets.into_iter().for_each(|v| { + *backing_stake_of.entry(v).or_insert(Zero::zero()) += + >::slashable_balance_of(&who) + }) + }); + + // elect winners + let mut sorted: Vec = backing_stake_of.keys().cloned().collect(); + sorted.sort_by_key(|x| backing_stake_of.get(x).unwrap()); + let winners: Vec = sorted + .iter() + .cloned() + .take(>::validator_count() as usize) + .collect(); + + let mut staked_assignments: Vec> = Vec::new(); + >::enumerate().for_each(|(who, nomination)| { + let mut dist: Vec<(T::AccountId, ExtendedBalance)> = Vec::new(); + nomination.targets.into_iter().for_each(|v| { + if winners.iter().find(|&w| *w == v).is_some() { + dist.push((v, ExtendedBalance::zero())); + } + }); + + if dist.len() == 0 { + return; + } + + // assign real stakes. just split the stake. + let stake = , u64>>::convert( + >::slashable_balance_of(&who), + ) as ExtendedBalance; + + let mut sum: ExtendedBalance = Zero::zero(); + let dist_len = dist.len() as ExtendedBalance; + + // assign main portion + // only take the first half into account. This should highly imbalance stuff, which is good. + dist.iter_mut() + .take(if dist_len > 1 { + (dist_len as usize) / 2 + } else { + 1 + }) + .for_each(|(_, w)| { + let partial = stake / dist_len; + *w = partial; + sum += partial; + }); + + // assign the leftover to last. + let leftover = stake - sum; + let last = dist.last_mut().unwrap(); + last.1 += leftover; + + staked_assignments.push(StakedAssignment { + who, + distribution: dist, + }); + }); + + // add self support to winners. + winners.iter().for_each(|w| { + staked_assignments.push(StakedAssignment { + who: w.clone(), + distribution: vec![( + w.clone(), + , u64>>::convert( + >::slashable_balance_of(&w), + ) as ExtendedBalance, + )], + }) + }); + + if do_reduce { + reduce(&mut staked_assignments); + } + + // helpers for building the compact + let snapshot_validators = >::snapshot_validators().unwrap(); + let snapshot_nominators = >::snapshot_nominators().unwrap(); + + let nominator_index = |a: &T::AccountId| -> Option { + snapshot_nominators + .iter() + .position(|x| x == a) + .and_then(|i| >::try_into(i).ok()) + }; + let validator_index = |a: &T::AccountId| -> Option { + snapshot_validators + .iter() + .position(|x| x == a) + .and_then(|i| >::try_into(i).ok()) + }; + let stake_of = |who: &T::AccountId| -> ExtendedBalance { + , u64>>::convert( + >::slashable_balance_of(who), + ) as ExtendedBalance + }; + + // convert back to ratio assignment. This takes less space. + let low_accuracy_assignment: Vec> = + staked_assignments + .into_iter() + .map(|sa| sa.into_assignment(true)) + .collect(); + + // re-calculate score based on what the chain will decode. + let score = { + let staked: Vec> = low_accuracy_assignment + .iter() + .map(|a| { + let stake = stake_of(&a.who); + a.clone().into_staked(stake, true) + }) + .collect(); + + let (support_map, _) = + build_support_map::(winners.as_slice(), staked.as_slice()); + evaluate_support::(&support_map) + }; + + // compact encode the assignment. + let compact = CompactAssignments::from_assignment( + low_accuracy_assignment, + nominator_index, + validator_index, + ) + .unwrap(); + + // winners to index. + let winners = winners + .into_iter() + .map(|w| { + snapshot_validators + .iter() + .position(|v| *v == w) + .unwrap() + .try_into() + .unwrap() + }) + .collect::>(); + + (winners, compact, score) +} + +/// Create a solution for seq-phragmen. This uses the same internal function as used by the offchain +/// worker code. +pub fn get_seq_phragmen_solution( + do_reduce: bool, +) -> (Vec, CompactAssignments, PhragmenScore) { + let sp_phragmen::PhragmenResult { + winners, + assignments, + } = >::do_phragmen::().unwrap(); + + offchain_election::prepare_submission::(assignments, winners, do_reduce).unwrap() +} + +/// Remove all validator, nominators, votes and exposures. +pub fn clean(era: EraIndex) + where + ::AccountId: codec::EncodeLike, + u32: codec::EncodeLike, +{ + >::enumerate().for_each(|(k, _)| { + let ctrl = >::bonded(&k).unwrap(); + >::remove(&k); + >::remove(&k); + >::remove(&ctrl); + >::remove(k, era); + }); + >::enumerate().for_each(|(k, _)| >::remove(k)); + >::remove_all(); + >::remove_all(); + >::kill(); + QueuedScore::kill(); +} diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 6687b83f05..f54fe05de0 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -18,7 +18,9 @@ use super::*; use mock::*; -use sp_runtime::{assert_eq_error_rate, traits::BadOrigin}; +use sp_runtime::{ + assert_eq_error_rate, traits::BadOrigin, +}; use sp_staking::offence::OffenceDetails; use frame_support::{ assert_ok, assert_noop, StorageMap, @@ -647,51 +649,37 @@ fn double_controlling_should_fail() { fn session_and_eras_work() { ExtBuilder::default().build().execute_with(|| { assert_eq!(Staking::active_era().unwrap().index, 0); + assert_eq!(Session::current_index(), 0); - // Block 1: No change. + // Session 1: No change. start_session(1); assert_eq!(Session::current_index(), 1); assert_eq!(Staking::active_era().unwrap().index, 0); - // Block 2: No change. + // Session 2: No change. start_session(2); assert_eq!(Session::current_index(), 2); assert_eq!(Staking::active_era().unwrap().index, 0); - // Block 3: Era increment. + // Session 3: Era increment. start_session(3); assert_eq!(Session::current_index(), 3); assert_eq!(Staking::active_era().unwrap().index, 1); - // Block 4: No change. + // Session 4: No change. start_session(4); assert_eq!(Session::current_index(), 4); assert_eq!(Staking::active_era().unwrap().index, 1); - // Block 5: No change. + // Session 5: No change. start_session(5); assert_eq!(Session::current_index(), 5); assert_eq!(Staking::active_era().unwrap().index, 1); - // Block 6: Era increment. + // Session 6: Era increment. start_session(6); assert_eq!(Session::current_index(), 6); assert_eq!(Staking::active_era().unwrap().index, 2); - - // Block 7: No change. - start_session(7); - assert_eq!(Session::current_index(), 7); - assert_eq!(Staking::active_era().unwrap().index, 2); - - // Block 8: No change. - start_session(8); - assert_eq!(Session::current_index(), 8); - assert_eq!(Staking::active_era().unwrap().index, 2); - - // Block 9: Era increment. - start_session(9); - assert_eq!(Session::current_index(), 9); - assert_eq!(Staking::active_era().unwrap().index, 3); }); } @@ -1736,11 +1724,11 @@ fn phragmen_should_not_overflow_validators() { let _ = Staking::chill(Origin::signed(10)); let _ = Staking::chill(Origin::signed(20)); - bond_validator(2, u64::max_value()); - bond_validator(4, u64::max_value()); + bond_validator(3, 2, u64::max_value()); + bond_validator(5, 4, u64::max_value()); - bond_nominator(6, u64::max_value() / 2, vec![3, 5]); - bond_nominator(8, u64::max_value() / 2, vec![3, 5]); + bond_nominator(7, 6, u64::max_value() / 2, vec![3, 5]); + bond_nominator(9, 8, u64::max_value() / 2, vec![3, 5]); start_era(1); @@ -1759,11 +1747,11 @@ fn phragmen_should_not_overflow_nominators() { let _ = Staking::chill(Origin::signed(10)); let _ = Staking::chill(Origin::signed(20)); - bond_validator(2, u64::max_value() / 2); - bond_validator(4, u64::max_value() / 2); + bond_validator(3, 2, u64::max_value() / 2); + bond_validator(5, 4, u64::max_value() / 2); - bond_nominator(6, u64::max_value(), vec![3, 5]); - bond_nominator(8, u64::max_value(), vec![3, 5]); + bond_nominator(7, 6, u64::max_value(), vec![3, 5]); + bond_nominator(9, 8, u64::max_value(), vec![3, 5]); start_era(1); @@ -1778,11 +1766,11 @@ fn phragmen_should_not_overflow_nominators() { #[test] fn phragmen_should_not_overflow_ultimate() { ExtBuilder::default().nominate(false).build().execute_with(|| { - bond_validator(2, u64::max_value()); - bond_validator(4, u64::max_value()); + bond_validator(3, 2, u64::max_value()); + bond_validator(5, 4, u64::max_value()); - bond_nominator(6, u64::max_value(), vec![3, 5]); - bond_nominator(8, u64::max_value(), vec![3, 5]); + bond_nominator(7, 6, u64::max_value(), vec![3, 5]); + bond_nominator(9, 8, u64::max_value(), vec![3, 5]); start_era(1); @@ -1923,21 +1911,23 @@ fn era_is_always_same_length() { // This ensures that the sessions is always of the same length if there is no forcing no // session changes. ExtBuilder::default().build().execute_with(|| { + let session_per_era = >::get(); + start_era(1); - assert_eq!(Staking::eras_start_session_index(Staking::active_era().unwrap().index).unwrap(), SessionsPerEra::get()); + assert_eq!(Staking::eras_start_session_index(active_era()).unwrap(), session_per_era); start_era(2); - assert_eq!(Staking::eras_start_session_index(Staking::active_era().unwrap().index).unwrap(), SessionsPerEra::get() * 2); + assert_eq!(Staking::eras_start_session_index(active_era()).unwrap(), session_per_era * 2u32); let session = Session::current_index(); ForceEra::put(Forcing::ForceNew); advance_session(); advance_session(); assert_eq!(Staking::active_era().unwrap().index, 3); - assert_eq!(Staking::eras_start_session_index(Staking::active_era().unwrap().index).unwrap(), session + 2); + assert_eq!(Staking::eras_start_session_index(active_era()).unwrap(), session + 2); start_era(4); - assert_eq!(Staking::eras_start_session_index(Staking::active_era().unwrap().index).unwrap(), session + 2 + SessionsPerEra::get()); + assert_eq!(Staking::eras_start_session_index(active_era()).unwrap(), session + 2u32 + session_per_era); }); } @@ -1963,6 +1953,7 @@ fn offence_forces_new_era() { fn offence_ensures_new_era_without_clobbering() { ExtBuilder::default().build().execute_with(|| { assert_ok!(Staking::force_new_era_always(Origin::ROOT)); + assert_eq!(Staking::force_era(), Forcing::ForceAlways); on_offence_now( &[OffenceDetails { @@ -1980,10 +1971,11 @@ fn offence_ensures_new_era_without_clobbering() { } #[test] -fn offence_deselects_validator_when_slash_is_zero() { +fn offence_deselects_validator_even_when_slash_is_zero() { ExtBuilder::default().build().execute_with(|| { assert!(Session::validators().contains(&11)); assert!(>::contains_key(11)); + on_offence_now( &[OffenceDetails { offender: ( @@ -1994,9 +1986,12 @@ fn offence_deselects_validator_when_slash_is_zero() { }], &[Perbill::from_percent(0)], ); + assert_eq!(Staking::force_era(), Forcing::ForceNew); assert!(!>::contains_key(11)); + start_era(1); + assert!(!Session::validators().contains(&11)); assert!(!>::contains_key(11)); }); @@ -2037,6 +2032,7 @@ fn slash_in_old_span_does_not_deselect() { assert!(>::contains_key(11)); assert!(Session::validators().contains(&11)); + on_offence_now( &[OffenceDetails { offender: ( @@ -2047,6 +2043,7 @@ fn slash_in_old_span_does_not_deselect() { }], &[Perbill::from_percent(0)], ); + assert_eq!(Staking::force_era(), Forcing::ForceNew); assert!(!>::contains_key(11)); @@ -2074,7 +2071,7 @@ fn slash_in_old_span_does_not_deselect() { 1, ); - // not for zero-slash. + // not forcing for zero-slash and previous span. assert_eq!(Staking::force_era(), Forcing::NotForcing); assert!(>::contains_key(11)); assert!(Session::validators().contains(&11)); @@ -2095,7 +2092,7 @@ fn slash_in_old_span_does_not_deselect() { // or non-zero. assert_eq!(Staking::force_era(), Forcing::NotForcing); assert!(>::contains_key(11)); - assert!(Session::validators().contains(&11)); + assert!(Session::validators().contains(&11)); assert_ledger_consistent(11); }); } @@ -2134,7 +2131,7 @@ fn reporters_receive_their_slice() { #[test] fn subsequent_reports_in_same_span_pay_out_less() { // This test verifies that the reporters of the offence receive their slice from the slashed - // amount. + // amount, but less and less if they submit multiple reports in one span. ExtBuilder::default().build().execute_with(|| { // The reporters' reward is calculated from the total exposure. let initial_balance = 1125; @@ -2241,12 +2238,16 @@ fn dont_slash_if_fraction_is_zero() { // The validator hasn't been slashed. The new era is not forced. assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Staking::force_era(), Forcing::ForceNew); + assert_ledger_consistent(11); }); } #[test] fn only_slash_for_max_in_era() { + // multiple slashes within one era are only applied if it is more than any previous slash in the + // same era. ExtBuilder::default().build().execute_with(|| { assert_eq!(Balances::free_balance(11), 1000); @@ -2295,6 +2296,7 @@ fn only_slash_for_max_in_era() { #[test] fn garbage_collection_after_slashing() { + // ensures that `SlashingSpans` and `SpanSlash` of an account is removed after reaping. ExtBuilder::default().existential_deposit(2).build().execute_with(|| { assert_eq!(Balances::free_balance(11), 256_000); @@ -2337,27 +2339,28 @@ fn garbage_collection_after_slashing() { #[test] fn garbage_collection_on_window_pruning() { + // ensures that `ValidatorSlashInEra` and `NominatorSlashInEra` are cleared after + // `BondingDuration`. ExtBuilder::default().build().execute_with(|| { start_era(1); assert_eq!(Balances::free_balance(11), 1000); + let now = Staking::active_era().unwrap().index; - let exposure = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); + let exposure = Staking::eras_stakers(now, 11); assert_eq!(Balances::free_balance(101), 2000); let nominated_value = exposure.others.iter().find(|o| o.who == 101).unwrap().value; on_offence_now( &[ OffenceDetails { - offender: (11, Staking::eras_stakers(Staking::active_era().unwrap().index, 11)), + offender: (11, Staking::eras_stakers(now, 11)), reporters: vec![], }, ], &[Perbill::from_percent(10)], ); - let now = Staking::active_era().unwrap().index; - assert_eq!(Balances::free_balance(11), 900); assert_eq!(Balances::free_balance(101), 2000 - (nominated_value / 10)); @@ -2389,10 +2392,8 @@ fn slashing_nominators_by_span_max() { assert_eq!(Balances::free_balance(101), 2000); assert_eq!(Staking::slashable_balance_of(&21), 1000); - let exposure_11 = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); let exposure_21 = Staking::eras_stakers(Staking::active_era().unwrap().index, 21); - assert_eq!(Balances::free_balance(101), 2000); let nominated_value_11 = exposure_11.others.iter().find(|o| o.who == 101).unwrap().value; let nominated_value_21 = exposure_21.others.iter().find(|o| o.who == 101).unwrap().value; @@ -2736,35 +2737,1101 @@ fn remove_multi_deferred() { let slashes = ::UnappliedSlashes::get(&1); assert_eq!(slashes.len(), 2); - println!("Slashes: {:?}", slashes); assert_eq!(slashes[0].validator, 21); assert_eq!(slashes[1].validator, 42); }) } +mod offchain_phragmen { + use crate::*; + use frame_support::{assert_noop, assert_ok}; + use sp_runtime::transaction_validity::TransactionSource; + use mock::*; + use parking_lot::RwLock; + use sp_core::offchain::{ + testing::{PoolState, TestOffchainExt, TestTransactionPoolExt}, + OffchainExt, TransactionPoolExt, + }; + use sp_io::TestExternalities; + use sp_phragmen::StakedAssignment; + use frame_support::traits::OffchainWorker; + use std::sync::Arc; + use substrate_test_utils::assert_eq_uvec; + + fn percent(x: u16) -> OffchainAccuracy { + OffchainAccuracy::from_percent(x) + } + + /// setup a new set of validators and nominator storage items independent of the parent mock + /// file. This produces a edge graph that can be reduced. + fn build_offchain_phragmen_test_ext() { + for i in (10..=40).step_by(10) { + // Note: we respect the convention of the mock (10, 11 pairs etc.) since these accounts + // have corresponding keys in session which makes everything more ergonomic and + // realistic. + bond_validator(i + 1, i, 100); + } + + let mut voter = 1; + bond_nominator(voter, 1000 + voter, 100, vec![11]); + voter = 2; + bond_nominator(voter, 1000 + voter, 100, vec![11, 11]); + voter = 3; + bond_nominator(voter, 1000 + voter, 100, vec![21, 41]); + voter = 4; + bond_nominator(voter, 1000 + voter, 100, vec![21, 31, 41]); + voter = 5; + bond_nominator(voter, 1000 + voter, 100, vec![21, 31, 41]); + } + + fn offchainify(ext: &mut TestExternalities) -> Arc> { + let (offchain, _state) = TestOffchainExt::new(); + let (pool, state) = TestTransactionPoolExt::new(); + + ext.register_extension(OffchainExt::new(offchain)); + ext.register_extension(TransactionPoolExt::new(pool)); + + state + } + + #[test] + fn is_current_session_final_works() { + ExtBuilder::default() + .session_per_era(3) + .build() + .execute_with(|| { + start_era(1); + assert_eq!(Session::current_index(), 3); + assert_eq!(Staking::current_era(), Some(1)); + assert_eq!(Staking::is_current_session_final(), false); + + start_session(4); + assert_eq!(Session::current_index(), 4); + assert_eq!(Staking::current_era(), Some(1)); + assert_eq!(Staking::is_current_session_final(), true); + + start_session(5); + assert_eq!(Session::current_index(), 5); + // era changed. + assert_eq!(Staking::current_era(), Some(2)); + assert_eq!(Staking::is_current_session_final(), false); + }) + } + + #[test] + fn offchain_election_flag_is_triggered() { + ExtBuilder::default() + .session_per_era(5) + .session_length(10) + .election_lookahead(3) + .build() + .execute_with(|| { + run_to_block(7); + assert_session_era!(0, 0); + + run_to_block(10); + assert_session_era!(1, 0); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + assert!(Staking::snapshot_nominators().is_none()); + assert!(Staking::snapshot_validators().is_none()); + + run_to_block(36); + assert_session_era!(3, 0); + + // fist era has session 0, which has 0 blocks length, so we have in total 40 blocks + // in the era. + run_to_block(37); + assert_session_era!(3, 0); + assert_eq!(Staking::era_election_status(), ElectionStatus::Open(37)); + assert!(Staking::snapshot_nominators().is_some()); + assert!(Staking::snapshot_validators().is_some()); + + run_to_block(38); + assert_eq!(Staking::era_election_status(), ElectionStatus::Open(37)); + + run_to_block(39); + assert_eq!(Staking::era_election_status(), ElectionStatus::Open(37)); + + run_to_block(40); + assert_session_era!(4, 0); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + assert!(Staking::snapshot_nominators().is_none()); + assert!(Staking::snapshot_validators().is_none()); + + run_to_block(86); + assert_session_era!(8, 1); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + assert!(Staking::snapshot_nominators().is_none()); + assert!(Staking::snapshot_validators().is_none()); + + // second era onwards has 50 blocks per era. + run_to_block(87); + assert_eq!(Staking::era_election_status(), ElectionStatus::Open(87)); + assert!(Staking::snapshot_nominators().is_some()); + assert!(Staking::snapshot_validators().is_some()); + + run_to_block(90); + assert_session_era!(9, 1); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + assert!(Staking::snapshot_nominators().is_none()); + assert!(Staking::snapshot_validators().is_none()); + }) + } + + #[test] + fn election_on_chain_fallback_works() { + ExtBuilder::default().build().execute_with(|| { + start_session(1); + start_session(2); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + // some election must have happened by now. + assert_eq!( + System::events() + .into_iter() + .map(|r| r.event) + .filter_map(|e| { + if let MetaEvent::staking(inner) = e { + Some(inner) + } else { + None + } + }) + .last() + .unwrap(), + RawEvent::StakingElection(ElectionCompute::OnChain), + ); + }) + } + + #[test] + #[ignore] // This takes a few mins + fn offchain_wont_work_if_snapshot_fails() { + ExtBuilder::default() + .offchain_phragmen_ext() + .election_lookahead(3) + .build() + .execute_with(|| { + run_to_block(12); + assert!(Staking::snapshot_validators().is_some()); + assert_eq!(Staking::era_election_status(), ElectionStatus::Open(12)); + + // validate more than the limit + let limit: NominatorIndex = ValidatorIndex::max_value() as NominatorIndex + 1; + let ctrl = 1_000_000; + for i in 0..limit { + bond_validator((1000 + i).into(), (1000 + i + ctrl).into(), 100); + } + + // window stays closed since no snapshot was taken. + run_to_block(27); + assert!(Staking::snapshot_validators().is_none()); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + }) + } + + #[test] + fn staking_is_locked_when_election_window_open() { + ExtBuilder::default() + .offchain_phragmen_ext() + .election_lookahead(3) + .build() + .execute_with(|| { + run_to_block(12); + assert!(Staking::snapshot_validators().is_some()); + assert_eq!(Staking::era_election_status(), ElectionStatus::Open(12)); + + let call = crate::Call::bond(999, 998, Default::default()); + let outer: mock::Call = call.into(); + + let lock_staking: LockStakingStatus = Default::default(); + assert_eq!( + lock_staking.validate(&10, &outer, Default::default(), Default::default(),), + TransactionValidity::Err(InvalidTransaction::Stale.into()), + ) + }) + } + + #[test] + fn signed_result_can_be_submitted() { + // should check that we have a new validator set normally, + // event says that it comes from offchain. + ExtBuilder::default() + .offchain_phragmen_ext() + .build() + .execute_with(|| { + run_to_block(12); + assert_eq!(Staking::era_election_status(), ElectionStatus::Open(12)); + assert!(Staking::snapshot_validators().is_some()); + + let (compact, winners, score) = prepare_submission_with(true, |_| {}); + assert_ok!(Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + )); + + let queued_result = Staking::queued_elected().unwrap(); + assert_eq!(queued_result.compute, ElectionCompute::Signed); + + run_to_block(15); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + + assert_eq!( + System::events() + .into_iter() + .map(|r| r.event) + .filter_map(|e| { + if let MetaEvent::staking(inner) = e { + Some(inner) + } else { + None + } + }) + .last() + .unwrap(), + RawEvent::StakingElection(ElectionCompute::Signed), + ); + }) + } + + #[test] + fn signed_result_can_be_submitted_later() { + // same as `signed_result_can_be_submitted` but at a later block. + ExtBuilder::default() + .offchain_phragmen_ext() + .build() + .execute_with(|| { + run_to_block(14); + assert_eq!(Staking::era_election_status(), ElectionStatus::Open(12)); + + let (compact, winners, score) = prepare_submission_with(true, |_| {}); + assert_ok!(Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + )); + + let queued_result = Staking::queued_elected().unwrap(); + assert_eq!(queued_result.compute, ElectionCompute::Signed); + + run_to_block(15); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + + assert_eq!( + System::events() + .into_iter() + .map(|r| r.event) + .filter_map(|e| { + if let MetaEvent::staking(inner) = e { + Some(inner) + } else { + None + } + }) + .last() + .unwrap(), + RawEvent::StakingElection(ElectionCompute::Signed), + ); + }) + } + + #[test] + fn early_solution_submission_is_rejected() { + // should check that we have a new validator set normally, + // event says that it comes from offchain. + ExtBuilder::default() + .offchain_phragmen_ext() + .build() + .execute_with(|| { + run_to_block(11); + // submission is not yet allowed + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + + // create all the indices just to build the solution. + Staking::create_stakers_snapshot(); + let (compact, winners, score) = prepare_submission_with(true, |_| {}); + Staking::kill_stakers_snapshot(); + + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenEarlySubmission, + ); + }) + } + + #[test] + fn weak_solution_is_rejected() { + // A solution which is weaker than what we currently have on-chain is rejected. + ExtBuilder::default() + .offchain_phragmen_ext() + .has_stakers(false) + .validator_count(4) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + // a good solution + let (compact, winners, score) = prepare_submission_with(true, |_| {}); + assert_ok!(Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + )); + + // a bad solution + let (compact, winners, score) = horrible_phragmen_with_post_processing(false); + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenWeakSubmission, + ); + }) + } + + #[test] + fn better_solution_is_accepted() { + // A solution which is better than what we currently have on-chain is accepted. + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + // a meeeeh solution + let (compact, winners, score) = horrible_phragmen_with_post_processing(false); + assert_ok!(Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + )); + + // a better solution + let (compact, winners, score) = prepare_submission_with(true, |_| {}); + assert_ok!(Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + )); + }) + } + + #[test] + fn offchain_worker_runs_when_window_open() { + // at the end of the first finalized block with ElectionStatus::open(_), it should execute. + let mut ext = ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(2) + .build(); + let state = offchainify(&mut ext); + ext.execute_with(|| { + run_to_block(12); + + // local key 11 is in the elected set. + assert_eq_uvec!(Session::validators(), vec![11, 21]); + assert_eq!(state.read().transactions.len(), 0); + Staking::offchain_worker(12); + assert_eq!(state.read().transactions.len(), 1); + + let encoded = state.read().transactions[0].clone(); + let extrinsic: Extrinsic = Decode::decode(&mut &*encoded).unwrap(); + + let call = extrinsic.call; + let inner = match call { + mock::Call::Staking(inner) => inner, + }; + + assert_eq!( + ::validate_unsigned( + TransactionSource::Local, + &inner, + ), + TransactionValidity::Ok(ValidTransaction { + priority: 1125, // the proposed slot stake. + requires: vec![], + provides: vec![("StakingOffchain", active_era()).encode()], + longevity: 3, + propagate: false, + }) + ) + }) + } + + #[test] + fn mediocre_submission_from_authority_is_early_rejected() { + let mut ext = ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .build(); + let state = offchainify(&mut ext); + ext.execute_with(|| { + run_to_block(12); + // put a good solution on-chain + let (compact, winners, score) = prepare_submission_with(true, |_| {}); + assert_ok!(Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ),); + + // now run the offchain worker in the same chain state. + Staking::offchain_worker(12); + assert_eq!(state.read().transactions.len(), 1); + + let encoded = state.read().transactions[0].clone(); + let extrinsic: Extrinsic = Decode::decode(&mut &*encoded).unwrap(); + + let call = extrinsic.call; + let inner = match call { + mock::Call::Staking(inner) => inner, + }; + + // pass this call to ValidateUnsigned + assert_eq!( + ::validate_unsigned( + TransactionSource::Local, + &inner, + ), + TransactionValidity::Err( + InvalidTransaction::Custom(>::PhragmenWeakSubmission.as_u8()).into(), + ), + ) + }) + } + + #[test] + fn invalid_phragmen_result_correct_number_of_winners() { + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + ValidatorCount::put(3); + let (compact, winners, score) = prepare_submission_with(true, |_| {}); + ValidatorCount::put(4); + + assert_eq!(winners.len(), 3); + + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenBogusWinnerCount, + ); + }) + } + + #[test] + fn invalid_phragmen_result_correct_number_of_winners_1() { + // if we have too little validators, then the number of candidates is the bound. + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(8) // we simply cannot elect 8 + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + ValidatorCount::put(3); + let (compact, winners, score) = prepare_submission_with(true, |_| {}); + ValidatorCount::put(4); + + assert_eq!(winners.len(), 3); + + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenBogusWinnerCount, + ); + }) + } + + #[test] + fn invalid_phragmen_result_correct_number_of_winners_2() { + // if we have too little validators, then the number of candidates is the bound. + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(8) // we simply cannot elect 8 + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + let (compact, winners, score) = prepare_submission_with(true, |_| {}); + + assert_eq!(winners.len(), 4); + + // all good. We chose 4 and it works. + assert_ok!(Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ),); + }) + } + + #[test] + fn invalid_phragmen_result_out_of_bound_nominator_index() { + // A nominator index which is simply invalid + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + assert_eq!(Staking::snapshot_nominators().unwrap().len(), 5 + 4); + assert_eq!(Staking::snapshot_validators().unwrap().len(), 4); + let (mut compact, winners, score) = prepare_submission_with(true, |_| {}); + + // index 9 doesn't exist. + compact.votes1.push((9, 2)); + + // The error type sadly cannot be more specific now. + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenBogusCompact, + ); + }) + } + + #[test] + fn invalid_phragmen_result_out_of_bound_validator_index() { + // A validator index which is out of bound + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + assert_eq!(Staking::snapshot_nominators().unwrap().len(), 5 + 4); + assert_eq!(Staking::snapshot_validators().unwrap().len(), 4); + let (mut compact, winners, score) = prepare_submission_with(true, |_| {}); + + // index 4 doesn't exist. + compact.votes1.push((3, 4)); + + // The error type sadly cannot be more specific now. + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenBogusCompact, + ); + }) + } + + #[test] + fn invalid_phragmen_result_out_of_bound_winner_index() { + // A winner index which is simply invalid + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + assert_eq!(Staking::snapshot_nominators().unwrap().len(), 5 + 4); + assert_eq!(Staking::snapshot_validators().unwrap().len(), 4); + let (compact, _, score) = prepare_submission_with(true, |_| {}); + + // index 4 doesn't exist. + let winners = vec![0, 1, 2, 4]; + + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenBogusWinner, + ); + }) + } + + #[test] + fn invalid_phragmen_result_non_winner_validator_index() { + // An edge that points to a correct validator index who is NOT a winner. This is very + // similar to the test that raises `PhragmenBogusNomination`. + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(2) // we select only 2. + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + assert_eq!(Staking::snapshot_nominators().unwrap().len(), 5 + 4); + assert_eq!(Staking::snapshot_validators().unwrap().len(), 4); + let (compact, winners, score) = prepare_submission_with(true, |a| { + a.iter_mut() + .find(|x| x.who == 5) + // all 3 cannot be among the winners. Although, all of them are validator + // candidates. + .map(|x| x.distribution = vec![(21, 50), (41, 30), (31, 20)]); + }); + + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenBogusEdge, + ); + }) + } + + #[test] + fn invalid_phragmen_result_wrong_self_vote() { + // A self vote for someone else. + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + let (compact, winners, score) = prepare_submission_with(true, |a| { + // mutate a self vote to target someone else. That someone else is still among the + // winners + a.iter_mut().find(|x| x.who == 11).map(|x| { + x.distribution + .iter_mut() + .find(|y| y.0 == 11) + .map(|y| y.0 = 21) + }); + }); + + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenBogusSelfVote, + ); + }) + } + + #[test] + fn invalid_phragmen_result_wrong_self_vote_2() { + // A self validator voting for someone else next to self vote. + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + let (compact, winners, score) = prepare_submission_with(true, |a| { + // Remove the self vote. + a.retain(|x| x.who != 11); + // add is as a new double vote + a.push(StakedAssignment { + who: 11, + distribution: vec![(11, 50), (21, 50)], + }); + }); + + // This raises score issue. + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenBogusSelfVote, + ); + }) + } + + #[test] + fn invalid_phragmen_result_over_stake() { + // Someone's edge ratios sums to more than 100%. + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + // Note: we don't reduce here to be able to tweak votes3. votes3 will vanish if you + // reduce. + let (mut compact, winners, score) = prepare_submission_with(false, |_| {}); + + if let Some(c) = compact.votes3.iter_mut().find(|x| x.0 == 0) { + // by default it should have been (0, [(2, 33%), (1, 33%)], 0) + // now the sum is above 100% + c.1 = [(2, percent(66)), (1, percent(66))]; + } + + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenBogusCompact, + ); + }) + } + + #[test] + fn invalid_phragmen_result_under_stake() { + // at the time of this writing, we cannot under stake someone. The compact assignment works + // in a way that some of the stakes are presented by the submitter, and the last one is read + // from chain by subtracting the rest from total. Hence, the sum is always correct. + // This test is only here as a demonstration. + } + + #[test] + fn invalid_phragmen_result_invalid_target_stealing() { + // A valid voter who voted for someone who is a candidate, and is a correct winner, but is + // actually NOT nominated by this nominator. + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + let (compact, winners, score) = prepare_submission_with(false, |a| { + // 3 only voted for 20 and 40. We add a fake vote to 30. The stake sum is still + // correctly 100. + a.iter_mut() + .find(|x| x.who == 3) + .map(|x| x.distribution = vec![(21, 50), (41, 30), (31, 20)]); + }); + + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenBogusNomination, + ); + }) + } + + #[test] + fn nomination_slash_filter_is_checked() { + // If a nominator has voted for someone who has been recently slashed, that particular + // nomination should be disabled for the upcoming election. A solution must respect this + // rule. + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + + // finalize the round with fallback. This is needed since all nominator submission + // are in era zero and we want this one to pass with no problems. + run_to_block(15); + + // go to the next session to trigger start_era and bump the active era + run_to_block(20); + + // slash 10. This must happen outside of the election window. + let offender_expo = Staking::eras_stakers(active_era(), 11); + on_offence_now( + &[OffenceDetails { + offender: (11, offender_expo.clone()), + reporters: vec![], + }], + &[Perbill::from_percent(50)], + ); + + // validate 10 again for the next round. But this guy will not have the votes that + // it should have had from 1 and 2. + assert_ok!(Staking::validate( + Origin::signed(10), + Default::default() + )); + + // open the election window and create snapshots. + run_to_block(32); + + // a solution that has been prepared after the slash. + let (compact, winners, score) = prepare_submission_with(false, |a| { + // no one is allowed to vote for 10, except for itself. + a.into_iter() + .filter(|s| s.who != 11) + .for_each(|s| + assert!(s.distribution.iter().find(|(t, _)| *t == 11).is_none()) + ); + }); + + // can be submitted. + assert_ok!(Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + )); + + // a wrong solution. + let (compact, winners, score) = prepare_submission_with(false, |a| { + // add back the vote that has been filtered out. + a.push(StakedAssignment { + who: 1, + distribution: vec![(11, 100)] + }); + }); + + // is rejected. + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenSlashedNomination, + ); + }) + } + + #[test] + fn invalid_phragmen_result_wrong_score() { + // A valid voter who's total distributed stake is more than what they bond + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .has_stakers(false) + .build() + .execute_with(|| { + build_offchain_phragmen_test_ext(); + run_to_block(12); + + let (compact, winners, mut score) = prepare_submission_with(true, |_| {}); + score[0] += 1; + + assert_noop!( + Staking::submit_election_solution( + Origin::signed(10), + winners, + compact, + score, + active_era(), + ), + Error::::PhragmenBogusScore, + ); + }) + } + + #[test] + fn offchain_storage_is_set() { + let mut ext = ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .build(); + let state = offchainify(&mut ext); + + ext.execute_with(|| { + use offchain_election::OFFCHAIN_HEAD_DB; + use sp_runtime::offchain::storage::StorageValueRef; + + run_to_block(12); + + Staking::offchain_worker(12); + // it works + assert_eq!(state.read().transactions.len(), 1); + + // and it is set + let storage = StorageValueRef::persistent(&OFFCHAIN_HEAD_DB); + assert_eq!(storage.get::().unwrap().unwrap(), 12); + }) + } + + #[test] + fn offchain_storage_prevents_duplicate() { + let mut ext = ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .build(); + let _ = offchainify(&mut ext); + + ext.execute_with(|| { + use offchain_election::OFFCHAIN_HEAD_DB; + use sp_runtime::offchain::storage::StorageValueRef; + let storage = StorageValueRef::persistent(&OFFCHAIN_HEAD_DB); + + run_to_block(12); + + // first run -- ok + assert_eq!( + offchain_election::set_check_offchain_execution_status::(12), + Ok(()), + ); + assert_eq!(storage.get::().unwrap().unwrap(), 12); + + // re-execute after the next. not allowed. + assert_eq!( + offchain_election::set_check_offchain_execution_status::(13), + Err("recently executed."), + ); + + // a fork like situation -- re-execute 10, 11, 12. But it won't go through. + assert_eq!( + offchain_election::set_check_offchain_execution_status::(10), + Err("fork."), + ); + assert_eq!( + offchain_election::set_check_offchain_execution_status::(11), + Err("fork."), + ); + assert_eq!( + offchain_election::set_check_offchain_execution_status::(12), + Err("recently executed."), + ); + }) + } + + #[test] + #[should_panic] + fn offence_is_blocked_when_window_open() { + ExtBuilder::default() + .offchain_phragmen_ext() + .validator_count(4) + .has_stakers(false) + .build() + .execute_with(|| { + run_to_block(12); + assert_eq!(Staking::era_election_status(), ElectionStatus::Open(12)); + + let offender_expo = Staking::eras_stakers(active_era(), 10); + + // panic from the impl in mock + on_offence_now( + &[OffenceDetails { + offender: (10, offender_expo.clone()), + reporters: vec![], + }], + &[Perbill::from_percent(10)], + ); + }) + } +} + #[test] -fn slash_kicks_validators_not_nominators() { +fn slash_kicks_validators_not_nominators_and_disables_nominator_for_kicked_validator() { ExtBuilder::default().build().execute_with(|| { start_era(1); + assert_eq_uvec!(Session::validators(), vec![11, 21]); + // pre-slash balance assert_eq!(Balances::free_balance(11), 1000); - - let exposure = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); assert_eq!(Balances::free_balance(101), 2000); - let nominated_value = exposure.others.iter().find(|o| o.who == 101).unwrap().value; + + // 11 and 21 both have the support of 100 + let exposure_11 = Staking::eras_stakers(active_era(), &11); + let exposure_21 = Staking::eras_stakers(active_era(), &21); + + assert_eq!(exposure_11.total, 1000 + 125); + assert_eq!(exposure_21.total, 1000 + 375); on_offence_now( - &[ - OffenceDetails { - offender: (11, exposure.clone()), - reporters: vec![], - }, - ], + &[OffenceDetails { + offender: (11, exposure_11.clone()), + reporters: vec![], + }], &[Perbill::from_percent(10)], ); + // post-slash balance + let nominator_slash_amount_11 = 125 / 10; assert_eq!(Balances::free_balance(11), 900); - assert_eq!(Balances::free_balance(101), 2000 - (nominated_value / 10)); + assert_eq!( + Balances::free_balance(101), + 2000 - nominator_slash_amount_11 + ); // This is the best way to check that the validator was chilled; `get` will // return default value. @@ -2776,8 +3843,23 @@ fn slash_kicks_validators_not_nominators() { // and make sure that the vote will be ignored even if the validator // re-registers. - let last_slash = ::SlashingSpans::get(&11).unwrap().last_nonzero_slash(); + let last_slash = ::SlashingSpans::get(&11) + .unwrap() + .last_nonzero_slash(); assert!(nominations.submitted_in < last_slash); + + // actually re-bond the slashed validator + assert_ok!(Staking::validate(Origin::signed(10), Default::default())); + + start_era(2); + let exposure_11 = Staking::eras_stakers(active_era(), &11); + let exposure_21 = Staking::eras_stakers(active_era(), &21); + + // 10 is re-elected, but without the support of 100 + assert_eq!(exposure_11.total, 900); + + // 20 is re-elected, with the (almost) entire support of 100 + assert_eq!(exposure_21.total, 1000 + 500 - nominator_slash_amount_11); }); } @@ -2890,7 +3972,7 @@ fn zero_slash_keeps_nominators() { assert_eq!(Balances::free_balance(11), 1000); - let exposure = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); + let exposure = Staking::eras_stakers(active_era(), 11); assert_eq!(Balances::free_balance(101), 2000); on_offence_now( diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 507cda53ed..77e4c679f4 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -24,7 +24,7 @@ use sp_core::u32_trait::Value as U32; use sp_runtime::{ RuntimeDebug, ConsensusEngineId, DispatchResult, DispatchError, - traits::{MaybeSerializeDeserialize, AtLeast32Bit, Saturating, TrailingZeroInput}, + traits::{MaybeSerializeDeserialize, AtLeast32Bit, Saturating, TrailingZeroInput, Bounded}, }; use crate::dispatch::Parameter; use crate::storage::StorageMap; @@ -87,7 +87,7 @@ impl< Created: Happened, Removed: Happened, K: FullCodec, - T: FullCodec + T: FullCodec, > StoredMap for StorageMapShim { fn get(k: &K) -> T { S::get(k) } fn is_explicit(k: &K) -> bool { S::contains_key(k) } @@ -138,6 +138,35 @@ impl< } } +/// Something that can estimate at which block the next session rotation will happen. This should +/// be the same logical unit that dictates `ShouldEndSession` to the session module. No Assumptions +/// are made about the scheduling of the sessions. +pub trait EstimateNextSessionRotation { + /// Return the block number at which the next session rotation is estimated to happen. + /// + /// None should be returned if the estimation fails to come to an answer + fn estimate_next_session_rotation(now: BlockNumber) -> Option; +} + +impl EstimateNextSessionRotation for () { + fn estimate_next_session_rotation(_: BlockNumber) -> Option { + Default::default() + } +} + +/// Something that can estimate at which block the next `new_session` will be triggered. This must +/// always be implemented by the session module. +pub trait EstimateNextNewSession { + /// Return the block number at which the next new session is estimated to happen. + fn estimate_next_new_session(now: BlockNumber) -> Option; +} + +impl EstimateNextNewSession for () { + fn estimate_next_new_session(_: BlockNumber) -> Option { + Default::default() + } +} + /// Anything that can have a `::len()` method. pub trait Len { /// Return the length of data type. diff --git a/frame/system/src/offchain.rs b/frame/system/src/offchain.rs index 5abafe7655..a3fe3e00ca 100644 --- a/frame/system/src/offchain.rs +++ b/frame/system/src/offchain.rs @@ -95,7 +95,8 @@ impl Signer for TAnyAppPubl } /// Retrieves a public key type for given `SignAndSubmitTransaction`. -pub type PublicOf = < +pub type PublicOf = +< >::CreateTransaction as CreateTransaction>::Extrinsic> @@ -109,7 +110,7 @@ pub type PublicOf = < /// you should use. pub trait SignAndSubmitTransaction { /// Unchecked extrinsic type. - type Extrinsic: ExtrinsicT + codec::Encode; + type Extrinsic: ExtrinsicT + Encode; /// A runtime-specific type to produce signed data for the extrinsic. type CreateTransaction: CreateTransaction; @@ -156,7 +157,7 @@ pub trait SignAndSubmitTransaction { /// you should use. pub trait SubmitUnsignedTransaction { /// Unchecked extrinsic type. - type Extrinsic: ExtrinsicT + codec::Encode; + type Extrinsic: ExtrinsicT + Encode; /// Submit given call to the transaction pool as unsigned transaction. /// @@ -164,7 +165,8 @@ pub trait SubmitUnsignedTransaction { /// and `Err` if transaction was rejected from the pool. fn submit_unsigned(call: impl Into) -> Result<(), ()> { let xt = Self::Extrinsic::new(call.into(), None).ok_or(())?; - sp_io::offchain::submit_transaction(xt.encode()) + let encoded_xt = xt.encode(); + sp_io::offchain::submit_transaction(encoded_xt) } } @@ -291,7 +293,7 @@ impl SignAndSubmitTransaction for TransactionSubmitte T: crate::Trait, C: CreateTransaction, S: Signer<>::Public, >::Signature>, - E: ExtrinsicT + codec::Encode, + E: ExtrinsicT + Encode, { type Extrinsic = E; type CreateTransaction = C; @@ -301,7 +303,7 @@ impl SignAndSubmitTransaction for TransactionSubmitte /// A blanket implementation to use the same submitter for unsigned transactions as well. impl SubmitUnsignedTransaction for TransactionSubmitter where T: crate::Trait, - E: ExtrinsicT + codec::Encode, + E: ExtrinsicT + Encode, { type Extrinsic = E; } @@ -310,7 +312,7 @@ impl SubmitUnsignedTransaction for TransactionSubmitt impl SubmitSignedTransaction for TransactionSubmitter where T: crate::Trait, C: CreateTransaction, - E: ExtrinsicT + codec::Encode, + E: ExtrinsicT + Encode, S: Signer<>::Public, >::Signature>, // Make sure we can unwrap the app crypto key. S: RuntimeAppPublic + AppPublic + Into<::Generic>, diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index a9da383061..1078927747 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -106,11 +106,6 @@ impl Module { /// /// All dispatchables must be annotated with weight and will have some fee info. This function /// always returns. - // NOTE: we can actually make it understand `ChargeTransactionPayment`, but would be some hassle - // for sure. We have to make it aware of the index of `ChargeTransactionPayment` in `Extra`. - // Alternatively, we could actually execute the tx's per-dispatch and record the balance of the - // sender before and after the pipeline.. but this is way too much hassle for a very very little - // potential gain in the future. pub fn query_info( unchecked_extrinsic: Extrinsic, len: u32, @@ -119,6 +114,11 @@ impl Module { T: Send + Sync, BalanceOf: Send + Sync, { + // NOTE: we can actually make it understand `ChargeTransactionPayment`, but would be some + // hassle for sure. We have to make it aware of the index of `ChargeTransactionPayment` in + // `Extra`. Alternatively, we could actually execute the tx's per-dispatch and record the + // balance of the sender before and after the pipeline.. but this is way too much hassle for + // a very very little potential gain in the future. let dispatch_info = ::get_dispatch_info(&unchecked_extrinsic); let partial_fee = diff --git a/primitives/arithmetic/fuzzer/Cargo.lock b/primitives/arithmetic/fuzzer/Cargo.lock new file mode 100644 index 0000000000..c7b703c139 --- /dev/null +++ b/primitives/arithmetic/fuzzer/Cargo.lock @@ -0,0 +1,401 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "arbitrary" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cf76cb6e2222ed0ea86b2b0ee2f71c96ec6edd5af42e84d59160e91b836ec4" + +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" + +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" + +[[package]] +name = "bitvec" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" + +[[package]] +name = "byte-slice-cast" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "c2-chacha" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" +dependencies = [ + "ppv-lite86", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "fixed-hash" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "getrandom" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "honggfuzz" +version = "0.5.45" +dependencies = [ + "arbitrary", + "lazy_static", + "memmap", +] + +[[package]] +name = "impl-codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "integer-sqrt" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" + +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +dependencies = [ + "autocfg", +] + +[[package]] +name = "parity-scale-codec" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f509c5e67ca0605ee17dcd3f91ef41cadd685c75a298fb6261b781a5acb3f910" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" + +[[package]] +name = "primitive-types" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" +dependencies = [ + "fixed-hash", + "impl-codec", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" +dependencies = [ + "c2-chacha", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "serde" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-arithmetic" +version = "2.0.0-alpha.3" +dependencies = [ + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "serde", + "sp-debug-derive", + "sp-std", +] + +[[package]] +name = "sp-arithmetic-fuzzer" +version = "2.0.0" +dependencies = [ + "honggfuzz", + "num-bigint", + "num-traits", + "primitive-types", + "sp-arithmetic", +] + +[[package]] +name = "sp-debug-derive" +version = "2.0.0-alpha.3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-std" +version = "2.0.0-alpha.3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +dependencies = [ + "serde", +] + +[[package]] +name = "uint" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" +dependencies = [ + "byteorder", + "crunchy", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/primitives/arithmetic/fuzzer/Cargo.toml b/primitives/arithmetic/fuzzer/Cargo.toml index 895ee60bd8..717ce2713b 100644 --- a/primitives/arithmetic/fuzzer/Cargo.toml +++ b/primitives/arithmetic/fuzzer/Cargo.toml @@ -20,6 +20,10 @@ num-traits = "0.2" name = "biguint" path = "src/biguint.rs" +[[bin]] +name = "per_thing_rational" +path = "src/per_thing_rational.rs" + [[bin]] name = "rational128" path = "src/rational128.rs" diff --git a/primitives/arithmetic/fuzzer/src/per_thing_rational.rs b/primitives/arithmetic/fuzzer/src/per_thing_rational.rs new file mode 100644 index 0000000000..84207cbd16 --- /dev/null +++ b/primitives/arithmetic/fuzzer/src/per_thing_rational.rs @@ -0,0 +1,123 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! # Running +//! Running this fuzzer can be done with `cargo hfuzz run per_thing_rational`. `honggfuzz` CLI options can +//! be used by setting `HFUZZ_RUN_ARGS`, such as `-n 4` to use 4 threads. +//! +//! # Debugging a panic +//! Once a panic is found, it can be debugged with +//! `cargo hfuzz run-debug per_thing_rational hfuzz_workspace/per_thing_rational/*.fuzz`. + +use honggfuzz::fuzz; +use sp_arithmetic::{ + PerThing, PerU16, Percent, Perbill, Perquintill, assert_eq_error_rate, + traits::SaturatedConversion, +}; + +fn main() { + loop { + fuzz!(| + data: ((u16, u16), (u32, u32), (u64, u64)) + | { + + let (u16_pair, u32_pair, u64_pair) = data; + + // peru16 + let (smaller, bigger) = (u16_pair.0.min(u16_pair.1), u16_pair.0.max(u16_pair.1)); + let ratio = PerU16::from_rational_approximation(smaller, bigger); + assert_per_thing_equal_error( + ratio, + PerU16::from_fraction(smaller as f64 / bigger.max(1) as f64), + 1, + ); + let (smaller, bigger) = (u32_pair.0.min(u32_pair.1), u32_pair.0.max(u32_pair.1)); + let ratio = PerU16::from_rational_approximation(smaller, bigger); + assert_per_thing_equal_error( + ratio, + PerU16::from_fraction(smaller as f64 / bigger.max(1) as f64), + 1, + ); + let (smaller, bigger) = (u64_pair.0.min(u64_pair.1), u64_pair.0.max(u64_pair.1)); + let ratio = PerU16::from_rational_approximation(smaller, bigger); + assert_per_thing_equal_error( + ratio, + PerU16::from_fraction(smaller as f64 / bigger.max(1) as f64), + 1, + ); + + // percent + let (smaller, bigger) = (u16_pair.0.min(u16_pair.1), u16_pair.0.max(u16_pair.1)); + let ratio = Percent::from_rational_approximation(smaller, bigger); + assert_per_thing_equal_error( + ratio, + Percent::from_fraction(smaller as f64 / bigger.max(1) as f64), + 1, + ); + + let (smaller, bigger) = (u32_pair.0.min(u32_pair.1), u32_pair.0.max(u32_pair.1)); + let ratio = Percent::from_rational_approximation(smaller, bigger); + assert_per_thing_equal_error( + ratio, + Percent::from_fraction(smaller as f64 / bigger.max(1) as f64), + 1, + ); + + let (smaller, bigger) = (u64_pair.0.min(u64_pair.1), u64_pair.0.max(u64_pair.1)); + let ratio = Percent::from_rational_approximation(smaller, bigger); + assert_per_thing_equal_error( + ratio, + Percent::from_fraction(smaller as f64 / bigger.max(1) as f64), + 1, + ); + + // perbill + let (smaller, bigger) = (u32_pair.0.min(u32_pair.1), u32_pair.0.max(u32_pair.1)); + let ratio = Perbill::from_rational_approximation(smaller, bigger); + assert_per_thing_equal_error( + ratio, + Perbill::from_fraction(smaller as f64 / bigger.max(1) as f64), + 100, + ); + + let (smaller, bigger) = (u64_pair.0.min(u64_pair.1), u64_pair.0.max(u64_pair.1)); + let ratio = Perbill::from_rational_approximation(smaller, bigger); + assert_per_thing_equal_error( + ratio, + Perbill::from_fraction(smaller as f64 / bigger.max(1) as f64), + 100, + ); + + // perquintillion + let (smaller, bigger) = (u64_pair.0.min(u64_pair.1), u64_pair.0.max(u64_pair.1)); + let ratio = Perquintill::from_rational_approximation(smaller, bigger); + assert_per_thing_equal_error( + ratio, + Perquintill::from_fraction(smaller as f64 / bigger.max(1) as f64), + 1000, + ); + + }) + } +} + +fn assert_per_thing_equal_error(a: T, b: T, err: u128) { + let a_abs = a.deconstruct().saturated_into::(); + let b_abs = b.deconstruct().saturated_into::(); + let diff = a_abs.max(b_abs) - a_abs.min(b_abs); + dbg!(&diff); + assert!(diff <= err, "{:?} !~ {:?}", a, b); +} diff --git a/primitives/arithmetic/src/lib.rs b/primitives/arithmetic/src/lib.rs index c2feae00b7..f6d8b53e34 100644 --- a/primitives/arithmetic/src/lib.rs +++ b/primitives/arithmetic/src/lib.rs @@ -19,7 +19,7 @@ #![cfg_attr(not(feature = "std"), no_std)] /// Copied from `sp-runtime` and documented there. -#[cfg(test)] +#[macro_export] macro_rules! assert_eq_error_rate { ($x:expr, $y:expr, $error:expr $(,)?) => { assert!( @@ -40,5 +40,17 @@ mod fixed64; mod rational128; pub use fixed64::Fixed64; -pub use per_things::{PerThing, Percent, Permill, Perbill, Perquintill}; +pub use per_things::{PerThing, Percent, PerU16, Permill, Perbill, Perquintill}; pub use rational128::Rational128; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn peru16_rational_does_not_overflow() { + // A historical example that will panic only for per_thing type that are created with + // maximum capacity of their type, e.g. PerU16. + let _ = PerU16::from_rational_approximation(17424870u32, 17424870); + } +} diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index cbb804baf5..ca6967456b 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -17,18 +17,24 @@ #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; -use sp_std::{ops, prelude::*, convert::TryInto}; +use sp_std::{ops, fmt, prelude::*, convert::TryInto}; use codec::{Encode, Decode, CompactAs}; -use crate::traits::{ - SaturatedConversion, UniqueSaturatedInto, Saturating, BaseArithmetic, +use crate::{ + traits::{SaturatedConversion, UniqueSaturatedInto, Saturating, BaseArithmetic, Bounded}, }; use sp_debug_derive::RuntimeDebug; /// Something that implements a fixed point ration with an arbitrary granularity `X`, as _parts per /// `X`_. -pub trait PerThing: Sized + Saturating + Copy { +pub trait PerThing: + Sized + Saturating + Copy + Default + Eq + PartialEq + Ord + PartialOrd + Bounded + fmt::Debug +{ /// The data type used to build this per-thingy. - type Inner: BaseArithmetic + Copy; + type Inner: BaseArithmetic + Copy + fmt::Debug; + + /// The data type that is used to store values bigger than the maximum of this type. This must + /// at least be able to store `Self::ACCURACY * Self::ACCURACY`. + type Upper: BaseArithmetic + Copy + fmt::Debug; /// accuracy of this type const ACCURACY: Self::Inner; @@ -63,12 +69,53 @@ pub trait PerThing: Sized + Saturating + Copy { /// The computation of this approximation is performed in the generic type `N`. Given /// `M` as the data type that can hold the maximum value of this per-thing (e.g. u32 for /// perbill), this can only work if `N == M` or `N: From + TryInto`. + /// + /// Note that this always rounds _down_, i.e. + /// + /// ```rust + /// # use sp_arithmetic::{Percent, PerThing}; + /// # fn main () { + /// // 989/100 is technically closer to 99%. + /// assert_eq!( + /// Percent::from_rational_approximation(989, 1000), + /// Percent::from_parts(98), + /// ); + /// # } + /// ``` fn from_rational_approximation(p: N, q: N) -> Self - where N: Clone + Ord + From + TryInto + ops::Div; + where N: + Clone + Ord + From + TryInto + TryInto + + ops::Div + ops::Rem + ops::Add; + + /// A mul implementation that always rounds down, whilst the standard `Mul` implementation + /// rounds to the nearest numbers + /// + /// ```rust + /// # use sp_arithmetic::{Percent, PerThing}; + /// # fn main () { + /// // rounds to closest + /// assert_eq!(Percent::from_percent(34) * 10u64, 3); + /// assert_eq!(Percent::from_percent(36) * 10u64, 4); + /// + /// // collapse down + /// assert_eq!(Percent::from_percent(34).mul_collapse(10u64), 3); + /// assert_eq!(Percent::from_percent(36).mul_collapse(10u64), 3); + /// # } + /// ``` + fn mul_collapse(self, b: N) -> N + where N: Clone + From + UniqueSaturatedInto + ops::Rem + + ops::Div + ops::Mul + ops::Add; } macro_rules! implement_per_thing { - ($name:ident, $test_mod:ident, [$($test_units:tt),+], $max:tt, $type:ty, $upper_type:ty, $title:expr $(,)?) => { + ( + $name:ident, + $test_mod:ident, + [$($test_units:tt),+], + $max:tt, $type:ty, + $upper_type:ty, + $title:expr $(,)? + ) => { /// A fixed point representation of a number between in the range [0, 1]. /// #[doc = $title] @@ -78,33 +125,30 @@ macro_rules! implement_per_thing { impl PerThing for $name { type Inner = $type; + type Upper = $upper_type; - /// The accuracy of this type. const ACCURACY: Self::Inner = $max; - /// Nothing. fn zero() -> Self { Self(0) } - /// `true` if this is nothing. fn is_zero(&self) -> bool { self.0 == 0 } - /// Everything. fn one() -> Self { Self($max) } - /// Consume self and deconstruct into a raw numeric type. fn deconstruct(self) -> Self::Inner { self.0 } - /// From an explicitly defined number of parts per maximum of the type. + // needed only for peru16. Since peru16 is the only type in which $max == + // $type::max_value(), rustc is being a smart-a** here by warning that the comparison + // is not needed. + #[allow(unused_comparisons)] fn from_parts(parts: Self::Inner) -> Self { Self([parts, $max][(parts > $max) as usize]) } - /// Converts a percent into `Self`. Equal to `x / 100`. fn from_percent(x: Self::Inner) -> Self { - Self([x, 100][(x > 100) as usize] * ($max / 100)) + Self::from_rational_approximation([x, 100][(x > 100) as usize] as $upper_type, 100) } - /// Return the product of multiplication of this value by itself. fn square(self) -> Self { // both can be safely casted and multiplied. let p: $upper_type = self.0 as $upper_type * self.0 as $upper_type; @@ -112,39 +156,43 @@ macro_rules! implement_per_thing { Self::from_rational_approximation(p, q) } - /// Converts a fraction into `Self`. #[cfg(feature = "std")] fn from_fraction(x: f64) -> Self { Self((x * ($max as f64)) as Self::Inner) } - /// Approximate the fraction `p/q` into a per-thing fraction. This will never overflow. - /// - /// The computation of this approximation is performed in the generic type `N`. Given - /// `M` as the data type that can hold the maximum value of this per-thing (e.g. u32 for - /// perbill), this can only work if `N == M` or `N: From + TryInto`. fn from_rational_approximation(p: N, q: N) -> Self - where N: Clone + Ord + From + TryInto + ops::Div + where N: + Clone + Ord + From + TryInto + TryInto + + ops::Div + ops::Rem + ops::Add { + let div_ceil = |x: N, f: N| -> N { + let mut o = x.clone() / f.clone(); + let r = x.rem(f.clone()); + if r > N::from(0) { + o = o + N::from(1); + } + o + }; + // q cannot be zero. - let q = q.max((1 as Self::Inner).into()); + let q: N = q.max((1 as Self::Inner).into()); // p should not be bigger than q. - let p = p.min(q.clone()); + let p: N = p.min(q.clone()); - let factor = (q.clone() / $max.into()).max((1 as Self::Inner).into()); + let factor: N = div_ceil(q.clone(), $max.into()).max((1 as Self::Inner).into()); - // q cannot overflow: (q / (q/$max)) < 2 * $max. p < q hence p also cannot overflow. - // this implies that Self::Inner must be able to fit 2 * $max. - let q_reduce: Self::Inner = (q / factor.clone()) + // q cannot overflow: (q / (q/$max)) < $max. p < q hence p also cannot overflow. + let q_reduce: $type = (q.clone() / factor.clone()) .try_into() .map_err(|_| "Failed to convert") .expect( - "q / (q/$max) < (2 * $max). Macro prevents any type being created that \ + "q / ceil(q/$max) < $max. Macro prevents any type being created that \ does not satisfy this; qed" ); - let p_reduce: Self::Inner = (p / factor.clone()) + let p_reduce: $type = (p / factor) .try_into() .map_err(|_| "Failed to convert") .expect( - "q / (q/$max) < (2 * $max). Macro prevents any type being created that \ + "q / ceil(q/$max) < $max. Macro prevents any type being created that \ does not satisfy this; qed" ); @@ -157,13 +205,49 @@ macro_rules! implement_per_thing { $name(part as Self::Inner) } + + fn mul_collapse(self, b: N) -> N + where + N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + + ops::Div + ops::Mul + ops::Add + { + let maximum: N = $max.into(); + let upper_max: $upper_type = $max.into(); + let part: N = self.0.into(); + + let rem_multiplied_divided = { + let rem = b.clone().rem(maximum.clone()); + + // `rem_sized` is inferior to $max, thus it fits into $type. This is assured by + // a test. + let rem_sized = rem.saturated_into::<$type>(); + + // `self` and `rem_sized` are inferior to $max, thus the product is less than + // $max^2 and fits into $upper_type. This is assured by a test. + let rem_multiplied_upper = rem_sized as $upper_type * self.0 as $upper_type; + + // `rem_multiplied_upper` is less than $max^2 therefore divided by $max it fits + // in $type. remember that $type always fits $max. + let rem_multiplied_divided_sized = + (rem_multiplied_upper / upper_max) as $type; + + // `rem_multiplied_divided_sized` is inferior to b, thus it can be converted + // back to N type + rem_multiplied_divided_sized.into() + }; + + (b / maximum) * part + rem_multiplied_divided + } } - /// Implement const functions impl $name { /// From an explicitly defined number of parts per maximum of the type. /// /// This can be called at compile time. + // needed only for peru16. Since peru16 is the only type in which $max == + // $type::max_value(), rustc is being a smart-a** here by warning that the comparison + // is not needed. + #[allow(unused_comparisons)] pub const fn from_parts(parts: $type) -> Self { Self([parts, $max][(parts > $max) as usize]) } @@ -202,6 +286,16 @@ macro_rules! implement_per_thing { } } + impl crate::traits::Bounded for $name { + fn min_value() -> Self { + ::zero() + } + + fn max_value() -> Self { + ::one() + } + } + impl ops::Div for $name { type Output = Self; @@ -212,9 +306,10 @@ macro_rules! implement_per_thing { } } - /// Overflow-prune multiplication. + /// Non-overflow multiplication. /// /// tailored to be used with a balance type. + /// impl ops::Mul for $name where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem @@ -241,6 +336,7 @@ macro_rules! implement_per_thing { // in $type. remember that $type always fits $max. let mut rem_multiplied_divided_sized = (rem_multiplied_upper / upper_max) as $type; + // fix a tiny rounding error if rem_multiplied_upper % upper_max > upper_max / 2 { rem_multiplied_divided_sized += 1; @@ -261,15 +357,17 @@ macro_rules! implement_per_thing { use super::{$name, Saturating, RuntimeDebug, PerThing}; use crate::traits::Zero; - #[test] fn macro_expanded_correctly() { - // needed for the `from_percent` to work. - assert!($max >= 100); - assert!($max % 100 == 0); + // needed for the `from_percent` to work. UPDATE: this is no longer needed; yet note + // that tests that use percentage or fractions such as $name::from_fraction(0.2) to + // create values will most likely be inaccurate when used with per_things that are + // not multiples of 100. + // assert!($max >= 100); + // assert!($max % 100 == 0); // needed for `from_rational_approximation` - assert!(2 * $max < <$type>::max_value()); + assert!(2 * ($max as $upper_type) < <$upper_type>::max_value()); assert!(<$upper_type>::from($max) < <$upper_type>::max_value()); // for something like percent they can be the same. @@ -298,7 +396,7 @@ macro_rules! implement_per_thing { (63, 1), (64, 2), (65, 2), - (<$type>::max_value(), <$type>::max_value().encode().len() + 1) + // (<$type>::max_value(), <$type>::max_value().encode().len() + 1) ]; for &(n, l) in &tests { let compact: codec::Compact<$name> = $name(n).into(); @@ -317,33 +415,73 @@ macro_rules! implement_per_thing { assert_eq!($name::zero(), $name::from_parts(Zero::zero())); assert_eq!($name::one(), $name::from_parts($max)); assert_eq!($name::ACCURACY, $max); - assert_eq!($name::from_percent(0), $name::from_parts(Zero::zero())); - assert_eq!($name::from_percent(10), $name::from_parts($max / 10)); - assert_eq!($name::from_percent(100), $name::from_parts($max)); + assert_eq!($name::from_fraction(0.0), $name::from_parts(Zero::zero())); + assert_eq!($name::from_fraction(0.1), $name::from_parts($max / 10)); + assert_eq!($name::from_fraction(1.0), $name::from_parts($max)); + } + + macro_rules! u256ify { + ($val:expr) => { + Into::::into($val) + }; } macro_rules! per_thing_mul_test { ($num_type:tt) => { // multiplication from all sort of from_percent assert_eq!( - $name::from_percent(100) * $num_type::max_value(), + $name::from_fraction(1.0) * $num_type::max_value(), $num_type::max_value() ); - assert_eq_error_rate!( - $name::from_percent(99) * $num_type::max_value(), - ((Into::::into($num_type::max_value()) * 99u32) / 100u32).as_u128() as $num_type, - 1, - ); - assert_eq!( - $name::from_percent(50) * $num_type::max_value(), - $num_type::max_value() / 2, - ); - assert_eq_error_rate!( - $name::from_percent(1) * $num_type::max_value(), - $num_type::max_value() / 100, - 1, - ); - assert_eq!($name::from_percent(0) * $num_type::max_value(), 0); + if $max % 100 == 0 { + assert_eq_error_rate!( + $name::from_percent(99) * $num_type::max_value(), + ((Into::::into($num_type::max_value()) * 99u32) / 100u32).as_u128() as $num_type, + 1, + ); + assert_eq!( + $name::from_fraction(0.5) * $num_type::max_value(), + $num_type::max_value() / 2, + ); + assert_eq_error_rate!( + $name::from_percent(1) * $num_type::max_value(), + $num_type::max_value() / 100, + 1, + ); + } else { + assert_eq!( + $name::from_fraction(0.99) * <$num_type>::max_value(), + ( + ( + u256ify!($name::from_fraction(0.99).0) * + u256ify!(<$num_type>::max_value()) / + u256ify!($max) + ).as_u128() + ) as $num_type, + ); + assert_eq!( + $name::from_fraction(0.50) * <$num_type>::max_value(), + ( + ( + u256ify!($name::from_fraction(0.50).0) * + u256ify!(<$num_type>::max_value()) / + u256ify!($max) + ).as_u128() + ) as $num_type, + ); + assert_eq!( + $name::from_fraction(0.01) * <$num_type>::max_value(), + ( + ( + u256ify!($name::from_fraction(0.01).0) * + u256ify!(<$num_type>::max_value()) / + u256ify!($max) + ).as_u128() + ) as $num_type, + ); + } + + assert_eq!($name::from_fraction(0.0) * $num_type::max_value(), 0); // // multiplication with bounds assert_eq!($name::one() * $num_type::max_value(), $num_type::max_value()); @@ -356,17 +494,20 @@ macro_rules! implement_per_thing { use primitive_types::U256; // accuracy test - assert_eq!($name::from_rational_approximation(1 as $type, 3) * 30 as $type, 10); + assert_eq!( + $name::from_rational_approximation(1 as $type, 3) * 30 as $type, + 10, + ); $(per_thing_mul_test!($test_units);)* } #[test] fn per_thing_mul_rounds_to_nearest_number() { - assert_eq!($name::from_percent(33) * 10u64, 3); - assert_eq!($name::from_percent(34) * 10u64, 3); - assert_eq!($name::from_percent(35) * 10u64, 3); - assert_eq!($name::from_percent(36) * 10u64, 4); + assert_eq!($name::from_fraction(0.33) * 10u64, 3); + assert_eq!($name::from_fraction(0.34) * 10u64, 3); + assert_eq!($name::from_fraction(0.35) * 10u64, 3); + assert_eq!($name::from_fraction(0.36) * 10u64, 4); } #[test] @@ -398,31 +539,32 @@ macro_rules! implement_per_thing { ); assert_eq!( $name::from_rational_approximation(1 as $num_type, 10), - $name::from_percent(10), + $name::from_fraction(0.10), ); assert_eq!( $name::from_rational_approximation(1 as $num_type, 4), - $name::from_percent(25), + $name::from_fraction(0.25), ); assert_eq!( $name::from_rational_approximation(1 as $num_type, 4), $name::from_rational_approximation(2 as $num_type, 8), ); // no accurate anymore but won't overflow. - assert_eq!( + assert_eq_error_rate!( $name::from_rational_approximation( $num_type::max_value() - 1, $num_type::max_value() - ), - $name::one(), + ).0 as $upper_type, + $name::one().0 as $upper_type, + 2, ); assert_eq_error_rate!( $name::from_rational_approximation( $num_type::max_value() / 3, $num_type::max_value() - ).0, - $name::from_parts($max / 3).0, - 2 + ).0 as $upper_type, + $name::from_parts($max / 3).0 as $upper_type, + 2, ); assert_eq!( $name::from_rational_approximation(1, $num_type::max_value()), @@ -436,13 +578,14 @@ macro_rules! implement_per_thing { // This is just to make sure something like Percent which _might_ get built from a // u8 does not overflow in the context of this test. let max_value = <$upper_type>::from($max); + // almost at the edge assert_eq!( - $name::from_rational_approximation($max - 1, $max + 1), + $name::from_rational_approximation(max_value - 1, max_value + 1), $name::from_parts($max - 2), ); assert_eq!( - $name::from_rational_approximation(1, $max-1), + $name::from_rational_approximation(1, $max - 1), $name::from_parts(1), ); assert_eq!( @@ -450,76 +593,83 @@ macro_rules! implement_per_thing { $name::from_parts(1), ); assert_eq!( - $name::from_rational_approximation(2, 2 * $max - 1), + $name::from_rational_approximation(2, 2 * max_value - 1), $name::from_parts(1), ); assert_eq!( - $name::from_rational_approximation(1, $max+1), + $name::from_rational_approximation(1, max_value + 1), $name::zero(), ); assert_eq!( $name::from_rational_approximation(3 * max_value / 2, 3 * max_value), - $name::from_percent(50), + $name::from_fraction(0.5), ); + $(per_thing_from_rationale_approx_test!($test_units);)* } #[test] fn per_things_mul_operates_in_output_type() { - // assert_eq!($name::from_percent(50) * 100u32, 50u32); - assert_eq!($name::from_percent(50) * 100u64, 50u64); - assert_eq!($name::from_percent(50) * 100u128, 50u128); + // assert_eq!($name::from_fraction(0.5) * 100u32, 50u32); + assert_eq!($name::from_fraction(0.5) * 100u64, 50u64); + assert_eq!($name::from_fraction(0.5) * 100u128, 50u128); } #[test] fn per_thing_saturating_op_works() { - assert_eq!( - $name::from_percent(50).saturating_add($name::from_percent(40)), - $name::from_percent(90) + assert_eq_error_rate!( + $name::from_fraction(0.5).saturating_add($name::from_fraction(0.4)).0 as $upper_type, + $name::from_fraction(0.9).0 as $upper_type, + 2, ); - assert_eq!( - $name::from_percent(50).saturating_add($name::from_percent(50)), - $name::from_percent(100) + assert_eq_error_rate!( + $name::from_fraction(0.5).saturating_add($name::from_fraction(0.5)).0 as $upper_type, + $name::one().0 as $upper_type, + 2, ); assert_eq!( - $name::from_percent(60).saturating_add($name::from_percent(50)), - $name::from_percent(100) + $name::from_fraction(0.6).saturating_add($name::from_fraction(0.5)), + $name::one(), ); - assert_eq!( - $name::from_percent(60).saturating_sub($name::from_percent(50)), - $name::from_percent(10) + assert_eq_error_rate!( + $name::from_fraction(0.6).saturating_sub($name::from_fraction(0.5)).0 as $upper_type, + $name::from_fraction(0.1).0 as $upper_type, + 2, ); assert_eq!( - $name::from_percent(60).saturating_sub($name::from_percent(60)), - $name::from_percent(0) + $name::from_fraction(0.6).saturating_sub($name::from_fraction(0.6)), + $name::from_fraction(0.0), ); assert_eq!( - $name::from_percent(60).saturating_sub($name::from_percent(70)), - $name::from_percent(0) + $name::from_fraction(0.6).saturating_sub($name::from_fraction(0.7)), + $name::from_fraction(0.0), ); - assert_eq!( - $name::from_percent(50).saturating_mul($name::from_percent(50)), - $name::from_percent(25) + assert_eq_error_rate!( + $name::from_fraction(0.5).saturating_mul($name::from_fraction(0.5)).0 as $upper_type, + $name::from_fraction(0.25).0 as $upper_type, + 2, ); - assert_eq!( - $name::from_percent(20).saturating_mul($name::from_percent(20)), - $name::from_percent(4) + assert_eq_error_rate!( + $name::from_fraction(0.2).saturating_mul($name::from_fraction(0.2)).0 as $upper_type, + $name::from_fraction(0.04).0 as $upper_type, + 2, ); - assert_eq!( - $name::from_percent(10).saturating_mul($name::from_percent(10)), - $name::from_percent(1) + assert_eq_error_rate!( + $name::from_fraction(0.1).saturating_mul($name::from_fraction(0.1)).0 as $upper_type, + $name::from_fraction(0.01).0 as $upper_type, + 1, ); } #[test] fn per_thing_square_works() { - assert_eq!($name::from_percent(100).square(), $name::from_percent(100)); - assert_eq!($name::from_percent(50).square(), $name::from_percent(25)); - assert_eq!($name::from_percent(10).square(), $name::from_percent(1)); + assert_eq!($name::from_fraction(1.0).square(), $name::from_fraction(1.0)); + assert_eq!($name::from_fraction(0.5).square(), $name::from_fraction(0.25)); + assert_eq!($name::from_fraction(0.1).square(), $name::from_fraction(0.01)); assert_eq!( - $name::from_percent(2).square(), + $name::from_fraction(0.02).square(), $name::from_parts((4 * <$upper_type>::from($max) / 100 / 100) as $type) ); } @@ -527,22 +677,32 @@ macro_rules! implement_per_thing { #[test] fn per_things_div_works() { // normal - assert_eq!($name::from_percent(10) / $name::from_percent(20), - $name::from_percent(50) + assert_eq_error_rate!( + ($name::from_fraction(0.1) / $name::from_fraction(0.20)).0 as $upper_type, + $name::from_fraction(0.50).0 as $upper_type, + 2, ); - assert_eq!($name::from_percent(10) / $name::from_percent(10), - $name::from_percent(100) + assert_eq_error_rate!( + ($name::from_fraction(0.1) / $name::from_fraction(0.10)).0 as $upper_type, + $name::from_fraction(1.0).0 as $upper_type, + 2, ); - assert_eq!($name::from_percent(10) / $name::from_percent(0), - $name::from_percent(100) + assert_eq_error_rate!( + ($name::from_fraction(0.1) / $name::from_fraction(0.0)).0 as $upper_type, + $name::from_fraction(1.0).0 as $upper_type, + 2, ); // will not overflow - assert_eq!($name::from_percent(10) / $name::from_percent(5), - $name::from_percent(100) + assert_eq_error_rate!( + ($name::from_fraction(0.10) / $name::from_fraction(0.05)).0 as $upper_type, + $name::from_fraction(1.0).0 as $upper_type, + 2, ); - assert_eq!($name::from_percent(100) / $name::from_percent(50), - $name::from_percent(100) + assert_eq_error_rate!( + ($name::from_fraction(1.0) / $name::from_fraction(0.5)).0 as $upper_type, + $name::from_fraction(1.0).0 as $upper_type, + 2, ); } } @@ -558,6 +718,15 @@ implement_per_thing!( u16, "_Percent_", ); +implement_per_thing!( + PerU16, + test_peru16, + [u32, u64, u128], + 65535_u16, + u16, + u32, + "_Parts per 65535_", +); implement_per_thing!( Permill, test_permill, diff --git a/primitives/consensus/vrf/src/schnorrkel.rs b/primitives/consensus/vrf/src/schnorrkel.rs index 635160aa00..265572dbda 100644 --- a/primitives/consensus/vrf/src/schnorrkel.rs +++ b/primitives/consensus/vrf/src/schnorrkel.rs @@ -17,8 +17,6 @@ //! Schnorrkel-based VRF. use codec::{Encode, Decode}; -#[cfg(feature = "std")] -use sp_core::U512; use sp_runtime::RuntimeDebug; use sp_std::ops::{Deref, DerefMut}; #[cfg(feature = "std")] @@ -27,6 +25,8 @@ use std::convert::TryFrom; use codec::EncodeLike; #[cfg(feature = "std")] use schnorrkel::errors::MultiSignatureStage; +#[cfg(feature = "std")] +use sp_core::U512; #[cfg(feature = "std")] pub use schnorrkel::{SignatureError, vrf::{VRF_PROOF_LENGTH, VRF_OUTPUT_LENGTH}}; diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index a9c118ce8f..c073862f29 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -962,6 +962,8 @@ pub mod key_types { pub const IM_ONLINE: KeyTypeId = KeyTypeId(*b"imon"); /// Key type for AuthorityDiscovery module, built-in. pub const AUTHORITY_DISCOVERY: KeyTypeId = KeyTypeId(*b"audi"); + /// Key type for staking, built-in. + pub const STAKING: KeyTypeId = KeyTypeId(*b"stak"); /// A key type ID useful for tests. pub const DUMMY: KeyTypeId = KeyTypeId(*b"dumy"); } diff --git a/primitives/phragmen/Cargo.toml b/primitives/phragmen/Cargo.toml index 2290b44c5f..088466d9fb 100644 --- a/primitives/phragmen/Cargo.toml +++ b/primitives/phragmen/Cargo.toml @@ -6,21 +6,25 @@ edition = "2018" license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -description = "PHRAGMENT primitives" +description = "Phragmen primitives" [dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } +sp-phragmen-compact = { version = "2.0.0-alpha.4", path = "./compact" } [dev-dependencies] substrate-test-utils = { version = "2.0.0-alpha.5", path = "../../test-utils" } -sp-io ={ version = "2.0.0-alpha.5", path = "../../primitives/io" } -rand = "0.7.2" +rand = "0.7.3" +sp-phragmen = { path = "." } [features] default = ["std"] +bench = [] std = [ + "codec/std", "serde", "sp-std/std", "sp-runtime/std", diff --git a/primitives/phragmen/benches/phragmen.rs b/primitives/phragmen/benches/phragmen.rs index aa99e6f384..33da0b1956 100644 --- a/primitives/phragmen/benches/phragmen.rs +++ b/primitives/phragmen/benches/phragmen.rs @@ -16,6 +16,7 @@ //! Note that execution times will not be accurate in an absolute scale, since //! - Everything is executed in the context of `TestExternalities` //! - Everything is executed in native environment. + #![cfg(feature = "bench")] #![feature(test)] diff --git a/primitives/phragmen/compact/Cargo.toml b/primitives/phragmen/compact/Cargo.toml new file mode 100644 index 0000000000..fb61a90b09 --- /dev/null +++ b/primitives/phragmen/compact/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "sp-phragmen-compact" +version = "2.0.0-dev" +authors = ["Parity Technologies "] +edition = "2018" +license = "GPL-3.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "Phragmen Compact Solution" + +[lib] +proc-macro = true + +[dependencies] +syn = { version = "1.0.7", features = ["full", "visit"] } +quote = "1.0" +proc-macro2 = "1.0.6" +proc-macro-crate = "0.1.4" diff --git a/primitives/phragmen/compact/src/assignment.rs b/primitives/phragmen/compact/src/assignment.rs new file mode 100644 index 0000000000..587e482ccb --- /dev/null +++ b/primitives/phragmen/compact/src/assignment.rs @@ -0,0 +1,210 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Code generation for the ratio assignment type. + +use crate::field_name_for; +use proc_macro2::{TokenStream as TokenStream2}; +use syn::{GenericArgument}; +use quote::quote; + +fn from_impl(count: usize) -> TokenStream2 { + let from_impl_single = { + let name = field_name_for(1); + quote!(1 => compact.#name.push( + ( + index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, + index_of_target(&distribution[0].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, + ) + ),) + }; + + let from_impl_double = { + let name = field_name_for(2); + quote!(2 => compact.#name.push( + ( + index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, + ( + index_of_target(&distribution[0].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, + distribution[0].1, + ), + index_of_target(&distribution[1].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, + ) + ),) + }; + + let from_impl_rest = (3..=count).map(|c| { + let inner = (0..c-1).map(|i| + quote!((index_of_target(&distribution[#i].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, distribution[#i].1),) + ).collect::(); + + let field_name = field_name_for(c); + let last_index = c - 1; + let last = quote!(index_of_target(&distribution[#last_index].0).ok_or(_phragmen::Error::CompactInvalidIndex)?); + + quote!( + #c => compact.#field_name.push((index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, [#inner], #last)), + ) + }).collect::(); + + quote!( + #from_impl_single + #from_impl_double + #from_impl_rest + ) +} + +fn into_impl(count: usize) -> TokenStream2 { + let into_impl_single = { + let name = field_name_for(1); + quote!( + for (voter_index, target_index) in self.#name { + assignments.push(_phragmen::Assignment { + who: voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?, + distribution: vec![ + (target_at(target_index).ok_or(_phragmen::Error::CompactInvalidIndex)?, Accuracy::one()) + ], + }) + } + ) + }; + + let into_impl_double = { + let name = field_name_for(2); + quote!( + for (voter_index, (t1_idx, p1), t2_idx) in self.#name { + if p1 >= Accuracy::one() { + return Err(_phragmen::Error::CompactStakeOverflow); + } + + // defensive only. Since Percent doesn't have `Sub`. + let p2 = _phragmen::sp_runtime::traits::Saturating::saturating_sub( + Accuracy::one(), + p1, + ); + + assignments.push( _phragmen::Assignment { + who: voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?, + distribution: vec![ + (target_at(t1_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, p1), + (target_at(t2_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, p2), + ] + }); + } + ) + }; + + let into_impl_rest = (3..=count).map(|c| { + let name = field_name_for(c); + quote!( + for (voter_index, inners, t_last_idx) in self.#name { + let mut sum = Accuracy::zero(); + let mut inners_parsed = inners + .iter() + .map(|(ref t_idx, p)| { + sum = _phragmen::sp_runtime::traits::Saturating::saturating_add(sum, *p); + let target = target_at(*t_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?; + Ok((target, *p)) + }) + .collect::, _phragmen::Error>>()?; + + if sum >= Accuracy::one() { + return Err(_phragmen::Error::CompactStakeOverflow); + } + + // defensive only. Since Percent doesn't have `Sub`. + let p_last = _phragmen::sp_runtime::traits::Saturating::saturating_sub( + Accuracy::one(), + sum, + ); + + inners_parsed.push((target_at(t_last_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, p_last)); + + assignments.push(_phragmen::Assignment { + who: voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?, + distribution: inners_parsed, + }); + } + ) + }).collect::(); + + quote!( + #into_impl_single + #into_impl_double + #into_impl_rest + ) +} + +pub(crate) fn assignment( + ident: syn::Ident, + voter_type: GenericArgument, + target_type: GenericArgument, + count: usize, +) -> TokenStream2 { + + let from_impl = from_impl(count); + let into_impl = into_impl(count); + + quote!( + impl< + #voter_type: _phragmen::codec::Codec + Default + Copy, + #target_type: _phragmen::codec::Codec + Default + Copy, + Accuracy: + _phragmen::codec::Codec + Default + Clone + _phragmen::sp_runtime::PerThing + + PartialOrd, + > + #ident<#voter_type, #target_type, Accuracy> + { + pub fn from_assignment( + assignments: Vec<_phragmen::Assignment>, + index_of_voter: FV, + index_of_target: FT, + ) -> Result + where + for<'r> FV: Fn(&'r A) -> Option<#voter_type>, + for<'r> FT: Fn(&'r A) -> Option<#target_type>, + A: _phragmen::IdentifierT, + { + let mut compact: #ident< + #voter_type, + #target_type, + Accuracy, + > = Default::default(); + + for _phragmen::Assignment { who, distribution } in assignments { + match distribution.len() { + 0 => continue, + #from_impl + _ => { + return Err(_phragmen::Error::CompactTargetOverflow); + } + } + }; + Ok(compact) + } + + pub fn into_assignment( + self, + voter_at: impl Fn(#voter_type) -> Option, + target_at: impl Fn(#target_type) -> Option, + ) -> Result>, _phragmen::Error> { + let mut assignments: Vec<_phragmen::Assignment> = Default::default(); + #into_impl + Ok(assignments) + } + } + ) +} diff --git a/primitives/phragmen/compact/src/lib.rs b/primitives/phragmen/compact/src/lib.rs new file mode 100644 index 0000000000..114aeaeb32 --- /dev/null +++ b/primitives/phragmen/compact/src/lib.rs @@ -0,0 +1,219 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Proc macro for phragmen compact assignment. + +use proc_macro::TokenStream; +use proc_macro2::{TokenStream as TokenStream2, Span, Ident}; +use proc_macro_crate::crate_name; +use quote::quote; +use syn::{GenericArgument, Type, parse::{Parse, ParseStream, Result}}; + +mod assignment; +mod staked; + +// prefix used for struct fields in compact. +const PREFIX: &'static str = "votes"; + +/// Generates a struct to store the phragmen assignments in a compact way. The struct can only store +/// distributions up to the given input count. The given count must be greater than 2. +/// +/// ```ignore +/// // generate a struct with nominator and edge weight u128, with maximum supported +/// // edge per voter of 16. +/// generate_compact_solution_type(pub TestCompact, 16) +/// ``` +/// +/// This generates: +/// +/// ```ignore +/// pub struct TestCompact { +/// votes1: Vec<(V, T)>, +/// votes2: Vec<(V, (T, W), T)>, +/// votes3: Vec<(V, [(T, W); 2usize], T)>, +/// votes4: Vec<(V, [(T, W); 3usize], T)>, +/// votes5: Vec<(V, [(T, W); 4usize], T)>, +/// votes6: Vec<(V, [(T, W); 5usize], T)>, +/// votes7: Vec<(V, [(T, W); 6usize], T)>, +/// votes8: Vec<(V, [(T, W); 7usize], T)>, +/// votes9: Vec<(V, [(T, W); 8usize], T)>, +/// votes10: Vec<(V, [(T, W); 9usize], T)>, +/// votes11: Vec<(V, [(T, W); 10usize], T)>, +/// votes12: Vec<(V, [(T, W); 11usize], T)>, +/// votes13: Vec<(V, [(T, W); 12usize], T)>, +/// votes14: Vec<(V, [(T, W); 13usize], T)>, +/// votes15: Vec<(V, [(T, W); 14usize], T)>, +/// votes16: Vec<(V, [(T, W); 15usize], T)>, +/// } +/// ``` +/// +/// The generic arguments are: +/// - `V`: identifier/index for voter (nominator) types. +/// - `T` identifier/index for candidate (validator) types. +/// - `W` weight type. +/// +/// Some conversion implementations are provided by default if +/// - `W` is u128, or +/// - `W` is anything that implements `PerThing` (such as `Perbill`) +/// +/// The ideas behind the structure are as follows: +/// +/// - For single distribution, no weight is stored. The weight is known to be 100%. +/// - For all the rest, the weight if the last distribution is omitted. This value can be computed +/// from the rest. +/// +#[proc_macro] +pub fn generate_compact_solution_type(item: TokenStream) -> TokenStream { + let CompactSolutionDef { + vis, + ident, + count, + } = syn::parse_macro_input!(item as CompactSolutionDef); + + let voter_type = GenericArgument::Type(Type::Verbatim(quote!(V))); + let target_type = GenericArgument::Type(Type::Verbatim(quote!(T))); + let weight_type = GenericArgument::Type(Type::Verbatim(quote!(W))); + + let imports = imports().unwrap_or_else(|e| e.to_compile_error()); + + let compact_def = struct_def( + vis, + ident.clone(), + count, + voter_type.clone(), + target_type.clone(), + weight_type, + ).unwrap_or_else(|e| e.to_compile_error()); + + let assignment_impls = assignment::assignment( + ident.clone(), + voter_type.clone(), + target_type.clone(), + count, + ); + + let staked_impls = staked::staked( + ident, + voter_type, + target_type, + count, + ); + + quote!( + #imports + #compact_def + #assignment_impls + #staked_impls + ).into() +} + +fn struct_def( + vis: syn::Visibility, + ident: syn::Ident, + count: usize, + voter_type: GenericArgument, + target_type: GenericArgument, + weight_type: GenericArgument, +) -> Result { + if count <= 2 { + Err(syn::Error::new( + Span::call_site(), + "cannot build compact solution struct with capacity less than 2." + ))? + } + + let singles = { + let name = field_name_for(1); + quote!(#name: Vec<(#voter_type, #target_type)>,) + }; + + let doubles = { + let name = field_name_for(2); + quote!(#name: Vec<(#voter_type, (#target_type, #weight_type), #target_type)>,) + }; + + let rest = (3..=count).map(|c| { + let field_name = field_name_for(c); + let array_len = c - 1; + quote!( + #field_name: Vec<( + #voter_type, + [(#target_type, #weight_type); #array_len], + #target_type + )>, + ) + }).collect::(); + + Ok(quote! ( + /// A struct to encode a Phragmen assignment in a compact way. + #[derive( + Default, + PartialEq, + Eq, + Clone, + _phragmen::sp_runtime::RuntimeDebug, + _phragmen::codec::Encode, + _phragmen::codec::Decode, + )] + #vis struct #ident<#voter_type, #target_type, #weight_type> { + // _marker: sp_std::marker::PhantomData, + #singles + #doubles + #rest + } + + impl<#voter_type, #target_type, #weight_type> _phragmen::VotingLimit + for #ident<#voter_type, #target_type, #weight_type> + { + const LIMIT: usize = #count; + } + )) +} + +fn imports() -> Result { + let sp_phragmen_imports = match crate_name("sp-phragmen") { + Ok(sp_phragmen) => { + let ident = syn::Ident::new(&sp_phragmen, Span::call_site()); + quote!( extern crate #ident as _phragmen; ) + } + Err(e) => return Err(syn::Error::new(Span::call_site(), &e)), + }; + + Ok(quote!( + #sp_phragmen_imports + )) +} + +struct CompactSolutionDef { + vis: syn::Visibility, + ident: syn::Ident, + count: usize, +} + +impl Parse for CompactSolutionDef { + fn parse(input: ParseStream) -> syn::Result { + let vis: syn::Visibility = input.parse()?; + let ident: syn::Ident = input.parse()?; + let _ = ::parse(input)?; + let count_literal: syn::LitInt = input.parse()?; + let count = count_literal.base10_parse::()?; + Ok(Self { vis, ident, count } ) + } +} + +fn field_name_for(n: usize) -> Ident { + Ident::new(&format!("{}{}", PREFIX, n), Span::call_site()) +} diff --git a/primitives/phragmen/compact/src/staked.rs b/primitives/phragmen/compact/src/staked.rs new file mode 100644 index 0000000000..a7cf853f17 --- /dev/null +++ b/primitives/phragmen/compact/src/staked.rs @@ -0,0 +1,208 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Code generation for the staked assignment type. + +use crate::field_name_for; +use proc_macro2::{TokenStream as TokenStream2}; +use syn::{GenericArgument}; +use quote::quote; + +fn from_impl(count: usize) -> TokenStream2 { + let from_impl_single = { + let name = field_name_for(1); + quote!(1 => compact.#name.push( + ( + index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, + index_of_target(&distribution[0].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, + ) + ),) + }; + + let from_impl_double = { + let name = field_name_for(2); + quote!(2 => compact.#name.push( + ( + index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, + ( + index_of_target(&distribution[0].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, + distribution[0].1, + ), + index_of_target(&distribution[1].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, + ) + ),) + }; + + let from_impl_rest = (3..=count).map(|c| { + let inner = (0..c-1).map(|i| + quote!((index_of_target(&distribution[#i].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, distribution[#i].1),) + ).collect::(); + + let field_name = field_name_for(c); + let last_index = c - 1; + let last = quote!(index_of_target(&distribution[#last_index].0).ok_or(_phragmen::Error::CompactInvalidIndex)?); + + quote!( + #c => compact.#field_name.push((index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, [#inner], #last)), + ) + }).collect::(); + + quote!( + #from_impl_single + #from_impl_double + #from_impl_rest + ) +} + +fn into_impl(count: usize) -> TokenStream2 { + let into_impl_single = { + let name = field_name_for(1); + quote!( + for (voter_index, target_index) in self.#name { + let who = voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?; + let all_stake = max_of(&who); + assignments.push(_phragmen::StakedAssignment { + who, + distribution: vec![(target_at(target_index).ok_or(_phragmen::Error::CompactInvalidIndex)?, all_stake)], + }) + } + ) + }; + + let into_impl_double = { + let name = field_name_for(2); + quote!( + for (voter_index, (t1_idx, w1), t2_idx) in self.#name { + let who = voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?; + let all_stake = max_of(&who); + + if w1 >= all_stake { + return Err(_phragmen::Error::CompactStakeOverflow); + } + + // w2 is ensured to be positive. + let w2 = all_stake - w1; + assignments.push( _phragmen::StakedAssignment { + who, + distribution: vec![ + (target_at(t1_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, w1), + (target_at(t2_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, w2), + ] + }); + } + ) + }; + + let into_impl_rest = (3..=count).map(|c| { + let name = field_name_for(c); + quote!( + for (voter_index, inners, t_last_idx) in self.#name { + let who = voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?; + let mut sum = u128::min_value(); + let all_stake = max_of(&who); + + let mut inners_parsed = inners + .iter() + .map(|(ref t_idx, w)| { + sum = sum.saturating_add(*w); + let target = target_at(*t_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?; + Ok((target, *w)) + }).collect::, _phragmen::Error>>()?; + + if sum >= all_stake { + return Err(_phragmen::Error::CompactStakeOverflow); + } + // w_last is proved to be positive. + let w_last = all_stake - sum; + + inners_parsed.push((target_at(t_last_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, w_last)); + + assignments.push(_phragmen::StakedAssignment { + who, + distribution: inners_parsed, + }); + } + ) + }).collect::(); + + quote!( + #into_impl_single + #into_impl_double + #into_impl_rest + ) +} + +pub(crate) fn staked( + ident: syn::Ident, + voter_type: GenericArgument, + target_type: GenericArgument, + count: usize, +) -> TokenStream2 { + + let from_impl = from_impl(count); + let into_impl = into_impl(count); + quote!( + impl< + #voter_type: _phragmen::codec::Codec + Default + Copy, + #target_type: _phragmen::codec::Codec + Default + Copy, + > + #ident<#voter_type, #target_type, u128> + { + /// Generate self from a vector of `StakedAssignment`. + pub fn from_staked( + assignments: Vec<_phragmen::StakedAssignment>, + index_of_voter: FV, + index_of_target: FT, + ) -> Result + where + for<'r> FV: Fn(&'r A) -> Option<#voter_type>, + for<'r> FT: Fn(&'r A) -> Option<#target_type>, + A: _phragmen::IdentifierT + { + let mut compact: #ident<#voter_type, #target_type, u128> = Default::default(); + for _phragmen::StakedAssignment { who, distribution } in assignments { + match distribution.len() { + 0 => continue, + #from_impl + _ => { + return Err(_phragmen::Error::CompactTargetOverflow); + } + } + }; + Ok(compact) + } + + /// Convert self into `StakedAssignment`. The given function should return the total + /// weight of a voter. It is used to subtract the sum of all the encoded weights to + /// infer the last one. + pub fn into_staked( + self, + max_of: FM, + voter_at: impl Fn(#voter_type) -> Option, + target_at: impl Fn(#target_type) -> Option, + ) + -> Result>, _phragmen::Error> + where + for<'r> FM: Fn(&'r A) -> u128, + A: _phragmen::IdentifierT, + { + let mut assignments: Vec<_phragmen::StakedAssignment> = Default::default(); + #into_impl + Ok(assignments) + } + } + ) +} diff --git a/primitives/phragmen/fuzzer/.gitignore b/primitives/phragmen/fuzzer/.gitignore new file mode 100644 index 0000000000..3ebcb104d4 --- /dev/null +++ b/primitives/phragmen/fuzzer/.gitignore @@ -0,0 +1,2 @@ +hfuzz_target +hfuzz_workspace diff --git a/primitives/phragmen/fuzzer/Cargo.lock b/primitives/phragmen/fuzzer/Cargo.lock new file mode 100644 index 0000000000..5f4e9a2451 --- /dev/null +++ b/primitives/phragmen/fuzzer/Cargo.lock @@ -0,0 +1,1602 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "ahash" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3" +dependencies = [ + "const-random", +] + +[[package]] +name = "aho-corasick" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" +dependencies = [ + "memchr", +] + +[[package]] +name = "arbitrary" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cf76cb6e2222ed0ea86b2b0ee2f71c96ec6edd5af42e84d59160e91b836ec4" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" + +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" + +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" + +[[package]] +name = "backtrace" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad235dabf00f36301792cfe82499880ba54c6486be094d1047b02bacb67c14e8" +dependencies = [ + "backtrace-sys", + "cfg-if", + "libc", + "rustc-demangle", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca797db0057bae1a7aa2eef3283a874695455cecf08a43bfb8507ee0ebc1ed69" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "base58" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bitvec" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" + +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +dependencies = [ + "arrayvec 0.4.12", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "byte-slice-cast" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "cc" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "clear_on_drop" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" +dependencies = [ + "cc", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "const-random" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a" +dependencies = [ + "const-random-macro", + "proc-macro-hack", +] + +[[package]] +name = "const-random-macro" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a" +dependencies = [ + "getrandom", + "proc-macro-hack", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array", + "subtle 1.0.0", +] + +[[package]] +name = "curve25519-dalek" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d" +dependencies = [ + "byteorder", + "clear_on_drop", + "digest", + "rand_core 0.3.1", + "subtle 2.2.2", +] + +[[package]] +name = "curve25519-dalek" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839" +dependencies = [ + "byteorder", + "digest", + "rand_core 0.5.1", + "subtle 2.2.2", + "zeroize 1.1.0", +] + +[[package]] +name = "derive_more" +version = "0.99.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a806e96c59a76a5ba6e18735b6cf833344671e61e7863f2edb5c518ea2cac95c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.0-pre.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978710b352437433c97b2bff193f2fb1dfd58a093f863dd95e225a19baa599a2" +dependencies = [ + "clear_on_drop", + "curve25519-dalek 2.0.0", + "rand 0.7.3", + "sha2", +] + +[[package]] +name = "environmental" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516aa8d7a71cb00a1c4146f0798549b93d083d4f189b3ced8f3de6b8f11ee6c4" + +[[package]] +name = "failure" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8529c2421efa3066a5cbd8063d2244603824daccb6936b079010bb2aa89464b" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fixed-hash" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" +dependencies = [ + "byteorder", + "libc", + "rand 0.7.3", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +dependencies = [ + "typenum", +] + +[[package]] +name = "getrandom" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hash-db" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" + +[[package]] +name = "hash256-std-hasher" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead" +dependencies = [ + "ahash", + "autocfg 0.1.7", +] + +[[package]] +name = "hex" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" + +[[package]] +name = "hmac" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +dependencies = [ + "crypto-mac", + "digest", +] + +[[package]] +name = "hmac-drbg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" +dependencies = [ + "digest", + "generic-array", + "hmac", +] + +[[package]] +name = "honggfuzz" +version = "0.5.45" +dependencies = [ + "arbitrary", + "lazy_static", + "memmap", +] + +[[package]] +name = "impl-codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-serde" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e3cae7e99c7ff5a995da2cf78dd0a5383740eda71d98cf7b1910c301ac69b8" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-serde" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bbe9ea9b182f0fb1cabbd61f4ff9b7b7b9197955e95a7e4c27de5055eb29ff8" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "integer-sqrt" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" + +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" + +[[package]] +name = "libsecp256k1" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" +dependencies = [ + "arrayref", + "crunchy", + "digest", + "hmac-drbg", + "rand 0.7.3", + "sha2", + "subtle 2.2.2", + "typenum", +] + +[[package]] +name = "lock_api" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" + +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "memory-db" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "198831fe8722331a395bc199a5d08efbc197497ef354cb4c77b969c02ffc0fc4" +dependencies = [ + "ahash", + "hash-db", + "hashbrown", + "parity-util-mem", +] + +[[package]] +name = "memory_units" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" + +[[package]] +name = "merlin" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b0942b357c1b4d0dc43ba724674ec89c3218e6ca2b3e8269e7cb53bcecd2f6e" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.4.2", + "zeroize 1.1.0", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg 1.0.0", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +dependencies = [ + "autocfg 1.0.0", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da4dc79f9e6c81bef96148c8f6b8e72ad4541caa4a24373e900a36da07de03a3" +dependencies = [ + "autocfg 1.0.0", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +dependencies = [ + "autocfg 1.0.0", +] + +[[package]] +name = "once_cell" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" +dependencies = [ + "parking_lot 0.9.0", +] + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "parity-scale-codec" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f509c5e67ca0605ee17dcd3f91ef41cadd685c75a298fb6261b781a5acb3f910" +dependencies = [ + "arrayvec 0.5.1", + "bitvec", + "byte-slice-cast", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parity-util-mem" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1476e40bf8f5c6776e9600983435821ca86eb9819d74a6207cca69d091406a" +dependencies = [ + "cfg-if", + "impl-trait-for-tuples", + "parity-util-mem-derive", + "parking_lot 0.10.0", + "primitive-types", + "winapi", +] + +[[package]] +name = "parity-util-mem-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" +dependencies = [ + "proc-macro2", + "syn", + "synstructure", +] + +[[package]] +name = "parity-wasm" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" + +[[package]] +name = "parking_lot" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" +dependencies = [ + "lock_api", + "parking_lot_core 0.6.2", + "rustc_version", +] + +[[package]] +name = "parking_lot" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" +dependencies = [ + "lock_api", + "parking_lot_core 0.7.0", +] + +[[package]] +name = "parking_lot_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" +dependencies = [ + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "rustc_version", + "smallvec 0.6.13", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" +dependencies = [ + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "smallvec 1.2.0", + "winapi", +] + +[[package]] +name = "paste" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e1afe738d71b1ebab5f1207c055054015427dbfc7bbe9ee1266894156ec046" +dependencies = [ + "paste-impl", + "proc-macro-hack", +] + +[[package]] +name = "paste-impl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d4dc4a7f6f743211c5aab239640a65091535d97d43d92a52bca435a640892bb" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pbkdf2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +dependencies = [ + "byteorder", + "crypto-mac", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" + +[[package]] +name = "primitive-types" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-serde 0.3.0", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.7", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" + +[[package]] +name = "regex" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1132f845907680735a84409c3bebc64d1364a5683ffbce899550cd09d5eaefc1" + +[[package]] +name = "rustc-demangle" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "schnorrkel" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" +dependencies = [ + "curve25519-dalek 1.2.3", + "failure", + "merlin", + "rand 0.6.5", + "rand_core 0.4.2", + "rand_os", + "sha2", + "subtle 2.2.2", + "zeroize 0.9.3", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" +dependencies = [ + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", +] + +[[package]] +name = "smallvec" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" +dependencies = [ + "maybe-uninit", +] + +[[package]] +name = "smallvec" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" + +[[package]] +name = "sp-application-crypto" +version = "2.0.0-alpha.3" +dependencies = [ + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-std", +] + +[[package]] +name = "sp-arithmetic" +version = "2.0.0-alpha.3" +dependencies = [ + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "serde", + "sp-debug-derive", + "sp-std", +] + +[[package]] +name = "sp-core" +version = "2.0.0-alpha.3" +dependencies = [ + "base58", + "blake2-rfc", + "byteorder", + "ed25519-dalek", + "hash-db", + "hash256-std-hasher", + "hex", + "impl-serde 0.3.0", + "lazy_static", + "libsecp256k1", + "log", + "num-traits", + "parity-scale-codec", + "parity-util-mem", + "parking_lot 0.10.0", + "primitive-types", + "rand 0.7.3", + "regex", + "rustc-hex", + "schnorrkel", + "serde", + "sha2", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", + "sp-std", + "sp-storage", + "substrate-bip39", + "tiny-bip39", + "tiny-keccak", + "twox-hash", + "wasmi", + "zeroize 1.1.0", +] + +[[package]] +name = "sp-debug-derive" +version = "2.0.0-alpha.3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-externalities" +version = "0.8.0-alpha.3" +dependencies = [ + "environmental", + "sp-std", + "sp-storage", +] + +[[package]] +name = "sp-inherents" +version = "2.0.0-alpha.3" +dependencies = [ + "derive_more", + "parity-scale-codec", + "parking_lot 0.10.0", + "sp-core", + "sp-std", +] + +[[package]] +name = "sp-io" +version = "2.0.0-alpha.3" +dependencies = [ + "hash-db", + "libsecp256k1", + "log", + "parity-scale-codec", + "sp-core", + "sp-externalities", + "sp-runtime-interface", + "sp-state-machine", + "sp-std", + "sp-trie", + "sp-wasm-interface", +] + +[[package]] +name = "sp-panic-handler" +version = "2.0.0-alpha.3" +dependencies = [ + "backtrace", + "log", +] + +[[package]] +name = "sp-phragmen" +version = "2.0.0-alpha.3" +dependencies = [ + "parity-scale-codec", + "serde", + "sp-core", + "sp-phragmen-compact", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "sp-phragmen-compact" +version = "2.0.0-dev" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-phragmen-fuzzer" +version = "2.0.0" +dependencies = [ + "honggfuzz", + "rand 0.7.3", + "sp-phragmen", +] + +[[package]] +name = "sp-runtime" +version = "2.0.0-alpha.3" +dependencies = [ + "hash256-std-hasher", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "parity-util-mem", + "paste", + "rand 0.7.3", + "serde", + "sp-application-crypto", + "sp-arithmetic", + "sp-core", + "sp-inherents", + "sp-io", + "sp-std", +] + +[[package]] +name = "sp-runtime-interface" +version = "2.0.0-alpha.3" +dependencies = [ + "parity-scale-codec", + "primitive-types", + "sp-externalities", + "sp-runtime-interface-proc-macro", + "sp-std", + "sp-wasm-interface", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "2.0.0-alpha.3" +dependencies = [ + "Inflector", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-state-machine" +version = "0.8.0-alpha.3" +dependencies = [ + "hash-db", + "log", + "num-traits", + "parity-scale-codec", + "parking_lot 0.10.0", + "rand 0.7.3", + "sp-core", + "sp-externalities", + "sp-panic-handler", + "sp-trie", + "trie-db", + "trie-root", +] + +[[package]] +name = "sp-std" +version = "2.0.0-alpha.3" + +[[package]] +name = "sp-storage" +version = "2.0.0-alpha.3" +dependencies = [ + "impl-serde 0.2.3", + "serde", + "sp-debug-derive", + "sp-std", +] + +[[package]] +name = "sp-trie" +version = "2.0.0-alpha.3" +dependencies = [ + "hash-db", + "memory-db", + "parity-scale-codec", + "sp-core", + "sp-std", + "trie-db", + "trie-root", +] + +[[package]] +name = "sp-wasm-interface" +version = "2.0.0-alpha.3" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-std", + "wasmi", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "substrate-bip39" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" +dependencies = [ + "hmac", + "pbkdf2", + "schnorrkel", + "sha2", +] + +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + +[[package]] +name = "subtle" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" + +[[package]] +name = "syn" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tiny-bip39" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6848cd8f566953ce1e8faeba12ee23cbdbb0437754792cd857d44628b5685e3" +dependencies = [ + "failure", + "hmac", + "once_cell", + "pbkdf2", + "rand 0.7.3", + "rustc-hash", + "sha2", + "unicode-normalization", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2953ca5148619bc99695c1274cb54c5275bbb913c6adad87e72eaf8db9787f69" +dependencies = [ + "crunchy", +] + +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +dependencies = [ + "serde", +] + +[[package]] +name = "trie-db" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de9222c50cc325855621271157c973da27a0dcd26fa06f8edf81020bd2333df0" +dependencies = [ + "hash-db", + "hashbrown", + "log", + "rustc-hex", + "smallvec 1.2.0", +] + +[[package]] +name = "trie-root" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "652931506d2c1244d7217a70b99f56718a7b4161b37f04e7cd868072a99f68cd" +dependencies = [ + "hash-db", +] + +[[package]] +name = "twox-hash" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" +dependencies = [ + "rand 0.7.3", +] + +[[package]] +name = "typenum" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" + +[[package]] +name = "uint" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" +dependencies = [ + "byteorder", + "crunchy", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" +dependencies = [ + "smallvec 1.2.0", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasmi" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" +dependencies = [ + "libc", + "memory_units", + "num-rational", + "num-traits", + "parity-wasm", + "wasmi-validation", +] + +[[package]] +name = "wasmi-validation" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93" +dependencies = [ + "parity-wasm", +] + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "zeroize" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" + +[[package]] +name = "zeroize" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/primitives/phragmen/fuzzer/Cargo.toml b/primitives/phragmen/fuzzer/Cargo.toml new file mode 100644 index 0000000000..645b1c151b --- /dev/null +++ b/primitives/phragmen/fuzzer/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "sp-phragmen-fuzzer" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sp-phragmen = { version = "2.0.0-alpha.3", path = ".." } +honggfuzz = "0.5" +rand = "0.7.3" + +[workspace] + +[[bin]] +name = "reduce" +path = "src/reduce.rs" diff --git a/primitives/phragmen/fuzzer/src/reduce.rs b/primitives/phragmen/fuzzer/src/reduce.rs new file mode 100644 index 0000000000..4bf08590a1 --- /dev/null +++ b/primitives/phragmen/fuzzer/src/reduce.rs @@ -0,0 +1,145 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! # Running +//! +//! Run with `cargo hfuzz run reduce`. `honggfuzz`. +//! +//! # Debugging a panic +//! +//! Once a panic is found, it can be debugged with +//! `cargo hfuzz run-debug reduce hfuzz_workspace/reduce/*.fuzz`. + +use honggfuzz::fuzz; +use sp_phragmen::{StakedAssignment, ExtendedBalance, build_support_map, reduce}; +use rand::{self, Rng}; + +type Balance = u128; +type AccountId = u64; + +/// Or any other token type. +const KSM: Balance = 1_000_000_000_000; + +fn main() { + loop { + fuzz!(|_data: _| { + let (assignments, winners) = generate_random_phragmen_assignment( + rr(100, 1000), + rr(100, 2000), + 8, + 8, + ); + reduce_and_compare(&assignments, &winners); + }); + } +} + +fn generate_random_phragmen_assignment( + voter_count: usize, + target_count: usize, + avg_edge_per_voter: usize, + edge_per_voter_var: usize, +) -> (Vec>, Vec) { + // random in range of (a, b) + let rr_128 = |a: u128, b: u128| -> u128 { rand::thread_rng().gen_range(a, b) }; + + // prefix to distinguish the voter and target account ranges. + let target_prefix = 1_000_000; + // let target_prefix = 1000; + assert!(voter_count < target_prefix); + + let mut assignments = Vec::with_capacity(voter_count as usize); + let mut winners: Vec = Vec::new(); + + let all_targets = (target_prefix..(target_prefix + target_count)) + .map(|a| a as AccountId) + .collect::>(); + + (1..=voter_count).for_each(|acc| { + let mut targets_to_chose_from = all_targets.clone(); + let targets_to_chose = if edge_per_voter_var > 0 { rr( + avg_edge_per_voter - edge_per_voter_var, + avg_edge_per_voter + edge_per_voter_var, + ) } else { avg_edge_per_voter }; + + let distribution = (0..targets_to_chose).map(|_| { + let target = targets_to_chose_from.remove(rr(0, targets_to_chose_from.len())); + if winners.iter().find(|w| **w == target).is_none() { + winners.push(target.clone()); + } + (target, rr_128(1 * KSM, 100 * KSM)) + }).collect::>(); + + assignments.push(StakedAssignment { + who: (acc as AccountId), + distribution, + }); + }); + + (assignments, winners) +} + +fn assert_assignments_equal( + winners: &Vec, + ass1: &Vec>, + ass2: &Vec>, +) { + + let (support_1, _) = build_support_map::(winners, ass1); + let (support_2, _) = build_support_map::(winners, ass2); + + for (who, support) in support_1.iter() { + assert_eq!(support.total, support_2.get(who).unwrap().total); + } +} + +fn reduce_and_compare( + assignment: &Vec>, + winners: &Vec, +) { + let mut altered_assignment = assignment.clone(); + let n = assignment.len() as u32; + let m = winners.len() as u32; + + let edges_before = assignment_len(&assignment); + let num_changed = reduce(&mut altered_assignment); + let edges_after = edges_before - num_changed; + + assert!( + edges_after <= m + n, + "reduce bound not satisfied. n = {}, m = {}, edges after reduce = {} (removed {})", + n, + m, + edges_after, + num_changed, + ); + + assert_assignments_equal( + winners, + &assignment, + &altered_assignment, + ); +} + +fn assignment_len(assignments: &[StakedAssignment]) -> u32 { + let mut counter = 0; + assignments.iter().for_each(|x| x.distribution.iter().for_each(|_| counter += 1)); + counter +} + +fn rr(a: usize, b: usize) -> usize { + rand::thread_rng().gen_range(a, b) +} diff --git a/primitives/phragmen/src/helpers.rs b/primitives/phragmen/src/helpers.rs new file mode 100644 index 0000000000..27f51b4a05 --- /dev/null +++ b/primitives/phragmen/src/helpers.rs @@ -0,0 +1,94 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Helper methods for phragmen. + +use crate::{Assignment, ExtendedBalance, IdentifierT, StakedAssignment}; +use sp_runtime::PerThing; +use sp_std::prelude::*; + +/// Converts a vector of ratio assignments into ones with absolute budget value. +pub fn assignment_ratio_to_staked( + ratio: Vec>, + stake_of: FS, +) -> Vec> +where + for<'r> FS: Fn(&'r A) -> ExtendedBalance, + T: sp_std::ops::Mul, + ExtendedBalance: From<::Inner>, +{ + ratio + .into_iter() + .map(|a| { + let stake = stake_of(&a.who); + a.into_staked(stake, true) + }) + .collect() +} + +/// Converts a vector of staked assignments into ones with ratio values. +pub fn assignment_staked_to_ratio( + ratio: Vec>, +) -> Vec> +where + ExtendedBalance: From<::Inner>, +{ + ratio.into_iter().map(|a| a.into_assignment(true)).collect() +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::ExtendedBalance; + use sp_runtime::Perbill; + + #[test] + fn into_staked_works() { + let ratio = vec![ + Assignment { + who: 1u32, + distribution: vec![ + (10u32, Perbill::from_fraction(0.5)), + (20, Perbill::from_fraction(0.5)), + ], + }, + Assignment { + who: 2u32, + distribution: vec![ + (10, Perbill::from_fraction(0.33)), + (20, Perbill::from_fraction(0.67)), + ], + }, + ]; + + let stake_of = |_: &u32| -> ExtendedBalance { 100u128 }; + let staked = assignment_ratio_to_staked(ratio, stake_of); + + assert_eq!( + staked, + vec![ + StakedAssignment { + who: 1u32, + distribution: vec![(10u32, 50), (20, 50),] + }, + StakedAssignment { + who: 2u32, + distribution: vec![(10u32, 33), (20, 67),] + } + ] + ); + } +} diff --git a/primitives/phragmen/src/lib.rs b/primitives/phragmen/src/lib.rs index aba714faeb..c0d94a71e1 100644 --- a/primitives/phragmen/src/lib.rs +++ b/primitives/phragmen/src/lib.rs @@ -33,19 +33,60 @@ #![cfg_attr(not(feature = "std"), no_std)] -use sp_std::{prelude::*, collections::btree_map::BTreeMap, convert::TryFrom}; -use sp_runtime::{ - PerThing, Rational128, RuntimeDebug, - helpers_128bit::multiply_by_rational, -}; -use sp_runtime::traits::{ - Zero, Convert, Member, AtLeast32Bit, SaturatedConversion, Bounded, Saturating, -}; +use sp_std::{prelude::*, collections::btree_map::BTreeMap, fmt::Debug, cmp::Ordering, convert::TryFrom}; +use sp_runtime::{helpers_128bit::multiply_by_rational, PerThing, Rational128, RuntimeDebug, SaturatedConversion}; +use sp_runtime::traits::{Zero, Convert, Member, AtLeast32Bit, Saturating, Bounded}; #[cfg(test)] mod mock; #[cfg(test)] mod tests; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; +#[cfg(feature = "std")] +use codec::{Encode, Decode}; + +mod node; +mod reduce; +mod helpers; + +// re-export reduce stuff. +pub use reduce::reduce; + +// re-export the helpers. +pub use helpers::*; + +// re-export the compact macro, with the dependencies of the macro. +#[doc(hidden)] +pub use codec; +#[doc(hidden)] +pub use sp_runtime; + +// re-export the compact solution type. +pub use sp_phragmen_compact::generate_compact_solution_type; + +/// A trait to limit the number of votes per voter. The generated compact type will implement this. +pub trait VotingLimit { + const LIMIT: usize; +} + +/// an aggregator trait for a generic type of a voter/target identifier. This usually maps to +/// substrate's account id. +pub trait IdentifierT: Clone + Eq + Default + Ord + Debug + codec::Codec {} + +impl IdentifierT for T {} + +/// The errors that might occur in the this crate and compact. +#[derive(Debug, Eq, PartialEq)] +pub enum Error { + /// While going from compact to staked, the stake of all the edges has gone above the + /// total and the last stake cannot be assigned. + CompactStakeOverflow, + /// The compact type has a voter who's number of targets is out of bound. + CompactTargetOverflow, + /// One of the index functions returned none. + CompactInvalidIndex, +} /// A type in which performing operations on balances and stakes of candidates and voters are safe. /// @@ -55,6 +96,9 @@ mod tests; /// Balance types converted to `ExtendedBalance` are referred to as `Votes`. pub type ExtendedBalance = u128; +/// The score of an assignment. This can be computed from the support map via [`evaluate_support`]. +pub type PhragmenScore = [ExtendedBalance; 3]; + /// The denominator used for loads. Since votes are collected as u64, the smallest ratio that we /// might collect is `1/approval_stake` where approval stake is the sum of votes. Hence, some number /// bigger than u64::max_value() is needed. For maximum accuracy we simply use u128; @@ -62,11 +106,11 @@ const DEN: u128 = u128::max_value(); /// A candidate entity for phragmen election. #[derive(Clone, Default, RuntimeDebug)] -pub struct Candidate { +struct Candidate { /// Identifier. - pub who: AccountId, + who: AccountId, /// Intermediary value used to sort candidates. - pub score: Rational128, + score: Rational128, /// Sum of the stake of this candidate based on received votes. approval_stake: ExtendedBalance, /// Flag for being elected. @@ -75,7 +119,7 @@ pub struct Candidate { /// A voter entity. #[derive(Clone, Default, RuntimeDebug)] -pub struct Voter { +struct Voter { /// Identifier. who: AccountId, /// List of candidates proposed by this voter. @@ -88,7 +132,7 @@ pub struct Voter { /// A candidate being backed by a voter. #[derive(Clone, Default, RuntimeDebug)] -pub struct Edge { +struct Edge { /// Identifier. who: AccountId, /// Load of this vote. @@ -97,12 +141,6 @@ pub struct Edge { candidate_index: usize, } -/// Particular `AccountId` was backed by `T`-ratio of a nominator's stake. -pub type PhragmenAssignment = (AccountId, T); - -/// Particular `AccountId` was backed by `ExtendedBalance` of a nominator's stake. -pub type PhragmenStakedAssignment = (AccountId, ExtendedBalance); - /// Final result of the phragmen election. #[derive(RuntimeDebug)] pub struct PhragmenResult { @@ -111,7 +149,142 @@ pub struct PhragmenResult { pub winners: Vec<(AccountId, ExtendedBalance)>, /// Individual assignments. for each tuple, the first elements is a voter and the second /// is the list of candidates that it supports. - pub assignments: Vec<(AccountId, Vec>)> + pub assignments: Vec>, +} + +/// A voter's stake assignment among a set of targets, represented as ratios. +#[derive(RuntimeDebug, Clone, Default)] +#[cfg_attr(feature = "std", derive(PartialEq, Eq, Encode, Decode))] +pub struct Assignment { + /// Voter's identifier + pub who: AccountId, + /// The distribution of the voter's stake. + pub distribution: Vec<(AccountId, T)>, +} + +impl Assignment +where + ExtendedBalance: From<::Inner>, +{ + /// Convert from a ratio assignment into one with absolute values aka. [`StakedAssignment`]. + /// + /// It needs `stake` which is the total budget of the voter. If `fill` is set to true, + /// it _tries_ to ensure that all the potential rounding errors are compensated and the + /// distribution's sum is exactly equal to the total budget, by adding or subtracting the + /// remainder from the last distribution. + /// + /// If an edge ratio is [`Bounded::max_value()`], it is dropped. This edge can never mean + /// anything useful. + pub fn into_staked(self, stake: ExtendedBalance, fill: bool) -> StakedAssignment + where + T: sp_std::ops::Mul, + { + let mut sum: ExtendedBalance = Bounded::min_value(); + let mut distribution = self + .distribution + .into_iter() + .filter_map(|(target, p)| { + // if this ratio is zero, then skip it. + if p == Bounded::min_value() { + None + } else { + // NOTE: this mul impl will always round to the nearest number, so we might both + // overflow and underflow. + let distribution_stake = p * stake; + // defensive only. We assume that balance cannot exceed extended balance. + sum = sum.saturating_add(distribution_stake); + Some((target, distribution_stake)) + } + }) + .collect::>(); + + if fill { + // NOTE: we can do this better. + // https://revs.runtime-revolution.com/getting-100-with-rounded-percentages-273ffa70252b + if let Some(leftover) = stake.checked_sub(sum) { + if let Some(last) = distribution.last_mut() { + last.1 = last.1.saturating_add(leftover); + } + } else if let Some(excess) = sum.checked_sub(stake) { + if let Some(last) = distribution.last_mut() { + last.1 = last.1.saturating_sub(excess); + } + } + } + + StakedAssignment { + who: self.who, + distribution, + } + } +} + +/// A voter's stake assignment among a set of targets, represented as absolute values in the scale +/// of [`ExtendedBalance`]. +#[derive(RuntimeDebug, Clone, Default)] +#[cfg_attr(feature = "std", derive(PartialEq, Eq, Encode, Decode))] +pub struct StakedAssignment { + /// Voter's identifier + pub who: AccountId, + /// The distribution of the voter's stake. + pub distribution: Vec<(AccountId, ExtendedBalance)>, +} + +impl StakedAssignment { + /// Converts self into the normal [`Assignment`] type. + /// + /// If `fill` is set to true, it _tries_ to ensure that all the potential rounding errors are + /// compensated and the distribution's sum is exactly equal to 100%, by adding or subtracting + /// the remainder from the last distribution. + /// + /// NOTE: it is quite critical that this attempt always works. The data type returned here will + /// potentially get used to create a compact type; a compact type requires sum of ratios to be + /// less than 100% upon un-compacting. + /// + /// If an edge stake is so small that it cannot be represented in `T`, it is ignored. This edge + /// can never be re-created and does not mean anything useful anymore. + pub fn into_assignment(self, fill: bool) -> Assignment + where + ExtendedBalance: From<::Inner>, + { + let accuracy: u128 = T::ACCURACY.saturated_into(); + let mut sum: u128 = Zero::zero(); + let stake = self.distribution.iter().map(|x| x.1).sum(); + let mut distribution = self + .distribution + .into_iter() + .filter_map(|(target, w)| { + let per_thing = T::from_rational_approximation(w, stake); + if per_thing == Bounded::min_value() { + None + } else { + sum += per_thing.clone().deconstruct().saturated_into(); + Some((target, per_thing)) + } + }) + .collect::>(); + + if fill { + if let Some(leftover) = accuracy.checked_sub(sum) { + if let Some(last) = distribution.last_mut() { + last.1 = last.1.saturating_add( + T::from_parts(leftover.saturated_into()) + ); + } + } else if let Some(excess) = sum.checked_sub(accuracy) { + if let Some(last) = distribution.last_mut() { + last.1 = last.1.saturating_sub( + T::from_parts(excess.saturated_into()) + ); + } + } + } + + Assignment { + who: self.who, + distribution, + } + } } /// A structure to demonstrate the phragmen result from the perspective of the candidate, i.e. how @@ -122,12 +295,12 @@ pub struct PhragmenResult { /// This, at the current version, resembles the `Exposure` defined in the Staking pallet, yet /// they do not necessarily have to be the same. #[derive(Default, RuntimeDebug)] -#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize, Eq, PartialEq))] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Eq, PartialEq))] pub struct Support { /// Total support. pub total: ExtendedBalance, /// Support from voters. - pub voters: Vec>, + pub voters: Vec<(AccountId, ExtendedBalance)>, } /// A linkage from a candidate and its [`Support`]. @@ -164,7 +337,7 @@ pub fn elect( // return structures let mut elected_candidates: Vec<(AccountId, ExtendedBalance)>; - let mut assigned: Vec<(AccountId, Vec>)>; + let mut assigned: Vec>; // used to cache and access candidates index. let mut c_idx_cache = BTreeMap::::new(); @@ -271,7 +444,10 @@ pub fn elect( // update backing stake of candidates and voters for n in &mut voters { - let mut assignment = (n.who.clone(), vec![]); + let mut assignment = Assignment { + who: n.who.clone(), + ..Default::default() + }; for e in &mut n.edges { if elected_candidates.iter().position(|(ref c, _)| *c == e.who).is_some() { let per_bill_parts: R::Inner = @@ -298,44 +474,45 @@ pub fn elect( // R::Inner. .unwrap_or(Bounded::max_value()) } else { - // defensive only. Both edge and nominator loads are built from + // defensive only. Both edge and voter loads are built from // scores, hence MUST have the same denominator. Zero::zero() } } }; let per_thing = R::from_parts(per_bill_parts); - assignment.1.push((e.who.clone(), per_thing)); + assignment.distribution.push((e.who.clone(), per_thing)); } } - if assignment.1.len() > 0 { - // To ensure an assertion indicating: no stake from the nominator going to waste, + let len = assignment.distribution.len(); + if len > 0 { + // To ensure an assertion indicating: no stake from the voter going to waste, // we add a minimal post-processing to equally assign all of the leftover stake ratios. - let vote_count: R::Inner = assignment.1.len().saturated_into(); - let len = assignment.1.len(); - let mut sum: R::Inner = Zero::zero(); - assignment.1.iter().for_each(|a| sum = sum.saturating_add(a.1.deconstruct())); + let vote_count: R::Inner = len.saturated_into(); let accuracy = R::ACCURACY; + let mut sum: R::Inner = Zero::zero(); + assignment.distribution.iter().for_each(|a| sum = sum.saturating_add(a.1.deconstruct())); + let diff = accuracy.saturating_sub(sum); let diff_per_vote = (diff / vote_count).min(accuracy); if !diff_per_vote.is_zero() { for i in 0..len { - let current_ratio = assignment.1[i % len].1; + let current_ratio = assignment.distribution[i % len].1; let next_ratio = current_ratio .saturating_add(R::from_parts(diff_per_vote)); - assignment.1[i % len].1 = next_ratio; + assignment.distribution[i % len].1 = next_ratio; } } - // `remainder` is set to be less than maximum votes of a nominator (currently 16). + // `remainder` is set to be less than maximum votes of a voter (currently 16). // safe to cast it to usize. let remainder = diff - diff_per_vote * vote_count; for i in 0..remainder.saturated_into::() { - let current_ratio = assignment.1[i % len].1; + let current_ratio = assignment.distribution[i % len].1; let next_ratio = current_ratio.saturating_add(R::from_parts(1u8.into())); - assignment.1[i % len].1 = next_ratio; + assignment.distribution[i % len].1 = next_ratio; } assigned.push(assignment); } @@ -347,39 +524,109 @@ pub fn elect( }) } -/// Build the support map from the given phragmen result. -pub fn build_support_map( - elected_stashes: &Vec, - assignments: &Vec<(AccountId, Vec>)>, - stake_of: FS, -) -> SupportMap where +/// Build the support map from the given phragmen result. It maps a flat structure like +/// +/// ```nocompile +/// assignments: vec![ +/// voter1, vec![(candidate1, w11), (candidate2, w12)], +/// voter2, vec![(candidate1, w21), (candidate2, w22)] +/// ] +/// ``` +/// +/// into a mapping of candidates and their respective support: +/// +/// ```nocompile +/// SupportMap { +/// candidate1: Support { +/// own:0, +/// total: w11 + w21, +/// others: vec![(candidate1, w11), (candidate2, w21)] +/// }, +/// candidate2: Support { +/// own:0, +/// total: w12 + w22, +/// others: vec![(candidate1, w12), (candidate2, w22)] +/// }, +/// } +/// ``` +/// +/// The second returned flag indicates the number of edges who didn't corresponded to an actual +/// winner from the given winner set. A value in this place larger than 0 indicates a potentially +/// faulty assignment. +/// +/// `O(E)` where `E` is the total number of edges. +pub fn build_support_map( + winners: &[AccountId], + assignments: &[StakedAssignment], +) -> (SupportMap, u32) where AccountId: Default + Ord + Member, - Balance: Default + Copy + AtLeast32Bit, - C: Convert + Convert, - for<'r> FS: Fn(&'r AccountId) -> Balance, - R: PerThing + sp_std::ops::Mul, { - let to_votes = |b: Balance| >::convert(b) as ExtendedBalance; + let mut errors = 0; // Initialize the support of each candidate. let mut supports = >::new(); - elected_stashes + winners .iter() .for_each(|e| { supports.insert(e.clone(), Default::default()); }); // build support struct. - for (n, assignment) in assignments.iter() { - for (c, per_thing) in assignment.iter() { - let nominator_stake = to_votes(stake_of(n)); - // AUDIT: it is crucially important for the `Mul` implementation of all - // per-things to be sound. - let other_stake = *per_thing * nominator_stake; + for StakedAssignment { who, distribution } in assignments.iter() { + for (c, weight_extended) in distribution.iter() { if let Some(support) = supports.get_mut(c) { - support.voters.push((n.clone(), other_stake)); - support.total = support.total.saturating_add(other_stake); + support.total = support.total.saturating_add(*weight_extended); + support.voters.push((who.clone(), *weight_extended)); + } else { + errors = errors.saturating_add(1); } } } - supports + (supports, errors) +} + +/// Evaluate a phragmen result, given the support map. The returned tuple contains: +/// +/// - Minimum support. This value must be **maximized**. +/// - Sum of all supports. This value must be **maximized**. +/// - Sum of all supports squared. This value must be **minimized**. +/// +/// `O(E)` where `E` is the total number of edges. +pub fn evaluate_support( + support: &SupportMap, +) -> PhragmenScore { + let mut min_support = ExtendedBalance::max_value(); + let mut sum: ExtendedBalance = Zero::zero(); + // NOTE: this will probably saturate but using big num makes it even slower. We'll have to see. + // This must run on chain.. + let mut sum_squared: ExtendedBalance = Zero::zero(); + for (_, support) in support.iter() { + sum += support.total; + let squared = support.total.saturating_mul(support.total); + sum_squared = sum_squared.saturating_add(squared); + if support.total < min_support { + min_support = support.total; + } + } + [min_support, sum, sum_squared] +} + +/// Compares two sets of phragmen scores based on desirability and returns true if `that` is +/// better than `this`. +/// +/// Evaluation is done in a lexicographic manner. +/// +/// Note that the third component should be minimized. +pub fn is_score_better(this: PhragmenScore, that: PhragmenScore) -> bool { + match that + .iter() + .enumerate() + .map(|(i, e)| e.cmp(&this[i])) + .collect::>() + .as_slice() + { + [Ordering::Greater, _, _] => true, + [Ordering::Equal, Ordering::Greater, _] => true, + [Ordering::Equal, Ordering::Equal, Ordering::Less] => true, + _ => false, + } } /// Performs equalize post-processing to the output of the election algorithm. This happens in @@ -388,13 +635,13 @@ pub fn build_support_map( /// /// No value is returned from the function and the `supports` parameter is updated. /// -/// * `assignments`: exactly the same is the output of phragmen. -/// * `supports`: mutable reference to s `SupportMap`. This parameter is updated. -/// * `tolerance`: maximum difference that can occur before an early quite happens. -/// * `iterations`: maximum number of iterations that will be processed. -/// * `stake_of`: something that can return the stake stake of a particular candidate or voter. +/// - `assignments`: exactly the same is the output of phragmen. +/// - `supports`: mutable reference to s `SupportMap`. This parameter is updated. +/// - `tolerance`: maximum difference that can occur before an early quite happens. +/// - `iterations`: maximum number of iterations that will be processed. +/// - `stake_of`: something that can return the stake stake of a particular candidate or voter. pub fn equalize( - mut assignments: Vec<(AccountId, Vec>)>, + mut assignments: Vec>, supports: &mut SupportMap, tolerance: ExtendedBalance, iterations: usize, @@ -408,13 +655,13 @@ pub fn equalize( for _i in 0..iterations { let mut max_diff = 0; - for (voter, assignment) in assignments.iter_mut() { - let voter_budget = stake_of(&voter); + for StakedAssignment { who, distribution } in assignments.iter_mut() { + let voter_budget = stake_of(&who); let diff = do_equalize::<_, _, C>( - voter, + who, voter_budget, - assignment, + distribution, supports, tolerance, ); @@ -432,7 +679,7 @@ pub fn equalize( fn do_equalize( voter: &AccountId, budget_balance: Balance, - elected_edges: &mut Vec>, + elected_edges: &mut Vec<(AccountId, ExtendedBalance)>, support_map: &mut SupportMap, tolerance: ExtendedBalance ) -> ExtendedBalance where diff --git a/primitives/phragmen/src/mock.rs b/primitives/phragmen/src/mock.rs index 66ef64a6c2..31ce3d38c3 100644 --- a/primitives/phragmen/src/mock.rs +++ b/primitives/phragmen/src/mock.rs @@ -18,10 +18,10 @@ #![cfg(test)] -use crate::{elect, PhragmenResult, PhragmenAssignment}; +use crate::{elect, PhragmenResult, Assignment}; use sp_runtime::{ - assert_eq_error_rate, Perbill, PerThing, - traits::{Convert, Member, SaturatedConversion} + assert_eq_error_rate, PerThing, + traits::{Convert, Member, SaturatedConversion, Zero, One} }; use sp_std::collections::btree_map::BTreeMap; @@ -320,22 +320,23 @@ pub(crate) fn create_stake_of(stakes: &[(AccountId, Balance)]) } -pub fn check_assignments(assignments: Vec<(AccountId, Vec>)>) { - for (_, a) in assignments { - let sum: u32 = a.iter().map(|(_, p)| p.deconstruct()).sum(); - assert_eq_error_rate!(sum, Perbill::ACCURACY, 5); +pub fn check_assignments_sum(assignments: Vec>) { + for Assignment { distribution, .. } in assignments { + let mut sum: u128 = Zero::zero(); + distribution.iter().for_each(|(_, p)| sum += p.deconstruct().saturated_into()); + assert_eq_error_rate!(sum, T::ACCURACY.saturated_into(), 1); } } -pub(crate) fn run_and_compare( +pub(crate) fn run_and_compare( candidates: Vec, voters: Vec<(AccountId, Vec)>, - stake_of: Box Balance>, + stake_of: &Box Balance>, to_elect: usize, min_to_elect: usize, ) { // run fixed point code. - let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Perbill>( + let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Output>( to_elect, min_to_elect, candidates.clone(), @@ -353,14 +354,14 @@ pub(crate) fn run_and_compare( assert_eq!(winners, truth_value.winners); - for (nominator, assigned) in assignments.clone() { - if let Some(float_assignments) = truth_value.assignments.iter().find(|x| x.0 == nominator) { - for (candidate, per_thingy) in assigned { + for Assignment { who, distribution } in assignments.clone() { + if let Some(float_assignments) = truth_value.assignments.iter().find(|x| x.0 == who) { + for (candidate, per_thingy) in distribution { if let Some(float_assignment) = float_assignments.1.iter().find(|x| x.0 == candidate ) { assert_eq_error_rate!( - Perbill::from_fraction(float_assignment.1).deconstruct(), + Output::from_fraction(float_assignment.1).deconstruct(), per_thingy.deconstruct(), - 1, + Output::Inner::one(), ); } else { panic!("candidate mismatch. This should never happen.") @@ -371,7 +372,7 @@ pub(crate) fn run_and_compare( } } - check_assignments(assignments); + check_assignments_sum(assignments); } pub(crate) fn build_support_map_float( diff --git a/primitives/phragmen/src/node.rs b/primitives/phragmen/src/node.rs new file mode 100644 index 0000000000..92ef325a34 --- /dev/null +++ b/primitives/phragmen/src/node.rs @@ -0,0 +1,287 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! (very) Basic implementation of a graph node used in the reduce algorithm. + +use sp_runtime::RuntimeDebug; +use sp_std::{cell::RefCell, fmt, prelude::*, rc::Rc}; + +/// The role that a node can accept. +#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, RuntimeDebug)] +pub(crate) enum NodeRole { + /// A voter. This is synonym to a nominator in a staking context. + Voter, + /// A target. This is synonym to a candidate/validator in a staking context. + Target, +} + +pub(crate) type RefCellOf = Rc>; +pub(crate) type NodeRef = RefCellOf>; + +/// Identifier of a node. This is particularly handy to have a proper `PartialEq` implementation. +/// Otherwise, self votes wouldn't have been indistinguishable. +#[derive(PartialOrd, Ord, Clone, PartialEq, Eq)] +pub(crate) struct NodeId { + /// An account-like identifier representing the node. + pub who: A, + /// The role of the node. + pub role: NodeRole, +} + +impl NodeId { + /// Create a new [`NodeId`]. + pub fn from(who: A, role: NodeRole) -> Self { + Self { who, role } + } +} + +#[cfg(feature = "std")] +impl sp_std::fmt::Debug for NodeId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> sp_std::fmt::Result { + write!( + f, + "Node({:?}, {:?})", + self.who, + if self.role == NodeRole::Voter { + "V" + } else { + "T" + } + ) + } +} + +/// A one-way graph note. This can only store a pointer to its parent. +#[derive(Clone)] +pub(crate) struct Node { + /// The identifier of the note. + pub(crate) id: NodeId, + /// The parent pointer. + pub(crate) parent: Option>, +} + +impl PartialEq for Node { + fn eq(&self, other: &Node) -> bool { + self.id == other.id + } +} + +impl Eq for Node {} + +#[cfg(feature = "std")] +impl fmt::Debug for Node { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "({:?} --> {:?})", + self.id, + self.parent.as_ref().map(|p| p.borrow().id.clone()) + ) + } +} + +impl Node { + /// Create a new [`Node`] + pub fn new(id: NodeId) -> Node { + Self { id, parent: None } + } + + /// Returns true if `other` is the parent of `who`. + pub fn is_parent_of(who: &NodeRef, other: &NodeRef) -> bool { + if who.borrow().parent.is_none() { + return false; + } + who.borrow().parent.as_ref() == Some(other) + } + + /// Removes the parent of `who`. + pub fn remove_parent(who: &NodeRef) { + who.borrow_mut().parent = None; + } + + /// Sets `who`'s parent to be `parent`. + pub fn set_parent_of(who: &NodeRef, parent: &NodeRef) { + who.borrow_mut().parent = Some(parent.clone()); + } + + /// Finds the root of `start`. It return a tuple of `(root, root_vec)` where `root_vec` is the + /// vector of Nodes leading to the root. Hence the first element is the start itself and the + /// last one is the root. As convenient, the root itself is also returned as the first element + /// of the tuple. + /// + /// This function detects cycles and breaks as soon a duplicate node is visited, returning the + /// cycle up to but not including the duplicate node. + /// + /// If you are certain that no cycles exist, you can use [`root_unchecked`]. + pub fn root(start: &NodeRef) -> (NodeRef, Vec>) { + let mut parent_path: Vec> = Vec::new(); + let mut visited: Vec> = Vec::new(); + + parent_path.push(start.clone()); + visited.push(start.clone()); + let mut current = start.clone(); + + while let Some(ref next_parent) = current.clone().borrow().parent { + if visited.contains(next_parent) { + break; + } + parent_path.push(next_parent.clone()); + current = next_parent.clone(); + visited.push(current.clone()); + } + + (current, parent_path) + } + + /// Consumes self and wraps it in a `Rc>`. This type can be used as the pointer type + /// to a parent node. + pub fn into_ref(self) -> NodeRef { + Rc::from(RefCell::from(self)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn id(i: u32) -> NodeId { + NodeId::from(i, NodeRole::Target) + } + + #[test] + fn basic_create_works() { + let node = Node::new(id(10)); + assert_eq!( + node, + Node { + id: NodeId { + who: 10, + role: NodeRole::Target + }, + parent: None + } + ); + } + + #[test] + fn set_parent_works() { + let a = Node::new(id(10)).into_ref(); + let b = Node::new(id(20)).into_ref(); + + assert_eq!(a.borrow().parent, None); + Node::set_parent_of(&a, &b); + assert_eq!(*a.borrow().parent.as_ref().unwrap(), b); + } + + #[test] + fn get_root_singular() { + let a = Node::new(id(1)).into_ref(); + assert_eq!(Node::root(&a), (a.clone(), vec![a.clone()])); + } + + #[test] + fn get_root_works() { + // D <-- A <-- B <-- C + // \ + // <-- E + let a = Node::new(id(1)).into_ref(); + let b = Node::new(id(2)).into_ref(); + let c = Node::new(id(3)).into_ref(); + let d = Node::new(id(4)).into_ref(); + let e = Node::new(id(5)).into_ref(); + let f = Node::new(id(6)).into_ref(); + + Node::set_parent_of(&c, &b); + Node::set_parent_of(&b, &a); + Node::set_parent_of(&e, &a); + Node::set_parent_of(&a, &d); + + assert_eq!( + Node::root(&e), + (d.clone(), vec![e.clone(), a.clone(), d.clone()]), + ); + + assert_eq!(Node::root(&a), (d.clone(), vec![a.clone(), d.clone()]),); + + assert_eq!( + Node::root(&c), + (d.clone(), vec![c.clone(), b.clone(), a.clone(), d.clone()]), + ); + + // D A <-- B <-- C + // F <-- / \ + // <-- E + Node::set_parent_of(&a, &f); + + assert_eq!(Node::root(&a), (f.clone(), vec![a.clone(), f.clone()]),); + + assert_eq!( + Node::root(&c), + (f.clone(), vec![c.clone(), b.clone(), a.clone(), f.clone()]), + ); + } + + #[test] + fn get_root_on_cycle() { + // A ---> B + // | | + // <---- C + let a = Node::new(id(1)).into_ref(); + let b = Node::new(id(2)).into_ref(); + let c = Node::new(id(3)).into_ref(); + + Node::set_parent_of(&a, &b); + Node::set_parent_of(&b, &c); + Node::set_parent_of(&c, &a); + + let (root, path) = Node::root(&a); + assert_eq!(root, c); + assert_eq!(path.clone(), vec![a.clone(), b.clone(), c.clone()]); + } + + #[test] + fn get_root_on_cycle_2() { + // A ---> B + // | | | + // - C + let a = Node::new(id(1)).into_ref(); + let b = Node::new(id(2)).into_ref(); + let c = Node::new(id(3)).into_ref(); + + Node::set_parent_of(&a, &b); + Node::set_parent_of(&b, &c); + Node::set_parent_of(&c, &b); + + let (root, path) = Node::root(&a); + assert_eq!(root, c); + assert_eq!(path.clone(), vec![a.clone(), b.clone(), c.clone()]); + } + + #[test] + fn node_cmp_stack_overflows_on_non_unique_elements() { + // To make sure we don't stack overflow on duplicate who. This needs manual impl of + // PartialEq. + let a = Node::new(id(1)).into_ref(); + let b = Node::new(id(2)).into_ref(); + let c = Node::new(id(3)).into_ref(); + + Node::set_parent_of(&a, &b); + Node::set_parent_of(&b, &c); + Node::set_parent_of(&c, &a); + + Node::root(&a); + } +} diff --git a/primitives/phragmen/src/reduce.rs b/primitives/phragmen/src/reduce.rs new file mode 100644 index 0000000000..54a71a7ff2 --- /dev/null +++ b/primitives/phragmen/src/reduce.rs @@ -0,0 +1,1076 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Rust implementation of the Phragmén reduce algorithm. This can be used by any off chain +//! application to reduce cycles from the edge assignment, which will result in smaller size. +//! +//! ### Notions +//! - `m`: size of the committee to elect. +//! - `k`: maximum allowed votes (16 as of this writing). +//! - `nv ∈ E` means that nominator `n ∈ N` supports the election of candidate `v ∈ V`. +//! - A valid solution consists of a tuple `(S, W)` , where `S ⊆ V` is a committee of m validators, +//! and `W : E → R ≥ 0` is an edge weight vector which describes how the budget of each nominator +//! n is fractionally assigned to n 's elected neighbors. +//! - `E_w := { e ∈ E : w_e > 0 }`. +//! +//! ### Algorithm overview +//! +//! > We consider the input edge weight vector `w` as a directed flow over `E_w` , where the flow in +//! > each edge is directed from the nominator to the validator. We build `w′` from `w` by removing +//! > **circulations** to cancel out the flow over as many edges as possible, while preserving flow +//! > demands over all vertices and without reverting the flow direction over any edge. As long as +//! > there is a cycle, we can remove an additional circulation and eliminate at least one new edge +//! > from `E_w′` . This shows that the algorithm always progresses and will eventually finish with +//! > an acyclic edge support. We keep a data structure that represents a forest of rooted trees, +//! > which is initialized as a collection of singletons – one per vertex – and to which edges in +//! > `E_w` are added one by one, causing the trees to merge. Whenever a new edge creates a cycle, +//! > we detect it and destroy it by removing a circulation. We also run a pre-computation which is +//! > designed to detect and remove cycles of length four exclusively. This pre-computation is +//! > optional, and if we skip it then the running time becomes `O (|E_w| ⋅ m), so the +//! > pre-computation makes sense only if `m >> k` and `|E_w| >> m^2`. +//! +//! ### Resources: +//! +//! 1. https://hackmd.io/JOn9x98iS0e0DPWQ87zGWg?view + +use crate::node::{Node, NodeId, NodeRef, NodeRole}; +use crate::{ExtendedBalance, IdentifierT, StakedAssignment}; +use sp_runtime::traits::{Bounded, Zero}; +use sp_std::{ + collections::btree_map::{BTreeMap, Entry::*}, + prelude::*, +}; + +/// Map type used for reduce_4. Can be easily swapped with HashMap. +type Map = BTreeMap<(A, A), A>; + +/// Returns all combinations of size two in the collection `input` with no repetition. +fn combinations_2(input: &[T]) -> Vec<(T, T)> { + let n = input.len(); + if n < 2 { + return Default::default(); + } + + let mut comb = Vec::with_capacity(n * (n - 1) / 2); + for i in 0..n { + for j in i + 1..n { + comb.push((input[i].clone(), input[j].clone())) + } + } + comb +} + +/// Returns the count of trailing common elements in two slices. +pub(crate) fn trailing_common(t1: &[T], t2: &[T]) -> usize { + t1.iter().rev().zip(t2.iter().rev()).take_while(|e| e.0 == e.1).count() +} + +/// Merges two parent roots as described by the reduce algorithm. +fn merge(voter_root_path: Vec>, target_root_path: Vec>) { + let (shorter_path, longer_path) = if voter_root_path.len() <= target_root_path.len() { + (voter_root_path, target_root_path) + } else { + (target_root_path, voter_root_path) + }; + + // iterate from last to beginning, skipping the first one. This asserts that + // indexing is always correct. + shorter_path + .iter() + .zip(shorter_path.iter().skip(1)) + .for_each(|(voter, next)| Node::set_parent_of(&next, &voter)); + Node::set_parent_of(&shorter_path[0], &longer_path[0]); +} + +/// Reduce only redundant edges with cycle length of 4. +/// +/// Returns the number of edges removed. +/// +/// It is strictly assumed that the `who` attribute of all provided assignments are unique. The +/// result will most likely be corrupt otherwise. +/// +/// O(|E_w| ⋅ k). +fn reduce_4(assignments: &mut Vec>) -> u32 { + let mut combination_map: Map = Map::new(); + let mut num_changed: u32 = Zero::zero(); + + // we have to use the old fashioned loops here with manual indexing. Borrowing assignments will + // not work since then there is NO way to mutate it inside. + for assignment_index in 0..assignments.len() { + let who = assignments[assignment_index].who.clone(); + + // all combinations for this particular voter + let distribution_ids = &assignments[assignment_index] + .distribution + .iter() + .map(|(t, _p)| t.clone()) + .collect::>(); + let candidate_combinations = combinations_2(distribution_ids); + + for (v1, v2) in candidate_combinations { + match combination_map.entry((v1.clone(), v2.clone())) { + Vacant(entry) => { + entry.insert(who.clone()); + } + Occupied(mut entry) => { + let other_who = entry.get_mut(); + + // double check if who is still voting for this pair. If not, it means that this + // pair is no longer valid and must have been removed in previous rounds. The + // reason for this is subtle; candidate_combinations is created once while the + // inner loop might remove some edges. Note that if count() > 2, the we have + // duplicates. + if assignments[assignment_index] + .distribution + .iter() + .filter(|(t, _)| *t == v1 || *t == v2) + .count() != 2 + { + continue; + } + + // check if other_who voted for the same pair v1, v2. + let maybe_other_assignments = assignments.iter().find(|a| a.who == *other_who); + if maybe_other_assignments.is_none() { + continue; + } + let other_assignment = + maybe_other_assignments.expect("value is checked to be 'Some'"); + + // Collect potential cycle votes + let mut other_cycle_votes = other_assignment + .distribution + .iter() + .filter_map(|(t, w)| { + if *t == v1 || *t == v2 { + Some((t.clone(), *w)) + } else { + None + } + }) + .collect::>(); + + let other_votes_count = other_cycle_votes.len(); + + // If the length is more than 2, then we have identified duplicates. For now, we + // just skip. Later on we can early exit and stop processing this data since it + // is corrupt anyhow. + debug_assert!(other_votes_count <= 2); + + if other_votes_count < 2 { + // This is not a cycle. Replace and continue. + *other_who = who.clone(); + continue; + } else if other_votes_count == 2 { + // This is a cycle. + let mut who_cycle_votes: Vec<(A, ExtendedBalance)> = Vec::with_capacity(2); + assignments[assignment_index] + .distribution + .iter() + .for_each(|(t, w)| { + if *t == v1 || *t == v2 { + who_cycle_votes.push((t.clone(), *w)); + } + }); + + if who_cycle_votes.len() != 2 { + continue; + } + + // Align the targets similarly. This helps with the circulation below. + if other_cycle_votes[0].0 != who_cycle_votes[0].0 { + other_cycle_votes.swap(0, 1); + } + + // Find min + let mut min_value: ExtendedBalance = Bounded::max_value(); + let mut min_index: usize = 0; + let cycle = who_cycle_votes + .iter() + .chain(other_cycle_votes.iter()) + .enumerate() + .map(|(index, (t, w))| { + if *w <= min_value { + min_value = *w; + min_index = index; + } + (t.clone(), *w) + }) + .collect::>(); + + // min was in the first part of the chained iters + let mut increase_indices: Vec = Vec::new(); + let mut decrease_indices: Vec = Vec::new(); + decrease_indices.push(min_index); + if min_index < 2 { + // min_index == 0 => sibling_index <- 1 + // min_index == 1 => sibling_index <- 0 + let sibling_index = 1 - min_index; + increase_indices.push(sibling_index); + // valid because the two chained sections of `cycle` are aligned; + // index [0, 2] are both voting for v1 or both v2. Same goes for [1, 3]. + decrease_indices.push(sibling_index + 2); + increase_indices.push(min_index + 2); + } else { + // min_index == 2 => sibling_index <- 3 + // min_index == 3 => sibling_index <- 2 + let sibling_index = 3 - min_index % 2; + increase_indices.push(sibling_index); + // valid because the two chained sections of `cycle` are aligned; + // index [0, 2] are both voting for v1 or both v2. Same goes for [1, 3]. + decrease_indices.push(sibling_index - 2); + increase_indices.push(min_index - 2); + } + + // apply changes + let mut remove_indices: Vec = Vec::with_capacity(1); + increase_indices.into_iter().for_each(|i| { + let voter = if i < 2 { + who.clone() + } else { + other_who.clone() + }; + // Note: so this is pretty ambiguous. We should only look for one + // assignment that meets this criteria and if we find multiple then that + // is a corrupt input. Same goes for the next block. + assignments + .iter_mut() + .filter(|a| a.who == voter) + .for_each(|ass| { + ass.distribution + .iter_mut() + .position(|(t, _)| *t == cycle[i].0) + .map(|idx| { + let next_value = + ass.distribution[idx].1.saturating_add(min_value); + ass.distribution[idx].1 = next_value; + }); + }); + }); + decrease_indices.into_iter().for_each(|i| { + let voter = if i < 2 { + who.clone() + } else { + other_who.clone() + }; + assignments + .iter_mut() + .filter(|a| a.who == voter) + .for_each(|ass| { + ass.distribution + .iter_mut() + .position(|(t, _)| *t == cycle[i].0) + .map(|idx| { + let next_value = + ass.distribution[idx].1.saturating_sub(min_value); + if next_value.is_zero() { + ass.distribution.remove(idx); + remove_indices.push(i); + num_changed += 1; + } else { + ass.distribution[idx].1 = next_value; + } + }); + }); + }); + + // remove either one of them. + let who_removed = remove_indices.iter().find(|i| **i < 2usize).is_some(); + let other_removed = + remove_indices.into_iter().find(|i| *i >= 2usize).is_some(); + + match (who_removed, other_removed) { + (false, true) => { + *other_who = who.clone(); + } + (true, false) => { + // nothing, other_who can stay there. + } + (true, true) => { + // remove and don't replace + entry.remove(); + } + (false, false) => { + // Neither of the edges was removed? impossible. + debug_assert!(false, "Duplicate voter (or other corrupt input)."); + } + } + } + } + } + } + } + + num_changed +} + +/// Reduce redundant edges from the edge weight graph, with all possible length. +/// +/// To get the best performance, this should be called after `reduce_4()`. +/// +/// Returns the number of edges removed. +/// +/// It is strictly assumed that the `who` attribute of all provided assignments are unique. The +/// result will most likely be corrupt otherwise. +/// +/// O(|Ew| ⋅ m) +fn reduce_all(assignments: &mut Vec>) -> u32 { + let mut num_changed: u32 = Zero::zero(); + let mut tree: BTreeMap, NodeRef> = BTreeMap::new(); + + // NOTE: This code can heavily use an index cache. Looking up a pair of (voter, target) in the + // assignments happens numerous times and and we can save time. For now it is written as such + // because abstracting some of this code into a function/closure is super hard due to borrow + // checks (and most likely needs unsafe code at the end). For now I will keep it as it and + // refactor later. + + // a flat iterator of (voter, target) over all pairs of votes. Similar to reduce_4, we loop + // without borrowing. + for assignment_index in 0..assignments.len() { + let voter = assignments[assignment_index].who.clone(); + + let mut dist_index = 0; + loop { + // A distribution could have been removed. We don't know for sure. Hence, we check. + let maybe_dist = assignments[assignment_index].distribution.get(dist_index); + if maybe_dist.is_none() { + // The rest of this loop is moot. + break; + } + let (target, _) = maybe_dist.expect("Value checked to be some").clone(); + + // store if they existed already. + let voter_id = NodeId::from(voter.clone(), NodeRole::Voter); + let target_id = NodeId::from(target.clone(), NodeRole::Target); + let voter_exists = tree.contains_key(&voter_id); + let target_exists = tree.contains_key(&target_id); + + // create both. + let voter_node = tree + .entry(voter_id.clone()) + .or_insert(Node::new(voter_id).into_ref()) + .clone(); + let target_node = tree + .entry(target_id.clone()) + .or_insert(Node::new(target_id).into_ref()) + .clone(); + + // If one exists but the other one doesn't, or if both does not, then set the existing + // one as the parent of the non-existing one and move on. Else, continue with the rest + // of the code. + match (voter_exists, target_exists) { + (false, false) => { + Node::set_parent_of(&target_node, &voter_node); + dist_index += 1; + continue; + } + (false, true) => { + Node::set_parent_of(&voter_node, &target_node); + dist_index += 1; + continue; + } + (true, false) => { + Node::set_parent_of(&target_node, &voter_node); + dist_index += 1; + continue; + } + (true, true) => { /* don't continue and execute the rest */ } + }; + + let (voter_root, voter_root_path) = Node::root(&voter_node); + let (target_root, target_root_path) = Node::root(&target_node); + + if voter_root != target_root { + // swap + merge(voter_root_path, target_root_path); + dist_index += 1; + } else { + // find common and cycle. + let common_count = trailing_common(&voter_root_path, &target_root_path); + + // because roots are the same. + #[cfg(feature = "std")] + debug_assert_eq!( + target_root_path.last().unwrap(), + voter_root_path.last().unwrap() + ); + debug_assert!(common_count > 0); + + // cycle part of each path will be `path[path.len() - common_count - 1 : 0]` + // NOTE: the order of chaining is important! it is always build from [target, ..., + // voter] + let cycle = target_root_path + .iter() + .take(target_root_path.len() - common_count + 1) + .cloned() + .chain( + voter_root_path + .iter() + .take(voter_root_path.len() - common_count) + .rev() + .cloned(), + ) + .collect::>>(); + + // a cycle's length shall always be multiple of two. + #[cfg(feature = "std")] + debug_assert_eq!(cycle.len() % 2, 0); + + // find minimum of cycle. + let mut min_value: ExtendedBalance = Bounded::max_value(); + // The voter and the target pair that create the min edge. + let mut min_target: A = Default::default(); + let mut min_voter: A = Default::default(); + // The index of the min in opaque cycle list. + let mut min_index = 0usize; + // 1 -> next // 0 -> prev + let mut min_direction = 0u32; + // helpers + let next_index = |i| { + if i < (cycle.len() - 1) { + i + 1 + } else { + 0 + } + }; + let prev_index = |i| { + if i > 0 { + i - 1 + } else { + cycle.len() - 1 + } + }; + for i in 0..cycle.len() { + if cycle[i].borrow().id.role == NodeRole::Voter { + // NOTE: sadly way too many clones since I don't want to make A: Copy + let current = cycle[i].borrow().id.who.clone(); + let next = cycle[next_index(i)].borrow().id.who.clone(); + let prev = cycle[prev_index(i)].borrow().id.who.clone(); + assignments.iter().find(|a| a.who == current).map(|ass| { + ass.distribution.iter().find(|d| d.0 == next).map(|(_, w)| { + if *w < min_value { + min_value = *w; + min_target = next.clone(); + min_voter = current.clone(); + min_index = i; + min_direction = 1; + } + }) + }); + assignments.iter().find(|a| a.who == current).map(|ass| { + ass.distribution.iter().find(|d| d.0 == prev).map(|(_, w)| { + if *w < min_value { + min_value = *w; + min_target = prev.clone(); + min_voter = current.clone(); + min_index = i; + min_direction = 0; + } + }) + }); + } + } + + // if the min edge is in the voter's sub-chain. + // [target, ..., X, Y, ... voter] + let target_chunk = target_root_path.len() - common_count; + let min_chain_in_voter = (min_index + min_direction as usize) > target_chunk; + + // walk over the cycle and update the weights + let mut should_inc_counter = true; + let start_operation_add = ((min_index % 2) + min_direction as usize) % 2 == 1; + let mut additional_removed = Vec::new(); + for i in 0..cycle.len() { + let current = cycle[i].borrow(); + if current.id.role == NodeRole::Voter { + let prev = cycle[prev_index(i)].borrow(); + assignments + .iter_mut() + .enumerate() + .filter(|(_, a)| a.who == current.id.who) + .for_each(|(target_ass_index, ass)| { + ass.distribution + .iter_mut() + .position(|(t, _)| *t == prev.id.who) + .map(|idx| { + let next_value = if i % 2 == 0 { + if start_operation_add { + ass.distribution[idx].1.saturating_add(min_value) + } else { + ass.distribution[idx].1.saturating_sub(min_value) + } + } else { + if start_operation_add { + ass.distribution[idx].1.saturating_sub(min_value) + } else { + ass.distribution[idx].1.saturating_add(min_value) + } + }; + + if next_value.is_zero() { + // if the removed edge is from the current assignment, dis_index + // should NOT be increased. + if target_ass_index == assignment_index { + should_inc_counter = false + } + ass.distribution.remove(idx); + num_changed += 1; + // only add if this is not the min itself. + if !(i == min_index && min_direction == 0) { + additional_removed.push(( + cycle[i].clone(), + cycle[prev_index(i)].clone(), + )); + } + } else { + ass.distribution[idx].1 = next_value; + } + }); + }); + + let next = cycle[next_index(i)].borrow(); + assignments + .iter_mut() + .enumerate() + .filter(|(_, a)| a.who == current.id.who) + .for_each(|(target_ass_index, ass)| { + ass.distribution + .iter_mut() + .position(|(t, _)| *t == next.id.who) + .map(|idx| { + let next_value = if i % 2 == 0 { + if start_operation_add { + ass.distribution[idx].1.saturating_sub(min_value) + } else { + ass.distribution[idx].1.saturating_add(min_value) + } + } else { + if start_operation_add { + ass.distribution[idx].1.saturating_add(min_value) + } else { + ass.distribution[idx].1.saturating_sub(min_value) + } + }; + + if next_value.is_zero() { + // if the removed edge is from the current assignment, dis_index + // should NOT be increased. + if target_ass_index == assignment_index { + should_inc_counter = false + } + ass.distribution.remove(idx); + num_changed += 1; + if !(i == min_index && min_direction == 1) { + additional_removed.push(( + cycle[i].clone(), + cycle[next_index(i)].clone(), + )); + } + } else { + ass.distribution[idx].1 = next_value; + } + }); + }); + } + } + + // don't do anything if the edge removed itself. This is always the first and last + // element + let should_reorg = !(min_index == (cycle.len() - 1) && min_direction == 1); + + // re-org. + if should_reorg { + let min_edge = vec![min_voter, min_target]; + if min_chain_in_voter { + // NOTE: safe; voter_root_path is always bigger than 1 element. + for i in 0..voter_root_path.len() - 1 { + let current = voter_root_path[i].clone().borrow().id.who.clone(); + let next = voter_root_path[i + 1].clone().borrow().id.who.clone(); + if min_edge.contains(¤t) && min_edge.contains(&next) { + break; + } + Node::set_parent_of(&voter_root_path[i + 1], &voter_root_path[i]); + } + Node::set_parent_of(&voter_node, &target_node); + } else { + // NOTE: safe; target_root_path is always bigger than 1 element. + for i in 0..target_root_path.len() - 1 { + let current = target_root_path[i].clone().borrow().id.who.clone(); + let next = target_root_path[i + 1].clone().borrow().id.who.clone(); + if min_edge.contains(¤t) && min_edge.contains(&next) { + break; + } + Node::set_parent_of(&target_root_path[i + 1], &target_root_path[i]); + } + Node::set_parent_of(&target_node, &voter_node); + } + } + + // remove every other node which has collapsed to zero + for (r1, r2) in additional_removed { + if Node::is_parent_of(&r1, &r2) { + Node::remove_parent(&r1); + } else if Node::is_parent_of(&r2, &r1) { + Node::remove_parent(&r2); + } + } + + // increment the counter if needed. + if should_inc_counter { + dist_index += 1; + } + } + } + } + + num_changed +} + +/// Reduce the given [`PhragmenResult`]. This removes redundant edges from without changing the +/// overall backing of any of the elected candidates. +/// +/// Returns the number of edges removed. +/// +/// IMPORTANT: It is strictly assumed that the `who` attribute of all provided assignments are +/// unique. The result will most likely be corrupt otherwise. Furthermore, if the _distribution +/// vector_ contains duplicate ids, only the first instance is ever updates. +/// +/// O(min{ |Ew| ⋅ k + m3 , |Ew| ⋅ m }) +pub fn reduce(assignments: &mut Vec>) -> u32 where { + let mut num_changed = reduce_4(assignments); + num_changed += reduce_all(assignments); + num_changed +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn merging_works() { + // D <-- A <-- B <-- C + // + // F <-- E + let d = Node::new(NodeId::from(1, NodeRole::Target)).into_ref(); + let a = Node::new(NodeId::from(2, NodeRole::Target)).into_ref(); + let b = Node::new(NodeId::from(3, NodeRole::Target)).into_ref(); + let c = Node::new(NodeId::from(4, NodeRole::Target)).into_ref(); + let e = Node::new(NodeId::from(5, NodeRole::Target)).into_ref(); + let f = Node::new(NodeId::from(6, NodeRole::Target)).into_ref(); + + Node::set_parent_of(&c, &b); + Node::set_parent_of(&b, &a); + Node::set_parent_of(&a, &d); + Node::set_parent_of(&e, &f); + + let path1 = vec![c.clone(), b.clone(), a.clone(), d.clone()]; + let path2 = vec![e.clone(), f.clone()]; + + merge(path1, path2); + // D <-- A <-- B <-- C + // | + // F --> E --> --> + assert_eq!(e.borrow().clone().parent.unwrap().borrow().id.who, 4u32); // c + } + + #[test] + fn merge_with_len_one() { + // D <-- A <-- B <-- C + // + // F <-- E + let d = Node::new(NodeId::from(1, NodeRole::Target)).into_ref(); + let a = Node::new(NodeId::from(2, NodeRole::Target)).into_ref(); + let b = Node::new(NodeId::from(3, NodeRole::Target)).into_ref(); + let c = Node::new(NodeId::from(4, NodeRole::Target)).into_ref(); + let f = Node::new(NodeId::from(6, NodeRole::Target)).into_ref(); + + Node::set_parent_of(&c, &b); + Node::set_parent_of(&b, &a); + Node::set_parent_of(&a, &d); + + let path1 = vec![c.clone(), b.clone(), a.clone(), d.clone()]; + let path2 = vec![f.clone()]; + + merge(path1, path2); + // D <-- A <-- B <-- C + // | + // F --> --> + assert_eq!(f.borrow().clone().parent.unwrap().borrow().id.who, 4u32); // c + } + + #[test] + fn basic_reduce_4_cycle_works() { + use super::*; + + let assignments = vec![ + StakedAssignment { + who: 1, + distribution: vec![(10, 25), (20, 75)], + }, + StakedAssignment { + who: 2, + distribution: vec![(10, 50), (20, 50)], + }, + ]; + + let mut new_assignments = assignments.clone(); + let num_reduced = reduce_4(&mut new_assignments); + + assert_eq!(num_reduced, 1); + assert_eq!( + new_assignments, + vec![ + StakedAssignment { + who: 1, + distribution: vec![(20, 100),], + }, + StakedAssignment { + who: 2, + distribution: vec![(10, 75), (20, 25),], + }, + ], + ); + } + + #[test] + fn basic_reduce_all_cycles_works() { + let mut assignments = vec![ + StakedAssignment { + who: 1, + distribution: vec![(10, 10)], + }, + StakedAssignment { + who: 2, + distribution: vec![(10, 15), (20, 5)], + }, + StakedAssignment { + who: 3, + distribution: vec![(20, 15), (40, 15)], + }, + StakedAssignment { + who: 4, + distribution: vec![(20, 10), (30, 10), (40, 20)], + }, + StakedAssignment { + who: 5, + distribution: vec![(20, 20), (30, 10), (40, 20)], + }, + ]; + + assert_eq!(3, reduce_all(&mut assignments)); + + assert_eq!( + assignments, + vec![ + StakedAssignment { + who: 1, + distribution: vec![(10, 10),] + }, + StakedAssignment { + who: 2, + distribution: vec![(10, 15), (20, 5),], + }, + StakedAssignment { + who: 3, + distribution: vec![(20, 30),], + }, + StakedAssignment { + who: 4, + distribution: vec![(40, 40),] + }, + StakedAssignment { + who: 5, + distribution: vec![(20, 15), (30, 20), (40, 15),], + }, + ], + ) + } + + #[test] + fn basic_reduce_works() { + let mut assignments = vec![ + StakedAssignment { + who: 1, + distribution: vec![(10, 10)], + }, + StakedAssignment { + who: 2, + distribution: vec![(10, 15), (20, 5)], + }, + StakedAssignment { + who: 3, + distribution: vec![(20, 15), (40, 15)], + }, + StakedAssignment { + who: 4, + distribution: vec![(20, 10), (30, 10), (40, 20)], + }, + StakedAssignment { + who: 5, + distribution: vec![(20, 20), (30, 10), (40, 20)], + }, + ]; + + assert_eq!(3, reduce(&mut assignments)); + + assert_eq!( + assignments, + vec![ + StakedAssignment { + who: 1, + distribution: vec![(10, 10),] + }, + StakedAssignment { + who: 2, + distribution: vec![(10, 15), (20, 5),], + }, + StakedAssignment { + who: 3, + distribution: vec![(20, 30),], + }, + StakedAssignment { + who: 4, + distribution: vec![(40, 40),] + }, + StakedAssignment { + who: 5, + distribution: vec![(20, 15), (30, 20), (40, 15),], + }, + ], + ) + } + + #[test] + fn should_deal_with_self_vote() { + let mut assignments = vec![ + StakedAssignment { + who: 1, + distribution: vec![(10, 10)], + }, + StakedAssignment { + who: 2, + distribution: vec![(10, 15), (20, 5)], + }, + StakedAssignment { + who: 3, + distribution: vec![(20, 15), (40, 15)], + }, + StakedAssignment { + who: 4, + distribution: vec![(20, 10), (30, 10), (40, 20)], + }, + StakedAssignment { + who: 5, + distribution: vec![(20, 20), (30, 10), (40, 20)], + }, + // self vote from 10 and 20 to itself. + StakedAssignment { + who: 10, + distribution: vec![(10, 100)], + }, + StakedAssignment { + who: 20, + distribution: vec![(20, 200)], + }, + ]; + + assert_eq!(3, reduce(&mut assignments)); + + assert_eq!( + assignments, + vec![ + StakedAssignment { + who: 1, + distribution: vec![(10, 10),] + }, + StakedAssignment { + who: 2, + distribution: vec![(10, 15), (20, 5),], + }, + StakedAssignment { + who: 3, + distribution: vec![(20, 30),], + }, + StakedAssignment { + who: 4, + distribution: vec![(40, 40),] + }, + StakedAssignment { + who: 5, + distribution: vec![(20, 15), (30, 20), (40, 15),], + }, + // should stay untouched. + StakedAssignment { + who: 10, + distribution: vec![(10, 100)] + }, + StakedAssignment { + who: 20, + distribution: vec![(20, 200)] + }, + ], + ) + } + + #[test] + fn reduce_3_common_votes_same_weight() { + let mut assignments = vec![ + StakedAssignment { + who: 4, + distribution: vec![ + ( + 1000000, + 100, + ), + ( + 1000002, + 100, + ), + ( + 1000004, + 100, + ), + ], + }, + StakedAssignment { + who: 5, + distribution: vec![ + ( + 1000000, + 100, + ), + ( + 1000002, + 100, + ), + ( + 1000004, + 100, + ), + ], + }, + ]; + + reduce_4(&mut assignments); + + assert_eq!( + assignments, + vec![ + StakedAssignment { + who: 4, + distribution: vec![(1000000, 200,), (1000004, 100,),], + }, + StakedAssignment { + who: 5, + distribution: vec![(1000002, 200,), (1000004, 100,),], + }, + ], + ) + } + + #[test] + #[should_panic] + fn reduce_panics_on_duplicate_voter() { + let mut assignments = vec![ + StakedAssignment { + who: 1, + distribution: vec![(10, 10), (20, 10)], + }, + StakedAssignment { + who: 1, + distribution: vec![(10, 15), (20, 5)], + }, + StakedAssignment { + who: 2, + distribution: vec![(10, 15), (20, 15)], + }, + ]; + + reduce(&mut assignments); + } + + #[test] + fn should_deal_with_duplicates_target() { + let mut assignments = vec![ + StakedAssignment { + who: 1, + distribution: vec![(10, 15), (20, 5)], + }, + StakedAssignment { + who: 2, + distribution: vec![ + (10, 15), + (20, 15), + // duplicate + (10, 1), + // duplicate + (20, 1), + ], + }, + ]; + + reduce(&mut assignments); + + assert_eq!( + assignments, + vec![ + StakedAssignment { + who: 1, + distribution: vec![(10, 20),], + }, + StakedAssignment { + who: 2, + distribution: vec![ + (10, 10), + (20, 20), + // duplicate votes are silently ignored. + (10, 1), + (20, 1), + ], + }, + ], + ) + } + + #[test] + fn bound_should_be_kept() { + let mut assignments = vec![ + StakedAssignment { + who: 1, + distribution: vec![(103, 72), (101, 53), (100, 83), (102, 38)], + }, + StakedAssignment { + who: 2, + distribution: vec![(103, 18), (101, 36), (102, 54), (100, 94)], + }, + StakedAssignment { + who: 3, + distribution: vec![(100, 96), (101, 35), (102, 52), (103, 69)], + }, + StakedAssignment { + who: 4, + distribution: vec![(102, 34), (100, 47), (103, 91), (101, 73)], + }, + ]; + + let winners = vec![103, 101, 100, 102]; + + let n = 4; + let m = winners.len() as u32; + let num_reduced = reduce_all(&mut assignments); + assert!(16 - num_reduced <= n + m); + } +} diff --git a/primitives/phragmen/src/tests.rs b/primitives/phragmen/src/tests.rs index 8bcf007c7b..e9861ede72 100644 --- a/primitives/phragmen/src/tests.rs +++ b/primitives/phragmen/src/tests.rs @@ -19,11 +19,12 @@ #![cfg(test)] use crate::mock::*; -use crate::{elect, PhragmenResult, PhragmenStakedAssignment, build_support_map, Support, equalize}; +use crate::{ + elect, equalize, build_support_map, is_score_better, + Support, StakedAssignment, Assignment, PhragmenResult, ExtendedBalance, +}; use substrate_test_utils::assert_eq_uvec; -use sp_runtime::Perbill; - -type Output = Perbill; +use sp_runtime::{Perbill, Permill, Percent, PerU16, traits::Convert}; #[test] fn float_phragmen_poc_works() { @@ -81,7 +82,7 @@ fn phragmen_poc_works() { ]; let stake_of = create_stake_of(&[(10, 10), (20, 20), (30, 30)]); - let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Perbill>( 2, 2, candidates, @@ -92,9 +93,21 @@ fn phragmen_poc_works() { assert_eq_uvec!( assignments, vec![ - (10, vec![(2, Perbill::from_percent(100))]), - (20, vec![(3, Perbill::from_percent(100))]), - (30, vec![(2, Perbill::from_percent(100/2)), (3, Perbill::from_percent(100/2))]), + Assignment { + who: 10u64, + distribution: vec![(2, Perbill::from_percent(100))], + }, + Assignment { + who: 20, + distribution: vec![(3, Perbill::from_percent(100))], + }, + Assignment { + who: 30, + distribution: vec![ + (2, Perbill::from_percent(100/2)), + (3, Perbill::from_percent(100/2)), + ], + }, ] ); } @@ -115,7 +128,10 @@ fn phragmen_poc_2_works() { (4, 500), ]); - run_and_compare(candidates, voters, stake_of, 2, 2); + run_and_compare::(candidates.clone(), voters.clone(), &stake_of, 2, 2); + run_and_compare::(candidates.clone(), voters.clone(), &stake_of, 2, 2); + run_and_compare::(candidates.clone(), voters.clone(), &stake_of, 2, 2); + run_and_compare::(candidates, voters, &stake_of, 2, 2); } #[test] @@ -133,7 +149,10 @@ fn phragmen_poc_3_works() { (4, 1000), ]); - run_and_compare(candidates, voters, stake_of, 2, 2); + run_and_compare::(candidates.clone(), voters.clone(), &stake_of, 2, 2); + run_and_compare::(candidates.clone(), voters.clone(), &stake_of, 2, 2); + run_and_compare::(candidates.clone(), voters.clone(), &stake_of, 2, 2); + run_and_compare::(candidates, voters, &stake_of, 2, 2); } #[test] @@ -149,7 +168,7 @@ fn phragmen_accuracy_on_large_scale_only_validators() { (5, (u64::max_value() - 2).into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Perbill>( 2, 2, candidates.clone(), @@ -158,7 +177,7 @@ fn phragmen_accuracy_on_large_scale_only_validators() { assert_eq_uvec!(winners, vec![(1, 18446744073709551614u128), (5, 18446744073709551613u128)]); assert_eq!(assignments.len(), 2); - check_assignments(assignments); + check_assignments_sum(assignments); } #[test] @@ -179,7 +198,7 @@ fn phragmen_accuracy_on_large_scale_validators_and_nominators() { (14, u64::max_value().into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Perbill>( 2, 2, candidates, @@ -190,13 +209,25 @@ fn phragmen_accuracy_on_large_scale_validators_and_nominators() { assert_eq!( assignments, vec![ - (13, vec![(1, Perbill::one())]), - (14, vec![(2, Perbill::one())]), - (1, vec![(1, Perbill::one())]), - (2, vec![(2, Perbill::one())]), + Assignment { + who: 13u64, + distribution: vec![(1, Perbill::one())], + }, + Assignment { + who: 14, + distribution: vec![(2, Perbill::one())], + }, + Assignment { + who: 1, + distribution: vec![(1, Perbill::one())], + }, + Assignment { + who: 2, + distribution: vec![(2, Perbill::one())], + }, ] ); - check_assignments(assignments); + check_assignments_sum(assignments); } #[test] @@ -210,7 +241,7 @@ fn phragmen_accuracy_on_small_scale_self_vote() { (30, 1), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments: _ } = elect::<_, _, TestCurrencyToVote, Perbill>( 3, 3, candidates, @@ -240,7 +271,7 @@ fn phragmen_accuracy_on_small_scale_no_self_vote() { (3, 1), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments: _ } = elect::<_, _, TestCurrencyToVote, Perbill>( 3, 3, candidates, @@ -273,7 +304,7 @@ fn phragmen_large_scale_test() { (50, 990000000000000000), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Perbill>( 2, 2, candidates, @@ -281,7 +312,7 @@ fn phragmen_large_scale_test() { ).unwrap(); assert_eq_uvec!(winners, vec![(24, 1490000000000200000u128), (22, 1490000000000100000u128)]); - check_assignments(assignments); + check_assignments_sum(assignments); } #[test] @@ -299,7 +330,7 @@ fn phragmen_large_scale_test_2() { (50, nom_budget.into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments } = elect::<_, _, TestCurrencyToVote, Perbill>( 2, 2, candidates, @@ -310,12 +341,24 @@ fn phragmen_large_scale_test_2() { assert_eq!( assignments, vec![ - (50, vec![(2, Perbill::from_parts(500000001)), (4, Perbill::from_parts(499999999))]), - (2, vec![(2, Perbill::one())]), - (4, vec![(4, Perbill::one())]), + Assignment { + who: 50u64, + distribution: vec![ + (2, Perbill::from_parts(500000001)), + (4, Perbill::from_parts(499999999)) + ], + }, + Assignment { + who: 2, + distribution: vec![(2, Perbill::one())], + }, + Assignment { + who: 4, + distribution: vec![(4, Perbill::one())], + }, ], ); - check_assignments(assignments); + check_assignments_sum(assignments); } #[test] @@ -348,7 +391,7 @@ fn phragmen_linear_equalize() { (130, 1000), ]); - run_and_compare(candidates, voters, stake_of, 2, 2); + run_and_compare::(candidates, voters, &stake_of, 2, 2); } #[test] @@ -363,7 +406,7 @@ fn elect_has_no_entry_barrier() { (2, 10), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, _, TestCurrencyToVote, Output>( + let PhragmenResult { winners, assignments: _ } = elect::<_, _, TestCurrencyToVote, Perbill>( 3, 3, candidates, @@ -390,7 +433,7 @@ fn minimum_to_elect_is_respected() { (2, 10), ]); - let maybe_result = elect::<_, _, TestCurrencyToVote, Output>( + let maybe_result = elect::<_, _, TestCurrencyToVote, Perbill>( 10, 10, candidates, @@ -416,7 +459,7 @@ fn self_votes_should_be_kept() { (1, 8), ]); - let result = elect::<_, _, TestCurrencyToVote, Output>( + let result = elect::<_, _, TestCurrencyToVote, Perbill>( 2, 2, candidates, @@ -427,27 +470,28 @@ fn self_votes_should_be_kept() { assert_eq!( result.assignments, vec![ - (10, vec![(10, Perbill::from_percent(100))]), - (20, vec![(20, Perbill::from_percent(100))]), - (1, vec![ + Assignment { who: 10, distribution: vec![(10, Perbill::from_percent(100))] }, + Assignment { who: 20, distribution: vec![(20, Perbill::from_percent(100))] }, + Assignment { who: 1, distribution: vec![ (10, Perbill::from_percent(50)), (20, Perbill::from_percent(50)) ] - ) + }, ], ); - let mut supports = build_support_map::< - Balance, - AccountId, - _, - TestCurrencyToVote, - Output, - >( - &result.winners.into_iter().map(|(who, _)| who).collect(), - &result.assignments, - &stake_of - ); + let staked_assignments: Vec> = result.assignments + .into_iter() + .map(|a| { + let stake = >::convert(stake_of(&a.who)) as ExtendedBalance; + a.into_staked(stake, true) + }).collect(); + + let winners = result.winners.into_iter().map(|(who, _)| who).collect::>(); + let (mut supports, _) = build_support_map::( + winners.as_slice(), + &staked_assignments, + ); assert_eq!(supports.get(&5u64), None); assert_eq!( @@ -459,23 +503,13 @@ fn self_votes_should_be_kept() { &Support { total: 24u128, voters: vec![(20u64, 20u128), (1u64, 4u128)] }, ); - let assignments = result.assignments; - let mut staked_assignments - : Vec<(AccountId, Vec>)> - = Vec::with_capacity(assignments.len()); - for (n, assignment) in assignments.iter() { - let mut staked_assignment - : Vec> - = Vec::with_capacity(assignment.len()); - let stake = stake_of(&n); - for (c, per_thing) in assignment.iter() { - let vote_stake = *per_thing * stake; - staked_assignment.push((c.clone(), vote_stake)); - } - staked_assignments.push((n.clone(), staked_assignment)); - } - - equalize::(staked_assignments, &mut supports, 0, 2usize, &stake_of); + equalize::( + staked_assignments, + &mut supports, + 0, + 2usize, + &stake_of, + ); assert_eq!( supports.get(&10u64).unwrap(), @@ -486,3 +520,462 @@ fn self_votes_should_be_kept() { &Support { total: 20u128, voters: vec![(20u64, 20u128)] }, ); } + +#[test] +fn assignment_convert_works() { + let staked = StakedAssignment { + who: 1 as AccountId, + distribution: vec![ + (20, 100 as Balance), + (30, 25), + ], + }; + + let assignment = staked.clone().into_assignment(true); + assert_eq!( + assignment, + Assignment { + who: 1, + distribution: vec![ + (20, Perbill::from_percent(80)), + (30, Perbill::from_percent(20)), + ] + } + ); + + assert_eq!( + assignment.into_staked(125, true), + staked, + ); +} + +#[test] +fn score_comparison_is_lexicographical() { + // only better in the fist parameter, worse in the other two ✅ + assert_eq!( + is_score_better([10, 20, 30], [12, 10, 35]), + true, + ); + + // worse in the first, better in the other two ❌ + assert_eq!( + is_score_better([10, 20, 30], [9, 30, 10]), + false, + ); + + // equal in the first, the second one dictates. + assert_eq!( + is_score_better([10, 20, 30], [10, 25, 40]), + true, + ); + + // equal in the first two, the last one dictates. + assert_eq!( + is_score_better([10, 20, 30], [10, 20, 40]), + false, + ); +} + +mod compact { + use codec::{Decode, Encode}; + use crate::generate_compact_solution_type; + use super::{AccountId, Balance}; + // these need to come from the same dev-dependency `sp-phragmen`, not from the crate. + use sp_phragmen::{Assignment, StakedAssignment, Error as PhragmenError}; + use sp_std::{convert::{TryInto, TryFrom}, fmt::Debug}; + use sp_runtime::Percent; + + type Accuracy = Percent; + + generate_compact_solution_type!(TestCompact, 16); + + #[test] + fn compact_struct_is_codec() { + let compact = TestCompact::<_, _, _> { + votes1: vec![(2u64, 20), (4, 40)], + votes2: vec![ + (1, (10, Accuracy::from_percent(80)), 11), + (5, (50, Accuracy::from_percent(85)), 51), + ], + ..Default::default() + }; + + let encoded = compact.encode(); + + assert_eq!( + compact, + Decode::decode(&mut &encoded[..]).unwrap(), + ); + } + + fn basic_ratio_test_with() where + V: codec::Codec + Copy + Default + PartialEq + Eq + TryInto + TryFrom + From + Debug, + T: codec::Codec + Copy + Default + PartialEq + Eq + TryInto + TryFrom + From + Debug, + >::Error: std::fmt::Debug, + >::Error: std::fmt::Debug, + >::Error: std::fmt::Debug, + >::Error: std::fmt::Debug, + { + let voters = vec![ + 2 as AccountId, + 4, + 1, + 5, + 3, + ]; + let targets = vec![ + 10 as AccountId, + 11, + 20, // 2 + 30, + 31, // 4 + 32, + 40, // 6 + 50, + 51, // 8 + ]; + + let assignments = vec![ + Assignment { + who: 2 as AccountId, + distribution: vec![(20u64, Accuracy::from_percent(100))] + }, + Assignment { + who: 4, + distribution: vec![(40, Accuracy::from_percent(100))], + }, + Assignment { + who: 1, + distribution: vec![ + (10, Accuracy::from_percent(80)), + (11, Accuracy::from_percent(20)) + ], + }, + Assignment { + who: 5, + distribution: vec![ + (50, Accuracy::from_percent(85)), + (51, Accuracy::from_percent(15)), + ] + }, + Assignment { + who: 3, + distribution: vec![ + (30, Accuracy::from_percent(50)), + (31, Accuracy::from_percent(25)), + (32, Accuracy::from_percent(25)), + ], + }, + ]; + + let voter_index = |a: &AccountId| -> Option { + voters.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() + }; + let target_index = |a: &AccountId| -> Option { + targets.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() + }; + + let compacted = >::from_assignment( + assignments.clone(), + voter_index, + target_index, + ).unwrap(); + + assert_eq!( + compacted, + TestCompact { + votes1: vec![(V::from(0u8), T::from(2u8)), (V::from(1u8), T::from(6u8))], + votes2: vec![ + (V::from(2u8), (T::from(0u8), Accuracy::from_percent(80)), T::from(1u8)), + (V::from(3u8), (T::from(7u8), Accuracy::from_percent(85)), T::from(8u8)), + ], + votes3: vec![ + ( + V::from(4), + [(T::from(3u8), Accuracy::from_percent(50)), (T::from(4u8), Accuracy::from_percent(25))], + T::from(5u8), + ), + ], + ..Default::default() + } + ); + + let voter_at = |a: V| -> Option { voters.get(>::try_into(a).unwrap()).cloned() }; + let target_at = |a: T| -> Option { targets.get(>::try_into(a).unwrap()).cloned() }; + + assert_eq!( + compacted.into_assignment(voter_at, target_at).unwrap(), + assignments, + ); + } + + #[test] + fn basic_from_and_into_compact_works_assignments() { + basic_ratio_test_with::(); + basic_ratio_test_with::(); + basic_ratio_test_with::(); + } + + #[test] + fn basic_from_and_into_compact_works_staked_assignments() { + let voters = vec![ + 2 as AccountId, + 4, + 1, + 5, + 3, + ]; + let targets = vec![ + 10 as AccountId, 11, + 20, + 30, 31, 32, + 40, + 50, 51, + ]; + + let assignments = vec![ + StakedAssignment { + who: 2 as AccountId, + distribution: vec![(20, 100 as Balance)] + }, + StakedAssignment { + who: 4, + distribution: vec![(40, 100)], + }, + StakedAssignment { + who: 1, + distribution: vec![ + (10, 80), + (11, 20) + ], + }, + StakedAssignment { + who: 5, distribution: + vec![ + (50, 85), + (51, 15), + ] + }, + StakedAssignment { + who: 3, + distribution: vec![ + (30, 50), + (31, 25), + (32, 25), + ], + }, + ]; + + let voter_index = |a: &AccountId| -> Option { + voters.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() + }; + let target_index = |a: &AccountId| -> Option { + targets.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() + }; + + let compacted = >::from_staked( + assignments.clone(), + voter_index, + target_index, + ).unwrap(); + + assert_eq!( + compacted, + TestCompact { + votes1: vec![(0, 2), (1, 6)], + votes2: vec![ + (2, (0, 80), 1), + (3, (7, 85), 8), + ], + votes3: vec![ + (4, [(3, 50), (4, 25)], 5), + ], + ..Default::default() + } + ); + + let max_of_fn = |_: &AccountId| -> Balance { 100u128 }; + let voter_at = |a: u16| -> Option { voters.get(a as usize).cloned() }; + let target_at = |a: u16| -> Option { targets.get(a as usize).cloned() }; + + assert_eq!( + compacted.into_staked( + max_of_fn, + voter_at, + target_at, + ).unwrap(), + assignments, + ); + } + + #[test] + fn compact_into_stake_must_report_overflow() { + // The last edge which is computed from the rest should ALWAYS be positive. + // in votes2 + let compact = TestCompact:: { + votes1: Default::default(), + votes2: vec![(0, (1, 10), 2)], + ..Default::default() + }; + + let entity_at = |a: u16| -> Option { Some(a as AccountId) }; + let max_of = |_: &AccountId| -> Balance { 5 }; + + assert_eq!( + compact.into_staked(&max_of, &entity_at, &entity_at).unwrap_err(), + PhragmenError::CompactStakeOverflow, + ); + + // in votes3 onwards + let compact = TestCompact:: { + votes1: Default::default(), + votes2: Default::default(), + votes3: vec![(0, [(1, 7), (2, 8)], 3)], + ..Default::default() + }; + + assert_eq!( + compact.into_staked(&max_of, &entity_at, &entity_at).unwrap_err(), + PhragmenError::CompactStakeOverflow, + ); + + // Also if equal + let compact = TestCompact:: { + votes1: Default::default(), + votes2: Default::default(), + // 5 is total, we cannot leave none for 30 here. + votes3: vec![(0, [(1, 3), (2, 2)], 3)], + ..Default::default() + }; + + assert_eq!( + compact.into_staked(&max_of, &entity_at, &entity_at).unwrap_err(), + PhragmenError::CompactStakeOverflow, + ); + } + + #[test] + fn compact_into_assignment_must_report_overflow() { + // in votes2 + let compact = TestCompact:: { + votes1: Default::default(), + votes2: vec![(0, (1, Accuracy::from_percent(100)), 2)], + ..Default::default() + }; + + let entity_at = |a: u16| -> Option { Some(a as AccountId) }; + + assert_eq!( + compact.into_assignment(&entity_at, &entity_at).unwrap_err(), + PhragmenError::CompactStakeOverflow, + ); + + // in votes3 onwards + let compact = TestCompact:: { + votes1: Default::default(), + votes2: Default::default(), + votes3: vec![(0, [(1, Accuracy::from_percent(70)), (2, Accuracy::from_percent(80))], 3)], + ..Default::default() + }; + + assert_eq!( + compact.into_assignment(&entity_at, &entity_at).unwrap_err(), + PhragmenError::CompactStakeOverflow, + ); + } + + #[test] + fn target_count_overflow_is_detected() { + let assignments = vec![ + StakedAssignment { + who: 1 as AccountId, + distribution: (10..26).map(|i| (i as AccountId, i as Balance)).collect::>(), + }, + ]; + + let entity_index = |a: &AccountId| -> Option { Some(*a as u16) }; + + let compacted = >::from_staked( + assignments.clone(), + entity_index, + entity_index, + ); + + assert!(compacted.is_ok()); + + let assignments = vec![ + StakedAssignment { + who: 1 as AccountId, + distribution: (10..27).map(|i| (i as AccountId, i as Balance)).collect::>(), + }, + ]; + + let compacted = >::from_staked( + assignments.clone(), + entity_index, + entity_index, + ); + + assert_eq!( + compacted.unwrap_err(), + PhragmenError::CompactTargetOverflow, + ); + + let assignments = vec![ + Assignment { + who: 1 as AccountId, + distribution: (10..27).map(|i| (i as AccountId, Percent::from_parts(i as u8))).collect::>(), + }, + ]; + + let compacted = >::from_assignment( + assignments.clone(), + entity_index, + entity_index, + ); + + assert_eq!( + compacted.unwrap_err(), + PhragmenError::CompactTargetOverflow, + ); + } + + #[test] + fn zero_target_count_is_ignored() { + let voters = vec![1 as AccountId, 2]; + let targets = vec![10 as AccountId, 11]; + + let assignments = vec![ + StakedAssignment { + who: 1 as AccountId, + distribution: vec![(10, 100 as Balance), (11, 100)] + }, + StakedAssignment { + who: 2, + distribution: vec![], + }, + ]; + + let voter_index = |a: &AccountId| -> Option { + voters.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() + }; + let target_index = |a: &AccountId| -> Option { + targets.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() + }; + + let compacted = >::from_staked( + assignments.clone(), + voter_index, + target_index, + ).unwrap(); + + assert_eq!( + compacted, + TestCompact { + votes1: Default::default(), + votes2: vec![(0, (0, 100), 1)], + ..Default::default() + } + ); + } +} diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 632deb13cb..1a9aad6bdf 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -68,7 +68,10 @@ pub use sp_application_crypto::{RuntimeAppPublic, BoundToRuntimeAppPublic}; pub use sp_core::RuntimeDebug; /// Re-export top-level arithmetic stuff. -pub use sp_arithmetic::{Perquintill, Perbill, Permill, Percent, Rational128, Fixed64, PerThing}; +pub use sp_arithmetic::{ + Perquintill, Perbill, Permill, Percent, PerU16, Rational128, Fixed64, PerThing, + traits::SaturatedConversion, +}; /// Re-export 128 bit helpers. pub use sp_arithmetic::helpers_128bit; /// Re-export big_uint stuff. diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 0ddb5c4dbf..6bd4b263c3 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -929,7 +929,7 @@ pub trait OpaqueKeys: Clone { fn key_ids() -> &'static [crate::KeyTypeId]; /// Get the raw bytes of key with key-type ID `i`. fn get_raw(&self, i: super::KeyTypeId) -> &[u8]; - /// Get the decoded key with index `i`. + /// Get the decoded key with key-type ID `i`. fn get(&self, i: super::KeyTypeId) -> Option { T::decode(&mut self.get_raw(i)).ok() } diff --git a/primitives/staking/src/offence.rs b/primitives/staking/src/offence.rs index 06e73f018b..584f3a75ea 100644 --- a/primitives/staking/src/offence.rs +++ b/primitives/staking/src/offence.rs @@ -142,11 +142,20 @@ pub trait OnOffenceHandler { /// Zero is a valid value for a fraction. /// /// The `session` parameter is the session index of the offence. + /// + /// The receiver might decide to not accept this offence. In this case, the call site is + /// responsible for queuing the report and re-submitting again. fn on_offence( offenders: &[OffenceDetails], slash_fraction: &[Perbill], session: SessionIndex, - ); + ) -> Result<(), ()>; + + /// Can an offence be reported now or not. This is an method to short-circuit a call into + /// `on_offence`. Ideally, a correct implementation should return `false` if `on_offence` will + /// return `Err`. Nonetheless, this is up to the implementation and this trait cannot guarantee + /// it. + fn can_report() -> bool; } impl OnOffenceHandler for () { @@ -154,7 +163,9 @@ impl OnOffenceHandler for () { _offenders: &[OffenceDetails], _slash_fraction: &[Perbill], _session: SessionIndex, - ) {} + ) -> Result<(), ()> { Ok(()) } + + fn can_report() -> bool { true } } /// A details about an offending authority for a particular kind of offence. -- GitLab From 2ba47dbcae8564bdf6493040c34ce7a5bf1005bf Mon Sep 17 00:00:00 2001 From: Seun Lanlege Date: Thu, 26 Mar 2020 16:03:34 +0100 Subject: [PATCH 087/300] Adds state_queryStorageAt (#5362) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * adds state_queryStorageAt * make at param for query_storage_at optional * Update client/rpc/src/state/state_full.rs Co-Authored-By: Tomasz Drwięga * adds query_storage_at to StateBackend Co-authored-by: Tomasz Drwięga --- client/rpc-api/src/state/mod.rs | 8 +++++ client/rpc/src/state/mod.rs | 15 +++++++++ client/rpc/src/state/state_full.rs | 20 +++++++++--- client/rpc/src/state/state_light.rs | 8 +++++ client/rpc/src/state/tests.rs | 47 +++++++++++++++++++++++++---- 5 files changed, 88 insertions(+), 10 deletions(-) diff --git a/client/rpc-api/src/state/mod.rs b/client/rpc-api/src/state/mod.rs index b2cf8ce909..d29e46a4b5 100644 --- a/client/rpc-api/src/state/mod.rs +++ b/client/rpc-api/src/state/mod.rs @@ -136,6 +136,14 @@ pub trait StateApi { hash: Option ) -> FutureResult>>; + /// Query storage entries (by key) starting at block hash given as the second parameter. + #[rpc(name = "state_queryStorageAt")] + fn query_storage_at( + &self, + keys: Vec, + at: Option, + ) -> FutureResult>>; + /// New runtime version subscription #[pubsub( subscription = "state_runtimeVersion", diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index 82568866ee..2747405c04 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -163,6 +163,13 @@ pub trait StateBackend: Send + Sync + 'static keys: Vec, ) -> FutureResult>>; + /// Query storage entries (by key) starting at block hash given as the second parameter. + fn query_storage_at( + &self, + keys: Vec, + at: Option + ) -> FutureResult>>; + /// New runtime version subscription fn subscribe_runtime_version( &self, @@ -357,6 +364,14 @@ impl StateApi for State self.backend.query_storage(from, to, keys) } + fn query_storage_at( + &self, + keys: Vec, + at: Option + ) -> FutureResult>> { + self.backend.query_storage_at(keys, at) + } + fn subscribe_storage( &self, meta: Self::Metadata, diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index b7589d2aef..bf80820543 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -33,7 +33,7 @@ use sp_core::{ }; use sp_version::RuntimeVersion; use sp_runtime::{ - generic::BlockId, traits::{Block as BlockT, NumberFor, SaturatedConversion}, + generic::BlockId, traits::{Block as BlockT, NumberFor, SaturatedConversion, CheckedSub}, }; use sp_api::{Metadata, ProvideRuntimeApi, CallApiAt}; @@ -94,8 +94,8 @@ impl FullState let from_meta = self.client.header_metadata(from).map_err(invalid_block_err)?; let to_meta = self.client.header_metadata(to).map_err(invalid_block_err)?; - if from_meta.number >= to_meta.number { - return Err(invalid_block_range(&from_meta, &to_meta, "from number >= to number".to_owned())) + if from_meta.number > to_meta.number { + return Err(invalid_block_range(&from_meta, &to_meta, "from number > to number".to_owned())) } // check if we can get from `to` to `from` by going through parent_hashes. @@ -122,7 +122,10 @@ impl FullState .max_key_changes_range(from_number, BlockId::Hash(to_meta.hash)) .map_err(client_err)?; let filtered_range_begin = changes_trie_range - .map(|(begin, _)| (begin - from_number).saturated_into::()); + .and_then(|(begin, _)| { + // avoids a corner case where begin < from_number (happens when querying genesis) + begin.checked_sub(&from_number).map(|x| x.saturated_into::()) + }); let (unfiltered_range, filtered_range) = split_range(hashes.len(), filtered_range_begin); Ok(QueryStorageRange { @@ -398,6 +401,15 @@ impl StateBackend for FullState, + at: Option + ) -> FutureResult>> { + let at = at.unwrap_or_else(|| self.client.info().best_hash); + self.query_storage(at, Some(at), keys) + } + fn subscribe_runtime_version( &self, _meta: crate::metadata::Metadata, diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index 59c0f2183c..092419ad01 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -331,6 +331,14 @@ impl StateBackend for LightState, + _at: Option + ) -> FutureResult>> { + Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) + } + fn subscribe_storage( &self, _meta: crate::metadata::Metadata, diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index c7b5f88215..4a9b701959 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -30,6 +30,7 @@ use substrate_test_runtime_client::{ sp_consensus::BlockOrigin, runtime, }; +use sp_runtime::generic::BlockId; const CHILD_INFO: ChildInfo<'static> = ChildInfo::new_default(b"unique_id"); @@ -212,7 +213,7 @@ fn should_send_initial_storage_changes_and_notifications() { #[test] fn should_query_storage() { - fn run_tests(mut client: Arc) { + fn run_tests(mut client: Arc, has_changes_trie_config: bool) { let core = tokio::runtime::Runtime::new().unwrap(); let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); @@ -237,6 +238,13 @@ fn should_query_storage() { let block2_hash = add_block(1); let genesis_hash = client.genesis_hash(); + if has_changes_trie_config { + assert_eq!( + client.max_key_changes_range(1, BlockId::Hash(block1_hash)).unwrap(), + Some((0, BlockId::Hash(block1_hash))), + ); + } + let mut expected = vec![ StorageChangeSet { block: genesis_hash, @@ -306,7 +314,7 @@ fn should_query_storage() { Err(Error::InvalidBlockRange { from: format!("1 ({:?})", block1_hash), to: format!("0 ({:?})", genesis_hash), - details: "from number >= to number".to_owned(), + details: "from number > to number".to_owned(), }).map_err(|e| e.to_string()) ); @@ -376,12 +384,39 @@ fn should_query_storage() { details: format!("UnknownBlock: header not found in db: {}", random_hash1), }).map_err(|e| e.to_string()), ); + + // single block range + let result = api.query_storage_at( + keys.clone(), + Some(block1_hash), + ); + + assert_eq!( + result.wait().unwrap(), + vec![ + StorageChangeSet { + block: block1_hash, + changes: vec![ + (StorageKey(vec![1_u8]), None), + (StorageKey(vec![2_u8]), Some(StorageData(vec![2_u8]))), + (StorageKey(vec![3_u8]), Some(StorageData(vec![3_u8]))), + (StorageKey(vec![4_u8]), None), + (StorageKey(vec![5_u8]), Some(StorageData(vec![0_u8]))), + ] + } + ] + ); } - run_tests(Arc::new(substrate_test_runtime_client::new())); - run_tests(Arc::new(TestClientBuilder::new() - .changes_trie_config(Some(ChangesTrieConfiguration::new(4, 2))) - .build())); + run_tests(Arc::new(substrate_test_runtime_client::new()), false); + run_tests( + Arc::new( + TestClientBuilder::new() + .changes_trie_config(Some(ChangesTrieConfiguration::new(4, 2))) + .build(), + ), + true, + ); } #[test] -- GitLab From f7bd10a548201cb68491f72be73115279d97f160 Mon Sep 17 00:00:00 2001 From: gabriel klawitter Date: Thu, 26 Mar 2020 21:10:53 +0530 Subject: [PATCH 088/300] ci: check_polkadot: look for arbitrary link to polkadot pr eventually (#5415) --- .maintain/gitlab/check_polkadot.sh | 35 ++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/.maintain/gitlab/check_polkadot.sh b/.maintain/gitlab/check_polkadot.sh index 1d5bba98af..0df940ffe2 100755 --- a/.maintain/gitlab/check_polkadot.sh +++ b/.maintain/gitlab/check_polkadot.sh @@ -3,9 +3,11 @@ # check if a pr is compatible with polkadot companion pr or master if not # available # -# mark companion pr in the body of the polkadot pr like +# to override one that was just mentioned mark companion pr in the body of the +# polkadot pr like # # polkadot companion: paritytech/polkadot#567 +# github_api_substrate_pull_url="https://api.github.com/repos/paritytech/substrate/pulls" @@ -29,7 +31,9 @@ polkadot companion: paritytech/polkadot#567 it will then run cargo check from this polkadot's branch with substrate code -from this pull request. +from this pull request. in absence of that string it will check if a polkadot +pr is mentioned and will use the last one instead. if none of the above can be +found it will check the build against polkadot:master. EOT @@ -49,18 +53,27 @@ if expr match "${CI_COMMIT_REF_NAME}" '^[0-9]\+$' >/dev/null then boldprint "this is pull request no ${CI_COMMIT_REF_NAME}" # get the last reference to a pr in polkadot - comppr="$(curl -H "${github_header}" -s ${github_api_substrate_pull_url}/${CI_COMMIT_REF_NAME} \ - | sed -n -r \ - -e 's;^[[:space:]]+"body":[[:space:]]+".*polkadot companion: paritytech/polkadot#([0-9]+).*"[^"]+$;\1;p' \ - -e 's;^[[:space:]]+"body":[[:space:]]+".*polkadot companion: https://github.com/paritytech/polkadot/pull/([0-9]+).*"[^"]+$;\1;p' \ + pr_body="$(curl -H "${github_header}" -s ${github_api_substrate_pull_url}/${CI_COMMIT_REF_NAME} \ + | sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p')" + + pr_companion="$(echo "${pr_body}" | sed -n -r \ + -e 's;^.*polkadot companion: paritytech/polkadot#([0-9]+).*$;\1;p' \ + -e 's;^.*polkadot companion: https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ | tail -n 1)" - if [ "${comppr}" ] + if [ -z "${pr_companion}" ] + then + pr_companion="$(echo "${pr_body}" | sed -n -r \ + 's;^.*https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ + | tail -n 1)" + fi + + if [ "${pr_companion}" ] then - boldprint "companion pr specified: #${comppr}" - git fetch --depth 1 origin refs/pull/${comppr}/head:pr/${comppr} - git checkout pr/${comppr} + boldprint "companion pr specified/detected: #${pr_companion}" + git fetch --depth 1 origin refs/pull/${pr_companion}/head:pr/${pr_companion} + git checkout pr/${pr_companion} else - boldprint "no companion pr declared - building polkadot:master" + boldprint "no companion pr found - building polkadot:master" fi else boldprint "this is not a pull request - building polkadot:master" -- GitLab From f1b23dfa420f80457b60ace224808bf843b0bbe1 Mon Sep 17 00:00:00 2001 From: cheme Date: Thu, 26 Mar 2020 20:06:54 +0100 Subject: [PATCH 089/300] Apply review suggestion --- client/network/src/protocol.rs | 23 ++++++--------- .../src/protocol/light_client_handler.rs | 19 +++++-------- client/rpc-api/src/child_state/mod.rs | 3 ++ primitives/state-machine/src/backend.rs | 4 +-- primitives/state-machine/src/basic.rs | 2 +- .../state-machine/src/changes_trie/input.rs | 15 +++------- primitives/state-machine/src/ext.rs | 4 +-- .../state-machine/src/in_memory_backend.rs | 2 +- primitives/storage/src/lib.rs | 28 ++++--------------- test-utils/runtime/client/src/lib.rs | 2 +- 10 files changed, 35 insertions(+), 67 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 788c88b620..d8c8f8dc9c 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -323,7 +323,7 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a> { message::RemoteReadChildRequest { id, block, - storage_key: storage_key.key(), + storage_key: storage_key.into_inner(), keys, }); @@ -365,7 +365,7 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a> { last, min, max, - storage_key: storage_key.map(|p| p.key()), + storage_key: storage_key.map(|p| p.into_inner()), key, }); @@ -1626,7 +1626,7 @@ impl Protocol { trace!(target: "sync", "Remote read child request {} from {} ({} {} at {})", request.id, who, HexDisplay::from(&request.storage_key), keys_str(), request.block); let prefixed_key = PrefixedStorageKey::new_ref(&request.storage_key); - let child_info = match prefixed_key.and_then(|key| ChildType::from_prefixed_key(key)) { + let child_info = match ChildType::from_prefixed_key(prefixed_key) { Some((ChildType::ParentKeyId, storage_key)) => Ok(ChildInfo::new_default(storage_key)), None => Err("Invalid child storage key".into()), }; @@ -1727,24 +1727,17 @@ impl Protocol { request.last ); let key = StorageKey(request.key); - let prefixed_key = if let Some(storage_key) = request.storage_key.as_ref() { - if let Some(storage_key) = PrefixedStorageKey::new_ref(storage_key) { - Ok(Some(storage_key)) - } else { - Err("Invalid prefixed storage key".into()) - } - } else { - Ok(None) - }; + let prefixed_key = request.storage_key.as_ref() + .map(|storage_key| PrefixedStorageKey::new_ref(storage_key)); let (first, last, min, max) = (request.first, request.last, request.min, request.max); - let proof = match prefixed_key.and_then(|p_key| self.context_data.chain.key_changes_proof( + let proof = match self.context_data.chain.key_changes_proof( first, last, min, max, - p_key, + prefixed_key, &key, - )) { + ) { Ok(proof) => proof, Err(error) => { trace!(target: "sync", "Remote changes proof request {} from {} for key {} ({}..{}) failed with: {}", diff --git a/client/network/src/protocol/light_client_handler.rs b/client/network/src/protocol/light_client_handler.rs index dc6ad3fc34..4f20c9ced0 100644 --- a/client/network/src/protocol/light_client_handler.rs +++ b/client/network/src/protocol/light_client_handler.rs @@ -513,7 +513,7 @@ where let block = Decode::decode(&mut request.block.as_ref())?; let prefixed_key = PrefixedStorageKey::new_ref(&request.storage_key); - let child_info = match prefixed_key.and_then(|key| ChildType::from_prefixed_key(key)) { + let child_info = match ChildType::from_prefixed_key(prefixed_key) { Some((ChildType::ParentKeyId, storage_key)) => Ok(ChildInfo::new_default(storage_key)), None => Err("Invalid child storage key".into()), }; @@ -592,18 +592,12 @@ where let max = Decode::decode(&mut request.max.as_ref())?; let key = StorageKey(request.key.clone()); let storage_key = if request.storage_key.is_empty() { - Ok(None) + None } else { - if let Some(storage_key) = PrefixedStorageKey::new_ref(&request.storage_key) { - Ok(Some(storage_key)) - } else { - Err("Invalid prefix for storage key.".into()) - } + Some(PrefixedStorageKey::new_ref(&request.storage_key)) }; - let proof = match storage_key.and_then(|storage_key| { - self.chain.key_changes_proof(first, last, min, max, storage_key, &key) - }) { + let proof = match self.chain.key_changes_proof(first, last, min, max, storage_key, &key) { Ok(proof) => proof, Err(error) => { log::trace!("remote changes proof request from {} for key {} ({:?}..{:?}) failed with: {}", @@ -922,7 +916,7 @@ fn serialize_request(request: &Request) -> api::v1::light::Request Request::ReadChild { request, .. } => { let r = api::v1::light::RemoteReadChildRequest { block: request.block.encode(), - storage_key: request.storage_key.clone().key(), + storage_key: request.storage_key.clone().into_inner(), keys: request.keys.clone(), }; api::v1::light::request::Request::RemoteReadChildRequest(r) @@ -941,7 +935,8 @@ fn serialize_request(request: &Request) -> api::v1::light::Request last: request.last_block.1.encode(), min: request.tries_roots.1.encode(), max: request.max_block.1.encode(), - storage_key: request.storage_key.clone().map(|s| s.key()).unwrap_or_default(), + storage_key: request.storage_key.clone().map(|s| s.into_inner()) + .unwrap_or_default(), key: request.key.clone(), }; api::v1::light::request::Request::RemoteChangesRequest(r) diff --git a/client/rpc-api/src/child_state/mod.rs b/client/rpc-api/src/child_state/mod.rs index 3c530b64de..a46269cad6 100644 --- a/client/rpc-api/src/child_state/mod.rs +++ b/client/rpc-api/src/child_state/mod.rs @@ -23,6 +23,9 @@ use crate::state::error::FutureResult; pub use self::gen_client::Client as ChildStateClient; /// Substrate child state API +/// +/// Note that all `PrefixedStorageKey` are desierialized +/// from json and not guaranted valid. #[rpc] pub trait ChildStateApi { /// RPC Metadata diff --git a/primitives/state-machine/src/backend.rs b/primitives/state-machine/src/backend.rs index c3b2146a73..0d4134b6ad 100644 --- a/primitives/state-machine/src/backend.rs +++ b/primitives/state-machine/src/backend.rs @@ -187,9 +187,9 @@ pub trait Backend: std::fmt::Debug { let prefixed_storage_key = child_info.prefixed_storage_key(); txs.consolidate(child_txs); if empty { - child_roots.push((prefixed_storage_key.key(), None)); + child_roots.push((prefixed_storage_key.into_inner(), None)); } else { - child_roots.push((prefixed_storage_key.key(), Some(child_root.encode()))); + child_roots.push((prefixed_storage_key.into_inner(), Some(child_root.encode()))); } } let (root, parent_txs) = self.storage_root( diff --git a/primitives/state-machine/src/basic.rs b/primitives/state-machine/src/basic.rs index b8b3210a87..f03d5c1659 100644 --- a/primitives/state-machine/src/basic.rs +++ b/primitives/state-machine/src/basic.rs @@ -242,7 +242,7 @@ impl Externalities for BasicExternalities { if &empty_hash[..] == &child_root[..] { top.remove(prefixed_storage_key.as_slice()); } else { - top.insert(prefixed_storage_key.key(), child_root); + top.insert(prefixed_storage_key.into_inner(), child_root); } } diff --git a/primitives/state-machine/src/changes_trie/input.rs b/primitives/state-machine/src/changes_trie/input.rs index 4007620f92..4f0f3da40c 100644 --- a/primitives/state-machine/src/changes_trie/input.rs +++ b/primitives/state-machine/src/changes_trie/input.rs @@ -177,17 +177,10 @@ impl Decode for InputKey { block: Decode::decode(input)?, key: Decode::decode(input)?, })), - 3 => { - let block = Decode::decode(input)?; - if let Some(storage_key) = PrefixedStorageKey::new(Decode::decode(input)?) { - Ok(InputKey::ChildIndex(ChildIndex { - block, - storage_key, - })) - } else { - Err("Invalid prefixed key in change trie".into()) - } - }, + 3 => Ok(InputKey::ChildIndex(ChildIndex { + block: Decode::decode(input)?, + storage_key: PrefixedStorageKey::new(Decode::decode(input)?), + })), _ => Err("Invalid input key variant".into()), } } diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index 33f502a75b..fa0e24d2ec 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -458,9 +458,9 @@ where // A better design would be to manage 'child_storage_transaction' in a // similar way as 'storage_transaction' but for each child trie. if is_empty { - self.overlay.set_storage(prefixed_storage_key.key(), None); + self.overlay.set_storage(prefixed_storage_key.into_inner(), None); } else { - self.overlay.set_storage(prefixed_storage_key.key(), Some(root.clone())); + self.overlay.set_storage(prefixed_storage_key.into_inner(), Some(root.clone())); } trace!(target: "state-trace", "{:04x}: ChildRoot({}) {}", diff --git a/primitives/state-machine/src/in_memory_backend.rs b/primitives/state-machine/src/in_memory_backend.rs index b0048d90f4..5878759753 100644 --- a/primitives/state-machine/src/in_memory_backend.rs +++ b/primitives/state-machine/src/in_memory_backend.rs @@ -331,7 +331,7 @@ impl Backend for InMemory where H::Out: Codec { if let Some(child_info) = child_info.as_ref() { let prefix_storage_key = child_info.prefixed_storage_key(); let ch = insert_into_memory_db::(&mut mdb, map.clone().into_iter())?; - new_child_roots.push((prefix_storage_key.key(), ch.as_ref().into())); + new_child_roots.push((prefix_storage_key.into_inner(), ch.as_ref().into())); } else { root_map = Some(map); } diff --git a/primitives/storage/src/lib.rs b/primitives/storage/src/lib.rs index de2a0d7e01..eeb57d6677 100644 --- a/primitives/storage/src/lib.rs +++ b/primitives/storage/src/lib.rs @@ -61,36 +61,20 @@ impl DerefMut for PrefixedStorageKey { impl PrefixedStorageKey { /// Create a prefixed storage key from its byte array /// representation. - /// Returns `None` on unknown prefix. - pub fn new(inner: Vec) -> Option { - let result = PrefixedStorageKey(inner); - // currently only support for child trie key - // note that this function should not be use in a runtime - // as it will change its behavior with future child types. - if ChildType::from_prefixed_key(&result).is_some() { - Some(result) - } else { - None - } + pub fn new(inner: Vec) -> Self { + PrefixedStorageKey(inner) } - pub fn new_ref(inner: &Vec) -> Option<&Self> { - let result = PrefixedStorageKey::ref_cast(inner); - // currently only support for child trie key - // note that this function should not be use in a runtime - // as it will change its behavior with future child types. - if ChildType::from_prefixed_key(&result).is_some() { - Some(result) - } else { - None - } + /// Create a prefixed storage key reference. + pub fn new_ref(inner: &Vec) -> &Self { + PrefixedStorageKey::ref_cast(inner) } /// Get inner key, this should /// only be needed when writing /// into parent trie to avoid an /// allocation. - pub fn key(self) -> Vec { + pub fn into_inner(self) -> Vec { self.0 } } diff --git a/test-utils/runtime/client/src/lib.rs b/test-utils/runtime/client/src/lib.rs index e4849dee99..10360c8076 100644 --- a/test-utils/runtime/client/src/lib.rs +++ b/test-utils/runtime/client/src/lib.rs @@ -128,7 +128,7 @@ impl substrate_test_client::GenesisInit for GenesisParameters { child_content.data.clone().into_iter().collect() ); let prefixed_storage_key = child_content.child_info.prefixed_storage_key(); - (prefixed_storage_key.key(), state_root.encode()) + (prefixed_storage_key.into_inner(), state_root.encode()) }); let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( storage.top.clone().into_iter().chain(child_roots).collect() -- GitLab From beff53804f44450b9aa10c45d87dadf48828fd60 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Fri, 27 Mar 2020 10:41:31 +0100 Subject: [PATCH 090/300] Add emojis (#5420) --- bin/node/cli/src/browser.rs | 6 +++--- client/basic-authorship/src/basic_authorship.rs | 4 ++-- client/cli/src/commands/runcmd.rs | 8 ++++---- client/cli/src/lib.rs | 2 +- client/consensus/babe/src/lib.rs | 6 +++--- client/consensus/manual-seal/src/finalize_block.rs | 4 ++-- client/consensus/slots/src/lib.rs | 6 +++--- client/finality-grandpa/src/environment.rs | 4 ++-- client/finality-grandpa/src/import.rs | 2 +- client/informant/src/display.rs | 6 +++--- client/informant/src/lib.rs | 4 ++-- client/network/src/discovery.rs | 2 +- client/network/src/protocol/light_dispatch.rs | 6 +++--- client/network/src/protocol/sync.rs | 10 +++++----- client/network/src/protocol/sync/extra_requests.rs | 2 +- client/network/src/service.rs | 4 ++-- client/service/src/builder.rs | 2 +- client/service/src/chain_ops.rs | 4 ++-- client/src/client.rs | 2 +- 19 files changed, 42 insertions(+), 42 deletions(-) diff --git a/bin/node/cli/src/browser.rs b/bin/node/cli/src/browser.rs index e79ce273a3..d0746e8448 100644 --- a/bin/node/cli/src/browser.rs +++ b/bin/node/cli/src/browser.rs @@ -43,9 +43,9 @@ async fn start_inner(chain_spec: String, log_level: String) -> Result ProposerFactory let id = BlockId::hash(parent_hash); - info!("Starting consensus session on top of parent {:?}", parent_hash); + info!("🙌 Starting consensus session on top of parent {:?}", parent_hash); let proposer = Proposer { inner: Arc::new(ProposerInner { @@ -277,7 +277,7 @@ impl ProposerInner let (block, storage_changes, proof) = block_builder.build()?.into_inner(); - info!("Prepared block for proposing at {} [hash: {:?}; parent_hash: {}; extrinsics ({}): [{}]]", + info!("🎁 Prepared block for proposing at {} [hash: {:?}; parent_hash: {}; extrinsics ({}): [{}]]", block.header().number(), ::Hash::from(block.header().hash()), block.header().parent_hash(), diff --git a/client/cli/src/commands/runcmd.rs b/client/cli/src/commands/runcmd.rs index 030d952ec1..8a6d675d32 100644 --- a/client/cli/src/commands/runcmd.rs +++ b/client/cli/src/commands/runcmd.rs @@ -140,7 +140,7 @@ pub struct RunCmd { /// /// A comma-separated list of origins (protocol://domain or special `null` /// value). Value of `all` will disable origin validation. Default is to - /// allow localhost and https://polkadot.js.org origins. When running in + /// allow localhost and https://polkadot.js.org origins. When running in /// --dev mode the default is to allow all origins. #[structopt(long = "rpc-cors", value_name = "ORIGINS", parse(try_from_str = parse_cors))] pub rpc_cors: Option, @@ -461,9 +461,9 @@ impl RunCmd { info!("{}", version.name); info!(" version {}", config.full_version()); info!(" by {}, {}-{}", version.author, version.copyright_start_year, Local::today().year()); - info!("Chain specification: {}", config.expect_chain_spec().name()); - info!("Node name: {}", config.name); - info!("Roles: {}", config.display_role()); + info!("📋 Chain specification: {}", config.expect_chain_spec().name()); + info!("🏷 Node name: {}", config.name); + info!("👤 Roles: {}", config.display_role()); match config.roles { Roles::LIGHT => run_service_until_exit( diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index e28edebd60..f94df935a1 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -211,7 +211,7 @@ pub fn init_logger(pattern: &str) { }); if builder.try_init().is_err() { - info!("Not registering Substrate logger, as there is already a global logger registered!"); + info!("💬 Not registering Substrate logger, as there is already a global logger registered!"); } } diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index 6ce9fc7e72..5365aae2aa 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -368,7 +368,7 @@ pub fn start_babe(BabeParams { &inherent_data_providers, )?; - babe_info!("Starting BABE Authorship worker"); + babe_info!("👶 Starting BABE Authorship worker"); Ok(sc_consensus_slots::start_slot_worker( config.0, select_chain, @@ -1010,7 +1010,7 @@ impl BlockImport for BabeBlockImport::FetchEpoch(parent_hash).into()) })?; - babe_info!("New epoch {} launching at block {} (block slot {} >= start slot {}).", + babe_info!("👶 New epoch {} launching at block {} (block slot {} >= start slot {}).", viable_epoch.as_ref().epoch_index, hash, slot_number, @@ -1018,7 +1018,7 @@ impl BlockImport for BabeBlockImport(params: FinalizeBlockParams) rpc::send_result(&mut sender, Err(e.into())) } Ok(()) => { - log::info!("Successfully finalized block: {}", hash); + log::info!("✅ Successfully finalized block: {}", hash); rpc::send_result(&mut sender, Ok(())) } } -} \ No newline at end of file +} diff --git a/client/consensus/slots/src/lib.rs b/client/consensus/slots/src/lib.rs index 7fc4bdc7d2..d0f1f6ec4b 100644 --- a/client/consensus/slots/src/lib.rs +++ b/client/consensus/slots/src/lib.rs @@ -258,10 +258,10 @@ pub trait SimpleSlotWorker { Box::new(futures::future::select(proposing, delay).map(move |v| match v { futures::future::Either::Left((b, _)) => b.map(|b| (b, claim)), futures::future::Either::Right(_) => { - info!("Discarding proposal for slot {}; block production took too long", slot_number); + info!("⌛️ Discarding proposal for slot {}; block production took too long", slot_number); // If the node was compiled with debug, tell the user to use release optimizations. #[cfg(build_type="debug")] - info!("Recompile your node in `--release` mode to mitigate this problem."); + info!("👉 Recompile your node in `--release` mode to mitigate this problem."); telemetry!(CONSENSUS_INFO; "slots.discarding_proposal_took_too_long"; "slot" => slot_number, ); @@ -289,7 +289,7 @@ pub trait SimpleSlotWorker { ); info!( - "Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.", + "🔖 Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.", header_num, block_import_params.post_hash(), header_hash, diff --git a/client/finality-grandpa/src/environment.rs b/client/finality-grandpa/src/environment.rs index a0f37f20cb..eb80ad30ac 100644 --- a/client/finality-grandpa/src/environment.rs +++ b/client/finality-grandpa/src/environment.rs @@ -1090,9 +1090,9 @@ pub(crate) fn finalize_block( let (new_id, set_ref) = authority_set.current(); if set_ref.len() > 16 { - info!("Applying GRANDPA set change to new set with {} authorities", set_ref.len()); + info!("👴 Applying GRANDPA set change to new set with {} authorities", set_ref.len()); } else { - info!("Applying GRANDPA set change to new set {:?}", set_ref); + info!("👴 Applying GRANDPA set change to new set {:?}", set_ref); } telemetry!(CONSENSUS_INFO; "afg.generating_new_authority_set"; diff --git a/client/finality-grandpa/src/import.rs b/client/finality-grandpa/src/import.rs index ef5cc739de..004e14bcba 100644 --- a/client/finality-grandpa/src/import.rs +++ b/client/finality-grandpa/src/import.rs @@ -629,7 +629,7 @@ where match result { Err(CommandOrError::VoterCommand(command)) => { - info!(target: "afg", "Imported justification for block #{} that triggers \ + info!(target: "afg", "👴 Imported justification for block #{} that triggers \ command {}, signaling voter.", number, command); // send the command to the voter diff --git a/client/informant/src/display.rs b/client/informant/src/display.rs index 53c9697868..f08c1f04c7 100644 --- a/client/informant/src/display.rs +++ b/client/informant/src/display.rs @@ -68,9 +68,9 @@ impl InformantDisplay { self.last_number = Some(best_number); let (status, target) = match (net_status.sync_state, net_status.best_seen_block) { - (SyncState::Idle, _) => ("Idle".into(), "".into()), - (SyncState::Downloading, None) => (format!("Syncing{}", speed), "".into()), - (SyncState::Downloading, Some(n)) => (format!("Syncing{}", speed), format!(", target=#{}", n)), + (SyncState::Idle, _) => ("💤 Idle".into(), "".into()), + (SyncState::Downloading, None) => (format!("⚙️ Syncing{}", speed), "".into()), + (SyncState::Downloading, Some(n)) => (format!("⚙️ Syncing{}", speed), format!(", target=#{}", n)), }; if self.format == OutputFormat::Coloured { diff --git a/client/informant/src/lib.rs b/client/informant/src/lib.rs index d104a64a2d..5c2ac41d44 100644 --- a/client/informant/src/lib.rs +++ b/client/informant/src/lib.rs @@ -79,7 +79,7 @@ pub fn build(service: &impl AbstractService, format: OutputFormat) -> impl futur match maybe_ancestor { Ok(ref ancestor) if ancestor.hash != *last_hash => info!( - "Reorg from #{},{} to #{},{}, common ancestor #{},{}", + "♻️ Reorg from #{},{} to #{},{}, common ancestor #{},{}", last_num, last_hash, n.header.number(), n.hash, ancestor.number, ancestor.hash, @@ -94,7 +94,7 @@ pub fn build(service: &impl AbstractService, format: OutputFormat) -> impl futur last_best = Some((n.header.number().clone(), n.hash.clone())); } - info!(target: "substrate", "Imported #{} ({})", n.header.number(), n.hash); + info!(target: "substrate", "✨ Imported #{} ({})", n.header.number(), n.hash); future::ready(()) }); diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index ecce7d81e3..ed5016642b 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -293,7 +293,7 @@ impl NetworkBehaviour for DiscoveryBehaviour { fn inject_new_external_addr(&mut self, addr: &Multiaddr) { let new_addr = addr.clone() .with(Protocol::P2p(self.local_peer_id.clone().into())); - info!(target: "sub-libp2p", "Discovered new external address for our node: {}", new_addr); + info!(target: "sub-libp2p", "🔍 Discovered new external address for our node: {}", new_addr); NetworkBehaviour::inject_new_external_addr(&mut self.kademlia, addr) } diff --git a/client/network/src/protocol/light_dispatch.rs b/client/network/src/protocol/light_dispatch.rs index 22d26075b3..39e90881fb 100644 --- a/client/network/src/protocol/light_dispatch.rs +++ b/client/network/src/protocol/light_dispatch.rs @@ -270,7 +270,7 @@ impl LightDispatch where let request = match self.remove(peer.clone(), request_id) { Some(request) => request, None => { - info!("Invalid remote {} response from peer {}", rtype, peer); + info!("💔 Invalid remote {} response from peer {}", rtype, peer); network.report_peer(&peer, ReputationChange::new_fatal("Invalid remote response")); network.disconnect_peer(&peer); self.remove_peer(&peer); @@ -282,7 +282,7 @@ impl LightDispatch where let (retry_count, retry_request_data) = match try_accept(request, &self.checker) { Accept::Ok => (retry_count, None), Accept::CheckFailed(error, retry_request_data) => { - info!("Failed to check remote {} response from peer {}: {}", rtype, peer, error); + info!("💔 Failed to check remote {} response from peer {}: {}", rtype, peer, error); network.report_peer(&peer, ReputationChange::new_fatal("Failed remote response check")); network.disconnect_peer(&peer); self.remove_peer(&peer); @@ -296,7 +296,7 @@ impl LightDispatch where } }, Accept::Unexpected(retry_request_data) => { - info!("Unexpected response to remote {} from peer", rtype); + info!("💔 Unexpected response to remote {} from peer", rtype); network.report_peer(&peer, ReputationChange::new_fatal("Unexpected remote response")); network.disconnect_peer(&peer); self.remove_peer(&peer); diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index e8629b4fdf..df12522d37 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -378,12 +378,12 @@ impl ChainSync { Err(BadPeer(who, rep::BLOCKCHAIN_READ_ERROR)) } Ok(BlockStatus::KnownBad) => { - info!("New peer with known bad best block {} ({}).", best_hash, best_number); + info!("💔 New peer with known bad best block {} ({}).", best_hash, best_number); Err(BadPeer(who, rep::BAD_BLOCK)) } Ok(BlockStatus::Unknown) => { if best_number.is_zero() { - info!("New peer with unknown genesis hash {} ({}).", best_hash, best_number); + info!("💔 New peer with unknown genesis hash {} ({}).", best_hash, best_number); return Err(BadPeer(who, rep::GENESIS_MISMATCH)); } // If there are more than `MAJOR_SYNC_BLOCKS` in the import queue then we have @@ -711,7 +711,7 @@ impl ChainSync { return Err(BadPeer(who, rep::UNKNOWN_ANCESTOR)) }, (_, Err(e)) => { - info!("Error answering legitimate blockchain query: {:?}", e); + info!("❌ Error answering legitimate blockchain query: {:?}", e); return Err(BadPeer(who, rep::BLOCKCHAIN_READ_ERROR)) } }; @@ -943,7 +943,7 @@ impl ChainSync { if aux.bad_justification { if let Some(peer) = who { - info!("Sent block with bad justification to import"); + info!("💔 Sent block with bad justification to import"); output.push(Err(BadPeer(peer, rep::BAD_JUSTIFICATION))); } } @@ -973,7 +973,7 @@ impl ChainSync { }, Err(BlockImportError::BadBlock(who)) => { if let Some(peer) = who { - info!("Block {:?} received from peer {} has been blacklisted", hash, peer); + info!("💔 Block {:?} received from peer {} has been blacklisted", hash, peer); output.push(Err(BadPeer(peer, rep::BAD_BLOCK))); } }, diff --git a/client/network/src/protocol/sync/extra_requests.rs b/client/network/src/protocol/sync/extra_requests.rs index 81b12a1a70..3d854b574b 100644 --- a/client/network/src/protocol/sync/extra_requests.rs +++ b/client/network/src/protocol/sync/extra_requests.rs @@ -221,7 +221,7 @@ impl ExtraRequests { }; if self.tree.finalize_root(&finalized_hash).is_none() { - warn!(target: "sync", "Imported {:?} {:?} which isn't a root in the tree: {:?}", + warn!(target: "sync", "‼️ Imported {:?} {:?} which isn't a root in the tree: {:?}", finalized_hash, finalized_number, self.tree.roots().collect::>() diff --git a/client/network/src/service.rs b/client/network/src/service.rs index e06d3bd13e..17a0e67cdc 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -1090,7 +1090,7 @@ impl<'a, B: BlockT, H: ExHashT> Link for NetworkLink<'a, B, H> { fn justification_imported(&mut self, who: PeerId, hash: &B::Hash, number: NumberFor, success: bool) { self.protocol.user_protocol_mut().justification_import_result(hash.clone(), number, success); if !success { - info!("Invalid justification provided by {} for #{}", who, hash); + info!("💔 Invalid justification provided by {} for #{}", who, hash); self.protocol.user_protocol_mut().disconnect_peer(&who); self.protocol.user_protocol_mut().report_peer(who, ReputationChange::new_fatal("Invalid justification")); } @@ -1110,7 +1110,7 @@ impl<'a, B: BlockT, H: ExHashT> Link for NetworkLink<'a, B, H> { let success = finalization_result.is_ok(); self.protocol.user_protocol_mut().finality_proof_import_result(request_block, finalization_result); if !success { - info!("Invalid finality proof provided by {} for #{}", who, request_block.0); + info!("💔 Invalid finality proof provided by {} for #{}", who, request_block.0); self.protocol.user_protocol_mut().disconnect_peer(&who); self.protocol.user_protocol_mut().report_peer(who, ReputationChange::new_fatal("Invalid finality proof")); } diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 4363e204c0..10a1cd9749 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -827,7 +827,7 @@ ServiceBuilder< let chain_spec = config.expect_chain_spec(); let version = config.full_version(); - info!("Highest known block at #{}", chain_info.best_number); + info!("📦 Highest known block at #{}", chain_info.best_number); telemetry!( SUBSTRATE_INFO; "node.start"; diff --git a/client/service/src/chain_ops.rs b/client/service/src/chain_ops.rs index c58a2755dd..12fae32241 100644 --- a/client/service/src/chain_ops.rs +++ b/client/service/src/chain_ops.rs @@ -125,7 +125,7 @@ impl< return std::task::Poll::Ready(Err(From::from(err))); }, }; - info!("Importing {} blocks", c); + info!("📦 Importing {} blocks", c); count = Some(c); c } @@ -185,7 +185,7 @@ impl< } if link.imported_blocks >= count { - info!("Imported {} blocks. Best: #{}", read_block_count, client.chain_info().best_number); + info!("🎉 Imported {} blocks. Best: #{}", read_block_count, client.chain_info().best_number); return std::task::Poll::Ready(Ok(())); } else { diff --git a/client/src/client.rs b/client/src/client.rs index 5c7fa80291..7ec941ee7a 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -260,7 +260,7 @@ impl Client where backend.begin_state_operation(&mut op, BlockId::Hash(Default::default()))?; let state_root = op.reset_storage(genesis_storage)?; let genesis_block = genesis::construct_genesis_block::(state_root.into()); - info!("Initializing Genesis block/state (state: {}, header-hash: {})", + info!("🔨 Initializing Genesis block/state (state: {}, header-hash: {})", genesis_block.header().state_root(), genesis_block.header().hash() ); -- GitLab From 871e128a8ea131421577aeb83bb2278c77597877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 27 Mar 2020 11:21:14 +0100 Subject: [PATCH 091/300] Make all `PerThing` types implement all trait methods on the type (#5422) This removes the requirement to import `PerThing` to use a type that implements the trait. --- frame/babe/src/lib.rs | 2 +- frame/grandpa/src/lib.rs | 2 +- frame/im-online/src/lib.rs | 2 +- frame/staking/src/inflation.rs | 2 +- frame/staking/src/slashing.rs | 2 +- .../fuzzer/src/per_thing_rational.rs | 3 +- primitives/arithmetic/src/per_things.rs | 55 ++++++++++++++++--- primitives/runtime/src/curve.rs | 2 +- 8 files changed, 53 insertions(+), 17 deletions(-) diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 7315d17618..32d5d3c7a5 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -28,7 +28,7 @@ use frame_support::{ weights::{Weight, SimpleDispatchInfo, WeighData}, }; use sp_timestamp::OnTimestampSet; -use sp_runtime::{generic::DigestItem, ConsensusEngineId, Perbill, PerThing}; +use sp_runtime::{generic::DigestItem, ConsensusEngineId, Perbill}; use sp_runtime::traits::{IsMember, SaturatedConversion, Saturating, Hash, One}; use sp_staking::{ SessionIndex, diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index 9635bba2d1..030699b525 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -34,7 +34,7 @@ use sp_std::prelude::*; use codec::{self as codec, Encode, Decode}; use frame_support::{decl_event, decl_storage, decl_module, decl_error, storage}; use sp_runtime::{ - DispatchResult, generic::{DigestItem, OpaqueDigestItemId}, traits::Zero, Perbill, PerThing, + DispatchResult, generic::{DigestItem, OpaqueDigestItemId}, traits::Zero, Perbill, }; use sp_staking::{ SessionIndex, diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 59f2c681b3..cbce3095b6 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -81,7 +81,7 @@ use pallet_session::historical::IdentificationTuple; use sp_runtime::{ offchain::storage::StorageValueRef, RuntimeDebug, - traits::{Convert, Member, Saturating, AtLeast32Bit}, Perbill, PerThing, + traits::{Convert, Member, Saturating, AtLeast32Bit}, Perbill, transaction_validity::{ TransactionValidity, ValidTransaction, InvalidTransaction, TransactionSource, TransactionPriority, diff --git a/frame/staking/src/inflation.rs b/frame/staking/src/inflation.rs index e75ac3af2b..d20741d9bc 100644 --- a/frame/staking/src/inflation.rs +++ b/frame/staking/src/inflation.rs @@ -19,7 +19,7 @@ //! The staking rate in NPoS is the total amount of tokens staked by nominators and validators, //! divided by the total token supply. -use sp_runtime::{Perbill, PerThing, traits::AtLeast32Bit, curve::PiecewiseLinear}; +use sp_runtime::{Perbill, traits::AtLeast32Bit, curve::PiecewiseLinear}; /// The total payout to all validators (and their nominators) per era. /// diff --git a/frame/staking/src/slashing.rs b/frame/staking/src/slashing.rs index 3d5ea3bad5..26f0828989 100644 --- a/frame/staking/src/slashing.rs +++ b/frame/staking/src/slashing.rs @@ -52,7 +52,7 @@ use super::{ EraIndex, Trait, Module, Store, BalanceOf, Exposure, Perbill, SessionInterface, NegativeImbalanceOf, UnappliedSlash, }; -use sp_runtime::{traits::{Zero, Saturating}, PerThing, RuntimeDebug}; +use sp_runtime::{traits::{Zero, Saturating}, RuntimeDebug}; use frame_support::{ StorageMap, StorageDoubleMap, traits::{Currency, OnUnbalanced, Imbalance}, diff --git a/primitives/arithmetic/fuzzer/src/per_thing_rational.rs b/primitives/arithmetic/fuzzer/src/per_thing_rational.rs index 84207cbd16..c2dda3de22 100644 --- a/primitives/arithmetic/fuzzer/src/per_thing_rational.rs +++ b/primitives/arithmetic/fuzzer/src/per_thing_rational.rs @@ -24,8 +24,7 @@ use honggfuzz::fuzz; use sp_arithmetic::{ - PerThing, PerU16, Percent, Perbill, Perquintill, assert_eq_error_rate, - traits::SaturatedConversion, + PerThing, PerU16, Percent, Perbill, Perquintill, traits::SaturatedConversion, }; fn main() { diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index ca6967456b..86b0fa59a6 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -19,9 +19,7 @@ use serde::{Serialize, Deserialize}; use sp_std::{ops, fmt, prelude::*, convert::TryInto}; use codec::{Encode, Decode, CompactAs}; -use crate::{ - traits::{SaturatedConversion, UniqueSaturatedInto, Saturating, BaseArithmetic, Bounded}, -}; +use crate::traits::{SaturatedConversion, UniqueSaturatedInto, Saturating, BaseArithmetic, Bounded}; use sp_debug_derive::RuntimeDebug; /// Something that implements a fixed point ration with an arbitrary granularity `X`, as _parts per @@ -103,8 +101,8 @@ pub trait PerThing: /// # } /// ``` fn mul_collapse(self, b: N) -> N - where N: Clone + From + UniqueSaturatedInto + ops::Rem - + ops::Div + ops::Mul + ops::Add; + where N: Clone + From + UniqueSaturatedInto + ops::Rem + + ops::Div + ops::Mul + ops::Add; } macro_rules! implement_per_thing { @@ -259,13 +257,52 @@ macro_rules! implement_per_thing { Self([x, 100][(x > 100) as usize] * ($max / 100)) } - /// Everything. - /// - /// To avoid having to import `PerThing` when one needs to be used in test mocks. - #[cfg(feature = "std")] + /// See [`PerThing::one`]. pub fn one() -> Self { ::one() } + + /// See [`PerThing::zero`]. + pub fn zero() -> Self { + ::zero() + } + + /// See [`PerThing::is_zero`]. + pub fn is_zero(&self) -> bool { + PerThing::is_zero(self) + } + + /// See [`PerThing::deconstruct`]. + pub fn deconstruct(self) -> $type { + PerThing::deconstruct(self) + } + + /// See [`PerThing::square`]. + pub fn square(self) -> Self { + PerThing::square(self) + } + + /// See [`PerThing::from_fraction`]. + #[cfg(feature = "std")] + pub fn from_fraction(x: f64) -> Self { + ::from_fraction(x) + } + + /// See [`PerThing::from_rational_approximation`]. + pub fn from_rational_approximation(p: N, q: N) -> Self + where N: Clone + Ord + From<$type> + TryInto<$type> + + TryInto<$upper_type> + ops::Div + ops::Rem + + ops::Add { + ::from_rational_approximation(p, q) + } + + /// See [`PerThing::mul_collapse`]. + pub fn mul_collapse(self, b: N) -> N + where N: Clone + From<$type> + UniqueSaturatedInto<$type> + + ops::Rem + ops::Div + ops::Mul + + ops::Add { + PerThing::mul_collapse(self, b) + } } impl Saturating for $name { diff --git a/primitives/runtime/src/curve.rs b/primitives/runtime/src/curve.rs index e04ce77fb2..b00cbed652 100644 --- a/primitives/runtime/src/curve.rs +++ b/primitives/runtime/src/curve.rs @@ -16,7 +16,7 @@ //! Provides some utilities to define a piecewise linear function. -use crate::{Perbill, PerThing, traits::{AtLeast32Bit, SaturatedConversion}}; +use crate::{Perbill, traits::{AtLeast32Bit, SaturatedConversion}}; use core::ops::Sub; /// Piecewise Linear function in [0, 1] -> [0, 1]. -- GitLab From d15e96bddf97191d7c98b2e51811992e013dde2c Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 27 Mar 2020 11:21:34 +0100 Subject: [PATCH 092/300] Update CONTRIBUTING.adoc (#5425) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update CONTRIBUTING.adoc * Update docs/CONTRIBUTING.adoc Co-Authored-By: Bastian Köcher * Update docs/CONTRIBUTING.adoc Co-Authored-By: Bastian Köcher Co-authored-by: Bastian Köcher --- docs/CONTRIBUTING.adoc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/docs/CONTRIBUTING.adoc b/docs/CONTRIBUTING.adoc index cdd9809fff..5a1a4466b0 100644 --- a/docs/CONTRIBUTING.adoc +++ b/docs/CONTRIBUTING.adoc @@ -25,9 +25,10 @@ Merging pull requests once CI is successful: - it does not alter any logic (e.g. comments, dependencies, docs), then it may be tagged https://github.com/paritytech/substrate/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+label%3AA2-insubstantial[`insubstantial`] and merged by its author once CI is complete. - it is an urgent fix with no large change to logic, then it may be merged after a non-author contributor has approved the review once CI is complete. -. Once a PR is ready for review please add the https://github.com/paritytech/substrate/pulls?q=is%3Apr+is%3Aopen+label%3AA0-pleasereview[`pleasereview`] label. Generally PRs should sit with this label for 48 hours in order to garner feedback. It may be merged before if all relevant parties had a look at it. -. If the first review is not an approval, swap `A0-pleasereview` to any label `[A3, A7]` to indicate that the PR has received some feedback, but needs further work. For example. https://github.com/paritytech/substrate/labels/A3-inprogress[`A3-inprogress`] is a general indicator that the PR is work in progress and https://github.com/paritytech/substrate/labels/A4-gotissues[`A4-gotissues`] means that it has significant problems that need fixing. Once the work is done, change the label back to `A0-pleasereview`. You might end up swapping a few times back and forth to climb up the A label group. Once a PR is https://github.com/paritytech/substrate/labels/A8-looksgood[`A8-looksgood`], it is ready to merge. -. PRs that break the external API must be tagged with https://github.com/paritytech/substrate/labels/B2-breaksapi[`breaksapi`], when it changes the FRAME or consensus of running system with https://github.com/paritytech/substrate/labels/B3-breaksconsensus[`breaksconsensus`] +. Once a PR is ready for review please add the https://github.com/paritytech/substrate/pulls?q=is%3Apr+is%3Aopen+label%3AA0-pleasereview[`A0-pleasereview`] label. Generally PRs should sit with this label for 48 hours in order to garner feedback. It may be merged before if all relevant parties had a look at it. +. If the first review is not an approval, swap `A0-pleasereview` to any label `[A3, A7]` to indicate that the PR has received some feedback, but needs further work. For example. https://github.com/paritytech/substrate/labels/A3-inprogress[`A3-inprogress`] is a general indicator that the PR is work in progress and https://github.com/paritytech/substrate/labels/A4-gotissues[`A4-gotissues`] means that it has significant problems that need fixing. Once the work is done, change the label back to `A0-pleasereview`. You might end up swapping a few times back and forth to climb up the A label group. Once a PR is https://github.com/paritytech/substrate/labels/A8-mergeoncegreen[`A8-mergeoncegreen`], it is ready to merge. +. PRs must be tagged with respect to _release notes_ with https://github.com/paritytech/substrate/labels/B0-silent[`B0-silent`] and `B1-..`. The former indicates that no changes should be mentioned in any release notes. The latter indicates that the changes should be reported in the corresponding release note +. PRs that break the external API must be tagged with https://github.com/paritytech/substrate/labels/B2-breaksapi[`B2-breaksapi`], when it changes the FRAME or consensus of running system with https://github.com/paritytech/substrate/labels/B3-breaksconsensus[`B3-breaksconsensus`] . No PR should be merged until all reviews' comments are addressed. *Reviewing pull requests*: @@ -48,16 +49,19 @@ When reviewing a pull request, the end-goal is to suggest useful changes to the === Updating Polkadot as well -If your PR changes the external APIs or interfaces used by Polkadot, **a corresponding PR on Polkadot must** be submitted as well. If you tagged the PR with `breaksapi` or `breaksconsensus` this is most certainly the case, in all other cases check for it by running step 1. +**All pull requests will be checked agains either Polkadot master, or your provided Polkadot companion PR**. That is, If your PR changes the external APIs or interfaces used by Polkadot. If you tagged the PR with `breaksapi` or `breaksconsensus` this is most certainly the case, in all other cases check for it by running step 1 below. -To update a corresponding Polkadot PR: +To create a Polkadot companion PR: -0. Pull latest Polkadot master (or clone it, if you haven't yet). -1. Replace `polkadot-master` in all `Cargo.toml` with the name of the PR-branch - e.g. by running `find . -name "Cargo.toml" -exec sed -i "s/polkadot-master/PR_BRANCH/g" {}` (and to your repo, if the branch is not on mainline); Commit this change. -2. Make the changes required to pass the build again. -3. Submit all this as a PR against the Polkadot Repo, link that new PR in the existing substrate PR for reference -4. Wait for reviews on both -5. Once both PRs have been green lit, merge the Substrate PR into master and sync the changes onto the `polkadot-master` on mainline (push it). Now revert that first commit in your Polkadot PR, reverting the name back to `polkadot-master`, push and wait for the CI to confirm all is fine. Then merge the Polkadot PR. +. Pull latest Polkadot master (or clone it, if you haven't yet). +. Override your local cargo config to point to your local substrate (pointing to your WIP branch): place `paths = ["path/to/substrate"]` in `~/.cargo/config`. +. Make the changes required and build polkadot locally. +. Submit all this as a PR against the Polkadot Repo. Link to your Polkadot PR in the _description_ of your Substrate PR as "polkadot companion: [URL]". +. Now you should see that the `check_polkadot` CI job will build your Substrate PR agains the mentioned Polkadot branch in your PR description. +. Wait for reviews on both +. Once both PRs have been green lit, they can both be merged 🍻. + +If your PR is reviewed well, but a Polkadot PR is missing, signal it with https://github.com/paritytech/substrate/labels/A7-needspolkadotpr[`A7-needspolkadotpr`] to prevent it from getting automatically merged. As there might be multiple pending PRs that might conflict with one another, a) you should not merge the substrate PR until the Polkadot PR has also been reviewed and b) both should be merged pretty quickly after another to not block others. -- GitLab From 7c632679a95e895cc7871554e041c61f1b622353 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 27 Mar 2020 12:02:37 +0100 Subject: [PATCH 093/300] Clarify when `changes_root` returns `None` (#5428) --- primitives/io/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index a6dcfd1b76..7800658974 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -286,7 +286,8 @@ pub trait Storage { /// /// The hashing algorithm is defined by the `Block`. /// - /// Returns an `Option` that holds the SCALE encoded hash. + /// Returns an `Some(_)` which holds the SCALE encoded hash or `None` when + /// changes trie is disabled. fn changes_root(&mut self, parent_hash: &[u8]) -> Option> { self.storage_changes_root(parent_hash) .expect("Invalid `parent_hash` given to `changes_root`.") -- GitLab From 3f3fb5b81fadc9522a54fdc502ce04cd3d46acc6 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Fri, 27 Mar 2020 04:35:48 -0700 Subject: [PATCH 094/300] update futures dependency (#5426) --- bin/node-template/node/Cargo.toml | 2 +- bin/node/cli/Cargo.toml | 2 +- client/authority-discovery/Cargo.toml | 2 +- client/basic-authorship/Cargo.toml | 2 +- client/cli/Cargo.toml | 2 +- client/consensus/aura/Cargo.toml | 2 +- client/consensus/babe/Cargo.toml | 2 +- client/consensus/babe/rpc/Cargo.toml | 2 +- client/consensus/manual-seal/Cargo.toml | 2 +- client/consensus/slots/Cargo.toml | 2 +- client/finality-grandpa/Cargo.toml | 2 +- client/informant/Cargo.toml | 2 +- client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 2 +- client/network/test/Cargo.toml | 2 +- client/offchain/Cargo.toml | 2 +- client/peerset/Cargo.toml | 2 +- client/service/Cargo.toml | 2 +- client/telemetry/Cargo.toml | 2 +- client/transaction-pool/graph/Cargo.toml | 2 +- test-utils/client/Cargo.toml | 2 +- test-utils/runtime/client/Cargo.toml | 2 +- utils/frame/rpc/system/Cargo.toml | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/bin/node-template/node/Cargo.toml b/bin/node-template/node/Cargo.toml index d545943de9..fa2f02d725 100644 --- a/bin/node-template/node/Cargo.toml +++ b/bin/node-template/node/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/paritytech/substrate/" name = "node-template" [dependencies] -futures = "0.3.1" +futures = "0.3.4" log = "0.4.8" structopt = "0.3.8" diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index d45f5d7848..00ab7b08db 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -106,7 +106,7 @@ sc-keystore = { version = "2.0.0-alpha.5", path = "../../../client/keystore" } sc-consensus-babe = { version = "0.8.0-alpha.5", features = ["test-helpers"], path = "../../../client/consensus/babe" } sc-consensus-epochs = { version = "0.8.0-alpha.5", path = "../../../client/consensus/epochs" } sc-service-test = { version = "2.0.0-dev", path = "../../../client/service/test" } -futures = "0.3.1" +futures = "0.3.4" tempfile = "3.1.0" assert_cmd = "0.12" nix = "0.17" diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 5a7f78b95d..a5cb723fc4 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -16,7 +16,7 @@ prost-build = "0.6.1" bytes = "0.5.0" codec = { package = "parity-scale-codec", default-features = false, version = "1.2.0" } derive_more = "0.99.2" -futures = "0.3.1" +futures = "0.3.4" futures-timer = "3.0.1" libp2p = { version = "0.16.2", default-features = false, features = ["secp256k1", "libp2p-websocket"] } log = "0.4.8" diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index 34ce9c948c..495642296e 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -10,7 +10,7 @@ description = "Basic implementation of block-authoring logic." [dependencies] log = "0.4.8" -futures = "0.3.1" +futures = "0.3.4" codec = { package = "parity-scale-codec", version = "1.2.0" } sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index cc1b90dd2f..d623d670ad 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -20,7 +20,7 @@ ansi_term = "0.12.1" lazy_static = "1.4.0" app_dirs = "1.2.1" tokio = { version = "0.2.9", features = [ "signal", "rt-core", "rt-threaded" ] } -futures = "0.3.1" +futures = "0.3.4" fdlimit = "0.1.4" serde_json = "1.0.41" sc-informant = { version = "0.8.0-alpha.5", path = "../informant" } diff --git a/client/consensus/aura/Cargo.toml b/client/consensus/aura/Cargo.toml index ced8617375..4f120abc96 100644 --- a/client/consensus/aura/Cargo.toml +++ b/client/consensus/aura/Cargo.toml @@ -18,7 +18,7 @@ sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } codec = { package = "parity-scale-codec", version = "1.2.0" } sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } derive_more = "0.99.2" -futures = "0.3.1" +futures = "0.3.4" futures-timer = "3.0.1" sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } sc-keystore = { version = "2.0.0-alpha.5", path = "../../keystore" } diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index a0d73180ed..1a725868fb 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -36,7 +36,7 @@ sc-consensus-uncles = { version = "0.8.0-alpha.5", path = "../uncles" } sc-consensus-slots = { version = "0.8.0-alpha.5", path = "../slots" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } fork-tree = { version = "2.0.0-alpha.5", path = "../../../utils/fork-tree" } -futures = "0.3.1" +futures = "0.3.4" futures-timer = "3.0.1" parking_lot = "0.10.0" log = "0.4.8" diff --git a/client/consensus/babe/rpc/Cargo.toml b/client/consensus/babe/rpc/Cargo.toml index 1f820cd66b..193f7d73fa 100644 --- a/client/consensus/babe/rpc/Cargo.toml +++ b/client/consensus/babe/rpc/Cargo.toml @@ -18,7 +18,7 @@ serde = { version = "1.0.104", features=["derive"] } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../../primitives/blockchain" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../../../primitives/runtime" } sc-consensus-epochs = { version = "0.8.0-alpha.5", path = "../../epochs" } -futures = "0.3.1" +futures = "0.3.4" derive_more = "0.99.2" sp-api = { version = "2.0.0-alpha.5", path = "../../../../primitives/api" } sp-consensus = { version = "0.8.0-alpha.5", path = "../../../../primitives/consensus/common" } diff --git a/client/consensus/manual-seal/Cargo.toml b/client/consensus/manual-seal/Cargo.toml index edb98ab21a..3bb8016868 100644 --- a/client/consensus/manual-seal/Cargo.toml +++ b/client/consensus/manual-seal/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] derive_more = "0.99.2" -futures = "0.3.1" +futures = "0.3.4" jsonrpc-core = "14.0.5" jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.5" diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index fd05cf7ca4..79d5a6c51f 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -20,7 +20,7 @@ sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } sc-telemetry = { version = "2.0.0-alpha.5", path = "../../telemetry" } sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } -futures = "0.3.1" +futures = "0.3.4" futures-timer = "3.0.1" parking_lot = "0.10.0" log = "0.4.8" diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index a202f9d205..c18b9bf45e 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.rs/sc-finality-grandpa" [dependencies] fork-tree = { version = "2.0.0-alpha.5", path = "../../utils/fork-tree" } -futures = "0.3.1" +futures = "0.3.4" futures-timer = "3.0.1" log = "0.4.8" parking_lot = "0.10.0" diff --git a/client/informant/Cargo.toml b/client/informant/Cargo.toml index 9f3a93fbae..0675a48ac6 100644 --- a/client/informant/Cargo.toml +++ b/client/informant/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] ansi_term = "0.12.1" -futures = "0.3.1" +futures = "0.3.4" log = "0.4.8" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } wasm-timer = "0.2" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index c0418125a4..e68f0f3f40 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -11,7 +11,7 @@ documentation = "https://docs.rs/sc-network-gossip" [dependencies] -futures = "0.3.1" +futures = "0.3.4" futures-timer = "3.0.1" libp2p = { version = "0.16.2", default-features = false, features = ["libp2p-websocket"] } log = "0.4.8" diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index bb326cbefa..b96cae8629 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -22,7 +22,7 @@ either = "1.5.3" erased-serde = "0.3.9" fnv = "1.0.6" fork-tree = { version = "2.0.0-alpha.5", path = "../../utils/fork-tree" } -futures = "0.3.1" +futures = "0.3.4" futures_codec = "0.3.3" futures-timer = "3.0.1" wasm-timer = "0.2" diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index e3d7852dd4..0a3fb1e3ea 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/paritytech/substrate/" sc-network = { version = "0.8.0-alpha.5", path = "../" } log = "0.4.8" parking_lot = "0.10.0" -futures = "0.3.1" +futures = "0.3.4" futures-timer = "3.0.1" rand = "0.7.2" libp2p = { version = "0.16.2", default-features = false, features = ["libp2p-websocket"] } diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index 9dac18e946..473425bc21 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -13,7 +13,7 @@ bytes = "0.5" sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } fnv = "1.0.6" -futures = "0.3.1" +futures = "0.3.4" futures-timer = "3.0.1" log = "0.4.8" threadpool = "1.7" diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index ea3a6b6974..5d4aa28bf2 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -11,7 +11,7 @@ documentation = "https://docs.rs/sc-peerset" [dependencies] -futures = "0.3.1" +futures = "0.3.4" libp2p = { version = "0.16.2", default-features = false } log = "0.4.8" serde_json = "1.0.41" diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index eb9e3dc2a6..b3fb0953eb 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -20,7 +20,7 @@ wasmtime = [ [dependencies] derive_more = "0.99.2" futures01 = { package = "futures", version = "0.1.29" } -futures = "0.3.1" +futures = "0.3.4" futures-diagnose = "1.0" parking_lot = "0.10.0" lazy_static = "1.4.0" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index 543abd6a8b..ee7e710c85 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/sc-telemetry" [dependencies] bytes = "0.5" parking_lot = "0.10.0" -futures = "0.3.1" +futures = "0.3.4" futures-timer = "3.0.1" wasm-timer = "0.2.0" libp2p = { version = "0.16.2", default-features = false, features = ["libp2p-websocket"] } diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index 08593e6784..65ff1becec 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -10,7 +10,7 @@ description = "Generic Transaction Pool" [dependencies] derive_more = "0.99.2" -futures = "0.3.1" +futures = "0.3.4" log = "0.4.8" parking_lot = "0.10.0" serde = { version = "1.0.101", features = ["derive"] } diff --git a/test-utils/client/Cargo.toml b/test-utils/client/Cargo.toml index 66fd728696..1078c43b31 100644 --- a/test-utils/client/Cargo.toml +++ b/test-utils/client/Cargo.toml @@ -14,7 +14,7 @@ sc-client = { version = "0.8.0-alpha.5", path = "../../client/" } sc-client-db = { version = "0.8.0-alpha.5", features = ["test-helpers"], path = "../../client/db" } sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } sc-executor = { version = "0.8.0-alpha.5", path = "../../client/executor" } -futures = "0.3.1" +futures = "0.3.4" hash-db = "0.15.2" sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } codec = { package = "parity-scale-codec", version = "1.2.0" } diff --git a/test-utils/runtime/client/Cargo.toml b/test-utils/runtime/client/Cargo.toml index 3af6c4967e..4de5e28ff7 100644 --- a/test-utils/runtime/client/Cargo.toml +++ b/test-utils/runtime/client/Cargo.toml @@ -19,4 +19,4 @@ sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockch codec = { package = "parity-scale-codec", version = "1.2.0" } sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } -futures = "0.3.1" +futures = "0.3.4" diff --git a/utils/frame/rpc/system/Cargo.toml b/utils/frame/rpc/system/Cargo.toml index a4f6833fad..780fcd3344 100644 --- a/utils/frame/rpc/system/Cargo.toml +++ b/utils/frame/rpc/system/Cargo.toml @@ -11,7 +11,7 @@ description = "FRAME's system exposed over Substrate RPC" [dependencies] sc-client = { version = "0.8.0-alpha.5", path = "../../../../client/" } codec = { package = "parity-scale-codec", version = "1.2.0" } -futures = "0.3.1" +futures = "0.3.4" jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" -- GitLab From 1479cfc847f630a19e793b3526ec1ee275eb9227 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Fri, 27 Mar 2020 12:38:14 +0100 Subject: [PATCH 095/300] fix tests (#5416) --- frame/staking/src/mock.rs | 12 +++++++++++- frame/staking/src/tests.rs | 3 --- frame/timestamp/src/lib.rs | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 0045e96b3e..d8d9a55032 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -40,6 +40,8 @@ use crate::{ CompactAssignments, ValidatorIndex, NominatorIndex, Validators, OffchainAccuracy, }; +const INIT_TIMESTAMP: u64 = 30_000; + /// The AccountId alias in this test module. pub(crate) type AccountId = u64; pub(crate) type AccountIndex = u64; @@ -482,6 +484,14 @@ impl ExtBuilder { let validators = Session::validators(); SESSION.with(|x| *x.borrow_mut() = (validators.clone(), HashSet::new())); }); + + // We consider all test to start after timestamp is initialized + // This must be ensured by having `timestamp::on_initialize` called before + // `staking::on_initialize` + ext.execute_with(|| { + Timestamp::set_timestamp(INIT_TIMESTAMP); + }); + ext } } @@ -593,7 +603,7 @@ pub fn start_session(session_index: SessionIndex) { for i in Session::current_index()..session_index { Staking::on_finalize(System::block_number()); System::set_block_number((i + 1).into()); - Timestamp::set_timestamp(System::block_number() * 1000); + Timestamp::set_timestamp(System::block_number() * 1000 + INIT_TIMESTAMP); Session::on_initialize(System::block_number()); Staking::on_initialize(System::block_number()); } diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index f54fe05de0..abd3c00ae8 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -254,8 +254,6 @@ fn staking_should_work() { // --- Block 1: start_session(1); - Timestamp::set_timestamp(1); // Initialize time. - // remember + compare this along with the test. assert_eq_uvec!(validator_controllers(), vec![20, 10]); @@ -1039,7 +1037,6 @@ fn bond_extra_and_withdraw_unbonded_works() { assert_ne!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11), Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] }); // trigger next era. - Timestamp::set_timestamp(10); start_era(2); assert_eq!(Staking::active_era().unwrap().index, 2); diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index d64b43ac17..7dccc47096 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -250,7 +250,7 @@ impl UnixTime for Module { // now is duration since unix epoch in millisecond as documented in // `sp_timestamp::InherentDataProvider`. let now = Self::now(); - sp_std::if_std! { + sp_std::if_std! { if now == T::Moment::zero() { debug::error!( "`pallet_timestamp::UnixTime::now` is called at genesis, invalid value returned: 0" -- GitLab From f541b01c65acb2027471a244b50a5ecc6aa5757a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 27 Mar 2020 15:54:48 +0100 Subject: [PATCH 096/300] Enable `wasmtime` only for `x86_64` in substrate node (#5432) * Enable `wasmtime` only for `x86_64` in substrate node When using the new feature of cargo `cargo build -Z features=itarget`, the `wasmtime` feature will not bleed into the build for other architectures. * Use new cargo feature in CI --- .gitlab-ci.yml | 2 +- bin/node/cli/Cargo.toml | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 12baa3978a..5af113f648 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -328,7 +328,7 @@ check-web-wasm: - time cargo build --target=wasm32-unknown-unknown -p sp-consensus - time cargo build --target=wasm32-unknown-unknown -p sc-telemetry # Note: the command below is a bit weird because several Cargo issues prevent us from compiling the node in a more straight-forward way. - - time cargo build --manifest-path=bin/node/cli/Cargo.toml --no-default-features --features "browser" --target=wasm32-unknown-unknown + - time cargo +nightly build --manifest-path=bin/node/cli/Cargo.toml --no-default-features --features "browser" --target=wasm32-unknown-unknown -Z features=itarget - sccache -s test-full-crypto-feature: diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index 00ab7b08db..f6c22149e6 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -101,6 +101,11 @@ wasm-bindgen = { version = "0.2.57", optional = true } wasm-bindgen-futures = { version = "0.4.7", optional = true } browser-utils = { package = "substrate-browser-utils", path = "../../../utils/browser", optional = true, version = "0.8.0-alpha.5"} +[target.'cfg(target_arch="x86_64")'.dependencies] +node-executor = { version = "2.0.0-alpha.4", path = "../executor", features = [ "wasmtime" ] } +sc-cli = { version = "0.8.0-alpha.4", optional = true, path = "../../../client/cli", features = [ "wasmtime" ] } +sc-service = { version = "0.8.0-alpha.4", default-features = false, path = "../../../client/service", features = [ "wasmtime" ] } + [dev-dependencies] sc-keystore = { version = "2.0.0-alpha.5", path = "../../../client/keystore" } sc-consensus-babe = { version = "0.8.0-alpha.5", features = ["test-helpers"], path = "../../../client/consensus/babe" } @@ -130,7 +135,7 @@ version = "3.0.4" optional = true [features] -default = ["cli", "wasmtime"] +default = [ "cli" ] browser = [ "browser-utils", "wasm-bindgen", @@ -146,10 +151,4 @@ cli = [ "structopt", "vergen", ] -wasmtime = [ - "cli", - "node-executor/wasmtime", - "sc-cli/wasmtime", - "sc-service/wasmtime", -] runtime-benchmarks = [ "node-runtime/runtime-benchmarks" ] -- GitLab From 180534b4037a117ab39a8b2be72c51bfdfc1c1f5 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Fri, 27 Mar 2020 21:40:12 +0100 Subject: [PATCH 097/300] Hide metadata function for in decl_event, and add doc for GenesisConfig (#5431) * hide metadata function for non generic event * add doc for decl_storage --- frame/support/procedural/src/storage/genesis_config/mod.rs | 2 ++ frame/support/src/event.rs | 1 + 2 files changed, 3 insertions(+) diff --git a/frame/support/procedural/src/storage/genesis_config/mod.rs b/frame/support/procedural/src/storage/genesis_config/mod.rs index 09afcb9a60..eeeca150d9 100644 --- a/frame/support/procedural/src/storage/genesis_config/mod.rs +++ b/frame/support/procedural/src/storage/genesis_config/mod.rs @@ -66,6 +66,7 @@ fn decl_genesis_config_and_impl_default( let genesis_where_clause = &genesis_config.genesis_where_clause; quote!( + /// Genesis config for the module, allow to build genesis storage. #[derive(#scrate::Serialize, #scrate::Deserialize)] #[cfg(feature = "std")] #[serde(rename_all = "camelCase")] @@ -138,6 +139,7 @@ fn impl_build_storage( quote!{ #[cfg(feature = "std")] impl#genesis_impl GenesisConfig#genesis_struct #genesis_where_clause { + /// Build the storage for this module. pub fn build_storage #fn_generic (&self) -> std::result::Result< #scrate::sp_runtime::Storage, String diff --git a/frame/support/src/event.rs b/frame/support/src/event.rs index 8b7de01159..1184b379f4 100644 --- a/frame/support/src/event.rs +++ b/frame/support/src/event.rs @@ -288,6 +288,7 @@ macro_rules! __decl_generic_event { } impl<$( $generic_param ),* $(, $instance)?> RawEvent<$( $generic_param ),* $(, $instance)?> { #[allow(dead_code)] + #[doc(hidden)] pub fn metadata() -> &'static [$crate::event::EventMetadata] { $crate::__events_to_metadata!(; $( $events )* ) } -- GitLab From 2f3a0f64d5308b6a20483c8a165d8a55f24dae58 Mon Sep 17 00:00:00 2001 From: Spencer Judge Date: Fri, 27 Mar 2020 13:41:29 -0700 Subject: [PATCH 098/300] Provide easy conversions from common key types to `AccountId32` (#5423) * Provide easy conversions from common key types to `AccountId32` * Fix spaces instead of tabs --- primitives/core/src/crypto.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index c073862f29..6301600921 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -18,6 +18,7 @@ //! Cryptographic utilities. // end::description[] +use crate::{sr25519, ed25519}; use sp_std::hash::Hash; use sp_std::vec::Vec; #[cfg(feature = "std")] @@ -615,6 +616,18 @@ impl From for [u8; 32] { } } +impl From for AccountId32 { + fn from(k: sr25519::Public) -> Self { + k.0.into() + } +} + +impl From for AccountId32 { + fn from(k: ed25519::Public) -> Self { + k.0.into() + } +} + #[cfg(feature = "std")] impl std::fmt::Display for AccountId32 { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { -- GitLab From 29c73254af739cf964d0a005d6b07adaca4d954c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sat, 28 Mar 2020 22:16:05 +0100 Subject: [PATCH 099/300] Upgrade `parity-scale-codec` to `1.3.0` (#5443) --- Cargo.lock | 18 ++++++++++++++---- bin/node-template/pallets/template/Cargo.toml | 2 +- bin/node-template/runtime/Cargo.toml | 2 +- bin/node/cli/Cargo.toml | 2 +- bin/node/executor/Cargo.toml | 2 +- bin/node/inspect/Cargo.toml | 2 +- bin/node/runtime/Cargo.toml | 2 +- bin/node/testing/Cargo.toml | 2 +- bin/node/transaction-factory/Cargo.toml | 2 +- bin/utils/subkey/Cargo.toml | 2 +- client/Cargo.toml | 2 +- client/api/Cargo.toml | 2 +- client/authority-discovery/Cargo.toml | 2 +- client/basic-authorship/Cargo.toml | 2 +- client/block-builder/Cargo.toml | 2 +- client/consensus/aura/Cargo.toml | 2 +- client/consensus/babe/Cargo.toml | 2 +- client/consensus/epochs/Cargo.toml | 2 +- client/consensus/pow/Cargo.toml | 2 +- client/consensus/slots/Cargo.toml | 2 +- client/db/Cargo.toml | 2 +- client/executor/Cargo.toml | 2 +- client/executor/common/Cargo.toml | 2 +- client/executor/wasmi/Cargo.toml | 2 +- client/executor/wasmtime/Cargo.toml | 2 +- client/finality-grandpa/Cargo.toml | 2 +- client/network/Cargo.toml | 2 +- client/offchain/Cargo.toml | 2 +- client/rpc-api/Cargo.toml | 2 +- client/rpc/Cargo.toml | 2 +- client/service/Cargo.toml | 2 +- client/state-db/Cargo.toml | 2 +- client/transaction-pool/Cargo.toml | 2 +- client/transaction-pool/graph/Cargo.toml | 2 +- frame/assets/Cargo.toml | 2 +- frame/aura/Cargo.toml | 2 +- frame/authority-discovery/Cargo.toml | 2 +- frame/authorship/Cargo.toml | 2 +- frame/babe/Cargo.toml | 2 +- frame/balances/Cargo.toml | 2 +- frame/benchmarking/Cargo.toml | 2 +- frame/collective/Cargo.toml | 2 +- frame/contracts/Cargo.toml | 2 +- frame/contracts/common/Cargo.toml | 2 +- frame/contracts/rpc/Cargo.toml | 2 +- frame/contracts/rpc/runtime-api/Cargo.toml | 2 +- frame/democracy/Cargo.toml | 2 +- frame/elections-phragmen/Cargo.toml | 2 +- frame/elections/Cargo.toml | 2 +- frame/evm/Cargo.toml | 2 +- frame/example-offchain-worker/Cargo.toml | 2 +- frame/example/Cargo.toml | 2 +- frame/executive/Cargo.toml | 2 +- frame/finality-tracker/Cargo.toml | 2 +- frame/generic-asset/Cargo.toml | 2 +- frame/grandpa/Cargo.toml | 2 +- frame/identity/Cargo.toml | 2 +- frame/im-online/Cargo.toml | 2 +- frame/indices/Cargo.toml | 2 +- frame/membership/Cargo.toml | 2 +- frame/metadata/Cargo.toml | 2 +- frame/nicks/Cargo.toml | 2 +- frame/offences/Cargo.toml | 2 +- frame/randomness-collective-flip/Cargo.toml | 2 +- frame/recovery/Cargo.toml | 2 +- frame/scored-pool/Cargo.toml | 2 +- frame/session/Cargo.toml | 2 +- frame/society/Cargo.toml | 2 +- frame/staking/Cargo.toml | 2 +- frame/staking/fuzz/Cargo.lock | 12 ++++++------ frame/staking/fuzz/Cargo.toml | 2 +- frame/sudo/Cargo.toml | 2 +- frame/support/Cargo.toml | 2 +- frame/support/test/Cargo.toml | 2 +- frame/system/Cargo.toml | 2 +- frame/system/rpc/runtime-api/Cargo.toml | 2 +- frame/timestamp/Cargo.toml | 2 +- frame/transaction-payment/Cargo.toml | 2 +- frame/transaction-payment/rpc/Cargo.toml | 2 +- .../rpc/runtime-api/Cargo.toml | 2 +- frame/treasury/Cargo.toml | 2 +- frame/utility/Cargo.toml | 2 +- frame/vesting/Cargo.toml | 2 +- primitives/api/Cargo.toml | 2 +- primitives/api/test/Cargo.toml | 2 +- primitives/application-crypto/Cargo.toml | 2 +- primitives/arithmetic/Cargo.toml | 2 +- primitives/arithmetic/fuzzer/Cargo.lock | 4 ++-- primitives/authority-discovery/Cargo.toml | 2 +- primitives/authorship/Cargo.toml | 2 +- primitives/block-builder/Cargo.toml | 2 +- primitives/blockchain/Cargo.toml | 2 +- primitives/consensus/aura/Cargo.toml | 2 +- primitives/consensus/babe/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- primitives/consensus/pow/Cargo.toml | 2 +- primitives/core/Cargo.toml | 2 +- primitives/finality-grandpa/Cargo.toml | 2 +- primitives/finality-tracker/Cargo.toml | 2 +- primitives/inherents/Cargo.toml | 2 +- primitives/io/Cargo.toml | 2 +- primitives/phragmen/fuzzer/Cargo.lock | 12 ++++++------ primitives/runtime-interface/Cargo.toml | 2 +- primitives/runtime/Cargo.toml | 2 +- primitives/sandbox/Cargo.toml | 2 +- primitives/staking/Cargo.toml | 2 +- primitives/state-machine/Cargo.toml | 2 +- primitives/test-primitives/Cargo.toml | 2 +- primitives/timestamp/Cargo.toml | 2 +- primitives/transaction-pool/Cargo.toml | 2 +- primitives/trie/Cargo.toml | 2 +- primitives/version/Cargo.toml | 2 +- primitives/wasm-interface/Cargo.toml | 2 +- test-utils/client/Cargo.toml | 2 +- test-utils/runtime/Cargo.toml | 2 +- test-utils/runtime/client/Cargo.toml | 2 +- test-utils/runtime/transaction-pool/Cargo.toml | 2 +- utils/fork-tree/Cargo.toml | 2 +- utils/frame/benchmarking-cli/Cargo.toml | 2 +- utils/frame/rpc/system/Cargo.toml | 2 +- 120 files changed, 144 insertions(+), 134 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 36846702a3..22636830a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -367,9 +367,13 @@ checksum = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" [[package]] name = "bitvec" -version = "0.15.2" +version = "0.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" +checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" +dependencies = [ + "either", + "radium", +] [[package]] name = "blake2" @@ -4721,9 +4725,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f509c5e67ca0605ee17dcd3f91ef41cadd685c75a298fb6261b781a5acb3f910" +checksum = "329c8f7f4244ddb5c37c103641027a76c530e65e8e4b8240b29f81ea40508b17" dependencies = [ "arrayvec 0.5.1", "bitvec", @@ -5199,6 +5203,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + [[package]] name = "rand" version = "0.3.23" diff --git a/bin/node-template/pallets/template/Cargo.toml b/bin/node-template/pallets/template/Cargo.toml index c28636cd61..cda81e5d22 100644 --- a/bin/node-template/pallets/template/Cargo.toml +++ b/bin/node-template/pallets/template/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet template" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } safe-mix = { default-features = false, version = '1.0.0' } [dependencies.frame-support] diff --git a/bin/node-template/runtime/Cargo.toml b/bin/node-template/runtime/Cargo.toml index c5f778e055..dcd8366f14 100644 --- a/bin/node-template/runtime/Cargo.toml +++ b/bin/node-template/runtime/Cargo.toml @@ -8,7 +8,7 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } aura = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-aura", path = "../../../frame/aura" } balances = { version = "2.0.0-alpha.5", default-features = false, package = "pallet-balances", path = "../../../frame/balances" } diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index f6c22149e6..995dfaef7f 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -31,7 +31,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] # third-party dependencies -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } serde = { version = "1.0.102", features = ["derive"] } futures = { version = "0.3.1", features = ["compat"] } hex-literal = "0.2.1" diff --git a/bin/node/executor/Cargo.toml b/bin/node/executor/Cargo.toml index 02c6a141e9..45a43233c0 100644 --- a/bin/node/executor/Cargo.toml +++ b/bin/node/executor/Cargo.toml @@ -9,7 +9,7 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } node-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } sc-executor = { version = "0.8.0-alpha.5", path = "../../../client/executor" } diff --git a/bin/node/inspect/Cargo.toml b/bin/node/inspect/Cargo.toml index 36ba0c7205..78186acfa4 100644 --- a/bin/node/inspect/Cargo.toml +++ b/bin/node/inspect/Cargo.toml @@ -8,7 +8,7 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } derive_more = "0.99" log = "0.4.8" sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 34f2e381c2..6d509966f3 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] # third-party dependencies -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } integer-sqrt = { version = "0.1.2" } serde = { version = "1.0.102", optional = true } diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index d852aaac26..83d521b272 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -14,7 +14,7 @@ pallet-balances = { version = "2.0.0-alpha.5", path = "../../../frame/balances" sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } sc-client-db = { version = "0.8.0-alpha.5", path = "../../../client/db/", features = ["kvdb-rocksdb"] } sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api/" } -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } pallet-contracts = { version = "2.0.0-alpha.5", path = "../../../frame/contracts" } pallet-grandpa = { version = "2.0.0-alpha.5", path = "../../../frame/grandpa" } pallet-indices = { version = "2.0.0-alpha.5", path = "../../../frame/indices" } diff --git a/bin/node/transaction-factory/Cargo.toml b/bin/node/transaction-factory/Cargo.toml index b95b55a536..755dcc5faf 100644 --- a/bin/node/transaction-factory/Cargo.toml +++ b/bin/node/transaction-factory/Cargo.toml @@ -13,7 +13,7 @@ sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } sc-block-builder = { version = "0.8.0-alpha.5", path = "../../../client/block-builder" } sc-client = { version = "0.8.0-alpha.5", path = "../../../client" } -codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } log = "0.4.8" sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index d8d7532a4c..dab03cd2e5 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -19,7 +19,7 @@ tiny-bip39 = "0.7" substrate-bip39 = "0.4.1" hex = "0.4.0" hex-literal = "0.2.1" -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } frame-system = { version = "2.0.0-alpha.5", path = "../../../frame/system" } pallet-balances = { version = "2.0.0-alpha.5", path = "../../../frame/balances" } pallet-transaction-payment = { version = "2.0.0-alpha.5", path = "../../../frame/transaction-payment" } diff --git a/client/Cargo.toml b/client/Cargo.toml index 7a38faad04..1dd7f72f66 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -11,7 +11,7 @@ description = "Substrate Client and associated logic." [dependencies] sc-block-builder = { version = "0.8.0-alpha.5", path = "block-builder" } sc-client-api = { version = "2.0.0-alpha.5", path = "api" } -codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } sp-consensus = { version = "0.8.0-alpha.5", path = "../primitives/consensus/common" } derive_more = { version = "0.99.2" } sc-executor = { version = "0.8.0-alpha.5", path = "executor" } diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index c3afdee413..0d13bc1cb5 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -11,7 +11,7 @@ documentation = "https://docs.rs/sc-client-api" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } derive_more = { version = "0.99.2" } sc-executor = { version = "0.8.0-alpha.5", path = "../executor" } diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index a5cb723fc4..09b4fa8391 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -14,7 +14,7 @@ prost-build = "0.6.1" [dependencies] bytes = "0.5.0" -codec = { package = "parity-scale-codec", default-features = false, version = "1.2.0" } +codec = { package = "parity-scale-codec", default-features = false, version = "1.3.0" } derive_more = "0.99.2" futures = "0.3.4" futures-timer = "3.0.1" diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index 495642296e..97fb8f2c6c 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -11,7 +11,7 @@ description = "Basic implementation of block-authoring logic." [dependencies] log = "0.4.8" futures = "0.3.4" -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } diff --git a/client/block-builder/Cargo.toml b/client/block-builder/Cargo.toml index 351c3e0a77..376d75ef86 100644 --- a/client/block-builder/Cargo.toml +++ b/client/block-builder/Cargo.toml @@ -18,7 +18,7 @@ sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } sp-block-builder = { version = "2.0.0-alpha.5", path = "../../primitives/block-builder" } sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } -codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } [dev-dependencies] substrate-test-runtime-client = { path = "../../test-utils/runtime/client" } diff --git a/client/consensus/aura/Cargo.toml b/client/consensus/aura/Cargo.toml index 4f120abc96..04ed44026f 100644 --- a/client/consensus/aura/Cargo.toml +++ b/client/consensus/aura/Cargo.toml @@ -15,7 +15,7 @@ sp-block-builder = { version = "2.0.0-alpha.5", path = "../../../primitives/bloc sc-block-builder = { version = "0.8.0-alpha.5", path = "../../../client/block-builder" } sc-client = { version = "0.8.0-alpha.5", path = "../../" } sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } derive_more = "0.99.2" futures = "0.3.4" diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index 1a725868fb..e2c7c6efc7 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sc-consensus-babe" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/babe" } sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../../primitives/application-crypto" } diff --git a/client/consensus/epochs/Cargo.toml b/client/consensus/epochs/Cargo.toml index acc13bd575..ff9153299c 100644 --- a/client/consensus/epochs/Cargo.toml +++ b/client/consensus/epochs/Cargo.toml @@ -9,7 +9,7 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } parking_lot = "0.10.0" fork-tree = { version = "2.0.0-alpha.5", path = "../../../utils/fork-tree" } sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.5"} diff --git a/client/consensus/pow/Cargo.toml b/client/consensus/pow/Cargo.toml index a168c0b380..f8ea106d9c 100644 --- a/client/consensus/pow/Cargo.toml +++ b/client/consensus/pow/Cargo.toml @@ -9,7 +9,7 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index 79d5a6c51f..4e388cdec0 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } sc-client-api = { version = "2.0.0-alpha.5", path = "../../api" } sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index b2ece9b7ff..6d3389b5f9 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -18,7 +18,7 @@ kvdb-memorydb = "0.5.0" linked-hash-map = "0.5.2" hash-db = "0.15.2" parity-util-mem = { version = "0.6.0", default-features = false, features = ["std"] } -codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index 4dca9fa6d5..e6a43dd685 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -11,7 +11,7 @@ documentation = "https://docs.rs/sc-executor" [dependencies] derive_more = "0.99.2" -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } sp-trie = { version = "2.0.0-alpha.5", path = "../../primitives/trie" } diff --git a/client/executor/common/Cargo.toml b/client/executor/common/Cargo.toml index 14a1f8333b..ae89524a49 100644 --- a/client/executor/common/Cargo.toml +++ b/client/executor/common/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.rs/sc-executor-common/" [dependencies] log = "0.4.8" derive_more = "0.99.2" -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } wasmi = "0.6.2" sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } sp-allocator = { version = "2.0.0-alpha.5", path = "../../../primitives/allocator" } diff --git a/client/executor/wasmi/Cargo.toml b/client/executor/wasmi/Cargo.toml index bae36353a2..600090e90e 100644 --- a/client/executor/wasmi/Cargo.toml +++ b/client/executor/wasmi/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/sc-executor-wasmi" log = "0.4.8" wasmi = "0.6.2" parity-wasm = "0.41.0" -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } sc-executor-common = { version = "0.8.0-alpha.5", path = "../common" } sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/wasm-interface" } sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime-interface" } diff --git a/client/executor/wasmtime/Cargo.toml b/client/executor/wasmtime/Cargo.toml index 3b30e63fbb..6ca17408ef 100644 --- a/client/executor/wasmtime/Cargo.toml +++ b/client/executor/wasmtime/Cargo.toml @@ -12,7 +12,7 @@ description = "Defines a `WasmRuntime` that uses the Wasmtime JIT to execute." log = "0.4.8" scoped-tls = "1.0" parity-wasm = "0.41.0" -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } sc-executor-common = { version = "0.8.0-alpha.5", path = "../common" } sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/wasm-interface" } sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime-interface" } diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index c18b9bf45e..f6be06ba74 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -18,7 +18,7 @@ log = "0.4.8" parking_lot = "0.10.0" rand = "0.7.2" assert_matches = "1.3.0" -parity-scale-codec = { version = "1.2.0", features = ["derive"] } +parity-scale-codec = { version = "1.3.0", features = ["derive"] } sp-arithmetic = { version = "2.0.0-alpha.5", path = "../../primitives/arithmetic" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index b96cae8629..1d43b72e37 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -16,7 +16,7 @@ prost-build = "0.6.1" [dependencies] bitflags = "1.2.0" bytes = "0.5.0" -codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } derive_more = "0.99.2" either = "1.5.3" erased-serde = "0.3.9" diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index 473425bc21..9e5d69a171 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -19,7 +19,7 @@ log = "0.4.8" threadpool = "1.7" num_cpus = "1.10" sp-offchain = { version = "2.0.0-alpha.5", path = "../../primitives/offchain" } -codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } parking_lot = "0.10.0" sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } rand = "0.7.2" diff --git a/client/rpc-api/Cargo.toml b/client/rpc-api/Cargo.toml index 7d41c4f61c..918b54234e 100644 --- a/client/rpc-api/Cargo.toml +++ b/client/rpc-api/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate RPC interfaces." [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } derive_more = "0.99.2" futures = { version = "0.3.1", features = ["compat"] } jsonrpc-core = "14.0.3" diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index cd4dd166f5..d4003d1861 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -13,7 +13,7 @@ sc-rpc-api = { version = "0.8.0-alpha.5", path = "../rpc-api" } sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } sc-client = { version = "0.8.0-alpha.5", path = "../" } sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } futures = { version = "0.3.1", features = ["compat"] } jsonrpc-pubsub = "14.0.3" log = "0.4.8" diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index b3fb0953eb..2a7869efe5 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -47,7 +47,7 @@ sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } sc-client = { version = "0.8.0-alpha.5", path = "../" } sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } sc-client-db = { version = "0.8.0-alpha.5", path = "../db" } -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } sc-executor = { version = "0.8.0-alpha.5", path = "../executor" } sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../transaction-pool" } sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index c056ee9fac..c4b21bd407 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -13,7 +13,7 @@ parking_lot = "0.10.0" log = "0.4.8" sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } -codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } parity-util-mem = "0.6" parity-util-mem-derive = "0.1.0" diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index f5b6539a29..e01409ecb0 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate transaction pool implementation." [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } derive_more = "0.99.2" futures = { version = "0.3.1", features = ["compat"] } futures-diagnose = "1.0" diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index 65ff1becec..6de5e68c55 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -24,7 +24,7 @@ linked-hash-map = "0.5.2" [dev-dependencies] assert_matches = "1.3.0" -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../../test-utils/runtime" } criterion = "0.3" diff --git a/frame/assets/Cargo.toml b/frame/assets/Cargo.toml index 8b6dac4e09..893e595e71 100644 --- a/frame/assets/Cargo.toml +++ b/frame/assets/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME asset management pallet" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } # Needed for various traits. In our case, `OnFinalize`. sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } # Needed for type-safe access to storage DB. diff --git a/frame/aura/Cargo.toml b/frame/aura/Cargo.toml index eb9c4556f5..9ea72b23b3 100644 --- a/frame/aura/Cargo.toml +++ b/frame/aura/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME AURA consensus pallet" [dependencies] sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/application-crypto" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } diff --git a/frame/authority-discovery/Cargo.toml b/frame/authority-discovery/Cargo.toml index 64c6c22eeb..b6032e93d4 100644 --- a/frame/authority-discovery/Cargo.toml +++ b/frame/authority-discovery/Cargo.toml @@ -11,7 +11,7 @@ description = "FRAME pallet for authority discovery" [dependencies] sp-authority-discovery = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/authority-discovery" } sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/application-crypto" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } diff --git a/frame/authorship/Cargo.toml b/frame/authorship/Cargo.toml index 105ae68d59..05b85ded59 100644 --- a/frame/authorship/Cargo.toml +++ b/frame/authorship/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } sp-authorship = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/authorship" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } diff --git a/frame/babe/Cargo.toml b/frame/babe/Cargo.toml index 8790b3775c..5b7096b342 100644 --- a/frame/babe/Cargo.toml +++ b/frame/babe/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "Consensus extension module for BABE consensus. Collects on-chain randomness from VRF outputs and manages epoch transitions." [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } diff --git a/frame/balances/Cargo.toml b/frame/balances/Cargo.toml index 1151fffe67..73409560b1 100644 --- a/frame/balances/Cargo.toml +++ b/frame/balances/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME pallet to manage balances" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } diff --git a/frame/benchmarking/Cargo.toml b/frame/benchmarking/Cargo.toml index dcdb4f65fa..481ea3235d 100644 --- a/frame/benchmarking/Cargo.toml +++ b/frame/benchmarking/Cargo.toml @@ -10,7 +10,7 @@ description = "Macro for benchmarking a FRAME runtime." [dependencies] linregress = "0.1" -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api", default-features = false } sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../primitives/runtime-interface", default-features = false } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime", default-features = false } diff --git a/frame/collective/Cargo.toml b/frame/collective/Cargo.toml index 018340341f..f682208380 100644 --- a/frame/collective/Cargo.toml +++ b/frame/collective/Cargo.toml @@ -10,7 +10,7 @@ description = "Collective system: Members of a set of account IDs can make their [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } diff --git a/frame/contracts/Cargo.toml b/frame/contracts/Cargo.toml index 3689eaa9d1..cde9be3105 100644 --- a/frame/contracts/Cargo.toml +++ b/frame/contracts/Cargo.toml @@ -11,7 +11,7 @@ description = "FRAME pallet for WASM contracts" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } pwasm-utils = { version = "0.12.0", default-features = false } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } parity-wasm = { version = "0.41.0", default-features = false } wasmi-validation = { version = "0.3.0", default-features = false } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } diff --git a/frame/contracts/common/Cargo.toml b/frame/contracts/common/Cargo.toml index 19fe69b879..9cb136cd43 100644 --- a/frame/contracts/common/Cargo.toml +++ b/frame/contracts/common/Cargo.toml @@ -10,7 +10,7 @@ description = "A crate that hosts a common definitions that are relevant for the [dependencies] # This crate should not rely on any of the frame primitives. -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" } diff --git a/frame/contracts/rpc/Cargo.toml b/frame/contracts/rpc/Cargo.toml index 520dc4b7e5..3b725bf4cb 100644 --- a/frame/contracts/rpc/Cargo.toml +++ b/frame/contracts/rpc/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "Node-specific RPC methods for interaction with contracts." [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" diff --git a/frame/contracts/rpc/runtime-api/Cargo.toml b/frame/contracts/rpc/runtime-api/Cargo.toml index e4211dee79..a3c0790f9f 100644 --- a/frame/contracts/rpc/runtime-api/Cargo.toml +++ b/frame/contracts/rpc/runtime-api/Cargo.toml @@ -10,7 +10,7 @@ description = "Runtime API definition required by Contracts RPC extensions." [dependencies] sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/api" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/std" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/runtime" } pallet-contracts-primitives = { version = "2.0.0-alpha.5", default-features = false, path = "../../common" } diff --git a/frame/democracy/Cargo.toml b/frame/democracy/Cargo.toml index 6e7aa60e79..6d7e3bd86b 100644 --- a/frame/democracy/Cargo.toml +++ b/frame/democracy/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME pallet for democracy" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index 97b7dc1243..fec2c4078a 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME election pallet for PHRAGMEN" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } sp-phragmen = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/phragmen" } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } diff --git a/frame/elections/Cargo.toml b/frame/elections/Cargo.toml index a5cf36614e..c86039a68b 100644 --- a/frame/elections/Cargo.toml +++ b/frame/elections/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME pallet for elections" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml index a2c9a247f1..bcb7b3ac5e 100644 --- a/frame/evm/Cargo.toml +++ b/frame/evm/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME EVM contracts pallet" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../timestamp" } diff --git a/frame/example-offchain-worker/Cargo.toml b/frame/example-offchain-worker/Cargo.toml index 425cdb05c1..53e6e5f054 100644 --- a/frame/example-offchain-worker/Cargo.toml +++ b/frame/example-offchain-worker/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME example pallet for offchain worker" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } serde = { version = "1.0.101", optional = true } diff --git a/frame/example/Cargo.toml b/frame/example/Cargo.toml index 344ceab2f5..90435dcd7e 100644 --- a/frame/example/Cargo.toml +++ b/frame/example/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME example pallet" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking" } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } diff --git a/frame/executive/Cargo.toml b/frame/executive/Cargo.toml index 3ecd9753b0..15c4d02aa2 100644 --- a/frame/executive/Cargo.toml +++ b/frame/executive/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME executives engine" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } serde = { version = "1.0.101", optional = true } diff --git a/frame/finality-tracker/Cargo.toml b/frame/finality-tracker/Cargo.toml index 3c2d560e1a..a8c1587e53 100644 --- a/frame/finality-tracker/Cargo.toml +++ b/frame/finality-tracker/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.rs/pallet-finality-tracker" [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } diff --git a/frame/generic-asset/Cargo.toml b/frame/generic-asset/Cargo.toml index 2195bc064b..fe5160ea27 100644 --- a/frame/generic-asset/Cargo.toml +++ b/frame/generic-asset/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME pallet for generic asset management" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } diff --git a/frame/grandpa/Cargo.toml b/frame/grandpa/Cargo.toml index 43aa5d0c68..f57cb319f2 100644 --- a/frame/grandpa/Cargo.toml +++ b/frame/grandpa/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME pallet for GRANDPA finality gadget" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } sp-finality-grandpa = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/finality-grandpa" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } diff --git a/frame/identity/Cargo.toml b/frame/identity/Cargo.toml index f13970e6b2..9430ff53fc 100644 --- a/frame/identity/Cargo.toml +++ b/frame/identity/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME identity management pallet" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } diff --git a/frame/im-online/Cargo.toml b/frame/im-online/Cargo.toml index 5d5d40079e..e5258f6918 100644 --- a/frame/im-online/Cargo.toml +++ b/frame/im-online/Cargo.toml @@ -11,7 +11,7 @@ description = "FRAME's I'm online pallet" [dependencies] sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/application-crypto" } pallet-authorship = { version = "2.0.0-alpha.5", default-features = false, path = "../authorship" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } diff --git a/frame/indices/Cargo.toml b/frame/indices/Cargo.toml index 859461bfe7..c6070545ec 100644 --- a/frame/indices/Cargo.toml +++ b/frame/indices/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME indices management pallet" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-keyring = { version = "2.0.0-alpha.5", optional = true, path = "../../primitives/keyring" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } diff --git a/frame/membership/Cargo.toml b/frame/membership/Cargo.toml index 9272d1c76b..ef3abfbbf6 100644 --- a/frame/membership/Cargo.toml +++ b/frame/membership/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME membership management pallet" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } diff --git a/frame/metadata/Cargo.toml b/frame/metadata/Cargo.toml index 1719d98f34..ce68d3bc31 100644 --- a/frame/metadata/Cargo.toml +++ b/frame/metadata/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "Decodable variant of the RuntimeMetadata." [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } diff --git a/frame/nicks/Cargo.toml b/frame/nicks/Cargo.toml index 5c21fde705..76bc183ca3 100644 --- a/frame/nicks/Cargo.toml +++ b/frame/nicks/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME pallet for nick management" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } diff --git a/frame/offences/Cargo.toml b/frame/offences/Cargo.toml index 31f7b1d8f4..28dba9fc55 100644 --- a/frame/offences/Cargo.toml +++ b/frame/offences/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME offences pallet" [dependencies] pallet-balances = { version = "2.0.0-alpha.5", default-features = false, path = "../balances" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } diff --git a/frame/randomness-collective-flip/Cargo.toml b/frame/randomness-collective-flip/Cargo.toml index dd897cc71f..ac6cb08ee8 100644 --- a/frame/randomness-collective-flip/Cargo.toml +++ b/frame/randomness-collective-flip/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME randomness collective flip pallet" [dependencies] safe-mix = { version = "1.0", default-features = false } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } diff --git a/frame/recovery/Cargo.toml b/frame/recovery/Cargo.toml index 35fc394880..4ac5e45471 100644 --- a/frame/recovery/Cargo.toml +++ b/frame/recovery/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME account recovery pallet" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } diff --git a/frame/scored-pool/Cargo.toml b/frame/scored-pool/Cargo.toml index a00b80be32..711bfd4c09 100644 --- a/frame/scored-pool/Cargo.toml +++ b/frame/scored-pool/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for scored pools" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } diff --git a/frame/session/Cargo.toml b/frame/session/Cargo.toml index 2e1e9e2433..e22708387c 100644 --- a/frame/session/Cargo.toml +++ b/frame/session/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME sessions pallet" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/staking" } diff --git a/frame/society/Cargo.toml b/frame/society/Cargo.toml index f2aaccaeb3..b0734e54d4 100644 --- a/frame/society/Cargo.toml +++ b/frame/society/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME society pallet" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index 8a9310e223..953859f97b 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME pallet staking" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-phragmen = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/phragmen" } sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} diff --git a/frame/staking/fuzz/Cargo.lock b/frame/staking/fuzz/Cargo.lock index e8469483db..f6e8cfa08d 100644 --- a/frame/staking/fuzz/Cargo.lock +++ b/frame/staking/fuzz/Cargo.lock @@ -978,7 +978,7 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f509c5e67ca0605ee17dcd3f91ef41cadd685c75a298fb6261b781a5acb3f910" dependencies = [ @@ -991,7 +991,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245" dependencies = [ @@ -1078,7 +1078,7 @@ dependencies = [ "cloudabi", "libc", "redox_syscall", - "smallvec 1.2.0", + "smallvec 1.3.0", "winapi", ] @@ -1482,7 +1482,7 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" @@ -1958,7 +1958,7 @@ dependencies = [ "hashbrown", "log", "rustc-hex", - "smallvec 1.2.0", + "smallvec 1.3.0", ] [[package]] @@ -2003,7 +2003,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" dependencies = [ - "smallvec 1.2.0", + "smallvec 1.3.0", ] [[package]] diff --git a/frame/staking/fuzz/Cargo.toml b/frame/staking/fuzz/Cargo.toml index e4e08a065c..12fc919530 100644 --- a/frame/staking/fuzz/Cargo.toml +++ b/frame/staking/fuzz/Cargo.toml @@ -10,7 +10,7 @@ cargo-fuzz = true [dependencies] libfuzzer-sys = "0.3" -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } pallet-staking = { version = "2.0.0-alpha.2", path = "..", features = ["testing-utils"] } pallet-staking-reward-curve = { version = "2.0.0-alpha.2", path = "../reward-curve" } pallet-session = { version = "2.0.0-alpha.2", path = "../../session" } diff --git a/frame/sudo/Cargo.toml b/frame/sudo/Cargo.toml index bb2bb09002..c11d681013 100644 --- a/frame/sudo/Cargo.toml +++ b/frame/sudo/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME pallet for sudo" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index 0e904a78a4..2ea985fa70 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -11,7 +11,7 @@ description = "Support code for the runtime." [dependencies] log = "0.4" serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } frame-metadata = { version = "11.0.0-alpha.5", default-features = false, path = "../metadata" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index 0f7c89f5c0..a1edf70f61 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-io ={ path = "../../../primitives/io", default-features = false , version = "2.0.0-alpha.5"} sp-state-machine = { version = "0.8.0-alpha.5", optional = true, path = "../../../primitives/state-machine" } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../" } diff --git a/frame/system/Cargo.toml b/frame/system/Cargo.toml index 7f2e38d176..77c1b36407 100644 --- a/frame/system/Cargo.toml +++ b/frame/system/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME system module" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-alpha.5"} diff --git a/frame/system/rpc/runtime-api/Cargo.toml b/frame/system/rpc/runtime-api/Cargo.toml index 6df4f0ea61..bdd1c3ad83 100644 --- a/frame/system/rpc/runtime-api/Cargo.toml +++ b/frame/system/rpc/runtime-api/Cargo.toml @@ -10,7 +10,7 @@ description = "Runtime API definition required by System RPC extensions." [dependencies] sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/api" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } [features] default = ["std"] diff --git a/frame/timestamp/Cargo.toml b/frame/timestamp/Cargo.toml index ed5e77cb5d..ef9d3f3f2d 100644 --- a/frame/timestamp/Cargo.toml +++ b/frame/timestamp/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.rs/pallet-timestamp" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io", optional = true } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } diff --git a/frame/transaction-payment/Cargo.toml b/frame/transaction-payment/Cargo.toml index c9f952d0c4..a26e18edd3 100644 --- a/frame/transaction-payment/Cargo.toml +++ b/frame/transaction-payment/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet to manage transaction payments" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } diff --git a/frame/transaction-payment/rpc/Cargo.toml b/frame/transaction-payment/rpc/Cargo.toml index 2e27e53009..a5bf10b713 100644 --- a/frame/transaction-payment/rpc/Cargo.toml +++ b/frame/transaction-payment/rpc/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "RPC interface for the transaction payment module." [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" diff --git a/frame/transaction-payment/rpc/runtime-api/Cargo.toml b/frame/transaction-payment/rpc/runtime-api/Cargo.toml index 02d1232037..646d3ae81b 100644 --- a/frame/transaction-payment/rpc/runtime-api/Cargo.toml +++ b/frame/transaction-payment/rpc/runtime-api/Cargo.toml @@ -11,7 +11,7 @@ description = "RPC runtime API for transaction payment FRAME pallet" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/api" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/std" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../../primitives/runtime" } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../../support" } diff --git a/frame/treasury/Cargo.toml b/frame/treasury/Cargo.toml index def7ffcb0c..4d761a28cc 100644 --- a/frame/treasury/Cargo.toml +++ b/frame/treasury/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME pallet to manage treasury" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } diff --git a/frame/utility/Cargo.toml b/frame/utility/Cargo.toml index 690465b5d2..fb7bd00978 100644 --- a/frame/utility/Cargo.toml +++ b/frame/utility/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME utilities pallet" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } diff --git a/frame/vesting/Cargo.toml b/frame/vesting/Cargo.toml index c66d7da0e8..767ec3c14d 100644 --- a/frame/vesting/Cargo.toml +++ b/frame/vesting/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME pallet for manage vesting" [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } diff --git a/primitives/api/Cargo.toml b/primitives/api/Cargo.toml index 3e33295afe..bb71d89d11 100644 --- a/primitives/api/Cargo.toml +++ b/primitives/api/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "Substrate runtime api primitives" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } sp-api-proc-macro = { version = "2.0.0-alpha.5", path = "proc-macro" } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } diff --git a/primitives/api/test/Cargo.toml b/primitives/api/test/Cargo.toml index 54d66470cf..299c86a7e3 100644 --- a/primitives/api/test/Cargo.toml +++ b/primitives/api/test/Cargo.toml @@ -16,7 +16,7 @@ sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../blockchain" } sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } sc-block-builder = { version = "0.8.0-alpha.5", path = "../../../client/block-builder" } -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } trybuild = "1.0.17" rustversion = "1.0.0" diff --git a/primitives/application-crypto/Cargo.toml b/primitives/application-crypto/Cargo.toml index c65584c2fb..b0df978273 100644 --- a/primitives/application-crypto/Cargo.toml +++ b/primitives/application-crypto/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.rs/sp-application-crypto" [dependencies] sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } diff --git a/primitives/arithmetic/Cargo.toml b/primitives/arithmetic/Cargo.toml index f41cac4fb5..f4a7236223 100644 --- a/primitives/arithmetic/Cargo.toml +++ b/primitives/arithmetic/Cargo.toml @@ -11,7 +11,7 @@ documentation = "https://docs.rs/sp-arithmetic" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } integer-sqrt = "0.1.2" num-traits = { version = "0.2.8", default-features = false } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } diff --git a/primitives/arithmetic/fuzzer/Cargo.lock b/primitives/arithmetic/fuzzer/Cargo.lock index c7b703c139..3a4187437a 100644 --- a/primitives/arithmetic/fuzzer/Cargo.lock +++ b/primitives/arithmetic/fuzzer/Cargo.lock @@ -158,7 +158,7 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f509c5e67ca0605ee17dcd3f91ef41cadd685c75a298fb6261b781a5acb3f910" dependencies = [ @@ -171,7 +171,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245" dependencies = [ diff --git a/primitives/authority-discovery/Cargo.toml b/primitives/authority-discovery/Cargo.toml index 3f40bb1b75..a6cea0c51c 100644 --- a/primitives/authority-discovery/Cargo.toml +++ b/primitives/authority-discovery/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../application-crypto" } -codec = { package = "parity-scale-codec", default-features = false, version = "1.2.0" } +codec = { package = "parity-scale-codec", default-features = false, version = "1.3.0" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } diff --git a/primitives/authorship/Cargo.toml b/primitives/authorship/Cargo.toml index a69ce303bc..eb319775d5 100644 --- a/primitives/authorship/Cargo.toml +++ b/primitives/authorship/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/paritytech/substrate/" sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../inherents" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } [features] default = [ "std" ] diff --git a/primitives/block-builder/Cargo.toml b/primitives/block-builder/Cargo.toml index 13c8062ade..9a26789253 100644 --- a/primitives/block-builder/Cargo.toml +++ b/primitives/block-builder/Cargo.toml @@ -12,7 +12,7 @@ description = "The block builder runtime api." sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../inherents" } [features] diff --git a/primitives/blockchain/Cargo.toml b/primitives/blockchain/Cargo.toml index 097f9048e5..f47f7a6a51 100644 --- a/primitives/blockchain/Cargo.toml +++ b/primitives/blockchain/Cargo.toml @@ -15,7 +15,7 @@ log = "0.4.8" lru = "0.4.0" parking_lot = "0.10.0" derive_more = "0.99.2" -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-consensus = { version = "0.8.0-alpha.5", path = "../consensus/common" } sp-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } sp-block-builder = { version = "2.0.0-alpha.5", path = "../block-builder" } diff --git a/primitives/consensus/aura/Cargo.toml b/primitives/consensus/aura/Cargo.toml index af25bfaba5..fb29ac49b7 100644 --- a/primitives/consensus/aura/Cargo.toml +++ b/primitives/consensus/aura/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../application-crypto" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../std" } sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../api" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../runtime" } diff --git a/primitives/consensus/babe/Cargo.toml b/primitives/consensus/babe/Cargo.toml index d036040643..cb64925ef5 100644 --- a/primitives/consensus/babe/Cargo.toml +++ b/primitives/consensus/babe/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../../application-crypto" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../std" } sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../api" } sp-consensus = { version = "0.8.0-alpha.5", optional = true, path = "../common" } diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index db66fd0d57..49c1df0bb7 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -23,7 +23,7 @@ futures-diagnose = "1.0" sp-std = { version = "2.0.0-alpha.5", path = "../../std" } sp-version = { version = "2.0.0-alpha.5", path = "../../version" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } -codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } parking_lot = "0.10.0" serde = { version = "1.0", features = ["derive"] } diff --git a/primitives/consensus/pow/Cargo.toml b/primitives/consensus/pow/Cargo.toml index 38be986d1d..14232a506b 100644 --- a/primitives/consensus/pow/Cargo.toml +++ b/primitives/consensus/pow/Cargo.toml @@ -13,7 +13,7 @@ sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../../ap sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../std" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../runtime" } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../core" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } [features] default = ["std"] diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 5def0e8b3f..4dbbf85e17 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -11,7 +11,7 @@ documentation = "https://docs.rs/sp-core" [dependencies] sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } log = { version = "0.4.8", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } byteorder = { version = "1.3.2", default-features = false } diff --git a/primitives/finality-grandpa/Cargo.toml b/primitives/finality-grandpa/Cargo.toml index 94bcd2bce4..17219d9d10 100644 --- a/primitives/finality-grandpa/Cargo.toml +++ b/primitives/finality-grandpa/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.rs/sp-finality-grandpa" [dependencies] sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../application-crypto" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } diff --git a/primitives/finality-tracker/Cargo.toml b/primitives/finality-tracker/Cargo.toml index e6cf53495a..26efb61c2c 100644 --- a/primitives/finality-tracker/Cargo.toml +++ b/primitives/finality-tracker/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "FRAME module that tracks the last finalized block, as perceived by block authors." [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } diff --git a/primitives/inherents/Cargo.toml b/primitives/inherents/Cargo.toml index 8cc9cb4dd0..05ef38b238 100644 --- a/primitives/inherents/Cargo.toml +++ b/primitives/inherents/Cargo.toml @@ -14,7 +14,7 @@ documentation = "https://docs.rs/sp-inherents" parking_lot = { version = "0.10.0", optional = true } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } derive_more = { version = "0.99.2", optional = true } [features] diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index 7531df7e81..2cd2c00006 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -11,7 +11,7 @@ documentation = "https://docs.rs/sp-io" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } hash-db = { version = "0.15.2", default-features = false } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } diff --git a/primitives/phragmen/fuzzer/Cargo.lock b/primitives/phragmen/fuzzer/Cargo.lock index 5f4e9a2451..3ef2a27324 100644 --- a/primitives/phragmen/fuzzer/Cargo.lock +++ b/primitives/phragmen/fuzzer/Cargo.lock @@ -633,7 +633,7 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] name = "parity-scale-codec" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f509c5e67ca0605ee17dcd3f91ef41cadd685c75a298fb6261b781a5acb3f910" dependencies = [ @@ -646,7 +646,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245" dependencies = [ @@ -733,7 +733,7 @@ dependencies = [ "cloudabi", "libc", "redox_syscall", - "smallvec 1.2.0", + "smallvec 1.3.0", "winapi", ] @@ -1113,7 +1113,7 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" @@ -1469,7 +1469,7 @@ dependencies = [ "hashbrown", "log", "rustc-hex", - "smallvec 1.2.0", + "smallvec 1.3.0", ] [[package]] @@ -1514,7 +1514,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" dependencies = [ - "smallvec 1.2.0", + "smallvec 1.3.0", ] [[package]] diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 68da7f1bf8..647d0fb49d 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -14,7 +14,7 @@ sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../wasm-interface", def sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } sp-runtime-interface-proc-macro = { version = "2.0.0-alpha.5", path = "proc-macro" } sp-externalities = { version = "0.8.0-alpha.5", optional = true, path = "../externalities" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } static_assertions = "1.0.0" primitive-types = { version = "0.7.0", default-features = false } diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index e44a778fdd..c0d31e2c35 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.rs/sp-runtime" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../application-crypto" } sp-arithmetic = { version = "2.0.0-alpha.5", default-features = false, path = "../arithmetic" } diff --git a/primitives/sandbox/Cargo.toml b/primitives/sandbox/Cargo.toml index 3b9408dc8e..881961dbd1 100755 --- a/primitives/sandbox/Cargo.toml +++ b/primitives/sandbox/Cargo.toml @@ -14,7 +14,7 @@ sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../io" } sp-wasm-interface = { version = "2.0.0-alpha.5", default-features = false, path = "../wasm-interface" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } [dev-dependencies] wabt = "0.9.2" diff --git a/primitives/staking/Cargo.toml b/primitives/staking/Cargo.toml index 01f68ac3ce..ef2c93c099 100644 --- a/primitives/staking/Cargo.toml +++ b/primitives/staking/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "A crate which contains primitives that are useful for implementation that uses staking approaches in general. Definitions related to sessions, slashing, etc go here." [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } diff --git a/primitives/state-machine/Cargo.toml b/primitives/state-machine/Cargo.toml index 47321181c7..5d4461018d 100644 --- a/primitives/state-machine/Cargo.toml +++ b/primitives/state-machine/Cargo.toml @@ -18,7 +18,7 @@ trie-root = "0.16.0" sp-trie = { version = "2.0.0-alpha.5", path = "../trie" } sp-core = { version = "2.0.0-alpha.5", path = "../core" } sp-panic-handler = { version = "2.0.0-alpha.5", path = "../panic-handler" } -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } num-traits = "0.2.8" rand = "0.7.2" sp-externalities = { version = "0.8.0-alpha.5", path = "../externalities" } diff --git a/primitives/test-primitives/Cargo.toml b/primitives/test-primitives/Cargo.toml index 20f7d13dc9..6938189550 100644 --- a/primitives/test-primitives/Cargo.toml +++ b/primitives/test-primitives/Cargo.toml @@ -10,7 +10,7 @@ publish = false [dependencies] sp-application-crypto = { version = "2.0.0-alpha.5", default-features = false, path = "../application-crypto" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../core" } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } diff --git a/primitives/timestamp/Cargo.toml b/primitives/timestamp/Cargo.toml index cd31c1db25..4948fa4bf5 100644 --- a/primitives/timestamp/Cargo.toml +++ b/primitives/timestamp/Cargo.toml @@ -12,7 +12,7 @@ description = "Substrate core types and inherents for timestamps." sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../inherents" } impl-trait-for-tuples = "0.1.3" wasm-timer = "0.2" diff --git a/primitives/transaction-pool/Cargo.toml b/primitives/transaction-pool/Cargo.toml index e345b1a1f0..e0281c9571 100644 --- a/primitives/transaction-pool/Cargo.toml +++ b/primitives/transaction-pool/Cargo.toml @@ -11,7 +11,7 @@ documentation = "https://docs.rs/sp-transaction-pool" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", optional = true } +codec = { package = "parity-scale-codec", version = "1.3.0", optional = true } derive_more = { version = "0.99.2", optional = true } futures = { version = "0.3.1", optional = true } log = { version = "0.4.8", optional = true } diff --git a/primitives/trie/Cargo.toml b/primitives/trie/Cargo.toml index cb91377f96..6b976671b2 100644 --- a/primitives/trie/Cargo.toml +++ b/primitives/trie/Cargo.toml @@ -14,7 +14,7 @@ name = "bench" harness = false [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } hash-db = { version = "0.15.2", default-features = false } trie-db = { version = "0.20.0", default-features = false } diff --git a/primitives/version/Cargo.toml b/primitives/version/Cargo.toml index 406eff4fbf..01c66c6511 100644 --- a/primitives/version/Cargo.toml +++ b/primitives/version/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/sp-version" [dependencies] impl-serde = { version = "0.2.3", optional = true } serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../std" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } diff --git a/primitives/wasm-interface/Cargo.toml b/primitives/wasm-interface/Cargo.toml index 998463d6e9..5e97f8f36a 100644 --- a/primitives/wasm-interface/Cargo.toml +++ b/primitives/wasm-interface/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/sp-wasm-interface" wasmi = { version = "0.6.2", optional = true } impl-trait-for-tuples = "0.1.2" sp-std = { version = "2.0.0-alpha.5", path = "../std", default-features = false } -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } [features] default = [ "std" ] diff --git a/test-utils/client/Cargo.toml b/test-utils/client/Cargo.toml index 1078c43b31..26a9a0b7c9 100644 --- a/test-utils/client/Cargo.toml +++ b/test-utils/client/Cargo.toml @@ -17,7 +17,7 @@ sc-executor = { version = "0.8.0-alpha.5", path = "../../client/executor" } futures = "0.3.4" hash-db = "0.15.2" sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index 39920688e2..c6ae0ee2de 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -15,7 +15,7 @@ sp-consensus-aura = { version = "0.8.0-alpha.5", default-features = false, path sp-consensus-babe = { version = "0.8.0-alpha.5", default-features = false, path = "../../primitives/consensus/babe" } sp-block-builder = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/block-builder" } cfg-if = "0.1.10" -codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } frame-executive = { version = "2.0.0-alpha.5", default-features = false, path = "../../frame/executive" } sp-inherents = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/inherents" } sp-keyring = { version = "2.0.0-alpha.5", optional = true, path = "../../primitives/keyring" } diff --git a/test-utils/runtime/client/Cargo.toml b/test-utils/runtime/client/Cargo.toml index 4de5e28ff7..cf47c505c6 100644 --- a/test-utils/runtime/client/Cargo.toml +++ b/test-utils/runtime/client/Cargo.toml @@ -16,7 +16,7 @@ substrate-test-runtime = { version = "2.0.0-dev", path = "../../runtime" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } futures = "0.3.4" diff --git a/test-utils/runtime/transaction-pool/Cargo.toml b/test-utils/runtime/transaction-pool/Cargo.toml index cc58bdcbd0..8493ec0077 100644 --- a/test-utils/runtime/transaction-pool/Cargo.toml +++ b/test-utils/runtime/transaction-pool/Cargo.toml @@ -11,7 +11,7 @@ publish = false [dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../client" } parking_lot = "0.10.0" -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } diff --git a/utils/fork-tree/Cargo.toml b/utils/fork-tree/Cargo.toml index 0814a761ec..667bec06ac 100644 --- a/utils/fork-tree/Cargo.toml +++ b/utils/fork-tree/Cargo.toml @@ -10,4 +10,4 @@ description = "Utility library for managing tree-like ordered data with logic fo documentation = "https://docs.rs/fork-tree" [dependencies] -codec = { package = "parity-scale-codec", version = "1.2.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } diff --git a/utils/frame/benchmarking-cli/Cargo.toml b/utils/frame/benchmarking-cli/Cargo.toml index d63e516b45..8b3e5b03d9 100644 --- a/utils/frame/benchmarking-cli/Cargo.toml +++ b/utils/frame/benchmarking-cli/Cargo.toml @@ -20,7 +20,7 @@ sp-externalities = { version = "0.8.0-alpha.5", path = "../../../primitives/exte sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } structopt = "0.3.8" -codec = { version = "1.2.0", package = "parity-scale-codec" } +codec = { version = "1.3.0", package = "parity-scale-codec" } [features] default = ["rocksdb"] diff --git a/utils/frame/rpc/system/Cargo.toml b/utils/frame/rpc/system/Cargo.toml index 780fcd3344..d32f485ce8 100644 --- a/utils/frame/rpc/system/Cargo.toml +++ b/utils/frame/rpc/system/Cargo.toml @@ -10,7 +10,7 @@ description = "FRAME's system exposed over Substrate RPC" [dependencies] sc-client = { version = "0.8.0-alpha.5", path = "../../../../client/" } -codec = { package = "parity-scale-codec", version = "1.2.0" } +codec = { package = "parity-scale-codec", version = "1.3.0" } futures = "0.3.4" jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.3" -- GitLab From 7a96d6216d0c61e687c3152139eac0468586f4d1 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sun, 29 Mar 2020 01:40:00 -0700 Subject: [PATCH 100/300] don't use delays in tests (#5404) --- Cargo.lock | 12 +++- client/transaction-pool/Cargo.toml | 2 +- client/transaction-pool/src/lib.rs | 23 ++++++- client/transaction-pool/src/revalidation.rs | 47 +++++++++---- client/transaction-pool/src/testing/pool.rs | 74 +++++++++++---------- 5 files changed, 106 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 22636830a6..b0d6c55686 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2345,6 +2345,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" +[[package]] +name = "intervalier" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "750dc2c10615a0aa0d38a5adf9d4e62651c178109f40253cb6235b3f638af6a9" +dependencies = [ + "futures 0.3.4", + "futures-timer 2.0.2", +] + [[package]] name = "iovec" version = "0.1.4" @@ -6690,8 +6700,8 @@ dependencies = [ "derive_more", "futures 0.3.4", "futures-diagnose", - "futures-timer 2.0.2", "hex", + "intervalier", "log 0.4.8", "parity-scale-codec", "parity-util-mem", diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index e01409ecb0..3528463c7b 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -23,7 +23,7 @@ sc-transaction-graph = { version = "2.0.0-alpha.5", path = "./graph" } sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } -futures-timer = "2.0" +intervalier = "0.3" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index 4c54cf28e0..c50d9dbbb4 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -31,7 +31,7 @@ pub use sc_transaction_graph as txpool; pub use crate::api::{FullChainApi, LightChainApi}; use std::{collections::HashMap, sync::Arc, pin::Pin}; -use futures::{Future, FutureExt, future::ready, channel::oneshot}; +use futures::{prelude::*, future::ready, channel::oneshot}; use parking_lot::Mutex; use sp_runtime::{ @@ -151,6 +151,27 @@ impl BasicPool Self::with_revalidation_type(options, pool_api, RevalidationType::Full) } + /// Create new basic transaction pool with provided api, for tests. + #[cfg(test)] + pub fn new_test( + pool_api: Arc, + ) -> (Self, Pin + Send>>, intervalier::BackSignalControl) { + let pool = Arc::new(sc_transaction_graph::Pool::new(Default::default(), pool_api.clone())); + let (revalidation_queue, background_task, notifier) = + revalidation::RevalidationQueue::new_test(pool_api.clone(), pool.clone()); + ( + BasicPool { + api: pool_api, + pool, + revalidation_queue: Arc::new(revalidation_queue), + revalidation_strategy: Arc::new(Mutex::new(RevalidationStrategy::Always)), + ready_poll: Default::default(), + }, + background_task, + notifier, + ) + } + /// Create new basic transaction pool with provided api and custom /// revalidation type. pub fn with_revalidation_type( diff --git a/client/transaction-pool/src/revalidation.rs b/client/transaction-pool/src/revalidation.rs index ee0aa1ab2d..5a3b2521c3 100644 --- a/client/transaction-pool/src/revalidation.rs +++ b/client/transaction-pool/src/revalidation.rs @@ -23,9 +23,8 @@ use sp_runtime::traits::{Zero, SaturatedConversion}; use sp_runtime::generic::BlockId; use sp_runtime::transaction_validity::TransactionValidityError; -use futures::{prelude::*, channel::mpsc, stream::unfold}; +use futures::{prelude::*, channel::mpsc}; use std::time::Duration; -use futures_timer::Delay; #[cfg(not(test))] const BACKGROUND_REVALIDATION_INTERVAL: Duration = Duration::from_millis(200); @@ -53,12 +52,6 @@ struct RevalidationWorker { impl Unpin for RevalidationWorker {} -fn interval(duration: Duration) -> impl Stream + Unpin { - unfold((), move |_| { - Delay::new(duration).map(|_| Some(((), ()))) - }).map(drop) -} - /// Revalidate batch of transaction. /// /// Each transaction is validated against chain, and invalid are @@ -207,8 +200,13 @@ impl RevalidationWorker { /// It does two things: periodically tries to process some transactions /// from the queue and also accepts messages to enqueue some more /// transactions from the pool. - pub async fn run(mut self, from_queue: mpsc::UnboundedReceiver>) { - let interval = interval(BACKGROUND_REVALIDATION_INTERVAL).fuse(); + pub async fn run( + mut self, + from_queue: mpsc::UnboundedReceiver>, + interval: R, + ) where R: Send, R::Guard: Send + { + let interval = interval.into_stream().fuse(); let from_queue = from_queue.fuse(); futures::pin_mut!(interval, from_queue); let this = &mut self; @@ -270,9 +268,12 @@ where } } - /// New revalidation queue with background worker. - pub fn new_background(api: Arc, pool: Arc>) -> - (Self, Pin + Send>>) + pub fn new_with_interval( + api: Arc, + pool: Arc>, + interval: R, + ) -> (Self, Pin + Send>>) + where R: Send + 'static, R::Guard: Send { let (to_worker, from_queue) = mpsc::unbounded(); @@ -285,7 +286,25 @@ where background: Some(to_worker), }; - (queue, worker.run(from_queue).boxed()) + (queue, worker.run(from_queue, interval).boxed()) + } + + /// New revalidation queue with background worker. + pub fn new_background(api: Arc, pool: Arc>) -> + (Self, Pin + Send>>) + { + Self::new_with_interval(api, pool, intervalier::Interval::new(BACKGROUND_REVALIDATION_INTERVAL)) + } + + /// New revalidation queue with background worker and test signal. + #[cfg(test)] + pub fn new_test(api: Arc, pool: Arc>) -> + (Self, Pin + Send>>, intervalier::BackSignalControl) + { + let (interval, notifier) = intervalier::BackSignalInterval::new(BACKGROUND_REVALIDATION_INTERVAL); + let (queue, background) = Self::new_with_interval(api, pool, interval); + + (queue, background, notifier) } /// Queue some transaction for later revalidation. diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index 7dbb8e6158..766257ff5e 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -27,20 +27,25 @@ use substrate_test_runtime_client::{ AccountKeyring::*, }; use substrate_test_runtime_transaction_pool::{TestApi, uxt}; -use crate::revalidation::BACKGROUND_REVALIDATION_INTERVAL; -use futures::task::Poll; +use futures::{prelude::*, task::Poll}; use codec::Encode; fn pool() -> Pool { Pool::new(Default::default(), TestApi::with_alice_nonce(209).into()) } -fn maintained_pool() -> (BasicPool, futures::executor::ThreadPool) { - let (pool, background_task) = BasicPool::new(Default::default(), std::sync::Arc::new(TestApi::with_alice_nonce(209))); +fn maintained_pool() -> ( + BasicPool, + futures::executor::ThreadPool, + intervalier::BackSignalControl, +) { + let (pool, background_task, notifier) = BasicPool::new_test( + std::sync::Arc::new(TestApi::with_alice_nonce(209)) + ); let thread_pool = futures::executor::ThreadPool::new().unwrap(); - thread_pool.spawn_ok(background_task.expect("basic pool have background task")); - (pool, thread_pool) + thread_pool.spawn_ok(background_task); + (pool, thread_pool, notifier) } fn header(number: u64) -> Header { @@ -190,7 +195,7 @@ fn block_event_with_retracted(id: u64, retracted: Vec) -> ChainEvent>(), @@ -409,7 +413,7 @@ fn should_push_watchers_during_maintaince() { #[test] fn can_track_heap_size() { - let (pool, _guard) = maintained_pool(); + let (pool, _guard, _notifier) = maintained_pool(); block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 209))).expect("1. Imported"); block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 210))).expect("1. Imported"); block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt(Alice, 211))).expect("1. Imported"); @@ -629,7 +633,7 @@ fn fork_aware_finalization() { #[test] fn ready_set_should_not_resolve_before_block_update() { - let (pool, _guard) = maintained_pool(); + let (pool, _guard, _notifier) = maintained_pool(); let xt1 = uxt(Alice, 209); block_on(pool.submit_one(&BlockId::number(1), SOURCE, xt1.clone())).expect("1. Imported"); @@ -638,7 +642,7 @@ fn ready_set_should_not_resolve_before_block_update() { #[test] fn ready_set_should_resolve_after_block_update() { - let (pool, _guard) = maintained_pool(); + let (pool, _guard, _notifier) = maintained_pool(); pool.api.push_block(1, vec![]); let xt1 = uxt(Alice, 209); @@ -651,7 +655,7 @@ fn ready_set_should_resolve_after_block_update() { #[test] fn ready_set_should_eventually_resolve_when_block_update_arrives() { - let (pool, _guard) = maintained_pool(); + let (pool, _guard, _notifier) = maintained_pool(); pool.api.push_block(1, vec![]); let xt1 = uxt(Alice, 209); -- GitLab From 2206e52de02c0e8a4350003c7901fba265fec851 Mon Sep 17 00:00:00 2001 From: Joseph Mark Date: Sun, 29 Mar 2020 13:24:11 +0200 Subject: [PATCH 101/300] Extend PerThing + Saturating (#5281) * Extend PerThing + Saturating * Add saturating_pow to Saturating * Add saturating_truncating_mul to PerThing (rounding-down mul) * Add saturating_reciprocal_mul to PerThing (divide x by perthing) * Provide default methods where possible * Restore const functions * Fix test * Update primitives/arithmetic/src/per_things.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Add comment and test verifying no overflow * Formatting * Fix possible overflow and change type constraint * Use overflow pruning for all mul * Formatting and comments * Improve comments and names * Comments in `rational_mul_correction` explain overflow aversion. * Test rational_mul_correction * Formatting * Docs and formatting * Add new trait methods to Perthing type impl * Fix signature * saturating_pow for Delegations * Add missing trait method to impl Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/democracy/src/types.rs | 7 + primitives/arithmetic/src/fixed64.rs | 6 + primitives/arithmetic/src/per_things.rs | 642 ++++++++++++++++++------ primitives/arithmetic/src/traits.rs | 36 +- 4 files changed, 538 insertions(+), 153 deletions(-) diff --git a/frame/democracy/src/types.rs b/frame/democracy/src/types.rs index 7a145701e9..3454326364 100644 --- a/frame/democracy/src/types.rs +++ b/frame/democracy/src/types.rs @@ -62,6 +62,13 @@ impl Saturating for Delegations { capital: self.capital.saturating_mul(o.capital), } } + + fn saturating_pow(self, exp: usize) -> Self { + Self { + votes: self.votes.saturating_pow(exp), + capital: self.capital.saturating_pow(exp), + } + } } impl< diff --git a/primitives/arithmetic/src/fixed64.rs b/primitives/arithmetic/src/fixed64.rs index eea1ab68a3..6b399b6aa5 100644 --- a/primitives/arithmetic/src/fixed64.rs +++ b/primitives/arithmetic/src/fixed64.rs @@ -110,12 +110,18 @@ impl Saturating for Fixed64 { fn saturating_add(self, rhs: Self) -> Self { Self(self.0.saturating_add(rhs.0)) } + fn saturating_mul(self, rhs: Self) -> Self { Self(self.0.saturating_mul(rhs.0) / DIV) } + fn saturating_sub(self, rhs: Self) -> Self { Self(self.0.saturating_sub(rhs.0)) } + + fn saturating_pow(self, exp: usize) -> Self { + Self(self.0.saturating_pow(exp as u32)) + } } /// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index 86b0fa59a6..fa02b4ec61 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -19,7 +19,9 @@ use serde::{Serialize, Deserialize}; use sp_std::{ops, fmt, prelude::*, convert::TryInto}; use codec::{Encode, Decode, CompactAs}; -use crate::traits::{SaturatedConversion, UniqueSaturatedInto, Saturating, BaseArithmetic, Bounded}; +use crate::traits::{ + SaturatedConversion, UniqueSaturatedInto, Saturating, BaseArithmetic, Bounded, Zero, +}; use sp_debug_derive::RuntimeDebug; /// Something that implements a fixed point ration with an arbitrary granularity `X`, as _parts per @@ -30,33 +32,145 @@ pub trait PerThing: /// The data type used to build this per-thingy. type Inner: BaseArithmetic + Copy + fmt::Debug; - /// The data type that is used to store values bigger than the maximum of this type. This must - /// at least be able to store `Self::ACCURACY * Self::ACCURACY`. - type Upper: BaseArithmetic + Copy + fmt::Debug; + /// A data type larger than `Self::Inner`, used to avoid overflow in some computations. + /// It must be able to compute `ACCURACY^2`. + type Upper: BaseArithmetic + Copy + From + TryInto + fmt::Debug; - /// accuracy of this type + /// The accuracy of this type. const ACCURACY: Self::Inner; - /// NoThing - fn zero() -> Self; + /// Equivalent to `Self::from_parts(0)`. + fn zero() -> Self { Self::from_parts(Self::Inner::zero()) } - /// `true` if this is nothing. - fn is_zero(&self) -> bool; + /// Return `true` if this is nothing. + fn is_zero(&self) -> bool { self.deconstruct() == Self::Inner::zero() } - /// Everything. - fn one() -> Self; + /// Equivalent to `Self::from_parts(Self::ACCURACY)`. + fn one() -> Self { Self::from_parts(Self::ACCURACY) } - /// Consume self and deconstruct into a raw numeric type. - fn deconstruct(self) -> Self::Inner; - - /// From an explicitly defined number of parts per maximum of the type. - fn from_parts(parts: Self::Inner) -> Self; + /// Return `true` if this is one. + fn is_one(&self) -> bool { self.deconstruct() == Self::ACCURACY } - /// Converts a percent into `Self`. Equal to `x / 100`. - fn from_percent(x: Self::Inner) -> Self; + /// Build this type from a percent. Equivalent to `Self::from_parts(x * Self::ACCURACY / 100)` + /// but more accurate. + fn from_percent(x: Self::Inner) -> Self { + let a = x.min(100.into()); + let b = Self::ACCURACY; + // if Self::ACCURACY % 100 > 0 then we need the correction for accuracy + let c = rational_mul_correction::(b, a, 100.into(), Rounding::Nearest); + Self::from_parts(a / 100.into() * b + c) + } /// Return the product of multiplication of this value by itself. - fn square(self) -> Self; + fn square(self) -> Self { + let p = Self::Upper::from(self.deconstruct()); + let q = Self::Upper::from(Self::ACCURACY); + Self::from_rational_approximation(p * p, q * q) + } + + /// Multiplication that always rounds down to a whole number. The standard `Mul` rounds to the + /// nearest whole number. + /// + /// ```rust + /// # use sp_arithmetic::{Percent, PerThing}; + /// # fn main () { + /// // round to nearest + /// assert_eq!(Percent::from_percent(34) * 10u64, 3); + /// assert_eq!(Percent::from_percent(36) * 10u64, 4); + /// + /// // round down + /// assert_eq!(Percent::from_percent(34).mul_floor(10u64), 3); + /// assert_eq!(Percent::from_percent(36).mul_floor(10u64), 3); + /// # } + /// ``` + fn mul_floor(self, b: N) -> N + where N: Clone + From + UniqueSaturatedInto + ops::Rem + + ops::Div + ops::Mul + ops::Add + { + overflow_prune_mul::(b, self.deconstruct(), Rounding::Down) + } + + /// Multiplication that always rounds the result up to a whole number. The standard `Mul` + /// rounds to the nearest whole number. + /// + /// ```rust + /// # use sp_arithmetic::{Percent, PerThing}; + /// # fn main () { + /// // round to nearest + /// assert_eq!(Percent::from_percent(34) * 10u64, 3); + /// assert_eq!(Percent::from_percent(36) * 10u64, 4); + /// + /// // round up + /// assert_eq!(Percent::from_percent(34).mul_ceil(10u64), 4); + /// assert_eq!(Percent::from_percent(36).mul_ceil(10u64), 4); + /// # } + /// ``` + fn mul_ceil(self, b: N) -> N + where N: Clone + From + UniqueSaturatedInto + ops::Rem + + ops::Div + ops::Mul + ops::Add + { + overflow_prune_mul::(b, self.deconstruct(), Rounding::Up) + } + + /// Saturating multiplication by the reciprocal of `self`. The result is rounded to the + /// nearest whole number and saturates at the numeric bounds instead of overflowing. + /// + /// ```rust + /// # use sp_arithmetic::{Percent, PerThing}; + /// # fn main () { + /// assert_eq!(Percent::from_percent(50).saturating_reciprocal_mul(10u64), 20); + /// # } + /// ``` + fn saturating_reciprocal_mul(self, b: N) -> N + where N: Clone + From + UniqueSaturatedInto + ops::Rem + + ops::Div + ops::Mul + ops::Add + Saturating + { + saturating_reciprocal_mul::(b, self.deconstruct(), Rounding::Nearest) + } + + /// Saturating multiplication by the reciprocal of `self`. The result is rounded down to the + /// nearest whole number and saturates at the numeric bounds instead of overflowing. + /// + /// ```rust + /// # use sp_arithmetic::{Percent, PerThing}; + /// # fn main () { + /// // round to nearest + /// assert_eq!(Percent::from_percent(60).saturating_reciprocal_mul(10u64), 17); + /// // round down + /// assert_eq!(Percent::from_percent(60).saturating_reciprocal_mul_floor(10u64), 16); + /// # } + /// ``` + fn saturating_reciprocal_mul_floor(self, b: N) -> N + where N: Clone + From + UniqueSaturatedInto + ops::Rem + + ops::Div + ops::Mul + ops::Add + Saturating + { + saturating_reciprocal_mul::(b, self.deconstruct(), Rounding::Down) + } + + /// Saturating multiplication by the reciprocal of `self`. The result is rounded up to the + /// nearest whole number and saturates at the numeric bounds instead of overflowing. + /// + /// ```rust + /// # use sp_arithmetic::{Percent, PerThing}; + /// # fn main () { + /// // round to nearest + /// assert_eq!(Percent::from_percent(61).saturating_reciprocal_mul(10u64), 16); + /// // round up + /// assert_eq!(Percent::from_percent(61).saturating_reciprocal_mul_ceil(10u64), 17); + /// # } + /// ``` + fn saturating_reciprocal_mul_ceil(self, b: N) -> N + where N: Clone + From + UniqueSaturatedInto + ops::Rem + + ops::Div + ops::Mul + ops::Add + Saturating + { + saturating_reciprocal_mul::(b, self.deconstruct(), Rounding::Up) + } + + /// Consume self and return the number of parts per thing. + fn deconstruct(self) -> Self::Inner; + + /// Build this type from a number of parts per thing. + fn from_parts(parts: Self::Inner) -> Self; /// Converts a fraction into `Self`. #[cfg(feature = "std")] @@ -81,28 +195,106 @@ pub trait PerThing: /// # } /// ``` fn from_rational_approximation(p: N, q: N) -> Self - where N: - Clone + Ord + From + TryInto + TryInto + - ops::Div + ops::Rem + ops::Add; + where N: Clone + Ord + From + TryInto + TryInto + + ops::Div + ops::Rem + ops::Add; +} - /// A mul implementation that always rounds down, whilst the standard `Mul` implementation - /// rounds to the nearest numbers - /// - /// ```rust - /// # use sp_arithmetic::{Percent, PerThing}; - /// # fn main () { - /// // rounds to closest - /// assert_eq!(Percent::from_percent(34) * 10u64, 3); - /// assert_eq!(Percent::from_percent(36) * 10u64, 4); - /// - /// // collapse down - /// assert_eq!(Percent::from_percent(34).mul_collapse(10u64), 3); - /// assert_eq!(Percent::from_percent(36).mul_collapse(10u64), 3); - /// # } - /// ``` - fn mul_collapse(self, b: N) -> N - where N: Clone + From + UniqueSaturatedInto + ops::Rem - + ops::Div + ops::Mul + ops::Add; +/// The rounding method to use. +/// +/// `Perthing`s are unsigned so `Up` means towards infinity and `Down` means towards zero. +/// `Nearest` will round an exact half down. +enum Rounding { + Up, + Down, + Nearest, +} + +/// Saturating reciprocal multiplication. Compute `x / self`, saturating at the numeric +/// bounds instead of overflowing. +fn saturating_reciprocal_mul( + x: N, + part: P::Inner, + rounding: Rounding, +) -> N +where + N: Clone + From + UniqueSaturatedInto + ops::Div + ops::Mul + ops::Add + ops::Rem + Saturating, + P: PerThing, +{ + let maximum: N = P::ACCURACY.into(); + let c = rational_mul_correction::( + x.clone(), + P::ACCURACY, + part, + rounding, + ); + (x / part.into()).saturating_mul(maximum).saturating_add(c) +} + +/// Overflow-prune multiplication. Accurately multiply a value by `self` without overflowing. +fn overflow_prune_mul( + x: N, + part: P::Inner, + rounding: Rounding, +) -> N +where + N: Clone + From + UniqueSaturatedInto + ops::Div + ops::Mul + ops::Add + ops::Rem, + P: PerThing, +{ + let maximum: N = P::ACCURACY.into(); + let part_n: N = part.into(); + let c = rational_mul_correction::( + x.clone(), + part, + P::ACCURACY, + rounding, + ); + (x / maximum) * part_n + c +} + +/// Compute the error due to integer division in the expression `x / denom * numer`. +/// +/// Take the remainder of `x / denom` and multiply by `numer / denom`. The result can be added +/// to `x / denom * numer` for an accurate result. +fn rational_mul_correction( + x: N, + numer: P::Inner, + denom: P::Inner, + rounding: Rounding, +) -> N +where + N: From + UniqueSaturatedInto + ops::Div + ops::Mul + ops::Add + ops::Rem, + P: PerThing, +{ + let numer_upper = P::Upper::from(numer); + let denom_n = N::from(denom); + let denom_upper = P::Upper::from(denom); + let rem = x.rem(denom_n); + // `rem` is less than `denom`, which fits in `P::Inner`. + let rem_inner = rem.saturated_into::(); + // `P::Upper` always fits `P::Inner::max_value().pow(2)`, thus it fits `rem * numer`. + let rem_mul_upper = P::Upper::from(rem_inner) * numer_upper; + // `rem` is less than `denom`, so `rem * numer / denom` is less than `numer`, which fits in + // `P::Inner`. + let mut rem_mul_div_inner = (rem_mul_upper / denom_upper).saturated_into::(); + match rounding { + // Already rounded down + Rounding::Down => {}, + // Round up if the fractional part of the result is non-zero. + Rounding::Up => if rem_mul_upper % denom_upper > 0.into() { + // `rem * numer / denom` is less than `numer`, so this will not overflow. + rem_mul_div_inner = rem_mul_div_inner + 1.into(); + }, + // Round up if the fractional part of the result is greater than a half. An exact half is + // rounded down. + Rounding::Nearest => if rem_mul_upper % denom_upper > denom_upper / 2.into() { + // `rem * numer / denom` is less than `numer`, so this will not overflow. + rem_mul_div_inner = rem_mul_div_inner + 1.into(); + }, + } + rem_mul_div_inner.into() } macro_rules! implement_per_thing { @@ -110,15 +302,17 @@ macro_rules! implement_per_thing { $name:ident, $test_mod:ident, [$($test_units:tt),+], - $max:tt, $type:ty, + $max:tt, + $type:ty, $upper_type:ty, $title:expr $(,)? ) => { - /// A fixed point representation of a number between in the range [0, 1]. + /// A fixed point representation of a number in the range [0, 1]. /// #[doc = $title] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] - #[derive(Encode, Decode, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, CompactAs)] + #[derive(Encode, Decode, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, + RuntimeDebug, CompactAs)] pub struct $name($type); impl PerThing for $name { @@ -127,40 +321,20 @@ macro_rules! implement_per_thing { const ACCURACY: Self::Inner = $max; - fn zero() -> Self { Self(0) } - - fn is_zero(&self) -> bool { self.0 == 0 } - - fn one() -> Self { Self($max) } - + /// Consume self and return the number of parts per thing. fn deconstruct(self) -> Self::Inner { self.0 } - // needed only for peru16. Since peru16 is the only type in which $max == - // $type::max_value(), rustc is being a smart-a** here by warning that the comparison - // is not needed. - #[allow(unused_comparisons)] - fn from_parts(parts: Self::Inner) -> Self { - Self([parts, $max][(parts > $max) as usize]) - } - - fn from_percent(x: Self::Inner) -> Self { - Self::from_rational_approximation([x, 100][(x > 100) as usize] as $upper_type, 100) - } - - fn square(self) -> Self { - // both can be safely casted and multiplied. - let p: $upper_type = self.0 as $upper_type * self.0 as $upper_type; - let q: $upper_type = <$upper_type>::from($max) * <$upper_type>::from($max); - Self::from_rational_approximation(p, q) - } + /// Build this type from a number of parts per thing. + fn from_parts(parts: Self::Inner) -> Self { Self(parts.min($max)) } #[cfg(feature = "std")] - fn from_fraction(x: f64) -> Self { Self((x * ($max as f64)) as Self::Inner) } + fn from_fraction(x: f64) -> Self { + Self::from_parts((x * $max as f64) as Self::Inner) + } fn from_rational_approximation(p: N, q: N) -> Self - where N: - Clone + Ord + From + TryInto + TryInto + - ops::Div + ops::Rem + ops::Add + where N: Clone + Ord + From + TryInto + TryInto + + ops::Div + ops::Rem + ops::Add { let div_ceil = |x: N, f: N| -> N { let mut o = x.clone() / f.clone(); @@ -203,39 +377,6 @@ macro_rules! implement_per_thing { $name(part as Self::Inner) } - - fn mul_collapse(self, b: N) -> N - where - N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem - + ops::Div + ops::Mul + ops::Add - { - let maximum: N = $max.into(); - let upper_max: $upper_type = $max.into(); - let part: N = self.0.into(); - - let rem_multiplied_divided = { - let rem = b.clone().rem(maximum.clone()); - - // `rem_sized` is inferior to $max, thus it fits into $type. This is assured by - // a test. - let rem_sized = rem.saturated_into::<$type>(); - - // `self` and `rem_sized` are inferior to $max, thus the product is less than - // $max^2 and fits into $upper_type. This is assured by a test. - let rem_multiplied_upper = rem_sized as $upper_type * self.0 as $upper_type; - - // `rem_multiplied_upper` is less than $max^2 therefore divided by $max it fits - // in $type. remember that $type always fits $max. - let rem_multiplied_divided_sized = - (rem_multiplied_upper / upper_max) as $type; - - // `rem_multiplied_divided_sized` is inferior to b, thus it can be converted - // back to N type - rem_multiplied_divided_sized.into() - }; - - (b / maximum) * part + rem_multiplied_divided - } } impl $name { @@ -254,7 +395,7 @@ macro_rules! implement_per_thing { /// /// This can be created at compile time. pub const fn from_percent(x: $type) -> Self { - Self([x, 100][(x > 100) as usize] * ($max / 100)) + Self(([x, 100][(x > 100) as usize] as $upper_type * $max as $upper_type / 100) as $type) } /// See [`PerThing::one`]. @@ -262,6 +403,11 @@ macro_rules! implement_per_thing { ::one() } + /// See [`PerThing::is_one`]. + pub fn is_one(&self) -> bool { + PerThing::is_one(self) + } + /// See [`PerThing::zero`]. pub fn zero() -> Self { ::zero() @@ -296,23 +442,63 @@ macro_rules! implement_per_thing { ::from_rational_approximation(p, q) } - /// See [`PerThing::mul_collapse`]. - pub fn mul_collapse(self, b: N) -> N + /// See [`PerThing::mul_floor`]. + pub fn mul_floor(self, b: N) -> N + where N: Clone + From<$type> + UniqueSaturatedInto<$type> + + ops::Rem + ops::Div + ops::Mul + + ops::Add { + PerThing::mul_floor(self, b) + } + + /// See [`PerThing::mul_ceil`]. + pub fn mul_ceil(self, b: N) -> N where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + ops::Div + ops::Mul + ops::Add { - PerThing::mul_collapse(self, b) + PerThing::mul_ceil(self, b) + } + + /// See [`PerThing::saturating_reciprocal_mul`]. + fn saturating_reciprocal_mul(self, b: N) -> N + where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + + ops::Div + ops::Mul + ops::Add + + Saturating { + PerThing::saturating_reciprocal_mul(self, b) + } + + /// See [`PerThing::saturating_reciprocal_mul_floor`]. + fn saturating_reciprocal_mul_floor(self, b: N) -> N + where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + + ops::Div + ops::Mul + ops::Add + + Saturating { + PerThing::saturating_reciprocal_mul_floor(self, b) + } + + /// See [`PerThing::saturating_reciprocal_mul_ceil`]. + fn saturating_reciprocal_mul_ceil(self, b: N) -> N + where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + + ops::Div + ops::Mul + ops::Add + + Saturating { + PerThing::saturating_reciprocal_mul_ceil(self, b) } } impl Saturating for $name { + /// Saturating addition. Compute `self + rhs`, saturating at the numeric bounds instead of + /// overflowing. This operation is lossless if it does not saturate. fn saturating_add(self, rhs: Self) -> Self { // defensive-only: since `$max * 2 < $type::max_value()`, this can never overflow. Self::from_parts(self.0.saturating_add(rhs.0)) } + + /// Saturating subtraction. Compute `self - rhs`, saturating at the numeric bounds instead of + /// overflowing. This operation is lossless if it does not saturate. fn saturating_sub(self, rhs: Self) -> Self { Self::from_parts(self.0.saturating_sub(rhs.0)) } + + /// Saturating multiply. Compute `self * rhs`, saturating at the numeric bounds instead of + /// overflowing. This operation is lossy. fn saturating_mul(self, rhs: Self) -> Self { let a = self.0 as $upper_type; let b = rhs.0 as $upper_type; @@ -321,6 +507,31 @@ macro_rules! implement_per_thing { // This will always fit into $type. Self::from_parts(parts as $type) } + + /// Saturating exponentiation. Computes `self.pow(exp)`, saturating at the numeric + /// bounds instead of overflowing. This operation is lossy. + fn saturating_pow(self, exp: usize) -> Self { + if self.is_zero() || self.is_one() { + self + } else { + let p = <$name as PerThing>::Upper::from(self.deconstruct()); + let q = <$name as PerThing>::Upper::from(Self::ACCURACY); + let mut s = Self::one(); + for _ in 0..exp { + if s.is_zero() { + break; + } else { + // x^2 always fits in Self::Upper if x fits in Self::Inner. + // Verified by a test. + s = Self::from_rational_approximation( + <$name as PerThing>::Upper::from(s.deconstruct()) * p, + q * q, + ); + } + } + s + } + } } impl crate::traits::Bounded for $name { @@ -345,8 +556,7 @@ macro_rules! implement_per_thing { /// Non-overflow multiplication. /// - /// tailored to be used with a balance type. - /// + /// This is tailored to be used with a balance type. impl ops::Mul for $name where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem @@ -354,37 +564,7 @@ macro_rules! implement_per_thing { { type Output = N; fn mul(self, b: N) -> Self::Output { - let maximum: N = $max.into(); - let upper_max: $upper_type = $max.into(); - let part: N = self.0.into(); - - let rem_multiplied_divided = { - let rem = b.clone().rem(maximum.clone()); - - // `rem_sized` is inferior to $max, thus it fits into $type. This is assured by - // a test. - let rem_sized = rem.saturated_into::<$type>(); - - // `self` and `rem_sized` are inferior to $max, thus the product is less than - // $max^2 and fits into $upper_type. This is assured by a test. - let rem_multiplied_upper = rem_sized as $upper_type * self.0 as $upper_type; - - // `rem_multiplied_upper` is less than $max^2 therefore divided by $max it fits - // in $type. remember that $type always fits $max. - let mut rem_multiplied_divided_sized = - (rem_multiplied_upper / upper_max) as $type; - - // fix a tiny rounding error - if rem_multiplied_upper % upper_max > upper_max / 2 { - rem_multiplied_divided_sized += 1; - } - - // `rem_multiplied_divided_sized` is inferior to b, thus it can be converted - // back to N type - rem_multiplied_divided_sized.into() - }; - - (b / maximum) * part + rem_multiplied_divided + overflow_prune_mul::(b, self.deconstruct(), Rounding::Nearest) } } @@ -410,6 +590,9 @@ macro_rules! implement_per_thing { // for something like percent they can be the same. assert!((<$type>::max_value() as $upper_type) <= <$upper_type>::max_value()); assert!(<$upper_type>::from($max).checked_mul($max.into()).is_some()); + + // make sure saturating_pow won't overflow the upper type + assert!(<$upper_type>::from($max) * <$upper_type>::from($max) < <$upper_type>::max_value()); } #[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug)] @@ -452,6 +635,12 @@ macro_rules! implement_per_thing { assert_eq!($name::zero(), $name::from_parts(Zero::zero())); assert_eq!($name::one(), $name::from_parts($max)); assert_eq!($name::ACCURACY, $max); + + assert_eq!($name::from_percent(0), $name::from_parts(Zero::zero())); + assert_eq!($name::from_percent(10), $name::from_parts($max / 10)); + assert_eq!($name::from_percent(100), $name::from_parts($max)); + assert_eq!($name::from_percent(200), $name::from_parts($max)); + assert_eq!($name::from_fraction(0.0), $name::from_parts(Zero::zero())); assert_eq!($name::from_fraction(0.1), $name::from_parts($max / 10)); assert_eq!($name::from_fraction(1.0), $name::from_parts($max)); @@ -742,6 +931,177 @@ macro_rules! implement_per_thing { 2, ); } + + #[test] + fn saturating_pow_works() { + // x^0 == 1 + assert_eq!( + $name::from_parts($max / 2).saturating_pow(0), + $name::from_parts($max), + ); + + // x^1 == x + assert_eq!( + $name::from_parts($max / 2).saturating_pow(1), + $name::from_parts($max / 2), + ); + + // x^2 + assert_eq!( + $name::from_parts($max / 2).saturating_pow(2), + $name::from_parts($max / 2).square(), + ); + + // x^3 + assert_eq!( + $name::from_parts($max / 2).saturating_pow(3), + $name::from_parts($max / 8), + ); + + // 0^n == 0 + assert_eq!( + $name::from_parts(0).saturating_pow(3), + $name::from_parts(0), + ); + + // 1^n == 1 + assert_eq!( + $name::from_parts($max).saturating_pow(3), + $name::from_parts($max), + ); + + // (x < 1)^inf == 0 (where 2.pow(31) ~ inf) + assert_eq!( + $name::from_parts($max / 2).saturating_pow(2usize.pow(31)), + $name::from_parts(0), + ); + } + + #[test] + fn saturating_reciprocal_mul_works() { + // divide by 1 + assert_eq!( + $name::from_parts($max).saturating_reciprocal_mul(<$type>::from(10u8)), + 10, + ); + // divide by 1/2 + assert_eq!( + $name::from_parts($max / 2).saturating_reciprocal_mul(<$type>::from(10u8)), + 20, + ); + // saturate + assert_eq!( + $name::from_parts(1).saturating_reciprocal_mul($max), + <$type>::max_value(), + ); + // round to nearest + assert_eq!( + $name::from_percent(60).saturating_reciprocal_mul(<$type>::from(10u8)), + 17, + ); + // round down + assert_eq!( + $name::from_percent(60).saturating_reciprocal_mul_floor(<$type>::from(10u8)), + 16, + ); + // round to nearest + assert_eq!( + $name::from_percent(61).saturating_reciprocal_mul(<$type>::from(10u8)), + 16, + ); + // round up + assert_eq!( + $name::from_percent(61).saturating_reciprocal_mul_ceil(<$type>::from(10u8)), + 17, + ); + } + + #[test] + fn saturating_truncating_mul_works() { + assert_eq!( + $name::from_percent(49).mul_floor(10 as $type), + 4, + ); + let a: $upper_type = $name::from_percent(50).mul_floor(($max as $upper_type).pow(2)); + let b: $upper_type = ($max as $upper_type).pow(2) / 2; + if $max % 2 == 0 { + assert_eq!(a, b); + } else { + // difference should be less that 1%, IE less than the error in `from_percent` + assert!(b - a < ($max as $upper_type).pow(2) / 100 as $upper_type); + } + } + + #[test] + fn rational_mul_correction_works() { + assert_eq!( + super::rational_mul_correction::<$type, $name>( + <$type>::max_value(), + <$type>::max_value(), + <$type>::max_value(), + super::Rounding::Nearest, + ), + 0, + ); + assert_eq!( + super::rational_mul_correction::<$type, $name>( + <$type>::max_value() - 1, + <$type>::max_value(), + <$type>::max_value(), + super::Rounding::Nearest, + ), + <$type>::max_value() - 1, + ); + assert_eq!( + super::rational_mul_correction::<$upper_type, $name>( + ((<$type>::max_value() - 1) as $upper_type).pow(2), + <$type>::max_value(), + <$type>::max_value(), + super::Rounding::Nearest, + ), + 1, + ); + // ((max^2 - 1) % max) * max / max == max - 1 + assert_eq!( + super::rational_mul_correction::<$upper_type, $name>( + (<$type>::max_value() as $upper_type).pow(2) - 1, + <$type>::max_value(), + <$type>::max_value(), + super::Rounding::Nearest, + ), + (<$type>::max_value() - 1).into(), + ); + // (max % 2) * max / 2 == max / 2 + assert_eq!( + super::rational_mul_correction::<$upper_type, $name>( + (<$type>::max_value() as $upper_type).pow(2), + <$type>::max_value(), + 2 as $type, + super::Rounding::Nearest, + ), + <$type>::max_value() as $upper_type / 2, + ); + // ((max^2 - 1) % max) * 2 / max == 2 (rounded up) + assert_eq!( + super::rational_mul_correction::<$upper_type, $name>( + (<$type>::max_value() as $upper_type).pow(2) - 1, + 2 as $type, + <$type>::max_value(), + super::Rounding::Nearest, + ), + 2, + ); + // ((max^2 - 1) % max) * 2 / max == 1 (rounded down) + assert_eq!( + super::rational_mul_correction::<$upper_type, $name>( + (<$type>::max_value() as $upper_type).pow(2) - 1, + 2 as $type, + <$type>::max_value(), + super::Rounding::Down, + ), + 1, + ); + } } }; } diff --git a/primitives/arithmetic/src/traits.rs b/primitives/arithmetic/src/traits.rs index 75adf0e136..23f8f23f0b 100644 --- a/primitives/arithmetic/src/traits.rs +++ b/primitives/arithmetic/src/traits.rs @@ -21,7 +21,7 @@ use codec::HasCompact; pub use integer_sqrt::IntegerSquareRoot; pub use num_traits::{ Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, - CheckedShl, CheckedShr + CheckedShl, CheckedShr, checked_pow }; use sp_std::ops::{ Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, @@ -104,29 +104,41 @@ impl + Sized> UniqueSaturatedInto for S { } } -/// Simple trait to use checked mul and max value to give a saturated mul operation over -/// supported types. +/// Saturating arithmetic operations, returning maximum or minimum values instead of overflowing. pub trait Saturating { - /// Saturated addition - if the product can't fit in the type then just use max-value. - fn saturating_add(self, o: Self) -> Self; - - /// Saturated subtraction - if the product can't fit in the type then just use max-value. - fn saturating_sub(self, o: Self) -> Self; - - /// Saturated multiply - if the product can't fit in the type then just use max-value. - fn saturating_mul(self, o: Self) -> Self; + /// Saturating addition. Compute `self + rhs`, saturating at the numeric bounds instead of + /// overflowing. + fn saturating_add(self, rhs: Self) -> Self; + + /// Saturating subtraction. Compute `self - rhs`, saturating at the numeric bounds instead of + /// overflowing. + fn saturating_sub(self, rhs: Self) -> Self; + + /// Saturating multiply. Compute `self * rhs`, saturating at the numeric bounds instead of + /// overflowing. + fn saturating_mul(self, rhs: Self) -> Self; + + /// Saturating exponentiation. Compute `self.pow(exp)`, saturating at the numeric bounds + /// instead of overflowing. + fn saturating_pow(self, exp: usize) -> Self; } -impl Saturating for T { +impl Saturating for T { fn saturating_add(self, o: Self) -> Self { ::saturating_add(self, o) } + fn saturating_sub(self, o: Self) -> Self { ::saturating_sub(self, o) } + fn saturating_mul(self, o: Self) -> Self { self.checked_mul(&o).unwrap_or_else(Bounded::max_value) } + + fn saturating_pow(self, exp: usize) -> Self { + checked_pow(self, exp).unwrap_or_else(Bounded::max_value) + } } /// Convenience type to work around the highly unergonomic syntax needed -- GitLab From 44e2e1d953a4a78ca135ea5a7c9aa2c7df91f792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sun, 29 Mar 2020 14:12:18 +0200 Subject: [PATCH 102/300] Add method to `sc-cli` to reset the `SIGPIPE` signal handler (#5447) The signal handler will be reset to the default system one. This means the program will be exited instead of panicking. This is required to support piping in the console. --- Cargo.lock | 1 + bin/node/cli/src/command.rs | 2 ++ client/cli/Cargo.toml | 3 +++ client/cli/src/lib.rs | 18 ++++++++++++++++++ 4 files changed, 24 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index b0d6c55686..e87be8f0fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5832,6 +5832,7 @@ dependencies = [ "lazy_static", "log 0.4.8", "names", + "nix", "parity-util-mem", "regex", "rpassword", diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index 21584f0898..6e9b5ca575 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -25,6 +25,8 @@ where I: Iterator, T: Into + Clone, { + sc_cli::reset_signal_pipe_handler()?; + let args: Vec<_> = args.collect(); let opt = sc_cli::from_iter::(args.clone(), &version); diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index d623d670ad..7b9313c8d6 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -44,6 +44,9 @@ parity-util-mem = { version = "0.6.0", default-features = false, features = ["pr [target.'cfg(not(target_os = "unknown"))'.dependencies] rpassword = "4.0.1" +[target.'cfg(target_family = "unix")'.dependencies] +nix = "0.17.0" + [dev-dependencies] tempfile = "3.1.0" diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index f94df935a1..18a5991e39 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -221,3 +221,21 @@ fn kill_color(s: &str) -> String { } RE.replace_all(s, "").to_string() } + +/// Reset the signal pipe (`SIGPIPE`) handler to the default one provided by the system. +/// This will end the program on `SIGPIPE` instead of panicking. +/// +/// This should be called before calling any cli method or printing any output. +pub fn reset_signal_pipe_handler() -> Result<()> { + #[cfg(target_family = "unix")] + { + use nix::sys::signal; + + unsafe { + signal::signal(signal::Signal::SIGPIPE, signal::SigHandler::SigDfl) + .map_err(|e| Error::Other(e.to_string()))?; + } + } + + Ok(()) +} -- GitLab From 31352af110e834d86ea301f6df49eb18dac3ee95 Mon Sep 17 00:00:00 2001 From: pscott <30843220+pscott@users.noreply.github.com> Date: Mon, 30 Mar 2020 09:46:30 +0200 Subject: [PATCH 103/300] Build for only one target for docs.rs (#5427) * Add docs.rs metadata to all cargo.toml files * Remove docs.rs metada in substrate's cargo.toml --- .maintain/node-template-release/Cargo.toml | 3 +++ bin/node-template/node/Cargo.toml | 3 +++ bin/node-template/pallets/template/Cargo.toml | 3 +++ bin/node-template/runtime/Cargo.toml | 3 +++ bin/node/cli/Cargo.toml | 3 +++ bin/node/executor/Cargo.toml | 3 +++ bin/node/inspect/Cargo.toml | 3 +++ bin/node/primitives/Cargo.toml | 3 +++ bin/node/rpc-client/Cargo.toml | 3 +++ bin/node/rpc/Cargo.toml | 3 +++ bin/node/runtime/Cargo.toml | 3 +++ bin/node/testing/Cargo.toml | 3 +++ bin/node/transaction-factory/Cargo.toml | 3 +++ bin/utils/chain-spec-builder/Cargo.toml | 3 +++ bin/utils/subkey/Cargo.toml | 3 +++ client/Cargo.toml | 3 +++ client/api/Cargo.toml | 3 +++ client/authority-discovery/Cargo.toml | 3 +++ client/basic-authorship/Cargo.toml | 3 +++ client/block-builder/Cargo.toml | 3 +++ client/chain-spec/Cargo.toml | 3 +++ client/chain-spec/derive/Cargo.toml | 3 +++ client/cli/Cargo.toml | 3 +++ client/consensus/aura/Cargo.toml | 3 +++ client/consensus/babe/Cargo.toml | 3 +++ client/consensus/babe/rpc/Cargo.toml | 3 +++ client/consensus/epochs/Cargo.toml | 3 +++ client/consensus/manual-seal/Cargo.toml | 3 +++ client/consensus/pow/Cargo.toml | 3 +++ client/consensus/slots/Cargo.toml | 3 +++ client/consensus/uncles/Cargo.toml | 3 +++ client/db/Cargo.toml | 3 +++ client/executor/Cargo.toml | 3 +++ client/executor/common/Cargo.toml | 3 +++ client/executor/runtime-test/Cargo.toml | 3 +++ client/executor/wasmi/Cargo.toml | 3 +++ client/executor/wasmtime/Cargo.toml | 3 +++ client/finality-grandpa/Cargo.toml | 3 +++ client/informant/Cargo.toml | 3 +++ client/keystore/Cargo.toml | 3 +++ client/network-gossip/Cargo.toml | 3 +++ client/network/Cargo.toml | 3 +++ client/network/test/Cargo.toml | 3 +++ client/offchain/Cargo.toml | 3 +++ client/peerset/Cargo.toml | 3 +++ client/rpc-api/Cargo.toml | 3 +++ client/rpc-servers/Cargo.toml | 3 +++ client/rpc/Cargo.toml | 3 +++ client/service/Cargo.toml | 3 +++ client/service/test/Cargo.toml | 3 +++ client/state-db/Cargo.toml | 3 +++ client/telemetry/Cargo.toml | 3 +++ client/tracing/Cargo.toml | 3 +++ client/transaction-pool/Cargo.toml | 3 +++ client/transaction-pool/graph/Cargo.toml | 3 +++ frame/assets/Cargo.toml | 3 +++ frame/aura/Cargo.toml | 3 +++ frame/authority-discovery/Cargo.toml | 3 +++ frame/authorship/Cargo.toml | 3 +++ frame/babe/Cargo.toml | 3 +++ frame/balances/Cargo.toml | 3 +++ frame/benchmark/Cargo.toml | 3 +++ frame/benchmarking/Cargo.toml | 3 +++ frame/collective/Cargo.toml | 3 +++ frame/contracts/Cargo.toml | 3 +++ frame/contracts/common/Cargo.toml | 3 +++ frame/contracts/rpc/Cargo.toml | 3 +++ frame/contracts/rpc/runtime-api/Cargo.toml | 3 +++ frame/democracy/Cargo.toml | 3 +++ frame/elections-phragmen/Cargo.toml | 3 +++ frame/elections/Cargo.toml | 3 +++ frame/evm/Cargo.toml | 3 +++ frame/example-offchain-worker/Cargo.toml | 3 +++ frame/example/Cargo.toml | 3 +++ frame/executive/Cargo.toml | 3 +++ frame/finality-tracker/Cargo.toml | 3 +++ frame/generic-asset/Cargo.toml | 3 +++ frame/grandpa/Cargo.toml | 3 +++ frame/identity/Cargo.toml | 3 +++ frame/im-online/Cargo.toml | 3 +++ frame/indices/Cargo.toml | 3 +++ frame/membership/Cargo.toml | 3 +++ frame/metadata/Cargo.toml | 3 +++ frame/nicks/Cargo.toml | 3 +++ frame/offences/Cargo.toml | 3 +++ frame/randomness-collective-flip/Cargo.toml | 3 +++ frame/recovery/Cargo.toml | 3 +++ frame/scored-pool/Cargo.toml | 3 +++ frame/session/Cargo.toml | 3 +++ frame/session/benchmarking/Cargo.toml | 3 +++ frame/society/Cargo.toml | 3 +++ frame/staking/Cargo.toml | 3 +++ frame/staking/fuzz/Cargo.toml | 3 +++ frame/staking/reward-curve/Cargo.toml | 3 +++ frame/sudo/Cargo.toml | 3 +++ frame/support/Cargo.toml | 3 +++ frame/support/procedural/Cargo.toml | 3 +++ frame/support/procedural/tools/Cargo.toml | 3 +++ frame/support/procedural/tools/derive/Cargo.toml | 3 +++ frame/support/test/Cargo.toml | 3 +++ frame/system/Cargo.toml | 3 +++ frame/system/rpc/runtime-api/Cargo.toml | 3 +++ frame/timestamp/Cargo.toml | 3 +++ frame/transaction-payment/Cargo.toml | 3 +++ frame/transaction-payment/rpc/Cargo.toml | 3 +++ frame/transaction-payment/rpc/runtime-api/Cargo.toml | 3 +++ frame/treasury/Cargo.toml | 3 +++ frame/utility/Cargo.toml | 3 +++ frame/vesting/Cargo.toml | 3 +++ primitives/allocator/Cargo.toml | 3 +++ primitives/api/Cargo.toml | 3 +++ primitives/api/proc-macro/Cargo.toml | 3 +++ primitives/api/test/Cargo.toml | 3 +++ primitives/application-crypto/Cargo.toml | 3 +++ primitives/application-crypto/test/Cargo.toml | 3 +++ primitives/arithmetic/Cargo.toml | 3 +++ primitives/arithmetic/fuzzer/Cargo.toml | 3 +++ primitives/authority-discovery/Cargo.toml | 3 +++ primitives/authorship/Cargo.toml | 3 +++ primitives/block-builder/Cargo.toml | 3 +++ primitives/blockchain/Cargo.toml | 3 +++ primitives/consensus/aura/Cargo.toml | 3 +++ primitives/consensus/babe/Cargo.toml | 3 +++ primitives/consensus/common/Cargo.toml | 3 +++ primitives/consensus/pow/Cargo.toml | 3 +++ primitives/consensus/vrf/Cargo.toml | 3 +++ primitives/core/Cargo.toml | 3 +++ primitives/debug-derive/Cargo.toml | 3 +++ primitives/externalities/Cargo.toml | 3 +++ primitives/finality-grandpa/Cargo.toml | 3 +++ primitives/finality-tracker/Cargo.toml | 3 +++ primitives/inherents/Cargo.toml | 3 +++ primitives/io/Cargo.toml | 3 +++ primitives/keyring/Cargo.toml | 3 +++ primitives/offchain/Cargo.toml | 3 +++ primitives/panic-handler/Cargo.toml | 3 +++ primitives/phragmen/Cargo.toml | 3 +++ primitives/phragmen/compact/Cargo.toml | 3 +++ primitives/phragmen/fuzzer/Cargo.toml | 3 +++ primitives/rpc/Cargo.toml | 3 +++ primitives/runtime-interface/Cargo.toml | 3 +++ primitives/runtime-interface/proc-macro/Cargo.toml | 3 +++ primitives/runtime-interface/test-wasm-deprecated/Cargo.toml | 3 +++ primitives/runtime-interface/test-wasm/Cargo.toml | 3 +++ primitives/runtime-interface/test/Cargo.toml | 3 +++ primitives/runtime/Cargo.toml | 3 +++ primitives/sandbox/Cargo.toml | 3 +++ primitives/serializer/Cargo.toml | 3 +++ primitives/session/Cargo.toml | 3 +++ primitives/staking/Cargo.toml | 3 +++ primitives/state-machine/Cargo.toml | 3 +++ primitives/std/Cargo.toml | 3 +++ primitives/storage/Cargo.toml | 3 +++ primitives/test-primitives/Cargo.toml | 3 +++ primitives/timestamp/Cargo.toml | 3 +++ primitives/transaction-pool/Cargo.toml | 3 +++ primitives/trie/Cargo.toml | 3 +++ primitives/version/Cargo.toml | 3 +++ primitives/wasm-interface/Cargo.toml | 3 +++ test-utils/Cargo.toml | 3 +++ test-utils/client/Cargo.toml | 3 +++ test-utils/runtime/Cargo.toml | 3 +++ test-utils/runtime/client/Cargo.toml | 3 +++ test-utils/runtime/transaction-pool/Cargo.toml | 3 +++ utils/browser/Cargo.toml | 3 +++ utils/build-script-utils/Cargo.toml | 3 +++ utils/fork-tree/Cargo.toml | 3 +++ utils/frame/benchmarking-cli/Cargo.toml | 3 +++ utils/frame/rpc/support/Cargo.toml | 3 +++ utils/frame/rpc/system/Cargo.toml | 3 +++ utils/prometheus/Cargo.toml | 3 +++ utils/wasm-builder-runner/Cargo.toml | 3 +++ utils/wasm-builder/Cargo.toml | 3 +++ 173 files changed, 519 insertions(+) diff --git a/.maintain/node-template-release/Cargo.toml b/.maintain/node-template-release/Cargo.toml index 606def19bb..dd3166d58d 100644 --- a/.maintain/node-template-release/Cargo.toml +++ b/.maintain/node-template-release/Cargo.toml @@ -16,3 +16,6 @@ git2 = "0.8" flate2 = "1.0" [workspace] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node-template/node/Cargo.toml b/bin/node-template/node/Cargo.toml index fa2f02d725..b312d31111 100644 --- a/bin/node-template/node/Cargo.toml +++ b/bin/node-template/node/Cargo.toml @@ -39,3 +39,6 @@ node-template-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } [build-dependencies] vergen = "3.0.4" build-script-utils = { version = "2.0.0-alpha.5", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node-template/pallets/template/Cargo.toml b/bin/node-template/pallets/template/Cargo.toml index cda81e5d22..8e53a9a53a 100644 --- a/bin/node-template/pallets/template/Cargo.toml +++ b/bin/node-template/pallets/template/Cargo.toml @@ -45,3 +45,6 @@ std = [ 'safe-mix/std', 'frame-system/std' ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node-template/runtime/Cargo.toml b/bin/node-template/runtime/Cargo.toml index dcd8366f14..e8653e6df7 100644 --- a/bin/node-template/runtime/Cargo.toml +++ b/bin/node-template/runtime/Cargo.toml @@ -68,3 +68,6 @@ std = [ "transaction-payment/std", "template/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index 995dfaef7f..a45ef83076 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -152,3 +152,6 @@ cli = [ "vergen", ] runtime-benchmarks = [ "node-runtime/runtime-benchmarks" ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/executor/Cargo.toml b/bin/node/executor/Cargo.toml index 45a43233c0..2f1060a998 100644 --- a/bin/node/executor/Cargo.toml +++ b/bin/node/executor/Cargo.toml @@ -52,3 +52,6 @@ stress-test = [] [[bench]] name = "bench" harness = false + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/inspect/Cargo.toml b/bin/node/inspect/Cargo.toml index 78186acfa4..9e94fe74d6 100644 --- a/bin/node/inspect/Cargo.toml +++ b/bin/node/inspect/Cargo.toml @@ -18,3 +18,6 @@ sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockch sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } structopt = "0.3.8" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/primitives/Cargo.toml b/bin/node/primitives/Cargo.toml index d4d6d99092..81c5009f39 100644 --- a/bin/node/primitives/Cargo.toml +++ b/bin/node/primitives/Cargo.toml @@ -21,3 +21,6 @@ std = [ "sp-core/std", "sp-runtime/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/rpc-client/Cargo.toml b/bin/node/rpc-client/Cargo.toml index ec6839b71c..07ddbb4d80 100644 --- a/bin/node/rpc-client/Cargo.toml +++ b/bin/node/rpc-client/Cargo.toml @@ -15,3 +15,6 @@ jsonrpc-core-client = { version = "14.0.3", features = ["http", "ws"] } log = "0.4.8" node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } sc-rpc = { version = "2.0.0-alpha.5", path = "../../../client/rpc" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/rpc/Cargo.toml b/bin/node/rpc/Cargo.toml index ada97e5667..f1d230af90 100644 --- a/bin/node/rpc/Cargo.toml +++ b/bin/node/rpc/Cargo.toml @@ -25,3 +25,6 @@ sc-keystore = { version = "2.0.0-alpha.5", path = "../../../client/keystore" } sc-consensus-epochs = { version = "0.8.0-alpha.5", path = "../../../client/consensus/epochs" } sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 6d509966f3..0d61968591 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -151,3 +151,6 @@ runtime-benchmarks = [ "pallet-im-online/runtime-benchmarks", "pallet-democracy/runtime-benchmarks", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index 83d521b272..b16e313574 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -56,3 +56,6 @@ sc-service = { version = "0.8.0-alpha.5", path = "../../../client/service", feat [[bench]] name = "import" harness = false + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/transaction-factory/Cargo.toml b/bin/node/transaction-factory/Cargo.toml index 755dcc5faf..33ebeb767a 100644 --- a/bin/node/transaction-factory/Cargo.toml +++ b/bin/node/transaction-factory/Cargo.toml @@ -21,3 +21,6 @@ sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../../../client/service" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/utils/chain-spec-builder/Cargo.toml b/bin/utils/chain-spec-builder/Cargo.toml index 0cadbe7614..9b03dd17b7 100644 --- a/bin/utils/chain-spec-builder/Cargo.toml +++ b/bin/utils/chain-spec-builder/Cargo.toml @@ -15,3 +15,6 @@ node-cli = { version = "2.0.0-alpha.5", path = "../../node/cli" } sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } rand = "0.7.2" structopt = "0.3.8" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index dab03cd2e5..9bf20146a9 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -34,3 +34,6 @@ serde_json = "1.0" [features] bench = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/Cargo.toml b/client/Cargo.toml index 1dd7f72f66..66ef4da458 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -43,3 +43,6 @@ tempfile = "3.1.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../test-utils/runtime/client" } kvdb-memorydb = "0.5.0" sp-panic-handler = { version = "2.0.0-alpha.5", path = "../primitives/panic-handler" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index 0d13bc1cb5..1d5b0be5e4 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -39,3 +39,6 @@ sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/tran [dev-dependencies] sp-test-primitives = { version = "2.0.0-dev", path = "../../primitives/test-primitives" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 09b4fa8391..3fe4de13e3 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -38,3 +38,6 @@ env_logger = "0.7.0" quickcheck = "0.9.0" sc-peerset = { version = "2.0.0-alpha.5", path = "../peerset" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client"} + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index 97fb8f2c6c..040370ac49 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -29,3 +29,6 @@ futures-timer = "3.0.1" sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../../client/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } parking_lot = "0.10.0" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/block-builder/Cargo.toml b/client/block-builder/Cargo.toml index 376d75ef86..5f9ef7c75e 100644 --- a/client/block-builder/Cargo.toml +++ b/client/block-builder/Cargo.toml @@ -23,3 +23,6 @@ codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive [dev-dependencies] substrate-test-runtime-client = { path = "../../test-utils/runtime/client" } sp-trie = { version = "2.0.0-alpha.5", path = "../../primitives/trie" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/chain-spec/Cargo.toml b/client/chain-spec/Cargo.toml index 2eb172ffee..5d65cbd842 100644 --- a/client/chain-spec/Cargo.toml +++ b/client/chain-spec/Cargo.toml @@ -17,3 +17,6 @@ serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/chain-spec/derive/Cargo.toml b/client/chain-spec/derive/Cargo.toml index f7e57e26f3..9343c9a6de 100644 --- a/client/chain-spec/derive/Cargo.toml +++ b/client/chain-spec/derive/Cargo.toml @@ -18,3 +18,6 @@ quote = "1.0.3" syn = "1.0.7" [dev-dependencies] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 7b9313c8d6..b5d7213e4f 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -54,3 +54,6 @@ tempfile = "3.1.0" wasmtime = [ "sc-service/wasmtime", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/aura/Cargo.toml b/client/consensus/aura/Cargo.toml index 04ed44026f..f0fe368acb 100644 --- a/client/consensus/aura/Cargo.toml +++ b/client/consensus/aura/Cargo.toml @@ -43,3 +43,6 @@ sc-service = { version = "0.8.0-alpha.5", path = "../../service" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } env_logger = "0.7.0" tempfile = "3.1.0" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index e2c7c6efc7..19c5bf9e58 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -59,3 +59,6 @@ tempfile = "3.1.0" [features] test-helpers = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/babe/rpc/Cargo.toml b/client/consensus/babe/rpc/Cargo.toml index 193f7d73fa..feedb84fd5 100644 --- a/client/consensus/babe/rpc/Cargo.toml +++ b/client/consensus/babe/rpc/Cargo.toml @@ -30,3 +30,6 @@ substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../../tes sp-application-crypto = { version = "2.0.0-alpha.5", path = "../../../../primitives/application-crypto" } sp-keyring = { version = "2.0.0-alpha.5", path = "../../../../primitives/keyring" } tempfile = "3.1.0" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/epochs/Cargo.toml b/client/consensus/epochs/Cargo.toml index ff9153299c..3496141ec7 100644 --- a/client/consensus/epochs/Cargo.toml +++ b/client/consensus/epochs/Cargo.toml @@ -15,3 +15,6 @@ fork-tree = { version = "2.0.0-alpha.5", path = "../../../utils/fork-tree" } sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-alpha.5"} sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } sc-client-api = { path = "../../api" , version = "2.0.0-alpha.5"} + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/manual-seal/Cargo.toml b/client/consensus/manual-seal/Cargo.toml index 3bb8016868..b7e5f7b0b1 100644 --- a/client/consensus/manual-seal/Cargo.toml +++ b/client/consensus/manual-seal/Cargo.toml @@ -35,3 +35,6 @@ substrate-test-runtime-transaction-pool = { path = "../../../test-utils/runtime/ tokio = { version = "0.2", features = ["rt-core", "macros"] } env_logger = "0.7.0" tempfile = "3.1.0" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/pow/Cargo.toml b/client/consensus/pow/Cargo.toml index f8ea106d9c..c7832baae0 100644 --- a/client/consensus/pow/Cargo.toml +++ b/client/consensus/pow/Cargo.toml @@ -23,3 +23,6 @@ log = "0.4.8" futures = { version = "0.3.1", features = ["compat"] } sp-timestamp = { version = "2.0.0-alpha.5", path = "../../../primitives/timestamp" } derive_more = "0.99.2" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index 4e388cdec0..bf973ef47a 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -27,3 +27,6 @@ log = "0.4.8" [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/consensus/uncles/Cargo.toml b/client/consensus/uncles/Cargo.toml index 92d36f0bfd..7e8014199b 100644 --- a/client/consensus/uncles/Cargo.toml +++ b/client/consensus/uncles/Cargo.toml @@ -16,3 +16,6 @@ sp-authorship = { version = "2.0.0-alpha.5", path = "../../../primitives/authors sp-consensus = { version = "0.8.0-alpha.5", path = "../../../primitives/consensus/common" } sp-inherents = { version = "2.0.0-alpha.5", path = "../../../primitives/inherents" } log = "0.4.8" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index 6d3389b5f9..9308d4ee74 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -43,3 +43,6 @@ tempfile = "3" [features] default = [] test-helpers = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index e6a43dd685..cae0d56d8e 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -52,3 +52,6 @@ wasmtime = [ wasmi-errno = [ "wasmi/errno" ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/executor/common/Cargo.toml b/client/executor/common/Cargo.toml index ae89524a49..1f52b959d0 100644 --- a/client/executor/common/Cargo.toml +++ b/client/executor/common/Cargo.toml @@ -22,3 +22,6 @@ sp-serializer = { version = "2.0.0-alpha.5", path = "../../../primitives/seriali [features] default = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/executor/runtime-test/Cargo.toml b/client/executor/runtime-test/Cargo.toml index 7b75992234..e50061f4f2 100644 --- a/client/executor/runtime-test/Cargo.toml +++ b/client/executor/runtime-test/Cargo.toml @@ -28,3 +28,6 @@ std = [ "sp-std/std", "sp-allocator/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/executor/wasmi/Cargo.toml b/client/executor/wasmi/Cargo.toml index 600090e90e..ea8637b9e2 100644 --- a/client/executor/wasmi/Cargo.toml +++ b/client/executor/wasmi/Cargo.toml @@ -19,3 +19,6 @@ sp-wasm-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/was sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime-interface" } sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } sp-allocator = { version = "2.0.0-alpha.5", path = "../../../primitives/allocator" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/executor/wasmtime/Cargo.toml b/client/executor/wasmtime/Cargo.toml index 6ca17408ef..11f99e7876 100644 --- a/client/executor/wasmtime/Cargo.toml +++ b/client/executor/wasmtime/Cargo.toml @@ -22,3 +22,6 @@ wasmtime = { package = "substrate-wasmtime", version = "0.13.0-threadsafe.1" } [dev-dependencies] assert_matches = "1.3.0" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index f6be06ba74..6be790dc19 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -52,3 +52,6 @@ env_logger = "0.7.0" tokio = { version = "0.2", features = ["rt-core"] } tempfile = "3.1.0" sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/informant/Cargo.toml b/client/informant/Cargo.toml index 0675a48ac6..b60886d6de 100644 --- a/client/informant/Cargo.toml +++ b/client/informant/Cargo.toml @@ -19,3 +19,6 @@ sc-network = { version = "0.8.0-alpha.5", path = "../network" } sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../service" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/keystore/Cargo.toml b/client/keystore/Cargo.toml index 5b709630ef..af9cdf81bf 100644 --- a/client/keystore/Cargo.toml +++ b/client/keystore/Cargo.toml @@ -22,3 +22,6 @@ parking_lot = "0.10.0" [dev-dependencies] tempfile = "3.1.0" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index e68f0f3f40..153e8103de 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -22,3 +22,6 @@ wasm-timer = "0.2" [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 1d43b72e37..465cb2632f 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -73,3 +73,6 @@ tempfile = "3.1.0" [features] default = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index 0a3fb1e3ea..769e0faca9 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -29,3 +29,6 @@ env_logger = "0.7.0" substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } substrate-test-runtime = { version = "2.0.0-dev", path = "../../../test-utils/runtime" } tempfile = "3.1.0" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index 9e5d69a171..594f21a636 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -42,3 +42,6 @@ tokio = "0.2" [features] default = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 5d4aa28bf2..0ad96c0c6e 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -19,3 +19,6 @@ wasm-timer = "0.2" [dev-dependencies] rand = "0.7.2" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/rpc-api/Cargo.toml b/client/rpc-api/Cargo.toml index 918b54234e..03eed69f38 100644 --- a/client/rpc-api/Cargo.toml +++ b/client/rpc-api/Cargo.toml @@ -25,3 +25,6 @@ serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } sp-rpc = { version = "2.0.0-alpha.5", path = "../../primitives/rpc" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/rpc-servers/Cargo.toml b/client/rpc-servers/Cargo.toml index 5e0feb64c8..c834d7dbf7 100644 --- a/client/rpc-servers/Cargo.toml +++ b/client/rpc-servers/Cargo.toml @@ -19,3 +19,6 @@ sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } [target.'cfg(not(target_os = "unknown"))'.dependencies] http = { package = "jsonrpc-http-server", version = "14.0.3" } ws = { package = "jsonrpc-ws-server", version = "14.0.3" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index d4003d1861..7b06113dda 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -42,3 +42,6 @@ sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } tokio = "0.1.22" sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../transaction-pool" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 2a7869efe5..3811ea079d 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -66,3 +66,6 @@ substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-util sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/babe" } grandpa = { version = "0.8.0-alpha.5", package = "sc-finality-grandpa", path = "../finality-grandpa" } grandpa-primitives = { version = "2.0.0-alpha.5", package = "sp-finality-grandpa", path = "../../primitives/finality-grandpa" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/service/test/Cargo.toml b/client/service/test/Cargo.toml index 401ef8ae04..39c17420bf 100644 --- a/client/service/test/Cargo.toml +++ b/client/service/test/Cargo.toml @@ -23,3 +23,6 @@ sc-client = { version = "0.8.0-alpha.5", path = "../../" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index c4b21bd407..9da3c4e127 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -19,3 +19,6 @@ parity-util-mem-derive = "0.1.0" [dev-dependencies] env_logger = "0.7.0" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index ee7e710c85..bb7e7e5103 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -26,3 +26,6 @@ slog-json = { version = "2.3.0", features = ["nested-values"] } slog-scope = "4.1.2" take_mut = "0.2.2" void = "1.0.2" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/tracing/Cargo.toml b/client/tracing/Cargo.toml index 60a449c687..319526b610 100644 --- a/client/tracing/Cargo.toml +++ b/client/tracing/Cargo.toml @@ -21,3 +21,6 @@ sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } [dev-dependencies] tracing = "0.1.10" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 3528463c7b..4c14ef1139 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -32,3 +32,6 @@ hex = "0.4" sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } substrate-test-runtime-transaction-pool = { version = "2.0.0-dev", path = "../../test-utils/runtime/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index 6de5e68c55..a88ce6a2e4 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -31,3 +31,6 @@ criterion = "0.3" [[bench]] name = "basics" harness = false + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/assets/Cargo.toml b/frame/assets/Cargo.toml index 893e595e71..8b242ff0e8 100644 --- a/frame/assets/Cargo.toml +++ b/frame/assets/Cargo.toml @@ -32,3 +32,6 @@ std = [ "frame-support/std", "frame-system/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/aura/Cargo.toml b/frame/aura/Cargo.toml index 9ea72b23b3..36e7911661 100644 --- a/frame/aura/Cargo.toml +++ b/frame/aura/Cargo.toml @@ -46,3 +46,6 @@ std = [ "sp-timestamp/std", "pallet-timestamp/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/authority-discovery/Cargo.toml b/frame/authority-discovery/Cargo.toml index b6032e93d4..f67d4ee038 100644 --- a/frame/authority-discovery/Cargo.toml +++ b/frame/authority-discovery/Cargo.toml @@ -39,3 +39,6 @@ std = [ "frame-support/std", "frame-system/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/authorship/Cargo.toml b/frame/authorship/Cargo.toml index 05b85ded59..fb966113d5 100644 --- a/frame/authorship/Cargo.toml +++ b/frame/authorship/Cargo.toml @@ -33,3 +33,6 @@ std = [ "sp-io/std", "sp-authorship/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/babe/Cargo.toml b/frame/babe/Cargo.toml index 5b7096b342..8f88550022 100644 --- a/frame/babe/Cargo.toml +++ b/frame/babe/Cargo.toml @@ -45,3 +45,6 @@ std = [ "pallet-session/std", "sp-io/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/balances/Cargo.toml b/frame/balances/Cargo.toml index 73409560b1..f8a59ad154 100644 --- a/frame/balances/Cargo.toml +++ b/frame/balances/Cargo.toml @@ -35,3 +35,6 @@ std = [ "frame-system/std", ] runtime-benchmarks = ["frame-benchmarking"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/benchmark/Cargo.toml b/frame/benchmark/Cargo.toml index ed7f313694..804a283704 100644 --- a/frame/benchmark/Cargo.toml +++ b/frame/benchmark/Cargo.toml @@ -31,3 +31,6 @@ std = [ "frame-benchmarking/std", ] runtime-benchmarks = ["frame-benchmarking"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/benchmarking/Cargo.toml b/frame/benchmarking/Cargo.toml index 481ea3235d..7ed6066419 100644 --- a/frame/benchmarking/Cargo.toml +++ b/frame/benchmarking/Cargo.toml @@ -30,3 +30,6 @@ std = [ "frame-support/std", "frame-system/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/collective/Cargo.toml b/frame/collective/Cargo.toml index f682208380..113705c2c8 100644 --- a/frame/collective/Cargo.toml +++ b/frame/collective/Cargo.toml @@ -40,3 +40,6 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "frame-system/runtime-benchmarks", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/contracts/Cargo.toml b/frame/contracts/Cargo.toml index cde9be3105..a9318002ce 100644 --- a/frame/contracts/Cargo.toml +++ b/frame/contracts/Cargo.toml @@ -48,3 +48,6 @@ std = [ "wasmi-validation/std", "pallet-contracts-primitives/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/contracts/common/Cargo.toml b/frame/contracts/common/Cargo.toml index 9cb136cd43..d181896bd2 100644 --- a/frame/contracts/common/Cargo.toml +++ b/frame/contracts/common/Cargo.toml @@ -21,3 +21,6 @@ std = [ "sp-runtime/std", "sp-std/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/contracts/rpc/Cargo.toml b/frame/contracts/rpc/Cargo.toml index 3b725bf4cb..4414107f2c 100644 --- a/frame/contracts/rpc/Cargo.toml +++ b/frame/contracts/rpc/Cargo.toml @@ -24,3 +24,6 @@ pallet-contracts-rpc-runtime-api = { version = "0.8.0-alpha.5", path = "./runtim [dev-dependencies] serde_json = "1.0.41" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/contracts/rpc/runtime-api/Cargo.toml b/frame/contracts/rpc/runtime-api/Cargo.toml index a3c0790f9f..692bd3f25e 100644 --- a/frame/contracts/rpc/runtime-api/Cargo.toml +++ b/frame/contracts/rpc/runtime-api/Cargo.toml @@ -24,3 +24,6 @@ std = [ "sp-runtime/std", "pallet-contracts-primitives/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/democracy/Cargo.toml b/frame/democracy/Cargo.toml index 6d7e3bd86b..888e23e01b 100644 --- a/frame/democracy/Cargo.toml +++ b/frame/democracy/Cargo.toml @@ -41,3 +41,6 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index fec2c4078a..3cada4dcd3 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -35,3 +35,6 @@ std = [ "sp-std/std", ] runtime-benchmarks = ["frame-support/runtime-benchmarks"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/elections/Cargo.toml b/frame/elections/Cargo.toml index c86039a68b..6043ac4681 100644 --- a/frame/elections/Cargo.toml +++ b/frame/elections/Cargo.toml @@ -34,3 +34,6 @@ std = [ "sp-runtime/std", "frame-system/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml index bcb7b3ac5e..95b3c24d87 100644 --- a/frame/evm/Cargo.toml +++ b/frame/evm/Cargo.toml @@ -42,3 +42,6 @@ std = [ "evm/std", "pallet-timestamp/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/example-offchain-worker/Cargo.toml b/frame/example-offchain-worker/Cargo.toml index 53e6e5f054..6b3452d018 100644 --- a/frame/example-offchain-worker/Cargo.toml +++ b/frame/example-offchain-worker/Cargo.toml @@ -32,3 +32,6 @@ std = [ "sp-runtime/std", "sp-std/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/example/Cargo.toml b/frame/example/Cargo.toml index 90435dcd7e..014bcc91d4 100644 --- a/frame/example/Cargo.toml +++ b/frame/example/Cargo.toml @@ -35,3 +35,6 @@ std = [ "sp-io/std", "sp-std/std" ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/executive/Cargo.toml b/frame/executive/Cargo.toml index 15c4d02aa2..3c494199cb 100644 --- a/frame/executive/Cargo.toml +++ b/frame/executive/Cargo.toml @@ -35,3 +35,6 @@ std = [ "sp-runtime/std", "sp-std/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/finality-tracker/Cargo.toml b/frame/finality-tracker/Cargo.toml index a8c1587e53..e261fae05f 100644 --- a/frame/finality-tracker/Cargo.toml +++ b/frame/finality-tracker/Cargo.toml @@ -37,3 +37,6 @@ std = [ "sp-finality-tracker/std", "sp-inherents/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/generic-asset/Cargo.toml b/frame/generic-asset/Cargo.toml index fe5160ea27..b531a0ed9a 100644 --- a/frame/generic-asset/Cargo.toml +++ b/frame/generic-asset/Cargo.toml @@ -30,3 +30,6 @@ std =[ "frame-support/std", "frame-system/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/grandpa/Cargo.toml b/frame/grandpa/Cargo.toml index f57cb319f2..206b563bd9 100644 --- a/frame/grandpa/Cargo.toml +++ b/frame/grandpa/Cargo.toml @@ -39,3 +39,6 @@ std = [ "pallet-session/std", "pallet-finality-tracker/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/identity/Cargo.toml b/frame/identity/Cargo.toml index 9430ff53fc..22b385d06d 100644 --- a/frame/identity/Cargo.toml +++ b/frame/identity/Cargo.toml @@ -36,3 +36,6 @@ std = [ "frame-system/std", ] runtime-benchmarks = ["frame-benchmarking"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/im-online/Cargo.toml b/frame/im-online/Cargo.toml index e5258f6918..dabcc45ef1 100644 --- a/frame/im-online/Cargo.toml +++ b/frame/im-online/Cargo.toml @@ -41,3 +41,6 @@ std = [ "frame-system/std", ] runtime-benchmarks = ["frame-benchmarking"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/indices/Cargo.toml b/frame/indices/Cargo.toml index c6070545ec..f28f393642 100644 --- a/frame/indices/Cargo.toml +++ b/frame/indices/Cargo.toml @@ -35,3 +35,6 @@ std = [ "sp-runtime/std", "frame-system/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/membership/Cargo.toml b/frame/membership/Cargo.toml index ef3abfbbf6..41e56b584f 100644 --- a/frame/membership/Cargo.toml +++ b/frame/membership/Cargo.toml @@ -31,3 +31,6 @@ std = [ "frame-support/std", "frame-system/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/metadata/Cargo.toml b/frame/metadata/Cargo.toml index ce68d3bc31..f965e1dddc 100644 --- a/frame/metadata/Cargo.toml +++ b/frame/metadata/Cargo.toml @@ -22,3 +22,6 @@ std = [ "sp-core/std", "serde", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/nicks/Cargo.toml b/frame/nicks/Cargo.toml index 76bc183ca3..ea88021d25 100644 --- a/frame/nicks/Cargo.toml +++ b/frame/nicks/Cargo.toml @@ -32,3 +32,6 @@ std = [ "frame-support/std", "frame-system/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/offences/Cargo.toml b/frame/offences/Cargo.toml index 28dba9fc55..b858c03ba5 100644 --- a/frame/offences/Cargo.toml +++ b/frame/offences/Cargo.toml @@ -34,3 +34,6 @@ std = [ "frame-support/std", "frame-system/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/randomness-collective-flip/Cargo.toml b/frame/randomness-collective-flip/Cargo.toml index ac6cb08ee8..acd1c21688 100644 --- a/frame/randomness-collective-flip/Cargo.toml +++ b/frame/randomness-collective-flip/Cargo.toml @@ -30,3 +30,6 @@ std = [ "sp-runtime/std", "sp-std/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/recovery/Cargo.toml b/frame/recovery/Cargo.toml index 4ac5e45471..3347014f6e 100644 --- a/frame/recovery/Cargo.toml +++ b/frame/recovery/Cargo.toml @@ -33,3 +33,6 @@ std = [ "frame-support/std", "frame-system/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/scored-pool/Cargo.toml b/frame/scored-pool/Cargo.toml index 711bfd4c09..b878c5bb47 100644 --- a/frame/scored-pool/Cargo.toml +++ b/frame/scored-pool/Cargo.toml @@ -32,3 +32,6 @@ std = [ "frame-support/std", "frame-system/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/session/Cargo.toml b/frame/session/Cargo.toml index e22708387c..f12a8b4a71 100644 --- a/frame/session/Cargo.toml +++ b/frame/session/Cargo.toml @@ -40,3 +40,6 @@ std = [ "sp-trie/std", "sp-io/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/session/benchmarking/Cargo.toml b/frame/session/benchmarking/Cargo.toml index 434a9e1ec5..181fb37bfd 100644 --- a/frame/session/benchmarking/Cargo.toml +++ b/frame/session/benchmarking/Cargo.toml @@ -26,3 +26,6 @@ std = [ "pallet-staking/std", "pallet-session/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/society/Cargo.toml b/frame/society/Cargo.toml index b0734e54d4..be419fb63f 100644 --- a/frame/society/Cargo.toml +++ b/frame/society/Cargo.toml @@ -38,3 +38,6 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "frame-system/runtime-benchmarks", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index 953859f97b..228b7b60f8 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -71,3 +71,6 @@ runtime-benchmarks = [ "rand_chacha", "frame-benchmarking", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/staking/fuzz/Cargo.toml b/frame/staking/fuzz/Cargo.toml index 12fc919530..a78fbf17dc 100644 --- a/frame/staking/fuzz/Cargo.toml +++ b/frame/staking/fuzz/Cargo.toml @@ -33,3 +33,6 @@ members = ["."] [[bin]] name = "submit_solution" path = "fuzz_targets/submit_solution.rs" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/staking/reward-curve/Cargo.toml b/frame/staking/reward-curve/Cargo.toml index 1f3fd436fa..b3b749e96c 100644 --- a/frame/staking/reward-curve/Cargo.toml +++ b/frame/staking/reward-curve/Cargo.toml @@ -19,3 +19,6 @@ proc-macro-crate = "0.1.4" [dev-dependencies] sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/sudo/Cargo.toml b/frame/sudo/Cargo.toml index c11d681013..4216b94ec1 100644 --- a/frame/sudo/Cargo.toml +++ b/frame/sudo/Cargo.toml @@ -31,3 +31,6 @@ std = [ "frame-support/std", "frame-system/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index 2ea985fa70..3bad72a115 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -50,3 +50,6 @@ std = [ nightly = [] strict = [] runtime-benchmarks = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/support/procedural/Cargo.toml b/frame/support/procedural/Cargo.toml index 8befc50cd7..2f7450e4b8 100644 --- a/frame/support/procedural/Cargo.toml +++ b/frame/support/procedural/Cargo.toml @@ -16,3 +16,6 @@ frame-support-procedural-tools = { version = "2.0.0-alpha.5", path = "./tools" } proc-macro2 = "1.0.6" quote = "1.0.3" syn = { version = "1.0.7", features = ["full"] } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/support/procedural/tools/Cargo.toml b/frame/support/procedural/tools/Cargo.toml index ab24e371d3..f199f1245d 100644 --- a/frame/support/procedural/tools/Cargo.toml +++ b/frame/support/procedural/tools/Cargo.toml @@ -14,3 +14,6 @@ proc-macro2 = "1.0.6" quote = "1.0.3" syn = { version = "1.0.7", features = ["full", "visit"] } proc-macro-crate = "0.1.4" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/support/procedural/tools/derive/Cargo.toml b/frame/support/procedural/tools/derive/Cargo.toml index 39ac99e4fd..bf6346ab1b 100644 --- a/frame/support/procedural/tools/derive/Cargo.toml +++ b/frame/support/procedural/tools/derive/Cargo.toml @@ -15,3 +15,6 @@ proc-macro = true proc-macro2 = "1.0.6" quote = { version = "1.0.3", features = ["proc-macro"] } syn = { version = "1.0.7", features = ["proc-macro" ,"full", "extra-traits", "parsing"] } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index a1edf70f61..773523579b 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -32,3 +32,6 @@ std = [ "sp-runtime/std", "sp-state-machine", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/system/Cargo.toml b/frame/system/Cargo.toml index 77c1b36407..78288cff91 100644 --- a/frame/system/Cargo.toml +++ b/frame/system/Cargo.toml @@ -41,3 +41,6 @@ runtime-benchmarks = ["sp-runtime/runtime-benchmarks"] [[bench]] name = "bench" harness = false + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/system/rpc/runtime-api/Cargo.toml b/frame/system/rpc/runtime-api/Cargo.toml index bdd1c3ad83..9519427297 100644 --- a/frame/system/rpc/runtime-api/Cargo.toml +++ b/frame/system/rpc/runtime-api/Cargo.toml @@ -18,3 +18,6 @@ std = [ "sp-api/std", "codec/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/timestamp/Cargo.toml b/frame/timestamp/Cargo.toml index ef9d3f3f2d..eb7358e197 100644 --- a/frame/timestamp/Cargo.toml +++ b/frame/timestamp/Cargo.toml @@ -41,3 +41,6 @@ std = [ "sp-timestamp/std" ] runtime-benchmarks = ["frame-benchmarking", "sp-io"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/transaction-payment/Cargo.toml b/frame/transaction-payment/Cargo.toml index a26e18edd3..811c2885b1 100644 --- a/frame/transaction-payment/Cargo.toml +++ b/frame/transaction-payment/Cargo.toml @@ -31,3 +31,6 @@ std = [ "frame-system/std", "pallet-transaction-payment-rpc-runtime-api/std" ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/transaction-payment/rpc/Cargo.toml b/frame/transaction-payment/rpc/Cargo.toml index a5bf10b713..3dec060fb4 100644 --- a/frame/transaction-payment/rpc/Cargo.toml +++ b/frame/transaction-payment/rpc/Cargo.toml @@ -20,3 +20,6 @@ sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } sp-api = { version = "2.0.0-alpha.5", path = "../../../primitives/api" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-alpha.5", path = "./runtime-api" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/transaction-payment/rpc/runtime-api/Cargo.toml b/frame/transaction-payment/rpc/runtime-api/Cargo.toml index 646d3ae81b..447590111c 100644 --- a/frame/transaction-payment/rpc/runtime-api/Cargo.toml +++ b/frame/transaction-payment/rpc/runtime-api/Cargo.toml @@ -29,3 +29,6 @@ std = [ "sp-runtime/std", "frame-support/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/treasury/Cargo.toml b/frame/treasury/Cargo.toml index 4d761a28cc..6951c0eba9 100644 --- a/frame/treasury/Cargo.toml +++ b/frame/treasury/Cargo.toml @@ -38,3 +38,6 @@ runtime-benchmarks = [ "frame-benchmarking", "frame-support/runtime-benchmarks", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/utility/Cargo.toml b/frame/utility/Cargo.toml index fb7bd00978..173f60a2e5 100644 --- a/frame/utility/Cargo.toml +++ b/frame/utility/Cargo.toml @@ -33,3 +33,6 @@ std = [ "sp-io/std", "sp-std/std" ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/vesting/Cargo.toml b/frame/vesting/Cargo.toml index 767ec3c14d..e40062706f 100644 --- a/frame/vesting/Cargo.toml +++ b/frame/vesting/Cargo.toml @@ -37,3 +37,6 @@ std = [ "frame-system/std", ] runtime-benchmarks = ["frame-benchmarking"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/allocator/Cargo.toml b/primitives/allocator/Cargo.toml index eee82771d6..635a3c9128 100644 --- a/primitives/allocator/Cargo.toml +++ b/primitives/allocator/Cargo.toml @@ -25,3 +25,6 @@ std = [ "log", "derive_more", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/api/Cargo.toml b/primitives/api/Cargo.toml index bb71d89d11..fedeeceb3f 100644 --- a/primitives/api/Cargo.toml +++ b/primitives/api/Cargo.toml @@ -32,3 +32,6 @@ std = [ "sp-version/std", "hash-db", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/api/proc-macro/Cargo.toml b/primitives/api/proc-macro/Cargo.toml index 841da78832..25c5ae1343 100644 --- a/primitives/api/proc-macro/Cargo.toml +++ b/primitives/api/proc-macro/Cargo.toml @@ -24,3 +24,6 @@ proc-macro-crate = "0.1.4" [features] default = [ "std" ] std = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/api/test/Cargo.toml b/primitives/api/test/Cargo.toml index 299c86a7e3..f2e66afc24 100644 --- a/primitives/api/test/Cargo.toml +++ b/primitives/api/test/Cargo.toml @@ -34,3 +34,6 @@ harness = false [features] default = [ "std" ] std = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/application-crypto/Cargo.toml b/primitives/application-crypto/Cargo.toml index b0df978273..7c3fb53579 100644 --- a/primitives/application-crypto/Cargo.toml +++ b/primitives/application-crypto/Cargo.toml @@ -31,3 +31,6 @@ full_crypto = [ "sp-io/disable_panic_handler", "sp-io/disable_oom", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/application-crypto/test/Cargo.toml b/primitives/application-crypto/test/Cargo.toml index fae91e6783..d34840b4eb 100644 --- a/primitives/application-crypto/test/Cargo.toml +++ b/primitives/application-crypto/test/Cargo.toml @@ -15,3 +15,6 @@ substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-u sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } sp-api = { version = "2.0.0-alpha.5", path = "../../api" } sp-application-crypto = { version = "2.0.0-alpha.5", path = "../" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/arithmetic/Cargo.toml b/primitives/arithmetic/Cargo.toml index f4a7236223..208525f6c1 100644 --- a/primitives/arithmetic/Cargo.toml +++ b/primitives/arithmetic/Cargo.toml @@ -36,3 +36,6 @@ std = [ [[bench]] name = "bench" harness = false + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/arithmetic/fuzzer/Cargo.toml b/primitives/arithmetic/fuzzer/Cargo.toml index 717ce2713b..26b5f8c27b 100644 --- a/primitives/arithmetic/fuzzer/Cargo.toml +++ b/primitives/arithmetic/fuzzer/Cargo.toml @@ -27,3 +27,6 @@ path = "src/per_thing_rational.rs" [[bin]] name = "rational128" path = "src/rational128.rs" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/authority-discovery/Cargo.toml b/primitives/authority-discovery/Cargo.toml index a6cea0c51c..f37b67fab1 100644 --- a/primitives/authority-discovery/Cargo.toml +++ b/primitives/authority-discovery/Cargo.toml @@ -24,3 +24,6 @@ std = [ "sp-api/std", "sp-runtime/std" ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/authorship/Cargo.toml b/primitives/authorship/Cargo.toml index eb319775d5..a4d5aa03c2 100644 --- a/primitives/authorship/Cargo.toml +++ b/primitives/authorship/Cargo.toml @@ -22,3 +22,6 @@ std = [ "sp-inherents/std", "sp-runtime/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/block-builder/Cargo.toml b/primitives/block-builder/Cargo.toml index 9a26789253..df33b2c955 100644 --- a/primitives/block-builder/Cargo.toml +++ b/primitives/block-builder/Cargo.toml @@ -24,3 +24,6 @@ std = [ "sp-api/std", "sp-std/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/blockchain/Cargo.toml b/primitives/blockchain/Cargo.toml index f47f7a6a51..49e6baead1 100644 --- a/primitives/blockchain/Cargo.toml +++ b/primitives/blockchain/Cargo.toml @@ -20,3 +20,6 @@ sp-consensus = { version = "0.8.0-alpha.5", path = "../consensus/common" } sp-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } sp-block-builder = { version = "2.0.0-alpha.5", path = "../block-builder" } sp-state-machine = { version = "0.8.0-alpha.5", path = "../state-machine" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/consensus/aura/Cargo.toml b/primitives/consensus/aura/Cargo.toml index fb29ac49b7..99ce51a229 100644 --- a/primitives/consensus/aura/Cargo.toml +++ b/primitives/consensus/aura/Cargo.toml @@ -28,3 +28,6 @@ std = [ "sp-inherents/std", "sp-timestamp/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/consensus/babe/Cargo.toml b/primitives/consensus/babe/Cargo.toml index cb64925ef5..195a54a591 100644 --- a/primitives/consensus/babe/Cargo.toml +++ b/primitives/consensus/babe/Cargo.toml @@ -32,3 +32,6 @@ std = [ "sp-runtime/std", "sp-timestamp/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 49c1df0bb7..d942d7975a 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -32,3 +32,6 @@ sp-test-primitives = { version = "2.0.0-dev", path = "../../test-primitives" } [features] default = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/consensus/pow/Cargo.toml b/primitives/consensus/pow/Cargo.toml index 14232a506b..5ca60bb215 100644 --- a/primitives/consensus/pow/Cargo.toml +++ b/primitives/consensus/pow/Cargo.toml @@ -24,3 +24,6 @@ std = [ "sp-core/std", "codec/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/consensus/vrf/Cargo.toml b/primitives/consensus/vrf/Cargo.toml index 8fedd3f0e1..cf194ec38b 100644 --- a/primitives/consensus/vrf/Cargo.toml +++ b/primitives/consensus/vrf/Cargo.toml @@ -24,3 +24,6 @@ std = [ "sp-core/std", "sp-runtime/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 4dbbf85e17..7708188ea4 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -119,3 +119,6 @@ full_crypto = [ "libsecp256k1", "sp-runtime-interface/disable_target_static_assertions", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/debug-derive/Cargo.toml b/primitives/debug-derive/Cargo.toml index 83db220461..0079b6219f 100644 --- a/primitives/debug-derive/Cargo.toml +++ b/primitives/debug-derive/Cargo.toml @@ -22,3 +22,6 @@ std = [] [dev-dependencies] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/externalities/Cargo.toml b/primitives/externalities/Cargo.toml index 3eed98bd6e..af6e516fbf 100644 --- a/primitives/externalities/Cargo.toml +++ b/primitives/externalities/Cargo.toml @@ -13,3 +13,6 @@ documentation = "https://docs.rs/sp-externalities" sp-storage = { version = "2.0.0-alpha.5", path = "../storage" } sp-std = { version = "2.0.0-alpha.5", path = "../std" } environmental = { version = "1.1.1" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/finality-grandpa/Cargo.toml b/primitives/finality-grandpa/Cargo.toml index 17219d9d10..0595fa7ba7 100644 --- a/primitives/finality-grandpa/Cargo.toml +++ b/primitives/finality-grandpa/Cargo.toml @@ -28,3 +28,6 @@ std = [ "sp-api/std", "sp-runtime/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/finality-tracker/Cargo.toml b/primitives/finality-tracker/Cargo.toml index 26efb61c2c..4e6cf6c92d 100644 --- a/primitives/finality-tracker/Cargo.toml +++ b/primitives/finality-tracker/Cargo.toml @@ -20,3 +20,6 @@ std = [ "sp-std/std", "sp-inherents/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/inherents/Cargo.toml b/primitives/inherents/Cargo.toml index 05ef38b238..dd640f00ec 100644 --- a/primitives/inherents/Cargo.toml +++ b/primitives/inherents/Cargo.toml @@ -26,3 +26,6 @@ std = [ "sp-core/std", "derive_more", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index 2cd2c00006..9cda2120cc 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -46,3 +46,6 @@ std = [ disable_panic_handler = [] disable_oom = [] disable_allocator = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/keyring/Cargo.toml b/primitives/keyring/Cargo.toml index 29c0a35a54..0764146250 100644 --- a/primitives/keyring/Cargo.toml +++ b/primitives/keyring/Cargo.toml @@ -15,3 +15,6 @@ sp-core = { version = "2.0.0-alpha.5", path = "../core" } sp-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } lazy_static = "1.4.0" strum = { version = "0.16.0", features = ["derive"] } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/offchain/Cargo.toml b/primitives/offchain/Cargo.toml index a92f7e20c4..66febccd59 100644 --- a/primitives/offchain/Cargo.toml +++ b/primitives/offchain/Cargo.toml @@ -18,3 +18,6 @@ std = [ "sp-api/std", "sp-runtime/std" ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/panic-handler/Cargo.toml b/primitives/panic-handler/Cargo.toml index e16cc5dc76..169443f6c4 100644 --- a/primitives/panic-handler/Cargo.toml +++ b/primitives/panic-handler/Cargo.toml @@ -12,3 +12,6 @@ documentation = "https://docs.rs/sp-panic-handler" [dependencies] backtrace = "0.3.38" log = "0.4.8" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/phragmen/Cargo.toml b/primitives/phragmen/Cargo.toml index 088466d9fb..f5d26e8a40 100644 --- a/primitives/phragmen/Cargo.toml +++ b/primitives/phragmen/Cargo.toml @@ -29,3 +29,6 @@ std = [ "sp-std/std", "sp-runtime/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/phragmen/compact/Cargo.toml b/primitives/phragmen/compact/Cargo.toml index fb61a90b09..56b4520c54 100644 --- a/primitives/phragmen/compact/Cargo.toml +++ b/primitives/phragmen/compact/Cargo.toml @@ -16,3 +16,6 @@ syn = { version = "1.0.7", features = ["full", "visit"] } quote = "1.0" proc-macro2 = "1.0.6" proc-macro-crate = "0.1.4" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/phragmen/fuzzer/Cargo.toml b/primitives/phragmen/fuzzer/Cargo.toml index 645b1c151b..90af69a707 100644 --- a/primitives/phragmen/fuzzer/Cargo.toml +++ b/primitives/phragmen/fuzzer/Cargo.toml @@ -14,3 +14,6 @@ rand = "0.7.3" [[bin]] name = "reduce" path = "src/reduce.rs" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/rpc/Cargo.toml b/primitives/rpc/Cargo.toml index 5631f7a891..a7975fb475 100644 --- a/primitives/rpc/Cargo.toml +++ b/primitives/rpc/Cargo.toml @@ -14,3 +14,6 @@ sp-core = { version = "2.0.0-alpha.5", path = "../core" } [dev-dependencies] serde_json = "1.0.41" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 647d0fb49d..01f7f2f19c 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -43,3 +43,6 @@ std = [ # Disables static assertions in `impls.rs` that checks the word size. To prevent any footgun, the # check is changed into a runtime check. disable_target_static_assertions = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/runtime-interface/proc-macro/Cargo.toml b/primitives/runtime-interface/proc-macro/Cargo.toml index c8c12b9bdb..6d0b7ee5fb 100644 --- a/primitives/runtime-interface/proc-macro/Cargo.toml +++ b/primitives/runtime-interface/proc-macro/Cargo.toml @@ -18,3 +18,6 @@ quote = "1.0.3" proc-macro2 = "1.0.3" Inflector = "0.11.4" proc-macro-crate = "0.1.4" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml index b91a304c72..6f2d66bd77 100644 --- a/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml +++ b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml @@ -21,3 +21,6 @@ wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-run [features] default = [ "std" ] std = [ "sp-runtime-interface/std", "sp-std/std", "sp-core/std", "sp-io/std" ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/runtime-interface/test-wasm/Cargo.toml b/primitives/runtime-interface/test-wasm/Cargo.toml index cf72a10749..4eb4f01c9f 100644 --- a/primitives/runtime-interface/test-wasm/Cargo.toml +++ b/primitives/runtime-interface/test-wasm/Cargo.toml @@ -21,3 +21,6 @@ wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-run [features] default = [ "std" ] std = [ "sp-runtime-interface/std", "sp-std/std", "sp-core/std", "sp-io/std" ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/runtime-interface/test/Cargo.toml b/primitives/runtime-interface/test/Cargo.toml index 18cff357d8..f3bee038c8 100644 --- a/primitives/runtime-interface/test/Cargo.toml +++ b/primitives/runtime-interface/test/Cargo.toml @@ -16,3 +16,6 @@ sp-runtime-interface-test-wasm-deprecated = { version = "2.0.0-dev", path = "../ sp-state-machine = { version = "0.8.0-alpha.5", path = "../../../primitives/state-machine" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } sp-io = { version = "2.0.0-alpha.5", path = "../../io" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index c0d31e2c35..0e71e8becd 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -48,3 +48,6 @@ std = [ "parity-util-mem/std", "hash256-std-hasher/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/sandbox/Cargo.toml b/primitives/sandbox/Cargo.toml index 881961dbd1..5c1595027f 100755 --- a/primitives/sandbox/Cargo.toml +++ b/primitives/sandbox/Cargo.toml @@ -31,3 +31,6 @@ std = [ "sp-wasm-interface/std", ] strict = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/serializer/Cargo.toml b/primitives/serializer/Cargo.toml index 355fe596de..75263321b8 100644 --- a/primitives/serializer/Cargo.toml +++ b/primitives/serializer/Cargo.toml @@ -12,3 +12,6 @@ documentation = "https://docs.rs/sp-serializer" [dependencies] serde = "1.0.101" serde_json = "1.0.41" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/session/Cargo.toml b/primitives/session/Cargo.toml index 0a10107f98..ffe1bc327f 100644 --- a/primitives/session/Cargo.toml +++ b/primitives/session/Cargo.toml @@ -17,3 +17,6 @@ sp-runtime = { version = "2.0.0-alpha.5", optional = true, path = "../runtime" } [features] default = [ "std" ] std = [ "sp-api/std", "sp-std/std", "sp-runtime", "sp-core/std" ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/staking/Cargo.toml b/primitives/staking/Cargo.toml index ef2c93c099..60bf3f759e 100644 --- a/primitives/staking/Cargo.toml +++ b/primitives/staking/Cargo.toml @@ -20,3 +20,6 @@ std = [ "sp-runtime/std", "sp-std/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/state-machine/Cargo.toml b/primitives/state-machine/Cargo.toml index 5d4461018d..548f3f4308 100644 --- a/primitives/state-machine/Cargo.toml +++ b/primitives/state-machine/Cargo.toml @@ -29,3 +29,6 @@ sp-runtime = { version = "2.0.0-alpha.5", path = "../runtime" } [features] default = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/std/Cargo.toml b/primitives/std/Cargo.toml index e33b9d88aa..58ff78f2bb 100644 --- a/primitives/std/Cargo.toml +++ b/primitives/std/Cargo.toml @@ -13,3 +13,6 @@ documentation = "https://docs.rs/sp-std" [features] default = ["std"] std = [] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/storage/Cargo.toml b/primitives/storage/Cargo.toml index fa06f0cc24..e4e842848d 100644 --- a/primitives/storage/Cargo.toml +++ b/primitives/storage/Cargo.toml @@ -18,3 +18,6 @@ sp-debug-derive = { version = "2.0.0-alpha.5", path = "../debug-derive" } [features] default = [ "std" ] std = [ "sp-std/std", "serde", "impl-serde" ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/test-primitives/Cargo.toml b/primitives/test-primitives/Cargo.toml index 6938189550..b8cb583835 100644 --- a/primitives/test-primitives/Cargo.toml +++ b/primitives/test-primitives/Cargo.toml @@ -24,3 +24,6 @@ std = [ "sp-application-crypto/std", "serde", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/timestamp/Cargo.toml b/primitives/timestamp/Cargo.toml index 4948fa4bf5..4a0851ccb1 100644 --- a/primitives/timestamp/Cargo.toml +++ b/primitives/timestamp/Cargo.toml @@ -26,3 +26,6 @@ std = [ "codec/std", "sp-inherents/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/transaction-pool/Cargo.toml b/primitives/transaction-pool/Cargo.toml index e0281c9571..003212613e 100644 --- a/primitives/transaction-pool/Cargo.toml +++ b/primitives/transaction-pool/Cargo.toml @@ -30,3 +30,6 @@ std = [ "sp-api/std", "sp-runtime/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/trie/Cargo.toml b/primitives/trie/Cargo.toml index 6b976671b2..3876f46526 100644 --- a/primitives/trie/Cargo.toml +++ b/primitives/trie/Cargo.toml @@ -40,3 +40,6 @@ std = [ "trie-root/std", "sp-core/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/version/Cargo.toml b/primitives/version/Cargo.toml index 01c66c6511..726d064642 100644 --- a/primitives/version/Cargo.toml +++ b/primitives/version/Cargo.toml @@ -26,3 +26,6 @@ std = [ "sp-std/std", "sp-runtime/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/wasm-interface/Cargo.toml b/primitives/wasm-interface/Cargo.toml index 5e97f8f36a..4a35d5b518 100644 --- a/primitives/wasm-interface/Cargo.toml +++ b/primitives/wasm-interface/Cargo.toml @@ -18,3 +18,6 @@ codec = { package = "parity-scale-codec", version = "1.3.0", default-features = [features] default = [ "std" ] std = [ "wasmi", "sp-std/std", "codec/std" ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml index 4584c37910..b8c9f9bd60 100644 --- a/test-utils/Cargo.toml +++ b/test-utils/Cargo.toml @@ -6,3 +6,6 @@ edition = "2018" license = "GPL-3.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/test-utils/client/Cargo.toml b/test-utils/client/Cargo.toml index 26a9a0b7c9..ec87e7cd16 100644 --- a/test-utils/client/Cargo.toml +++ b/test-utils/client/Cargo.toml @@ -22,3 +22,6 @@ sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index c6ae0ee2de..be22747ea6 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -87,3 +87,6 @@ std = [ "sp-transaction-pool/std", "trie-db/std", ] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/test-utils/runtime/client/Cargo.toml b/test-utils/runtime/client/Cargo.toml index cf47c505c6..4be45fe466 100644 --- a/test-utils/runtime/client/Cargo.toml +++ b/test-utils/runtime/client/Cargo.toml @@ -20,3 +20,6 @@ codec = { package = "parity-scale-codec", version = "1.3.0" } sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api" } sc-client = { version = "0.8.0-alpha.5", path = "../../../client/" } futures = "0.3.4" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/test-utils/runtime/transaction-pool/Cargo.toml b/test-utils/runtime/transaction-pool/Cargo.toml index 8493ec0077..52e2020dc8 100644 --- a/test-utils/runtime/transaction-pool/Cargo.toml +++ b/test-utils/runtime/transaction-pool/Cargo.toml @@ -18,3 +18,6 @@ sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/t sc-transaction-graph = { version = "2.0.0-alpha.5", path = "../../../client/transaction-pool/graph" } futures = { version = "0.3.1", features = ["compat"] } derive_more = "0.99.2" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 4e0a6ac7d1..188f46bf19 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -31,3 +31,6 @@ rand6 = { package = "rand", version = "0.6", features = ["wasm-bindgen"] } rand = { version = "0.7", features = ["wasm-bindgen"] } futures-timer = { version = "3.0.1", features = ["wasm-bindgen"]} chrono = { version = "0.4", features = ["wasmbind"] } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/build-script-utils/Cargo.toml b/utils/build-script-utils/Cargo.toml index c5862a40ee..3fe10f6a82 100644 --- a/utils/build-script-utils/Cargo.toml +++ b/utils/build-script-utils/Cargo.toml @@ -9,3 +9,6 @@ repository = "https://github.com/paritytech/substrate/" description = "Crate with utility functions for `build.rs` scripts." [dependencies] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/fork-tree/Cargo.toml b/utils/fork-tree/Cargo.toml index 667bec06ac..e46618feb8 100644 --- a/utils/fork-tree/Cargo.toml +++ b/utils/fork-tree/Cargo.toml @@ -11,3 +11,6 @@ documentation = "https://docs.rs/fork-tree" [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/frame/benchmarking-cli/Cargo.toml b/utils/frame/benchmarking-cli/Cargo.toml index 8b3e5b03d9..f4b7218747 100644 --- a/utils/frame/benchmarking-cli/Cargo.toml +++ b/utils/frame/benchmarking-cli/Cargo.toml @@ -25,3 +25,6 @@ codec = { version = "1.3.0", package = "parity-scale-codec" } [features] default = ["rocksdb"] rocksdb = ["sc-client-db/kvdb-rocksdb"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/frame/rpc/support/Cargo.toml b/utils/frame/rpc/support/Cargo.toml index 4de85524e7..002fc1dd7a 100644 --- a/utils/frame/rpc/support/Cargo.toml +++ b/utils/frame/rpc/support/Cargo.toml @@ -21,3 +21,6 @@ sc-rpc-api = { version = "0.8.0-alpha.5", path = "../../../../client/rpc-api" } [dev-dependencies] frame-system = { version = "2.0.0-alpha.5", path = "../../../../frame/system" } tokio = "0.2" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/frame/rpc/system/Cargo.toml b/utils/frame/rpc/system/Cargo.toml index d32f485ce8..8df958736b 100644 --- a/utils/frame/rpc/system/Cargo.toml +++ b/utils/frame/rpc/system/Cargo.toml @@ -28,3 +28,6 @@ sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../../primitive substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../../test-utils/runtime/client" } env_logger = "0.7.0" sc-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../../client/transaction-pool" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/prometheus/Cargo.toml b/utils/prometheus/Cargo.toml index bad77b1ea6..d2913c5e59 100644 --- a/utils/prometheus/Cargo.toml +++ b/utils/prometheus/Cargo.toml @@ -18,3 +18,6 @@ derive_more = "0.99" async-std = { version = "1.0.1", features = ["unstable"] } hyper = { version = "0.13.1", default-features = false, features = ["stream"] } tokio = "0.2" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/wasm-builder-runner/Cargo.toml b/utils/wasm-builder-runner/Cargo.toml index 8a41fe98b2..77796ea8d9 100644 --- a/utils/wasm-builder-runner/Cargo.toml +++ b/utils/wasm-builder-runner/Cargo.toml @@ -10,3 +10,6 @@ license = "GPL-3.0" homepage = "https://substrate.dev" [dependencies] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/utils/wasm-builder/Cargo.toml b/utils/wasm-builder/Cargo.toml index 1aac891393..ed953cca57 100644 --- a/utils/wasm-builder/Cargo.toml +++ b/utils/wasm-builder/Cargo.toml @@ -19,3 +19,6 @@ fs2 = "0.4.3" wasm-gc-api = "0.1.11" atty = "0.2.13" itertools = "0.8.2" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] -- GitLab From 4b65f1763ea30ca586e03a03063e7ecd1ea9577f Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 30 Mar 2020 10:00:34 +0200 Subject: [PATCH 104/300] =?UTF-8?q?Make=20transactions=20and=20block=20ann?= =?UTF-8?q?ounces=20use=20notifications=20substre=E2=80=A6=20(#5360)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Make transactions and block announces use notifications * Add documentation --- client/network/src/lib.rs | 8 + client/network/src/protocol.rs | 151 ++++++++++++++---- .../src/protocol/generic_proto/behaviour.rs | 54 +++---- .../protocol/generic_proto/handler/group.rs | 95 +++++------ .../src/protocol/generic_proto/tests.rs | 4 +- 5 files changed, 197 insertions(+), 115 deletions(-) diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index a5107a0255..23233ee904 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -129,6 +129,14 @@ //! light-client-related requests for information about the state. Each request is the encoding of //! a `light::Request` and each response is the encoding of a `light::Response`, as defined in the //! `light.v1.proto` file in this source tree. +//! - **`//transactions/1`** is a notifications protocol (see below) where +//! transactions are pushed to other nodes. The handshake is empty on both sides. The message +//! format is a SCALE-encoded list of transactions, where each transaction is an opaque list of +//! bytes. +//! - **`//block-announces/1`** is a notifications protocol (see below) where +//! block announces are pushed to other nodes. The handshake is empty on both sides. The message +//! format is a SCALE-encoded tuple containing a block header followed with an opaque list of +//! bytes containing some data associated with this block announcement, e.g. a candidate message. //! - Notifications protocols that are registered using the `register_notifications_protocol` //! method. For example: `/paritytech/grandpa/1`. See below for more information. //! diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 7cf568065e..e21a2df9c8 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -39,7 +39,7 @@ use sp_runtime::traits::{ }; use sp_arithmetic::traits::SaturatedConversion; use message::{BlockAnnounce, BlockAttributes, Direction, FromBlock, Message, RequestId}; -use message::generic::Message as GenericMessage; +use message::generic::{Message as GenericMessage, ConsensusMessage}; use light_dispatch::{LightDispatch, LightDispatchNetwork, RequestData}; use prometheus_endpoint::{Registry, Gauge, GaugeVec, PrometheusError, Opts, register, U64}; use sync::{ChainSync, SyncState}; @@ -221,8 +221,12 @@ pub struct Protocol { behaviour: GenericProto, /// For each legacy gossiping engine ID, the corresponding new protocol name. protocol_name_by_engine: HashMap>, - /// For each protocol name, the legacy gossiping engine ID. - protocol_engine_by_name: HashMap, ConsensusEngineId>, + /// For each protocol name, the legacy equivalent. + legacy_equiv_by_name: HashMap, Fallback>, + /// Name of the protocol used for transactions. + transactions_protocol: Cow<'static, [u8]>, + /// Name of the protocol used for block announces. + block_announces_protocol: Cow<'static, [u8]>, /// Prometheus metrics. metrics: Option, /// The `PeerId`'s of all boot nodes. @@ -424,6 +428,17 @@ impl Default for ProtocolConfig { } } +/// Fallback mechanism to use to send a notification if no substream is open. +#[derive(Debug, Clone, PartialEq, Eq)] +enum Fallback { + /// Use a `Message::Consensus` with the given engine ID. + Consensus(ConsensusEngineId), + /// The message is the bytes encoding of a `Transactions` (which is itself defined as a `Vec`). + Transactions, + /// The message is the bytes encoding of a `BlockAnnounce`. + BlockAnnounce, +} + impl Protocol { /// Create a new instance. pub fn new( @@ -460,7 +475,27 @@ impl Protocol { let (peerset, peerset_handle) = sc_peerset::Peerset::from_config(peerset_config); let versions = &((MIN_VERSION as u8)..=(CURRENT_VERSION as u8)).collect::>(); - let behaviour = GenericProto::new(protocol_id, versions, peerset); + let mut behaviour = GenericProto::new(protocol_id.clone(), versions, peerset); + + let mut legacy_equiv_by_name = HashMap::new(); + + let transactions_protocol: Cow<'static, [u8]> = Cow::from({ + let mut proto = b"/".to_vec(); + proto.extend(protocol_id.as_bytes()); + proto.extend(b"/transactions/1"); + proto + }); + behaviour.register_notif_protocol(transactions_protocol.clone(), Vec::new()); + legacy_equiv_by_name.insert(transactions_protocol.clone(), Fallback::Transactions); + + let block_announces_protocol: Cow<'static, [u8]> = Cow::from({ + let mut proto = b"/".to_vec(); + proto.extend(protocol_id.as_bytes()); + proto.extend(b"/block-announces/1"); + proto + }); + behaviour.register_notif_protocol(block_announces_protocol.clone(), Vec::new()); + legacy_equiv_by_name.insert(block_announces_protocol.clone(), Fallback::BlockAnnounce); let protocol = Protocol { tick_timeout: Box::pin(interval(TICK_TIMEOUT)), @@ -481,7 +516,9 @@ impl Protocol { peerset_handle: peerset_handle.clone(), behaviour, protocol_name_by_engine: HashMap::new(), - protocol_engine_by_name: HashMap::new(), + legacy_equiv_by_name, + transactions_protocol, + block_announces_protocol, metrics: if let Some(r) = metrics_registry { Some(Metrics::register(r)?) } else { @@ -731,12 +768,18 @@ impl Protocol { ); } - fn send_message(&mut self, who: &PeerId, message: Message) { + fn send_message( + &mut self, + who: &PeerId, + message: Option<(Cow<'static, [u8]>, Vec)>, + legacy: Message, + ) { send_message::( &mut self.behaviour, &mut self.context_data.stats, who, message, + legacy, ); } @@ -793,11 +836,7 @@ impl Protocol { } } - fn on_block_request( - &mut self, - peer: PeerId, - request: message::BlockRequest - ) { + fn on_block_request(&mut self, peer: PeerId, request: message::BlockRequest) { trace!(target: "sync", "BlockRequest {} from {}: from {:?} to {:?} max {:?} for {:?}", request.id, peer, @@ -874,7 +913,7 @@ impl Protocol { blocks: blocks, }; trace!(target: "sync", "Sending BlockResponse with {} blocks", response.blocks.len()); - self.send_message(&peer, GenericMessage::BlockResponse(response)) + self.send_message(&peer, None, GenericMessage::BlockResponse(response)) } /// Adjusts the reputation of a node. @@ -1132,10 +1171,15 @@ impl Protocol { &mut self, target: PeerId, engine_id: ConsensusEngineId, - message: impl Into> + message: impl Into>, ) { if let Some(protocol_name) = self.protocol_name_by_engine.get(&engine_id) { - self.behaviour.write_notification(&target, engine_id, protocol_name.clone(), message); + let message = message.into(); + let fallback = GenericMessage::<(), (), (), ()>::Consensus(ConsensusMessage { + engine_id, + data: message.clone(), + }).encode(); + self.behaviour.write_notification(&target, protocol_name.clone(), message, fallback); } else { error!( target: "sub-libp2p", @@ -1158,8 +1202,8 @@ impl Protocol { if self.protocol_name_by_engine.insert(engine_id, protocol_name.clone()).is_some() { error!(target: "sub-libp2p", "Notifications protocol already registered: {:?}", protocol_name); } else { - self.behaviour.register_notif_protocol(protocol_name.clone(), engine_id, Vec::new()); - self.protocol_engine_by_name.insert(protocol_name, engine_id); + self.behaviour.register_notif_protocol(protocol_name.clone(), Vec::new()); + self.legacy_equiv_by_name.insert(protocol_name, Fallback::Consensus(engine_id)); } // Registering a protocol while we already have open connections isn't great, but for now @@ -1229,7 +1273,7 @@ impl Protocol { fn do_propagate_extrinsics( &mut self, extrinsics: &[(H, B::Extrinsic)], - ) -> HashMap> { + ) -> HashMap> { let mut propagated_to = HashMap::new(); for (who, peer) in self.context_data.peers.iter_mut() { // never send extrinsics to the light node @@ -1251,10 +1295,12 @@ impl Protocol { .push(who.to_base58()); } trace!(target: "sync", "Sending {} transactions to {}", to_send.len(), who); + let encoded = to_send.encode(); send_message:: ( &mut self.behaviour, &mut self.context_data.stats, &who, + Some((self.transactions_protocol.clone(), encoded)), GenericMessage::Transactions(to_send) ) } @@ -1309,7 +1355,7 @@ impl Protocol { trace!(target: "sync", "Announcing block {:?} to {}", hash, who); let inserted = peer.known_blocks.insert(hash); if inserted || force { - let message: Message = GenericMessage::BlockAnnounce(message::BlockAnnounce { + let message = message::BlockAnnounce { header: header.clone(), state: if peer.info.protocol_version >= 4 { if is_best { @@ -1325,13 +1371,16 @@ impl Protocol { } else { None }, - }); + }; + + let encoded = message.encode(); send_message:: ( &mut self.behaviour, &mut self.context_data.stats, &who, - message, + Some((self.block_announces_protocol.clone(), encoded)), + Message::::BlockAnnounce(message), ) } } @@ -1350,10 +1399,14 @@ impl Protocol { chain_status: Vec::new(), // TODO: find a way to make this backwards-compatible }; - self.send_message(&who, GenericMessage::Status(status)) + self.send_message(&who, None, GenericMessage::Status(status)) } - fn on_block_announce(&mut self, who: PeerId, announce: BlockAnnounce) -> CustomMessageOutcome { + fn on_block_announce( + &mut self, + who: PeerId, + announce: BlockAnnounce, + ) -> CustomMessageOutcome { let hash = announce.header.hash(); if let Some(ref mut peer) = self.context_data.peers.get_mut(&who) { peer.known_blocks.insert(hash.clone()); @@ -1468,6 +1521,7 @@ impl Protocol { self.send_message( &who, + None, GenericMessage::RemoteCallResponse(message::RemoteCallResponse { id: request.id, proof, @@ -1598,6 +1652,7 @@ impl Protocol { }; self.send_message( &who, + None, GenericMessage::RemoteReadResponse(message::RemoteReadResponse { id: request.id, proof, @@ -1662,6 +1717,7 @@ impl Protocol { }; self.send_message( &who, + None, GenericMessage::RemoteReadResponse(message::RemoteReadResponse { id: request.id, proof, @@ -1702,6 +1758,7 @@ impl Protocol { }; self.send_message( &who, + None, GenericMessage::RemoteHeaderResponse(message::RemoteHeaderResponse { id: request.id, header, @@ -1772,6 +1829,7 @@ impl Protocol { }; self.send_message( &who, + None, GenericMessage::RemoteChangesResponse(message::RemoteChangesResponse { id: request.id, max: proof.max_block, @@ -1822,6 +1880,7 @@ impl Protocol { }; self.send_message( &who, + None, GenericMessage::FinalityProofResponse(message::FinalityProofResponse { id: 0, block: request.block, @@ -1951,20 +2010,25 @@ fn send_request( peer.block_request = Some((Instant::now(), r.clone())); } } - send_message::(behaviour, stats, who, message) + send_message::(behaviour, stats, who, None, message) } fn send_message( behaviour: &mut GenericProto, stats: &mut HashMap<&'static str, PacketStats>, who: &PeerId, - message: Message, + message: Option<(Cow<'static, [u8]>, Vec)>, + legacy_message: Message, ) { - let encoded = message.encode(); - let mut stats = stats.entry(message.id()).or_default(); + let encoded = legacy_message.encode(); + let mut stats = stats.entry(legacy_message.id()).or_default(); stats.bytes_out += encoded.len() as u64; stats.count_out += 1; - behaviour.send_packet(who, encoded); + if let Some((proto, msg)) = message { + behaviour.write_notification(who, proto, msg, encoded); + } else { + behaviour.send_packet(who, encoded); + } } impl NetworkBehaviour for Protocol { @@ -2061,8 +2125,39 @@ impl NetworkBehaviour for Protocol { GenericProtoOut::CustomProtocolClosed { peer_id, .. } => { self.on_peer_disconnected(peer_id.clone()) }, - GenericProtoOut::CustomMessage { peer_id, message } => + GenericProtoOut::LegacyMessage { peer_id, message } => self.on_custom_message(peer_id, message), + GenericProtoOut::Notification { peer_id, protocol_name, message } => + match self.legacy_equiv_by_name.get(&protocol_name) { + Some(Fallback::Consensus(engine_id)) => { + CustomMessageOutcome::NotificationsReceived { + remote: peer_id, + messages: vec![(*engine_id, message.freeze())], + } + } + Some(Fallback::Transactions) => { + if let Ok(m) = message::Transactions::decode(&mut message.as_ref()) { + self.on_extrinsics(peer_id, m); + } else { + warn!(target: "sub-libp2p", "Failed to decode transactions list"); + } + CustomMessageOutcome::None + } + Some(Fallback::BlockAnnounce) => { + if let Ok(announce) = message::BlockAnnounce::decode(&mut message.as_ref()) { + let outcome = self.on_block_announce(peer_id.clone(), announce); + self.update_peer_info(&peer_id); + outcome + } else { + warn!(target: "sub-libp2p", "Failed to decode block announce"); + CustomMessageOutcome::None + } + } + None => { + error!(target: "sub-libp2p", "Received notification from unknown protocol {:?}", protocol_name); + CustomMessageOutcome::None + } + } GenericProtoOut::Clogged { peer_id, messages } => { debug!(target: "sync", "{} clogging messages:", messages.len()); for msg in messages.into_iter().take(5) { diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index 727415baaf..63625f1c9f 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -15,12 +15,10 @@ // along with Substrate. If not, see . use crate::{DiscoveryNetBehaviour, config::ProtocolId}; -use crate::protocol::message::generic::{Message as GenericMessage, ConsensusMessage}; use crate::protocol::generic_proto::handler::{NotifsHandlerProto, NotifsHandlerOut, NotifsHandlerIn}; use crate::protocol::generic_proto::upgrade::RegisteredProtocol; use bytes::BytesMut; -use codec::Encode as _; use fnv::FnvHashMap; use futures::prelude::*; use libp2p::core::{ConnectedPoint, Multiaddr, PeerId}; @@ -28,10 +26,9 @@ use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use log::{debug, error, trace, warn}; use rand::distributions::{Distribution as _, Uniform}; use smallvec::SmallVec; -use sp_runtime::ConsensusEngineId; -use std::{borrow::Cow, collections::hash_map::Entry, cmp}; -use std::{error, mem, pin::Pin, str, time::Duration}; use std::task::{Context, Poll}; +use std::{borrow::Cow, cmp, collections::hash_map::Entry}; +use std::{error, mem, pin::Pin, str, time::Duration}; use wasm_timer::Instant; /// Network behaviour that handles opening substreams for custom protocols with other nodes. @@ -84,7 +81,7 @@ pub struct GenericProto { legacy_protocol: RegisteredProtocol, /// Notification protocols. Entries are only ever added and not removed. - notif_protocols: Vec<(Cow<'static, [u8]>, ConsensusEngineId, Vec)>, + notif_protocols: Vec<(Cow<'static, [u8]>, Vec)>, /// Receiver for instructions about who to connect to or disconnect from. peerset: sc_peerset::Peerset, @@ -238,12 +235,22 @@ pub enum GenericProtoOut { reason: Cow<'static, str>, }, + /// Receives a message on the legacy substream. + LegacyMessage { + /// Id of the peer the message came from. + peer_id: PeerId, + /// Message that has been received. + message: BytesMut, + }, + /// Receives a message on a custom protocol substream. /// /// Also concerns received notifications for the notifications API. - CustomMessage { + Notification { /// Id of the peer the message came from. peer_id: PeerId, + /// Engine corresponding to the message. + protocol_name: Cow<'static, [u8]>, /// Message that has been received. message: BytesMut, }, @@ -285,10 +292,9 @@ impl GenericProto { pub fn register_notif_protocol( &mut self, protocol_name: impl Into>, - engine_id: ConsensusEngineId, handshake_msg: impl Into> ) { - self.notif_protocols.push((protocol_name.into(), engine_id, handshake_msg.into())); + self.notif_protocols.push((protocol_name.into(), handshake_msg.into())); } /// Returns the number of discovered nodes that we keep in memory. @@ -406,14 +412,15 @@ impl GenericProto { /// Also note that even if we have a valid open substream, it may in fact be already closed /// without us knowing, in which case the packet will not be received. /// - /// > **Note**: Ideally the `engine_id` parameter wouldn't be necessary. See the documentation - /// > of [`NotifsHandlerIn`] for more information. + /// The `fallback` parameter is used for backwards-compatibility reason if the remote doesn't + /// support our protocol. One needs to pass the equivalent of what would have been passed + /// with `send_packet`. pub fn write_notification( &mut self, target: &PeerId, - engine_id: ConsensusEngineId, protocol_name: Cow<'static, [u8]>, message: impl Into>, + encoded_fallback_message: Vec, ) { if !self.is_open(target) { return; @@ -421,7 +428,7 @@ impl GenericProto { trace!( target: "sub-libp2p", - "External API => Notification for {:?} with protocol {:?}", + "External API => Notification({:?}, {:?})", target, str::from_utf8(&protocol_name) ); @@ -431,7 +438,7 @@ impl GenericProto { peer_id: target.clone(), event: NotifsHandlerIn::SendNotification { message: message.into(), - engine_id, + encoded_fallback_message, protocol_name, }, }); @@ -999,7 +1006,7 @@ impl NetworkBehaviour for GenericProto { debug_assert!(self.is_open(&source)); trace!(target: "sub-libp2p", "Handler({:?}) => Message", source); trace!(target: "sub-libp2p", "External API <= Message({:?})", source); - let event = GenericProtoOut::CustomMessage { + let event = GenericProtoOut::LegacyMessage { peer_id: source, message, }; @@ -1007,7 +1014,7 @@ impl NetworkBehaviour for GenericProto { self.events.push(NetworkBehaviourAction::GenerateEvent(event)); } - NotifsHandlerOut::Notification { protocol_name, engine_id, message } => { + NotifsHandlerOut::Notification { protocol_name, message } => { debug_assert!(self.is_open(&source)); trace!( target: "sub-libp2p", @@ -1015,18 +1022,11 @@ impl NetworkBehaviour for GenericProto { source, str::from_utf8(&protocol_name) ); - trace!(target: "sub-libp2p", "External API <= Message({:?})", source); - let event = GenericProtoOut::CustomMessage { + trace!(target: "sub-libp2p", "External API <= Message({:?}, {:?})", protocol_name, source); + let event = GenericProtoOut::Notification { peer_id: source, - message: { - let message = GenericMessage::<(), (), (), ()>::Consensus(ConsensusMessage { - engine_id, - data: message.to_vec(), - }); - - // Note that we clone `message` here. - From::from(&message.encode()[..]) - }, + protocol_name, + message, }; self.events.push(NetworkBehaviourAction::GenerateEvent(event)); diff --git a/client/network/src/protocol/generic_proto/handler/group.rs b/client/network/src/protocol/generic_proto/handler/group.rs index d6d9919d3e..b4321234b0 100644 --- a/client/network/src/protocol/generic_proto/handler/group.rs +++ b/client/network/src/protocol/generic_proto/handler/group.rs @@ -51,10 +51,8 @@ use crate::protocol::generic_proto::{ handler::notif_out::{NotifsOutHandlerProto, NotifsOutHandler, NotifsOutHandlerIn, NotifsOutHandlerOut}, upgrade::{NotificationsIn, NotificationsOut, NotificationsHandshakeError, RegisteredProtocol, UpgradeCollec}, }; -use crate::protocol::message::generic::{Message as GenericMessage, ConsensusMessage}; use bytes::BytesMut; -use codec::Encode as _; use libp2p::core::{either::{EitherError, EitherOutput}, ConnectedPoint, PeerId}; use libp2p::core::upgrade::{EitherUpgrade, UpgradeError, SelectUpgrade, InboundUpgrade, OutboundUpgrade}; use libp2p::swarm::{ @@ -66,8 +64,7 @@ use libp2p::swarm::{ NegotiatedSubstream, }; use log::error; -use sp_runtime::ConsensusEngineId; -use std::{borrow::Cow, error, io, task::{Context, Poll}}; +use std::{borrow::Cow, error, io, str, task::{Context, Poll}}; /// Implements the `IntoProtocolsHandler` trait of libp2p. /// @@ -78,10 +75,10 @@ use std::{borrow::Cow, error, io, task::{Context, Poll}}; /// See the documentation at the module level for more information. pub struct NotifsHandlerProto { /// Prototypes for handlers for inbound substreams. - in_handlers: Vec<(NotifsInHandlerProto, ConsensusEngineId)>, + in_handlers: Vec, /// Prototypes for handlers for outbound substreams. - out_handlers: Vec<(NotifsOutHandlerProto, ConsensusEngineId)>, + out_handlers: Vec, /// Prototype for handler for backwards-compatibility. legacy: LegacyProtoHandlerProto, @@ -92,10 +89,10 @@ pub struct NotifsHandlerProto { /// See the documentation at the module level for more information. pub struct NotifsHandler { /// Handlers for inbound substreams. - in_handlers: Vec<(NotifsInHandler, ConsensusEngineId)>, + in_handlers: Vec, /// Handlers for outbound substreams. - out_handlers: Vec<(NotifsOutHandler, ConsensusEngineId)>, + out_handlers: Vec, /// Handler for backwards-compatibility. legacy: LegacyProtoHandler, @@ -121,7 +118,7 @@ impl IntoProtocolsHandler for NotifsHandlerProto { fn inbound_protocol(&self) -> SelectUpgrade, RegisteredProtocol> { let in_handlers = self.in_handlers.iter() - .map(|(h, _)| h.inbound_protocol()) + .map(|h| h.inbound_protocol()) .collect::>(); SelectUpgrade::new(in_handlers, self.legacy.inbound_protocol()) @@ -131,11 +128,11 @@ impl IntoProtocolsHandler for NotifsHandlerProto { NotifsHandler { in_handlers: self.in_handlers .into_iter() - .map(|(p, e)| (p.into_handler(remote_peer_id, connected_point), e)) + .map(|p| p.into_handler(remote_peer_id, connected_point)) .collect(), out_handlers: self.out_handlers .into_iter() - .map(|(p, e)| (p.into_handler(remote_peer_id, connected_point), e)) + .map(|p| p.into_handler(remote_peer_id, connected_point)) .collect(), legacy: self.legacy.into_handler(remote_peer_id, connected_point), enabled: EnabledState::Initial, @@ -155,7 +152,8 @@ pub enum NotifsHandlerIn { /// Sends a message through the custom protocol substream. /// - /// > **Note**: This must **not** be an encoded `ConsensusMessage` message. + /// > **Note**: This must **not** be a `ConsensusMessage`, `Transactions`, or + /// > `BlockAnnounce` message. SendLegacy { /// The message to send. message: Vec, @@ -166,17 +164,13 @@ pub enum NotifsHandlerIn { /// Name of the protocol for the message. /// /// Must match one of the registered protocols. For backwards-compatibility reasons, if - /// the remote doesn't support this protocol, we use the legacy substream to send a - /// `ConsensusMessage` message. + /// the remote doesn't support this protocol, we use the legacy substream. protocol_name: Cow<'static, [u8]>, - /// The engine ID to use, in case we need to send this message over the legacy substream. + /// Message to send on the legacy substream if the protocol isn't available. /// - /// > **Note**: Ideally this field wouldn't be necessary, and we would deduce the engine - /// > ID from the existing handlers. However, it is possible (especially in test - /// > situations) that we open connections before all the notification protocols - /// > have been registered, in which case we always rely on the legacy substream. - engine_id: ConsensusEngineId, + /// This corresponds to what you would have sent with `SendLegacy`. + encoded_fallback_message: Vec, /// The message to send. message: Vec, @@ -206,17 +200,10 @@ pub enum NotifsHandlerOut { /// Received a message on a custom protocol substream. Notification { - /// Engine corresponding to the message. + /// Name of the protocol of the message. protocol_name: Cow<'static, [u8]>, - /// For legacy reasons, the name to use if we had received the message from the legacy - /// substream. - engine_id: ConsensusEngineId, - /// Message that has been received. - /// - /// If `protocol_name` is `None`, this decodes to a `Message`. If `protocol_name` is `Some`, - /// this is directly a gossiping message. message: BytesMut, }, @@ -238,12 +225,12 @@ pub enum NotifsHandlerOut { impl NotifsHandlerProto { /// Builds a new handler. - pub fn new(legacy: RegisteredProtocol, list: impl Into, ConsensusEngineId, Vec)>>) -> Self { + pub fn new(legacy: RegisteredProtocol, list: impl Into, Vec)>>) -> Self { let list = list.into(); NotifsHandlerProto { - in_handlers: list.clone().into_iter().map(|(p, e, _)| (NotifsInHandlerProto::new(p), e)).collect(), - out_handlers: list.clone().into_iter().map(|(p, e, _)| (NotifsOutHandlerProto::new(p), e)).collect(), + in_handlers: list.clone().into_iter().map(|(p, _)| NotifsInHandlerProto::new(p)).collect(), + out_handlers: list.clone().into_iter().map(|(p, _)| NotifsOutHandlerProto::new(p)).collect(), legacy: LegacyProtoHandlerProto::new(legacy), } } @@ -266,7 +253,7 @@ impl ProtocolsHandler for NotifsHandler { fn listen_protocol(&self) -> SubstreamProtocol { let in_handlers = self.in_handlers.iter() - .map(|h| h.0.listen_protocol().into_upgrade().1) + .map(|h| h.listen_protocol().into_upgrade().1) .collect::>(); let proto = SelectUpgrade::new(in_handlers, self.legacy.listen_protocol().into_upgrade().1); @@ -279,7 +266,7 @@ impl ProtocolsHandler for NotifsHandler { ) { match out { EitherOutput::First((out, num)) => - self.in_handlers[num].0.inject_fully_negotiated_inbound(out), + self.in_handlers[num].inject_fully_negotiated_inbound(out), EitherOutput::Second(out) => self.legacy.inject_fully_negotiated_inbound(out), } @@ -292,7 +279,7 @@ impl ProtocolsHandler for NotifsHandler { ) { match (out, num) { (EitherOutput::First(out), Some(num)) => - self.out_handlers[num].0.inject_fully_negotiated_outbound(out, ()), + self.out_handlers[num].inject_fully_negotiated_outbound(out, ()), (EitherOutput::Second(out), None) => self.legacy.inject_fully_negotiated_outbound(out, ()), _ => error!("inject_fully_negotiated_outbound called with wrong parameters"), @@ -304,13 +291,13 @@ impl ProtocolsHandler for NotifsHandler { NotifsHandlerIn::Enable => { self.enabled = EnabledState::Enabled; self.legacy.inject_event(LegacyProtoHandlerIn::Enable); - for (handler, _) in &mut self.out_handlers { + for handler in &mut self.out_handlers { handler.inject_event(NotifsOutHandlerIn::Enable { initial_message: vec![] }); } for num in self.pending_in.drain(..) { - self.in_handlers[num].0.inject_event(NotifsInHandlerIn::Accept(vec![])); + self.in_handlers[num].inject_event(NotifsInHandlerIn::Accept(vec![])); } }, NotifsHandlerIn::Disable => { @@ -318,38 +305,31 @@ impl ProtocolsHandler for NotifsHandler { // The notifications protocols start in the disabled state. If we were in the // "Initial" state, then we shouldn't disable the notifications protocols again. if self.enabled != EnabledState::Initial { - for (handler, _) in &mut self.out_handlers { + for handler in &mut self.out_handlers { handler.inject_event(NotifsOutHandlerIn::Disable); } } self.enabled = EnabledState::Disabled; for num in self.pending_in.drain(..) { - self.in_handlers[num].0.inject_event(NotifsInHandlerIn::Refuse); + self.in_handlers[num].inject_event(NotifsInHandlerIn::Refuse); } }, NotifsHandlerIn::SendLegacy { message } => self.legacy.inject_event(LegacyProtoHandlerIn::SendCustomMessage { message }), - NotifsHandlerIn::SendNotification { message, engine_id, protocol_name } => { - for (handler, ngn_id) in &mut self.out_handlers { + NotifsHandlerIn::SendNotification { message, encoded_fallback_message, protocol_name } => { + for handler in &mut self.out_handlers { if handler.protocol_name() != &protocol_name[..] { - break; + continue; } if handler.is_open() { handler.inject_event(NotifsOutHandlerIn::Send(message)); return; - } else { - debug_assert_eq!(engine_id, *ngn_id); } } - let message = GenericMessage::<(), (), (), ()>::Consensus(ConsensusMessage { - engine_id, - data: message, - }); - self.legacy.inject_event(LegacyProtoHandlerIn::SendCustomMessage { - message: message.encode() + message: encoded_fallback_message, }); }, } @@ -362,21 +342,21 @@ impl ProtocolsHandler for NotifsHandler { ) { match (err, num) { (ProtocolsHandlerUpgrErr::Timeout, Some(num)) => - self.out_handlers[num].0.inject_dial_upgrade_error( + self.out_handlers[num].inject_dial_upgrade_error( (), ProtocolsHandlerUpgrErr::Timeout ), (ProtocolsHandlerUpgrErr::Timeout, None) => self.legacy.inject_dial_upgrade_error((), ProtocolsHandlerUpgrErr::Timeout), (ProtocolsHandlerUpgrErr::Timer, Some(num)) => - self.out_handlers[num].0.inject_dial_upgrade_error( + self.out_handlers[num].inject_dial_upgrade_error( (), ProtocolsHandlerUpgrErr::Timer ), (ProtocolsHandlerUpgrErr::Timer, None) => self.legacy.inject_dial_upgrade_error((), ProtocolsHandlerUpgrErr::Timer), (ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), Some(num)) => - self.out_handlers[num].0.inject_dial_upgrade_error( + self.out_handlers[num].inject_dial_upgrade_error( (), ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)) ), @@ -386,7 +366,7 @@ impl ProtocolsHandler for NotifsHandler { ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)) ), (ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::A(err))), Some(num)) => - self.out_handlers[num].0.inject_dial_upgrade_error( + self.out_handlers[num].inject_dial_upgrade_error( (), ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)) ), @@ -407,7 +387,7 @@ impl ProtocolsHandler for NotifsHandler { return KeepAlive::Yes; } - for (handler, _) in &self.in_handlers { + for handler in &self.in_handlers { let val = handler.connection_keep_alive(); if val.is_yes() { return KeepAlive::Yes; @@ -415,7 +395,7 @@ impl ProtocolsHandler for NotifsHandler { if ret < val { ret = val; } } - for (handler, _) in &self.out_handlers { + for handler in &self.out_handlers { let val = handler.connection_keep_alive(); if val.is_yes() { return KeepAlive::Yes; @@ -432,7 +412,7 @@ impl ProtocolsHandler for NotifsHandler { ) -> Poll< ProtocolsHandlerEvent > { - for (handler_num, (handler, engine_id)) in self.in_handlers.iter_mut().enumerate() { + for (handler_num, handler) in self.in_handlers.iter_mut().enumerate() { while let Poll::Ready(ev) = handler.poll(cx) { match ev { ProtocolsHandlerEvent::OutboundSubstreamRequest { .. } => @@ -453,7 +433,6 @@ impl ProtocolsHandler for NotifsHandler { if self.legacy.is_open() { let msg = NotifsHandlerOut::Notification { message, - engine_id: *engine_id, protocol_name: handler.protocol_name().to_owned().into(), }; return Poll::Ready(ProtocolsHandlerEvent::Custom(msg)); @@ -463,7 +442,7 @@ impl ProtocolsHandler for NotifsHandler { } } - for (handler_num, (handler, _)) in self.out_handlers.iter_mut().enumerate() { + for (handler_num, handler) in self.out_handlers.iter_mut().enumerate() { while let Poll::Ready(ev) = handler.poll(cx) { match ev { ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol, info: () } => diff --git a/client/network/src/protocol/generic_proto/tests.rs b/client/network/src/protocol/generic_proto/tests.rs index b63a725c07..00b840d581 100644 --- a/client/network/src/protocol/generic_proto/tests.rs +++ b/client/network/src/protocol/generic_proto/tests.rs @@ -245,7 +245,7 @@ fn two_nodes_transfer_lots_of_packets() { loop { match ready!(service2.poll_next_unpin(cx)) { Some(GenericProtoOut::CustomProtocolOpen { .. }) => {}, - Some(GenericProtoOut::CustomMessage { message, .. }) => { + Some(GenericProtoOut::LegacyMessage { message, .. }) => { match Message::::decode(&mut &message[..]).unwrap() { Message::::BlockResponse(BlockResponse { id: _, blocks }) => { assert!(blocks.is_empty()); @@ -315,7 +315,7 @@ fn basic_two_nodes_requests_in_parallel() { loop { match ready!(service2.poll_next_unpin(cx)) { Some(GenericProtoOut::CustomProtocolOpen { .. }) => {}, - Some(GenericProtoOut::CustomMessage { message, .. }) => { + Some(GenericProtoOut::LegacyMessage { message, .. }) => { let pos = to_receive.iter().position(|m| m.encode() == message).unwrap(); to_receive.remove(pos); if to_receive.is_empty() { -- GitLab From 7e7d3e0f811aa81bdb81100bff184da9133ae440 Mon Sep 17 00:00:00 2001 From: Rakan Alhneiti Date: Mon, 30 Mar 2020 13:18:59 +0200 Subject: [PATCH 105/300] Introduce `sign_with` method in keystore (#4925) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add KEY_KIND_ID to the public trait This change is being introduced for the purpose of identifying a public key with it's identifier and algorithm "kind". * Use `sign_with` as implemented in BareCryptoStore * Implement `sign_with` in sc_keystore * Fix inconsistencies, use *_KIND_ID in sp_core testing * Rename KeyKindId to CryptoTypeId * Remove pair-returning functions from BareCryptoStore trait * Define CryptoTypeId in app-crypto macros * Add functions to get keys supported by keystore * Fix sign_with signature to include CryptoTypePublicPair * Add `sign_with_any` and `sign_with_all` * Use keystore.sign_with in auth_discovery * Rename get_supported_keys -> supported_keys * Added headers to function docstrings * Use chain instead of extending a temp vector * Fixed some code formatting * Restrict size of CryptoTypeId This is to be able to use Encode/Decode derives and the overcome having the size being unknown at compile-time. * Implement sign_with in the trait itself * Remove whitespace * Use key_type also as a CryptoTypeId in app_crypto macros * Rename `get_keys` to `keys` in BareCryptoStore * Remove usage of key_pair funcs in tests * Adjust docstring for *_CYPTO_ID constants * Fix failures * Simplify mapping on keys * Remove one let * Fixed typo * PR feedback * remove whitespace * Zip keys and signatures * Use into_iter & remove cloned * Pass index to MissingSignature * Use typed errors instead of strings for BareCryptoStore * Implement Debug for trait error * Use hashsets for better performance for supported_keys * Make sure keys are inserted into the keystore * Make sign_with_all return type consistent with `sign_with` * Rename Error to BareCryptoStoreError * Rename CRYPT_TYPE_ID -> CRYPTO_ID * Remove unnecessary CRYPTO_ID declaration in Public trait * Convert pub key to CryptoTypePublicPair * Fix use * Fix code style * Implement From on CryptoTypePublicPair in app_crypto macros * Change CryptoTypePublicPair to a struct * Implement Display on CryptoTypePublicPair * Pass CryptoTypePublicPair to MissingSignature error * Adjust docs according to function signature * Unify keys implementation * Fix RPC author tests * Fix stackoverflow * Tabify spaces * Pass KeyTypeId to error for easier debugging * Fix asserts * Use ToHex to format public key * Use constants from sp_core * Rename testing KeyTypeId constants * Please compiler * Restore KeyTypeId names apparently, they're not only used in tests * Use BareCryptoStoreError instead of String * Document return value * Fix borrow check * Convert to hashset internally * WIP - iter_keys * Return raw_public_keys * Address PR feedback * Address PR Feedback * Fix hexdisplay import error * Update primitives/core/src/traits.rs Co-authored-by: Bastian Köcher --- client/authority-discovery/src/error.rs | 6 + client/authority-discovery/src/lib.rs | 42 +++-- client/keystore/src/lib.rs | 172 +++++++++++++----- client/rpc/src/author/tests.rs | 27 +-- primitives/application-crypto/src/ed25519.rs | 15 ++ primitives/application-crypto/src/lib.rs | 4 +- primitives/application-crypto/src/sr25519.rs | 15 ++ .../application-crypto/test/src/ed25519.rs | 12 +- .../application-crypto/test/src/sr25519.rs | 12 +- primitives/authority-discovery/src/lib.rs | 19 +- primitives/core/src/crypto.rs | 29 ++- primitives/core/src/ecdsa.rs | 5 +- primitives/core/src/ed25519.rs | 17 +- primitives/core/src/sr25519.rs | 19 +- primitives/core/src/testing.rs | 116 ++++++++---- primitives/core/src/traits.rs | 102 ++++++++++- primitives/io/src/lib.rs | 10 +- 17 files changed, 472 insertions(+), 150 deletions(-) diff --git a/client/authority-discovery/src/error.rs b/client/authority-discovery/src/error.rs index 74b7043c29..216f8c26bf 100644 --- a/client/authority-discovery/src/error.rs +++ b/client/authority-discovery/src/error.rs @@ -16,6 +16,8 @@ //! Authority discovery errors. +use sp_core::crypto::CryptoTypePublicPair; + /// AuthorityDiscovery Result. pub type Result = std::result::Result; @@ -46,6 +48,10 @@ pub enum Error { EncodingDecodingScale(codec::Error), /// Failed to parse a libp2p multi address. ParsingMultiaddress(libp2p::core::multiaddr::Error), + /// Failed to sign using a specific public key + MissingSignature(CryptoTypePublicPair), + /// Failed to sign using all public keys + Signing, /// Failed to register Prometheus metric. Prometheus(prometheus_endpoint::PrometheusError), } diff --git a/client/authority-discovery/src/lib.rs b/client/authority-discovery/src/lib.rs index 171a401bbb..ec103ab8a0 100644 --- a/client/authority-discovery/src/lib.rs +++ b/client/authority-discovery/src/lib.rs @@ -63,7 +63,7 @@ use prost::Message; use sc_client_api::blockchain::HeaderBackend; use sc_network::{DhtEvent, ExHashT, NetworkStateInfo}; use sp_authority_discovery::{AuthorityDiscoveryApi, AuthorityId, AuthoritySignature, AuthorityPair}; -use sp_core::crypto::{key_types, Pair}; +use sp_core::crypto::{key_types, CryptoTypePublicPair, Pair}; use sp_core::traits::BareCryptoStorePtr; use sp_runtime::{traits::Block as BlockT, generic::BlockId}; use sp_api::ProvideRuntimeApi; @@ -283,19 +283,36 @@ where .encode(&mut serialized_addresses) .map_err(Error::EncodingProto)?; - for key in self.get_priv_keys_within_authority_set()?.into_iter() { - let signature = key.sign(&serialized_addresses); + let keys: Vec = self.get_own_public_keys_within_authority_set()? + .into_iter() + .map(Into::into) + .collect(); + let signatures = self.key_store + .read() + .sign_with_all( + key_types::AUTHORITY_DISCOVERY, + keys.clone(), + serialized_addresses.as_slice(), + ) + .map_err(|_| Error::Signing)?; + + for (sign_result, key) in signatures.iter().zip(keys) { let mut signed_addresses = vec![]; + + // sign_with_all returns Result signature + // is generated for a public key that is supported. + // Verify that all signatures exist for all provided keys. + let signature = sign_result.as_ref().map_err(|_| Error::MissingSignature(key.clone()))?; schema::SignedAuthorityAddresses { addresses: serialized_addresses.clone(), - signature: signature.encode(), + signature: Encode::encode(&signature), } .encode(&mut signed_addresses) .map_err(Error::EncodingProto)?; self.network.put_value( - hash_authority_id(key.public().as_ref())?, + hash_authority_id(key.1.as_ref())?, signed_addresses, ); } @@ -446,21 +463,6 @@ where Ok(()) } - /// Retrieve all local authority discovery private keys that are within the current authority - /// set. - fn get_priv_keys_within_authority_set(&mut self) -> Result> { - let keys = self.get_own_public_keys_within_authority_set()? - .into_iter() - .map(std::convert::Into::into) - .filter_map(|pub_key| { - self.key_store.read().sr25519_key_pair(key_types::AUTHORITY_DISCOVERY, &pub_key) - }) - .map(std::convert::Into::into) - .collect(); - - Ok(keys) - } - /// Retrieve our public keys within the current authority set. // // A node might have multiple authority discovery keys within its keystore, e.g. an old one and diff --git a/client/keystore/src/lib.rs b/client/keystore/src/lib.rs index 087ddf326d..f8bc930971 100644 --- a/client/keystore/src/lib.rs +++ b/client/keystore/src/lib.rs @@ -17,10 +17,11 @@ //! Keystore (and session key management) for ed25519 based chains like Polkadot. #![warn(missing_docs)] - -use std::{collections::HashMap, path::PathBuf, fs::{self, File}, io::{self, Write}, sync::Arc}; +use std::{collections::{HashMap, HashSet}, path::PathBuf, fs::{self, File}, io::{self, Write}, sync::Arc}; use sp_core::{ - crypto::{KeyTypeId, Pair as PairT, Public, IsWrappedBy, Protected}, traits::BareCryptoStore, + crypto::{IsWrappedBy, CryptoTypePublicPair, KeyTypeId, Pair as PairT, Protected, Public}, + traits::{BareCryptoStore, BareCryptoStoreError as TraitError}, + Encode, }; use sp_application_crypto::{AppKey, AppPublic, AppPair, ed25519, sr25519}; use parking_lot::RwLock; @@ -44,6 +45,12 @@ pub enum Error { /// Invalid seed #[display(fmt="Invalid seed")] InvalidSeed, + /// Public key type is not supported + #[display(fmt="Key crypto type is not supported")] + KeyNotSupported(KeyTypeId), + /// Pair not found for public key and KeyTypeId + #[display(fmt="Pair not found for {} public key", "_0")] + PairNotFound(String), /// Keystore unavailable #[display(fmt="Keystore unavailable")] Unavailable, @@ -52,6 +59,21 @@ pub enum Error { /// Keystore Result pub type Result = std::result::Result; +impl From for TraitError { + fn from(error: Error) -> Self { + match error { + Error::KeyNotSupported(id) => TraitError::KeyNotSupported(id), + Error::PairNotFound(e) => TraitError::PairNotFound(e), + Error::InvalidSeed | Error::InvalidPhrase | Error::InvalidPassword => { + TraitError::ValidationError(error.to_string()) + }, + Error::Unavailable => TraitError::Unavailable, + Error::Io(e) => TraitError::Other(e.to_string()), + Error::Json(e) => TraitError::Other(e.to_string()), + } + } +} + impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { @@ -220,16 +242,35 @@ impl Store { self.key_pair_by_type::(IsWrappedBy::from_ref(public), Pair::ID).map(Into::into) } - /// Get public keys of all stored keys that match the given key type. - pub fn public_keys_by_type(&self, key_type: KeyTypeId) -> Result> { - let mut public_keys: Vec = self.additional.keys() - .filter_map(|(ty, public)| { - if *ty == key_type { - Some(TPublic::from_slice(public)) - } else { - None - } + /// Get public keys of all stored keys that match the key type. + /// + /// This will just use the type of the public key (a list of which to be returned) in order + /// to determine the key type. Unless you use a specialized application-type public key, then + /// this only give you keys registered under generic cryptography, and will not return keys + /// registered under the application type. + pub fn public_keys(&self) -> Result> { + self.raw_public_keys(Public::ID) + .map(|v| { + v.into_iter() + .map(|k| Public::from_slice(k.as_slice())) + .collect() }) + } + + /// Returns the file path for the given public key and key type. + fn key_file_path(&self, public: &[u8], key_type: KeyTypeId) -> Option { + let mut buf = self.path.as_ref()?.clone(); + let key_type = hex::encode(key_type.0); + let key = hex::encode(public); + buf.push(key_type + key.as_str()); + Some(buf) + } + + /// Returns a list of raw public keys filtered by `KeyTypeId` + fn raw_public_keys(&self, id: KeyTypeId) -> Result>> { + let mut public_keys: Vec> = self.additional.keys() + .into_iter() + .filter_map(|k| if k.0 == id { Some(k.1.clone()) } else { None }) .collect(); if let Some(path) = &self.path { @@ -241,8 +282,10 @@ impl Store { if let Some(name) = path.file_name().and_then(|n| n.to_str()) { match hex::decode(name) { Ok(ref hex) if hex.len() > 4 => { - if &hex[0..4] != &key_type.0 { continue } - let public = TPublic::from_slice(&hex[4..]); + if &hex[0..4] != &id.0 { + continue; + } + let public = hex[4..].to_vec(); public_keys.push(public); } _ => continue, @@ -253,71 +296,104 @@ impl Store { Ok(public_keys) } +} - /// Get public keys of all stored keys that match the key type. - /// - /// This will just use the type of the public key (a list of which to be returned) in order - /// to determine the key type. Unless you use a specialized application-type public key, then - /// this only give you keys registered under generic cryptography, and will not return keys - /// registered under the application type. - pub fn public_keys(&self) -> Result> { - self.public_keys_by_type::(Public::ID) - .map(|v| v.into_iter().map(Into::into).collect()) +impl BareCryptoStore for Store { + fn keys( + &self, + id: KeyTypeId + ) -> std::result::Result, TraitError> { + let raw_keys = self.raw_public_keys(id)?; + Ok(raw_keys.into_iter() + .fold(Vec::new(), |mut v, k| { + v.push(CryptoTypePublicPair(sr25519::CRYPTO_ID, k.clone())); + v.push(CryptoTypePublicPair(ed25519::CRYPTO_ID, k.clone())); + v + })) + } + + fn supported_keys( + &self, + id: KeyTypeId, + keys: Vec + ) -> std::result::Result, TraitError> { + let all_keys = self.keys(id)?.into_iter().collect::>(); + Ok(keys.into_iter() + .filter(|key| all_keys.contains(key)) + .collect::>()) } - /// Returns the file path for the given public key and key type. - fn key_file_path(&self, public: &[u8], key_type: KeyTypeId) -> Option { - let mut buf = self.path.as_ref()?.clone(); - let key_type = hex::encode(key_type.0); - let key = hex::encode(public); - buf.push(key_type + key.as_str()); - Some(buf) + fn sign_with( + &self, + id: KeyTypeId, + key: &CryptoTypePublicPair, + msg: &[u8], + ) -> std::result::Result, TraitError> { + match key.0 { + ed25519::CRYPTO_ID => { + let pub_key = ed25519::Public::from_slice(key.1.as_slice()); + let key_pair: ed25519::Pair = self + .key_pair_by_type::(&pub_key, id) + .map_err(|e| TraitError::from(e))?; + Ok(key_pair.sign(msg).encode()) + } + sr25519::CRYPTO_ID => { + let pub_key = sr25519::Public::from_slice(key.1.as_slice()); + let key_pair: sr25519::Pair = self + .key_pair_by_type::(&pub_key, id) + .map_err(|e| TraitError::from(e))?; + Ok(key_pair.sign(msg).encode()) + } + _ => Err(TraitError::KeyNotSupported(id)) + } } -} -impl BareCryptoStore for Store { fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec { - self.public_keys_by_type::(key_type).unwrap_or_default() + self.raw_public_keys(key_type) + .map(|v| { + v.into_iter() + .map(|k| sr25519::Public::from_slice(k.as_slice())) + .collect() + }) + .unwrap_or_default() } fn sr25519_generate_new( &mut self, id: KeyTypeId, seed: Option<&str>, - ) -> std::result::Result { + ) -> std::result::Result { let pair = match seed { Some(seed) => self.insert_ephemeral_from_seed_by_type::(seed, id), None => self.generate_by_type::(id), - }.map_err(|e| e.to_string())?; + }.map_err(|e| -> TraitError { e.into() })?; Ok(pair.public()) } - fn sr25519_key_pair(&self, id: KeyTypeId, pub_key: &sr25519::Public) -> Option { - self.key_pair_by_type::(pub_key, id).ok() - } - fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec { - self.public_keys_by_type::(key_type).unwrap_or_default() + self.raw_public_keys(key_type) + .map(|v| { + v.into_iter() + .map(|k| ed25519::Public::from_slice(k.as_slice())) + .collect() + }) + .unwrap_or_default() } fn ed25519_generate_new( &mut self, id: KeyTypeId, seed: Option<&str>, - ) -> std::result::Result { + ) -> std::result::Result { let pair = match seed { Some(seed) => self.insert_ephemeral_from_seed_by_type::(seed, id), None => self.generate_by_type::(id), - }.map_err(|e| e.to_string())?; + }.map_err(|e| -> TraitError { e.into() })?; Ok(pair.public()) } - fn ed25519_key_pair(&self, id: KeyTypeId, pub_key: &ed25519::Public) -> Option { - self.key_pair_by_type::(pub_key, id).ok() - } - fn insert_unknown(&mut self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> std::result::Result<(), ()> { @@ -337,7 +413,7 @@ impl BareCryptoStore for Store { mod tests { use super::*; use tempfile::TempDir; - use sp_core::{testing::{SR25519}, crypto::{Ss58Codec}}; + use sp_core::{testing::SR25519, crypto::Ss58Codec}; #[test] fn basic_store() { @@ -451,7 +527,7 @@ mod tests { fs::write(file_name, "test").expect("Invalid file is written"); assert!( - store.read().public_keys_by_type::(SR25519).unwrap().is_empty(), + store.read().sr25519_public_keys(SR25519).is_empty(), ); } } diff --git a/client/rpc/src/author/tests.rs b/client/rpc/src/author/tests.rs index 3093cd9d3b..8b956c23a5 100644 --- a/client/rpc/src/author/tests.rs +++ b/client/rpc/src/author/tests.rs @@ -21,7 +21,8 @@ use assert_matches::assert_matches; use codec::Encode; use sp_core::{ H256, blake2_256, hexdisplay::HexDisplay, testing::{ED25519, SR25519, KeyStore}, - traits::BareCryptoStorePtr, ed25519, crypto::{Pair, Public}, + traits::BareCryptoStorePtr, ed25519, sr25519, + crypto::{CryptoTypePublicPair, Pair, Public}, }; use rpc::futures::Stream as _; use substrate_test_runtime_client::{ @@ -173,7 +174,7 @@ fn should_return_pending_extrinsics() { let ex = uxt(AccountKeyring::Alice, 0); AuthorApi::submit_extrinsic(&p, ex.encode().into()).wait().unwrap(); - assert_matches!( + assert_matches!( p.pending_extrinsics(), Ok(ref expected) if *expected == vec![Bytes(ex.encode())] ); @@ -199,7 +200,7 @@ fn should_remove_extrinsics() { hash::ExtrinsicOrHash::Extrinsic(ex1.encode().into()), ]).unwrap(); - assert_eq!(removed.len(), 3); + assert_eq!(removed.len(), 3); } #[test] @@ -215,10 +216,9 @@ fn should_insert_key() { key_pair.public().0.to_vec().into(), ).expect("Insert key"); - let store_key_pair = setup.keystore.read() - .ed25519_key_pair(ED25519, &key_pair.public()).expect("Key exists in store"); + let public_keys = setup.keystore.read().keys(ED25519).unwrap(); - assert_eq!(key_pair.public(), store_key_pair.public()); + assert!(public_keys.contains(&CryptoTypePublicPair(ed25519::CRYPTO_ID, key_pair.public().to_raw_vec()))); } #[test] @@ -231,18 +231,11 @@ fn should_rotate_keys() { let session_keys = SessionKeys::decode(&mut &new_public_keys[..]) .expect("SessionKeys decode successfully"); - let ed25519_key_pair = setup.keystore.read().ed25519_key_pair( - ED25519, - &session_keys.ed25519.clone().into(), - ).expect("ed25519 key exists in store"); - - let sr25519_key_pair = setup.keystore.read().sr25519_key_pair( - SR25519, - &session_keys.sr25519.clone().into(), - ).expect("sr25519 key exists in store"); + let ed25519_public_keys = setup.keystore.read().keys(ED25519).unwrap(); + let sr25519_public_keys = setup.keystore.read().keys(SR25519).unwrap(); - assert_eq!(session_keys.ed25519, ed25519_key_pair.public().into()); - assert_eq!(session_keys.sr25519, sr25519_key_pair.public().into()); + assert!(ed25519_public_keys.contains(&CryptoTypePublicPair(ed25519::CRYPTO_ID, session_keys.ed25519.to_raw_vec()))); + assert!(sr25519_public_keys.contains(&CryptoTypePublicPair(sr25519::CRYPTO_ID, session_keys.sr25519.to_raw_vec()))); } #[test] diff --git a/primitives/application-crypto/src/ed25519.rs b/primitives/application-crypto/src/ed25519.rs index 414715a106..5be79ff4f7 100644 --- a/primitives/application-crypto/src/ed25519.rs +++ b/primitives/application-crypto/src/ed25519.rs @@ -23,12 +23,27 @@ use sp_std::vec::Vec; pub use sp_core::ed25519::*; mod app { + use sp_core::crypto::{CryptoTypePublicPair, Public as TraitPublic}; use sp_core::testing::ED25519; + use sp_core::ed25519::CRYPTO_ID; + crate::app_crypto!(super, ED25519); impl crate::traits::BoundToRuntimeAppPublic for Public { type Public = Self; } + + impl From for CryptoTypePublicPair { + fn from(key: Public) -> Self { + (&key).into() + } + } + + impl From<&Public> for CryptoTypePublicPair { + fn from(key: &Public) -> Self { + CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) + } + } } pub use app::{Public as AppPublic, Signature as AppSignature}; diff --git a/primitives/application-crypto/src/lib.rs b/primitives/application-crypto/src/lib.rs index b7c9ccaa98..07e2b45106 100644 --- a/primitives/application-crypto/src/lib.rs +++ b/primitives/application-crypto/src/lib.rs @@ -21,11 +21,11 @@ #![cfg_attr(not(feature = "std"), no_std)] #[doc(hidden)] -pub use sp_core::{self, crypto::{CryptoType, Public, Derive, IsWrappedBy, Wraps}, RuntimeDebug}; +pub use sp_core::{self, crypto::{CryptoType, CryptoTypePublicPair, Public, Derive, IsWrappedBy, Wraps}, RuntimeDebug}; #[doc(hidden)] #[cfg(feature = "full_crypto")] pub use sp_core::crypto::{SecretStringError, DeriveJunction, Ss58Codec, Pair}; -pub use sp_core::{crypto::{KeyTypeId, key_types}}; +pub use sp_core::crypto::{CryptoTypeId, KeyTypeId, key_types}; #[doc(hidden)] pub use codec; diff --git a/primitives/application-crypto/src/sr25519.rs b/primitives/application-crypto/src/sr25519.rs index 59c6f19b6f..a0f2cef1c4 100644 --- a/primitives/application-crypto/src/sr25519.rs +++ b/primitives/application-crypto/src/sr25519.rs @@ -23,12 +23,27 @@ use sp_std::vec::Vec; pub use sp_core::sr25519::*; mod app { + use sp_core::crypto::{CryptoTypePublicPair, Public as TraitPublic}; use sp_core::testing::SR25519; + use sp_core::sr25519::CRYPTO_ID; + crate::app_crypto!(super, SR25519); impl crate::traits::BoundToRuntimeAppPublic for Public { type Public = Self; } + + impl From for CryptoTypePublicPair { + fn from(key: Public) -> Self { + (&key).into() + } + } + + impl From<&Public> for CryptoTypePublicPair { + fn from(key: &Public) -> Self { + CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) + } + } } pub use app::{Public as AppPublic, Signature as AppSignature}; diff --git a/primitives/application-crypto/test/src/ed25519.rs b/primitives/application-crypto/test/src/ed25519.rs index 400edfd6ae..1d72962829 100644 --- a/primitives/application-crypto/test/src/ed25519.rs +++ b/primitives/application-crypto/test/src/ed25519.rs @@ -17,7 +17,10 @@ //! Integration tests for ed25519 use sp_runtime::generic::BlockId; -use sp_core::{testing::{KeyStore, ED25519}, crypto::Pair}; +use sp_core::{ + crypto::Pair, + testing::{KeyStore, ED25519}, +}; use substrate_test_runtime_client::{ TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, runtime::TestAPI, @@ -33,8 +36,7 @@ fn ed25519_works_in_runtime() { .test_ed25519_crypto(&BlockId::Number(0)) .expect("Tests `ed25519` crypto."); - let key_pair = keystore.read().ed25519_key_pair(ED25519, &public.as_ref()) - .expect("There should be at a `ed25519` key in the keystore for the given public key."); - - assert!(AppPair::verify(&signature, "ed25519", &AppPublic::from(key_pair.public()))); + let supported_keys = keystore.read().keys(ED25519).unwrap(); + assert!(supported_keys.contains(&public.clone().into())); + assert!(AppPair::verify(&signature, "ed25519", &AppPublic::from(public))); } diff --git a/primitives/application-crypto/test/src/sr25519.rs b/primitives/application-crypto/test/src/sr25519.rs index 49bb3c2a83..f2c7c48b2b 100644 --- a/primitives/application-crypto/test/src/sr25519.rs +++ b/primitives/application-crypto/test/src/sr25519.rs @@ -18,7 +18,10 @@ use sp_runtime::generic::BlockId; -use sp_core::{testing::{KeyStore, SR25519}, crypto::Pair}; +use sp_core::{ + crypto::Pair, + testing::{KeyStore, SR25519}, +}; use substrate_test_runtime_client::{ TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, runtime::TestAPI, @@ -34,8 +37,7 @@ fn sr25519_works_in_runtime() { .test_sr25519_crypto(&BlockId::Number(0)) .expect("Tests `sr25519` crypto."); - let key_pair = keystore.read().sr25519_key_pair(SR25519, public.as_ref()) - .expect("There should be at a `sr25519` key in the keystore for the given public key."); - - assert!(AppPair::verify(&signature, "sr25519", &AppPublic::from(key_pair.public()))); + let supported_keys = keystore.read().keys(SR25519).unwrap(); + assert!(supported_keys.contains(&public.clone().into())); + assert!(AppPair::verify(&signature, "sr25519", &AppPublic::from(public))); } diff --git a/primitives/authority-discovery/src/lib.rs b/primitives/authority-discovery/src/lib.rs index 8926825525..68680ad759 100644 --- a/primitives/authority-discovery/src/lib.rs +++ b/primitives/authority-discovery/src/lib.rs @@ -21,8 +21,25 @@ use sp_std::vec::Vec; mod app { - use sp_application_crypto::{app_crypto, key_types::AUTHORITY_DISCOVERY, sr25519}; + use sp_application_crypto::{ + CryptoTypePublicPair, + key_types::AUTHORITY_DISCOVERY, + Public as _, + app_crypto, + sr25519}; app_crypto!(sr25519, AUTHORITY_DISCOVERY); + + impl From for CryptoTypePublicPair { + fn from(key: Public) -> Self { + (&key).into() + } + } + + impl From<&Public> for CryptoTypePublicPair { + fn from(key: &Public) -> Self { + CryptoTypePublicPair(sr25519::CRYPTO_ID, key.to_raw_vec()) + } + } } sp_application_crypto::with_pair! { diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index 6301600921..f16c160960 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -21,6 +21,7 @@ use crate::{sr25519, ed25519}; use sp_std::hash::Hash; use sp_std::vec::Vec; +use sp_std::str; #[cfg(feature = "std")] use sp_std::convert::TryInto; use sp_std::convert::TryFrom; @@ -33,7 +34,8 @@ use codec::{Encode, Decode}; use regex::Regex; #[cfg(feature = "std")] use base58::{FromBase58, ToBase58}; - +#[cfg(feature = "std")] +use crate::hexdisplay::HexDisplay; use zeroize::Zeroize; #[doc(hidden)] pub use sp_std::ops::Deref; @@ -539,7 +541,9 @@ impl + AsRef<[u8]> + Default + Derive> Ss58Codec for T { } /// Trait suitable for typical cryptographic PKI key public type. -pub trait Public: AsRef<[u8]> + AsMut<[u8]> + Default + Derive + CryptoType + PartialEq + Eq + Clone + Send + Sync { +pub trait Public: + AsRef<[u8]> + AsMut<[u8]> + Default + Derive + CryptoType + PartialEq + Eq + Clone + Send + Sync +{ /// A new instance from the given slice. /// /// NOTE: No checking goes on to ensure this is a real public key. Only use it if @@ -955,6 +959,27 @@ impl<'a> TryFrom<&'a str> for KeyTypeId { } } +/// An identifier for a specific cryptographic algorithm used by a key pair +#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)] +pub struct CryptoTypeId(pub [u8; 4]); + +/// A type alias of CryptoTypeId & a public key +#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)] +pub struct CryptoTypePublicPair(pub CryptoTypeId, pub Vec); + +#[cfg(feature = "std")] +impl sp_std::fmt::Display for CryptoTypePublicPair { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + let id = match str::from_utf8(&(self.0).0[..]) { + Ok(id) => id.to_string(), + Err(_) => { + format!("{:#?}", self.0) + } + }; + write!(f, "{}-{}", id, HexDisplay::from(&self.1)) + } +} + /// Known key types; this also functions as a global registry of key types for projects wishing to /// avoid collisions with each other. /// diff --git a/primitives/core/src/ecdsa.rs b/primitives/core/src/ecdsa.rs index 548ae49b55..8a45157844 100644 --- a/primitives/core/src/ecdsa.rs +++ b/primitives/core/src/ecdsa.rs @@ -36,10 +36,13 @@ use crate::{hashing::blake2_256, crypto::{Pair as TraitPair, DeriveJunction, Sec use crate::crypto::Ss58Codec; #[cfg(feature = "std")] use serde::{de, Serializer, Serialize, Deserializer, Deserialize}; -use crate::crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}; +use crate::crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive, CryptoTypeId}; #[cfg(feature = "full_crypto")] use secp256k1::{PublicKey, SecretKey}; +/// An identifier used to match public keys against ecdsa keys +pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"ecds"); + /// A secret seed (which is bytewise essentially equivalent to a SecretKey). /// /// We need it as a different type because `Seed` is expected to be AsRef<[u8]>. diff --git a/primitives/core/src/ed25519.rs b/primitives/core/src/ed25519.rs index 5e04dcceff..abeac05388 100644 --- a/primitives/core/src/ed25519.rs +++ b/primitives/core/src/ed25519.rs @@ -38,10 +38,13 @@ use crate::crypto::{Pair as TraitPair, DeriveJunction, SecretStringError}; use crate::crypto::Ss58Codec; #[cfg(feature = "std")] use serde::{de, Serializer, Serialize, Deserializer, Deserialize}; -use crate::{crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}}; +use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId}; use sp_runtime_interface::pass_by::PassByInner; use sp_std::ops::Deref; +/// An identifier used to match public keys against ed25519 keys +pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"ed25"); + /// A secret seed. It's not called a "secret key" because ring doesn't expose the secret keys /// of the key pair (yeah, dumb); as such we're forced to remember the seed manually if we /// will need it later (such as for HDKD). @@ -378,6 +381,18 @@ impl TraitPublic for Public { impl Derive for Public {} +impl From for CryptoTypePublicPair { + fn from(key: Public) -> Self { + (&key).into() + } +} + +impl From<&Public> for CryptoTypePublicPair { + fn from(key: &Public) -> Self { + CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) + } +} + /// Derive a single hard junction. #[cfg(feature = "full_crypto")] fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed { diff --git a/primitives/core/src/sr25519.rs b/primitives/core/src/sr25519.rs index de643dbb0a..717952eb01 100644 --- a/primitives/core/src/sr25519.rs +++ b/primitives/core/src/sr25519.rs @@ -39,7 +39,7 @@ use crate::crypto::{ #[cfg(feature = "std")] use crate::crypto::Ss58Codec; -use crate::{crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}}; +use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId}; use crate::hash::{H256, H512}; use codec::{Encode, Decode}; use sp_std::ops::Deref; @@ -54,6 +54,9 @@ use sp_runtime_interface::pass_by::PassByInner; #[cfg(feature = "full_crypto")] const SIGNING_CTX: &[u8] = b"substrate"; +/// An identifier used to match public keys against sr25519 keys +pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"sr25"); + /// An Schnorrkel/Ristretto x25519 ("sr25519") public key. #[cfg_attr(feature = "full_crypto", derive(Hash))] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Encode, Decode, Default, PassByInner)] @@ -390,6 +393,18 @@ impl TraitPublic for Public { } } +impl From for CryptoTypePublicPair { + fn from(key: Public) -> Self { + (&key).into() + } +} + +impl From<&Public> for CryptoTypePublicPair { + fn from(key: &Public) -> Self { + CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) + } +} + #[cfg(feature = "std")] impl From for Pair { fn from(sec: MiniSecretKey) -> Pair { @@ -599,7 +614,7 @@ impl CryptoType for Pair { #[cfg(test)] mod compatibility_test { use super::*; - use crate::crypto::{DEV_PHRASE}; + use crate::crypto::DEV_PHRASE; use hex_literal::hex; // NOTE: tests to ensure addresses that are created with the `0.1.x` version (pre-audit) are diff --git a/primitives/core/src/testing.rs b/primitives/core/src/testing.rs index 247323f970..b5e6f4c7af 100644 --- a/primitives/core/src/testing.rs +++ b/primitives/core/src/testing.rs @@ -16,10 +16,16 @@ //! Types that should only be used for testing! +use crate::crypto::{KeyTypeId, CryptoTypePublicPair}; #[cfg(feature = "std")] -use crate::{ed25519, sr25519, crypto::{Public, Pair}}; -use crate::crypto::KeyTypeId; - +use crate::{ + crypto::{Pair, Public}, + ed25519, sr25519, + traits::BareCryptoStoreError +}; +#[cfg(feature = "std")] +use std::collections::HashSet; +use codec::Encode; /// Key type for generic Ed25519 key. pub const ED25519: KeyTypeId = KeyTypeId(*b"ed25"); /// Key type for generic Sr 25519 key. @@ -39,10 +45,41 @@ impl KeyStore { pub fn new() -> crate::traits::BareCryptoStorePtr { std::sync::Arc::new(parking_lot::RwLock::new(Self::default())) } + + fn sr25519_key_pair(&self, id: KeyTypeId, pub_key: &sr25519::Public) -> Option { + self.keys.get(&id) + .and_then(|inner| + inner.get(pub_key.as_slice()) + .map(|s| sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid")) + ) + } + + fn ed25519_key_pair(&self, id: KeyTypeId, pub_key: &ed25519::Public) -> Option { + self.keys.get(&id) + .and_then(|inner| + inner.get(pub_key.as_slice()) + .map(|s| ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid")) + ) + } + } #[cfg(feature = "std")] impl crate::traits::BareCryptoStore for KeyStore { + fn keys(&self, id: KeyTypeId) -> Result, BareCryptoStoreError> { + self.keys + .get(&id) + .map(|map| { + Ok(map.keys() + .fold(Vec::new(), |mut v, k| { + v.push(CryptoTypePublicPair(sr25519::CRYPTO_ID, k.clone())); + v.push(CryptoTypePublicPair(ed25519::CRYPTO_ID, k.clone())); + v + })) + }) + .unwrap_or(Ok(vec![])) + } + fn sr25519_public_keys(&self, id: KeyTypeId) -> Vec { self.keys.get(&id) .map(|keys| @@ -58,10 +95,11 @@ impl crate::traits::BareCryptoStore for KeyStore { &mut self, id: KeyTypeId, seed: Option<&str>, - ) -> Result { + ) -> Result { match seed { Some(seed) => { - let pair = sr25519::Pair::from_string(seed, None).expect("Generates an `sr25519` pair."); + let pair = sr25519::Pair::from_string(seed, None) + .map_err(|_| BareCryptoStoreError::ValidationError("Generates an `sr25519` pair.".to_owned()))?; self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into()); Ok(pair.public()) }, @@ -73,14 +111,6 @@ impl crate::traits::BareCryptoStore for KeyStore { } } - fn sr25519_key_pair(&self, id: KeyTypeId, pub_key: &sr25519::Public) -> Option { - self.keys.get(&id) - .and_then(|inner| - inner.get(pub_key.as_slice()) - .map(|s| sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid")) - ) - } - fn ed25519_public_keys(&self, id: KeyTypeId) -> Vec { self.keys.get(&id) .map(|keys| @@ -96,10 +126,11 @@ impl crate::traits::BareCryptoStore for KeyStore { &mut self, id: KeyTypeId, seed: Option<&str>, - ) -> Result { + ) -> Result { match seed { Some(seed) => { - let pair = ed25519::Pair::from_string(seed, None).expect("Generates an `ed25519` pair."); + let pair = ed25519::Pair::from_string(seed, None) + .map_err(|_| BareCryptoStoreError::ValidationError("Generates an `ed25519` pair.".to_owned()))?; self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into()); Ok(pair.public()) }, @@ -111,14 +142,6 @@ impl crate::traits::BareCryptoStore for KeyStore { } } - fn ed25519_key_pair(&self, id: KeyTypeId, pub_key: &ed25519::Public) -> Option { - self.keys.get(&id) - .and_then(|inner| - inner.get(pub_key.as_slice()) - .map(|s| ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid")) - ) - } - fn insert_unknown(&mut self, id: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> { self.keys.entry(id).or_default().insert(public.to_owned(), suri.to_string()); Ok(()) @@ -131,6 +154,40 @@ impl crate::traits::BareCryptoStore for KeyStore { fn has_keys(&self, public_keys: &[(Vec, KeyTypeId)]) -> bool { public_keys.iter().all(|(k, t)| self.keys.get(&t).and_then(|s| s.get(k)).is_some()) } + + fn supported_keys( + &self, + id: KeyTypeId, + keys: Vec, + ) -> std::result::Result, BareCryptoStoreError> { + let provided_keys = keys.into_iter().collect::>(); + let all_keys = self.keys(id)?.into_iter().collect::>(); + + Ok(provided_keys.intersection(&all_keys).cloned().collect()) + } + + fn sign_with( + &self, + id: KeyTypeId, + key: &CryptoTypePublicPair, + msg: &[u8], + ) -> Result, BareCryptoStoreError> { + match key.0 { + ed25519::CRYPTO_ID => { + let key_pair: ed25519::Pair = self + .ed25519_key_pair(id, &ed25519::Public::from_slice(key.1.as_slice())) + .ok_or(BareCryptoStoreError::PairNotFound("ed25519".to_owned()))?; + return Ok(key_pair.sign(msg).encode()); + } + sr25519::CRYPTO_ID => { + let key_pair: sr25519::Pair = self + .sr25519_key_pair(id, &sr25519::Public::from_slice(key.1.as_slice())) + .ok_or(BareCryptoStoreError::PairNotFound("sr25519".to_owned()))?; + return Ok(key_pair.sign(msg).encode()); + } + _ => Err(BareCryptoStoreError::KeyNotSupported(id)) + } + } } /// Macro for exporting functions from wasm in with the expected signature for using it with the @@ -247,11 +304,9 @@ mod tests { .ed25519_generate_new(ED25519, None) .expect("Generates key"); - let store_key_pair = store.read() - .ed25519_key_pair(ED25519, &public) - .expect("Key should exists in store"); + let public_keys = store.read().keys(ED25519).unwrap(); - assert_eq!(public, store_key_pair.public()); + assert!(public_keys.contains(&public.into())); } #[test] @@ -267,11 +322,8 @@ mod tests { key_pair.public().as_ref(), ).expect("Inserts unknown key"); - let store_key_pair = store.read().sr25519_key_pair( - SR25519, - &key_pair.public(), - ).expect("Gets key pair from keystore"); + let public_keys = store.read().keys(SR25519).unwrap(); - assert_eq!(key_pair.public(), store_key_pair.public()); + assert!(public_keys.contains(&key_pair.public().into())); } } diff --git a/primitives/core/src/traits.rs b/primitives/core/src/traits.rs index 21a0b77ca7..14839fb585 100644 --- a/primitives/core/src/traits.rs +++ b/primitives/core/src/traits.rs @@ -16,14 +16,35 @@ //! Shareable Substrate traits. -use crate::{crypto::KeyTypeId, ed25519, sr25519}; +use crate::{ + crypto::{KeyTypeId, CryptoTypePublicPair}, + ed25519, sr25519, +}; use std::{ - fmt::{Debug, Display}, panic::UnwindSafe, sync::Arc, borrow::Cow, + borrow::Cow, + fmt::{Debug, Display}, + panic::UnwindSafe, + sync::Arc, }; pub use sp_externalities::{Externalities, ExternalitiesExt}; +/// BareCryptoStore error +#[derive(Debug)] +pub enum BareCryptoStoreError { + /// Public key type is not supported + KeyNotSupported(KeyTypeId), + /// Pair not found for public key and KeyTypeId + PairNotFound(String), + /// Validation error + ValidationError(String), + /// Keystore unavailable + Unavailable, + /// Programming errors + Other(String) +} + /// Something that generates, stores and provides access to keys. pub trait BareCryptoStore: Send + Sync { /// Returns all sr25519 public keys for the given key type. @@ -37,10 +58,7 @@ pub trait BareCryptoStore: Send + Sync { &mut self, id: KeyTypeId, seed: Option<&str>, - ) -> Result; - /// Returns the sr25519 key pair for the given key type and public key combination. - fn sr25519_key_pair(&self, id: KeyTypeId, pub_key: &sr25519::Public) -> Option; - + ) -> Result; /// Returns all ed25519 public keys for the given key type. fn ed25519_public_keys(&self, id: KeyTypeId) -> Vec; /// Generate a new ed25519 key pair for the given key type and an optional seed. @@ -52,10 +70,7 @@ pub trait BareCryptoStore: Send + Sync { &mut self, id: KeyTypeId, seed: Option<&str>, - ) -> Result; - - /// Returns the ed25519 key pair for the given key type and public key combination. - fn ed25519_key_pair(&self, id: KeyTypeId, pub_key: &ed25519::Public) -> Option; + ) -> Result; /// Insert a new key. This doesn't require any known of the crypto; but a public key must be /// manually provided. @@ -67,11 +82,78 @@ pub trait BareCryptoStore: Send + Sync { /// Get the password for this store. fn password(&self) -> Option<&str>; + /// Find intersection between provided keys and supported keys + /// + /// Provided a list of (CryptoTypeId,[u8]) pairs, this would return + /// a filtered set of public keys which are supported by the keystore. + fn supported_keys( + &self, + id: KeyTypeId, + keys: Vec + ) -> Result, BareCryptoStoreError>; + /// List all supported keys + /// + /// Returns a set of public keys the signer supports. + fn keys(&self, id: KeyTypeId) -> Result, BareCryptoStoreError>; /// Checks if the private keys for the given public key and key type combinations exist. /// /// Returns `true` iff all private keys could be found. fn has_keys(&self, public_keys: &[(Vec, KeyTypeId)]) -> bool; + + /// Sign with key + /// + /// Signs a message with the private key that matches + /// the public key passed. + /// + /// Returns the SCALE encoded signature if key is found & supported, + /// an error otherwise. + fn sign_with( + &self, + id: KeyTypeId, + key: &CryptoTypePublicPair, + msg: &[u8], + ) -> Result, BareCryptoStoreError>; + + /// Sign with any key + /// + /// Given a list of public keys, find the first supported key and + /// sign the provided message with that key. + /// + /// Returns a tuple of the used key and the signature + fn sign_with_any( + &self, + id: KeyTypeId, + keys: Vec, + msg: &[u8] + ) -> Result<(CryptoTypePublicPair, Vec), BareCryptoStoreError> { + if keys.len() == 1 { + return self.sign_with(id, &keys[0], msg).map(|s| (keys[0].clone(), s)); + } else { + for k in self.supported_keys(id, keys)? { + if let Ok(sign) = self.sign_with(id, &k, msg) { + return Ok((k, sign)); + } + } + } + Err(BareCryptoStoreError::KeyNotSupported(id)) + } + + /// Sign with all keys + /// + /// Provided a list of public keys, sign a message with + /// each key given that the key is supported. + /// + /// Returns a list of `Result`s each representing the signature of each key or + /// a BareCryptoStoreError for non-supported keys. + fn sign_with_all( + &self, + id: KeyTypeId, + keys: Vec, + msg: &[u8], + ) -> Result, BareCryptoStoreError>>, ()>{ + Ok(keys.iter().map(|k| self.sign_with(id, k, msg)).collect()) + } } /// A pointer to the key store. diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index 7800658974..bc49df159e 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -411,8 +411,9 @@ pub trait Crypto { self.extension::() .expect("No `keystore` associated for the current context!") .read() - .ed25519_key_pair(id, &pub_key) - .map(|k| k.sign(msg)) + .sign_with(id, &pub_key.into(), msg) + .map(|sig| ed25519::Signature::from_slice(sig.as_slice())) + .ok() } /// Verify an `ed25519` signature. @@ -463,8 +464,9 @@ pub trait Crypto { self.extension::() .expect("No `keystore` associated for the current context!") .read() - .sr25519_key_pair(id, &pub_key) - .map(|k| k.sign(msg)) + .sign_with(id, &pub_key.into(), msg) + .map(|sig| sr25519::Signature::from_slice(sig.as_slice())) + .ok() } /// Verify an `sr25519` signature. -- GitLab From d21e3246eefda24bee316912ec3135c1d76460c8 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 30 Mar 2020 13:33:46 +0200 Subject: [PATCH 106/300] Fix tried to send handshake twice (#5413) * Fix tried to send handshake twice * Fix wrong boolean * Change to debug --- .../protocol/generic_proto/handler/group.rs | 9 +++++- .../generic_proto/handler/notif_in.rs | 28 +++++++++++++------ .../generic_proto/upgrade/notifications.rs | 15 +++++----- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/client/network/src/protocol/generic_proto/handler/group.rs b/client/network/src/protocol/generic_proto/handler/group.rs index b4321234b0..69a519134a 100644 --- a/client/network/src/protocol/generic_proto/handler/group.rs +++ b/client/network/src/protocol/generic_proto/handler/group.rs @@ -63,7 +63,8 @@ use libp2p::swarm::{ SubstreamProtocol, NegotiatedSubstream, }; -use log::error; +use log::{debug, error}; +use sp_runtime::ConsensusEngineId; use std::{borrow::Cow, error, io, str, task::{Context, Poll}}; /// Implements the `IntoProtocolsHandler` trait of libp2p. @@ -289,6 +290,9 @@ impl ProtocolsHandler for NotifsHandler { fn inject_event(&mut self, message: NotifsHandlerIn) { match message { NotifsHandlerIn::Enable => { + if let EnabledState::Enabled = self.enabled { + debug!("enabling already-enabled handler"); + } self.enabled = EnabledState::Enabled; self.legacy.inject_event(LegacyProtoHandlerIn::Enable); for handler in &mut self.out_handlers { @@ -301,6 +305,9 @@ impl ProtocolsHandler for NotifsHandler { } }, NotifsHandlerIn::Disable => { + if let EnabledState::Disabled = self.enabled { + debug!("disabling already-disabled handler"); + } self.legacy.inject_event(LegacyProtoHandlerIn::Disable); // The notifications protocols start in the disabled state. If we were in the // "Initial" state, then we shouldn't disable the notifications protocols again. diff --git a/client/network/src/protocol/generic_proto/handler/notif_in.rs b/client/network/src/protocol/generic_proto/handler/notif_in.rs index 4e16fb1af4..7558d1d361 100644 --- a/client/network/src/protocol/generic_proto/handler/notif_in.rs +++ b/client/network/src/protocol/generic_proto/handler/notif_in.rs @@ -36,7 +36,7 @@ use libp2p::swarm::{ }; use log::{error, warn}; use smallvec::SmallVec; -use std::{borrow::Cow, fmt, pin::Pin, str, task::{Context, Poll}}; +use std::{borrow::Cow, fmt, pin::Pin, task::{Context, Poll}}; /// Implements the `IntoProtocolsHandler` trait of libp2p. /// @@ -156,16 +156,19 @@ impl ProtocolsHandler for NotifsInHandler { &mut self, (msg, proto): >::Output ) { + // If a substream already exists, we drop it and replace it with the new incoming one. if self.substream.is_some() { - warn!( - target: "sub-libp2p", - "Received duplicate inbound notifications substream for {:?}", - str::from_utf8(self.in_protocol.protocol_name()), - ); - return; + self.events_queue.push(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Closed)); } + // Note that we drop the existing substream, which will send an equivalent to a TCP "RST" + // to the remote and force-close the substream. It might seem like an unclean way to get + // rid of a substream. However, keep in mind that it is invalid for the remote to open + // multiple such substreams, and therefore sending a "RST" is the correct thing to do. + // Also note that we have already closed our writing side during the initial handshake, + // and we can't close "more" than that anyway. self.substream = Some(proto); + self.events_queue.push(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::OpenRequest(msg))); self.pending_accept_refuses = self.pending_accept_refuses .checked_add(1) @@ -235,8 +238,15 @@ impl ProtocolsHandler for NotifsInHandler { match self.substream.as_mut().map(|s| Stream::poll_next(Pin::new(s), cx)) { None | Some(Poll::Pending) => {}, - Some(Poll::Ready(Some(Ok(msg)))) => - return Poll::Ready(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Notif(msg))), + Some(Poll::Ready(Some(Ok(msg)))) => { + if self.pending_accept_refuses != 0 { + warn!( + target: "sub-libp2p", + "Bad state in inbound-only handler: notif before accepting substream" + ); + } + return Poll::Ready(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Notif(msg))) + }, Some(Poll::Ready(None)) | Some(Poll::Ready(Some(Err(_)))) => { self.substream = None; return Poll::Ready(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Closed)); diff --git a/client/network/src/protocol/generic_proto/upgrade/notifications.rs b/client/network/src/protocol/generic_proto/upgrade/notifications.rs index 68898a08fe..b6ae1425f1 100644 --- a/client/network/src/protocol/generic_proto/upgrade/notifications.rs +++ b/client/network/src/protocol/generic_proto/upgrade/notifications.rs @@ -164,12 +164,9 @@ where TSubstream: AsyncRead + AsyncWrite, { /// Sends the handshake in order to inform the remote that we accept the substream. pub fn send_handshake(&mut self, message: impl Into>) { - match self.handshake { - NotificationsInSubstreamHandshake::NotSent => {} - _ => { - error!(target: "sub-libp2p", "Tried to send handshake twice"); - return; - } + if !matches!(self.handshake, NotificationsInSubstreamHandshake::NotSent) { + error!(target: "sub-libp2p", "Tried to send handshake twice"); + return; } self.handshake = NotificationsInSubstreamHandshake::PendingSend(message.into()); @@ -189,8 +186,10 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin, match mem::replace(this.handshake, NotificationsInSubstreamHandshake::Sent) { NotificationsInSubstreamHandshake::Sent => return Stream::poll_next(this.socket.as_mut(), cx), - NotificationsInSubstreamHandshake::NotSent => - return Poll::Pending, + NotificationsInSubstreamHandshake::NotSent => { + *this.handshake = NotificationsInSubstreamHandshake::NotSent; + return Poll::Pending + }, NotificationsInSubstreamHandshake::PendingSend(msg) => match Sink::poll_ready(this.socket.as_mut(), cx) { Poll::Ready(_) => { -- GitLab From b1035fc4d0c2ad2ae87a53abd2fcff50bd9d184c Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 30 Mar 2020 04:36:24 -0700 Subject: [PATCH 107/300] pub instead of remove (#5451) --- primitives/arithmetic/src/per_things.rs | 142 ++++++++++++------------ 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index fa02b4ec61..cbbeeae0cc 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -54,8 +54,8 @@ pub trait PerThing: /// Build this type from a percent. Equivalent to `Self::from_parts(x * Self::ACCURACY / 100)` /// but more accurate. fn from_percent(x: Self::Inner) -> Self { - let a = x.min(100.into()); - let b = Self::ACCURACY; + let a = x.min(100.into()); + let b = Self::ACCURACY; // if Self::ACCURACY % 100 > 0 then we need the correction for accuracy let c = rational_mul_correction::(b, a, 100.into(), Rounding::Nearest); Self::from_parts(a / 100.into() * b + c) @@ -64,12 +64,12 @@ pub trait PerThing: /// Return the product of multiplication of this value by itself. fn square(self) -> Self { let p = Self::Upper::from(self.deconstruct()); - let q = Self::Upper::from(Self::ACCURACY); + let q = Self::Upper::from(Self::ACCURACY); Self::from_rational_approximation(p * p, q * q) } - + /// Multiplication that always rounds down to a whole number. The standard `Mul` rounds to the - /// nearest whole number. + /// nearest whole number. /// /// ```rust /// # use sp_arithmetic::{Percent, PerThing}; @@ -91,7 +91,7 @@ pub trait PerThing: } /// Multiplication that always rounds the result up to a whole number. The standard `Mul` - /// rounds to the nearest whole number. + /// rounds to the nearest whole number. /// /// ```rust /// # use sp_arithmetic::{Percent, PerThing}; @@ -100,7 +100,7 @@ pub trait PerThing: /// assert_eq!(Percent::from_percent(34) * 10u64, 3); /// assert_eq!(Percent::from_percent(36) * 10u64, 4); /// - /// // round up + /// // round up /// assert_eq!(Percent::from_percent(34).mul_ceil(10u64), 4); /// assert_eq!(Percent::from_percent(36).mul_ceil(10u64), 4); /// # } @@ -134,7 +134,7 @@ pub trait PerThing: /// ```rust /// # use sp_arithmetic::{Percent, PerThing}; /// # fn main () { - /// // round to nearest + /// // round to nearest /// assert_eq!(Percent::from_percent(60).saturating_reciprocal_mul(10u64), 17); /// // round down /// assert_eq!(Percent::from_percent(60).saturating_reciprocal_mul_floor(10u64), 16); @@ -153,7 +153,7 @@ pub trait PerThing: /// ```rust /// # use sp_arithmetic::{Percent, PerThing}; /// # fn main () { - /// // round to nearest + /// // round to nearest /// assert_eq!(Percent::from_percent(61).saturating_reciprocal_mul(10u64), 16); /// // round up /// assert_eq!(Percent::from_percent(61).saturating_reciprocal_mul_ceil(10u64), 17); @@ -166,7 +166,7 @@ pub trait PerThing: saturating_reciprocal_mul::(b, self.deconstruct(), Rounding::Up) } - /// Consume self and return the number of parts per thing. + /// Consume self and return the number of parts per thing. fn deconstruct(self) -> Self::Inner; /// Build this type from a number of parts per thing. @@ -199,7 +199,7 @@ pub trait PerThing: ops::Div + ops::Rem + ops::Add; } -/// The rounding method to use. +/// The rounding method to use. /// /// `Perthing`s are unsigned so `Up` means towards infinity and `Down` means towards zero. /// `Nearest` will round an exact half down. @@ -209,23 +209,23 @@ enum Rounding { Nearest, } -/// Saturating reciprocal multiplication. Compute `x / self`, saturating at the numeric +/// Saturating reciprocal multiplication. Compute `x / self`, saturating at the numeric /// bounds instead of overflowing. fn saturating_reciprocal_mul( - x: N, + x: N, part: P::Inner, rounding: Rounding, ) -> N -where +where N: Clone + From + UniqueSaturatedInto + ops::Div + ops::Mul + ops::Add + ops::Rem + Saturating, P: PerThing, { let maximum: N = P::ACCURACY.into(); let c = rational_mul_correction::( - x.clone(), - P::ACCURACY, - part, + x.clone(), + P::ACCURACY, + part, rounding, ); (x / part.into()).saturating_mul(maximum).saturating_add(c) @@ -233,11 +233,11 @@ where /// Overflow-prune multiplication. Accurately multiply a value by `self` without overflowing. fn overflow_prune_mul( - x: N, + x: N, part: P::Inner, rounding: Rounding, -) -> N -where +) -> N +where N: Clone + From + UniqueSaturatedInto + ops::Div + ops::Mul + ops::Add + ops::Rem, P: PerThing, @@ -245,9 +245,9 @@ where let maximum: N = P::ACCURACY.into(); let part_n: N = part.into(); let c = rational_mul_correction::( - x.clone(), - part, - P::ACCURACY, + x.clone(), + part, + P::ACCURACY, rounding, ); (x / maximum) * part_n + c @@ -258,15 +258,15 @@ where /// Take the remainder of `x / denom` and multiply by `numer / denom`. The result can be added /// to `x / denom * numer` for an accurate result. fn rational_mul_correction( - x: N, - numer: P::Inner, - denom: P::Inner, + x: N, + numer: P::Inner, + denom: P::Inner, rounding: Rounding, ) -> N -where +where N: From + UniqueSaturatedInto + ops::Div + ops::Mul + ops::Add + ops::Rem, - P: PerThing, + Output=N> + ops::Add + ops::Rem, + P: PerThing, { let numer_upper = P::Upper::from(numer); let denom_n = N::from(denom); @@ -282,7 +282,7 @@ where match rounding { // Already rounded down Rounding::Down => {}, - // Round up if the fractional part of the result is non-zero. + // Round up if the fractional part of the result is non-zero. Rounding::Up => if rem_mul_upper % denom_upper > 0.into() { // `rem * numer / denom` is less than `numer`, so this will not overflow. rem_mul_div_inner = rem_mul_div_inner + 1.into(); @@ -302,7 +302,7 @@ macro_rules! implement_per_thing { $name:ident, $test_mod:ident, [$($test_units:tt),+], - $max:tt, + $max:tt, $type:ty, $upper_type:ty, $title:expr $(,)? @@ -321,19 +321,19 @@ macro_rules! implement_per_thing { const ACCURACY: Self::Inner = $max; - /// Consume self and return the number of parts per thing. + /// Consume self and return the number of parts per thing. fn deconstruct(self) -> Self::Inner { self.0 } /// Build this type from a number of parts per thing. fn from_parts(parts: Self::Inner) -> Self { Self(parts.min($max)) } #[cfg(feature = "std")] - fn from_fraction(x: f64) -> Self { - Self::from_parts((x * $max as f64) as Self::Inner) + fn from_fraction(x: f64) -> Self { + Self::from_parts((x * $max as f64) as Self::Inner) } fn from_rational_approximation(p: N, q: N) -> Self - where N: Clone + Ord + From + TryInto + TryInto + where N: Clone + Ord + From + TryInto + TryInto + ops::Div + ops::Rem + ops::Add { let div_ceil = |x: N, f: N| -> N { @@ -449,7 +449,7 @@ macro_rules! implement_per_thing { ops::Add { PerThing::mul_floor(self, b) } - + /// See [`PerThing::mul_ceil`]. pub fn mul_ceil(self, b: N) -> N where N: Clone + From<$type> + UniqueSaturatedInto<$type> + @@ -459,23 +459,23 @@ macro_rules! implement_per_thing { } /// See [`PerThing::saturating_reciprocal_mul`]. - fn saturating_reciprocal_mul(self, b: N) -> N + pub fn saturating_reciprocal_mul(self, b: N) -> N where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + ops::Div + ops::Mul + ops::Add + Saturating { PerThing::saturating_reciprocal_mul(self, b) } - + /// See [`PerThing::saturating_reciprocal_mul_floor`]. - fn saturating_reciprocal_mul_floor(self, b: N) -> N + pub fn saturating_reciprocal_mul_floor(self, b: N) -> N where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + ops::Div + ops::Mul + ops::Add + Saturating { PerThing::saturating_reciprocal_mul_floor(self, b) } - + /// See [`PerThing::saturating_reciprocal_mul_ceil`]. - fn saturating_reciprocal_mul_ceil(self, b: N) -> N + pub fn saturating_reciprocal_mul_ceil(self, b: N) -> N where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + ops::Div + ops::Mul + ops::Add + Saturating { @@ -524,7 +524,7 @@ macro_rules! implement_per_thing { // x^2 always fits in Self::Upper if x fits in Self::Inner. // Verified by a test. s = Self::from_rational_approximation( - <$name as PerThing>::Upper::from(s.deconstruct()) * p, + <$name as PerThing>::Upper::from(s.deconstruct()) * p, q * q, ); } @@ -936,43 +936,43 @@ macro_rules! implement_per_thing { fn saturating_pow_works() { // x^0 == 1 assert_eq!( - $name::from_parts($max / 2).saturating_pow(0), + $name::from_parts($max / 2).saturating_pow(0), $name::from_parts($max), ); // x^1 == x assert_eq!( - $name::from_parts($max / 2).saturating_pow(1), + $name::from_parts($max / 2).saturating_pow(1), $name::from_parts($max / 2), ); // x^2 assert_eq!( - $name::from_parts($max / 2).saturating_pow(2), + $name::from_parts($max / 2).saturating_pow(2), $name::from_parts($max / 2).square(), ); // x^3 assert_eq!( - $name::from_parts($max / 2).saturating_pow(3), + $name::from_parts($max / 2).saturating_pow(3), $name::from_parts($max / 8), ); // 0^n == 0 assert_eq!( - $name::from_parts(0).saturating_pow(3), + $name::from_parts(0).saturating_pow(3), $name::from_parts(0), ); // 1^n == 1 assert_eq!( - $name::from_parts($max).saturating_pow(3), + $name::from_parts($max).saturating_pow(3), $name::from_parts($max), ); // (x < 1)^inf == 0 (where 2.pow(31) ~ inf) assert_eq!( - $name::from_parts($max / 2).saturating_pow(2usize.pow(31)), + $name::from_parts($max / 2).saturating_pow(2usize.pow(31)), $name::from_parts(0), ); } @@ -994,7 +994,7 @@ macro_rules! implement_per_thing { $name::from_parts(1).saturating_reciprocal_mul($max), <$type>::max_value(), ); - // round to nearest + // round to nearest assert_eq!( $name::from_percent(60).saturating_reciprocal_mul(<$type>::from(10u8)), 17, @@ -1004,12 +1004,12 @@ macro_rules! implement_per_thing { $name::from_percent(60).saturating_reciprocal_mul_floor(<$type>::from(10u8)), 16, ); - // round to nearest + // round to nearest assert_eq!( $name::from_percent(61).saturating_reciprocal_mul(<$type>::from(10u8)), 16, ); - // round up + // round up assert_eq!( $name::from_percent(61).saturating_reciprocal_mul_ceil(<$type>::from(10u8)), 17, @@ -1022,7 +1022,7 @@ macro_rules! implement_per_thing { $name::from_percent(49).mul_floor(10 as $type), 4, ); - let a: $upper_type = $name::from_percent(50).mul_floor(($max as $upper_type).pow(2)); + let a: $upper_type = $name::from_percent(50).mul_floor(($max as $upper_type).pow(2)); let b: $upper_type = ($max as $upper_type).pow(2) / 2; if $max % 2 == 0 { assert_eq!(a, b); @@ -1036,27 +1036,27 @@ macro_rules! implement_per_thing { fn rational_mul_correction_works() { assert_eq!( super::rational_mul_correction::<$type, $name>( - <$type>::max_value(), - <$type>::max_value(), - <$type>::max_value(), + <$type>::max_value(), + <$type>::max_value(), + <$type>::max_value(), super::Rounding::Nearest, ), 0, ); assert_eq!( super::rational_mul_correction::<$type, $name>( - <$type>::max_value() - 1, - <$type>::max_value(), - <$type>::max_value(), + <$type>::max_value() - 1, + <$type>::max_value(), + <$type>::max_value(), super::Rounding::Nearest, ), <$type>::max_value() - 1, ); assert_eq!( super::rational_mul_correction::<$upper_type, $name>( - ((<$type>::max_value() - 1) as $upper_type).pow(2), - <$type>::max_value(), - <$type>::max_value(), + ((<$type>::max_value() - 1) as $upper_type).pow(2), + <$type>::max_value(), + <$type>::max_value(), super::Rounding::Nearest, ), 1, @@ -1064,9 +1064,9 @@ macro_rules! implement_per_thing { // ((max^2 - 1) % max) * max / max == max - 1 assert_eq!( super::rational_mul_correction::<$upper_type, $name>( - (<$type>::max_value() as $upper_type).pow(2) - 1, - <$type>::max_value(), - <$type>::max_value(), + (<$type>::max_value() as $upper_type).pow(2) - 1, + <$type>::max_value(), + <$type>::max_value(), super::Rounding::Nearest, ), (<$type>::max_value() - 1).into(), @@ -1074,8 +1074,8 @@ macro_rules! implement_per_thing { // (max % 2) * max / 2 == max / 2 assert_eq!( super::rational_mul_correction::<$upper_type, $name>( - (<$type>::max_value() as $upper_type).pow(2), - <$type>::max_value(), + (<$type>::max_value() as $upper_type).pow(2), + <$type>::max_value(), 2 as $type, super::Rounding::Nearest, ), @@ -1084,9 +1084,9 @@ macro_rules! implement_per_thing { // ((max^2 - 1) % max) * 2 / max == 2 (rounded up) assert_eq!( super::rational_mul_correction::<$upper_type, $name>( - (<$type>::max_value() as $upper_type).pow(2) - 1, + (<$type>::max_value() as $upper_type).pow(2) - 1, 2 as $type, - <$type>::max_value(), + <$type>::max_value(), super::Rounding::Nearest, ), 2, @@ -1094,9 +1094,9 @@ macro_rules! implement_per_thing { // ((max^2 - 1) % max) * 2 / max == 1 (rounded down) assert_eq!( super::rational_mul_correction::<$upper_type, $name>( - (<$type>::max_value() as $upper_type).pow(2) - 1, + (<$type>::max_value() as $upper_type).pow(2) - 1, 2 as $type, - <$type>::max_value(), + <$type>::max_value(), super::Rounding::Down, ), 1, -- GitLab From b0f833ee153c5347384c890b93c7421bff314a4f Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 30 Mar 2020 15:48:59 +0200 Subject: [PATCH 108/300] src/service/src/builder: Fix memory metric exposed in bytes not KiB (#5459) The library `sysinfo` exposes process memory as kibibytes and not bytes, thus the value needs to be multiplied by 1024 to comply with the metric name and the Prometheus base units [1]. [1] https://prometheus.io/docs/practices/naming/#base-units --- client/service/src/builder.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 10a1cd9749..0de4ea6aee 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -77,7 +77,7 @@ impl ServiceMetrics { "ready_transactions_number", "Number of transactions in the ready queue", )?, registry)?, memory_usage_bytes: register(Gauge::new( - "memory_usage_bytes", "Node memory usage", + "memory_usage_bytes", "Node memory (resident set size) usage", )?, registry)?, cpu_usage_percentage: register(Gauge::new( "cpu_usage_percentage", "Node CPU usage", @@ -1074,7 +1074,8 @@ ServiceBuilder< .unwrap_or(0), ); if let Some(metrics) = metrics.as_ref() { - metrics.memory_usage_bytes.set(memory); + // `sysinfo::Process::memory` returns memory usage in KiB and not bytes. + metrics.memory_usage_bytes.set(memory * 1024); metrics.cpu_usage_percentage.set(f64::from(cpu_usage)); metrics.ready_transactions_number.set(txpool_status.ready as u64); -- GitLab From b6c96a29d8c0779996145b2b57150a95508997e2 Mon Sep 17 00:00:00 2001 From: Stanislav Tkach Date: Mon, 30 Mar 2020 17:08:41 +0300 Subject: [PATCH 109/300] Change the difficulty parameter of PowAlgorithm::difficulty function to Hash (#5417) --- client/consensus/pow/src/lib.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/client/consensus/pow/src/lib.rs b/client/consensus/pow/src/lib.rs index 49d2e64f60..de41ea7bd2 100644 --- a/client/consensus/pow/src/lib.rs +++ b/client/consensus/pow/src/lib.rs @@ -151,7 +151,7 @@ pub trait PowAlgorithm { /// /// This function will be called twice during the import process, so the implementation /// should be properly cached. - fn difficulty(&self, parent: &BlockId) -> Result>; + fn difficulty(&self, parent: B::Hash) -> Result>; /// Verify that the seal is valid against given pre hash when parent block is not yet imported. /// /// None means that preliminary verify is not available for this algorithm. @@ -335,7 +335,7 @@ impl BlockImport for PowBlockImport difficulty, - None => self.algorithm.difficulty(&BlockId::hash(parent_hash))?, + None => self.algorithm.difficulty(parent_hash)?, }; let pre_hash = block.header.hash(); @@ -617,9 +617,7 @@ fn mine_loop( let (header, body) = proposal.block.deconstruct(); let (difficulty, seal) = { - let difficulty = algorithm.difficulty( - &BlockId::Hash(best_hash), - )?; + let difficulty = algorithm.difficulty(best_hash)?; loop { let seal = algorithm.mine( -- GitLab From c631a462833c1f560432d1cba8fad26184a25eff Mon Sep 17 00:00:00 2001 From: cheme Date: Mon, 30 Mar 2020 18:15:59 +0200 Subject: [PATCH 110/300] Fix unrelated warning for CI --- client/network/src/protocol/generic_proto/handler/group.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/client/network/src/protocol/generic_proto/handler/group.rs b/client/network/src/protocol/generic_proto/handler/group.rs index 69a519134a..6b23263b14 100644 --- a/client/network/src/protocol/generic_proto/handler/group.rs +++ b/client/network/src/protocol/generic_proto/handler/group.rs @@ -64,7 +64,6 @@ use libp2p::swarm::{ NegotiatedSubstream, }; use log::{debug, error}; -use sp_runtime::ConsensusEngineId; use std::{borrow::Cow, error, io, str, task::{Context, Poll}}; /// Implements the `IntoProtocolsHandler` trait of libp2p. -- GitLab From a54932d479d6bc8827271c5a49e7df507eba9629 Mon Sep 17 00:00:00 2001 From: yanganto Date: Tue, 31 Mar 2020 06:13:39 +0800 Subject: [PATCH 111/300] Show network id/version in subkey (#5457) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Show network id/version in subkey - show network id/version when creating - show network id/version when inspecting * Update bin/utils/subkey/src/main.rs use `unwrap_or_default` for more clean syntax Co-Authored-By: Bastian Köcher Co-authored-by: Bastian Köcher --- bin/utils/subkey/src/main.rs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/bin/utils/subkey/src/main.rs b/bin/utils/subkey/src/main.rs index 8f0f96c39e..237cc68df2 100644 --- a/bin/utils/subkey/src/main.rs +++ b/bin/utils/subkey/src/main.rs @@ -79,6 +79,7 @@ trait Crypto: Sized { ) where ::Public: PublicT, { + let v = network_override.unwrap_or_default(); if let Ok((pair, seed)) = Self::Pair::from_phrase(uri, password) { let public_key = Self::public_from_pair(&pair); @@ -86,6 +87,7 @@ trait Crypto: Sized { OutputType::Json => { let json = json!({ "secretPhrase": uri, + "networkId": String::from(v), "secretSeed": format_seed::(seed), "publicKey": format_public_key::(public_key.clone()), "accountId": format_account_id::(public_key), @@ -95,11 +97,13 @@ trait Crypto: Sized { }, OutputType::Text => { println!("Secret phrase `{}` is account:\n \ - Secret seed: {}\n \ - Public key (hex): {}\n \ - Account ID: {}\n \ - SS58 Address: {}", + Network ID/version: {}\n \ + Secret seed: {}\n \ + Public key (hex): {}\n \ + Account ID: {}\n \ + SS58 Address: {}", uri, + String::from(v), format_seed::(seed), format_public_key::(public_key.clone()), format_account_id::(public_key), @@ -114,6 +118,7 @@ trait Crypto: Sized { OutputType::Json => { let json = json!({ "secretKeyUri": uri, + "networkId": String::from(v), "secretSeed": if let Some(seed) = seed { format_seed::(seed) } else { "n/a".into() }, "publicKey": format_public_key::(public_key.clone()), "accountId": format_account_id::(public_key), @@ -123,11 +128,13 @@ trait Crypto: Sized { }, OutputType::Text => { println!("Secret Key URI `{}` is account:\n \ - Secret seed: {}\n \ - Public key (hex): {}\n \ - Account ID: {}\n \ - SS58 Address: {}", + Network ID/version: {}\n \ + Secret seed: {}\n \ + Public key (hex): {}\n \ + Account ID: {}\n \ + SS58 Address: {}", uri, + String::from(v), if let Some(seed) = seed { format_seed::(seed) } else { "n/a".into() }, format_public_key::(public_key.clone()), format_account_id::(public_key), -- GitLab From 69e790ea4d7c9becac98cd800604261c21d5d730 Mon Sep 17 00:00:00 2001 From: gabriel klawitter Date: Tue, 31 Mar 2020 14:25:12 +0530 Subject: [PATCH 112/300] Ci check companion (#5419) * add post-build-test stage * check status * fix busybox shell * renaming for consistency --- .gitlab-ci.yml | 18 +++- ...t.sh => check_polkadot_companion_build.sh} | 4 +- .../gitlab/check_polkadot_companion_status.sh | 99 +++++++++++++++++++ 3 files changed, 117 insertions(+), 4 deletions(-) rename .maintain/gitlab/{check_polkadot.sh => check_polkadot_companion_build.sh} (97%) create mode 100755 .maintain/gitlab/check_polkadot_companion_status.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5af113f648..06afc35058 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,6 +24,7 @@ stages: - test - build + - post-build-test - publish - kubernetes - flaming-fir @@ -127,11 +128,13 @@ check-line-width: allow_failure: true -check-polkadot: + + +check-polkadot-companion-build: stage: build <<: *docker-env script: - - ./.maintain/gitlab/check_polkadot.sh + - ./.maintain/gitlab/check_polkadot_companion_build.sh interruptible: true allow_failure: true @@ -434,6 +437,17 @@ check_warnings: fi +check-polkadot-companion-status: + stage: post-build-test + image: parity/tools:latest + <<: *kubernetes-build + only: + - /^[0-9]+$/ + script: + - ./.maintain/gitlab/check_polkadot_companion_status.sh + + + trigger-contracts-ci: stage: publish needs: diff --git a/.maintain/gitlab/check_polkadot.sh b/.maintain/gitlab/check_polkadot_companion_build.sh similarity index 97% rename from .maintain/gitlab/check_polkadot.sh rename to .maintain/gitlab/check_polkadot_companion_build.sh index 0df940ffe2..5bd51e0cd2 100755 --- a/.maintain/gitlab/check_polkadot.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -22,8 +22,8 @@ boldcat () { printf "|\n"; while read l; do printf "| \033[1m${l}\033[0m\n"; don boldcat <<-EOT -check_polkadot -============== +check_polkadot_companion_build +============================== this job checks if there is a string in the description of the pr like diff --git a/.maintain/gitlab/check_polkadot_companion_status.sh b/.maintain/gitlab/check_polkadot_companion_status.sh new file mode 100755 index 0000000000..e98a657460 --- /dev/null +++ b/.maintain/gitlab/check_polkadot_companion_status.sh @@ -0,0 +1,99 @@ +#!/bin/sh +# +# check for a polkadot companion pr and ensure it has approvals and is +# mergeable +# + +github_api_substrate_pull_url="https://api.github.com/repos/paritytech/substrate/pulls" +github_api_polkadot_pull_url="https://api.github.com/repos/paritytech/polkadot/pulls" +# use github api v3 in order to access the data without authentication +github_header="Accept: application/vnd.github.v3+json" + +boldprint () { printf "|\n| \033[1m${@}\033[0m\n|\n" ; } +boldcat () { printf "|\n"; while read l; do printf "| \033[1m${l}\033[0m\n"; done; printf "|\n" ; } + + + +boldcat <<-EOT + + +check_polkadot_companion_status +=============================== + +this job checks if there is a string in the description of the pr like + +polkadot companion: paritytech/polkadot#567 + +or any other polkadot pr is mentioned in this pr's description and checks its +status. + + +EOT + + +if ! [ "${CI_COMMIT_REF_NAME}" -gt 0 2>/dev/null ] +then + boldprint "this doesn't seem to be a pull request" + exit 1 +fi + +boldprint "this is pull request no ${CI_COMMIT_REF_NAME}" + +pr_body="$(curl -H "${github_header}" -s ${github_api_substrate_pull_url}/${CI_COMMIT_REF_NAME} \ + | sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p')" + +# get companion if explicitly specified +pr_companion="$(echo "${pr_body}" | sed -n -r \ + -e 's;^.*polkadot companion: paritytech/polkadot#([0-9]+).*$;\1;p' \ + -e 's;^.*polkadot companion: https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ + | tail -n 1)" + +# get companion mentioned in the description +if [ -z "${pr_companion}" ] +then + pr_companion="$(echo "${pr_body}" | sed -n -r \ + 's;^.*https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ + | tail -n 1)" +fi + +if [ -z "${pr_companion}" ] +then + boldprint "no companion pr found" + exit 0 +fi + +boldprint "companion pr: #${pr_companion}" + +# check the status of that pull request - needs to be +# mergable and approved + +curl -H "${github_header}" -sS -o companion_pr.json \ + ${github_api_polkadot_pull_url}/${pr_companion} + +if jq -e .merged < companion_pr.json >/dev/null +then + boldprint "polkadot pr #${pr_companion} already merged" + exit 0 +fi + +if jq -e '.mergeable and .mergeable_state == "clean"' < companion_pr.json >/dev/null +then + boldprint "polkadot pr #${pr_companion} mergeable" +else + boldprint "polkadot pr #${pr_companion} not mergeable or clean" + exit 1 +fi + +curl -H "${github_header}" -sS -o companion_pr_reviews.json \ + ${github_api_polkadot_pull_url}/${pr_companion}/reviews + +if [ "$(jq -r -e '.[].state' < companion_pr_reviews.json | uniq)" != "APPROVED" ] +then + boldprint "polkadot pr #${pr_companion} not APPROVED" + exit 1 +fi + +boldprint "polkadot pr #${pr_companion} state APPROVED" +exit 0 + + -- GitLab From fa71ce9cb3b814ec4d72e5b5bcefcec6097392fa Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Tue, 31 Mar 2020 11:02:16 +0200 Subject: [PATCH 113/300] Allow changing the behavior for imported blocks (#5236) * Added option to disable default block announce * Added on_block_imported on NetworkService * Revert "Added on_block_imported on NetworkService" This reverts commit ba360cad96e0cb041d7047af30df2a35eb112449. * Do not announce block if set to not announce block * Revert fix * Moving default announce block to NetworkConfig * WIP Forked at: 41bb2193a267805e2093a081bc3e2aaccc64283a Parent branch: origin/master * WIP Forked at: 41bb2193a267805e2093a081bc3e2aaccc64283a Parent branch: origin/master * Removing boolean in favor of explicit call * Fixing tests * WIP Forked at: 41bb2193a267805e2093a081bc3e2aaccc64283a Parent branch: origin/master * WIP Forked at: 41bb2193a267805e2093a081bc3e2aaccc64283a Parent branch: origin/master * increase spec_version * increase spec_version * Fixed test * Fixing test * Renamed should_announce_imported_blocks to announce_imported_blocks * Updated assert_cmd --- Cargo.lock | 14 ++++++++++++-- bin/node/cli/Cargo.toml | 2 +- client/network/src/protocol.rs | 13 ++----------- client/network/src/service.rs | 4 ++-- client/network/test/src/lib.rs | 5 +++-- client/service/src/builder.rs | 1 + client/service/src/config.rs | 3 +++ client/service/src/lib.rs | 7 ++++++- client/service/test/src/lib.rs | 1 + 9 files changed, 31 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e87be8f0fb..b8336c76c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,15 +178,16 @@ dependencies = [ [[package]] name = "assert_cmd" -version = "0.12.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ad62275a8bda1c2c9a9303aea121eb04204272d3be0735d5dc1f49eb9ff9a9" +checksum = "36101401a715c232f2c63a534a4b639415064b79d128d2a60d35678f8fb45204" dependencies = [ "doc-comment", "escargot", "predicates", "predicates-core", "predicates-tree", + "wait-timeout", ] [[package]] @@ -8935,6 +8936,15 @@ dependencies = [ "glob 0.2.11", ] +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.3.1" diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index a45ef83076..804a74b8c4 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -113,7 +113,7 @@ sc-consensus-epochs = { version = "0.8.0-alpha.5", path = "../../../client/conse sc-service-test = { version = "2.0.0-dev", path = "../../../client/service/test" } futures = "0.3.4" tempfile = "3.1.0" -assert_cmd = "0.12" +assert_cmd = "1.0" nix = "0.17" serde_json = "1.0" diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index e21a2df9c8..55bc40a950 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -1467,20 +1467,11 @@ impl Protocol { } } - /// Call this when a block has been imported in the import queue and we should announce it on - /// the network. - pub fn on_block_imported(&mut self, header: &B::Header, data: Vec, is_best: bool) { + /// Call this when a block has been imported in the import queue + pub fn on_block_imported(&mut self, header: &B::Header, is_best: bool) { if is_best { self.sync.update_chain_info(header); } - - // blocks are not announced by light clients - if self.config.roles.is_light() { - return; - } - - // send out block announcements - self.send_announcement(header, data, is_best, false); } /// Call this when a block has been finalized. The sync layer may have some additional diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 17a0e67cdc..2c93d70e26 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -403,8 +403,8 @@ impl NetworkWorker { } /// You must call this when a new block is imported by the client. - pub fn on_block_imported(&mut self, header: B::Header, data: Vec, is_best: bool) { - self.network_service.user_protocol_mut().on_block_imported(&header, data, is_best); + pub fn on_block_imported(&mut self, header: B::Header, is_best: bool) { + self.network_service.user_protocol_mut().on_block_imported(&header, is_best); } /// You must call this when a new block is finalized by the client. diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 8ff06fc5ac..8a4909277c 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -281,7 +281,8 @@ impl Peer { Default::default() }; self.block_import.import_block(import_block, cache).expect("block_import failed"); - self.network.on_block_imported(header, Vec::new(), true); + self.network.on_block_imported(header, true); + self.network.service().announce_block(hash, Vec::new()); at = hash; } @@ -785,9 +786,9 @@ pub trait TestNetFactory: Sized { while let Poll::Ready(Some(notification)) = peer.imported_blocks_stream.as_mut().poll_next(cx) { peer.network.on_block_imported( notification.header, - Vec::new(), true, ); + peer.network.service().announce_block(notification.hash, Vec::new()); } // We poll `finality_notification_stream`, but we only take the last event. diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 0de4ea6aee..6f8610a612 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -1204,6 +1204,7 @@ ServiceBuilder< network_status_sinks.clone(), system_rpc_rx, has_bootnodes, + config.announce_block, ), ); diff --git a/client/service/src/config.rs b/client/service/src/config.rs index d9d497d1e9..7eb1d501ce 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -127,6 +127,8 @@ pub struct Configuration { /// /// The default value is 8. pub max_runtime_instances: usize, + /// Announce block automatically after they have been imported + pub announce_block: bool, } /// Configuration of the client keystore. @@ -229,6 +231,7 @@ impl Default for Configuration { tracing_targets: Default::default(), tracing_receiver: Default::default(), max_runtime_instances: 8, + announce_block: true, } } } diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index db9bccf0bf..3a071893d5 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -328,6 +328,7 @@ fn build_network_future< status_sinks: Arc, NetworkState)>>>, mut rpc_rx: mpsc::UnboundedReceiver>, should_have_peers: bool, + announce_imported_blocks: bool, ) -> impl Future { let mut imported_blocks_stream = client.import_notification_stream().fuse(); let mut finality_notification_stream = client.finality_notification_stream().fuse(); @@ -337,7 +338,11 @@ fn build_network_future< // We poll `imported_blocks_stream`. while let Poll::Ready(Some(notification)) = Pin::new(&mut imported_blocks_stream).poll_next(cx) { - network.on_block_imported(notification.header, Vec::new(), notification.is_new_best); + network.on_block_imported(notification.header, notification.is_new_best); + + if announce_imported_blocks { + network.service().announce_block(notification.hash, Vec::new()); + } } // We poll `finality_notification_stream`, but we only take the last event. diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 3e1eda3795..57aed116ef 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -213,6 +213,7 @@ fn node_config Date: Tue, 31 Mar 2020 03:15:31 -0700 Subject: [PATCH 114/300] And one more fix to flaky tests (#5467) * imporoved intervallier version * remove extra event * use version 0.3.1 * fix warning --- Cargo.lock | 4 +-- .../protocol/generic_proto/handler/group.rs | 1 - client/transaction-pool/Cargo.toml | 2 +- client/transaction-pool/src/testing/pool.rs | 26 ++++++------------- 4 files changed, 11 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8336c76c9..94d1267c72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2348,9 +2348,9 @@ checksum = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" [[package]] name = "intervalier" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "750dc2c10615a0aa0d38a5adf9d4e62651c178109f40253cb6235b3f638af6a9" +checksum = "14200459dc2319eb13708aed1c1efb8307e0e0e801e7282476939492e1492631" dependencies = [ "futures 0.3.4", "futures-timer 2.0.2", diff --git a/client/network/src/protocol/generic_proto/handler/group.rs b/client/network/src/protocol/generic_proto/handler/group.rs index 69a519134a..6b23263b14 100644 --- a/client/network/src/protocol/generic_proto/handler/group.rs +++ b/client/network/src/protocol/generic_proto/handler/group.rs @@ -64,7 +64,6 @@ use libp2p::swarm::{ NegotiatedSubstream, }; use log::{debug, error}; -use sp_runtime::ConsensusEngineId; use std::{borrow::Cow, error, io, str, task::{Context, Poll}}; /// Implements the `IntoProtocolsHandler` trait of libp2p. diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 4c14ef1139..dee1d23fcb 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -23,7 +23,7 @@ sc-transaction-graph = { version = "2.0.0-alpha.5", path = "./graph" } sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } -intervalier = "0.3" +intervalier = "0.3.1" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } [dev-dependencies] diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index 766257ff5e..c6c54d9720 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -219,10 +219,9 @@ fn should_revalidate_during_maintenance() { pool.api.push_block(1, vec![xt1.clone()]); - notifier.clear(); block_on(pool.maintain(block_event(1))); assert_eq!(pool.status().ready, 1); - block_on(notifier.next()); + block_on(notifier.next_blocking()); // test that pool revalidated transaction that left ready and not included in the block assert_eq!(pool.api.validation_requests().len(), 3); @@ -263,14 +262,10 @@ fn should_not_retain_invalid_hashes_from_retracted() { let event = block_event_with_retracted(1, vec![retracted_hash]); - notifier.clear(); block_on(pool.maintain(event)); // maintenance is in background - block_on(notifier.next()); - - let event = block_event_with_retracted(1, vec![retracted_hash]); - - block_on(pool.maintain(event)); + block_on(notifier.next_blocking()); + assert_eq!(pool.status().ready, 0); } @@ -285,9 +280,8 @@ fn should_revalidate_transaction_multiple_times() { pool.api.push_block(1, vec![xt.clone()]); - notifier.clear(); block_on(pool.maintain(block_event(1))); - block_on(notifier.next()); + block_on(notifier.next_blocking()); block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); @@ -295,9 +289,8 @@ fn should_revalidate_transaction_multiple_times() { pool.api.push_block(2, vec![]); pool.api.add_invalid(&xt); - notifier.clear(); block_on(pool.maintain(block_event(2))); - block_on(notifier.next()); + block_on(notifier.next_blocking()); assert_eq!(pool.status().ready, 0); } @@ -315,17 +308,15 @@ fn should_revalidate_across_many_blocks() { assert_eq!(pool.status().ready, 2); pool.api.push_block(1, vec![]); - notifier.clear(); block_on(pool.maintain(block_event(1))); - block_on(notifier.next()); + block_on(notifier.next_blocking()); block_on(pool.submit_one(&BlockId::number(2), SOURCE, xt3.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 3); pool.api.push_block(2, vec![xt1.clone()]); - notifier.clear(); block_on(pool.maintain(block_event(2))); - block_on(notifier.next()); + block_on(notifier.next_blocking()); assert_eq!(pool.status().ready, 2); // xt1 and xt2 validated twice, then xt3 once, then xt2 and xt3 again @@ -369,9 +360,8 @@ fn should_push_watchers_during_maintaince() { pool.api.add_invalid(&tx4); // clear timer events if any - notifier.clear(); block_on(pool.maintain(block_event(0))); - block_on(notifier.next()); + block_on(notifier.next_blocking()); // then // hash3 is now invalid -- GitLab From ea5ea420830f022f789ab1928c53a15b745878fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 31 Mar 2020 13:46:07 +0200 Subject: [PATCH 115/300] Implements mocking of runtime apis (#5448) * Implements mocking of runtime apis This pr adds support for easily mock runtime api implementations for tests by using the `mock_impl_runtime_apis!` macro. The syntax is similar to `impl_runtime_apis!`. The mocked implementation automatically implements `ApiExt`, `ApiErrorExt` and `Core` as these are required by the runtime api traits, but not required in tests or only a subset of them. * Fix warnings * Update primitives/api/proc-macro/src/utils.rs Co-Authored-By: Nikolay Volf * Review feedback Co-authored-by: Nikolay Volf --- client/authority-discovery/src/tests.rs | 96 +---- client/finality-grandpa/src/tests.rs | 96 +---- .../api/proc-macro/src/decl_runtime_apis.rs | 16 +- .../api/proc-macro/src/impl_runtime_apis.rs | 80 ++-- primitives/api/proc-macro/src/lib.rs | 6 + .../proc-macro/src/mock_impl_runtime_apis.rs | 378 ++++++++++++++++++ primitives/api/proc-macro/src/utils.rs | 90 ++++- primitives/api/src/lib.rs | 87 +++- primitives/api/test/tests/decl_and_impl.rs | 52 ++- .../ui/mock_only_error_associated_type.rs | 19 + .../ui/mock_only_error_associated_type.stderr | 5 + .../test/tests/ui/mock_only_one_block_type.rs | 27 ++ .../tests/ui/mock_only_one_block_type.stderr | 19 + .../test/tests/ui/mock_only_one_error_type.rs | 29 ++ .../tests/ui/mock_only_one_error_type.stderr | 27 ++ .../test/tests/ui/mock_only_one_self_type.rs | 26 ++ .../tests/ui/mock_only_one_self_type.stderr | 19 + .../test/tests/ui/mock_only_self_reference.rs | 20 + .../tests/ui/mock_only_self_reference.stderr | 65 +++ 19 files changed, 899 insertions(+), 258 deletions(-) create mode 100644 primitives/api/proc-macro/src/mock_impl_runtime_apis.rs create mode 100644 primitives/api/test/tests/ui/mock_only_error_associated_type.rs create mode 100644 primitives/api/test/tests/ui/mock_only_error_associated_type.stderr create mode 100644 primitives/api/test/tests/ui/mock_only_one_block_type.rs create mode 100644 primitives/api/test/tests/ui/mock_only_one_block_type.stderr create mode 100644 primitives/api/test/tests/ui/mock_only_one_error_type.rs create mode 100644 primitives/api/test/tests/ui/mock_only_one_error_type.stderr create mode 100644 primitives/api/test/tests/ui/mock_only_one_self_type.rs create mode 100644 primitives/api/test/tests/ui/mock_only_one_self_type.stderr create mode 100644 primitives/api/test/tests/ui/mock_only_self_reference.rs create mode 100644 primitives/api/test/tests/ui/mock_only_self_reference.stderr diff --git a/client/authority-discovery/src/tests.rs b/client/authority-discovery/src/tests.rs index 1296c2b627..3178a06d90 100644 --- a/client/authority-discovery/src/tests.rs +++ b/client/authority-discovery/src/tests.rs @@ -21,8 +21,8 @@ use futures::executor::block_on; use futures::future::poll_fn; use libp2p::{kad, PeerId}; -use sp_api::{ApiExt, ApiErrorExt, Core, RuntimeVersion, StorageProof, ProvideRuntimeApi, ApiRef}; -use sp_core::{testing::KeyStore, ExecutionContext, NativeOrEncoded}; +use sp_api::{ProvideRuntimeApi, ApiRef}; +use sp_core::testing::KeyStore; use sp_runtime::traits::{Zero, Block as BlockT, NumberFor}; use substrate_test_runtime_client::runtime::Block; @@ -99,8 +99,7 @@ impl ProvideRuntimeApi for TestApi { fn runtime_api<'a>(&'a self) -> ApiRef<'a, Self::Api> { RuntimeApi { authorities: self.authorities.clone(), - } - .into() + }.into() } } @@ -149,90 +148,13 @@ struct RuntimeApi { authorities: Vec, } -impl Core for RuntimeApi { - fn Core_version_runtime_api_impl( - &self, - _: &BlockId, - _: ExecutionContext, - _: Option<()>, - _: Vec, - ) -> std::result::Result, sp_blockchain::Error> { - unimplemented!("Not required for testing!") - } - - fn Core_execute_block_runtime_api_impl( - &self, - _: &BlockId, - _: ExecutionContext, - _: Option, - _: Vec, - ) -> std::result::Result, sp_blockchain::Error> { - unimplemented!("Not required for testing!") - } +sp_api::mock_impl_runtime_apis! { + impl AuthorityDiscoveryApi for RuntimeApi { + type Error = sp_blockchain::Error; - fn Core_initialize_block_runtime_api_impl( - &self, - _: &BlockId, - _: ExecutionContext, - _: Option<&::Header>, - _: Vec, - ) -> std::result::Result, sp_blockchain::Error> { - unimplemented!("Not required for testing!") - } -} - -impl ApiErrorExt for RuntimeApi { - type Error = sp_blockchain::Error; -} - -impl ApiExt for RuntimeApi { - type StateBackend = < - substrate_test_runtime_client::Backend as sc_client_api::backend::Backend - >::State; - - fn map_api_result std::result::Result, R, E>( - &self, - _: F - ) -> std::result::Result { - unimplemented!("Not required for testing!") - } - - fn runtime_version_at( - &self, - _: &BlockId, - ) -> std::result::Result { - unimplemented!("Not required for testing!") - } - - fn record_proof(&mut self) { - unimplemented!("Not required for testing!") - } - - fn extract_proof(&mut self) -> Option { - unimplemented!("Not required for testing!") - } - - fn into_storage_changes( - &self, - _: &Self::StateBackend, - _: Option<&sp_api::ChangesTrieState, sp_api::NumberFor>>, - _: ::Hash, - ) -> std::result::Result, String> - where Self: Sized - { - unimplemented!("Not required for testing!") - } -} - -impl AuthorityDiscoveryApi for RuntimeApi { - fn AuthorityDiscoveryApi_authorities_runtime_api_impl( - &self, - _: &BlockId, - _: ExecutionContext, - _: Option<()>, - _: Vec, - ) -> std::result::Result>, sp_blockchain::Error> { - return Ok(NativeOrEncoded::Native(self.authorities.clone())); + fn authorities(&self) -> Vec { + self.authorities.clone() + } } } diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 50800f4784..05ce90d3f1 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -30,21 +30,17 @@ use sp_keyring::Ed25519Keyring; use sc_client::LongestChain; use sc_client_api::backend::TransactionFor; use sp_blockchain::Result; -use sp_api::{ApiRef, ApiErrorExt, Core, RuntimeVersion, ApiExt, StorageProof, ProvideRuntimeApi}; +use sp_api::{ApiRef, StorageProof, ProvideRuntimeApi}; use substrate_test_runtime_client::runtime::BlockNumber; use sp_consensus::{ BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, ImportResult, BlockImport, import_queue::{BoxJustificationImport, BoxFinalityProofImport}, }; -use std::{ - collections::{HashMap, HashSet}, - result, - pin::Pin, -}; +use std::{collections::{HashMap, HashSet}, pin::Pin}; use parity_scale_codec::Decode; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, HashFor}; use sp_runtime::generic::{BlockId, DigestItem}; -use sp_core::{H256, NativeOrEncoded, ExecutionContext, crypto::Public}; +use sp_core::{H256, crypto::Public}; use sp_finality_grandpa::{GRANDPA_ENGINE_ID, AuthorityList, GrandpaApi}; use sp_state_machine::{InMemoryBackend, prove_read, read_proof_check}; @@ -214,87 +210,13 @@ impl ProvideRuntimeApi for TestApi { } } -impl Core for RuntimeApi { - fn Core_version_runtime_api_impl( - &self, - _: &BlockId, - _: ExecutionContext, - _: Option<()>, - _: Vec, - ) -> Result> { - unimplemented!("Not required for testing!") - } - - fn Core_execute_block_runtime_api_impl( - &self, - _: &BlockId, - _: ExecutionContext, - _: Option, - _: Vec, - ) -> Result> { - unimplemented!("Not required for testing!") - } +sp_api::mock_impl_runtime_apis! { + impl GrandpaApi for RuntimeApi { + type Error = sp_blockchain::Error; - fn Core_initialize_block_runtime_api_impl( - &self, - _: &BlockId, - _: ExecutionContext, - _: Option<&::Header>, - _: Vec, - ) -> Result> { - unimplemented!("Not required for testing!") - } -} - -impl ApiErrorExt for RuntimeApi { - type Error = sp_blockchain::Error; -} - -impl ApiExt for RuntimeApi { - type StateBackend = < - substrate_test_runtime_client::Backend as sc_client_api::backend::Backend - >::State; - - fn map_api_result result::Result, R, E>( - &self, - _: F - ) -> result::Result { - unimplemented!("Not required for testing!") - } - - fn runtime_version_at(&self, _: &BlockId) -> Result { - unimplemented!("Not required for testing!") - } - - fn record_proof(&mut self) { - unimplemented!("Not required for testing!") - } - - fn extract_proof(&mut self) -> Option { - unimplemented!("Not required for testing!") - } - - fn into_storage_changes( - &self, - _: &Self::StateBackend, - _: Option<&sp_api::ChangesTrieState, sp_api::NumberFor>>, - _: ::Hash, - ) -> std::result::Result, String> - where Self: Sized - { - unimplemented!("Not required for testing!") - } -} - -impl GrandpaApi for RuntimeApi { - fn GrandpaApi_grandpa_authorities_runtime_api_impl( - &self, - _: &BlockId, - _: ExecutionContext, - _: Option<()>, - _: Vec, - ) -> Result> { - Ok(self.inner.genesis_authorities.clone()).map(NativeOrEncoded::Native) + fn grandpa_authorities(&self) -> AuthorityList { + self.inner.genesis_authorities.clone() + } } } diff --git a/primitives/api/proc-macro/src/decl_runtime_apis.rs b/primitives/api/proc-macro/src/decl_runtime_apis.rs index 459707bdb5..e9f3087912 100644 --- a/primitives/api/proc-macro/src/decl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/decl_runtime_apis.rs @@ -19,7 +19,7 @@ use crate::utils::{ fold_fn_decl_for_client_side, extract_parameter_names_types_and_borrows, generate_native_call_generator_fn_name, return_type_extract_type, generate_method_runtime_api_impl_name, generate_call_api_at_fn_name, prefix_function_with_trait, - replace_wild_card_parameter_names, + replace_wild_card_parameter_names, AllowSelfRefInParameters, }; use proc_macro2::{TokenStream, Span}; @@ -198,7 +198,7 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result { // Generate a native call generator for each function of the given trait. for fn_ in fns { - let params = extract_parameter_names_types_and_borrows(&fn_)?; + let params = extract_parameter_names_types_and_borrows(&fn_, AllowSelfRefInParameters::No)?; let trait_fn_name = &fn_.ident; let fn_name = generate_native_call_generator_fn_name(&fn_.ident); let output = return_type_replace_block_with_node_block(fn_.output.clone()); @@ -592,7 +592,10 @@ impl<'a> ToClientSideDecl<'a> { // Get types and if the value is borrowed from all parameters. // If there is an error, we push it as the block to the user. - let param_types = match extract_parameter_names_types_and_borrows(fn_sig) { + let param_types = match extract_parameter_names_types_and_borrows( + fn_sig, + AllowSelfRefInParameters::No, + ) { Ok(res) => res.into_iter().map(|v| { let ty = v.1; let borrow = v.2; @@ -629,7 +632,10 @@ impl<'a> ToClientSideDecl<'a> { mut method: TraitItemMethod, context: TokenStream, ) -> TraitItemMethod { - let params = match extract_parameter_names_types_and_borrows(&method.sig) { + let params = match extract_parameter_names_types_and_borrows( + &method.sig, + AllowSelfRefInParameters::No, + ) { Ok(res) => res.into_iter().map(|v| v.0).collect::>(), Err(e) => { self.errors.push(e.to_compile_error()); @@ -780,7 +786,7 @@ fn generate_runtime_api_id(trait_name: &str) -> TokenStream { let mut res = [0; 8]; res.copy_from_slice(blake2_rfc::blake2b::blake2b(8, &[], trait_name.as_bytes()).as_bytes()); - quote!( const ID: [u8; 8] = [ #( #res ),* ]; ) + quote!( const ID: [u8; 8] = [ #( #res ),* ]; ) } /// Generates the const variable that holds the runtime api version. diff --git a/primitives/api/proc-macro/src/impl_runtime_apis.rs b/primitives/api/proc-macro/src/impl_runtime_apis.rs index e16cf3b5c4..7def6aa0fb 100644 --- a/primitives/api/proc-macro/src/impl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/impl_runtime_apis.rs @@ -19,7 +19,8 @@ use crate::utils::{ generate_runtime_mod_name_for_trait, generate_method_runtime_api_impl_name, extract_parameter_names_types_and_borrows, generate_native_call_generator_fn_name, return_type_extract_type, generate_call_api_at_fn_name, prefix_function_with_trait, - extract_all_signature_types, + extract_all_signature_types, extract_block_type_from_trait_path, extract_impl_trait, + AllowSelfRefInParameters, RequireQualifiedTraitPath, }; use proc_macro2::{Span, TokenStream}; @@ -66,7 +67,7 @@ fn generate_impl_call( input: &Ident, impl_trait: &Path ) -> Result { - let params = extract_parameter_names_types_and_borrows(signature)?; + let params = extract_parameter_names_types_and_borrows(signature, AllowSelfRefInParameters::No)?; let c = generate_crate_access(HIDDEN_INCLUDES_ID); let c_iter = iter::repeat(&c); @@ -93,50 +94,6 @@ fn generate_impl_call( ) } -/// Extract the trait that is implemented in the given `ItemImpl`. -fn extract_impl_trait<'a>(impl_: &'a ItemImpl) -> Result<&'a Path> { - impl_.trait_.as_ref().map(|v| &v.1).ok_or_else( - || Error::new(impl_.span(), "Only implementation of traits are supported!") - ).and_then(|p| { - if p.segments.len() > 1 { - Ok(p) - } else { - Err( - Error::new( - p.span(), - "The implemented trait has to be referenced with a path, \ - e.g. `impl client::Core for Runtime`." - ) - ) - } - }) -} - -/// Extracts the runtime block identifier. -fn extract_runtime_block_ident(trait_: &Path) -> Result<&TypePath> { - let span = trait_.span(); - let generics = trait_ - .segments - .last() - .ok_or_else(|| Error::new(span, "Empty path not supported"))?; - - match &generics.arguments { - PathArguments::AngleBracketed(ref args) => { - args.args.first().and_then(|v| match v { - GenericArgument::Type(Type::Path(ref block)) => Some(block), - _ => None - }).ok_or_else(|| Error::new(args.span(), "Missing `Block` generic parameter.")) - }, - PathArguments::None => { - let span = trait_.segments.last().as_ref().unwrap().span(); - Err(Error::new(span, "Missing `Block` generic parameter.")) - }, - PathArguments::Parenthesized(_) => { - Err(Error::new(generics.arguments.span(), "Unexpected parentheses in path!")) - } - } -} - /// Generate all the implementation calls for the given functions. fn generate_impl_calls( impls: &[ItemImpl], @@ -145,7 +102,7 @@ fn generate_impl_calls( let mut impl_calls = Vec::new(); for impl_ in impls { - let impl_trait_path = extract_impl_trait(impl_)?; + let impl_trait_path = extract_impl_trait(impl_, RequireQualifiedTraitPath::Yes)?; let impl_trait = extend_with_runtime_decl_path(impl_trait_path.clone()); let impl_trait_ident = &impl_trait_path .segments @@ -307,11 +264,19 @@ fn generate_runtime_api_base_structures() -> Result { res } - fn runtime_version_at( + fn has_api( + &self, + at: &#crate_::BlockId, + ) -> std::result::Result where Self: Sized { + self.call.runtime_version_at(at).map(|v| v.has_api_with(&A::ID, |v| v == A::VERSION)) + } + + fn has_api_with bool>( &self, at: &#crate_::BlockId, - ) -> std::result::Result<#crate_::RuntimeVersion, C::Error> { - self.call.runtime_version_at(at) + pred: P, + ) -> std::result::Result where Self: Sized { + self.call.runtime_version_at(at).map(|v| v.has_api_with(&A::ID, pred)) } fn record_proof(&mut self) { @@ -450,7 +415,7 @@ fn generate_api_impl_for_runtime(impls: &[ItemImpl]) -> Result { // we put the `RuntimeBlock` as first argument for the trait generics. for impl_ in impls.iter() { let mut impl_ = impl_.clone(); - let trait_ = extract_impl_trait(&impl_)?.clone(); + let trait_ = extract_impl_trait(&impl_, RequireQualifiedTraitPath::Yes)?.clone(); let trait_ = extend_with_runtime_decl_path(trait_); impl_.trait_.as_mut().unwrap().1 = trait_; @@ -506,7 +471,10 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> { }).collect::>() }; - let (param_types, error) = match extract_parameter_names_types_and_borrows(&input.sig) { + let (param_types, error) = match extract_parameter_names_types_and_borrows( + &input.sig, + AllowSelfRefInParameters::No, + ) { Ok(res) => ( res.into_iter().map(|v| { let ty = v.1; @@ -645,13 +613,13 @@ fn generate_api_impl_for_runtime_api(impls: &[ItemImpl]) -> Result let mut result = Vec::with_capacity(impls.len()); for impl_ in impls { - let impl_trait_path = extract_impl_trait(&impl_)?; + let impl_trait_path = extract_impl_trait(&impl_, RequireQualifiedTraitPath::Yes)?; let impl_trait = &impl_trait_path .segments .last() .ok_or_else(|| Error::new(impl_trait_path.span(), "Empty trait path not possible!"))? .clone(); - let runtime_block = extract_runtime_block_ident(impl_trait_path)?; + let runtime_block = extract_block_type_from_trait_path(impl_trait_path)?; let runtime_type = &impl_.self_ty; let mut runtime_mod_path = extend_with_runtime_decl_path(impl_trait_path.clone()); // remove the trait to get just the module path @@ -682,7 +650,9 @@ fn generate_runtime_api_versions(impls: &[ItemImpl]) -> Result { let mut processed_traits = HashSet::new(); for impl_ in impls { - let mut path = extend_with_runtime_decl_path(extract_impl_trait(&impl_)?.clone()); + let mut path = extend_with_runtime_decl_path( + extract_impl_trait(&impl_, RequireQualifiedTraitPath::Yes)?.clone(), + ); // Remove the trait let trait_ = path .segments diff --git a/primitives/api/proc-macro/src/lib.rs b/primitives/api/proc-macro/src/lib.rs index 9e5908717c..12f435bd16 100644 --- a/primitives/api/proc-macro/src/lib.rs +++ b/primitives/api/proc-macro/src/lib.rs @@ -21,6 +21,7 @@ use proc_macro::TokenStream; mod impl_runtime_apis; +mod mock_impl_runtime_apis; mod decl_runtime_apis; mod utils; @@ -29,6 +30,11 @@ pub fn impl_runtime_apis(input: TokenStream) -> TokenStream { impl_runtime_apis::impl_runtime_apis_impl(input) } +#[proc_macro] +pub fn mock_impl_runtime_apis(input: TokenStream) -> TokenStream { + mock_impl_runtime_apis::mock_impl_runtime_apis_impl(input) +} + #[proc_macro] pub fn decl_runtime_apis(input: TokenStream) -> TokenStream { decl_runtime_apis::decl_runtime_apis_impl(input) diff --git a/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs b/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs new file mode 100644 index 0000000000..0767c804a6 --- /dev/null +++ b/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs @@ -0,0 +1,378 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use crate::utils::{ + generate_crate_access, generate_hidden_includes, + generate_method_runtime_api_impl_name, extract_parameter_names_types_and_borrows, + return_type_extract_type, extract_block_type_from_trait_path, extract_impl_trait, + AllowSelfRefInParameters, RequireQualifiedTraitPath, +}; + +use proc_macro2::{Span, TokenStream}; + +use quote::quote; + +use syn::{ + spanned::Spanned, parse_macro_input, Ident, Type, ItemImpl, ImplItem, TypePath, parse_quote, + parse::{Parse, ParseStream, Result, Error}, fold::{self, Fold}, +}; + +/// Unique identifier used to make the hidden includes unique for this macro. +const HIDDEN_INCLUDES_ID: &str = "MOCK_IMPL_RUNTIME_APIS"; + +/// The structure used for parsing the runtime api implementations. +struct RuntimeApiImpls { + impls: Vec, +} + +impl Parse for RuntimeApiImpls { + fn parse(input: ParseStream) -> Result { + let mut impls = Vec::new(); + + while !input.is_empty() { + impls.push(ItemImpl::parse(input)?); + } + + if impls.is_empty() { + Err(Error::new(Span::call_site(), "No api implementation given!")) + } else { + Ok(Self { impls }) + } + } +} + +/// Implement the `ApiExt` trait, `ApiErrorExt` trait and the `Core` runtime api. +fn implement_common_api_traits( + error_type: Option, + block_type: TypePath, + self_ty: Type, +) -> Result { + let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); + + let error_type = error_type.map(|e| quote!(#e)).unwrap_or_else(|| quote!(String)); + + Ok(quote!( + impl #crate_::ApiErrorExt for #self_ty { + type Error = #error_type; + } + + impl #crate_::ApiExt<#block_type> for #self_ty { + type StateBackend = #crate_::InMemoryBackend<#crate_::HashFor<#block_type>>; + + fn map_api_result std::result::Result, R, E>( + &self, + map_call: F, + ) -> std::result::Result where Self: Sized { + map_call(self) + } + + fn has_api( + &self, + _: &#crate_::BlockId<#block_type>, + ) -> std::result::Result where Self: Sized { + Ok(true) + } + + fn has_api_with bool>( + &self, + at: &#crate_::BlockId<#block_type>, + pred: P, + ) -> std::result::Result where Self: Sized { + Ok(pred(A::VERSION)) + } + + fn record_proof(&mut self) { + unimplemented!("`record_proof` not implemented for runtime api mocks") + } + + fn extract_proof(&mut self) -> Option<#crate_::StorageProof> { + unimplemented!("`extract_proof` not implemented for runtime api mocks") + } + + fn into_storage_changes( + &self, + _: &Self::StateBackend, + _: Option<&#crate_::ChangesTrieState< + #crate_::HashFor<#block_type>, + #crate_::NumberFor<#block_type>, + >>, + _: <#block_type as #crate_::BlockT>::Hash, + ) -> std::result::Result< + #crate_::StorageChanges, + String + > where Self: Sized { + unimplemented!("`into_storage_changes` not implemented for runtime api mocks") + } + } + + impl #crate_::Core<#block_type> for #self_ty { + fn Core_version_runtime_api_impl( + &self, + _: &#crate_::BlockId<#block_type>, + _: #crate_::ExecutionContext, + _: Option<()>, + _: Vec, + ) -> std::result::Result<#crate_::NativeOrEncoded<#crate_::RuntimeVersion>, #error_type> { + unimplemented!("Not required for testing!") + } + + fn Core_execute_block_runtime_api_impl( + &self, + _: &#crate_::BlockId<#block_type>, + _: #crate_::ExecutionContext, + _: Option<#block_type>, + _: Vec, + ) -> std::result::Result<#crate_::NativeOrEncoded<()>, #error_type> { + unimplemented!("Not required for testing!") + } + + fn Core_initialize_block_runtime_api_impl( + &self, + _: &#crate_::BlockId<#block_type>, + _: #crate_::ExecutionContext, + _: Option<&<#block_type as #crate_::BlockT>::Header>, + _: Vec, + ) -> std::result::Result<#crate_::NativeOrEncoded<()>, #error_type> { + unimplemented!("Not required for testing!") + } + } + )) +} + +/// Auxialiry structure to fold a runtime api trait implementation into the expected format. +/// +/// This renames the methods, changes the method parameters and extracts the error type. +struct FoldRuntimeApiImpl<'a> { + /// The block type that is being used. + block_type: &'a TypePath, + /// The identifier of the trait being implemented. + impl_trait: &'a Ident, + /// Stores the error type that is being found in the trait implementation as associated type + /// with the name `Error`. + error_type: &'a mut Option, +} + +impl<'a> Fold for FoldRuntimeApiImpl<'a> { + fn fold_impl_item_method(&mut self, mut input: syn::ImplItemMethod) -> syn::ImplItemMethod { + let block = { + let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); + + let (param_names, param_types, error) = match extract_parameter_names_types_and_borrows( + &input.sig, + AllowSelfRefInParameters::YesButIgnore, + ) { + Ok(res) => ( + res.iter().map(|v| v.0.clone()).collect::>(), + res.iter().map(|v| { + let ty = &v.1; + let borrow = &v.2; + quote!( #borrow #ty ) + }).collect::>(), + None + ), + Err(e) => (Vec::new(), Vec::new(), Some(e.to_compile_error())), + }; + + let block_type = &self.block_type; + + // Rewrite the input parameters. + input.sig.inputs = parse_quote! { + &self, + _: &#crate_::BlockId<#block_type>, + _: #crate_::ExecutionContext, + params: Option<( #( #param_types ),* )>, + _: Vec, + }; + + input.sig.ident = generate_method_runtime_api_impl_name( + &self.impl_trait, + &input.sig.ident, + ); + let ret_type = return_type_extract_type(&input.sig.output); + + // Generate the correct return type. + input.sig.output = parse_quote!( + -> std::result::Result<#crate_::NativeOrEncoded<#ret_type>, Self::Error> + ); + + let orig_block = input.block.clone(); + + // Generate the new method implementation that calls into the runtime. + parse_quote!( + { + // Get the error to the user (if we have one). + #error + + let (#( #param_names ),*) = params + .expect("Mocked runtime apis don't support calling deprecated api versions"); + + let __fn_implementation__ = move || #orig_block; + + Ok(#crate_::NativeOrEncoded::Native(__fn_implementation__())) + } + ) + }; + + let mut input = fold::fold_impl_item_method(self, input); + // We need to set the block, after we modified the rest of the ast, otherwise we would + // modify our generated block as well. + input.block = block; + input + } + + fn fold_impl_item(&mut self, input: ImplItem) -> ImplItem { + match input { + ImplItem::Type(ty) => { + if ty.ident == "Error" { + if let Some(error_type) = self.error_type { + if *error_type != ty.ty { + let error = Error::new( + ty.span(), + "Error type can not change between runtime apis", + ); + ImplItem::Verbatim(error.to_compile_error()) + } else { + ImplItem::Verbatim(Default::default()) + } + } else { + *self.error_type = Some(ty.ty); + ImplItem::Verbatim(Default::default()) + } + } else { + let error = Error::new( + ty.span(), + "Only associated type with name `Error` is allowed", + ); + ImplItem::Verbatim(error.to_compile_error()) + } + }, + o => fold::fold_impl_item(self, o), + } + } +} + +/// Result of [`generate_runtime_api_impls`]. +struct GeneratedRuntimeApiImpls { + /// All the runtime api implementations. + impls: TokenStream, + /// The error type that should be used by the runtime apis. + error_type: Option, + /// The block type that is being used by the runtime apis. + block_type: TypePath, + /// The type the traits are implemented for. + self_ty: Type, +} + +/// Generate the runtime api implementations from the given trait implementations. +/// +/// This folds the method names, changes the method parameters, method return type, +/// extracts the error type, self type and the block type. +fn generate_runtime_api_impls(impls: &[ItemImpl]) -> Result { + let mut result = Vec::with_capacity(impls.len()); + let mut error_type = None; + let mut global_block_type: Option = None; + let mut self_ty: Option> = None; + + for impl_ in impls { + let impl_trait_path = extract_impl_trait(&impl_, RequireQualifiedTraitPath::No)?; + let impl_trait = &impl_trait_path + .segments + .last() + .ok_or_else(|| Error::new(impl_trait_path.span(), "Empty trait path not possible!"))? + .clone(); + let block_type = extract_block_type_from_trait_path(impl_trait_path)?; + + self_ty = match self_ty.take() { + Some(self_ty) => { + if self_ty == impl_.self_ty { + Some(self_ty) + } else { + let mut error =Error::new( + impl_.self_ty.span(), + "Self type should not change between runtime apis", + ); + + error.combine(Error::new( + self_ty.span(), + "First self type found here", + )); + + return Err(error) + } + }, + None => Some(impl_.self_ty.clone()), + }; + + global_block_type = match global_block_type.take() { + Some(global_block_type) => { + if global_block_type == *block_type { + Some(global_block_type) + } else { + let mut error = Error::new( + block_type.span(), + "Block type should be the same between all runtime apis.", + ); + + error.combine(Error::new( + global_block_type.span(), + "First block type found here", + )); + + return Err(error) + } + }, + None => Some(block_type.clone()), + }; + + let mut visitor = FoldRuntimeApiImpl { + block_type, + impl_trait: &impl_trait.ident, + error_type: &mut error_type, + }; + + result.push(visitor.fold_item_impl(impl_.clone())); + } + + Ok(GeneratedRuntimeApiImpls { + impls: quote!( #( #result )* ), + error_type, + block_type: global_block_type.expect("There is a least one runtime api; qed"), + self_ty: *self_ty.expect("There is at least one runtime api; qed"), + }) +} + +/// The implementation of the `mock_impl_runtime_apis!` macro. +pub fn mock_impl_runtime_apis_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + // Parse all impl blocks + let RuntimeApiImpls { impls: api_impls } = parse_macro_input!(input as RuntimeApiImpls); + + mock_impl_runtime_apis_impl_inner(&api_impls).unwrap_or_else(|e| e.to_compile_error()).into() +} + +fn mock_impl_runtime_apis_impl_inner(api_impls: &[ItemImpl]) -> Result { + let hidden_includes = generate_hidden_includes(HIDDEN_INCLUDES_ID); + let GeneratedRuntimeApiImpls { impls, error_type, block_type, self_ty } = + generate_runtime_api_impls(api_impls)?; + let api_traits = implement_common_api_traits(error_type, block_type, self_ty)?; + + Ok(quote!( + #hidden_includes + + #impls + + #api_traits + )) +} diff --git a/primitives/api/proc-macro/src/utils.rs b/primitives/api/proc-macro/src/utils.rs index 8330624bf2..1a79cf6c1e 100644 --- a/primitives/api/proc-macro/src/utils.rs +++ b/primitives/api/proc-macro/src/utils.rs @@ -18,7 +18,7 @@ use proc_macro2::{TokenStream, Span}; use syn::{ Result, Ident, Signature, parse_quote, Type, Pat, spanned::Spanned, FnArg, Error, token::And, - ImplItem, ReturnType, + ImplItem, ReturnType, PathArguments, Path, GenericArgument, TypePath, ItemImpl, }; use quote::quote; @@ -126,13 +126,21 @@ pub fn generate_unique_pattern(pat: Pat, counter: &mut u32) -> Pat { }, _ => pat, } - } +} + +/// Allow `&self` in parameters of a method. +pub enum AllowSelfRefInParameters { + /// Allows `&self` in parameters, but doesn't return it as part of the parameters. + YesButIgnore, + No, +} /// Extracts the name, the type and `&` or ``(if it is a reference or not) /// for each parameter in the given function signature. -pub fn extract_parameter_names_types_and_borrows(sig: &Signature) - -> Result)>> -{ +pub fn extract_parameter_names_types_and_borrows( + sig: &Signature, + allow_self: AllowSelfRefInParameters, +) -> Result)>> { let mut result = Vec::new(); let mut generated_pattern_counter = 0; for input in sig.inputs.iter() { @@ -145,13 +153,20 @@ pub fn extract_parameter_names_types_and_borrows(sig: &Signature) t => { (t.clone(), None) }, }; - let name = - generate_unique_pattern((*arg.pat).clone(), &mut generated_pattern_counter); + let name = generate_unique_pattern( + (*arg.pat).clone(), + &mut generated_pattern_counter, + ); result.push((name, ty, borrow)); }, - FnArg::Receiver(_) => { + FnArg::Receiver(_) if matches!(allow_self, AllowSelfRefInParameters::No) => { return Err(Error::new(input.span(), "`self` parameter not supported!")) - } + }, + FnArg::Receiver(recv) => { + if recv.mutability.is_some() || recv.reference.is_none() { + return Err(Error::new(recv.span(), "Only `&self` is supported!")) + } + }, } } @@ -199,3 +214,60 @@ pub fn extract_all_signature_types(items: &[ImplItem]) -> Vec { .flatten() .collect() } + +/// Extracts the block type from a trait path. +/// +/// It is expected that the block type is the first type in the generic arguments. +pub fn extract_block_type_from_trait_path(trait_: &Path) -> Result<&TypePath> { + let span = trait_.span(); + let generics = trait_ + .segments + .last() + .ok_or_else(|| Error::new(span, "Empty path not supported"))?; + + match &generics.arguments { + PathArguments::AngleBracketed(ref args) => { + args.args.first().and_then(|v| match v { + GenericArgument::Type(Type::Path(ref block)) => Some(block), + _ => None + }).ok_or_else(|| Error::new(args.span(), "Missing `Block` generic parameter.")) + }, + PathArguments::None => { + let span = trait_.segments.last().as_ref().unwrap().span(); + Err(Error::new(span, "Missing `Block` generic parameter.")) + }, + PathArguments::Parenthesized(_) => { + Err(Error::new(generics.arguments.span(), "Unexpected parentheses in path!")) + }, + } +} + +/// Should a qualified trait path be required? +/// +/// e.g. `path::Trait` is qualified and `Trait` is not. +pub enum RequireQualifiedTraitPath { + Yes, + No, +} + +/// Extract the trait that is implemented by the given `ItemImpl`. +pub fn extract_impl_trait<'a>( + impl_: &'a ItemImpl, + require: RequireQualifiedTraitPath, +) -> Result<&'a Path> { + impl_.trait_.as_ref().map(|v| &v.1).ok_or_else( + || Error::new(impl_.span(), "Only implementation of traits are supported!") + ).and_then(|p| { + if p.segments.len() > 1 || matches!(require, RequireQualifiedTraitPath::No) { + Ok(p) + } else { + Err( + Error::new( + p.span(), + "The implemented trait has to be referenced with a path, \ + e.g. `impl client::Core for Runtime`." + ) + ) + } + }) +} diff --git a/primitives/api/src/lib.rs b/primitives/api/src/lib.rs index 0901be5831..74bcf19a99 100644 --- a/primitives/api/src/lib.rs +++ b/primitives/api/src/lib.rs @@ -36,7 +36,7 @@ extern crate self as sp_api; #[doc(hidden)] #[cfg(feature = "std")] pub use sp_state_machine::{ - OverlayedChanges, StorageProof, Backend as StateBackend, ChangesTrieState, + OverlayedChanges, StorageProof, Backend as StateBackend, ChangesTrieState, InMemoryBackend, }; #[doc(hidden)] #[cfg(feature = "std")] @@ -78,7 +78,8 @@ use std::{panic::UnwindSafe, cell::RefCell}; /// declaration. Besides one exception, the macro adds an extra generic parameter `Block: BlockT` /// to the client side and the runtime side. This generic parameter is usable by the user. /// -/// For implementing these macros you should use the `impl_runtime_apis!` macro. +/// For implementing these macros you should use the +/// [`impl_runtime_apis!`](macro.impl_runtime_apis.html) macro. /// /// # Example /// @@ -143,8 +144,9 @@ pub use sp_api_proc_macro::decl_runtime_apis; /// Tags given trait implementations as runtime apis. /// -/// All traits given to this macro, need to be declared with the `decl_runtime_apis!` macro. -/// The implementation of the trait should follow the declaration given to the `decl_runtime_apis!` +/// All traits given to this macro, need to be declared with the +/// [`decl_runtime_apis!`](macro.decl_runtime_apis.html) macro. The implementation of the trait +/// should follow the declaration given to the [`decl_runtime_apis!`](macro.decl_runtime_apis.html) /// macro, besides the `Block` type that is required as first generic parameter for each runtime /// api trait. When implementing a runtime api trait, it is required that the trait is referenced /// by a path, e.g. `impl my_trait::MyTrait for Runtime`. The macro will use this path to access @@ -182,7 +184,7 @@ pub use sp_api_proc_macro::decl_runtime_apis; /// # } /// # pub trait BlockBuilder { /// # fn build_block() -> Block; -/// # } +/// # } /// # } /// /// /// All runtime api implementations need to be done in one call of the macro! @@ -226,6 +228,70 @@ pub use sp_api_proc_macro::decl_runtime_apis; /// ``` pub use sp_api_proc_macro::impl_runtime_apis; +/// Mocks given trait implementations as runtime apis. +/// +/// Accepts similar syntax as [`impl_runtime_apis!`](macro.impl_runtime_apis.html) and generates +/// simplified mock implementations of the given runtime apis. The difference in syntax is that the +/// trait does not need to be referenced by a qualified path, methods accept the `&self` parameter +/// and the error type can be specified as associated type. If no error type is specified `String` +/// is used as error type. +/// +/// Besides implementing the given traits, the [`Core`], [`ApiExt`] and [`ApiErrorExt`] are +/// implemented automatically. +/// +/// # Example +/// +/// ```rust +/// use sp_version::create_runtime_str; +/// # +/// # use sp_runtime::traits::Block as BlockT; +/// # use sp_test_primitives::Block; +/// # +/// # sp_api::decl_runtime_apis! { +/// # /// Declare the api trait. +/// # pub trait Balance { +/// # /// Get the balance. +/// # fn get_balance() -> u64; +/// # /// Set the balance. +/// # fn set_balance(val: u64); +/// # } +/// # pub trait BlockBuilder { +/// # fn build_block() -> Block; +/// # } +/// # } +/// +/// struct MockApi { +/// balance: u64, +/// } +/// +/// /// All runtime api mock implementations need to be done in one call of the macro! +/// sp_api::mock_impl_runtime_apis! { +/// impl Balance for MockApi { +/// /// Here we take the `&self` to access the instance. +/// fn get_balance(&self) -> u64 { +/// self.balance +/// } +/// fn set_balance(_bal: u64) { +/// // Store the balance +/// } +/// } +/// +/// impl BlockBuilder for MockApi { +/// /// Sets the error type that is being used by the mock implementation. +/// /// The error type is used by all runtime apis. It is only required to +/// /// be specified in one trait implementation. +/// type Error = String; +/// +/// fn build_block() -> Block { +/// unimplemented!("Not Required in tests") +/// } +/// } +/// } +/// +/// # fn main() {} +/// ``` +pub use sp_api_proc_macro::mock_impl_runtime_apis; + /// A type that records all accessed trie nodes and generates a proof out of it. #[cfg(feature = "std")] pub type ProofRecorder = sp_state_machine::ProofRecorder>; @@ -293,21 +359,14 @@ pub trait ApiExt: ApiErrorExt { fn has_api( &self, at: &BlockId, - ) -> Result where Self: Sized { - self.runtime_version_at(at).map(|v| v.has_api_with(&A::ID, |v| v == A::VERSION)) - } + ) -> Result where Self: Sized; /// Check if the given api is implemented and the version passes a predicate. fn has_api_with bool>( &self, at: &BlockId, pred: P, - ) -> Result where Self: Sized { - self.runtime_version_at(at).map(|v| v.has_api_with(&A::ID, pred)) - } - - /// Returns the runtime version at the given block id. - fn runtime_version_at(&self, at: &BlockId) -> Result; + ) -> Result where Self: Sized; /// Start recording all accessed trie nodes for generating proofs. fn record_proof(&mut self); diff --git a/primitives/api/test/tests/decl_and_impl.rs b/primitives/api/test/tests/decl_and_impl.rs index d5a668dec1..a09bd0412c 100644 --- a/primitives/api/test/tests/decl_and_impl.rs +++ b/primitives/api/test/tests/decl_and_impl.rs @@ -14,7 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use sp_api::{RuntimeApiInfo, decl_runtime_apis, impl_runtime_apis}; +use sp_api::{ + RuntimeApiInfo, decl_runtime_apis, impl_runtime_apis, mock_impl_runtime_apis, + ApiExt, +}; use sp_runtime::{traits::{GetNodeBlockType, Block as BlockT}, generic::BlockId}; @@ -81,6 +84,34 @@ impl_runtime_apis! { } } +struct MockApi { + block: Option, +} + +mock_impl_runtime_apis! { + impl Api for MockApi { + fn test(_: u64) { + unimplemented!() + } + + fn something_with_block(&self, _: Block) -> Block { + self.block.clone().unwrap() + } + + fn function_with_two_args(_: u64, _: Block) { + unimplemented!() + } + + fn same_name() {} + + fn wild_card(_: u32) {} + } + + impl ApiWithCustomVersion for MockApi { + fn same_name() {} + } +} + type TestClient = substrate_test_runtime_client::sc_client::Client< substrate_test_runtime_client::Backend, substrate_test_runtime_client::Executor, @@ -129,3 +160,22 @@ fn check_runtime_api_versions() { check_runtime_api_versions_contains::>(); check_runtime_api_versions_contains::>(); } + +#[test] +fn mock_runtime_api_has_api() { + let mock = MockApi { block: None }; + + assert!( + mock.has_api::>(&BlockId::Number(0)).unwrap(), + ); + assert!(mock.has_api::>(&BlockId::Number(0)).unwrap()); +} + +#[test] +#[should_panic(expected = "Mocked runtime apis don't support calling deprecated api versions")] +fn mock_runtime_api_panics_on_calling_old_version() { + let mock = MockApi { block: None }; + + #[allow(deprecated)] + let _ = mock.same_name_before_version_2(&BlockId::Number(0)); +} diff --git a/primitives/api/test/tests/ui/mock_only_error_associated_type.rs b/primitives/api/test/tests/ui/mock_only_error_associated_type.rs new file mode 100644 index 0000000000..bbd3c71c94 --- /dev/null +++ b/primitives/api/test/tests/ui/mock_only_error_associated_type.rs @@ -0,0 +1,19 @@ +use substrate_test_runtime_client::runtime::Block; + +sp_api::decl_runtime_apis! { + pub trait Api { + fn test(data: u64); + } +} + +struct MockApi; + +sp_api::mock_impl_runtime_apis! { + impl Api for MockApi { + type OtherData = u32; + + fn test(data: u64) {} + } +} + +fn main() {} diff --git a/primitives/api/test/tests/ui/mock_only_error_associated_type.stderr b/primitives/api/test/tests/ui/mock_only_error_associated_type.stderr new file mode 100644 index 0000000000..beced70413 --- /dev/null +++ b/primitives/api/test/tests/ui/mock_only_error_associated_type.stderr @@ -0,0 +1,5 @@ +error: Only associated type with name `Error` is allowed + --> $DIR/mock_only_error_associated_type.rs:13:3 + | +13 | type OtherData = u32; + | ^^^^ diff --git a/primitives/api/test/tests/ui/mock_only_one_block_type.rs b/primitives/api/test/tests/ui/mock_only_one_block_type.rs new file mode 100644 index 0000000000..969b21d737 --- /dev/null +++ b/primitives/api/test/tests/ui/mock_only_one_block_type.rs @@ -0,0 +1,27 @@ +use substrate_test_runtime_client::runtime::Block; + +struct Block2; + +sp_api::decl_runtime_apis! { + pub trait Api { + fn test(data: u64); + } + + pub trait Api2 { + fn test(data: u64); + } +} + +struct MockApi; + +sp_api::mock_impl_runtime_apis! { + impl Api for MockApi { + fn test(data: u64) {} + } + + impl Api2 for MockApi { + fn test(data: u64) {} + } +} + +fn main() {} diff --git a/primitives/api/test/tests/ui/mock_only_one_block_type.stderr b/primitives/api/test/tests/ui/mock_only_one_block_type.stderr new file mode 100644 index 0000000000..1abc8db726 --- /dev/null +++ b/primitives/api/test/tests/ui/mock_only_one_block_type.stderr @@ -0,0 +1,19 @@ +error: Block type should be the same between all runtime apis. + --> $DIR/mock_only_one_block_type.rs:22:12 + | +22 | impl Api2 for MockApi { + | ^^^^^^ + +error: First block type found here + --> $DIR/mock_only_one_block_type.rs:18:11 + | +18 | impl Api for MockApi { + | ^^^^^ + +warning: unused import: `substrate_test_runtime_client::runtime::Block` + --> $DIR/mock_only_one_block_type.rs:1:5 + | +1 | use substrate_test_runtime_client::runtime::Block; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_imports)]` on by default diff --git a/primitives/api/test/tests/ui/mock_only_one_error_type.rs b/primitives/api/test/tests/ui/mock_only_one_error_type.rs new file mode 100644 index 0000000000..1c3f13dbb9 --- /dev/null +++ b/primitives/api/test/tests/ui/mock_only_one_error_type.rs @@ -0,0 +1,29 @@ +use substrate_test_runtime_client::runtime::Block; + +sp_api::decl_runtime_apis! { + pub trait Api { + fn test(data: u64); + } + + pub trait Api2 { + fn test(data: u64); + } +} + +struct MockApi; + +sp_api::mock_impl_runtime_apis! { + impl Api for MockApi { + type Error = u32; + + fn test(data: u64) {} + } + + impl Api2 for MockApi { + type Error = u64; + + fn test(data: u64) {} + } +} + +fn main() {} diff --git a/primitives/api/test/tests/ui/mock_only_one_error_type.stderr b/primitives/api/test/tests/ui/mock_only_one_error_type.stderr new file mode 100644 index 0000000000..8f026838c9 --- /dev/null +++ b/primitives/api/test/tests/ui/mock_only_one_error_type.stderr @@ -0,0 +1,27 @@ +error: Error type can not change between runtime apis + --> $DIR/mock_only_one_error_type.rs:23:3 + | +23 | type Error = u64; + | ^^^^ + +error[E0277]: the trait bound `u32: std::convert::From` is not satisfied + --> $DIR/mock_only_one_error_type.rs:15:1 + | +15 | / sp_api::mock_impl_runtime_apis! { +16 | | impl Api for MockApi { +17 | | type Error = u32; +18 | | +... | +26 | | } +27 | | } + | | ^ + | | | + | |_the trait `std::convert::From` is not implemented for `u32` + | in this macro invocation + | + = help: the following implementations were found: + > + > + > + > + and 16 others diff --git a/primitives/api/test/tests/ui/mock_only_one_self_type.rs b/primitives/api/test/tests/ui/mock_only_one_self_type.rs new file mode 100644 index 0000000000..4b29ec2a6a --- /dev/null +++ b/primitives/api/test/tests/ui/mock_only_one_self_type.rs @@ -0,0 +1,26 @@ +use substrate_test_runtime_client::runtime::Block; + +sp_api::decl_runtime_apis! { + pub trait Api { + fn test(data: u64); + } + + pub trait Api2 { + fn test(data: u64); + } +} + +struct MockApi; +struct MockApi2; + +sp_api::mock_impl_runtime_apis! { + impl Api for MockApi { + fn test(data: u64) {} + } + + impl Api2 for MockApi2 { + fn test(data: u64) {} + } +} + +fn main() {} diff --git a/primitives/api/test/tests/ui/mock_only_one_self_type.stderr b/primitives/api/test/tests/ui/mock_only_one_self_type.stderr new file mode 100644 index 0000000000..996d1d44c0 --- /dev/null +++ b/primitives/api/test/tests/ui/mock_only_one_self_type.stderr @@ -0,0 +1,19 @@ +error: Self type should not change between runtime apis + --> $DIR/mock_only_one_self_type.rs:21:23 + | +21 | impl Api2 for MockApi2 { + | ^^^^^^^^ + +error: First self type found here + --> $DIR/mock_only_one_self_type.rs:17:22 + | +17 | impl Api for MockApi { + | ^^^^^^^ + +warning: unused import: `substrate_test_runtime_client::runtime::Block` + --> $DIR/mock_only_one_self_type.rs:1:5 + | +1 | use substrate_test_runtime_client::runtime::Block; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_imports)]` on by default diff --git a/primitives/api/test/tests/ui/mock_only_self_reference.rs b/primitives/api/test/tests/ui/mock_only_self_reference.rs new file mode 100644 index 0000000000..8a733f5779 --- /dev/null +++ b/primitives/api/test/tests/ui/mock_only_self_reference.rs @@ -0,0 +1,20 @@ +use substrate_test_runtime_client::runtime::Block; + +sp_api::decl_runtime_apis! { + pub trait Api { + fn test(data: u64); + fn test2(data: u64); + } +} + +struct MockApi; + +sp_api::mock_impl_runtime_apis! { + impl Api for MockApi { + fn test(self, data: u64) {} + + fn test2(&mut self, data: u64) {} + } +} + +fn main() {} diff --git a/primitives/api/test/tests/ui/mock_only_self_reference.stderr b/primitives/api/test/tests/ui/mock_only_self_reference.stderr new file mode 100644 index 0000000000..9c1658b0a6 --- /dev/null +++ b/primitives/api/test/tests/ui/mock_only_self_reference.stderr @@ -0,0 +1,65 @@ +error: Only `&self` is supported! + --> $DIR/mock_only_self_reference.rs:14:11 + | +14 | fn test(self, data: u64) {} + | ^^^^ + +error: Only `&self` is supported! + --> $DIR/mock_only_self_reference.rs:16:12 + | +16 | fn test2(&mut self, data: u64) {} + | ^ + +error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for trait + --> $DIR/mock_only_self_reference.rs:12:1 + | +3 | / sp_api::decl_runtime_apis! { +4 | | pub trait Api { +5 | | fn test(data: u64); +6 | | fn test2(data: u64); +7 | | } +8 | | } + | |_- type in trait +... +12 | sp_api::mock_impl_runtime_apis! { + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | _expected `u64`, found `()` + | | +13 | | impl Api for MockApi { +14 | | fn test(self, data: u64) {} +15 | | +16 | | fn test2(&mut self, data: u64) {} +17 | | } +18 | | } + | |_- in this macro invocation + | + = note: expected fn pointer `fn(&MockApi, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId, substrate_test_runtime::Extrinsic>>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec<_>) -> std::result::Result<_, _>` + found fn pointer `fn(&MockApi, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId, substrate_test_runtime::Extrinsic>>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option<()>, std::vec::Vec<_>) -> std::result::Result<_, _>` + +error[E0053]: method `Api_test2_runtime_api_impl` has an incompatible type for trait + --> $DIR/mock_only_self_reference.rs:12:1 + | +3 | / sp_api::decl_runtime_apis! { +4 | | pub trait Api { +5 | | fn test(data: u64); +6 | | fn test2(data: u64); +7 | | } +8 | | } + | |_- type in trait +... +12 | sp_api::mock_impl_runtime_apis! { + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | _expected `u64`, found `()` + | | +13 | | impl Api for MockApi { +14 | | fn test(self, data: u64) {} +15 | | +16 | | fn test2(&mut self, data: u64) {} +17 | | } +18 | | } + | |_- in this macro invocation + | + = note: expected fn pointer `fn(&MockApi, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId, substrate_test_runtime::Extrinsic>>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec<_>) -> std::result::Result<_, _>` + found fn pointer `fn(&MockApi, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId, substrate_test_runtime::Extrinsic>>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option<()>, std::vec::Vec<_>) -> std::result::Result<_, _>` -- GitLab From 5f51dd868512f38cf27beb7dd743017bb59f4037 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Tue, 31 Mar 2020 15:20:09 +0200 Subject: [PATCH 116/300] Batch benchmarks together with `*` notation. (#5436) * Batch benchmarks together with `*` notation. * Fix short structopt conflict * Return error if `batches` is empty * Move fast benchmarks macro into `frame_benchmarking` (#5445) * Move macro into `frame_benchmarking` * Update docs * Extra line * Return error if `batches` is empty Co-authored-by: Shawn Tabrizi --- bin/node/runtime/src/lib.rs | 97 +++++-------------------- frame/benchmarking/src/lib.rs | 90 ++++++++++++++++++++--- frame/benchmarking/src/utils.rs | 34 ++++++--- utils/frame/benchmarking-cli/src/lib.rs | 71 +++++++++++------- 4 files changed, 166 insertions(+), 126 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 8868f28557..799fc5397c 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -858,95 +858,34 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { fn dispatch_benchmark( - module: Vec, - extrinsic: Vec, + pallet: Vec, + benchmark: Vec, lowest_range_values: Vec, highest_range_values: Vec, steps: Vec, repeat: u32, - ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::Benchmarking; + ) -> Result, sp_runtime::RuntimeString> { + use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark}; // Trying to add benchmarks directly to the Session Pallet caused cyclic dependency issues. // To get around that, we separated the Session benchmarks into its own crate, which is why // we need these two lines below. use pallet_session_benchmarking::Module as SessionBench; impl pallet_session_benchmarking::Trait for Runtime {} - let result = match module.as_slice() { - b"pallet-balances" | b"balances" => Balances::run_benchmark( - extrinsic, - lowest_range_values, - highest_range_values, - steps, - repeat, - ), - b"pallet-im-online" | b"im-online" => ImOnline::run_benchmark( - extrinsic, - lowest_range_values, - highest_range_values, - steps, - repeat, - ), - b"pallet-identity" | b"identity" => Identity::run_benchmark( - extrinsic, - lowest_range_values, - highest_range_values, - steps, - repeat, - ), - b"pallet-session" | b"session" => SessionBench::::run_benchmark( - extrinsic, - lowest_range_values, - highest_range_values, - steps, - repeat, - ), - b"pallet-staking" | b"staking" => Staking::run_benchmark( - extrinsic, - lowest_range_values, - highest_range_values, - steps, - repeat, - ), - b"pallet-timestamp" | b"timestamp" => Timestamp::run_benchmark( - extrinsic, - lowest_range_values, - highest_range_values, - steps, - repeat, - ), - b"pallet-treasury" | b"treasury" => Treasury::run_benchmark( - extrinsic, - lowest_range_values, - highest_range_values, - steps, - repeat, - ), - b"pallet-vesting" | b"vesting" => Vesting::run_benchmark( - extrinsic, - lowest_range_values, - highest_range_values, - steps, - repeat, - ), - b"pallet-democracy" | b"democracy" => Democracy::run_benchmark( - extrinsic, - lowest_range_values, - highest_range_values, - steps, - repeat, - ), - b"pallet-collective" | b"collective" => Council::run_benchmark( - extrinsic, - lowest_range_values, - highest_range_values, - steps, - repeat, - ), - _ => Err("Benchmark not found for this pallet."), - }; - - result.map_err(|e| e.into()) + let mut batches = Vec::::new(); + let params = (&pallet, &benchmark, &lowest_range_values, &highest_range_values, &steps, repeat); + add_benchmark!(params, batches, b"balances", Balances); + add_benchmark!(params, batches, b"im-online", ImOnline); + add_benchmark!(params, batches, b"identity", Identity); + add_benchmark!(params, batches, b"session", SessionBench::); + add_benchmark!(params, batches, b"staking", Staking); + add_benchmark!(params, batches, b"timestamp", Timestamp); + add_benchmark!(params, batches, b"treasury", Treasury); + add_benchmark!(params, batches, b"vesting", Vesting); + add_benchmark!(params, batches, b"democracy", Democracy); + add_benchmark!(params, batches, b"collective", Council); + if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } + Ok(batches) } } } diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index 4254edcac5..4cd6072ce4 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -505,15 +505,19 @@ macro_rules! impl_benchmark { NO_INSTANCE $( $name:ident ),* ) => { impl $crate::Benchmarking<$crate::BenchmarkResults> for Module { + fn benchmarks() -> Vec<&'static [u8]> { + vec![ $( stringify!($name).as_ref() ),* ] + } + fn run_benchmark( - extrinsic: Vec, - lowest_range_values: Vec, - highest_range_values: Vec, - steps: Vec, + extrinsic: &[u8], + lowest_range_values: &[u32], + highest_range_values: &[u32], + steps: &[u32], repeat: u32, ) -> Result, &'static str> { // Map the input to the selected benchmark. - let extrinsic = sp_std::str::from_utf8(extrinsic.as_slice()) + let extrinsic = sp_std::str::from_utf8(extrinsic) .map_err(|_| "`extrinsic` is not a valid utf8 string!")?; let selected_benchmark = match extrinsic { $( stringify!($name) => SelectedBenchmark::$name, )* @@ -597,15 +601,19 @@ macro_rules! impl_benchmark { INSTANCE $( $name:ident ),* ) => { impl, I: Instance> $crate::Benchmarking<$crate::BenchmarkResults> for Module { + fn benchmarks() -> Vec<&'static [u8]> { + vec![ $( stringify!($name).as_ref() ),* ] + } + fn run_benchmark( - extrinsic: Vec, - lowest_range_values: Vec, - highest_range_values: Vec, - steps: Vec, + extrinsic: &[u8], + lowest_range_values: &[u32], + highest_range_values: &[u32], + steps: &[u32], repeat: u32, ) -> Result, &'static str> { // Map the input to the selected benchmark. - let extrinsic = sp_std::str::from_utf8(extrinsic.as_slice()) + let extrinsic = sp_std::str::from_utf8(extrinsic) .map_err(|_| "`extrinsic` is not a valid utf8 string!")?; let selected_benchmark = match extrinsic { $( stringify!($name) => SelectedBenchmark::$name, )* @@ -686,3 +694,65 @@ macro_rules! impl_benchmark { } } } + + +/// This macro adds pallet benchmarks to a `Vec` object. +/// +/// First create an object that holds in the input parameters for the benchmark: +/// +/// ```ignore +/// let params = (&pallet, &benchmark, &lowest_range_values, &highest_range_values, &steps, repeat); +/// ``` +/// +/// Then define a mutable local variable to hold your `BenchmarkBatch` object: +/// +/// ```ignore +/// let mut batches = Vec::::new(); +/// ```` +/// +/// Then add the pallets you want to benchmark to this object, including the string +/// you want to use target a particular pallet: +/// +/// ```ignore +/// add_benchmark!(params, batches, b"balances", Balances); +/// add_benchmark!(params, batches, b"identity", Identity); +/// add_benchmark!(params, batches, b"session", SessionBench::); +/// ... +/// ``` +/// +/// At the end of `dispatch_benchmark`, you should return this batches object. +#[macro_export] +macro_rules! add_benchmark { + ( $params:ident, $batches:ident, $name:literal, $( $location:tt )* ) => ( + let (pallet, benchmark, lowest_range_values, highest_range_values, steps, repeat) = $params; + if &pallet[..] == &$name[..] || &pallet[..] == &b"*"[..] { + if &pallet[..] == &b"*"[..] || &benchmark[..] == &b"*"[..] { + for benchmark in $( $location )*::benchmarks().into_iter() { + $batches.push($crate::BenchmarkBatch { + results: $( $location )*::run_benchmark( + benchmark, + &lowest_range_values[..], + &highest_range_values[..], + &steps[..], + repeat, + )?, + pallet: pallet.to_vec(), + benchmark: benchmark.to_vec(), + }); + } + } else { + $batches.push($crate::BenchmarkBatch { + results: $( $location )*::run_benchmark( + &benchmark[..], + &lowest_range_values[..], + &highest_range_values[..], + &steps[..], + repeat, + )?, + pallet: pallet.to_vec(), + benchmark: benchmark.clone(), + }); + } + } + ) +} diff --git a/frame/benchmarking/src/utils.rs b/frame/benchmarking/src/utils.rs index 122ef02997..a6f262eab9 100644 --- a/frame/benchmarking/src/utils.rs +++ b/frame/benchmarking/src/utils.rs @@ -22,13 +22,24 @@ use sp_io::hashing::blake2_256; use sp_runtime::RuntimeString; /// An alphabet of possible parameters to use for benchmarking. -#[derive(codec::Encode, codec::Decode, Clone, Copy, PartialEq, Debug)] +#[derive(Encode, Decode, Clone, Copy, PartialEq, Debug)] #[allow(missing_docs)] #[allow(non_camel_case_types)] pub enum BenchmarkParameter { a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, } +/// The results of a single of benchmark. +#[derive(Encode, Decode, Clone, PartialEq, Debug)] +pub struct BenchmarkBatch { + /// The pallet containing this benchmark. + pub pallet: Vec, + /// The extrinsic (or benchmark name) of this benchmark. + pub benchmark: Vec, + /// The results from this benchmark. + pub results: Vec, +} + /// Results from running benchmarks on a FRAME pallet. /// Contains duration of the function call in nanoseconds along with the benchmark parameters /// used for that benchmark result. @@ -39,13 +50,13 @@ sp_api::decl_runtime_apis! { pub trait Benchmark { /// Dispatch the given benchmark. fn dispatch_benchmark( - module: Vec, - extrinsic: Vec, + pallet: Vec, + benchmark: Vec, lowest_range_values: Vec, highest_range_values: Vec, steps: Vec, repeat: u32, - ) -> Result, RuntimeString>; + ) -> Result, RuntimeString>; } } @@ -75,19 +86,24 @@ pub trait Benchmarking { /// The pallet benchmarking trait. pub trait Benchmarking { + /// Get the benchmarks available for this pallet. Generally there is one benchmark per + /// extrinsic, so these are sometimes just called "extrinsics". + fn benchmarks() -> Vec<&'static [u8]>; + /// Run the benchmarks for this pallet. /// /// Parameters - /// - `extrinsic`: The name of extrinsic function you want to benchmark encoded as bytes. + /// - `name`: The name of extrinsic function or benchmark you want to benchmark encoded as + /// bytes. /// - `steps`: The number of sample points you want to take across the range of parameters. /// - `lowest_range_values`: The lowest number for each range of parameters. /// - `highest_range_values`: The highest number for each range of parameters. /// - `repeat`: The number of times you want to repeat a benchmark. fn run_benchmark( - extrinsic: Vec, - lowest_range_values: Vec, - highest_range_values: Vec, - steps: Vec, + name: &[u8], + lowest_range_values: &[u32], + highest_range_values: &[u32], + steps: &[u32], repeat: u32, ) -> Result, &'static str>; } diff --git a/utils/frame/benchmarking-cli/src/lib.rs b/utils/frame/benchmarking-cli/src/lib.rs index 1c02a75401..f9851810bf 100644 --- a/utils/frame/benchmarking-cli/src/lib.rs +++ b/utils/frame/benchmarking-cli/src/lib.rs @@ -22,7 +22,7 @@ use sc_client_db::BenchmarkingState; use sc_service::{Configuration, ChainSpec}; use sc_executor::{NativeExecutor, NativeExecutionDispatch}; use codec::{Encode, Decode}; -use frame_benchmarking::{BenchmarkResults, Analysis}; +use frame_benchmarking::{BenchmarkBatch, Analysis}; use sp_core::{ tasks, traits::KeystoreExt, @@ -33,11 +33,11 @@ use sp_externalities::Extensions; /// The `benchmark` command used to benchmark FRAME Pallets. #[derive(Debug, structopt::StructOpt, Clone)] pub struct BenchmarkCmd { - /// Select a FRAME Pallet to benchmark. + /// Select a FRAME Pallet to benchmark, or `*` for all (in which case `extrinsic` must be `*`). #[structopt(short, long)] pub pallet: String, - /// Select an extrinsic to benchmark. + /// Select an extrinsic inside the pallet to benchmark, or `*` for all. #[structopt(short, long)] pub extrinsic: String, @@ -46,17 +46,29 @@ pub struct BenchmarkCmd { pub steps: Vec, /// Indicates lowest values for each of the component ranges. - #[structopt(long, use_delimiter = true)] + #[structopt(long = "low", use_delimiter = true)] pub lowest_range_values: Vec, /// Indicates highest values for each of the component ranges. - #[structopt(long, use_delimiter = true)] + #[structopt(long = "high", use_delimiter = true)] pub highest_range_values: Vec, /// Select how many repetitions of this benchmark should run. #[structopt(short, long, default_value = "1")] pub repeat: u32, + /// Print the raw results. + #[structopt(long = "raw")] + pub raw_data: bool, + + /// Don't print the median-slopes linear regression analysis. + #[structopt(long)] + pub no_median_slopes: bool, + + /// Don't print the min-squares linear regression analysis. + #[structopt(long)] + pub no_min_squares: bool, + #[allow(missing_docs)] #[structopt(flatten)] pub shared_params: sc_cli::SharedParams, @@ -135,47 +147,50 @@ impl BenchmarkCmd { .execute(strategy.into()) .map_err(|e| format!("Error executing runtime benchmark: {:?}", e))?; - let results = , String> as Decode>::decode(&mut &result[..]) + let results = , String> as Decode>::decode(&mut &result[..]) .map_err(|e| format!("Failed to decode benchmark results: {:?}", e))?; match results { - Ok(results) => { + Ok(batches) => for batch in batches.into_iter() { // Print benchmark metadata println!( "Pallet: {:?}, Extrinsic: {:?}, Lowest values: {:?}, Highest values: {:?}, Steps: {:?}, Repeat: {:?}", - self.pallet, - self.extrinsic, + String::from_utf8(batch.pallet).expect("Encoded from String; qed"), + String::from_utf8(batch.benchmark).expect("Encoded from String; qed"), self.lowest_range_values, self.highest_range_values, self.steps, self.repeat, ); - // Print the table header - results[0].0.iter().for_each(|param| print!("{:?},", param.0)); + if self.raw_data { + // Print the table header + batch.results[0].0.iter().for_each(|param| print!("{:?},", param.0)); - print!("extrinsic_time,storage_root_time\n"); - // Print the values - results.iter().for_each(|result| { - let parameters = &result.0; - parameters.iter().for_each(|param| print!("{:?},", param.1)); - // Print extrinsic time and storage root time - print!("{:?},{:?}\n", result.1, result.2); - }); + print!("extrinsic_time,storage_root_time\n"); + // Print the values + batch.results.iter().for_each(|result| { + let parameters = &result.0; + parameters.iter().for_each(|param| print!("{:?},", param.1)); + // Print extrinsic time and storage root time + print!("{:?},{:?}\n", result.1, result.2); + }); - print!("\n"); + print!("\n"); + } // Conduct analysis. - if let Some(analysis) = Analysis::median_slopes(&results) { - println!("Median Slopes Analysis\n========\n{}", analysis); + if !self.no_median_slopes { + if let Some(analysis) = Analysis::median_slopes(&batch.results) { + println!("Median Slopes Analysis\n========\n{}", analysis); + } } - - if let Some(analysis) = Analysis::min_squares_iqr(&results) { - println!("Min Squares Analysis\n========\n{}", analysis); + if !self.no_min_squares { + if let Some(analysis) = Analysis::min_squares_iqr(&batch.results) { + println!("Min Squares Analysis\n========\n{}", analysis); + } } - - eprintln!("Done."); - } + }, Err(error) => eprintln!("Error: {:?}", error), } -- GitLab From d0bbb22fa335bec188dea29e28db530c4bab86ae Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 31 Mar 2020 15:57:08 +0200 Subject: [PATCH 117/300] Prevent events from being emitted during genesis construction (#5463) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Don't populate runtime events in genesis * typo * Change to block zero * Fix vesting tests * Update frame/system/src/lib.rs Co-Authored-By: Bastian Köcher * Update frame/system/src/lib.rs Co-Authored-By: Bastian Köcher * Add test * Fix test * Fix contract tests * Fix phragmen tests * Fix Generic Assets Tests * Fix offences tests * Fix im-online * fix recovery * Fix utility tests * Shorter * Use ext Co-authored-by: Bastian Köcher --- bin/node/executor/tests/submit_transaction.rs | 3 +- frame/collective/src/lib.rs | 19 +++--------- frame/contracts/src/tests.rs | 4 ++- frame/democracy/src/tests.rs | 4 ++- frame/democracy/src/tests/cancellation.rs | 1 - frame/democracy/src/tests/lock_voting.rs | 1 - frame/democracy/src/tests/preimage.rs | 6 ---- frame/democracy/src/tests/public_proposals.rs | 6 ---- frame/democracy/src/tests/scheduling.rs | 4 --- frame/democracy/src/tests/voting.rs | 3 -- frame/elections-phragmen/src/lib.rs | 29 +++++++++---------- frame/elections/src/mock.rs | 6 ++-- frame/elections/src/tests.rs | 24 --------------- frame/generic-asset/src/mock.rs | 21 +++++++------- frame/im-online/src/mock.rs | 2 +- frame/offences/src/mock.rs | 4 ++- frame/recovery/src/tests.rs | 4 +-- frame/staking/src/mock.rs | 1 + frame/staking/src/tests.rs | 1 - frame/system/src/lib.rs | 24 +++++++++++++-- frame/utility/src/lib.rs | 4 ++- frame/vesting/src/lib.rs | 12 ++------ 22 files changed, 73 insertions(+), 110 deletions(-) diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index 784b140a13..536cf486e3 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -181,9 +181,8 @@ fn submitted_transaction_should_be_valid() { priority: 2_411_002_000_000, requires: vec![], provides: vec![(address, 0).encode()], - longevity: 127, + longevity: 128, propagate: true, }); }); } - diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 5afdcd2b42..d06d83b5be 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -590,19 +590,20 @@ mod tests { ); fn make_ext() -> sp_io::TestExternalities { - GenesisConfig { + let mut ext: sp_io::TestExternalities = GenesisConfig { collective_Instance1: Some(collective::GenesisConfig { members: vec![1, 2, 3], phantom: Default::default(), }), collective: None, - }.build_storage().unwrap().into() + }.build_storage().unwrap().into(); + ext.execute_with(|| System::set_block_number(1)); + ext } #[test] fn motions_basic_environment_works() { make_ext().execute_with(|| { - System::set_block_number(1); assert_eq!(Collective::members(), vec![1, 2, 3]); assert_eq!(Collective::proposals(), Vec::::new()); }); @@ -615,7 +616,6 @@ mod tests { #[test] fn close_works() { make_ext().execute_with(|| { - System::set_block_number(1); let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); @@ -644,7 +644,6 @@ mod tests { #[test] fn close_with_prime_works() { make_ext().execute_with(|| { - System::set_block_number(1); let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(Collective::set_members(Origin::ROOT, vec![1, 2, 3], Some(3))); @@ -668,7 +667,6 @@ mod tests { #[test] fn close_with_voting_prime_works() { make_ext().execute_with(|| { - System::set_block_number(1); let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(Collective::set_members(Origin::ROOT, vec![1, 2, 3], Some(1))); @@ -693,7 +691,6 @@ mod tests { #[test] fn removal_of_old_voters_votes_works() { make_ext().execute_with(|| { - System::set_block_number(1); let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); let end = 4; @@ -728,7 +725,6 @@ mod tests { #[test] fn removal_of_old_voters_votes_works_with_set_members() { make_ext().execute_with(|| { - System::set_block_number(1); let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); let end = 4; @@ -763,7 +759,6 @@ mod tests { #[test] fn propose_works() { make_ext().execute_with(|| { - System::set_block_number(1); let proposal = make_proposal(42); let hash = proposal.blake2_256().into(); let end = 4; @@ -793,7 +788,6 @@ mod tests { #[test] fn motions_ignoring_non_collective_proposals_works() { make_ext().execute_with(|| { - System::set_block_number(1); let proposal = make_proposal(42); assert_noop!( Collective::propose(Origin::signed(42), 3, Box::new(proposal.clone())), @@ -805,7 +799,6 @@ mod tests { #[test] fn motions_ignoring_non_collective_votes_works() { make_ext().execute_with(|| { - System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); @@ -833,7 +826,6 @@ mod tests { #[test] fn motions_revoting_works() { make_ext().execute_with(|| { - System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); let end = 4; @@ -885,7 +877,6 @@ mod tests { #[test] fn motions_reproposing_disapproved_works() { make_ext().execute_with(|| { - System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); @@ -899,7 +890,6 @@ mod tests { #[test] fn motions_disapproval_works() { make_ext().execute_with(|| { - System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); @@ -942,7 +932,6 @@ mod tests { #[test] fn motions_approval_works() { make_ext().execute_with(|| { - System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); assert_ok!(Collective::propose(Origin::signed(1), 2, Box::new(proposal.clone()))); diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 3c6cd62a44..04b9b1ee4c 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -279,7 +279,9 @@ impl ExtBuilder { }, gas_price: self.gas_price, }.assimilate_storage(&mut t).unwrap(); - sp_io::TestExternalities::new(t) + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext } } diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index f2544470aa..1e2e6dc688 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -160,7 +160,9 @@ fn new_test_ext() -> sp_io::TestExternalities { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], }.assimilate_storage(&mut t).unwrap(); GenesisConfig::default().assimilate_storage(&mut t).unwrap(); - sp_io::TestExternalities::new(t) + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext } type System = frame_system::Module; diff --git a/frame/democracy/src/tests/cancellation.rs b/frame/democracy/src/tests/cancellation.rs index c0e1b8b27a..424ec36dbe 100644 --- a/frame/democracy/src/tests/cancellation.rs +++ b/frame/democracy/src/tests/cancellation.rs @@ -21,7 +21,6 @@ use super::*; #[test] fn cancel_referendum_should_work() { new_test_ext().execute_with(|| { - System::set_block_number(1); let r = Democracy::inject_referendum( 2, set_balance_proposal_hash_and_note(2), diff --git a/frame/democracy/src/tests/lock_voting.rs b/frame/democracy/src/tests/lock_voting.rs index c46bb47b89..e83d974a8d 100644 --- a/frame/democracy/src/tests/lock_voting.rs +++ b/frame/democracy/src/tests/lock_voting.rs @@ -140,7 +140,6 @@ fn no_locks_without_conviction_should_work() { #[test] fn lock_voting_should_work_with_delegation() { new_test_ext().execute_with(|| { - System::set_block_number(1); let r = Democracy::inject_referendum( 2, set_balance_proposal_hash_and_note(2), diff --git a/frame/democracy/src/tests/preimage.rs b/frame/democracy/src/tests/preimage.rs index 1fb805f726..8d834c319e 100644 --- a/frame/democracy/src/tests/preimage.rs +++ b/frame/democracy/src/tests/preimage.rs @@ -21,7 +21,6 @@ use super::*; #[test] fn missing_preimage_should_fail() { new_test_ext().execute_with(|| { - System::set_block_number(1); let r = Democracy::inject_referendum( 2, set_balance_proposal_hash(2), @@ -40,7 +39,6 @@ fn missing_preimage_should_fail() { #[test] fn preimage_deposit_should_be_required_and_returned() { new_test_ext().execute_with(|| { - System::set_block_number(1); // fee of 100 is too much. PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 100); assert_noop!( @@ -71,7 +69,6 @@ fn preimage_deposit_should_be_required_and_returned() { #[test] fn preimage_deposit_should_be_reapable_earlier_by_owner() { new_test_ext().execute_with(|| { - System::set_block_number(1); PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); assert_ok!(Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2))); @@ -93,7 +90,6 @@ fn preimage_deposit_should_be_reapable_earlier_by_owner() { #[test] fn preimage_deposit_should_be_reapable() { new_test_ext().execute_with(|| { - System::set_block_number(1); assert_noop!( Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2)), Error::::PreimageMissing @@ -122,7 +118,6 @@ fn preimage_deposit_should_be_reapable() { #[test] fn noting_imminent_preimage_for_free_should_work() { new_test_ext().execute_with(|| { - System::set_block_number(1); PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); let r = Democracy::inject_referendum( @@ -152,7 +147,6 @@ fn noting_imminent_preimage_for_free_should_work() { #[test] fn reaping_imminent_preimage_should_fail() { new_test_ext().execute_with(|| { - System::set_block_number(1); let h = set_balance_proposal_hash_and_note(2); let r = Democracy::inject_referendum(3, h, VoteThreshold::SuperMajorityApprove, 1); assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); diff --git a/frame/democracy/src/tests/public_proposals.rs b/frame/democracy/src/tests/public_proposals.rs index ef68714601..04246e86f1 100644 --- a/frame/democracy/src/tests/public_proposals.rs +++ b/frame/democracy/src/tests/public_proposals.rs @@ -21,7 +21,6 @@ use super::*; #[test] fn backing_for_should_work() { new_test_ext().execute_with(|| { - System::set_block_number(1); assert_ok!(propose_set_balance_and_note(1, 2, 2)); assert_ok!(propose_set_balance_and_note(1, 4, 4)); assert_ok!(propose_set_balance_and_note(1, 3, 3)); @@ -34,7 +33,6 @@ fn backing_for_should_work() { #[test] fn deposit_for_proposals_should_be_taken() { new_test_ext().execute_with(|| { - System::set_block_number(1); assert_ok!(propose_set_balance_and_note(1, 2, 5)); assert_ok!(Democracy::second(Origin::signed(2), 0)); assert_ok!(Democracy::second(Origin::signed(5), 0)); @@ -49,7 +47,6 @@ fn deposit_for_proposals_should_be_taken() { #[test] fn deposit_for_proposals_should_be_returned() { new_test_ext().execute_with(|| { - System::set_block_number(1); assert_ok!(propose_set_balance_and_note(1, 2, 5)); assert_ok!(Democracy::second(Origin::signed(2), 0)); assert_ok!(Democracy::second(Origin::signed(5), 0)); @@ -65,7 +62,6 @@ fn deposit_for_proposals_should_be_returned() { #[test] fn proposal_with_deposit_below_minimum_should_not_work() { new_test_ext().execute_with(|| { - System::set_block_number(1); assert_noop!(propose_set_balance(1, 2, 0), Error::::ValueLow); }); } @@ -73,7 +69,6 @@ fn proposal_with_deposit_below_minimum_should_not_work() { #[test] fn poor_proposer_should_not_work() { new_test_ext().execute_with(|| { - System::set_block_number(1); assert_noop!(propose_set_balance(1, 2, 11), BalancesError::::InsufficientBalance); }); } @@ -81,7 +76,6 @@ fn poor_proposer_should_not_work() { #[test] fn poor_seconder_should_not_work() { new_test_ext().execute_with(|| { - System::set_block_number(1); assert_ok!(propose_set_balance_and_note(2, 2, 11)); assert_noop!(Democracy::second(Origin::signed(1), 0), BalancesError::::InsufficientBalance); }); diff --git a/frame/democracy/src/tests/scheduling.rs b/frame/democracy/src/tests/scheduling.rs index 81120ea5b5..db9724dedd 100644 --- a/frame/democracy/src/tests/scheduling.rs +++ b/frame/democracy/src/tests/scheduling.rs @@ -21,7 +21,6 @@ use super::*; #[test] fn simple_passing_should_work() { new_test_ext().execute_with(|| { - System::set_block_number(1); let r = Democracy::inject_referendum( 2, set_balance_proposal_hash_and_note(2), @@ -39,7 +38,6 @@ fn simple_passing_should_work() { #[test] fn simple_failing_should_work() { new_test_ext().execute_with(|| { - System::set_block_number(1); let r = Democracy::inject_referendum( 2, set_balance_proposal_hash_and_note(2), @@ -59,7 +57,6 @@ fn simple_failing_should_work() { #[test] fn ooo_inject_referendums_should_work() { new_test_ext().execute_with(|| { - System::set_block_number(1); let r1 = Democracy::inject_referendum( 3, set_balance_proposal_hash_and_note(3), @@ -90,7 +87,6 @@ fn ooo_inject_referendums_should_work() { #[test] fn delayed_enactment_should_work() { new_test_ext().execute_with(|| { - System::set_block_number(1); let r = Democracy::inject_referendum( 2, set_balance_proposal_hash_and_note(2), diff --git a/frame/democracy/src/tests/voting.rs b/frame/democracy/src/tests/voting.rs index 06fde99cbd..bdb8edb758 100644 --- a/frame/democracy/src/tests/voting.rs +++ b/frame/democracy/src/tests/voting.rs @@ -99,7 +99,6 @@ fn single_proposal_should_work() { #[test] fn controversial_voting_should_work() { new_test_ext().execute_with(|| { - System::set_block_number(1); let r = Democracy::inject_referendum( 2, set_balance_proposal_hash_and_note(2), @@ -126,7 +125,6 @@ fn controversial_voting_should_work() { #[test] fn controversial_low_turnout_voting_should_work() { new_test_ext().execute_with(|| { - System::set_block_number(1); let r = Democracy::inject_referendum( 2, set_balance_proposal_hash_and_note(2), @@ -151,7 +149,6 @@ fn passing_low_turnout_voting_should_work() { assert_eq!(Balances::free_balance(42), 0); assert_eq!(Balances::total_issuance(), 210); - System::set_block_number(1); let r = Democracy::inject_referendum( 2, set_balance_proposal_hash_and_note(2), diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 9a9e3c3143..12307fe712 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -1040,7 +1040,7 @@ mod tests { VOTING_BOND.with(|v| *v.borrow_mut() = self.voter_bond); TERM_DURATION.with(|v| *v.borrow_mut() = self.term_duration); DESIRED_RUNNERS_UP.with(|v| *v.borrow_mut() = self.desired_runners_up); - GenesisConfig { + let mut ext: sp_io::TestExternalities = GenesisConfig { pallet_balances: Some(pallet_balances::GenesisConfig::{ balances: vec![ (1, 10 * self.balance_factor), @@ -1051,7 +1051,9 @@ mod tests { (6, 60 * self.balance_factor) ], }), - }.build_storage().unwrap().into() + }.build_storage().unwrap().into(); + ext.execute_with(|| System::set_block_number(1)); + ext } } @@ -1072,7 +1074,6 @@ mod tests { #[test] fn params_should_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); assert_eq!(Elections::desired_members(), 2); assert_eq!(Elections::term_duration(), 5); assert_eq!(Elections::election_rounds(), 0); @@ -1096,7 +1097,6 @@ mod tests { .build() .execute_with(|| { - System::set_block_number(1); assert_eq!(Elections::term_duration(), 0); assert_eq!(Elections::desired_members(), 2); assert_eq!(Elections::election_rounds(), 0); @@ -1537,10 +1537,9 @@ mod tests { assert_eq!(balances(&5), (45, 5)); assert_ok!(Elections::report_defunct_voter(Origin::signed(5), 3)); - assert_eq!( - System::events()[7].event, - Event::elections(RawEvent::VoterReported(3, 5, true)) - ); + assert!(System::events().iter().any(|event| { + event.event == Event::elections(RawEvent::VoterReported(3, 5, true)) + })); assert_eq!(balances(&3), (28, 0)); assert_eq!(balances(&5), (47, 5)); @@ -1566,10 +1565,9 @@ mod tests { assert_eq!(balances(&5), (45, 5)); assert_ok!(Elections::report_defunct_voter(Origin::signed(5), 4)); - assert_eq!( - System::events()[7].event, - Event::elections(RawEvent::VoterReported(4, 5, false)) - ); + assert!(System::events().iter().any(|event| { + event.event == Event::elections(RawEvent::VoterReported(4, 5, false)) + })); assert_eq!(balances(&4), (35, 5)); assert_eq!(balances(&5), (45, 3)); @@ -1977,10 +1975,9 @@ mod tests { // 5 is an outgoing loser. will also get slashed. assert_eq!(balances(&5), (45, 2)); - assert_eq!( - System::events()[6].event, - Event::elections(RawEvent::NewTerm(vec![(4, 40), (5, 50)])), - ); + assert!(System::events().iter().any(|event| { + event.event == Event::elections(RawEvent::NewTerm(vec![(4, 40), (5, 50)])) + })); }) } diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index b82e73d512..2898be26ca 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -208,7 +208,7 @@ impl ExtBuilder { VOTING_FEE.with(|v| *v.borrow_mut() = self.voting_fee); PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow_mut() = self.bad_presentation_punishment); DECAY_RATIO.with(|v| *v.borrow_mut() = self.decay_ratio); - GenesisConfig { + let mut ext: sp_io::TestExternalities = GenesisConfig { pallet_balances: Some(pallet_balances::GenesisConfig::{ balances: vec![ (1, 10 * self.balance_factor), @@ -225,7 +225,9 @@ impl ExtBuilder { presentation_duration: 2, term_duration: 5, }), - }.build_storage().unwrap().into() + }.build_storage().unwrap().into(); + ext.execute_with(|| System::set_block_number(1)); + ext } } diff --git a/frame/elections/src/tests.rs b/frame/elections/src/tests.rs index e26f031290..64b01f12e0 100644 --- a/frame/elections/src/tests.rs +++ b/frame/elections/src/tests.rs @@ -26,7 +26,6 @@ use frame_support::{assert_ok, assert_err, assert_noop}; #[test] fn params_should_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); assert_eq!(Elections::next_vote_from(1), 4); assert_eq!(Elections::next_vote_from(4), 4); assert_eq!(Elections::next_vote_from(5), 8); @@ -408,8 +407,6 @@ fn voting_locking_stake_and_reserving_bond_works() { #[test] fn voting_without_any_candidate_count_should_not_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); - assert_eq!(Elections::candidates().len(), 0); assert_noop!( @@ -422,8 +419,6 @@ fn voting_without_any_candidate_count_should_not_work() { #[test] fn voting_setting_an_approval_vote_count_more_than_candidate_count_should_not_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); assert_eq!(Elections::candidates().len(), 1); @@ -437,8 +432,6 @@ fn voting_setting_an_approval_vote_count_more_than_candidate_count_should_not_wo #[test] fn voting_resubmitting_approvals_should_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 0, 40)); @@ -456,8 +449,6 @@ fn voting_resubmitting_approvals_should_work() { #[test] fn voting_retracting_voter_should_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); assert_eq!(Elections::candidates().len(), 1); @@ -501,7 +492,6 @@ fn voting_retracting_voter_should_work() { #[test] fn voting_invalid_retraction_index_should_not_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); @@ -514,7 +504,6 @@ fn voting_invalid_retraction_index_should_not_work() { #[test] fn voting_overflow_retraction_index_should_not_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); @@ -525,7 +514,6 @@ fn voting_overflow_retraction_index_should_not_work() { #[test] fn voting_non_voter_retraction_should_not_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); @@ -740,7 +728,6 @@ fn retracting_inactive_voter_by_nonvoter_should_not_work() { #[test] fn candidacy_simple_candidate_submission_should_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_eq!(Elections::candidate_reg_info(1), None); assert_eq!(Elections::candidate_reg_info(2), None); @@ -768,7 +755,6 @@ fn candidacy_submission_using_free_slot_should_work() { let mut t = new_test_ext_with_candidate_holes(); t.execute_with(|| { - System::set_block_number(1); assert_eq!(Elections::candidates(), vec![0, 0, 1]); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); @@ -784,7 +770,6 @@ fn candidacy_submission_using_alternative_free_slot_should_work() { let mut t = new_test_ext_with_candidate_holes(); t.execute_with(|| { - System::set_block_number(1); assert_eq!(Elections::candidates(), vec![0, 0, 1]); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); @@ -800,7 +785,6 @@ fn candidacy_submission_not_using_free_slot_should_not_work() { let mut t = new_test_ext_with_candidate_holes(); t.execute_with(|| { - System::set_block_number(1); assert_noop!( Elections::submit_candidacy(Origin::signed(4), 3), Error::::InvalidCandidateSlot @@ -811,7 +795,6 @@ fn candidacy_submission_not_using_free_slot_should_not_work() { #[test] fn candidacy_bad_candidate_slot_submission_should_not_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_noop!( Elections::submit_candidacy(Origin::signed(1), 1), @@ -823,7 +806,6 @@ fn candidacy_bad_candidate_slot_submission_should_not_work() { #[test] fn candidacy_non_free_candidate_slot_submission_should_not_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); assert_eq!(Elections::candidates(), vec![1]); @@ -837,7 +819,6 @@ fn candidacy_non_free_candidate_slot_submission_should_not_work() { #[test] fn candidacy_dupe_candidate_submission_should_not_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); assert_eq!(Elections::candidates(), vec![1]); @@ -851,7 +832,6 @@ fn candidacy_dupe_candidate_submission_should_not_work() { #[test] fn candidacy_poor_candidate_submission_should_not_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_noop!( Elections::submit_candidacy(Origin::signed(7), 0), @@ -863,8 +843,6 @@ fn candidacy_poor_candidate_submission_should_not_work() { #[test] fn election_voting_should_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); @@ -892,8 +870,6 @@ fn election_voting_should_work() { #[test] fn election_proxy_voting_should_work() { ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); >::insert(11, 1); diff --git a/frame/generic-asset/src/mock.rs b/frame/generic-asset/src/mock.rs index 8db140d90c..c805b793bc 100644 --- a/frame/generic-asset/src/mock.rs +++ b/frame/generic-asset/src/mock.rs @@ -127,16 +127,17 @@ impl ExtBuilder { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig:: { - assets: vec![self.asset_id], - endowed_accounts: self.accounts, - initial_balance: self.initial_balance, - next_asset_id: self.next_asset_id, - staking_asset_id: 16000, - spending_asset_id: 16001, - } - .assimilate_storage(&mut t).unwrap(); - - t.into() + assets: vec![self.asset_id], + endowed_accounts: self.accounts, + initial_balance: self.initial_balance, + next_asset_id: self.next_asset_id, + staking_asset_id: 16000, + spending_asset_id: 16001, + }.assimilate_storage(&mut t).unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext } } diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 1fd1bcbdfe..3dc0543d88 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -175,7 +175,7 @@ pub type System = frame_system::Module; pub type Session = pallet_session::Module; pub fn advance_session() { - let now = System::block_number(); + let now = System::block_number().max(1); System::set_block_number(now + 1); Session::rotate_session(); assert_eq!(Session::current_index(), (now / Period::get()) as u32); diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index 7ddbc6726d..e464200396 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -128,7 +128,9 @@ impl_outer_event! { pub fn new_test_ext() -> sp_io::TestExternalities { let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - t.into() + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext } /// Offences module. diff --git a/frame/recovery/src/tests.rs b/frame/recovery/src/tests.rs index 9c644291c9..fb993043a5 100644 --- a/frame/recovery/src/tests.rs +++ b/frame/recovery/src/tests.rs @@ -240,7 +240,7 @@ fn initiate_recovery_works() { assert_eq!(Balances::reserved_balance(1), 10); // Recovery status object is created correctly let recovery_status = ActiveRecovery { - created: 1, + created: 0, deposit: 10, friends: vec![], }; @@ -288,7 +288,7 @@ fn vouch_recovery_works() { assert_ok!(Recovery::vouch_recovery(Origin::signed(3), 5, 1)); // Final recovery status object is updated correctly let recovery_status = ActiveRecovery { - created: 1, + created: 0, deposit: 10, friends: vec![2, 3, 4], }; diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index d8d9a55032..b90064ae47 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -489,6 +489,7 @@ impl ExtBuilder { // This must be ensured by having `timestamp::on_initialize` called before // `staking::on_initialize` ext.execute_with(|| { + System::set_block_number(1); Timestamp::set_timestamp(INIT_TIMESTAMP); }); diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index abd3c00ae8..01334b918f 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -1706,7 +1706,6 @@ fn new_era_elects_correct_number_of_validators() { assert_eq!(Staking::validator_count(), 1); assert_eq!(validator_controllers().len(), 1); - System::set_block_number(1); Session::on_initialize(System::block_number()); assert_eq!(validator_controllers().len(), 1); diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 92948544ce..2d965b44f0 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -366,7 +366,7 @@ decl_storage! { ExtrinsicData get(fn extrinsic_data): map hasher(twox_64_concat) u32 => Vec; /// The current block number being processed. Set by `execute_block`. - Number get(fn block_number) build(|_| 1.into()): T::BlockNumber; + Number get(fn block_number): T::BlockNumber; /// Hash of the previous block. ParentHash get(fn parent_hash) build(|_| hash69()): T::Hash; @@ -749,6 +749,10 @@ impl Module { /// This will update storage entries that correspond to the specified topics. /// It is expected that light-clients could subscribe to this topics. pub fn deposit_event_indexed(topics: &[T::Hash], event: T::Event) { + let block_number = Self::block_number(); + // Don't populate events on genesis. + if block_number.is_zero() { return } + let phase = ExecutionPhase::get().unwrap_or_default(); let event = EventRecord { phase, @@ -781,10 +785,9 @@ impl Module { return; } - let block_no = Self::block_number(); for topic in topics { // The same applies here. - if >::append(topic, &[(block_no, event_idx)]).is_err() { + if >::append(topic, &[(block_number, event_idx)]).is_err() { return; } } @@ -2041,6 +2044,7 @@ mod tests { let mut ext = new_test_ext(); ext.register_extension(sp_core::traits::CallInWasmExt::new(executor)); ext.execute_with(|| { + System::set_block_number(1); System::set_code( RawOrigin::Root.into(), substrate_test_runtime_client::runtime::WASM_BINARY.to_vec(), @@ -2068,4 +2072,18 @@ mod tests { ).unwrap(); }); } + + #[test] + fn events_not_emitted_during_genesis() { + new_test_ext().execute_with(|| { + // Block Number is zero at genesis + assert!(System::block_number().is_zero()); + System::on_created_account(Default::default()); + assert!(System::events().is_empty()); + // Events will be emitted starting on block 1 + System::set_block_number(1); + System::on_created_account(Default::default()); + assert!(System::events().len() == 1); + }); + } } diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 0b60532c3d..2f7b11bdaa 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -661,7 +661,9 @@ mod tests { pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 10)], }.assimilate_storage(&mut t).unwrap(); - t.into() + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext } fn last_event() -> TestEvent { diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index 3f7cdf3170..b7ff091d32 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -452,7 +452,9 @@ mod tests { (12, 10, 20, 5 * self.existential_deposit) ], }.assimilate_storage(&mut t).unwrap(); - t.into() + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext } } @@ -462,7 +464,6 @@ mod tests { .existential_deposit(256) .build() .execute_with(|| { - assert_eq!(System::block_number(), 1); let user1_free_balance = Balances::free_balance(&1); let user2_free_balance = Balances::free_balance(&2); let user12_free_balance = Balances::free_balance(&12); @@ -521,7 +522,6 @@ mod tests { .existential_deposit(10) .build() .execute_with(|| { - assert_eq!(System::block_number(), 1); let user1_free_balance = Balances::free_balance(&1); assert_eq!(user1_free_balance, 100); // Account 1 has free balance // Account 1 has only 5 units vested at block 1 (plus 50 unvested) @@ -539,7 +539,6 @@ mod tests { .existential_deposit(10) .build() .execute_with(|| { - assert_eq!(System::block_number(), 1); let user1_free_balance = Balances::free_balance(&1); assert_eq!(user1_free_balance, 100); // Account 1 has free balance // Account 1 has only 5 units vested at block 1 (plus 50 unvested) @@ -555,7 +554,6 @@ mod tests { .existential_deposit(10) .build() .execute_with(|| { - assert_eq!(System::block_number(), 1); let user1_free_balance = Balances::free_balance(&1); assert_eq!(user1_free_balance, 100); // Account 1 has free balance // Account 1 has only 5 units vested at block 1 (plus 50 unvested) @@ -571,7 +569,6 @@ mod tests { .existential_deposit(10) .build() .execute_with(|| { - assert_eq!(System::block_number(), 1); assert_ok!(Balances::transfer(Some(3).into(), 1, 100)); assert_ok!(Balances::transfer(Some(3).into(), 2, 100)); @@ -599,7 +596,6 @@ mod tests { .existential_deposit(256) .build() .execute_with(|| { - assert_eq!(System::block_number(), 1); let user12_free_balance = Balances::free_balance(&12); assert_eq!(user12_free_balance, 2560); // Account 12 has free balance @@ -625,7 +621,6 @@ mod tests { .existential_deposit(256) .build() .execute_with(|| { - assert_eq!(System::block_number(), 1); let user3_free_balance = Balances::free_balance(&3); let user4_free_balance = Balances::free_balance(&4); assert_eq!(user3_free_balance, 256 * 30); @@ -669,7 +664,6 @@ mod tests { .existential_deposit(256) .build() .execute_with(|| { - assert_eq!(System::block_number(), 1); let user2_free_balance = Balances::free_balance(&2); let user4_free_balance = Balances::free_balance(&4); assert_eq!(user2_free_balance, 256 * 20); -- GitLab From 8688898455ed0ce9d27c848937e925a74dc368ea Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 31 Mar 2020 18:41:55 +0200 Subject: [PATCH 118/300] safe slice operation (#5471) --- frame/support/src/hash.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frame/support/src/hash.rs b/frame/support/src/hash.rs index f8d6409060..693e929a30 100644 --- a/frame/support/src/hash.rs +++ b/frame/support/src/hash.rs @@ -92,6 +92,10 @@ impl StorageHasher for Twox64Concat { } impl ReversibleStorageHasher for Twox64Concat { fn reverse(x: &[u8]) -> &[u8] { + if x.len() < 8 { + crate::debug::error!("Invalid reverse: hash length too short"); + return &[] + } &x[8..] } } @@ -110,6 +114,10 @@ impl StorageHasher for Blake2_128Concat { } impl ReversibleStorageHasher for Blake2_128Concat { fn reverse(x: &[u8]) -> &[u8] { + if x.len() < 16 { + crate::debug::error!("Invalid reverse: hash length too short"); + return &[] + } &x[16..] } } -- GitLab From fe1c78985bc59152bbf8ae36201b43939e2f8cce Mon Sep 17 00:00:00 2001 From: gabriel klawitter Date: Tue, 31 Mar 2020 23:03:35 +0530 Subject: [PATCH 119/300] ci: check_polkadot_companion_status: don't verify mergeable_state (#5473) --- .maintain/gitlab/check_polkadot_companion_status.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.maintain/gitlab/check_polkadot_companion_status.sh b/.maintain/gitlab/check_polkadot_companion_status.sh index e98a657460..b54f457dc5 100755 --- a/.maintain/gitlab/check_polkadot_companion_status.sh +++ b/.maintain/gitlab/check_polkadot_companion_status.sh @@ -76,11 +76,11 @@ then exit 0 fi -if jq -e '.mergeable and .mergeable_state == "clean"' < companion_pr.json >/dev/null +if jq -e '.mergeable' < companion_pr.json >/dev/null then boldprint "polkadot pr #${pr_companion} mergeable" else - boldprint "polkadot pr #${pr_companion} not mergeable or clean" + boldprint "polkadot pr #${pr_companion} not mergeable" exit 1 fi -- GitLab From f110871727528d102a2041c277839e0d971155d7 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 31 Mar 2020 12:16:41 -0600 Subject: [PATCH 120/300] Add deposit/withdraw events to EVM module (#5440) * Add deposit/withdraw events * Remove balances trait --- frame/evm/src/backend.rs | 2 +- frame/evm/src/lib.rs | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/frame/evm/src/backend.rs b/frame/evm/src/backend.rs index e0cb816c60..c610f24bb1 100644 --- a/frame/evm/src/backend.rs +++ b/frame/evm/src/backend.rs @@ -172,7 +172,7 @@ impl<'vicinity, T: Trait> ApplyBackend for Backend<'vicinity, T> { } for log in logs { - Module::::deposit_event(Event::Log(Log { + Module::::deposit_event(Event::::Log(Log { address: log.address, topics: log.topics, data: log.data, diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index efb4c3c4f9..a50c545a46 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -127,7 +127,7 @@ pub trait Trait: frame_system::Trait + pallet_timestamp::Trait { /// Currency type for deposit and withdraw. type Currency: Currency; /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From> + Into<::Event>; /// Precompiles associated with this EVM engine. type Precompiles: Precompiles; @@ -147,11 +147,17 @@ decl_storage! { decl_event! { /// EVM events - pub enum Event { + pub enum Event where + ::AccountId, + { /// Ethereum events from contracts. Log(Log), /// A contract has been created at given address. Created(H160), + /// A deposit has been made at a given address. + BalanceDeposit(AccountId, H160, U256), + /// A withdrawal has been made from a given address. + BalanceWithdraw(AccountId, H160, U256), } } @@ -202,6 +208,7 @@ decl_module! { Accounts::mutate(&address, |account| { account.balance += bvalue; }); + Module::::deposit_event(Event::::BalanceDeposit(sender, address, bvalue)); } /// Withdraw balance from EVM into currency/balances module. @@ -225,6 +232,7 @@ decl_module! { Accounts::insert(&address, account); T::Currency::resolve_creating(&sender, imbalance); + Module::::deposit_event(Event::::BalanceWithdraw(sender, address, bvalue)); } /// Issue an EVM call operation. This is similar to a message call transaction in Ethereum. @@ -289,7 +297,7 @@ decl_module! { }, )?; - Module::::deposit_event(Event::Created(create_address)); + Module::::deposit_event(Event::::Created(create_address)); Ok(()) } @@ -327,7 +335,7 @@ decl_module! { }, )?; - Module::::deposit_event(Event::Created(create_address)); + Module::::deposit_event(Event::::Created(create_address)); Ok(()) } } -- GitLab From dca30b25c94462a1021b2a7333cdf3de066a1737 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 31 Mar 2020 20:16:56 +0200 Subject: [PATCH 121/300] Increase limit on light client response size (#5461) * Increase limit on light client response size * Address review --- .../src/protocol/light_client_handler.rs | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/client/network/src/protocol/light_client_handler.rs b/client/network/src/protocol/light_client_handler.rs index c96c5d0818..4c228205d3 100644 --- a/client/network/src/protocol/light_client_handler.rs +++ b/client/network/src/protocol/light_client_handler.rs @@ -77,7 +77,8 @@ use wasm_timer::Instant; /// Configuration options for `LightClientHandler` behaviour. #[derive(Debug, Clone)] pub struct Config { - max_data_size: usize, + max_request_size: usize, + max_response_size: usize, max_pending_requests: usize, inactivity_timeout: Duration, request_timeout: Duration, @@ -87,13 +88,15 @@ pub struct Config { impl Config { /// Create a fresh configuration with the following options: /// - /// - max. data size = 1 MiB + /// - max. request size = 1 MiB + /// - max. response size = 16 MiB /// - max. pending requests = 128 /// - inactivity timeout = 15s /// - request timeout = 15s pub fn new(id: &ProtocolId) -> Self { let mut c = Config { - max_data_size: 1024 * 1024, + max_request_size: 1 * 1024 * 1024, + max_response_size: 16 * 1024 * 1024, max_pending_requests: 128, inactivity_timeout: Duration::from_secs(15), request_timeout: Duration::from_secs(15), @@ -103,9 +106,15 @@ impl Config { c } - /// Limit the max. length of incoming request bytes. - pub fn set_max_data_size(&mut self, v: usize) -> &mut Self { - self.max_data_size = v; + /// Limit the max. length in bytes of a request. + pub fn set_max_request_size(&mut self, v: usize) -> &mut Self { + self.max_request_size = v; + self + } + + /// Limit the max. length in bytes of a response. + pub fn set_max_response_size(&mut self, v: usize) -> &mut Self { + self.max_response_size = v; self } @@ -654,7 +663,7 @@ where fn new_handler(&mut self) -> Self::ProtocolsHandler { let p = InboundProtocol { - max_data_size: self.config.max_data_size, + max_request_size: self.config.max_request_size, protocol: self.config.protocol.clone(), }; OneShotHandler::new(SubstreamProtocol::new(p), self.config.inactivity_timeout) @@ -841,7 +850,7 @@ where let protocol = OutboundProtocol { request: buf, request_id: id, - max_data_size: self.config.max_data_size, + max_response_size: self.config.max_response_size, protocol: self.config.protocol.clone(), }; self.peers.get_mut(&peer).map(|info| info.status = PeerStatus::BusyWith(id)); @@ -1008,7 +1017,7 @@ pub enum Event { #[derive(Debug, Clone)] pub struct InboundProtocol { /// The max. request length in bytes. - max_data_size: usize, + max_request_size: usize, /// The protocol to use for upgrade negotiation. protocol: Bytes, } @@ -1032,7 +1041,7 @@ where fn upgrade_inbound(self, mut s: T, _: Self::Info) -> Self::Future { let future = async move { - let vec = read_one(&mut s, self.max_data_size).await?; + let vec = read_one(&mut s, self.max_request_size).await?; match api::v1::light::Request::decode(&vec[..]) { Ok(r) => Ok(Event::Request(r, s)), Err(e) => Err(ReadOneError::Io(io::Error::new(io::ErrorKind::Other, e))) @@ -1051,8 +1060,8 @@ pub struct OutboundProtocol { request: Vec, /// Local identifier for the request. Used to associate it with a response. request_id: u64, - /// The max. request length in bytes. - max_data_size: usize, + /// The max. response length in bytes. + max_response_size: usize, /// The protocol to use for upgrade negotiation. protocol: Bytes, } @@ -1077,7 +1086,7 @@ where fn upgrade_outbound(self, mut s: T, _: Self::Info) -> Self::Future { let future = async move { write_one(&mut s, &self.request).await?; - let vec = read_one(&mut s, self.max_data_size).await?; + let vec = read_one(&mut s, self.max_response_size).await?; api::v1::light::Response::decode(&vec[..]) .map(|r| Event::Response(self.request_id, r)) .map_err(|e| { -- GitLab From 95c4e64ab1fed30044a14da41625bac797d4e02b Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 31 Mar 2020 20:17:14 +0200 Subject: [PATCH 122/300] client/finality-grandpa: Instrument until-imported queue (#5438) * client/finality-grandpa: Instrument until-imported queue The `UntilImported` queue takes as input finality grandpa messages that depend on blocks that are not yet imported and holds them back until those blocks are imported. This commit adds a basic metric, the amount of messages waiting in the queue, to the module. For now this metric is only available for the global `UntilImported` queue awaiting blocks for commit and catch-up messages. * client/finality-grandpa/src/until_imported: Update metric help text Co-Authored-By: Ashley Co-authored-by: Ashley --- client/finality-grandpa/src/environment.rs | 1 + client/finality-grandpa/src/lib.rs | 37 ++++++- client/finality-grandpa/src/observer.rs | 1 + client/finality-grandpa/src/until_imported.rs | 102 +++++++++++++++++- 4 files changed, 134 insertions(+), 7 deletions(-) diff --git a/client/finality-grandpa/src/environment.rs b/client/finality-grandpa/src/environment.rs index eb80ad30ac..dec9492482 100644 --- a/client/finality-grandpa/src/environment.rs +++ b/client/finality-grandpa/src/environment.rs @@ -636,6 +636,7 @@ where self.client.clone(), incoming, "round", + None, ).map_err(Into::into)); // schedule network message cleanup when sink drops. diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index 967584fa9b..d8e5846a56 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -63,6 +63,7 @@ use sc_client_api::{ }; use sp_blockchain::{HeaderBackend, Error as ClientError, HeaderMetadata}; use parity_scale_codec::{Decode, Encode}; +use prometheus_endpoint::{PrometheusError, Registry}; use sp_runtime::generic::BlockId; use sp_runtime::traits::{NumberFor, Block as BlockT, DigestFor, Zero}; use sc_keystore::KeyStorePtr; @@ -104,7 +105,7 @@ pub use voting_rule::{ }; use aux_schema::PersistentData; -use environment::{Environment, VoterSetState, Metrics}; +use environment::{Environment, VoterSetState}; use import::GrandpaBlockImport; use until_imported::UntilGlobalMessageBlocksImported; use communication::{NetworkBridge, Network as NetworkT}; @@ -519,6 +520,7 @@ fn global_communication( client: Arc, network: &NetworkBridge, keystore: &Option, + metrics: Option, ) -> ( impl Stream< Item = Result, CommandOrError>>, @@ -549,6 +551,7 @@ fn global_communication( client.clone(), global_in, "global", + metrics, ); let global_in = global_in.map_err(CommandOrError::from); @@ -696,6 +699,20 @@ pub fn run_grandpa_voter( Ok(future::select(voter_work, telemetry_task).map(drop)) } +struct Metrics { + environment: environment::Metrics, + until_imported: until_imported::Metrics, +} + +impl Metrics { + fn register(registry: &Registry) -> Result { + Ok(Metrics { + environment: environment::Metrics::register(registry)?, + until_imported: until_imported::Metrics::register(registry)?, + }) + } +} + /// Future that powers the voter. #[must_use] struct VoterWork, SC, VR> { @@ -703,6 +720,9 @@ struct VoterWork, SC, VR> { env: Arc>, voter_commands_rx: mpsc::UnboundedReceiver>>, network: NetworkBridge, + + /// Prometheus metrics. + metrics: Option, } impl VoterWork @@ -725,6 +745,14 @@ where voter_commands_rx: mpsc::UnboundedReceiver>>, prometheus_registry: Option, ) -> Self { + let metrics = match prometheus_registry.as_ref().map(Metrics::register) { + Some(Ok(metrics)) => Some(metrics), + Some(Err(e)) => { + debug!(target: "afg", "Failed to register metrics: {:?}", e); + None + } + None => None, + }; let voters = persistent_data.authority_set.current_authorities(); let env = Arc::new(Environment { @@ -738,10 +766,7 @@ where authority_set: persistent_data.authority_set.clone(), consensus_changes: persistent_data.consensus_changes.clone(), voter_set_state: persistent_data.set_state.clone(), - metrics: prometheus_registry.map(|registry| { - Metrics::register(®istry) - .expect("Other metrics would have failed to register before these; qed") - }), + metrics: metrics.as_ref().map(|m| m.environment.clone()), _phantom: PhantomData, }); @@ -752,6 +777,7 @@ where env, voter_commands_rx, network, + metrics, }; work.rebuild_voter(); work @@ -800,6 +826,7 @@ where self.env.client.clone(), &self.env.network, &self.env.config.keystore, + self.metrics.as_ref().map(|m| m.until_imported.clone()), ); let last_completed_round = completed_rounds.last(); diff --git a/client/finality-grandpa/src/observer.rs b/client/finality-grandpa/src/observer.rs index 07eaf1db9f..2382c6e249 100644 --- a/client/finality-grandpa/src/observer.rs +++ b/client/finality-grandpa/src/observer.rs @@ -255,6 +255,7 @@ where self.client.clone(), &self.network, &self.keystore, + None, ); let last_finalized_number = self.client.info().finalized_number; diff --git a/client/finality-grandpa/src/until_imported.rs b/client/finality-grandpa/src/until_imported.rs index 223078ec92..95bcceaded 100644 --- a/client/finality-grandpa/src/until_imported.rs +++ b/client/finality-grandpa/src/until_imported.rs @@ -29,13 +29,17 @@ use super::{ }; use log::{debug, warn}; -use sc_client_api::{BlockImportNotification, ImportNotifications}; use futures::prelude::*; use futures::stream::Fuse; use futures_timer::Delay; use futures::channel::mpsc::UnboundedReceiver; use finality_grandpa::voter; use parking_lot::Mutex; +use prometheus_endpoint::{ + Gauge, U64, PrometheusError, register, Registry, +}; +use sc_client_api::{BlockImportNotification, ImportNotifications}; +use sp_finality_grandpa::AuthorityId; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use std::collections::{HashMap, VecDeque}; @@ -43,7 +47,6 @@ use std::pin::Pin; use std::sync::Arc; use std::task::{Context, Poll}; use std::time::{Duration, Instant}; -use sp_finality_grandpa::AuthorityId; const LOG_PENDING_INTERVAL: Duration = Duration::from_secs(15); @@ -77,6 +80,63 @@ pub(crate) enum DiscardWaitOrReady { Ready(R), } +/// Prometheus metrics for the `UntilImported` queue. +// +// At a given point in time there can be more than one `UntilImported` queue. One can not register a +// metric twice, thus queues need to share the same Prometheus metrics instead of instantiating +// their own ones. +// +// When a queue is dropped it might still contain messages. In order for those to not distort the +// Prometheus metrics, the `Metric` struct cleans up after itself within its `Drop` implementation +// by subtracting the local_waiting_messages (the amount of messages left in the queue about to +// be dropped) from the global_waiting_messages gauge. +pub(crate) struct Metrics { + global_waiting_messages: Gauge, + local_waiting_messages: u64, +} + +impl Metrics { + pub(crate) fn register(registry: &Registry) -> Result { + Ok(Self { + global_waiting_messages: register(Gauge::new( + "finality_grandpa_until_imported_waiting_messages_number", + "Number of finality grandpa messages waiting within the until imported queue.", + )?, registry)?, + local_waiting_messages: 0, + }) + } + + fn waiting_messages_inc(&mut self) { + self.local_waiting_messages += 1; + self.global_waiting_messages.inc(); + } + + fn waiting_messages_dec(&mut self) { + self.local_waiting_messages -= 1; + self.global_waiting_messages.dec(); + } +} + + +impl Clone for Metrics { + fn clone(&self) -> Self { + Metrics { + global_waiting_messages: self.global_waiting_messages.clone(), + // When cloned, reset local_waiting_messages, so the global counter is not reduced a + // second time for the same messages on `drop` of the clone. + local_waiting_messages: 0, + } + } +} + +impl Drop for Metrics { + fn drop(&mut self) { + // Reduce the global counter by the amount of messages that were still left in the dropped + // queue. + self.global_waiting_messages.sub(self.local_waiting_messages) + } +} + /// Buffering imported messages until blocks with given hashes are imported. #[pin_project::pin_project] pub(crate) struct UntilImported> { @@ -86,12 +146,17 @@ pub(crate) struct UntilImported, ready: VecDeque, + /// Interval at which to check status of each awaited block. check_pending: Pin> + Send>>, /// Mapping block hashes to their block number, the point in time it was /// first encountered (Instant) and a list of GRANDPA messages referencing /// the block hash. pending: HashMap, Instant, Vec)>, + + /// Queue identifier for differentiation in logs. identifier: &'static str, + /// Prometheus metrics. + metrics: Option, } impl UntilImported where @@ -108,6 +173,7 @@ impl UntilImported, ) -> Self { // how often to check if pending messages that are waiting for blocks to be // imported can be checked. @@ -131,6 +197,7 @@ impl UntilImported Stream for UntilImported this.ready.push_back(item), } + + if let Some(metrics) = &mut this.metrics { + metrics.waiting_messages_inc(); + } } Poll::Pending => break, } @@ -238,6 +309,9 @@ impl Stream for UntilImported Date: Tue, 31 Mar 2020 20:54:57 +0200 Subject: [PATCH 123/300] Check that `PerThing` valid on decode (#5475) --- primitives/arithmetic/src/per_things.rs | 31 +++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index cbbeeae0cc..11f897fcc0 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -18,7 +18,7 @@ use serde::{Serialize, Deserialize}; use sp_std::{ops, fmt, prelude::*, convert::TryInto}; -use codec::{Encode, Decode, CompactAs}; +use codec::{Encode, CompactAs}; use crate::traits::{ SaturatedConversion, UniqueSaturatedInto, Saturating, BaseArithmetic, Bounded, Zero, }; @@ -311,7 +311,7 @@ macro_rules! implement_per_thing { /// #[doc = $title] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] - #[derive(Encode, Decode, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, + #[derive(Encode, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, CompactAs)] pub struct $name($type); @@ -534,6 +534,18 @@ macro_rules! implement_per_thing { } } + impl codec::Decode for $name { + fn decode(input: &mut I) -> Result { + let inner = <$type as codec::Decode>::decode(input)?; + + if inner <= ::ACCURACY { + Ok(Self(inner)) + } else { + Err("Value is greater than allowed maximum!".into()) + } + } + } + impl crate::traits::Bounded for $name { fn min_value() -> Self { ::zero() @@ -629,6 +641,21 @@ macro_rules! implement_per_thing { } } + #[test] + fn fail_on_invalid_encoded_value() { + let value = <$upper_type>::from($max) * 2; + let casted = value as $type; + let encoded = casted.encode(); + + // For types where `$max == $type::maximum()` we can not + if <$upper_type>::from(casted) == value { + assert_eq!( + $name::decode(&mut &encoded[..]), + Err("Value is greater than allowed maximum!".into()), + ); + } + } + #[test] fn per_thing_api_works() { // some really basic stuff -- GitLab From 9b4909269f3039f981247dfa0f5b6ec3133288e7 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Tue, 31 Mar 2020 22:40:28 +0200 Subject: [PATCH 124/300] Fix Collective <-> Elections initialization. (#5454) * A patch * Fix * Better approach. * Fix grumbles --- Cargo.lock | 109 +++++++++++------------- bin/node/cli/src/chain_spec.rs | 12 +-- bin/node/runtime/src/lib.rs | 5 +- bin/node/testing/src/genesis.rs | 1 + frame/elections-phragmen/Cargo.toml | 3 +- frame/elections-phragmen/src/lib.rs | 92 ++++++++++++++++++-- primitives/arithmetic/src/per_things.rs | 2 +- 7 files changed, 149 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 94d1267c72..c2a31d5b08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,9 +99,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "013a6e0a2cbe3d20f9c60b65458f7a7f7a5e636c5d0f45a5a6aee5d4b1f01785" +checksum = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff" [[package]] name = "app_dirs" @@ -178,12 +178,11 @@ dependencies = [ [[package]] name = "assert_cmd" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36101401a715c232f2c63a534a4b639415064b79d128d2a60d35678f8fb45204" +checksum = "c88b9ca26f9c16ec830350d309397e74ee9abdfd8eb1f71cb6ecc71a3fc818da" dependencies = [ "doc-comment", - "escargot", "predicates", "predicates-core", "predicates-tree", @@ -1055,9 +1054,9 @@ checksum = "11c0346158a19b3627234e15596f5e465c360fcdb97d817bcb255e0510f5a788" [[package]] name = "derive_more" -version = "0.99.3" +version = "0.99.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a806e96c59a76a5ba6e18735b6cf833344671e61e7863f2edb5c518ea2cac95c" +checksum = "e2323f3f47db9a0e77ce7a300605d8d2098597fc451ed1a97bb1f6411bb550a7" dependencies = [ "proc-macro2", "quote", @@ -1189,18 +1188,18 @@ checksum = "516aa8d7a71cb00a1c4146f0798549b93d083d4f189b3ced8f3de6b8f11ee6c4" [[package]] name = "erased-serde" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7d80305c9bd8cd78e3c753eb9fb110f83621e5211f1a3afffcc812b104daf9" +checksum = "d88b6d1705e16a4d62e05ea61cc0496c2bd190f4fa8e5c1f11ce747be6bcf3d1" dependencies = [ "serde", ] [[package]] name = "errno" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" +checksum = "b480f641ccf0faf324e20c1d3e53d81b7484c698b42ea677f6907ae4db195371" dependencies = [ "errno-dragonfly", "libc", @@ -1217,18 +1216,6 @@ dependencies = [ "libc", ] -[[package]] -name = "escargot" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74cf96bec282dcdb07099f7e31d9fed323bca9435a09aba7b6d99b7617bca96d" -dependencies = [ - "lazy_static", - "log 0.4.8", - "serde", - "serde_json", -] - [[package]] name = "ethbloom" version = "0.9.0" @@ -1976,9 +1963,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7938e6aa2a31df4e21f224dc84704bd31c089a6d1355c535b03667371cccc843" +checksum = "377038bf3c89d18d6ca1431e7a5027194fbd724ca10592b9487ede5e8e144f42" dependencies = [ "bytes 0.5.4", "fnv", @@ -2029,9 +2016,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8" +checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e" dependencies = [ "libc", ] @@ -2211,7 +2198,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.2.3", + "h2 0.2.4", "http 0.2.1", "http-body 0.3.1", "httparse", @@ -3343,9 +3330,9 @@ checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" [[package]] name = "multimap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc" +checksum = "d8883adfde9756c1d30b0f519c9b8c502a94b41ac62f696453c37c7fc0a958ce" [[package]] name = "multistream-select" @@ -4861,9 +4848,9 @@ dependencies = [ [[package]] name = "paste" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8292c1e1e81ddb552c4c90c36af201a0ce7e34995f55f0480f01052f242811c9" +checksum = "092d791bf7847f70bbd49085489fba25fc2c193571752bff9e36e74e72403932" dependencies = [ "paste-impl", "proc-macro-hack", @@ -4871,9 +4858,9 @@ dependencies = [ [[package]] name = "paste-impl" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9c43f2645f06ee452544ad032886a75f3d1797b9487dcadcae9100ba58a51c" +checksum = "406c23fb4c45cc6f68a9bbabb8ec7bd6f8cfcbd17e9e8f72c2460282f8325729" dependencies = [ "proc-macro-hack", "proc-macro2", @@ -5087,9 +5074,9 @@ checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" [[package]] name = "proc-macro2" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" +checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" dependencies = [ "unicode-xid", ] @@ -5161,9 +5148,9 @@ dependencies = [ [[package]] name = "protobuf" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1b4a8efc42cf150049e8a490f618c7c60e82332405065f202a7e33aa5a1f06" +checksum = "71964f34fd51cf04882d7ae3325fa0794d4cad66a03d0003f38d8ae4f63ba126" [[package]] name = "pwasm-utils" @@ -5531,9 +5518,9 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.11" +version = "0.16.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "741ba1704ae21999c00942f9f5944f801e977f54302af346b596287599ad1862" +checksum = "1ba5a8ec64ee89a76c98c549af81ff14813df09c3e6dc4766c3856da48597a0c" dependencies = [ "cc", "lazy_static", @@ -6793,21 +6780,22 @@ dependencies = [ [[package]] name = "security-framework" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97bbedbe81904398b6ebb054b3e912f99d55807125790f3198ac990d98def5b0" +checksum = "572dfa3a0785509e7a44b5b4bebcf94d41ba34e9ed9eb9df722545c3b3c4144a" dependencies = [ "bitflags", "core-foundation", "core-foundation-sys", + "libc", "security-framework-sys", ] [[package]] name = "security-framework-sys" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06fd2f23e31ef68dd2328cc383bd493142e46107a3a0e24f7d734e3f3b80fe4c" +checksum = "8ddb15a5fec93b7021b8a9e96009c5d8d51c15673569f7c0f6b7204e5b7b404f" dependencies = [ "core-foundation-sys", "libc", @@ -6878,9 +6866,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25" +checksum = "78a7a12c167809363ec3bd7329fc0a3369056996de43c4b37ef3cd54a6ce4867" dependencies = [ "itoa", "ryu", @@ -8228,18 +8216,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3711fd1c4e75b3eff12ba5c40dba762b6b65c5476e8174c1a664772060c49bf" +checksum = "f0570dc61221295909abdb95c739f2e74325e14293b2026b0a7e195091ec54ae" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae2b85ba4c9aa32dd3343bd80eb8d22e9b54b7688c17ea3907f236885353b233" +checksum = "227362df41d566be41a28f64401e07a043157c21c14b9785a0d8e256f940a8fd" dependencies = [ "proc-macro2", "quote", @@ -8277,9 +8265,9 @@ dependencies = [ [[package]] name = "tiny-bip39" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e255ec4f7d4aaccbede17dffcfb2e71434d17f5c921d5a06823b8e58a2bcd468" +checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" dependencies = [ "failure", "hmac", @@ -8351,6 +8339,7 @@ checksum = "0fa5e81d6bc4e67fe889d5783bd2a128ab2e0cfa487e0be16b6a8d177b101616" dependencies = [ "bytes 0.5.4", "fnv", + "futures-core", "iovec", "lazy_static", "libc", @@ -8592,9 +8581,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" +checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" dependencies = [ "bytes 0.5.4", "futures-core", @@ -9169,18 +9158,18 @@ dependencies = [ [[package]] name = "wast" -version = "11.0.0" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df4d67ba9266f4fcaf2e8a1afadc5e2a959e51aecc07b1ecbdf85a6ddaf08bde" +checksum = "0615ba420811bcda39cf80e8a1bd75997aec09222bda35165920a07ef15cc695" dependencies = [ "leb128", ] [[package]] name = "wat" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9400dc1c8512087b2d974b1b9b0a6c4e6e26e7e8acf629e3e351165a1ed301" +checksum = "095f615fbfcae695e3a4cea7d9f02f70561c81274c0142f45a12bf1e154d08bd" dependencies = [ "wast", ] @@ -9303,9 +9292,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" +checksum = "fa515c5163a99cc82bab70fd3bfdd36d827be85de63737b40fcef2ce084a436e" dependencies = [ "winapi 0.3.8", ] diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index 45cb01b0ba..700556206d 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -20,9 +20,10 @@ use sc_chain_spec::ChainSpecExtension; use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519}; use serde::{Serialize, Deserialize}; use node_runtime::{ - AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig, - GrandpaConfig, ImOnlineConfig, SessionConfig, SessionKeys, StakerStatus, StakingConfig, - IndicesConfig, SocietyConfig, SudoConfig, SystemConfig, TechnicalCommitteeConfig, WASM_BINARY, + AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, + DemocracyConfig,GrandpaConfig, ImOnlineConfig, SessionConfig, SessionKeys, StakerStatus, + StakingConfig, ElectionsConfig, IndicesConfig, SocietyConfig, SudoConfig, SystemConfig, + TechnicalCommitteeConfig, WASM_BINARY, }; use node_runtime::Block; use node_runtime::constants::currency::*; @@ -270,13 +271,14 @@ pub fn testnet_genesis( .. Default::default() }), pallet_democracy: Some(DemocracyConfig::default()), - pallet_collective_Instance1: Some(CouncilConfig { + pallet_elections_phragmen: Some(ElectionsConfig { members: endowed_accounts.iter() .take((num_endowed_accounts + 1) / 2) .cloned() + .map(|member| (member, STASH)) .collect(), - phantom: Default::default(), }), + pallet_collective_Instance1: Some(CouncilConfig::default()), pallet_collective_Instance2: Some(TechnicalCommitteeConfig { members: endowed_accounts.iter() .take((num_endowed_accounts + 1) / 2) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 799fc5397c..8f33752ffc 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -418,6 +418,9 @@ impl pallet_elections_phragmen::Trait for Runtime { type Event = Event; type Currency = Balances; type ChangeMembers = Council; + // NOTE: this implies that council's genesis members cannot be set directly and must come from + // this module. + type InitializeMembers = Council; type CurrencyToVote = CurrencyToVoteHandler; type CandidacyBond = CandidacyBond; type VotingBond = VotingBond; @@ -652,7 +655,7 @@ construct_runtime!( Democracy: pallet_democracy::{Module, Call, Storage, Config, Event}, Council: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, TechnicalCommittee: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, - Elections: pallet_elections_phragmen::{Module, Call, Storage, Event}, + Elections: pallet_elections_phragmen::{Module, Call, Storage, Event, Config}, TechnicalMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, FinalityTracker: pallet_finality_tracker::{Module, Call, Inherent}, Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event}, diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index e35059e0c6..8a57010770 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -109,6 +109,7 @@ pub fn config_endowed( pallet_collective_Instance1: Some(Default::default()), pallet_collective_Instance2: Some(Default::default()), pallet_membership_Instance1: Some(Default::default()), + pallet_elections_phragmen: Some(Default::default()), pallet_sudo: Some(Default::default()), pallet_treasury: Some(Default::default()), pallet_society: Some(SocietyConfig { diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index 3cada4dcd3..1fbfbc20ce 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -10,6 +10,7 @@ description = "FRAME election pallet for PHRAGMEN" [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.101", optional = true } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } sp-phragmen = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/phragmen" } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } @@ -22,11 +23,11 @@ hex-literal = "0.2.1" pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } substrate-test-utils = { version = "2.0.0-alpha.5", path = "../../test-utils" } -serde = { version = "1.0.101" } [features] default = ["std"] std = [ + "serde", "codec/std", "frame-support/std", "sp-runtime/std", diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 12307fe712..28fc66bef9 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -91,7 +91,7 @@ use frame_support::{ weights::{SimpleDispatchInfo, Weight, WeighData}, storage::{StorageMap, IterableStorageMap}, traits::{ Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons, - ChangeMembers, OnUnbalanced, WithdrawReason, Contains, BalanceStatus + ChangeMembers, OnUnbalanced, WithdrawReason, Contains, BalanceStatus, InitializeMembers, } }; use sp_phragmen::{build_support_map, ExtendedBalance}; @@ -118,6 +118,9 @@ pub trait Trait: frame_system::Trait { /// What to do when the members change. type ChangeMembers: ChangeMembers; + /// What to do with genesis members + type InitializeMembers: InitializeMembers; + /// Convert a balance into a number used for election calculation. /// This must fit into a `u64` but is allowed to be sensibly lossy. type CurrencyToVote: Convert, u64> + Convert>; @@ -160,11 +163,44 @@ decl_storage! { pub ElectionRounds get(fn election_rounds): u32 = Zero::zero(); /// Votes and locked stake of a particular voter. - pub Voting: map hasher(twox_64_concat) T::AccountId => (BalanceOf, Vec); + pub Voting get(fn voting): map hasher(twox_64_concat) T::AccountId => (BalanceOf, Vec); /// The present candidate list. Sorted based on account-id. A current member or runner-up /// can never enter this vector and is always implicitly assumed to be a candidate. pub Candidates get(fn candidates): Vec; + } add_extra_genesis { + config(members): Vec<(T::AccountId, BalanceOf)>; + build(|config: &GenesisConfig| { + let members = config.members.iter().map(|(ref member, ref stake)| { + // make sure they have enough stake + assert!( + T::Currency::free_balance(member) >= *stake, + "Genesis member does not have enough stake", + ); + + // reserve candidacy bond and set as members. + T::Currency::reserve(&member, T::CandidacyBond::get()) + .expect("Genesis member does not have enough balance to be a candidate"); + + // Note: all members will only vote for themselves, hence they must be given exactly + // their own stake as total backing. Any sane election should behave as such. + // Nonetheless, stakes will be updated for term 1 onwards according to the election. + >::append(&[(member.clone(), *stake)]) + .expect("Failed to append genesis members."); + + // set self-votes to make persistent. + >::vote( + T::Origin::from(Some(member.clone()).into()), + vec![member.clone()], + *stake, + ).expect("Genesis member could not vote."); + + member.clone() + }).collect::>(); + + // report genesis members to upstream, if any. + T::InitializeMembers::initialize_members(&members); + }) } } @@ -844,7 +880,7 @@ mod tests { Perbill, testing::Header, BuildStorage, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, }; - use crate as elections; + use crate as elections_phragmen; use frame_system as system; parameter_types! { @@ -980,6 +1016,7 @@ mod tests { type Currency = Balances; type CurrencyToVote = CurrencyToVoteHandler; type ChangeMembers = TestChangeMembers; + type InitializeMembers = (); type CandidacyBond = CandidacyBond; type VotingBond = VotingBond; type TermDuration = TermDuration; @@ -1001,11 +1038,12 @@ mod tests { { System: system::{Module, Call, Event}, Balances: pallet_balances::{Module, Call, Event, Config}, - Elections: elections::{Module, Call, Event}, + Elections: elections_phragmen::{Module, Call, Event, Config}, } ); pub struct ExtBuilder { + genesis_members: Vec<(u64, u64)>, balance_factor: u64, voter_bond: u64, term_duration: u64, @@ -1015,6 +1053,7 @@ mod tests { impl Default for ExtBuilder { fn default() -> Self { Self { + genesis_members: vec![], balance_factor: 1, voter_bond: 2, desired_runners_up: 0, @@ -1036,10 +1075,15 @@ mod tests { self.term_duration = duration; self } + pub fn genesis_members(mut self, members: Vec<(u64, u64)>) -> Self { + self.genesis_members = members; + self + } pub fn build(self) -> sp_io::TestExternalities { VOTING_BOND.with(|v| *v.borrow_mut() = self.voter_bond); TERM_DURATION.with(|v| *v.borrow_mut() = self.term_duration); DESIRED_RUNNERS_UP.with(|v| *v.borrow_mut() = self.desired_runners_up); + MEMBERS.with(|m| *m.borrow_mut() = self.genesis_members.iter().map(|(m, _)| m.clone()).collect::>()); let mut ext: sp_io::TestExternalities = GenesisConfig { pallet_balances: Some(pallet_balances::GenesisConfig::{ balances: vec![ @@ -1051,6 +1095,9 @@ mod tests { (6, 60 * self.balance_factor) ], }), + elections_phragmen: Some(elections_phragmen::GenesisConfig:: { + members: self.genesis_members + }), }.build_storage().unwrap().into(); ext.execute_with(|| System::set_block_number(1)); ext @@ -1090,6 +1137,37 @@ mod tests { }); } + #[test] + fn genesis_members_should_work() { + ExtBuilder::default().genesis_members(vec![(1, 10), (2, 20)]).build().execute_with(|| { + System::set_block_number(1); + assert_eq!(Elections::members(), vec![(1, 10), (2, 20)]); + + assert_eq!(Elections::voting(1), (10, vec![1])); + assert_eq!(Elections::voting(2), (20, vec![2])); + + // they will persist since they have self vote. + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members_ids(), vec![1, 2]); + }) + } + + #[test] + #[should_panic = "Genesis member does not have enough stake"] + fn genesis_members_cannot_over_stake_0() { + // 10 cannot lock 20 as their stake and extra genesis will panic. + ExtBuilder::default().genesis_members(vec![(1, 20), (2, 20)]).build(); + } + + #[test] + #[should_panic] + fn genesis_members_cannot_over_stake_1() { + // 10 cannot reserve 20 as voting bond and extra genesis will panic. + ExtBuilder::default().voter_bond(20).genesis_members(vec![(1, 10), (2, 20)]).build(); + } + #[test] fn term_duration_zero_is_passive() { ExtBuilder::default() @@ -1538,7 +1616,7 @@ mod tests { assert_ok!(Elections::report_defunct_voter(Origin::signed(5), 3)); assert!(System::events().iter().any(|event| { - event.event == Event::elections(RawEvent::VoterReported(3, 5, true)) + event.event == Event::elections_phragmen(RawEvent::VoterReported(3, 5, true)) })); assert_eq!(balances(&3), (28, 0)); @@ -1566,7 +1644,7 @@ mod tests { assert_ok!(Elections::report_defunct_voter(Origin::signed(5), 4)); assert!(System::events().iter().any(|event| { - event.event == Event::elections(RawEvent::VoterReported(4, 5, false)) + event.event == Event::elections_phragmen(RawEvent::VoterReported(4, 5, false)) })); assert_eq!(balances(&4), (35, 5)); @@ -1976,7 +2054,7 @@ mod tests { assert_eq!(balances(&5), (45, 2)); assert!(System::events().iter().any(|event| { - event.event == Event::elections(RawEvent::NewTerm(vec![(4, 40), (5, 50)])) + event.event == Event::elections_phragmen(RawEvent::NewTerm(vec![(4, 40), (5, 50)])) })); }) } diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index 11f897fcc0..ad529fbf32 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -201,7 +201,7 @@ pub trait PerThing: /// The rounding method to use. /// -/// `Perthing`s are unsigned so `Up` means towards infinity and `Down` means towards zero. +/// `PerThing`s are unsigned so `Up` means towards infinity and `Down` means towards zero. /// `Nearest` will round an exact half down. enum Rounding { Up, -- GitLab From 92b1be176f88498c487a4ea8fcd27362edac806e Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 31 Mar 2020 22:53:21 +0200 Subject: [PATCH 125/300] Benchmark Utility Pallet (#5384) * Move tests * Move around feature cfgs * Start benchmarks * as_multi bench * finish * fix tests * Update frame/utility/src/benchmarking.rs Co-Authored-By: Marcio Diaz * Update Cargo.toml * fix test Co-authored-by: Marcio Diaz --- Cargo.lock | 1 + bin/node/runtime/Cargo.toml | 10 +- bin/node/runtime/src/lib.rs | 7 +- frame/balances/src/benchmarking.rs | 2 + frame/balances/src/lib.rs | 8 +- frame/balances/src/tests.rs | 2 + frame/balances/src/tests_composite.rs | 2 + frame/balances/src/tests_local.rs | 2 + frame/benchmark/src/benchmarking.rs | 2 + frame/benchmark/src/lib.rs | 3 +- frame/identity/src/benchmarking.rs | 2 + frame/identity/src/lib.rs | 3 +- frame/timestamp/src/benchmarking.rs | 4 +- frame/timestamp/src/lib.rs | 1 - frame/treasury/src/benchmarking.rs | 2 + frame/treasury/src/lib.rs | 2 - frame/treasury/src/tests.rs | 20 ++ frame/utility/Cargo.toml | 6 + frame/utility/src/benchmarking.rs | 148 +++++++++ frame/utility/src/lib.rs | 430 +------------------------ frame/utility/src/tests.rs | 442 ++++++++++++++++++++++++++ frame/vesting/src/benchmarking.rs | 4 +- frame/vesting/src/lib.rs | 1 - 23 files changed, 653 insertions(+), 451 deletions(-) create mode 100644 frame/utility/src/benchmarking.rs create mode 100644 frame/utility/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index c2a31d5b08..7a85935e99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4658,6 +4658,7 @@ dependencies = [ name = "pallet-utility" version = "2.0.0-alpha.5" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", "pallet-balances", diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 0d61968591..07d3b8beda 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -138,18 +138,18 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-collective/runtime-benchmarks", + "pallet-democracy/runtime-benchmarks", "pallet-elections-phragmen/runtime-benchmarks", "pallet-identity/runtime-benchmarks", + "pallet-im-online/runtime-benchmarks", + "pallet-society/runtime-benchmarks", + "pallet-staking/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", - "pallet-staking/runtime-benchmarks", + "pallet-utility/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", "pallet-collective/runtime-benchmarks", "pallet-session-benchmarking", - "pallet-staking/runtime-benchmarks", - "pallet-society/runtime-benchmarks", - "pallet-im-online/runtime-benchmarks", - "pallet-democracy/runtime-benchmarks", ] [package.metadata.docs.rs] diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 8f33752ffc..881807ea24 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -878,15 +878,16 @@ impl_runtime_apis! { let mut batches = Vec::::new(); let params = (&pallet, &benchmark, &lowest_range_values, &highest_range_values, &steps, repeat); add_benchmark!(params, batches, b"balances", Balances); - add_benchmark!(params, batches, b"im-online", ImOnline); + add_benchmark!(params, batches, b"collective", Council); + add_benchmark!(params, batches, b"democracy", Democracy); add_benchmark!(params, batches, b"identity", Identity); + add_benchmark!(params, batches, b"im-online", ImOnline); add_benchmark!(params, batches, b"session", SessionBench::); add_benchmark!(params, batches, b"staking", Staking); add_benchmark!(params, batches, b"timestamp", Timestamp); add_benchmark!(params, batches, b"treasury", Treasury); + add_benchmark!(params, batches, b"utility", Utility); add_benchmark!(params, batches, b"vesting", Vesting); - add_benchmark!(params, batches, b"democracy", Democracy); - add_benchmark!(params, batches, b"collective", Council); if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } Ok(batches) } diff --git a/frame/balances/src/benchmarking.rs b/frame/balances/src/benchmarking.rs index d35ec7cc85..161fdab96b 100644 --- a/frame/balances/src/benchmarking.rs +++ b/frame/balances/src/benchmarking.rs @@ -16,6 +16,8 @@ //! Balances pallet benchmarking. +#![cfg(feature = "runtime-benchmarks")] + use super::*; use frame_system::RawOrigin; diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index b83530d635..39e15b3f4f 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -148,14 +148,10 @@ #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(test)] -mod tests_local; -#[cfg(test)] -mod tests_composite; -#[cfg(test)] #[macro_use] mod tests; -#[cfg(feature = "runtime-benchmarks")] +mod tests_local; +mod tests_composite; mod benchmarking; use sp_std::prelude::*; diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index 98c7c856bc..8055c2013e 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -16,6 +16,8 @@ //! Macro for creating the tests for the module. +#![cfg(test)] + #[macro_export] macro_rules! decl_tests { ($test:ty, $ext_builder:ty, $existential_deposit:expr) => { diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index 3a5c2178f8..8935dc4c9a 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -16,6 +16,8 @@ //! Test utilities +#![cfg(test)] + use sp_runtime::{Perbill, traits::{ConvertInto, IdentityLookup}, testing::Header}; use sp_core::H256; use sp_io; diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index 861c197212..c8a4a298f5 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -16,6 +16,8 @@ //! Test utilities +#![cfg(test)] + use sp_runtime::{Perbill, traits::{ConvertInto, IdentityLookup}, testing::Header}; use sp_core::H256; use sp_io; diff --git a/frame/benchmark/src/benchmarking.rs b/frame/benchmark/src/benchmarking.rs index 29f9e8ee97..1e4740da2c 100644 --- a/frame/benchmark/src/benchmarking.rs +++ b/frame/benchmark/src/benchmarking.rs @@ -16,6 +16,8 @@ //! Benchmarks for common FRAME Pallet operations. +#![cfg(feature = "runtime-benchmarks")] + use super::*; use frame_system::RawOrigin; diff --git a/frame/benchmark/src/lib.rs b/frame/benchmark/src/lib.rs index 4ac0539eff..b571ffb5b9 100644 --- a/frame/benchmark/src/lib.rs +++ b/frame/benchmark/src/lib.rs @@ -26,8 +26,7 @@ use frame_system::{self as system, ensure_signed}; use codec::{Encode, Decode}; use sp_std::prelude::Vec; -#[cfg(feature = "runtime-benchmarks")] -pub mod benchmarking; +mod benchmarking; /// Type alias for currency balance. pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; diff --git a/frame/identity/src/benchmarking.rs b/frame/identity/src/benchmarking.rs index 1ca10707c9..b5236e6219 100644 --- a/frame/identity/src/benchmarking.rs +++ b/frame/identity/src/benchmarking.rs @@ -16,6 +16,8 @@ //! Identity pallet benchmarking. +#![cfg(feature = "runtime-benchmarks")] + use super::*; use frame_system::RawOrigin; diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index 4cbd8c7a2b..e5b1fe68bb 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -78,8 +78,7 @@ use frame_support::{ }; use frame_system::{self as system, ensure_signed, ensure_root}; -#[cfg(feature = "runtime-benchmarks")] -pub mod benchmarking; +mod benchmarking; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; diff --git a/frame/timestamp/src/benchmarking.rs b/frame/timestamp/src/benchmarking.rs index 5f69cdbe7e..65b4dbf2b0 100644 --- a/frame/timestamp/src/benchmarking.rs +++ b/frame/timestamp/src/benchmarking.rs @@ -16,10 +16,10 @@ //! Timestamp pallet benchmarking. -use super::*; +#![cfg(feature = "runtime-benchmarks")] +use super::*; use sp_std::prelude::*; - use frame_system::RawOrigin; use frame_benchmarking::benchmarks; diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 7dccc47096..5d5180314e 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -91,7 +91,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(feature = "runtime-benchmarks")] mod benchmarking; use sp_std::{result, cmp}; diff --git a/frame/treasury/src/benchmarking.rs b/frame/treasury/src/benchmarking.rs index a47c89df45..925832e04c 100644 --- a/frame/treasury/src/benchmarking.rs +++ b/frame/treasury/src/benchmarking.rs @@ -16,6 +16,8 @@ //! Treasury pallet benchmarking. +#![cfg(feature = "runtime-benchmarks")] + use super::*; use frame_system::RawOrigin; diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 376ec85fc9..27e0e852d6 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -102,9 +102,7 @@ use frame_support::{weights::{Weight, WeighData, SimpleDispatchInfo}, traits::Co use codec::{Encode, Decode}; use frame_system::{self as system, ensure_signed, ensure_root}; -#[cfg(test)] mod tests; -#[cfg(feature = "runtime-benchmarks")] mod benchmarking; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index 262afb3819..1f6dbecef5 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -1,3 +1,23 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Treasury pallet tests. + +#![cfg(test)] + use super::*; use frame_support::{ diff --git a/frame/utility/Cargo.toml b/frame/utility/Cargo.toml index 173f60a2e5..cf1042d852 100644 --- a/frame/utility/Cargo.toml +++ b/frame/utility/Cargo.toml @@ -18,6 +18,8 @@ sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../. sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } + [dev-dependencies] sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } @@ -33,6 +35,10 @@ std = [ "sp-io/std", "sp-std/std" ] +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", +] [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/utility/src/benchmarking.rs b/frame/utility/src/benchmarking.rs new file mode 100644 index 0000000000..f16754fad5 --- /dev/null +++ b/frame/utility/src/benchmarking.rs @@ -0,0 +1,148 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +// Benchmarks for Utility Pallet + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; +use frame_system::RawOrigin; +use frame_benchmarking::{benchmarks, account}; +use sp_runtime::traits::Saturating; + +use crate::Module as Utility; + +const SEED: u32 = 0; + +fn setup_multi(s: u32, z: u32) -> Result<(Vec, Box<::Call>), &'static str>{ + let mut signatories: Vec = Vec::new(); + for i in 0 .. s { + let signatory = account("signatory", i, SEED); + // Give them some balance for a possible deposit + let deposit = T::MultisigDepositBase::get() + T::MultisigDepositFactor::get() * s.into(); + let balance = T::Currency::minimum_balance().saturating_mul(100.into()) + deposit; + T::Currency::make_free_balance_be(&signatory, balance); + signatories.push(signatory); + } + signatories.sort(); + let call: Box<::Call> = Box::new(frame_system::Call::remark(vec![0; z as usize]).into()); + return Ok((signatories, call)) +} + +benchmarks! { + _ { } + + batch { + let c in 0 .. 1000; + let mut calls: Vec<::Call> = Vec::new(); + for i in 0 .. c { + let call = frame_system::Call::remark(vec![]).into(); + calls.push(call); + } + let caller = account("caller", 0, SEED); + }: _(RawOrigin::Signed(caller), calls) + + as_sub { + let u in 0 .. 1000; + let caller = account("caller", u, SEED); + let call = Box::new(frame_system::Call::remark(vec![]).into()); + }: _(RawOrigin::Signed(caller), u as u16, call) + + as_multi_create { + // Signatories, need at least 2 total people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + }: as_multi(RawOrigin::Signed(caller), s as u16, signatories, None, call) + + as_multi_approve { + // Signatories, need at least 2 people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let mut signatories2 = signatories.clone(); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + // before the call, get the timepoint + let timepoint = Utility::::timepoint(); + // Create the multi + Utility::::as_multi(RawOrigin::Signed(caller).into(), s as u16, signatories, None, call.clone())?; + let caller2 = signatories2.remove(0); + }: as_multi(RawOrigin::Signed(caller2), s as u16, signatories2, Some(timepoint), call) + + as_multi_complete { + // Signatories, need at least 2 people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let mut signatories2 = signatories.clone(); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + // before the call, get the timepoint + let timepoint = Utility::::timepoint(); + // Create the multi + Utility::::as_multi(RawOrigin::Signed(caller).into(), s as u16, signatories, None, call.clone())?; + // Everyone except the first person approves + for i in 1 .. s - 1 { + let mut signatories_loop = signatories2.clone(); + let caller_loop = signatories_loop.remove(i as usize); + Utility::::as_multi(RawOrigin::Signed(caller_loop).into(), s as u16, signatories_loop, Some(timepoint), call.clone())?; + } + let caller2 = signatories2.remove(0); + }: as_multi(RawOrigin::Signed(caller2), s as u16, signatories2, Some(timepoint), call) + + approve_as_multi_create { + // Signatories, need at least 2 people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + let call_hash = call.using_encoded(blake2_256); + // Create the multi + }: approve_as_multi(RawOrigin::Signed(caller), s as u16, signatories, None, call_hash) + + approve_as_multi_approve { + // Signatories, need at least 2 people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let mut signatories2 = signatories.clone(); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + let call_hash = call.using_encoded(blake2_256); + // before the call, get the timepoint + let timepoint = Utility::::timepoint(); + // Create the multi + Utility::::as_multi(RawOrigin::Signed(caller).into(), s as u16, signatories, None, call.clone())?; + let caller2 = signatories2.remove(0); + }: approve_as_multi(RawOrigin::Signed(caller2), s as u16, signatories2, Some(timepoint), call_hash) + + cancel_as_multi { + // Signatories, need at least 2 people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + let call_hash = call.using_encoded(blake2_256); + let timepoint = Utility::::timepoint(); + // Create the multi + Utility::::as_multi(RawOrigin::Signed(caller.clone()).into(), s as u16, signatories.clone(), None, call.clone())?; + }: _(RawOrigin::Signed(caller), s as u16, signatories, timepoint, call_hash) +} diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 2f7b11bdaa..927d8b8786 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -72,6 +72,9 @@ use frame_support::{traits::{Get, ReservableCurrency, Currency}, use frame_system::{self as system, ensure_signed}; use sp_runtime::{DispatchError, DispatchResult, traits::Dispatchable}; +mod tests; +mod benchmarking; + type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// Configuration trait. @@ -80,7 +83,7 @@ pub trait Trait: frame_system::Trait { type Event: From> + Into<::Event>; /// The overarching call type. - type Call: Parameter + Dispatchable + GetDispatchInfo; + type Call: Parameter + Dispatchable + GetDispatchInfo + From>; /// The currency mechanism. type Currency: ReservableCurrency; @@ -563,428 +566,3 @@ impl Module { Ok(signatories) } } - -#[cfg(test)] -mod tests { - use super::*; - - use frame_support::{ - assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch, - weights::Weight, impl_outer_event - }; - use sp_core::H256; - use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; - use crate as utility; - - impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} - } - - impl_outer_event! { - pub enum TestEvent for Test { - system, - pallet_balances, - utility, - } - } - impl_outer_dispatch! { - pub enum Call for Test where origin: Origin { - pallet_balances::Balances, - utility::Utility, - } - } - - // For testing the pallet, we construct most of a mock runtime. This means - // first constructing a configuration type (`Test`) which `impl`s each of the - // configuration traits of pallets we want to use. - #[derive(Clone, Eq, PartialEq)] - pub struct Test; - parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - } - impl frame_system::Trait for Test { - type Origin = Origin; - type Index = u64; - type BlockNumber = u64; - type Hash = H256; - type Call = Call; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = TestEvent; - type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; - type Version = (); - type ModuleToIndex = (); - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - } - parameter_types! { - pub const ExistentialDeposit: u64 = 1; - } - impl pallet_balances::Trait for Test { - type Balance = u64; - type Event = TestEvent; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - } - parameter_types! { - pub const MultisigDepositBase: u64 = 1; - pub const MultisigDepositFactor: u64 = 1; - pub const MaxSignatories: u16 = 3; - } - impl Trait for Test { - type Event = TestEvent; - type Call = Call; - type Currency = Balances; - type MultisigDepositBase = MultisigDepositBase; - type MultisigDepositFactor = MultisigDepositFactor; - type MaxSignatories = MaxSignatories; - } - type System = frame_system::Module; - type Balances = pallet_balances::Module; - type Utility = Module; - - use pallet_balances::Call as BalancesCall; - use pallet_balances::Error as BalancesError; - - fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - pallet_balances::GenesisConfig:: { - balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 10)], - }.assimilate_storage(&mut t).unwrap(); - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } - - fn last_event() -> TestEvent { - system::Module::::events().pop().map(|e| e.event).expect("Event expected") - } - - fn expect_event>(e: E) { - assert_eq!(last_event(), e.into()); - } - - fn now() -> Timepoint { - Utility::timepoint() - } - - #[test] - fn multisig_deposit_is_taken_and_returned() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call.clone())); - assert_eq!(Balances::free_balance(1), 2); - assert_eq!(Balances::reserved_balance(1), 3); - - assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), call)); - assert_eq!(Balances::free_balance(1), 5); - assert_eq!(Balances::reserved_balance(1), 0); - }); - } - - #[test] - fn cancel_multisig_returns_deposit() { - new_test_ext().execute_with(|| { - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - assert_ok!(Utility::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone())); - assert_ok!(Utility::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone())); - assert_eq!(Balances::free_balance(1), 6); - assert_eq!(Balances::reserved_balance(1), 4); - assert_ok!( - Utility::cancel_as_multi(Origin::signed(1), 3, vec![2, 3], now(), hash.clone()), - ); - assert_eq!(Balances::free_balance(1), 10); - assert_eq!(Balances::reserved_balance(1), 0); - }); - } - - #[test] - fn timepoint_checking_works() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - - assert_noop!( - Utility::approve_as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), hash.clone()), - Error::::UnexpectedTimepoint, - ); - - assert_ok!(Utility::approve_as_multi(Origin::signed(1), 2, vec![2, 3], None, hash)); - - assert_noop!( - Utility::as_multi(Origin::signed(2), 2, vec![1, 3], None, call.clone()), - Error::::NoTimepoint, - ); - let later = Timepoint { index: 1, .. now() }; - assert_noop!( - Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(later), call.clone()), - Error::::WrongTimepoint, - ); - }); - } - - #[test] - fn multisig_2_of_3_works() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - assert_ok!(Utility::approve_as_multi(Origin::signed(1), 2, vec![2, 3], None, hash)); - assert_eq!(Balances::free_balance(6), 0); - - assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), call)); - assert_eq!(Balances::free_balance(6), 15); - }); - } - - #[test] - fn multisig_3_of_3_works() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 3); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - assert_ok!(Utility::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone())); - assert_ok!(Utility::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone())); - assert_eq!(Balances::free_balance(6), 0); - - assert_ok!(Utility::as_multi(Origin::signed(3), 3, vec![1, 2], Some(now()), call)); - assert_eq!(Balances::free_balance(6), 15); - }); - } - - #[test] - fn cancel_multisig_works() { - new_test_ext().execute_with(|| { - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - assert_ok!(Utility::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone())); - assert_ok!(Utility::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone())); - assert_noop!( - Utility::cancel_as_multi(Origin::signed(2), 3, vec![1, 3], now(), hash.clone()), - Error::::NotOwner, - ); - assert_ok!( - Utility::cancel_as_multi(Origin::signed(1), 3, vec![2, 3], now(), hash.clone()), - ); - }); - } - - #[test] - fn multisig_2_of_3_as_multi_works() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call.clone())); - assert_eq!(Balances::free_balance(6), 0); - - assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), call)); - assert_eq!(Balances::free_balance(6), 15); - }); - } - - #[test] - fn multisig_2_of_3_as_multi_with_many_calls_works() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call1 = Box::new(Call::Balances(BalancesCall::transfer(6, 10))); - let call2 = Box::new(Call::Balances(BalancesCall::transfer(7, 5))); - - assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call1.clone())); - assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], None, call2.clone())); - assert_ok!(Utility::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), call2)); - assert_ok!(Utility::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), call1)); - - assert_eq!(Balances::free_balance(6), 10); - assert_eq!(Balances::free_balance(7), 5); - }); - } - - #[test] - fn multisig_2_of_3_cannot_reissue_same_call() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 10))); - assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call.clone())); - assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), call.clone())); - assert_eq!(Balances::free_balance(multi), 5); - - assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call.clone())); - assert_ok!(Utility::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), call)); - - let err = DispatchError::from(BalancesError::::InsufficientBalance).stripped(); - expect_event(RawEvent::MultisigExecuted(3, now(), multi, Err(err))); - }); - } - - #[test] - fn zero_threshold_fails() { - new_test_ext().execute_with(|| { - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - assert_noop!( - Utility::as_multi(Origin::signed(1), 0, vec![2], None, call), - Error::::ZeroThreshold, - ); - }); - } - - #[test] - fn too_many_signatories_fails() { - new_test_ext().execute_with(|| { - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - assert_noop!( - Utility::as_multi(Origin::signed(1), 2, vec![2, 3, 4], None, call.clone()), - Error::::TooManySignatories, - ); - }); - } - - #[test] - fn duplicate_approvals_are_ignored() { - new_test_ext().execute_with(|| { - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - assert_ok!(Utility::approve_as_multi(Origin::signed(1), 2, vec![2, 3], None, hash.clone())); - assert_noop!( - Utility::approve_as_multi(Origin::signed(1), 2, vec![2, 3], Some(now()), hash.clone()), - Error::::AlreadyApproved, - ); - assert_ok!(Utility::approve_as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), hash.clone())); - assert_noop!( - Utility::approve_as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), hash.clone()), - Error::::NoApprovalsNeeded, - ); - }); - } - - #[test] - fn multisig_1_of_3_works() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 1); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - assert_noop!( - Utility::approve_as_multi(Origin::signed(1), 1, vec![2, 3], None, hash.clone()), - Error::::NoApprovalsNeeded, - ); - assert_noop!( - Utility::as_multi(Origin::signed(4), 1, vec![2, 3], None, call.clone()), - BalancesError::::InsufficientBalance, - ); - assert_ok!(Utility::as_multi(Origin::signed(1), 1, vec![2, 3], None, call)); - - assert_eq!(Balances::free_balance(6), 15); - }); - } - - #[test] - fn as_sub_works() { - new_test_ext().execute_with(|| { - let sub_1_0 = Utility::sub_account_id(1, 0); - assert_ok!(Balances::transfer(Origin::signed(1), sub_1_0, 5)); - assert_noop!(Utility::as_sub( - Origin::signed(1), - 1, - Box::new(Call::Balances(BalancesCall::transfer(6, 3))), - ), BalancesError::::InsufficientBalance); - assert_ok!(Utility::as_sub( - Origin::signed(1), - 0, - Box::new(Call::Balances(BalancesCall::transfer(2, 3))), - )); - assert_eq!(Balances::free_balance(sub_1_0), 2); - assert_eq!(Balances::free_balance(2), 13); - }); - } - - #[test] - fn batch_with_root_works() { - new_test_ext().execute_with(|| { - assert_eq!(Balances::free_balance(1), 10); - assert_eq!(Balances::free_balance(2), 10); - assert_ok!(Utility::batch(Origin::ROOT, vec![ - Call::Balances(BalancesCall::force_transfer(1, 2, 5)), - Call::Balances(BalancesCall::force_transfer(1, 2, 5)) - ])); - assert_eq!(Balances::free_balance(1), 0); - assert_eq!(Balances::free_balance(2), 20); - }); - } - - #[test] - fn batch_with_signed_works() { - new_test_ext().execute_with(|| { - assert_eq!(Balances::free_balance(1), 10); - assert_eq!(Balances::free_balance(2), 10); - assert_ok!( - Utility::batch(Origin::signed(1), vec![ - Call::Balances(BalancesCall::transfer(2, 5)), - Call::Balances(BalancesCall::transfer(2, 5)) - ]), - ); - assert_eq!(Balances::free_balance(1), 0); - assert_eq!(Balances::free_balance(2), 20); - }); - } - - #[test] - fn batch_early_exit_works() { - new_test_ext().execute_with(|| { - assert_eq!(Balances::free_balance(1), 10); - assert_eq!(Balances::free_balance(2), 10); - assert_ok!( - Utility::batch(Origin::signed(1), vec![ - Call::Balances(BalancesCall::transfer(2, 5)), - Call::Balances(BalancesCall::transfer(2, 10)), - Call::Balances(BalancesCall::transfer(2, 5)), - ]), - ); - assert_eq!(Balances::free_balance(1), 5); - assert_eq!(Balances::free_balance(2), 15); - }); - } -} diff --git a/frame/utility/src/tests.rs b/frame/utility/src/tests.rs new file mode 100644 index 0000000000..9fcd525020 --- /dev/null +++ b/frame/utility/src/tests.rs @@ -0,0 +1,442 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +// Tests for Utility Pallet + +#![cfg(test)] + +use super::*; + +use frame_support::{ + assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch, + weights::Weight, impl_outer_event +}; +use sp_core::H256; +use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; +use crate as utility; + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +impl_outer_event! { + pub enum TestEvent for Test { + system, + pallet_balances, + utility, + } +} +impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + frame_system::System, + pallet_balances::Balances, + utility::Utility, + } +} + +// For testing the pallet, we construct most of a mock runtime. This means +// first constructing a configuration type (`Test`) which `impl`s each of the +// configuration traits of pallets we want to use. +#[derive(Clone, Eq, PartialEq)] +pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} +impl frame_system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Call = Call; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = TestEvent; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); +} +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} +impl pallet_balances::Trait for Test { + type Balance = u64; + type Event = TestEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; +} +parameter_types! { + pub const MultisigDepositBase: u64 = 1; + pub const MultisigDepositFactor: u64 = 1; + pub const MaxSignatories: u16 = 3; +} +impl Trait for Test { + type Event = TestEvent; + type Call = Call; + type Currency = Balances; + type MultisigDepositBase = MultisigDepositBase; + type MultisigDepositFactor = MultisigDepositFactor; + type MaxSignatories = MaxSignatories; +} +type System = frame_system::Module; +type Balances = pallet_balances::Module; +type Utility = Module; + +use pallet_balances::Call as BalancesCall; +use pallet_balances::Error as BalancesError; + +fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 10)], + }.assimilate_storage(&mut t).unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +fn last_event() -> TestEvent { + system::Module::::events().pop().map(|e| e.event).expect("Event expected") +} + +fn expect_event>(e: E) { + assert_eq!(last_event(), e.into()); +} + +fn now() -> Timepoint { + Utility::timepoint() +} + +#[test] +fn multisig_deposit_is_taken_and_returned() { + new_test_ext().execute_with(|| { + let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); + assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call.clone())); + assert_eq!(Balances::free_balance(1), 2); + assert_eq!(Balances::reserved_balance(1), 3); + + assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), call)); + assert_eq!(Balances::free_balance(1), 5); + assert_eq!(Balances::reserved_balance(1), 0); + }); +} + +#[test] +fn cancel_multisig_returns_deposit() { + new_test_ext().execute_with(|| { + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); + let hash = call.using_encoded(blake2_256); + assert_ok!(Utility::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone())); + assert_ok!(Utility::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone())); + assert_eq!(Balances::free_balance(1), 6); + assert_eq!(Balances::reserved_balance(1), 4); + assert_ok!( + Utility::cancel_as_multi(Origin::signed(1), 3, vec![2, 3], now(), hash.clone()), + ); + assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::reserved_balance(1), 0); + }); +} + +#[test] +fn timepoint_checking_works() { + new_test_ext().execute_with(|| { + let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); + let hash = call.using_encoded(blake2_256); + + assert_noop!( + Utility::approve_as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), hash.clone()), + Error::::UnexpectedTimepoint, + ); + + assert_ok!(Utility::approve_as_multi(Origin::signed(1), 2, vec![2, 3], None, hash)); + + assert_noop!( + Utility::as_multi(Origin::signed(2), 2, vec![1, 3], None, call.clone()), + Error::::NoTimepoint, + ); + let later = Timepoint { index: 1, .. now() }; + assert_noop!( + Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(later), call.clone()), + Error::::WrongTimepoint, + ); + }); +} + +#[test] +fn multisig_2_of_3_works() { + new_test_ext().execute_with(|| { + let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); + let hash = call.using_encoded(blake2_256); + assert_ok!(Utility::approve_as_multi(Origin::signed(1), 2, vec![2, 3], None, hash)); + assert_eq!(Balances::free_balance(6), 0); + + assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), call)); + assert_eq!(Balances::free_balance(6), 15); + }); +} + +#[test] +fn multisig_3_of_3_works() { + new_test_ext().execute_with(|| { + let multi = Utility::multi_account_id(&[1, 2, 3][..], 3); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); + let hash = call.using_encoded(blake2_256); + assert_ok!(Utility::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone())); + assert_ok!(Utility::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone())); + assert_eq!(Balances::free_balance(6), 0); + + assert_ok!(Utility::as_multi(Origin::signed(3), 3, vec![1, 2], Some(now()), call)); + assert_eq!(Balances::free_balance(6), 15); + }); +} + +#[test] +fn cancel_multisig_works() { + new_test_ext().execute_with(|| { + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); + let hash = call.using_encoded(blake2_256); + assert_ok!(Utility::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone())); + assert_ok!(Utility::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone())); + assert_noop!( + Utility::cancel_as_multi(Origin::signed(2), 3, vec![1, 3], now(), hash.clone()), + Error::::NotOwner, + ); + assert_ok!( + Utility::cancel_as_multi(Origin::signed(1), 3, vec![2, 3], now(), hash.clone()), + ); + }); +} + +#[test] +fn multisig_2_of_3_as_multi_works() { + new_test_ext().execute_with(|| { + let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); + assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call.clone())); + assert_eq!(Balances::free_balance(6), 0); + + assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), call)); + assert_eq!(Balances::free_balance(6), 15); + }); +} + +#[test] +fn multisig_2_of_3_as_multi_with_many_calls_works() { + new_test_ext().execute_with(|| { + let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call1 = Box::new(Call::Balances(BalancesCall::transfer(6, 10))); + let call2 = Box::new(Call::Balances(BalancesCall::transfer(7, 5))); + + assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call1.clone())); + assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], None, call2.clone())); + assert_ok!(Utility::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), call2)); + assert_ok!(Utility::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), call1)); + + assert_eq!(Balances::free_balance(6), 10); + assert_eq!(Balances::free_balance(7), 5); + }); +} + +#[test] +fn multisig_2_of_3_cannot_reissue_same_call() { + new_test_ext().execute_with(|| { + let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 10))); + assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call.clone())); + assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), call.clone())); + assert_eq!(Balances::free_balance(multi), 5); + + assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call.clone())); + assert_ok!(Utility::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), call)); + + let err = DispatchError::from(BalancesError::::InsufficientBalance).stripped(); + expect_event(RawEvent::MultisigExecuted(3, now(), multi, Err(err))); + }); +} + +#[test] +fn zero_threshold_fails() { + new_test_ext().execute_with(|| { + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); + assert_noop!( + Utility::as_multi(Origin::signed(1), 0, vec![2], None, call), + Error::::ZeroThreshold, + ); + }); +} + +#[test] +fn too_many_signatories_fails() { + new_test_ext().execute_with(|| { + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); + assert_noop!( + Utility::as_multi(Origin::signed(1), 2, vec![2, 3, 4], None, call.clone()), + Error::::TooManySignatories, + ); + }); +} + +#[test] +fn duplicate_approvals_are_ignored() { + new_test_ext().execute_with(|| { + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); + let hash = call.using_encoded(blake2_256); + assert_ok!(Utility::approve_as_multi(Origin::signed(1), 2, vec![2, 3], None, hash.clone())); + assert_noop!( + Utility::approve_as_multi(Origin::signed(1), 2, vec![2, 3], Some(now()), hash.clone()), + Error::::AlreadyApproved, + ); + assert_ok!(Utility::approve_as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), hash.clone())); + assert_noop!( + Utility::approve_as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), hash.clone()), + Error::::NoApprovalsNeeded, + ); + }); +} + +#[test] +fn multisig_1_of_3_works() { + new_test_ext().execute_with(|| { + let multi = Utility::multi_account_id(&[1, 2, 3][..], 1); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); + let hash = call.using_encoded(blake2_256); + assert_noop!( + Utility::approve_as_multi(Origin::signed(1), 1, vec![2, 3], None, hash.clone()), + Error::::NoApprovalsNeeded, + ); + assert_noop!( + Utility::as_multi(Origin::signed(4), 1, vec![2, 3], None, call.clone()), + BalancesError::::InsufficientBalance, + ); + assert_ok!(Utility::as_multi(Origin::signed(1), 1, vec![2, 3], None, call)); + + assert_eq!(Balances::free_balance(6), 15); + }); +} + +#[test] +fn as_sub_works() { + new_test_ext().execute_with(|| { + let sub_1_0 = Utility::sub_account_id(1, 0); + assert_ok!(Balances::transfer(Origin::signed(1), sub_1_0, 5)); + assert_noop!(Utility::as_sub( + Origin::signed(1), + 1, + Box::new(Call::Balances(BalancesCall::transfer(6, 3))), + ), BalancesError::::InsufficientBalance); + assert_ok!(Utility::as_sub( + Origin::signed(1), + 0, + Box::new(Call::Balances(BalancesCall::transfer(2, 3))), + )); + assert_eq!(Balances::free_balance(sub_1_0), 2); + assert_eq!(Balances::free_balance(2), 13); + }); +} + +#[test] +fn batch_with_root_works() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::free_balance(2), 10); + assert_ok!(Utility::batch(Origin::ROOT, vec![ + Call::Balances(BalancesCall::force_transfer(1, 2, 5)), + Call::Balances(BalancesCall::force_transfer(1, 2, 5)) + ])); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::free_balance(2), 20); + }); +} + +#[test] +fn batch_with_signed_works() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::free_balance(2), 10); + assert_ok!( + Utility::batch(Origin::signed(1), vec![ + Call::Balances(BalancesCall::transfer(2, 5)), + Call::Balances(BalancesCall::transfer(2, 5)) + ]), + ); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::free_balance(2), 20); + }); +} + +#[test] +fn batch_early_exit_works() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::free_balance(2), 10); + assert_ok!( + Utility::batch(Origin::signed(1), vec![ + Call::Balances(BalancesCall::transfer(2, 5)), + Call::Balances(BalancesCall::transfer(2, 10)), + Call::Balances(BalancesCall::transfer(2, 5)), + ]), + ); + assert_eq!(Balances::free_balance(1), 5); + assert_eq!(Balances::free_balance(2), 15); + }); +} diff --git a/frame/vesting/src/benchmarking.rs b/frame/vesting/src/benchmarking.rs index 8d0f0214eb..2ef8ed9ef8 100644 --- a/frame/vesting/src/benchmarking.rs +++ b/frame/vesting/src/benchmarking.rs @@ -16,6 +16,8 @@ //! Vesting pallet benchmarking. +#![cfg(feature = "runtime-benchmarks")] + use super::*; use frame_system::{RawOrigin, Module as System}; @@ -119,6 +121,6 @@ benchmarks! { }; let _ = T::Currency::make_free_balance_be(&from, transfer_amount * 10.into()); - + }: _(RawOrigin::Signed(from), to_lookup, vesting_schedule) } diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index b7ff091d32..b0c98e78bd 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -60,7 +60,6 @@ use frame_support::traits::{ use frame_support::weights::SimpleDispatchInfo; use frame_system::{self as system, ensure_signed}; -#[cfg(feature = "runtime-benchmarks")] mod benchmarking; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -- GitLab From d477017fb655f71de6c952b7eb085866bd8f6f7f Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Tue, 31 Mar 2020 16:16:24 -0700 Subject: [PATCH 126/300] remove ws feature from json client (#5478) --- Cargo.lock | 470 ++++++----------------- bin/node/rpc-client/Cargo.toml | 2 +- client/consensus/babe/rpc/Cargo.toml | 2 +- client/rpc-api/Cargo.toml | 2 +- frame/contracts/rpc/Cargo.toml | 2 +- frame/transaction-payment/rpc/Cargo.toml | 2 +- utils/frame/rpc/support/Cargo.toml | 2 +- utils/frame/rpc/system/Cargo.toml | 2 +- 8 files changed, 135 insertions(+), 349 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a85935e99..4e16401288 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -210,7 +210,7 @@ dependencies = [ "futures-io", "futures-timer 2.0.2", "kv-log-macro", - "log 0.4.8", + "log", "memchr", "mio", "mio-uds", @@ -294,16 +294,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" -[[package]] -name = "base64" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -dependencies = [ - "byteorder 1.3.4", - "safemem", -] - [[package]] name = "base64" version = "0.10.1" @@ -343,7 +333,7 @@ dependencies = [ "env_logger 0.7.1", "lazy_static", "lazycell", - "log 0.4.8", + "log", "peeking_take_while", "proc-macro2", "quote", @@ -680,7 +670,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7871d2947441b0fdd8e2bd1ce2a2f75304f896582c0d572162d48290683c48" dependencies = [ - "log 0.4.8", + "log", "web-sys", ] @@ -747,7 +737,7 @@ dependencies = [ "cranelift-codegen-shared", "cranelift-entity", "gimli", - "log 0.4.8", + "log", "serde", "smallvec 1.2.0", "target-lexicon", @@ -786,7 +776,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "518344698fa6c976d853319218415fdfb4f1bc6b42d0b2e2df652e55dff1f778" dependencies = [ "cranelift-codegen", - "log 0.4.8", + "log", "smallvec 1.2.0", "target-lexicon", ] @@ -811,7 +801,7 @@ dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", - "log 0.4.8", + "log", "serde", "thiserror", "wasmparser", @@ -1162,7 +1152,7 @@ checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" dependencies = [ "atty", "humantime", - "log 0.4.8", + "log", "regex", "termcolor", ] @@ -1175,7 +1165,7 @@ checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" dependencies = [ "atty", "humantime", - "log 0.4.8", + "log", "regex", "termcolor", ] @@ -1307,7 +1297,7 @@ dependencies = [ "anyhow", "goblin", "indexmap", - "log 0.4.8", + "log", "scroll", "string-interner", "target-lexicon", @@ -1364,7 +1354,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8505b75b31ef7285168dd237c4a7db3c1f3e0927e7d314e670bc98e854272fe9" dependencies = [ "env_logger 0.6.2", - "log 0.4.8", + "log", ] [[package]] @@ -1375,7 +1365,7 @@ checksum = "024517816630be5204eba201e8d1d405042b1255a5e0e3f298b054fc24d59e1d" dependencies = [ "futures 0.3.4", "futures-timer 2.0.2", - "log 0.4.8", + "log", "num-traits", "parity-scale-codec", "parking_lot 0.9.0", @@ -1419,21 +1409,6 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "fork-tree" version = "2.0.0-alpha.5" @@ -1512,7 +1487,7 @@ dependencies = [ "frame-support-procedural", "frame-system", "impl-trait-for-tuples", - "log 0.4.8", + "log", "once_cell", "parity-scale-codec", "paste", @@ -1721,7 +1696,7 @@ dependencies = [ "futures 0.1.29", "futures 0.3.4", "lazy_static", - "log 0.4.8", + "log", "parking_lot 0.9.0", "pin-project", "serde", @@ -1915,7 +1890,7 @@ dependencies = [ "aho-corasick", "bstr", "fnv", - "log 0.4.8", + "log", "regex", ] @@ -1938,7 +1913,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3081214398d39e4bd7f2c1975f0488ed04614ffdd976c6fc7a0708278552c0da" dependencies = [ - "log 0.4.8", + "log", "plain", "scroll", ] @@ -1955,7 +1930,7 @@ dependencies = [ "futures 0.1.29", "http 0.1.21", "indexmap", - "log 0.4.8", + "log", "slab", "string", "tokio-io", @@ -1974,7 +1949,7 @@ dependencies = [ "futures-util", "http 0.2.1", "indexmap", - "log 0.4.8", + "log", "slab", "tokio 0.2.13", "tokio-util", @@ -2139,25 +2114,6 @@ dependencies = [ "quick-error", ] -[[package]] -name = "hyper" -version = "0.10.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" -dependencies = [ - "base64 0.9.3", - "httparse", - "language-tags", - "log 0.3.9", - "mime", - "num_cpus", - "time", - "traitobject", - "typeable", - "unicase 1.4.2", - "url 1.7.2", -] - [[package]] name = "hyper" version = "0.12.35" @@ -2173,7 +2129,7 @@ dependencies = [ "httparse", "iovec", "itoa", - "log 0.4.8", + "log", "net2", "rustc_version", "time", @@ -2203,7 +2159,7 @@ dependencies = [ "http-body 0.3.1", "httparse", "itoa", - "log 0.4.8", + "log", "net2", "pin-project", "time", @@ -2222,7 +2178,7 @@ dependencies = [ "ct-logs", "futures-util", "hyper 0.13.4", - "log 0.4.8", + "log", "rustls 0.17.0", "rustls-native-certs", "tokio 0.2.13", @@ -2230,19 +2186,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "hyper-tls" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.29", - "hyper 0.12.35", - "native-tls", - "tokio-io", -] - [[package]] name = "idna" version = "0.1.5" @@ -2400,15 +2343,12 @@ dependencies = [ "failure", "futures 0.1.29", "hyper 0.12.35", - "hyper-tls", "jsonrpc-core", "jsonrpc-pubsub", - "log 0.4.8", + "log", "serde", "serde_json", - "tokio 0.1.22", "url 1.7.2", - "websocket", ] [[package]] @@ -2418,7 +2358,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe3b688648f1ef5d5072229e2d672ecb92cbff7d1c79bcf3fd5898f3f3df0970" dependencies = [ "futures 0.1.29", - "log 0.4.8", + "log", "serde", "serde_derive", "serde_json", @@ -2454,10 +2394,10 @@ dependencies = [ "hyper 0.12.35", "jsonrpc-core", "jsonrpc-server-utils", - "log 0.4.8", + "log", "net2", "parking_lot 0.10.0", - "unicase 2.6.0", + "unicase", ] [[package]] @@ -2467,7 +2407,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b31c9b90731276fdd24d896f31bb10aecf2e5151733364ae81123186643d939" dependencies = [ "jsonrpc-core", - "log 0.4.8", + "log", "parking_lot 0.10.0", "serde", ] @@ -2482,10 +2422,10 @@ dependencies = [ "globset", "jsonrpc-core", "lazy_static", - "log 0.4.8", + "log", "tokio 0.1.22", "tokio-codec", - "unicase 2.6.0", + "unicase", ] [[package]] @@ -2496,7 +2436,7 @@ checksum = "b94e5773b2ae66e0e02c80775ce6bbba6f15d5bb47c14ec36a36fcf94f8df851" dependencies = [ "jsonrpc-core", "jsonrpc-server-utils", - "log 0.4.8", + "log", "parking_lot 0.10.0", "slab", "ws", @@ -2535,7 +2475,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c54d9f465d530a752e6ebdc217e081a7a614b48cb200f6f0aee21ba6bc9aabb" dependencies = [ - "log 0.4.8", + "log", ] [[package]] @@ -2568,7 +2508,7 @@ dependencies = [ "fs-swap", "interleaved-ordered", "kvdb", - "log 0.4.8", + "log", "num_cpus", "owning_ref", "parity-util-mem", @@ -2588,19 +2528,13 @@ dependencies = [ "js-sys", "kvdb", "kvdb-memorydb", - "log 0.4.8", + "log", "parity-util-mem", "send_wrapper 0.3.0", "wasm-bindgen", "web-sys", ] -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" - [[package]] name = "lazy_static" version = "1.4.0" @@ -2693,7 +2627,7 @@ dependencies = [ "futures-timer 3.0.2", "lazy_static", "libsecp256k1", - "log 0.4.8", + "log", "multistream-select", "parity-multiaddr", "parity-multihash", @@ -2741,7 +2675,7 @@ checksum = "b99e552f9939b606eb4b59f7f64d9b01e3f96752f47e350fc3c5fc646ed3f649" dependencies = [ "futures 0.3.4", "libp2p-core", - "log 0.4.8", + "log", ] [[package]] @@ -2775,7 +2709,7 @@ dependencies = [ "futures_codec", "libp2p-core", "libp2p-swarm", - "log 0.4.8", + "log", "lru", "prost", "prost-build", @@ -2795,7 +2729,7 @@ dependencies = [ "futures 0.3.4", "libp2p-core", "libp2p-swarm", - "log 0.4.8", + "log", "prost", "prost-build", "smallvec 1.2.0", @@ -2816,7 +2750,7 @@ dependencies = [ "futures_codec", "libp2p-core", "libp2p-swarm", - "log 0.4.8", + "log", "parity-multihash", "prost", "prost-build", @@ -2843,7 +2777,7 @@ dependencies = [ "lazy_static", "libp2p-core", "libp2p-swarm", - "log 0.4.8", + "log", "net2", "rand 0.7.3", "smallvec 1.2.0", @@ -2862,7 +2796,7 @@ dependencies = [ "futures 0.3.4", "futures_codec", "libp2p-core", - "log 0.4.8", + "log", "parking_lot 0.10.0", "unsigned-varint", ] @@ -2877,7 +2811,7 @@ dependencies = [ "futures 0.3.4", "lazy_static", "libp2p-core", - "log 0.4.8", + "log", "prost", "prost-build", "rand 0.7.3", @@ -2897,7 +2831,7 @@ dependencies = [ "futures 0.3.4", "libp2p-core", "libp2p-swarm", - "log 0.4.8", + "log", "rand 0.7.3", "void", "wasm-timer", @@ -2913,7 +2847,7 @@ dependencies = [ "futures 0.3.4", "futures_codec", "libp2p-core", - "log 0.4.8", + "log", "prost", "prost-build", "rw-stream-sink", @@ -2928,7 +2862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b916938a8868f75180aeeffcc6a516a922d165e8fa2a90b57bad989d1ccbb57a" dependencies = [ "futures 0.3.4", - "log 0.4.8", + "log", "pin-project", "rand 0.7.3", "salsa20", @@ -2948,7 +2882,7 @@ dependencies = [ "js-sys", "lazy_static", "libp2p-core", - "log 0.4.8", + "log", "parity-send-wrapper", "pin-project", "prost", @@ -2973,7 +2907,7 @@ checksum = "275471e7c0e88ae004660866cd54f603bd8bd1f4caef541a27f50dd8640c4d4c" dependencies = [ "futures 0.3.4", "libp2p-core", - "log 0.4.8", + "log", "smallvec 1.2.0", "void", "wasm-timer", @@ -2991,7 +2925,7 @@ dependencies = [ "get_if_addrs", "ipnet", "libp2p-core", - "log 0.4.8", + "log", ] [[package]] @@ -3003,7 +2937,7 @@ dependencies = [ "async-std", "futures 0.3.4", "libp2p-core", - "log 0.4.8", + "log", ] [[package]] @@ -3031,7 +2965,7 @@ dependencies = [ "either", "futures 0.3.4", "libp2p-core", - "log 0.4.8", + "log", "quicksink", "rustls 0.16.0", "rw-stream-sink", @@ -3138,15 +3072,6 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -dependencies = [ - "log 0.4.8", -] - [[package]] name = "log" version = "0.4.8" @@ -3250,15 +3175,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "mime" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -dependencies = [ - "log 0.3.9", -] - [[package]] name = "miniz_oxide" version = "0.3.6" @@ -3280,7 +3196,7 @@ dependencies = [ "iovec", "kernel32-sys", "libc", - "log 0.4.8", + "log", "miow", "net2", "slab", @@ -3294,7 +3210,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" dependencies = [ "lazycell", - "log 0.4.8", + "log", "mio", "slab", ] @@ -3342,7 +3258,7 @@ checksum = "f938ffe420493e77c8b6cbcc3f282283f68fc889c5dcbc8e51668d5f3a01ad94" dependencies = [ "bytes 0.5.4", "futures 0.1.29", - "log 0.4.8", + "log", "smallvec 1.2.0", "tokio-io", "unsigned-varint", @@ -3374,24 +3290,6 @@ dependencies = [ "rand 0.3.23", ] -[[package]] -name = "native-tls" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d" -dependencies = [ - "lazy_static", - "libc", - "log 0.4.8", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "net2" version = "0.2.33" @@ -3427,7 +3325,7 @@ dependencies = [ "futures 0.3.4", "hex-literal", "jsonrpc-core", - "log 0.4.8", + "log", "nix", "node-executor", "node-inspect", @@ -3527,7 +3425,7 @@ name = "node-inspect" version = "0.8.0-alpha.5" dependencies = [ "derive_more", - "log 0.4.8", + "log", "parity-scale-codec", "sc-cli", "sc-client-api", @@ -3579,7 +3477,7 @@ dependencies = [ "futures 0.1.29", "hyper 0.12.35", "jsonrpc-core-client", - "log 0.4.8", + "log", "node-primitives", "sc-rpc", ] @@ -3651,7 +3549,7 @@ name = "node-template" version = "2.0.0-alpha.5" dependencies = [ "futures 0.3.4", - "log 0.4.8", + "log", "node-template-runtime", "sc-basic-authorship", "sc-cli", @@ -3715,7 +3613,7 @@ dependencies = [ "frame-support", "frame-system", "fs_extra", - "log 0.4.8", + "log", "node-executor", "node-primitives", "node-runtime", @@ -3757,7 +3655,7 @@ dependencies = [ name = "node-transaction-factory" version = "0.8.0-alpha.5" dependencies = [ - "log 0.4.8", + "log", "parity-scale-codec", "sc-block-builder", "sc-cli", @@ -3791,7 +3689,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6" dependencies = [ "memchr", - "version_check 0.9.1", + "version_check", ] [[package]] @@ -3911,39 +3809,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" -[[package]] -name = "openssl" -version = "0.10.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "973293749822d7dd6370d6da1e523b0d1db19f06c459134c658b2a4261378b52" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "lazy_static", - "libc", - "openssl-sys", -] - [[package]] name = "openssl-probe" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -[[package]] -name = "openssl-sys" -version = "0.9.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1024c0a59774200a555087a6da3f253a9095a5f344e353b212ac4c8b8e450986" -dependencies = [ - "autocfg 1.0.0", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "output_vt100" version = "0.1.2" @@ -5045,7 +4916,7 @@ dependencies = [ "proc-macro2", "quote", "syn", - "version_check 0.9.1", + "version_check", ] [[package]] @@ -5058,7 +4929,7 @@ dependencies = [ "quote", "syn", "syn-mid", - "version_check 0.9.1", + "version_check", ] [[package]] @@ -5115,7 +4986,7 @@ dependencies = [ "bytes 0.5.4", "heck", "itertools", - "log 0.4.8", + "log", "multimap", "petgraph", "prost", @@ -5160,7 +5031,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f7a12f176deee919f4ba55326ee17491c8b707d0987aed822682c821b660192" dependencies = [ "byteorder 1.3.4", - "log 0.4.8", + "log", "parity-wasm 0.41.0", ] @@ -5177,7 +5048,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" dependencies = [ "env_logger 0.7.1", - "log 0.4.8", + "log", "rand 0.7.3", "rand_core 0.5.1", ] @@ -5607,7 +5478,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e" dependencies = [ "base64 0.10.1", - "log 0.4.8", + "log", "ring", "sct", "webpki", @@ -5620,7 +5491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1" dependencies = [ "base64 0.11.0", - "log 0.4.8", + "log", "ring", "sct", "webpki", @@ -5675,12 +5546,6 @@ dependencies = [ "rustc_version", ] -[[package]] -name = "safemem" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" - [[package]] name = "salsa20" version = "0.3.0" @@ -5720,7 +5585,7 @@ dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", "libp2p", - "log 0.4.8", + "log", "parity-scale-codec", "prost", "prost-build", @@ -5746,7 +5611,7 @@ version = "0.8.0-alpha.5" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", - "log 0.4.8", + "log", "parity-scale-codec", "parking_lot 0.10.0", "sc-block-builder", @@ -5819,7 +5684,7 @@ dependencies = [ "fdlimit", "futures 0.3.4", "lazy_static", - "log 0.4.8", + "log", "names", "nix", "parity-util-mem", @@ -5857,7 +5722,7 @@ dependencies = [ "hex-literal", "kvdb", "kvdb-memorydb", - "log 0.4.8", + "log", "parity-scale-codec", "parking_lot 0.10.0", "sc-block-builder", @@ -5893,7 +5758,7 @@ dependencies = [ "hash-db", "hex-literal", "kvdb", - "log 0.4.8", + "log", "parity-scale-codec", "parking_lot 0.10.0", "sc-executor", @@ -5925,7 +5790,7 @@ dependencies = [ "kvdb-memorydb", "kvdb-rocksdb", "linked-hash-map", - "log 0.4.8", + "log", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.0", @@ -5955,7 +5820,7 @@ dependencies = [ "env_logger 0.7.1", "futures 0.3.4", "futures-timer 3.0.2", - "log 0.4.8", + "log", "parity-scale-codec", "parking_lot 0.10.0", "sc-block-builder", @@ -5994,7 +5859,7 @@ dependencies = [ "fork-tree", "futures 0.3.4", "futures-timer 3.0.2", - "log 0.4.8", + "log", "merlin", "num-bigint", "num-rational", @@ -6083,7 +5948,7 @@ dependencies = [ "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", - "log 0.4.8", + "log", "parking_lot 0.10.0", "sc-basic-authorship", "sc-client", @@ -6107,7 +5972,7 @@ version = "0.8.0-alpha.5" dependencies = [ "derive_more", "futures 0.3.4", - "log 0.4.8", + "log", "parity-scale-codec", "sc-client-api", "sp-api", @@ -6127,7 +5992,7 @@ version = "0.8.0-alpha.5" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", - "log 0.4.8", + "log", "parity-scale-codec", "parking_lot 0.10.0", "sc-client-api", @@ -6146,7 +6011,7 @@ dependencies = [ name = "sc-consensus-uncles" version = "0.8.0-alpha.5" dependencies = [ - "log 0.4.8", + "log", "sc-client-api", "sp-authorship", "sp-consensus", @@ -6164,7 +6029,7 @@ dependencies = [ "hex-literal", "lazy_static", "libsecp256k1", - "log 0.4.8", + "log", "parity-scale-codec", "parity-wasm 0.41.0", "parking_lot 0.10.0", @@ -6194,7 +6059,7 @@ name = "sc-executor-common" version = "0.8.0-alpha.5" dependencies = [ "derive_more", - "log 0.4.8", + "log", "parity-scale-codec", "sp-allocator", "sp-core", @@ -6208,7 +6073,7 @@ dependencies = [ name = "sc-executor-wasmi" version = "0.8.0-alpha.5" dependencies = [ - "log 0.4.8", + "log", "parity-scale-codec", "parity-wasm 0.41.0", "sc-executor-common", @@ -6224,7 +6089,7 @@ name = "sc-executor-wasmtime" version = "0.8.0-alpha.5" dependencies = [ "assert_matches", - "log 0.4.8", + "log", "parity-scale-codec", "parity-wasm 0.41.0", "sc-executor-common", @@ -6246,7 +6111,7 @@ dependencies = [ "fork-tree", "futures 0.3.4", "futures-timer 3.0.2", - "log 0.4.8", + "log", "parity-scale-codec", "parking_lot 0.10.0", "pin-project", @@ -6284,7 +6149,7 @@ version = "0.8.0-alpha.5" dependencies = [ "ansi_term 0.12.1", "futures 0.3.4", - "log 0.4.8", + "log", "parity-util-mem", "sc-client-api", "sc-network", @@ -6330,7 +6195,7 @@ dependencies = [ "libp2p", "linked-hash-map", "linked_hash_set", - "log 0.4.8", + "log", "lru", "nohash-hasher", "parity-scale-codec", @@ -6375,7 +6240,7 @@ dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", "libp2p", - "log 0.4.8", + "log", "lru", "sc-network", "sp-runtime", @@ -6391,7 +6256,7 @@ dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", "libp2p", - "log 0.4.8", + "log", "parking_lot 0.10.0", "rand 0.7.3", "sc-block-builder", @@ -6420,7 +6285,7 @@ dependencies = [ "futures-timer 3.0.2", "hyper 0.13.4", "hyper-rustls", - "log 0.4.8", + "log", "num_cpus", "parity-scale-codec", "parking_lot 0.10.0", @@ -6446,7 +6311,7 @@ version = "2.0.0-alpha.5" dependencies = [ "futures 0.3.4", "libp2p", - "log 0.4.8", + "log", "rand 0.7.3", "serde_json", "wasm-timer", @@ -6462,7 +6327,7 @@ dependencies = [ "hash-db", "jsonrpc-core", "jsonrpc-pubsub", - "log 0.4.8", + "log", "parity-scale-codec", "parking_lot 0.10.0", "sc-block-builder", @@ -6499,7 +6364,7 @@ dependencies = [ "jsonrpc-core-client", "jsonrpc-derive", "jsonrpc-pubsub", - "log 0.4.8", + "log", "parity-scale-codec", "parking_lot 0.10.0", "serde", @@ -6519,7 +6384,7 @@ dependencies = [ "jsonrpc-http-server", "jsonrpc-pubsub", "jsonrpc-ws-server", - "log 0.4.8", + "log", "serde", "serde_json", "sp-runtime", @@ -6549,7 +6414,7 @@ dependencies = [ "futures-diagnose", "futures-timer 3.0.2", "lazy_static", - "log 0.4.8", + "log", "parity-multiaddr", "parity-scale-codec", "parity-util-mem", @@ -6598,7 +6463,7 @@ dependencies = [ "fdlimit", "futures 0.1.29", "futures 0.3.4", - "log 0.4.8", + "log", "sc-client", "sc-network", "sc-service", @@ -6615,7 +6480,7 @@ name = "sc-state-db" version = "0.8.0-alpha.5" dependencies = [ "env_logger 0.7.1", - "log 0.4.8", + "log", "parity-scale-codec", "parity-util-mem", "parity-util-mem-derive", @@ -6632,7 +6497,7 @@ dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", "libp2p", - "log 0.4.8", + "log", "parking_lot 0.10.0", "pin-project", "rand 0.7.3", @@ -6650,7 +6515,7 @@ name = "sc-tracing" version = "2.0.0-alpha.5" dependencies = [ "erased-serde", - "log 0.4.8", + "log", "parking_lot 0.10.0", "sc-telemetry", "serde", @@ -6669,7 +6534,7 @@ dependencies = [ "derive_more", "futures 0.3.4", "linked-hash-map", - "log 0.4.8", + "log", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.0", @@ -6692,7 +6557,7 @@ dependencies = [ "futures-diagnose", "hex", "intervalier", - "log 0.4.8", + "log", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.0", @@ -7040,7 +6905,7 @@ dependencies = [ "futures 0.3.4", "http 0.2.1", "httparse", - "log 0.4.8", + "log", "rand 0.7.3", "sha1", "smallvec 1.2.0", @@ -7053,7 +6918,7 @@ name = "sp-allocator" version = "2.0.0-alpha.5" dependencies = [ "derive_more", - "log 0.4.8", + "log", "sp-core", "sp-std", "sp-wasm-interface", @@ -7189,7 +7054,7 @@ name = "sp-blockchain" version = "2.0.0-alpha.5" dependencies = [ "derive_more", - "log 0.4.8", + "log", "lru", "parity-scale-codec", "parking_lot 0.10.0", @@ -7208,7 +7073,7 @@ dependencies = [ "futures-diagnose", "futures-timer 3.0.2", "libp2p", - "log 0.4.8", + "log", "parity-scale-codec", "parking_lot 0.10.0", "serde", @@ -7288,7 +7153,7 @@ dependencies = [ "impl-serde 0.3.0", "lazy_static", "libsecp256k1", - "log 0.4.8", + "log", "num-traits", "parity-scale-codec", "parity-util-mem", @@ -7371,7 +7236,7 @@ version = "2.0.0-alpha.5" dependencies = [ "hash-db", "libsecp256k1", - "log 0.4.8", + "log", "parity-scale-codec", "sp-core", "sp-externalities", @@ -7405,7 +7270,7 @@ name = "sp-panic-handler" version = "2.0.0-alpha.5" dependencies = [ "backtrace", - "log 0.4.8", + "log", ] [[package]] @@ -7447,7 +7312,7 @@ version = "2.0.0-alpha.5" dependencies = [ "hash256-std-hasher", "impl-trait-for-tuples", - "log 0.4.8", + "log", "parity-scale-codec", "parity-util-mem", "paste", @@ -7574,7 +7439,7 @@ version = "0.8.0-alpha.5" dependencies = [ "hash-db", "hex-literal", - "log 0.4.8", + "log", "num-traits", "parity-scale-codec", "parking_lot 0.10.0", @@ -7633,7 +7498,7 @@ version = "2.0.0-alpha.5" dependencies = [ "derive_more", "futures 0.3.4", - "log 0.4.8", + "log", "parity-scale-codec", "serde", "sp-api", @@ -7839,7 +7704,7 @@ dependencies = [ "js-sys", "kvdb-web", "libp2p-wasm-ext", - "log 0.4.8", + "log", "rand 0.6.5", "rand 0.7.3", "sc-chain-spec", @@ -7880,7 +7745,7 @@ dependencies = [ "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", - "log 0.4.8", + "log", "parity-scale-codec", "sc-client", "sc-transaction-pool", @@ -7901,7 +7766,7 @@ dependencies = [ "derive_more", "futures-util", "hyper 0.13.4", - "log 0.4.8", + "log", "prometheus", "tokio 0.2.13", ] @@ -7934,7 +7799,7 @@ dependencies = [ "frame-support", "frame-system", "frame-system-rpc-runtime-api", - "log 0.4.8", + "log", "memory-db", "pallet-babe", "pallet-timestamp", @@ -8203,7 +8068,7 @@ dependencies = [ "proc-macro2", "quote", "syn", - "version_check 0.9.1", + "version_check", ] [[package]] @@ -8427,7 +8292,7 @@ checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" dependencies = [ "bytes 0.4.12", "futures 0.1.29", - "log 0.4.8", + "log", ] [[package]] @@ -8450,7 +8315,7 @@ dependencies = [ "crossbeam-utils", "futures 0.1.29", "lazy_static", - "log 0.4.8", + "log", "mio", "num_cpus", "parking_lot 0.9.0", @@ -8518,7 +8383,7 @@ dependencies = [ "crossbeam-utils", "futures 0.1.29", "lazy_static", - "log 0.4.8", + "log", "num_cpus", "slab", "tokio-executor 0.1.10", @@ -8536,17 +8401,6 @@ dependencies = [ "tokio-executor 0.1.10", ] -[[package]] -name = "tokio-tls" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c" -dependencies = [ - "futures 0.1.29", - "native-tls", - "tokio-io", -] - [[package]] name = "tokio-udp" version = "0.1.6" @@ -8555,7 +8409,7 @@ checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82" dependencies = [ "bytes 0.4.12", "futures 0.1.29", - "log 0.4.8", + "log", "mio", "tokio-codec", "tokio-io", @@ -8572,7 +8426,7 @@ dependencies = [ "futures 0.1.29", "iovec", "libc", - "log 0.4.8", + "log", "mio", "mio-uds", "tokio-codec", @@ -8589,7 +8443,7 @@ dependencies = [ "bytes 0.5.4", "futures-core", "futures-sink", - "log 0.4.8", + "log", "pin-project-lite", "tokio 0.2.13", ] @@ -8639,12 +8493,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "traitobject" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" - [[package]] name = "treeline" version = "0.1.0" @@ -8675,7 +8523,7 @@ checksum = "de9222c50cc325855621271157c973da27a0dcd26fa06f8edf81020bd2333df0" dependencies = [ "hash-db", "hashbrown", - "log 0.4.8", + "log", "rustc-hex", "smallvec 1.2.0", ] @@ -8736,15 +8584,9 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" dependencies = [ - "rand 0.7.3", + "rand 0.3.23", ] -[[package]] -name = "typeable" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" - [[package]] name = "typenum" version = "1.11.2" @@ -8763,22 +8605,13 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "unicase" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -dependencies = [ - "version_check 0.1.5", -] - [[package]] name = "unicase" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" dependencies = [ - "version_check 0.9.1", + "version_check", ] [[package]] @@ -8885,12 +8718,6 @@ dependencies = [ "chrono", ] -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" - [[package]] name = "version_check" version = "0.9.1" @@ -8953,7 +8780,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" dependencies = [ "futures 0.1.29", - "log 0.4.8", + "log", "try-lock", ] @@ -8963,7 +8790,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" dependencies = [ - "log 0.4.8", + "log", "try-lock", ] @@ -8991,7 +8818,7 @@ checksum = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd" dependencies = [ "bumpalo", "lazy_static", - "log 0.4.8", + "log", "proc-macro2", "quote", "syn", @@ -9045,7 +8872,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0c32691b6c7e6c14e7f8fd55361a9088b507aa49620fcd06c09b3a1082186b9" dependencies = [ - "log 0.4.8", + "log", "parity-wasm 0.32.0", "rustc-demangle", ] @@ -9129,7 +8956,7 @@ dependencies = [ "file-per-thread-logger", "indexmap", "libc", - "log 0.4.8", + "log", "more-asserts", "rayon", "serde", @@ -9213,47 +9040,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "websocket" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413b37840b9e27b340ce91b319ede10731de8c72f5bc4cb0206ec1ca4ce581d0" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.29", - "hyper 0.10.16", - "native-tls", - "rand 0.6.5", - "tokio-codec", - "tokio-io", - "tokio-reactor", - "tokio-tcp", - "tokio-tls", - "unicase 1.4.2", - "url 1.7.2", - "websocket-base", -] - -[[package]] -name = "websocket-base" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e3810f0d00c4dccb54c30a4eee815e703232819dec7b007db115791c42aa374" -dependencies = [ - "base64 0.10.1", - "bitflags", - "byteorder 1.3.4", - "bytes 0.4.12", - "futures 0.1.29", - "native-tls", - "rand 0.6.5", - "sha1", - "tokio-codec", - "tokio-io", - "tokio-tcp", - "tokio-tls", -] - [[package]] name = "which" version = "3.1.1" @@ -9315,7 +9101,7 @@ dependencies = [ "byteorder 1.3.4", "bytes 0.4.12", "httparse", - "log 0.4.8", + "log", "mio", "mio-extras", "rand 0.7.3", @@ -9358,7 +9144,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84300bb493cc878f3638b981c62b4632ec1a5c52daaa3036651e8c106d3b55ea" dependencies = [ "futures 0.3.4", - "log 0.4.8", + "log", "nohash-hasher", "parking_lot 0.10.0", "rand 0.7.3", diff --git a/bin/node/rpc-client/Cargo.toml b/bin/node/rpc-client/Cargo.toml index 07ddbb4d80..df095bc5bb 100644 --- a/bin/node/rpc-client/Cargo.toml +++ b/bin/node/rpc-client/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/paritytech/substrate/" env_logger = "0.7.0" futures = "0.1.29" hyper = "0.12.35" -jsonrpc-core-client = { version = "14.0.3", features = ["http", "ws"] } +jsonrpc-core-client = { version = "14.0.5", default-features = false, features = ["http"] } log = "0.4.8" node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } sc-rpc = { version = "2.0.0-alpha.5", path = "../../../client/rpc" } diff --git a/client/consensus/babe/rpc/Cargo.toml b/client/consensus/babe/rpc/Cargo.toml index feedb84fd5..6bdaeb5ddf 100644 --- a/client/consensus/babe/rpc/Cargo.toml +++ b/client/consensus/babe/rpc/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/paritytech/substrate/" [dependencies] sc-consensus-babe = { version = "0.8.0-alpha.5", path = "../" } jsonrpc-core = "14.0.3" -jsonrpc-core-client = "14.0.3" +jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.3" sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../../../primitives/consensus/babe" } serde = { version = "1.0.104", features=["derive"] } diff --git a/client/rpc-api/Cargo.toml b/client/rpc-api/Cargo.toml index 03eed69f38..c5043b5b07 100644 --- a/client/rpc-api/Cargo.toml +++ b/client/rpc-api/Cargo.toml @@ -13,7 +13,7 @@ codec = { package = "parity-scale-codec", version = "1.3.0" } derive_more = "0.99.2" futures = { version = "0.3.1", features = ["compat"] } jsonrpc-core = "14.0.3" -jsonrpc-core-client = "14.0.3" +jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.3" jsonrpc-pubsub = "14.0.3" log = "0.4.8" diff --git a/frame/contracts/rpc/Cargo.toml b/frame/contracts/rpc/Cargo.toml index 4414107f2c..fa13d8ec3f 100644 --- a/frame/contracts/rpc/Cargo.toml +++ b/frame/contracts/rpc/Cargo.toml @@ -11,7 +11,7 @@ description = "Node-specific RPC methods for interaction with contracts." [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0" } jsonrpc-core = "14.0.3" -jsonrpc-core-client = "14.0.3" +jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.3" sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } diff --git a/frame/transaction-payment/rpc/Cargo.toml b/frame/transaction-payment/rpc/Cargo.toml index 3dec060fb4..cd74829b29 100644 --- a/frame/transaction-payment/rpc/Cargo.toml +++ b/frame/transaction-payment/rpc/Cargo.toml @@ -11,7 +11,7 @@ description = "RPC interface for the transaction payment module." [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0" } jsonrpc-core = "14.0.3" -jsonrpc-core-client = "14.0.3" +jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.3" sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } sp-rpc = { version = "2.0.0-alpha.5", path = "../../../primitives/rpc" } diff --git a/utils/frame/rpc/support/Cargo.toml b/utils/frame/rpc/support/Cargo.toml index 002fc1dd7a..72884330d2 100644 --- a/utils/frame/rpc/support/Cargo.toml +++ b/utils/frame/rpc/support/Cargo.toml @@ -10,7 +10,7 @@ description = "Substrate RPC for FRAME's support" [dependencies] futures = { version = "0.3.0", features = ["compat"] } -jsonrpc-client-transports = "14" +jsonrpc-client-transports = { version = "14.0.5", default-features = false, features = ["http"] } jsonrpc-core = "14" codec = { package = "parity-scale-codec", version = "1" } serde = "1" diff --git a/utils/frame/rpc/system/Cargo.toml b/utils/frame/rpc/system/Cargo.toml index 8df958736b..a9e775393d 100644 --- a/utils/frame/rpc/system/Cargo.toml +++ b/utils/frame/rpc/system/Cargo.toml @@ -13,7 +13,7 @@ sc-client = { version = "0.8.0-alpha.5", path = "../../../../client/" } codec = { package = "parity-scale-codec", version = "1.3.0" } futures = "0.3.4" jsonrpc-core = "14.0.3" -jsonrpc-core-client = "14.0.3" +jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.3" log = "0.4.8" serde = { version = "1.0.101", features = ["derive"] } -- GitLab From 176b19f8ed7bd98c27b40a6f92f6cd8cf48f9988 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Wed, 1 Apr 2020 14:08:23 +0200 Subject: [PATCH 127/300] Reset benchmarks by removing post-genesis changes (#5435) * Reset by removing pos-genesis changes * CLI option for DB cache size * Update Cargo.lock Co-authored-by: Shawn Tabrizi --- Cargo.lock | 10 +++--- client/db/src/bench.rs | 42 ++++++++++++++++++++----- client/service/src/lib.rs | 2 +- utils/frame/benchmarking-cli/src/lib.rs | 7 ++++- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4e16401288..36ce03e613 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -603,9 +603,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "0.29.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92986241798376849e1a007827041fed9bb36195822c2049d18e174420e0534" +checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a" dependencies = [ "glob 0.3.0", "libc", @@ -4934,9 +4934,9 @@ dependencies = [ [[package]] name = "proc-macro-hack" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcfdefadc3d57ca21cf17990a28ef4c0f7c61383a28cb7604cf4a18e6ede1420" +checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" [[package]] name = "proc-macro-nested" @@ -8584,7 +8584,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" dependencies = [ - "rand 0.3.23", + "rand 0.7.3", ] [[package]] diff --git a/client/db/src/bench.rs b/client/db/src/bench.rs index 05ec51f1c8..f90e85c2bf 100644 --- a/client/db/src/bench.rs +++ b/client/db/src/bench.rs @@ -19,6 +19,7 @@ use std::sync::Arc; use std::path::PathBuf; use std::cell::{Cell, RefCell}; +use std::collections::HashMap; use rand::Rng; use hash_db::{Prefix, Hasher}; @@ -54,12 +55,14 @@ pub struct BenchmarkingState { genesis_root: B::Hash, state: RefCell>>, db: Cell>>, - genesis: as StateBackend>>::Transaction, + genesis: HashMap, (Vec, i32)>, + record: Cell>>, + cache_size_mb: Option, } impl BenchmarkingState { /// Create a new instance that creates a database in a temporary dir. - pub fn new(genesis: Storage) -> Result { + pub fn new(genesis: Storage, cache_size_mb: Option) -> Result { let temp_dir = PathBuf::from(std::env::temp_dir()); let name: String = rand::thread_rng().sample_iter(&rand::distributions::Alphanumeric).take(10).collect(); let path = temp_dir.join(&name); @@ -76,6 +79,8 @@ impl BenchmarkingState { root: Cell::new(root), genesis: Default::default(), genesis_root: Default::default(), + record: Default::default(), + cache_size_mb, }; state.reopen()?; @@ -88,7 +93,7 @@ impl BenchmarkingState { genesis.top.into_iter().map(|(k, v)| (k, Some(v))), child_delta, ); - state.genesis = transaction.clone(); + state.genesis = transaction.clone().drain(); state.genesis_root = root.clone(); state.commit(root, transaction)?; Ok(state) @@ -97,7 +102,10 @@ impl BenchmarkingState { fn reopen(&self) -> Result<(), String> { *self.state.borrow_mut() = None; self.db.set(None); - let db_config = DatabaseConfig::with_columns(1); + let mut db_config = DatabaseConfig::with_columns(1); + if let Some(size) = &self.cache_size_mb { + db_config.memory_budget.insert(0, *size); + } let path = self.path.to_str() .ok_or_else(|| String::from("Invalid database path"))?; let db = Arc::new(Database::open(&db_config, &path).map_err(|e| format!("Error opening database: {:?}", e))?); @@ -257,14 +265,17 @@ impl StateBackend> for BenchmarkingState { { if let Some(db) = self.db.take() { let mut db_transaction = DBTransaction::new(); - - for (key, (val, rc)) in transaction.drain() { + let changes = transaction.drain(); + let mut keys = Vec::with_capacity(changes.len()); + for (key, (val, rc)) in changes { if rc > 0 { db_transaction.put(0, &key, &val); } else if rc < 0 { db_transaction.delete(0, &key); } + keys.push(key); } + self.record.set(keys); db.write(db_transaction).map_err(|_| String::from("Error committing transaction"))?; self.root.set(storage_root); } else { @@ -274,9 +285,24 @@ impl StateBackend> for BenchmarkingState { } fn wipe(&self) -> Result<(), Self::Error> { - self.kill()?; + // Restore to genesis + let record = self.record.take(); + if let Some(db) = self.db.take() { + let mut db_transaction = DBTransaction::new(); + for key in record { + match self.genesis.get(&key) { + Some((v, _)) => db_transaction.put(0, &key, v), + None => db_transaction.delete(0, &key), + } + } + db.write(db_transaction).map_err(|_| String::from("Error committing transaction"))?; + } + + self.db.set(None); + *self.state.borrow_mut() = None; + + self.root.set(self.genesis_root.clone()); self.reopen()?; - self.commit(self.genesis_root.clone(), self.genesis.clone())?; Ok(()) } } diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 3a071893d5..7bcddd7ad7 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -58,7 +58,7 @@ pub use self::builder::{ ServiceBuilder, ServiceBuilderCommand, TFullClient, TLightClient, TFullBackend, TLightBackend, TFullCallExecutor, TLightCallExecutor, }; -pub use config::{Configuration, Roles, PruningMode}; +pub use config::{Configuration, Roles, PruningMode, DatabaseConfig}; pub use sc_chain_spec::{ ChainSpec, GenericChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension }; diff --git a/utils/frame/benchmarking-cli/src/lib.rs b/utils/frame/benchmarking-cli/src/lib.rs index f9851810bf..926d140e02 100644 --- a/utils/frame/benchmarking-cli/src/lib.rs +++ b/utils/frame/benchmarking-cli/src/lib.rs @@ -91,6 +91,10 @@ pub struct BenchmarkCmd { default_value = "Interpreted" )] pub wasm_method: WasmExecutionMethod, + + /// Limit the memory the database cache can use. + #[structopt(long = "db-cache", value_name = "MiB", default_value = "128")] + pub database_cache_size: u32, } impl BenchmarkCmd { @@ -116,7 +120,8 @@ impl BenchmarkCmd { let genesis_storage = spec.build_storage()?; let mut changes = Default::default(); - let state = BenchmarkingState::::new(genesis_storage)?; + let cache_size = Some(self.database_cache_size as usize); + let state = BenchmarkingState::::new(genesis_storage, cache_size)?; let executor = NativeExecutor::::new( wasm_method, None, // heap pages -- GitLab From 2449d21ca2998325b95671236dd9911c3534718d Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Wed, 1 Apr 2020 15:52:39 +0200 Subject: [PATCH 128/300] Introduce scheduler and use it for the democracy dispatch queue (#5412) * Initial draft of the logic * Build and tests * Make work with new initialize infratructure. * Update frame/scheduler/src/lib.rs Co-Authored-By: Marcio Diaz * Update frame/scheduler/src/lib.rs Co-Authored-By: Marcio Diaz * Update frame/scheduler/src/lib.rs Co-Authored-By: Marcio Diaz * Update frame/scheduler/src/lib.rs Co-Authored-By: Marcio Diaz * Fix test * Update frame/scheduler/src/lib.rs Co-Authored-By: Marcio Diaz * Rejig interface to make it more useful for democracy. * Try to get democraxy module to make use of scheduler. * Make democracy use scheduler. * Use actual max weight for enactent * Remove TODO * Fix runtime build * Minor cleanup * Fix scheduler. * Fix benchmarks * Fix * Fix * Fix * More bench fixes * Fix * Fix. * Add more bench constants. * Fix cancel_queued bench. * Fix test comment. * Update frame/scheduler/src/lib.rs Co-Authored-By: Marcio Diaz Co-authored-by: Marcio Diaz --- Cargo.lock | 18 + Cargo.toml | 1 + bin/node/cli/Cargo.toml | 2 +- bin/node/runtime/Cargo.toml | 3 +- bin/node/runtime/src/lib.rs | 14 + frame/democracy/Cargo.toml | 1 + frame/democracy/src/benchmarking.rs | 74 ++-- frame/democracy/src/lib.rs | 176 +++++--- frame/democracy/src/tests.rs | 14 +- frame/democracy/src/tests/cancellation.rs | 6 +- frame/democracy/src/tests/preimage.rs | 1 - frame/democracy/src/tests/voting.rs | 4 +- frame/elections-phragmen/Cargo.toml | 1 + frame/scheduler/Cargo.toml | 35 ++ frame/scheduler/src/lib.rs | 518 ++++++++++++++++++++++ frame/support/src/traits.rs | 80 +++- 16 files changed, 826 insertions(+), 122 deletions(-) create mode 100644 frame/scheduler/Cargo.toml create mode 100644 frame/scheduler/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 36ce03e613..77852437f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3512,6 +3512,7 @@ dependencies = [ "pallet-offences", "pallet-randomness-collective-flip", "pallet-recovery", + "pallet-scheduler", "pallet-session", "pallet-session-benchmarking", "pallet-society", @@ -4044,6 +4045,7 @@ dependencies = [ "frame-system", "hex-literal", "pallet-balances", + "pallet-scheduler", "parity-scale-codec", "serde", "sp-core", @@ -4077,6 +4079,7 @@ dependencies = [ "frame-system", "hex-literal", "pallet-balances", + "pallet-scheduler", "parity-scale-codec", "serde", "sp-core", @@ -4314,6 +4317,21 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-scheduler" +version = "2.0.0-alpha.5" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-scored-pool" version = "2.0.0-alpha.5" diff --git a/Cargo.toml b/Cargo.toml index 39a6ff1f2d..9b30bfd39e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,6 +86,7 @@ members = [ "frame/offences", "frame/randomness-collective-flip", "frame/recovery", + "frame/scheduler", "frame/scored-pool", "frame/session", "frame/session/benchmarking", diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index 804a74b8c4..c477471166 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -16,7 +16,7 @@ repository = "https://github.com/paritytech/substrate/" wasm-opt = false [badges] -travis-ci = { repository = "paritytech/substrate", branch = "master" } +travis-ci = { repository = "paritytech/substrate" } maintenance = { status = "actively-developed" } is-it-maintained-issue-resolution = { repository = "paritytech/substrate" } is-it-maintained-open-issues = { repository = "paritytech/substrate" } diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 07d3b8beda..67e50e53f6 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -61,8 +61,9 @@ pallet-session = { version = "2.0.0-alpha.5", features = ["historical"], path = pallet-session-benchmarking = { version = "2.0.0-alpha.5", path = "../../../frame/session/benchmarking", default-features = false, optional = true } pallet-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/staking" } pallet-staking-reward-curve = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/staking/reward-curve" } -pallet-sudo = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/sudo" } +pallet-scheduler = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/scheduler" } pallet-society = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/society" } +pallet-sudo = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/sudo" } pallet-timestamp = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/timestamp" } pallet-treasury = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/treasury" } pallet-utility = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/utility" } diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 881807ea24..309f4ed024 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -207,6 +207,17 @@ impl pallet_utility::Trait for Runtime { type MaxSignatories = MaxSignatories; } +parameter_types! { + pub const MaximumWeight: Weight = 2_000_000; +} + +impl pallet_scheduler::Trait for Runtime { + type Event = Event; + type Origin = Origin; + type Call = Call; + type MaximumWeight = MaximumWeight; +} + parameter_types! { pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS; pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; @@ -262,6 +273,7 @@ impl pallet_transaction_payment::Trait for Runtime { parameter_types! { pub const MinimumPeriod: Moment = SLOT_DURATION / 2; } + impl pallet_timestamp::Trait for Runtime { type Moment = Moment; type OnTimestampSet = Babe; @@ -392,6 +404,7 @@ impl pallet_democracy::Trait for Runtime { type CooloffPeriod = CooloffPeriod; type PreimageByteDeposit = PreimageByteDeposit; type Slash = Treasury; + type Scheduler = Scheduler; } parameter_types! { @@ -670,6 +683,7 @@ construct_runtime!( Society: pallet_society::{Module, Call, Storage, Event, Config}, Recovery: pallet_recovery::{Module, Call, Storage, Event}, Vesting: pallet_vesting::{Module, Call, Storage, Event, Config}, + Scheduler: pallet_scheduler::{Module, Call, Storage, Event}, } ); diff --git a/frame/democracy/Cargo.toml b/frame/democracy/Cargo.toml index 888e23e01b..7886457644 100644 --- a/frame/democracy/Cargo.toml +++ b/frame/democracy/Cargo.toml @@ -21,6 +21,7 @@ frame-system = { version = "2.0.0-alpha.5", default-features = false, path = ".. [dev-dependencies] sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +pallet-scheduler = { version = "2.0.0-alpha.5", path = "../scheduler" } sp-storage = { version = "2.0.0-alpha.5", path = "../../primitives/storage" } hex-literal = "0.2.1" diff --git a/frame/democracy/src/benchmarking.rs b/frame/democracy/src/benchmarking.rs index 2429edbefd..a483269c43 100644 --- a/frame/democracy/src/benchmarking.rs +++ b/frame/democracy/src/benchmarking.rs @@ -29,6 +29,9 @@ const SEED: u32 = 0; const MAX_USERS: u32 = 1000; const MAX_REFERENDUMS: u32 = 100; const MAX_PROPOSALS: u32 = 100; +const MAX_SECONDERS: u32 = 100; +const MAX_VETOERS: u32 = 100; +const MAX_BYTES: u32 = 16_384; fn funded_account(name: &'static str, index: u32) -> T::AccountId { let caller: T::AccountId = account(name, index, SEED); @@ -57,6 +60,13 @@ fn add_referendum(n: u32) -> Result { 0.into(), ); let referendum_index: ReferendumIndex = ReferendumCount::get() - 1; + let _ = T::Scheduler::schedule_named( + (DEMOCRACY_ID, referendum_index), + 0.into(), + None, + 63, + Call::enact_proposal(proposal_hash, referendum_index).into(), + ); Ok(referendum_index) } @@ -89,7 +99,7 @@ benchmarks! { let p in 1 .. MAX_PROPOSALS; // Add p proposals - for i in 0..p { + for i in 0 .. p { add_proposal::(i)?; } @@ -99,10 +109,10 @@ benchmarks! { }: _(RawOrigin::Signed(caller), proposal_hash, value.into()) second { - let s in 0 .. 100; + let s in 0 .. MAX_SECONDERS; // Create s existing "seconds" - for i in 0..s { + for i in 0 .. s { let seconder = funded_account::("seconder", i); Democracy::::second(RawOrigin::Signed(seconder).into(), 0)?; } @@ -202,7 +212,7 @@ benchmarks! { veto_external { // Existing veto-ers - let v in 0 .. 100; + let v in 0 .. MAX_VETOERS; let proposal_hash: T::Hash = T::Hashing::hash_of(&v); @@ -210,7 +220,7 @@ benchmarks! { Democracy::::external_propose_default(origin_propose, proposal_hash.clone())?; let mut vetoers: Vec = Vec::new(); - for i in 0..v { + for i in 0 .. v { vetoers.push(account("vetoer", i, SEED)); } Blacklist::::insert(proposal_hash, (T::BlockNumber::zero(), vetoers)); @@ -228,12 +238,9 @@ benchmarks! { }: _(RawOrigin::Root, referendum_index) cancel_queued { - let d in 0 .. 100; + let u in 1 .. MAX_USERS; - let referendum_index = add_referendum::(d)?; - let block_number: T::BlockNumber = 0.into(); - let hash: T::Hash = T::Hashing::hash_of(&d); - >::put(vec![(block_number, hash, referendum_index.clone()); d as usize]); + let referendum_index = add_referendum::(u)?; }: _(RawOrigin::Root, referendum_index) open_proxy { @@ -297,15 +304,17 @@ benchmarks! { }: _(RawOrigin::Signed(delegator)) clear_public_proposals { - let p in 0 .. 100; + let p in 0 .. MAX_PROPOSALS; + for i in 0 .. p { add_proposal::(i)?; } + }: _(RawOrigin::Root) note_preimage { // Num of bytes in encoded proposal - let b in 0 .. 16_384; + let b in 0 .. MAX_BYTES; let caller = funded_account::("caller", b); let encoded_proposal = vec![0; b as usize]; @@ -313,51 +322,32 @@ benchmarks! { note_imminent_preimage { // Num of bytes in encoded proposal - let b in 0 .. 16_384; - // Length of dispatch queue - let d in 0 .. 100; + let b in 0 .. MAX_BYTES; - let mut dispatch_queue = Vec::new(); // d + 1 to include the one we are testing - for i in 0 .. d + 1 { - let encoded_proposal = vec![0; i as usize]; - let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); - let block_number = T::BlockNumber::zero(); - let referendum_index: ReferendumIndex = 0; - dispatch_queue.push((block_number, proposal_hash, referendum_index)) - } - >::put(dispatch_queue); + let encoded_proposal = vec![0; b as usize]; + let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); + let block_number = T::BlockNumber::one(); + Preimages::::insert(&proposal_hash, PreimageStatus::Missing(block_number)); let caller = funded_account::("caller", b); - let encoded_proposal = vec![0; d as usize]; + let encoded_proposal = vec![0; b as usize]; }: _(RawOrigin::Signed(caller), encoded_proposal) reap_preimage { // Num of bytes in encoded proposal - let b in 0 .. 16_384; - // Length of dispatch queue - let d in 0 .. 100; - - let mut dispatch_queue = Vec::new(); - for i in 0 .. d { - let encoded_proposal = vec![0; i as usize]; - let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); - let block_number = T::BlockNumber::zero(); - let referendum_index: ReferendumIndex = 0; - dispatch_queue.push((block_number, proposal_hash, referendum_index)) - } - >::put(dispatch_queue); + let b in 0 .. MAX_BYTES; - let caller = funded_account::("caller", d); - let encoded_proposal = vec![0; d as usize]; + let encoded_proposal = vec![0; b as usize]; + let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); + + let caller = funded_account::("caller", b); Democracy::::note_preimage(RawOrigin::Signed(caller.clone()).into(), encoded_proposal.clone())?; // We need to set this otherwise we get `Early` error. let block_number = T::VotingPeriod::get() + T::EnactmentPeriod::get() + T::BlockNumber::one(); System::::set_block_number(block_number.into()); - let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); - }: _(RawOrigin::Signed(caller), proposal_hash) unlock { diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index 7223b66a4e..5f50ee04da 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -165,15 +165,16 @@ use sp_std::prelude::*; use sp_runtime::{ - DispatchResult, DispatchError, traits::{Zero, EnsureOrigin, Hash, Dispatchable, Saturating}, + DispatchResult, DispatchError, RuntimeDebug, + traits::{Zero, EnsureOrigin, Hash, Dispatchable, Saturating}, }; -use codec::{Ref, Decode}; +use codec::{Ref, Encode, Decode}; use frame_support::{ decl_module, decl_storage, decl_event, decl_error, ensure, Parameter, weights::{SimpleDispatchInfo, Weight, WeighData}, traits::{ Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, - OnUnbalanced, BalanceStatus + OnUnbalanced, BalanceStatus, schedule::Named as ScheduleNamed } }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -206,7 +207,7 @@ type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; pub trait Trait: frame_system::Trait + Sized { - type Proposal: Parameter + Dispatchable; + type Proposal: Parameter + Dispatchable + From>; type Event: From> + Into<::Event>; /// Currency type for this module. @@ -273,6 +274,33 @@ pub trait Trait: frame_system::Trait + Sized { /// Handler for the unbalanced reduction when slashing a preimage deposit. type Slash: OnUnbalanced>; + + /// The Scheduler. + type Scheduler: ScheduleNamed; +} + +#[derive(Clone, Encode, Decode, RuntimeDebug)] +pub enum PreimageStatus { + /// The preimage is imminently needed at the argument. + Missing(BlockNumber), + /// The preimage is available. + Available { + data: Vec, + provider: AccountId, + deposit: Balance, + since: BlockNumber, + /// None if it's not imminent. + expiry: Option, + }, +} + +impl PreimageStatus { + fn to_missing_expiry(self) -> Option { + match self { + PreimageStatus::Missing(expiry) => Some(expiry), + _ => None, + } + } } decl_storage! { @@ -293,7 +321,7 @@ decl_storage! { // https://github.com/paritytech/substrate/issues/5322 pub Preimages: map hasher(identity) T::Hash - => Option<(Vec, T::AccountId, BalanceOf, T::BlockNumber)>; + => Option, T::BlockNumber>>; /// The next free referendum index, aka the number of referenda started so far. pub ReferendumCount get(fn referendum_count) build(|_| 0 as ReferendumIndex): ReferendumIndex; @@ -306,11 +334,6 @@ decl_storage! { map hasher(twox_64_concat) ReferendumIndex => Option>>; - // TODO: Refactor DispatchQueue into its own pallet. - // https://github.com/paritytech/substrate/issues/5322 - /// Queue of successful referenda to be dispatched. Stored ordered by block number. - pub DispatchQueue get(fn dispatch_queue): Vec<(T::BlockNumber, T::Hash, ReferendumIndex)>; - /// All votes for a particular voter. We store the balance for the number of votes that we /// have recorded. The second item is the total amount of delegations, that will be added. pub VotingOf: map hasher(twox_64_concat) T::AccountId => Voting, T::AccountId, T::BlockNumber>; @@ -816,11 +839,8 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedOperational(10_000)] fn cancel_queued(origin, which: ReferendumIndex) { ensure_root(origin)?; - let mut items = >::get(); - let original_len = items.len(); - items.retain(|i| i.2 != which); - ensure!(items.len() < original_len, Error::::ProposalMissing); - >::put(items); + T::Scheduler::cancel_named((DEMOCRACY_ID, which)) + .map_err(|_| Error::::ProposalMissing)?; } fn on_initialize(n: T::BlockNumber) -> Weight { @@ -986,7 +1006,14 @@ decl_module! { T::Currency::reserve(&who, deposit)?; let now = >::block_number(); - >::insert(proposal_hash, (encoded_proposal, who.clone(), deposit, now)); + let a = PreimageStatus::Available { + data: encoded_proposal, + provider: who.clone(), + deposit, + since: now, + expiry: None, + }; + >::insert(proposal_hash, a); Self::deposit_event(RawEvent::PreimageNoted(proposal_hash, who, deposit)); } @@ -1007,13 +1034,19 @@ decl_module! { fn note_imminent_preimage(origin, encoded_proposal: Vec) { let who = ensure_signed(origin)?; let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); - ensure!(!>::contains_key(&proposal_hash), Error::::DuplicatePreimage); - let queue = >::get(); - ensure!(queue.iter().any(|item| &item.1 == &proposal_hash), Error::::NotImminent); + let status = Preimages::::get(&proposal_hash).ok_or(Error::::NotImminent)?; + let expiry = status.to_missing_expiry().ok_or(Error::::DuplicatePreimage)?; let now = >::block_number(); let free = >::zero(); - >::insert(proposal_hash, (encoded_proposal, who.clone(), free, now)); + let a = PreimageStatus::Available { + data: encoded_proposal, + provider: who.clone(), + deposit: Zero::zero(), + since: now, + expiry: Some(expiry), + }; + >::insert(proposal_hash, a); Self::deposit_event(RawEvent::PreimageNoted(proposal_hash, who, free)); } @@ -1036,20 +1069,22 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(10_000)] fn reap_preimage(origin, proposal_hash: T::Hash) { let who = ensure_signed(origin)?; + let (provider, deposit, since, expiry) = >::get(&proposal_hash) + .and_then(|m| match m { + PreimageStatus::Available { provider, deposit, since, expiry, .. } + => Some((provider, deposit, since, expiry)), + _ => None, + }).ok_or(Error::::PreimageMissing)?; - let (_, old, deposit, then) = >::get(&proposal_hash) - .ok_or(Error::::PreimageMissing)?; let now = >::block_number(); let (voting, enactment) = (T::VotingPeriod::get(), T::EnactmentPeriod::get()); - let additional = if who == old { Zero::zero() } else { enactment }; - ensure!(now >= then + voting + additional, Error::::TooEarly); - - let queue = >::get(); - ensure!(!queue.iter().any(|item| &item.1 == &proposal_hash), Error::::Imminent); + let additional = if who == provider { Zero::zero() } else { enactment }; + ensure!(now >= since + voting + additional, Error::::TooEarly); + ensure!(expiry.map_or(true, |e| now > e), Error::::Imminent); - let _ = T::Currency::repatriate_reserved(&old, &who, deposit, BalanceStatus::Free); + let _ = T::Currency::repatriate_reserved(&provider, &who, deposit, BalanceStatus::Free); >::remove(&proposal_hash); - Self::deposit_event(RawEvent::PreimageReaped(proposal_hash, old, deposit, who)); + Self::deposit_event(RawEvent::PreimageReaped(proposal_hash, provider, deposit, who)); } /// Unlock tokens that have an expired lock. @@ -1222,6 +1257,13 @@ decl_module! { let target = Self::proxy(who).and_then(|a| a.as_active()).ok_or(Error::::NotProxy)?; Self::try_remove_vote(&target, index, UnvoteScope::Any) } + + /// Enact a proposal from a referendum. For now we just make the weight be the maximum. + #[weight = SimpleDispatchInfo::MaxNormal] + fn enact_proposal(origin, proposal_hash: T::Hash, index: ReferendumIndex) -> DispatchResult { + ensure_root(origin)?; + Self::do_enact_proposal(proposal_hash, index) + } } } @@ -1544,28 +1586,6 @@ impl Module { ref_index } - /// Enact a proposal from a referendum. - fn enact_proposal(proposal_hash: T::Hash, index: ReferendumIndex) -> DispatchResult { - if let Some((encoded_proposal, who, amount, _)) = >::take(&proposal_hash) { - if let Ok(proposal) = T::Proposal::decode(&mut &encoded_proposal[..]) { - let _ = T::Currency::unreserve(&who, amount); - Self::deposit_event(RawEvent::PreimageUsed(proposal_hash, who, amount)); - - let ok = proposal.dispatch(frame_system::RawOrigin::Root.into()).is_ok(); - Self::deposit_event(RawEvent::Executed(index, ok)); - - Ok(()) - } else { - T::Slash::on_unbalanced(T::Currency::slash_reserved(&who, amount).0); - Self::deposit_event(RawEvent::PreimageInvalid(proposal_hash, index)); - Err(Error::::PreimageInvalid.into()) - } - } else { - Self::deposit_event(RawEvent::PreimageMissing(proposal_hash, index)); - Err(Error::::PreimageMissing.into()) - } - } - /// Table the next waiting proposal for a vote. fn launch_next(now: T::BlockNumber) -> DispatchResult { if LastTabledWasExternal::take() { @@ -1622,6 +1642,28 @@ impl Module { } } + fn do_enact_proposal(proposal_hash: T::Hash, index: ReferendumIndex) -> DispatchResult { + let preimage = >::take(&proposal_hash); + if let Some(PreimageStatus::Available { data, provider, deposit, .. }) = preimage { + if let Ok(proposal) = T::Proposal::decode(&mut &data[..]) { + let _ = T::Currency::unreserve(&provider, deposit); + Self::deposit_event(RawEvent::PreimageUsed(proposal_hash, provider, deposit)); + + let ok = proposal.dispatch(frame_system::RawOrigin::Root.into()).is_ok(); + Self::deposit_event(RawEvent::Executed(index, ok)); + + Ok(()) + } else { + T::Slash::on_unbalanced(T::Currency::slash_reserved(&provider, deposit).0); + Self::deposit_event(RawEvent::PreimageInvalid(proposal_hash, index)); + Err(Error::::PreimageInvalid.into()) + } + } else { + Self::deposit_event(RawEvent::PreimageMissing(proposal_hash, index)); + Err(Error::::PreimageMissing.into()) + } + } + fn bake_referendum( now: T::BlockNumber, index: ReferendumIndex, @@ -1633,13 +1675,24 @@ impl Module { if approved { Self::deposit_event(RawEvent::Passed(index)); if status.delay.is_zero() { - let _ = Self::enact_proposal(status.proposal_hash, index); + let _ = Self::do_enact_proposal(status.proposal_hash, index); } else { - let item = (now + status.delay, status.proposal_hash, index); - >::mutate(|queue| { - let pos = queue.binary_search_by_key(&item.0, |x| x.0).unwrap_or_else(|e| e); - queue.insert(pos, item); + let when = now + status.delay; + // Note that we need the preimage now. + Preimages::::mutate_exists(&status.proposal_hash, |maybe_pre| match *maybe_pre { + Some(PreimageStatus::Available { ref mut expiry, .. }) => *expiry = Some(when), + ref mut a => *a = Some(PreimageStatus::Missing(when)), }); + + if T::Scheduler::schedule_named( + (DEMOCRACY_ID, index), + when, + None, + 63, + Call::enact_proposal(status.proposal_hash, index).into(), + ).is_err() { + frame_support::print("LOGIC ERROR: bake_referendum/schedule_named failed"); + } } } else { Self::deposit_event(RawEvent::NotPassed(index)); @@ -1662,17 +1715,6 @@ impl Module { let approved = Self::bake_referendum(now, index, info)?; ReferendumInfoOf::::insert(index, ReferendumInfo::Finished { end: now, approved }); } - - let queue = >::get(); - let mut used = 0; - // It's stored in order, so the earliest will always be at the start. - for &(_, proposal_hash, index) in queue.iter().take_while(|x| x.0 == now) { - let _ = Self::enact_proposal(proposal_hash.clone(), index); - used += 1; - } - if used != 0 { - >::put(&queue[used..]); - } Ok(()) } } diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index 1e2e6dc688..8fca8fa4cf 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -21,7 +21,7 @@ use std::cell::RefCell; use codec::Encode; use frame_support::{ impl_outer_origin, impl_outer_dispatch, assert_noop, assert_ok, parameter_types, - ord_parameter_types, traits::Contains, weights::Weight, + ord_parameter_types, traits::{Contains, OnInitialize}, weights::Weight, }; use sp_core::H256; use sp_runtime::{ @@ -71,7 +71,7 @@ impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; - type Call = (); + type Call = Call; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = u64; @@ -90,6 +90,13 @@ impl frame_system::Trait for Test { } parameter_types! { pub const ExistentialDeposit: u64 = 1; + pub const MaximumWeight: u32 = 1000000; +} +impl pallet_scheduler::Trait for Test { + type Event = (); + type Origin = Origin; + type Call = Call; + type MaximumWeight = MaximumWeight; } impl pallet_balances::Trait for Test { type Balance = u64; @@ -152,6 +159,7 @@ impl super::Trait for Test { type Slash = (); type InstantOrigin = EnsureSignedBy; type InstantAllowed = InstantAllowed; + type Scheduler = Scheduler; } fn new_test_ext() -> sp_io::TestExternalities { @@ -167,6 +175,7 @@ fn new_test_ext() -> sp_io::TestExternalities { type System = frame_system::Module; type Balances = pallet_balances::Module; +type Scheduler = pallet_scheduler::Module; type Democracy = Module; #[test] @@ -215,6 +224,7 @@ fn propose_set_balance_and_note(who: u64, value: u64, delay: u64) -> DispatchRes fn next_block() { System::set_block_number(System::block_number() + 1); + Scheduler::on_initialize(System::block_number()); assert_eq!(Democracy::begin_block(System::block_number()), Ok(())); } diff --git a/frame/democracy/src/tests/cancellation.rs b/frame/democracy/src/tests/cancellation.rs index 424ec36dbe..998b0c14d8 100644 --- a/frame/democracy/src/tests/cancellation.rs +++ b/frame/democracy/src/tests/cancellation.rs @@ -50,13 +50,11 @@ fn cancel_queued_should_work() { fast_forward_to(4); - assert_eq!(Democracy::dispatch_queue(), vec![ - (6, set_balance_proposal_hash_and_note(2), 0) - ]); + assert!(pallet_scheduler::Agenda::::get(6)[0].is_some()); assert_noop!(Democracy::cancel_queued(Origin::ROOT, 1), Error::::ProposalMissing); assert_ok!(Democracy::cancel_queued(Origin::ROOT, 0)); - assert_eq!(Democracy::dispatch_queue(), vec![]); + assert!(pallet_scheduler::Agenda::::get(6)[0].is_none()); }); } diff --git a/frame/democracy/src/tests/preimage.rs b/frame/democracy/src/tests/preimage.rs index 8d834c319e..7d977b0ba8 100644 --- a/frame/democracy/src/tests/preimage.rs +++ b/frame/democracy/src/tests/preimage.rs @@ -152,7 +152,6 @@ fn reaping_imminent_preimage_should_fail() { assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); next_block(); next_block(); - // now imminent. assert_noop!(Democracy::reap_preimage(Origin::signed(6), h), Error::::Imminent); }); } diff --git a/frame/democracy/src/tests/voting.rs b/frame/democracy/src/tests/voting.rs index bdb8edb758..43aed29a32 100644 --- a/frame/democracy/src/tests/voting.rs +++ b/frame/democracy/src/tests/voting.rs @@ -85,9 +85,7 @@ fn single_proposal_should_work() { fast_forward_to(4); assert!(Democracy::referendum_status(0).is_err()); - assert_eq!(Democracy::dispatch_queue(), vec![ - (6, set_balance_proposal_hash_and_note(2), 0) - ]); + assert!(pallet_scheduler::Agenda::::get(6)[0].is_some()); // referendum passes and wait another two blocks for enactment. fast_forward_to(6); diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index 1fbfbc20ce..fb219bbebc 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -21,6 +21,7 @@ sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../pr sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } hex-literal = "0.2.1" pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } +pallet-scheduler = { version = "2.0.0-alpha.5", path = "../scheduler" } sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } substrate-test-utils = { version = "2.0.0-alpha.5", path = "../../test-utils" } diff --git a/frame/scheduler/Cargo.toml b/frame/scheduler/Cargo.toml new file mode 100644 index 0000000000..531de95867 --- /dev/null +++ b/frame/scheduler/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "pallet-scheduler" +version = "2.0.0-alpha.5" +authors = ["Parity Technologies "] +edition = "2018" +license = "Unlicense" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "FRAME example pallet" + +[dependencies] +serde = { version = "1.0.101", optional = true } +codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } +frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking" } +frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-alpha.4", default-features = false, path = "../../primitives/io" } + +[dev-dependencies] +sp-core = { version = "2.0.0-alpha.4", path = "../../primitives/core", default-features = false } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "sp-runtime/std", + "frame-benchmarking/std", + "frame-support/std", + "frame-system/std", + "sp-io/std", + "sp-std/std" +] diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs new file mode 100644 index 0000000000..8c60df3527 --- /dev/null +++ b/frame/scheduler/src/lib.rs @@ -0,0 +1,518 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! # Scheduler +//! +//! \# Scheduler +//! +//! - \[`scheduler::Trait`](./trait.Trait.html) +//! - \[`Call`](./enum.Call.html) +//! - \[`Module`](./struct.Module.html) +//! +//! \## Overview +//! +//! // Short description of pallet's purpose. +//! // Links to Traits that should be implemented. +//! // What this pallet is for. +//! // What functionality the pallet provides. +//! // When to use the pallet (use case examples). +//! // How it is used. +//! // Inputs it uses and the source of each input. +//! // Outputs it produces. +//! +//! \## Terminology +//! +//! \## Goals +//! +//! \## Interface +//! +//! \### Dispatchable Functions + +// Ensure we're `no_std` when compiling for Wasm. +#![cfg_attr(not(feature = "std"), no_std)] + +use sp_std::prelude::*; +use codec::{Encode, Decode}; +use sp_runtime::{RuntimeDebug, traits::{Zero, One}}; +use frame_support::{ + dispatch::{Dispatchable, DispatchResult, Parameter}, decl_module, decl_storage, decl_event, + traits::{Get, schedule}, + weights::{GetDispatchInfo, Weight}, +}; +use frame_system::{self as system}; + +/// Our pallet's configuration trait. All our types and constants go in here. If the +/// pallet is dependent on specific other pallets, then their configuration traits +/// should be added to our implied traits list. +/// +/// `system::Trait` should always be included in our implied traits. +pub trait Trait: system::Trait { + /// The overarching event type. + type Event: From> + Into<::Event>; + + /// The aggregated origin which the dispatch will take. + type Origin: From>; + + /// The aggregated call type. + type Call: Parameter + Dispatchable::Origin> + GetDispatchInfo; + + /// The maximum weight that may be scheduled per block for any dispatchables of less priority + /// than `schedule::HARD_DEADLINE`. + type MaximumWeight: Get; +} + +/// Just a simple index for naming period tasks. +pub type PeriodicIndex = u32; +/// The location of a scheduled task that can be used to remove it. +pub type TaskAddress = (BlockNumber, u32); + +/// Information regarding an item to be executed in the future. +#[derive(Clone, RuntimeDebug, Encode, Decode)] +pub struct Scheduled { + /// The unique identity for this task, if there is one. + maybe_id: Option>, + /// This task's priority. + priority: schedule::Priority, + /// The call to be dispatched. + call: Call, + /// If the call is periodic, then this points to the information concerning that. + maybe_periodic: Option>, +} + +decl_storage! { + trait Store for Module as Scheduler { + /// Items to be executed, indexed by the block number that they should be executed on. + pub Agenda: map hasher(twox_64_concat) T::BlockNumber + => Vec::Call, T::BlockNumber>>>; + + /// Lookup from identity to the block number and index of the task. + Lookup: map hasher(twox_64_concat) Vec => Option>; + } +} + +decl_event!( + pub enum Event where ::BlockNumber { + Scheduled(BlockNumber), + Dispatched(TaskAddress, Option>, DispatchResult), + } +); + +decl_module! { + // Simple declaration of the `Module` type. Lets the macro know what its working on. + pub struct Module for enum Call where origin: ::Origin { + fn deposit_event() = default; + + fn on_initialize(now: T::BlockNumber) -> Weight { + let limit = T::MaximumWeight::get(); + let mut queued = Agenda::::take(now).into_iter() + .enumerate() + .filter_map(|(index, s)| s.map(|inner| (index as u32, inner))) + .collect::>(); + queued.sort_by_key(|(_, s)| s.priority); + let mut result = 0; + let unused_items = queued.into_iter() + .enumerate() + .scan(0, |cumulative_weight, (order, (index, s))| { + *cumulative_weight += s.call.get_dispatch_info().weight; + Some((order, index, *cumulative_weight, s)) + }) + .filter_map(|(order, index, cumulative_weight, mut s)| { + if s.priority <= schedule::HARD_DEADLINE || cumulative_weight <= limit || order == 0 { + let r = s.call.clone().dispatch(system::RawOrigin::Root.into()); + let maybe_id = s.maybe_id.clone(); + if let &Some((period, count)) = &s.maybe_periodic { + if count > 1 { + s.maybe_periodic = Some((period, count - 1)); + } else { + s.maybe_periodic = None; + } + let next = now + period; + if let Some(ref id) = s.maybe_id { + let next_index = Agenda::::decode_len(now + period).unwrap_or(0) as u32; + Lookup::::insert(id, (next, next_index)); + } + Agenda::::append_or_insert(next, &[Some(s)][..]); + } else { + if let Some(ref id) = s.maybe_id { + Lookup::::remove(id); + } + } + Self::deposit_event(RawEvent::Dispatched((now, index), maybe_id, r)); + result = cumulative_weight; + None + } else { + Some(Some(s)) + } + }) + .collect::>(); + if !unused_items.is_empty() { + let next = now + One::one(); + Agenda::::append_or_insert(next, &unused_items[..]); + } + result + } + } +} + +impl schedule::Anon::Call> for Module { + type Address = TaskAddress; + + fn schedule( + when: T::BlockNumber, + maybe_periodic: Option>, + priority: schedule::Priority, + call: ::Call + ) -> Self::Address { + // sanitize maybe_periodic + let maybe_periodic = maybe_periodic + .filter(|p| p.1 > 1 && !p.0.is_zero()) + // Remove one from the number of repetitions since we will schedule one now. + .map(|(p, c)| (p, c - 1)); + let s = Some(Scheduled { maybe_id: None, priority, call, maybe_periodic }); + Agenda::::append_or_insert(when, &[s][..]); + (when, Agenda::::decode_len(when).unwrap_or(1) as u32 - 1) + } + + fn cancel((when, index): Self::Address) -> Result<(), ()> { + if let Some(s) = Agenda::::mutate(when, |agenda| agenda.get_mut(index as usize).and_then(Option::take)) { + if let Some(id) = s.maybe_id { + Lookup::::remove(id) + } + Ok(()) + } else { + Err(()) + } + } +} + +impl schedule::Named::Call> for Module { + type Address = TaskAddress; + + fn schedule_named( + id: impl Encode, + when: T::BlockNumber, + maybe_periodic: Option>, + priority: schedule::Priority, + call: ::Call, + ) -> Result { + // determine id and ensure it is unique + let id = id.encode(); + if Lookup::::contains_key(&id) { + return Err(()) + } + + // sanitize maybe_periodic + let maybe_periodic = maybe_periodic + .filter(|p| p.1 > 1 && !p.0.is_zero()) + // Remove one from the number of repetitions since we will schedule one now. + .map(|(p, c)| (p, c - 1)); + + let s = Scheduled { maybe_id: Some(id.clone()), priority, call, maybe_periodic }; + Agenda::::append_or_insert(when, &[Some(s)][..]); + let index = Agenda::::decode_len(when).unwrap_or(1) as u32 - 1; + let address = (when, index); + Lookup::::insert(&id, &address); + Ok(address) + } + + fn cancel_named(id: impl Encode) -> Result<(), ()> { + if let Some((when, index)) = id.using_encoded(|d| Lookup::::take(d)) { + let i = index as usize; + Agenda::::mutate(when, |agenda| if let Some(s) = agenda.get_mut(i) { *s = None }); + Ok(()) + } else { + Err(()) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use frame_support::{ + impl_outer_event, impl_outer_origin, impl_outer_dispatch, parameter_types, assert_ok, + traits::{OnInitialize, OnFinalize, schedule::{Anon, Named}}, + weights::{DispatchClass, FunctionOf} + }; + use sp_core::H256; + // The testing primitives are very useful for avoiding having to work with signatures + // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. + use sp_runtime::{ + Perbill, + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + }; + use crate as scheduler; + + mod logger { + use super::*; + use std::cell::RefCell; + use frame_system::ensure_root; + + thread_local! { + static LOG: RefCell> = RefCell::new(Vec::new()); + } + pub fn log() -> Vec { + LOG.with(|log| log.borrow().clone()) + } + pub trait Trait: system::Trait { + type Event: From + Into<::Event>; + } + decl_storage! { + trait Store for Module as Logger { + } + } + decl_event! { + pub enum Event { + Logged(u32, Weight), + } + } + decl_module! { + // Simple declaration of the `Module` type. Lets the macro know what its working on. + pub struct Module for enum Call where origin: ::Origin { + fn deposit_event() = default; + + #[weight = FunctionOf( + |args: (&u32, &Weight)| *args.1, + |_: (&u32, &Weight)| DispatchClass::Normal, + true + )] + fn log(origin, i: u32, weight: Weight) { + ensure_root(origin)?; + Self::deposit_event(Event::Logged(i, weight)); + LOG.with(|log| { + log.borrow_mut().push(i); + }) + } + } + } + } + + impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} + } + + impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + system::System, + logger::Logger, + } + } + + impl_outer_event! { + pub enum Event for Test { + system, + logger, + scheduler, + } + } + // For testing the pallet, we construct most of a mock runtime. This means + // first constructing a configuration type (`Test`) which `impl`s each of the + // configuration traits of pallets we want to use. + #[derive(Clone, Eq, PartialEq)] + pub struct Test; + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + } + impl system::Trait for Test { + type Origin = Origin; + type Call = (); + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + } + impl logger::Trait for Test { + type Event = (); + } + parameter_types! { + pub const MaximumWeight: Weight = 10_000; + } + impl Trait for Test { + type Event = (); + type Origin = Origin; + type Call = Call; + type MaximumWeight = MaximumWeight; + } + type System = system::Module; + type Logger = logger::Module; + type Scheduler = Module; + + // This function basically just builds a genesis storage key/value store according to + // our desired mockup. + fn new_test_ext() -> sp_io::TestExternalities { + let t = system::GenesisConfig::default().build_storage::().unwrap(); + t.into() + } + + fn run_to_block(n: u64) { + while System::block_number() < n { + Scheduler::on_finalize(System::block_number()); + System::set_block_number(System::block_number() + 1); + Scheduler::on_initialize(System::block_number()); + } + } + + #[test] + fn basic_scheduling_works() { + new_test_ext().execute_with(|| { + Scheduler::schedule(4, None, 127, Call::Logger(logger::Call::log(42, 1000))); + run_to_block(3); + assert!(logger::log().is_empty()); + run_to_block(4); + assert_eq!(logger::log(), vec![42u32]); + run_to_block(100); + assert_eq!(logger::log(), vec![42u32]); + }); + } + + #[test] + fn periodic_scheduling_works() { + new_test_ext().execute_with(|| { + // at #4, every 3 blocks, 3 times. + Scheduler::schedule(4, Some((3, 3)), 127, Call::Logger(logger::Call::log(42, 1000))); + run_to_block(3); + assert!(logger::log().is_empty()); + run_to_block(4); + assert_eq!(logger::log(), vec![42u32]); + run_to_block(6); + assert_eq!(logger::log(), vec![42u32]); + run_to_block(7); + assert_eq!(logger::log(), vec![42u32, 42u32]); + run_to_block(9); + assert_eq!(logger::log(), vec![42u32, 42u32]); + run_to_block(10); + assert_eq!(logger::log(), vec![42u32, 42u32, 42u32]); + run_to_block(100); + assert_eq!(logger::log(), vec![42u32, 42u32, 42u32]); + }); + } + + #[test] + fn cancel_named_scheduling_works_with_normal_cancel() { + new_test_ext().execute_with(|| { + // at #4. + Scheduler::schedule_named(1u32, 4, None, 127, Call::Logger(logger::Call::log(69, 1000))).unwrap(); + let i = Scheduler::schedule(4, None, 127, Call::Logger(logger::Call::log(42, 1000))); + run_to_block(3); + assert!(logger::log().is_empty()); + assert_ok!(Scheduler::cancel_named(1u32)); + assert_ok!(Scheduler::cancel(i)); + run_to_block(100); + assert!(logger::log().is_empty()); + }); + } + + #[test] + fn cancel_named_periodic_scheduling_works() { + new_test_ext().execute_with(|| { + // at #4, every 3 blocks, 3 times. + Scheduler::schedule_named(1u32, 4, Some((3, 3)), 127, Call::Logger(logger::Call::log(42, 1000))).unwrap(); + // same id results in error. + assert!(Scheduler::schedule_named(1u32, 4, None, 127, Call::Logger(logger::Call::log(69, 1000))).is_err()); + // different id is ok. + Scheduler::schedule_named(2u32, 8, None, 127, Call::Logger(logger::Call::log(69, 1000))).unwrap(); + run_to_block(3); + assert!(logger::log().is_empty()); + run_to_block(4); + assert_eq!(logger::log(), vec![42u32]); + run_to_block(6); + assert_ok!(Scheduler::cancel_named(1u32)); + run_to_block(100); + assert_eq!(logger::log(), vec![42u32, 69u32]); + }); + } + + #[test] + fn scheduler_respects_weight_limits() { + new_test_ext().execute_with(|| { + Scheduler::schedule(4, None, 127, Call::Logger(logger::Call::log(42, 6000))); + Scheduler::schedule(4, None, 127, Call::Logger(logger::Call::log(69, 6000))); + run_to_block(4); + assert_eq!(logger::log(), vec![42u32]); + run_to_block(5); + assert_eq!(logger::log(), vec![42u32, 69u32]); + }); + } + + #[test] + fn scheduler_respects_hard_deadlines_more() { + new_test_ext().execute_with(|| { + Scheduler::schedule(4, None, 0, Call::Logger(logger::Call::log(42, 6000))); + Scheduler::schedule(4, None, 0, Call::Logger(logger::Call::log(69, 6000))); + run_to_block(4); + assert_eq!(logger::log(), vec![42u32, 69u32]); + }); + } + + #[test] + fn scheduler_respects_priority_ordering() { + new_test_ext().execute_with(|| { + Scheduler::schedule(4, None, 1, Call::Logger(logger::Call::log(42, 6000))); + Scheduler::schedule(4, None, 0, Call::Logger(logger::Call::log(69, 6000))); + run_to_block(4); + assert_eq!(logger::log(), vec![69u32, 42u32]); + }); + } + + #[test] + fn scheduler_respects_priority_ordering_with_soft_deadlines() { + new_test_ext().execute_with(|| { + Scheduler::schedule(4, None, 255, Call::Logger(logger::Call::log(42, 5000))); + Scheduler::schedule(4, None, 127, Call::Logger(logger::Call::log(69, 5000))); + Scheduler::schedule(4, None, 126, Call::Logger(logger::Call::log(2600, 6000))); + run_to_block(4); + assert_eq!(logger::log(), vec![2600u32]); + run_to_block(5); + assert_eq!(logger::log(), vec![2600u32, 69u32, 42u32]); + }); + } + + #[test] + fn initialize_weight_is_correct() { + new_test_ext().execute_with(|| { + Scheduler::schedule(1, None, 255, Call::Logger(logger::Call::log(3, 1000))); + Scheduler::schedule(1, None, 128, Call::Logger(logger::Call::log(42, 5000))); + Scheduler::schedule(1, None, 127, Call::Logger(logger::Call::log(69, 5000))); + Scheduler::schedule(1, None, 126, Call::Logger(logger::Call::log(2600, 6000))); + let weight = Scheduler::on_initialize(1); + assert_eq!(weight, 6000); + let weight = Scheduler::on_initialize(2); + assert_eq!(weight, 10000); + let weight = Scheduler::on_initialize(3); + assert_eq!(weight, 1000); + let weight = Scheduler::on_initialize(4); + assert_eq!(weight, 0); + }); + } +} diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 77e4c679f4..f19d3995ea 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -19,7 +19,7 @@ //! NOTE: If you're looking for `parameter_types`, it has moved in to the top-level module. use sp_std::{prelude::*, result, marker::PhantomData, ops::Div, fmt::Debug}; -use codec::{FullCodec, Codec, Encode, Decode}; +use codec::{FullCodec, Codec, Encode, Decode, EncodeLike}; use sp_core::u32_trait::Value as U32; use sp_runtime::{ RuntimeDebug, @@ -1144,6 +1144,84 @@ pub trait OffchainWorker { fn offchain_worker(_n: BlockNumber) {} } +pub mod schedule { + use super::*; + + /// Information relating to the period of a scheduled task. First item is the length of the + /// period and the second is the number of times it should be executed in total before the task + /// is considered finished and removed. + pub type Period = (BlockNumber, u32); + + /// Priority with which a call is scheduled. It's just a linear amount with lowest values meaning + /// higher priority. + pub type Priority = u8; + + /// The highest priority. We invert the value so that normal sorting will place the highest + /// priority at the beginning of the list. + pub const HIGHEST_PRORITY: Priority = 0; + /// Anything of this value or lower will definitely be scheduled on the block that they ask for, even + /// if it breaches the `MaximumWeight` limitation. + pub const HARD_DEADLINE: Priority = 63; + /// The lowest priority. Most stuff should be around here. + pub const LOWEST_PRORITY: Priority = 255; + + /// A type that can be used as a scheduler. + pub trait Anon { + /// An address which can be used for removing a scheduled task. + type Address: Codec + Clone + Eq + EncodeLike + Debug; + + /// Schedule a one-off dispatch to happen at the beginning of some block in the future. + /// + /// This is not named. + /// + /// Infallible. + fn schedule( + when: BlockNumber, + maybe_periodic: Option>, + priority: Priority, + call: Call + ) -> Self::Address; + + /// Cancel a scheduled task. If periodic, then it will cancel all further instances of that, + /// also. + /// + /// Will return an error if the `address` is invalid. + /// + /// NOTE: This guaranteed to work only *before* the point that it is due to be executed. + /// If it ends up being delayed beyond the point of execution, then it cannot be cancelled. + /// + /// NOTE2: This will not work to cancel periodic tasks after their initial execution. For + /// that, you must name the task explicitly using the `Named` trait. + fn cancel(address: Self::Address) -> Result<(), ()>; + } + + /// A type that can be used as a scheduler. + pub trait Named { + /// An address which can be used for removing a scheduled task. + type Address: Codec + Clone + Eq + EncodeLike + sp_std::fmt::Debug; + + /// Schedule a one-off dispatch to happen at the beginning of some block in the future. + /// + /// - `id`: The identity of the task. This must be unique and will return an error if not. + fn schedule_named( + id: impl Encode, + when: BlockNumber, + maybe_periodic: Option>, + priority: Priority, + call: Call + ) -> Result; + + /// Cancel a scheduled, named task. If periodic, then it will cancel all further instances + /// of that, also. + /// + /// Will return an error if the `id` is invalid. + /// + /// NOTE: This guaranteed to work only *before* the point that it is due to be executed. + /// If it ends up being delayed beyond the point of execution, then it cannot be cancelled. + fn cancel_named(id: impl Encode) -> Result<(), ()>; + } +} + #[cfg(test)] mod tests { use super::*; -- GitLab From 78502f547f6badf71858986ebf0d5aa5ed72c85b Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Wed, 1 Apr 2020 16:22:34 +0200 Subject: [PATCH 129/300] check_polkadot.sh: use the branch matching substrate's branch if possible (#5468) * check_polkadot.sh: use the branch matching substrate's branch if possible * convert to grep * update comment --- .../gitlab/check_polkadot_companion_build.sh | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index 5bd51e0cd2..04524a736a 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -30,10 +30,11 @@ this job checks if there is a string in the description of the pr like polkadot companion: paritytech/polkadot#567 -it will then run cargo check from this polkadot's branch with substrate code -from this pull request. in absence of that string it will check if a polkadot -pr is mentioned and will use the last one instead. if none of the above can be -found it will check the build against polkadot:master. +it will then run cargo check from this polkadot's branch with substrate code +from this pull request. in absence of that string it will check if a polkadot +pr is mentioned and will use the last one instead. if none of the above can be +found it will check if polkadot has a branch of the exact same name than the +substrate's branch. if it can't find anything, it will uses master instead EOT @@ -52,9 +53,11 @@ cd polkadot if expr match "${CI_COMMIT_REF_NAME}" '^[0-9]\+$' >/dev/null then boldprint "this is pull request no ${CI_COMMIT_REF_NAME}" + # get the last reference to a pr in polkadot - pr_body="$(curl -H "${github_header}" -s ${github_api_substrate_pull_url}/${CI_COMMIT_REF_NAME} \ - | sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p')" + pr_data="$(curl -sSL -H "${github_header}" -s ${github_api_substrate_pull_url}/${CI_COMMIT_REF_NAME})" + pr_ref="$(echo $pr_data | grep -Po '"ref"\s*:\s*"\K(?!master)[^"]*')" + pr_body="$(echo $pr_data | sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p')" pr_companion="$(echo "${pr_body}" | sed -n -r \ -e 's;^.*polkadot companion: paritytech/polkadot#([0-9]+).*$;\1;p' \ @@ -73,7 +76,13 @@ then git fetch --depth 1 origin refs/pull/${pr_companion}/head:pr/${pr_companion} git checkout pr/${pr_companion} else - boldprint "no companion pr found - building polkadot:master" + if git fetch --depth 1 origin "$pr_ref":branch/"$pr_ref" + then + boldprint "companion branch detected: $pr_ref" + git checkout branch/"$pr_ref" + else + boldprint "no companion branch found - building polkadot:master" + fi fi else boldprint "this is not a pull request - building polkadot:master" -- GitLab From b4db9a959ad45badbd70e12703df647bc10fec67 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 1 Apr 2020 17:25:53 +0200 Subject: [PATCH 130/300] Remove DiscoveryNetBehaviour trait (#5430) --- client/network/src/behaviour.rs | 2 +- client/network/src/lib.rs | 11 ---------- client/network/src/protocol.rs | 15 ++++++------- .../src/protocol/generic_proto/behaviour.rs | 21 ++++++++++--------- 4 files changed, 20 insertions(+), 29 deletions(-) diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index e7aca1975c..37bc9bfb01 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use crate::{ - debug_info, discovery::DiscoveryBehaviour, discovery::DiscoveryOut, DiscoveryNetBehaviour, + debug_info, discovery::DiscoveryBehaviour, discovery::DiscoveryOut, Event, protocol::event::DhtEvent, ExHashT, }; use crate::protocol::{self, light_client_handler, CustomMessageOutcome, Protocol}; diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index 23233ee904..bb58f8c7bf 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -255,14 +255,3 @@ pub use libp2p::{Multiaddr, PeerId}; pub use libp2p::multiaddr; pub use sc_peerset::ReputationChange; - -/// Extension trait for `NetworkBehaviour` that also accepts discovering nodes. -trait DiscoveryNetBehaviour { - /// Notify the protocol that we have learned about the existence of nodes. - /// - /// Can (or most likely will) be called multiple times with the same `PeerId`s. - /// - /// Also note that there is no notification for expired nodes. The implementer must add a TTL - /// system, or remove nodes that will fail to reach. - fn add_discovered_nodes(&mut self, nodes: impl Iterator); -} diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 55bc40a950..d534bde810 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::{DiscoveryNetBehaviour, config::ProtocolId}; +use crate::config::ProtocolId; use crate::utils::interval; use bytes::{Bytes, BytesMut}; use futures::prelude::*; @@ -1582,6 +1582,13 @@ impl Protocol { self.sync.request_finality_proof(&hash, number) } + /// Notify the protocol that we have learned about the existence of nodes. + /// + /// Can be called multiple times with the same `PeerId`s. + pub fn add_discovered_nodes(&mut self, peer_ids: impl Iterator) { + self.behaviour.add_discovered_nodes(peer_ids) + } + pub fn finality_proof_import_result( &mut self, request_block: (B::Hash, NumberFor), @@ -2205,12 +2212,6 @@ impl NetworkBehaviour for Protocol { } } -impl DiscoveryNetBehaviour for Protocol { - fn add_discovered_nodes(&mut self, peer_ids: impl Iterator) { - self.behaviour.add_discovered_nodes(peer_ids) - } -} - impl Drop for Protocol { fn drop(&mut self) { debug!(target: "sync", "Network stats:\n{}", self.format_stats()); diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index 63625f1c9f..e52ac5575f 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::{DiscoveryNetBehaviour, config::ProtocolId}; +use crate::config::ProtocolId; use crate::protocol::generic_proto::handler::{NotifsHandlerProto, NotifsHandlerOut, NotifsHandlerIn}; use crate::protocol::generic_proto::upgrade::RegisteredProtocol; @@ -405,6 +405,16 @@ impl GenericProto { } } + /// Notify the behaviour that we have learned about the existence of nodes. + /// + /// Can be called multiple times with the same `PeerId`s. + pub fn add_discovered_nodes(&mut self, peer_ids: impl Iterator) { + self.peerset.discovered(peer_ids.into_iter().map(|peer_id| { + debug!(target: "sub-libp2p", "PSM <= Discovered({:?})", peer_id); + peer_id + })); + } + /// Sends a notification to a peer. /// /// Has no effect if the custom protocol is not open with the given peer. @@ -708,15 +718,6 @@ impl GenericProto { } } -impl DiscoveryNetBehaviour for GenericProto { - fn add_discovered_nodes(&mut self, peer_ids: impl Iterator) { - self.peerset.discovered(peer_ids.into_iter().map(|peer_id| { - debug!(target: "sub-libp2p", "PSM <= Discovered({:?})", peer_id); - peer_id - })); - } -} - impl NetworkBehaviour for GenericProto { type ProtocolsHandler = NotifsHandlerProto; type OutEvent = GenericProtoOut; -- GitLab From 8b304e4920c41e918876c48be73eac2bef22e826 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Wed, 1 Apr 2020 19:41:48 +0200 Subject: [PATCH 131/300] A few missing emojies (#5490) * A few missing emojies * P2p message emojis * Add a bit of colour * format * Introduce a couple of spaces * Some spaces --- bin/node/cli/src/browser.rs | 2 +- client/cli/src/commands/runcmd.rs | 2 +- client/informant/src/display.rs | 10 ++++----- client/informant/src/lib.rs | 11 +++++----- .../generic_proto/handler/notif_out.rs | 22 +++++++++---------- client/network/src/service.rs | 2 +- client/telemetry/src/worker/node.rs | 12 +++++----- utils/prometheus/src/lib.rs | 2 +- 8 files changed, 32 insertions(+), 31 deletions(-) diff --git a/bin/node/cli/src/browser.rs b/bin/node/cli/src/browser.rs index d0746e8448..ea380b3ffd 100644 --- a/bin/node/cli/src/browser.rs +++ b/bin/node/cli/src/browser.rs @@ -44,7 +44,7 @@ async fn start_inner(chain_spec: String, log_level: String) -> Result InformantDisplay { if self.format == OutputFormat::Coloured { info!( target: "substrate", - "{}{} ({} peers), best: #{} ({}), finalized #{} ({}), ⬇ {} ⬆ {}", + "{}{} ({} peers), best: #{} ({}), finalized #{} ({}), {} {}", Colour::White.bold().paint(&status), target, Colour::White.bold().paint(format!("{}", num_connected_peers)), - Colour::White.paint(format!("{}", best_number)), + Colour::White.bold().paint(format!("{}", best_number)), best_hash, - Colour::White.paint(format!("{}", finalized_number)), + Colour::White.bold().paint(format!("{}", finalized_number)), info.chain.finalized_hash, - TransferRateFormat(net_status.average_download_per_sec), - TransferRateFormat(net_status.average_upload_per_sec), + Colour::Green.paint(format!("⬇ {}", TransferRateFormat(net_status.average_download_per_sec))), + Colour::Red.paint(format!("⬆ {}", TransferRateFormat(net_status.average_upload_per_sec))), ); } else { info!( diff --git a/client/informant/src/lib.rs b/client/informant/src/lib.rs index 5c2ac41d44..66d5ed41fb 100644 --- a/client/informant/src/lib.rs +++ b/client/informant/src/lib.rs @@ -16,6 +16,7 @@ //! Console informant. Prints sync progress and block events. Runs on the calling thread. +use ansi_term::Colour; use sc_client_api::BlockchainEvents; use futures::prelude::*; use log::{info, warn, trace}; @@ -79,10 +80,10 @@ pub fn build(service: &impl AbstractService, format: OutputFormat) -> impl futur match maybe_ancestor { Ok(ref ancestor) if ancestor.hash != *last_hash => info!( - "♻️ Reorg from #{},{} to #{},{}, common ancestor #{},{}", - last_num, last_hash, - n.header.number(), n.hash, - ancestor.number, ancestor.hash, + "♻️ Reorg on #{},{} to #{},{}, common ancestor #{},{}", + Colour::Red.bold().paint(format!("{}", last_num)), last_hash, + Colour::Green.bold().paint(format!("{}", n.header.number())), n.hash, + Colour::White.bold().paint(format!("{}", ancestor.number)), ancestor.hash, ), Ok(_) => {}, Err(e) => warn!("Error computing tree route: {}", e), @@ -94,7 +95,7 @@ pub fn build(service: &impl AbstractService, format: OutputFormat) -> impl futur last_best = Some((n.header.number().clone(), n.hash.clone())); } - info!(target: "substrate", "✨ Imported #{} ({})", n.header.number(), n.hash); + info!(target: "substrate", "✨ Imported #{} ({})", Colour::White.bold().paint(format!("{}", n.header.number())), n.hash); future::ready(()) }); diff --git a/client/network/src/protocol/generic_proto/handler/notif_out.rs b/client/network/src/protocol/generic_proto/handler/notif_out.rs index 8c64491d99..62d2409be8 100644 --- a/client/network/src/protocol/generic_proto/handler/notif_out.rs +++ b/client/network/src/protocol/generic_proto/handler/notif_out.rs @@ -244,8 +244,8 @@ impl ProtocolsHandler for NotifsOutHandler { // Any other situation should never happen. State::Disabled | State::Refused | State::Open { .. } | State::DisabledOpen(_) => - error!("State mismatch in notifications handler: substream already open"), - State::Poisoned => error!("Notifications handler in a poisoned state"), + error!("☎️ State mismatch in notifications handler: substream already open"), + State::Poisoned => error!("☎️ Notifications handler in a poisoned state"), } } @@ -270,7 +270,7 @@ impl ProtocolsHandler for NotifsOutHandler { if sub.close().now_or_never().is_none() { log::warn!( target: "sub-libp2p", - "Improperly closed outbound notifications substream" + "📞 Improperly closed outbound notifications substream" ); } @@ -282,19 +282,19 @@ impl ProtocolsHandler for NotifsOutHandler { self.state = State::Opening { initial_message }; }, State::Opening { .. } | State::Refused | State::Open { .. } => - error!("Tried to enable notifications handler that was already enabled"), - State::Poisoned => error!("Notifications handler in a poisoned state"), + error!("☎️ Tried to enable notifications handler that was already enabled"), + State::Poisoned => error!("☎️ Notifications handler in a poisoned state"), } } NotifsOutHandlerIn::Disable => { match mem::replace(&mut self.state, State::Poisoned) { State::Disabled | State::DisabledOpen(_) | State::DisabledOpening => - error!("Tried to disable notifications handler that was already disabled"), + error!("☎️ Tried to disable notifications handler that was already disabled"), State::Opening { .. } => self.state = State::DisabledOpening, State::Refused => self.state = State::Disabled, State::Open { substream, .. } => self.state = State::DisabledOpen(substream), - State::Poisoned => error!("Notifications handler in a poisoned state"), + State::Poisoned => error!("☎️ Notifications handler in a poisoned state"), } } @@ -304,14 +304,14 @@ impl ProtocolsHandler for NotifsOutHandler { } else { log::warn!( target: "sub-libp2p", - "Failed to push message to queue, dropped it" + "📞 Failed to push message to queue, dropped it" ); } } else { // This is an API misuse. log::warn!( target: "sub-libp2p", - "Tried to send a notification on a disabled handler" + "📞 Tried to send a notification on a disabled handler" ); }, } @@ -321,14 +321,14 @@ impl ProtocolsHandler for NotifsOutHandler { match mem::replace(&mut self.state, State::Poisoned) { State::Disabled => {}, State::DisabledOpen(_) | State::Refused | State::Open { .. } => - error!("State mismatch in NotificationsOut"), + error!("☎️ State mismatch in NotificationsOut"), State::Opening { .. } => { self.state = State::Refused; let ev = NotifsOutHandlerOut::Refused; self.events_queue.push(ProtocolsHandlerEvent::Custom(ev)); }, State::DisabledOpening => self.state = State::Disabled, - State::Poisoned => error!("Notifications handler in a poisoned state"), + State::Poisoned => error!("☎️ Notifications handler in a poisoned state"), } } diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 2c93d70e26..4b77bdccaa 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -226,7 +226,7 @@ impl NetworkWorker { let local_identity = params.network_config.node_key.clone().into_keypair()?; let local_public = local_identity.public(); let local_peer_id = local_public.clone().into_peer_id(); - info!(target: "sub-libp2p", "Local node identity is: {}", local_peer_id.to_base58()); + info!(target: "sub-libp2p", "🏷 Local node identity is: {}", local_peer_id.to_base58()); let checker = params.on_demand.as_ref() .map(|od| od.checker().clone()) diff --git a/client/telemetry/src/worker/node.rs b/client/telemetry/src/worker/node.rs index 58e9f20bd5..d28c3854f0 100644 --- a/client/telemetry/src/worker/node.rs +++ b/client/telemetry/src/worker/node.rs @@ -116,7 +116,7 @@ where TTrans: Clone + Unpin, TTrans::Dial: Unpin, pending.push_back(payload.into()); Ok(()) } else { - warn!(target: "telemetry", "Rejected log entry because queue is full for {:?}", + warn!(target: "telemetry", "⚠️ Rejected log entry because queue is full for {:?}", self.addr); Err(()) } @@ -137,7 +137,7 @@ where TTrans: Clone + Unpin, TTrans::Dial: Unpin, break NodeSocket::Connected(conn) }, Poll::Ready(Err(err)) => { - warn!(target: "telemetry", "Disconnected from {}: {:?}", self.addr, err); + warn!(target: "telemetry", "⚠️ Disconnected from {}: {:?}", self.addr, err); let timeout = gen_rand_reconnect_delay(); self.socket = NodeSocket::WaitingReconnect(timeout); return Poll::Ready(NodeEvent::Disconnected(err)) @@ -146,7 +146,7 @@ where TTrans: Clone + Unpin, TTrans::Dial: Unpin, } NodeSocket::Dialing(mut s) => match Future::poll(Pin::new(&mut s), cx) { Poll::Ready(Ok(sink)) => { - debug!(target: "telemetry", "Connected to {}", self.addr); + debug!(target: "telemetry", "✅ Connected to {}", self.addr); let conn = NodeSocketConnected { sink, pending: VecDeque::new(), @@ -158,7 +158,7 @@ where TTrans: Clone + Unpin, TTrans::Dial: Unpin, }, Poll::Pending => break NodeSocket::Dialing(s), Poll::Ready(Err(err)) => { - warn!(target: "telemetry", "Error while dialing {}: {:?}", self.addr, err); + warn!(target: "telemetry", "❌ Error while dialing {}: {:?}", self.addr, err); let timeout = gen_rand_reconnect_delay(); socket = NodeSocket::WaitingReconnect(timeout); } @@ -169,7 +169,7 @@ where TTrans: Clone + Unpin, TTrans::Dial: Unpin, socket = NodeSocket::Dialing(d); } Err(err) => { - warn!(target: "telemetry", "Error while dialing {}: {:?}", self.addr, err); + warn!(target: "telemetry", "❌ Error while dialing {}: {:?}", self.addr, err); let timeout = gen_rand_reconnect_delay(); socket = NodeSocket::WaitingReconnect(timeout); } @@ -181,7 +181,7 @@ where TTrans: Clone + Unpin, TTrans::Dial: Unpin, break NodeSocket::WaitingReconnect(s) } NodeSocket::Poisoned => { - error!(target: "telemetry", "Poisoned connection with {}", self.addr); + error!(target: "telemetry", "‼️ Poisoned connection with {}", self.addr); break NodeSocket::Poisoned } } diff --git a/utils/prometheus/src/lib.rs b/utils/prometheus/src/lib.rs index 54b9183bc6..4a8f05d929 100644 --- a/utils/prometheus/src/lib.rs +++ b/utils/prometheus/src/lib.rs @@ -120,7 +120,7 @@ mod known_os { .await .map_err(|_| Error::PortInUse(prometheus_addr))?; - log::info!("Prometheus server started at {}", prometheus_addr); + log::info!("〽️ Prometheus server started at {}", prometheus_addr); let service = make_service_fn(move |_| { let registry = registry.clone(); -- GitLab From 905677dbd9389735d2e69583999262370c4a091f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Wed, 1 Apr 2020 18:43:34 +0100 Subject: [PATCH 132/300] babe: restore epoch changes migration code (#5487) This was removed in https://github.com/paritytech/substrate/pull/5291 but is still too early to do it as it requires nodes still on Polkadot v0.7.26 to resync from scratch. --- client/consensus/babe/src/aux_schema.rs | 77 +++++++++++++++++++++++- client/consensus/epochs/src/lib.rs | 2 + client/consensus/epochs/src/migration.rs | 55 +++++++++++++++++ 3 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 client/consensus/epochs/src/migration.rs diff --git a/client/consensus/babe/src/aux_schema.rs b/client/consensus/babe/src/aux_schema.rs index 3ca2f560d4..6f69e65940 100644 --- a/client/consensus/babe/src/aux_schema.rs +++ b/client/consensus/babe/src/aux_schema.rs @@ -25,7 +25,7 @@ use sc_client_api::backend::AuxStore; use sp_blockchain::{Result as ClientResult, Error as ClientError}; use sp_runtime::traits::Block as BlockT; use sp_consensus_babe::BabeBlockWeight; -use sc_consensus_epochs::{EpochChangesFor, SharedEpochChanges}; +use sc_consensus_epochs::{EpochChangesFor, SharedEpochChanges, migration::EpochChangesForV0}; use crate::Epoch; const BABE_EPOCH_CHANGES_VERSION: &[u8] = b"babe_epoch_changes_version"; @@ -57,7 +57,11 @@ pub(crate) fn load_epoch_changes( let version = load_decode::<_, u32>(backend, BABE_EPOCH_CHANGES_VERSION)?; let maybe_epoch_changes = match version { - None | Some(BABE_EPOCH_CHANGES_CURRENT_VERSION) => load_decode::<_, EpochChangesFor>( + None => load_decode::<_, EpochChangesForV0>( + backend, + BABE_EPOCH_CHANGES_KEY, + )?.map(|v0| v0.migrate()), + Some(BABE_EPOCH_CHANGES_CURRENT_VERSION) => load_decode::<_, EpochChangesFor>( backend, BABE_EPOCH_CHANGES_KEY, )?, @@ -123,3 +127,72 @@ pub(crate) fn load_block_weight( ) -> ClientResult> { load_decode(backend, block_weight_key(block_hash).as_slice()) } + +#[cfg(test)] +mod test { + use super::*; + use crate::Epoch; + use fork_tree::ForkTree; + use substrate_test_runtime_client; + use sp_core::H256; + use sp_runtime::traits::NumberFor; + use sc_consensus_epochs::{PersistedEpoch, PersistedEpochHeader, EpochHeader}; + use sp_consensus::Error as ConsensusError; + use sc_network_test::Block as TestBlock; + + #[test] + fn load_decode_from_v0_epoch_changes() { + let epoch = Epoch { + start_slot: 0, + authorities: vec![], + randomness: [0; 32], + epoch_index: 1, + duration: 100, + }; + let client = substrate_test_runtime_client::new(); + let mut v0_tree = ForkTree::, _>::new(); + v0_tree.import::<_, ConsensusError>( + Default::default(), + Default::default(), + PersistedEpoch::Regular(epoch), + &|_, _| Ok(false), // Test is single item only so this can be set to false. + ).unwrap(); + + client.insert_aux( + &[(BABE_EPOCH_CHANGES_KEY, + &EpochChangesForV0::::from_raw(v0_tree).encode()[..])], + &[], + ).unwrap(); + + assert_eq!( + load_decode::<_, u32>(&client, BABE_EPOCH_CHANGES_VERSION).unwrap(), + None, + ); + + let epoch_changes = load_epoch_changes::(&client).unwrap(); + + assert!( + epoch_changes.lock() + .tree() + .iter() + .map(|(_, _, epoch)| epoch.clone()) + .collect::>() == + vec![PersistedEpochHeader::Regular(EpochHeader { + start_slot: 0, + end_slot: 100, + })], + ); // PersistedEpochHeader does not implement Debug, so we use assert! directly. + + write_epoch_changes::( + &epoch_changes.lock(), + |values| { + client.insert_aux(values, &[]).unwrap(); + }, + ); + + assert_eq!( + load_decode::<_, u32>(&client, BABE_EPOCH_CHANGES_VERSION).unwrap(), + Some(1), + ); + } +} diff --git a/client/consensus/epochs/src/lib.rs b/client/consensus/epochs/src/lib.rs index d5816d960c..001c172b34 100644 --- a/client/consensus/epochs/src/lib.rs +++ b/client/consensus/epochs/src/lib.rs @@ -16,6 +16,8 @@ //! Generic utilities for epoch-based consensus engines. +pub mod migration; + use std::{sync::Arc, ops::Add, collections::BTreeMap, borrow::{Borrow, BorrowMut}}; use parking_lot::Mutex; use codec::{Encode, Decode}; diff --git a/client/consensus/epochs/src/migration.rs b/client/consensus/epochs/src/migration.rs new file mode 100644 index 0000000000..e4717b5584 --- /dev/null +++ b/client/consensus/epochs/src/migration.rs @@ -0,0 +1,55 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Migration types for epoch changes. + +use std::collections::BTreeMap; +use codec::{Encode, Decode}; +use fork_tree::ForkTree; +use sp_runtime::traits::{Block as BlockT, NumberFor}; +use crate::{Epoch, EpochChanges, PersistedEpoch, PersistedEpochHeader}; + +/// Legacy definition of epoch changes. +#[derive(Clone, Encode, Decode)] +pub struct EpochChangesV0 { + inner: ForkTree>, +} + +/// Type alias for legacy definition of epoch changes. +pub type EpochChangesForV0 = EpochChangesV0<::Hash, NumberFor, Epoch>; + +impl EpochChangesV0 where + Hash: PartialEq + Ord + Copy, + Number: Ord + Copy, +{ + /// Create a new value of this type from raw. + pub fn from_raw(inner: ForkTree>) -> Self { + Self { inner } + } + + /// Migrate the type into current epoch changes definition. + pub fn migrate(self) -> EpochChanges { + let mut epochs = BTreeMap::new(); + + let inner = self.inner.map(&mut |hash, number, data| { + let header = PersistedEpochHeader::from(&data); + epochs.insert((*hash, *number), data); + header + }); + + EpochChanges { inner, epochs } + } +} -- GitLab From f68d22fc131b05d5785c19ac3c4ff67ca4cb05f8 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 1 Apr 2020 19:44:42 +0200 Subject: [PATCH 133/300] Switch to new light client protocol (#5472) * Switch to the new protocol * Oops, forgot to remove light_dispatch.rs * Fix tests * Address review --- client/network/src/behaviour.rs | 4 +- client/network/src/config.rs | 2 +- client/network/src/on_demand_layer.rs | 116 +- client/network/src/protocol.rs | 299 +--- .../src/protocol/light_client_handler.rs | 360 ++++- client/network/src/protocol/light_dispatch.rs | 1313 ----------------- client/network/src/service.rs | 69 +- 7 files changed, 481 insertions(+), 1682 deletions(-) delete mode 100644 client/network/src/protocol/light_dispatch.rs diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index 37bc9bfb01..26a020aae0 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -133,7 +133,6 @@ impl Behaviour { } /// Issue a light client request. - #[allow(unused)] pub fn light_client_request(&mut self, r: light_client_handler::Request) -> Result<(), light_client_handler::Error> { self.light_client_handler.request(r) } @@ -175,6 +174,9 @@ Behaviour { let ev = Event::NotificationsReceived { remote, messages }; self.events.push(BehaviourOut::Event(ev)); }, + CustomMessageOutcome::PeerNewBest(peer_id, number) => { + self.light_client_handler.update_best_block(&peer_id, number); + } CustomMessageOutcome::None => {} } } diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 3f73d761ce..b8031654df 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -20,7 +20,7 @@ //! See the documentation of [`Params`]. pub use crate::chain::{Client, FinalityProofProvider}; -pub use crate::on_demand_layer::OnDemand; +pub use crate::on_demand_layer::{AlwaysBadChecker, OnDemand}; pub use crate::service::{TransactionPool, EmptyTransactionPool}; pub use libp2p::{identity, core::PublicKey, wasm_ext::ExtTransport, build_multiaddr}; diff --git a/client/network/src/on_demand_layer.rs b/client/network/src/on_demand_layer.rs index d672ed0b7f..822901e677 100644 --- a/client/network/src/on_demand_layer.rs +++ b/client/network/src/on_demand_layer.rs @@ -16,16 +16,17 @@ //! On-demand requests service. -use crate::protocol::light_dispatch::RequestData; -use std::{collections::HashMap, pin::Pin, sync::Arc, task::Context, task::Poll}; -use futures::{prelude::*, channel::mpsc, channel::oneshot}; +use crate::protocol::light_client_handler; + +use futures::{channel::mpsc, channel::oneshot, prelude::*}; use parking_lot::Mutex; -use sp_blockchain::Error as ClientError; use sc_client_api::{ - Fetcher, FetchChecker, RemoteHeaderRequest, RemoteCallRequest, RemoteReadRequest, - RemoteChangesRequest, RemoteReadChildRequest, RemoteBodyRequest, + FetchChecker, Fetcher, RemoteBodyRequest, RemoteCallRequest, RemoteChangesRequest, + RemoteHeaderRequest, RemoteReadChildRequest, RemoteReadRequest, StorageProof, ChangesProof, }; +use sp_blockchain::Error as ClientError; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; +use std::{collections::HashMap, pin::Pin, sync::Arc, task::Context, task::Poll}; /// Implements the `Fetcher` trait of the client. Makes it possible for the light client to perform /// network requests for some state. @@ -41,13 +42,72 @@ pub struct OnDemand { /// Note that a better alternative would be to use a MPMC queue here, and add a `poll` method /// from the `OnDemand`. However there exists no popular implementation of MPMC channels in /// asynchronous Rust at the moment - requests_queue: Mutex>>>, + requests_queue: Mutex>>>, /// Sending side of `requests_queue`. - requests_send: mpsc::UnboundedSender>, + requests_send: mpsc::UnboundedSender>, +} + +/// Dummy implementation of `FetchChecker` that always assumes that responses are bad. +/// +/// Considering that it is the responsibility of the client to build the fetcher, it can use this +/// implementation if it knows that it will never perform any request. +#[derive(Default, Clone)] +pub struct AlwaysBadChecker; + +impl FetchChecker for AlwaysBadChecker { + fn check_header_proof( + &self, + _request: &RemoteHeaderRequest, + _remote_header: Option, + _remote_proof: StorageProof, + ) -> Result { + Err(ClientError::Msg("AlwaysBadChecker".into())) + } + + fn check_read_proof( + &self, + _request: &RemoteReadRequest, + _remote_proof: StorageProof, + ) -> Result,Option>>, ClientError> { + Err(ClientError::Msg("AlwaysBadChecker".into())) + } + + fn check_read_child_proof( + &self, + _request: &RemoteReadChildRequest, + _remote_proof: StorageProof, + ) -> Result, Option>>, ClientError> { + Err(ClientError::Msg("AlwaysBadChecker".into())) + } + + fn check_execution_proof( + &self, + _request: &RemoteCallRequest, + _remote_proof: StorageProof, + ) -> Result, ClientError> { + Err(ClientError::Msg("AlwaysBadChecker".into())) + } + + fn check_changes_proof( + &self, + _request: &RemoteChangesRequest, + _remote_proof: ChangesProof + ) -> Result, u32)>, ClientError> { + Err(ClientError::Msg("AlwaysBadChecker".into())) + } + + fn check_body_proof( + &self, + _request: &RemoteBodyRequest, + _body: Vec + ) -> Result, ClientError> { + Err(ClientError::Msg("AlwaysBadChecker".into())) + } } -impl OnDemand where +impl OnDemand +where B::Header: HeaderT, { /// Creates new on-demand service. @@ -74,12 +134,15 @@ impl OnDemand where /// /// If this function returns `None`, that means that the receiver has already been extracted in /// the past, and therefore that something already handles the requests. - pub(crate) fn extract_receiver(&self) -> Option>> { + pub(crate) fn extract_receiver( + &self, + ) -> Option>> { self.requests_queue.lock().take() } } -impl Fetcher for OnDemand where +impl Fetcher for OnDemand +where B: BlockT, B::Header: HeaderT, { @@ -91,40 +154,55 @@ impl Fetcher for OnDemand where fn remote_header(&self, request: RemoteHeaderRequest) -> Self::RemoteHeaderResult { let (sender, receiver) = oneshot::channel(); - let _ = self.requests_send.unbounded_send(RequestData::RemoteHeader(request, sender)); + let _ = self + .requests_send + .unbounded_send(light_client_handler::Request::Header { request, sender }); RemoteResponse { receiver } } fn remote_read(&self, request: RemoteReadRequest) -> Self::RemoteReadResult { let (sender, receiver) = oneshot::channel(); - let _ = self.requests_send.unbounded_send(RequestData::RemoteRead(request, sender)); + let _ = self + .requests_send + .unbounded_send(light_client_handler::Request::Read { request, sender }); RemoteResponse { receiver } } fn remote_read_child( &self, - request: RemoteReadChildRequest + request: RemoteReadChildRequest, ) -> Self::RemoteReadResult { let (sender, receiver) = oneshot::channel(); - let _ = self.requests_send.unbounded_send(RequestData::RemoteReadChild(request, sender)); + let _ = self + .requests_send + .unbounded_send(light_client_handler::Request::ReadChild { request, sender }); RemoteResponse { receiver } } fn remote_call(&self, request: RemoteCallRequest) -> Self::RemoteCallResult { let (sender, receiver) = oneshot::channel(); - let _ = self.requests_send.unbounded_send(RequestData::RemoteCall(request, sender)); + let _ = self + .requests_send + .unbounded_send(light_client_handler::Request::Call { request, sender }); RemoteResponse { receiver } } - fn remote_changes(&self, request: RemoteChangesRequest) -> Self::RemoteChangesResult { + fn remote_changes( + &self, + request: RemoteChangesRequest, + ) -> Self::RemoteChangesResult { let (sender, receiver) = oneshot::channel(); - let _ = self.requests_send.unbounded_send(RequestData::RemoteChanges(request, sender)); + let _ = self + .requests_send + .unbounded_send(light_client_handler::Request::Changes { request, sender }); RemoteResponse { receiver } } fn remote_body(&self, request: RemoteBodyRequest) -> Self::RemoteBodyResult { let (sender, receiver) = oneshot::channel(); - let _ = self.requests_send.unbounded_send(RequestData::RemoteBody(request, sender)); + let _ = self + .requests_send + .unbounded_send(light_client_handler::Request::Body { request, sender }); RemoteResponse { receiver } } } diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index d534bde810..357cd3baca 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -38,21 +38,20 @@ use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, NumberFor, One, Zero, CheckedSub }; use sp_arithmetic::traits::SaturatedConversion; -use message::{BlockAnnounce, BlockAttributes, Direction, FromBlock, Message, RequestId}; +use message::{BlockAnnounce, Message}; use message::generic::{Message as GenericMessage, ConsensusMessage}; -use light_dispatch::{LightDispatch, LightDispatchNetwork, RequestData}; use prometheus_endpoint::{Registry, Gauge, GaugeVec, PrometheusError, Opts, register, U64}; use sync::{ChainSync, SyncState}; use crate::service::{TransactionPool, ExHashT}; use crate::config::{BoxFinalityProofRequestBuilder, Roles}; use std::borrow::Cow; -use std::collections::{BTreeMap, HashMap, HashSet}; +use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; use std::sync::Arc; use std::fmt::Write; use std::{cmp, num::NonZeroUsize, pin::Pin, task::Poll, time}; use log::{log, Level, trace, debug, warn, error}; use crate::chain::{Client, FinalityProofProvider}; -use sc_client_api::{FetchChecker, ChangesProof, StorageProof}; +use sc_client_api::{ChangesProof, StorageProof}; use crate::error; use util::LruHashSet; use wasm_timer::Instant; @@ -74,7 +73,6 @@ pub mod block_requests; pub mod message; pub mod event; pub mod light_client_handler; -pub mod light_dispatch; pub mod sync; pub use block_requests::BlockRequests; @@ -201,9 +199,9 @@ pub struct Protocol { tick_timeout: Pin + Send>>, /// Interval at which we call `propagate_extrinsics`. propagate_timeout: Pin + Send>>, + /// Pending list of messages to return from `poll` as a priority. + pending_messages: VecDeque>, config: ProtocolConfig, - /// Handler for light client requests. - light_dispatch: LightDispatch, genesis_hash: B::Hash, sync: ChainSync, context_data: ContextData, @@ -276,132 +274,6 @@ pub struct PeerInfo { pub best_number: ::Number, } -struct LightDispatchIn<'a> { - behaviour: &'a mut GenericProto, - peerset: sc_peerset::PeersetHandle, -} - -impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a> { - fn report_peer(&mut self, who: &PeerId, reputation: sc_peerset::ReputationChange) { - self.peerset.report_peer(who.clone(), reputation) - } - - fn disconnect_peer(&mut self, who: &PeerId) { - self.behaviour.disconnect_peer(who) - } - - fn send_header_request(&mut self, who: &PeerId, id: RequestId, block: <::Header as HeaderT>::Number) { - let message: Message = message::generic::Message::RemoteHeaderRequest(message::RemoteHeaderRequest { - id, - block, - }); - - self.behaviour.send_packet(who, message.encode()) - } - - fn send_read_request( - &mut self, - who: &PeerId, - id: RequestId, - block: ::Hash, - keys: Vec>, - ) { - let message: Message = message::generic::Message::RemoteReadRequest(message::RemoteReadRequest { - id, - block, - keys, - }); - - self.behaviour.send_packet(who, message.encode()) - } - - fn send_read_child_request( - &mut self, - who: &PeerId, - id: RequestId, - block: ::Hash, - storage_key: Vec, - child_info: Vec, - child_type: u32, - keys: Vec>, - ) { - let message: Message = message::generic::Message::RemoteReadChildRequest(message::RemoteReadChildRequest { - id, - block, - storage_key, - child_info, - child_type, - keys, - }); - - self.behaviour.send_packet(who, message.encode()) - } - - fn send_call_request( - &mut self, - who: &PeerId, - id: RequestId, - block: ::Hash, - method: String, - data: Vec - ) { - let message: Message = message::generic::Message::RemoteCallRequest(message::RemoteCallRequest { - id, - block, - method, - data, - }); - - self.behaviour.send_packet(who, message.encode()) - } - - fn send_changes_request( - &mut self, - who: &PeerId, - id: RequestId, - first: ::Hash, - last: ::Hash, - min: ::Hash, - max: ::Hash, - storage_key: Option>, - key: Vec, - ) { - let message: Message = message::generic::Message::RemoteChangesRequest(message::RemoteChangesRequest { - id, - first, - last, - min, - max, - storage_key, - key, - }); - - self.behaviour.send_packet(who, message.encode()) - } - - fn send_body_request( - &mut self, - who: &PeerId, - id: RequestId, - fields: BlockAttributes, - from: FromBlock<::Hash, <::Header as HeaderT>::Number>, - to: Option<::Hash>, - direction: Direction, - max: Option - ) { - let message: Message = message::generic::Message::BlockRequest(message::BlockRequest:: { - id, - fields, - from, - to, - direction, - max, - }); - - self.behaviour.send_packet(who, message.encode()) - } -} - /// Data necessary to create a context. struct ContextData { // All connected peers @@ -444,7 +316,6 @@ impl Protocol { pub fn new( config: ProtocolConfig, chain: Arc>, - checker: Arc>, transaction_pool: Arc>, finality_proof_provider: Option>>, finality_proof_request_builder: Option>, @@ -500,13 +371,13 @@ impl Protocol { let protocol = Protocol { tick_timeout: Box::pin(interval(TICK_TIMEOUT)), propagate_timeout: Box::pin(interval(PROPAGATE_TIMEOUT)), + pending_messages: VecDeque::new(), config, context_data: ContextData { peers: HashMap::new(), stats: HashMap::new(), chain, }, - light_dispatch: LightDispatch::new(checker), genesis_hash: info.genesis_hash, sync, handshaking_peers: HashMap::new(), @@ -609,20 +480,6 @@ impl Protocol { self.sync.num_sync_requests() } - /// Starts a new data demand request. - /// - /// The parameter contains a `Sender` where the result, once received, must be sent. - pub(crate) fn add_light_client_request(&mut self, rq: RequestData) { - self.light_dispatch.add_request(LightDispatchIn { - behaviour: &mut self.behaviour, - peerset: self.peerset_handle.clone(), - }, rq); - } - - fn is_light_response(&self, who: &PeerId, response_id: message::RequestId) -> bool { - self.light_dispatch.is_light_response(&who, response_id) - } - fn handle_response( &mut self, who: PeerId, @@ -682,15 +539,10 @@ impl Protocol { GenericMessage::Status(s) => return self.on_status_message(who, s), GenericMessage::BlockRequest(r) => self.on_block_request(who, r), GenericMessage::BlockResponse(r) => { - // Note, this is safe because only `ordinary bodies` and `remote bodies` are received in this matter. - if self.is_light_response(&who, r.id) { - self.on_remote_body_response(who, r); - } else { - if let Some(request) = self.handle_response(who.clone(), &r) { - let outcome = self.on_block_response(who.clone(), request, r); - self.update_peer_info(&who); - return outcome - } + if let Some(request) = self.handle_response(who.clone(), &r) { + let outcome = self.on_block_response(who.clone(), request, r); + self.update_peer_info(&who); + return outcome } }, GenericMessage::BlockAnnounce(announce) => { @@ -701,20 +553,20 @@ impl Protocol { GenericMessage::Transactions(m) => self.on_extrinsics(who, m), GenericMessage::RemoteCallRequest(request) => self.on_remote_call_request(who, request), - GenericMessage::RemoteCallResponse(response) => - self.on_remote_call_response(who, response), + GenericMessage::RemoteCallResponse(_) => + warn!(target: "sub-libp2p", "Received unexpected RemoteCallResponse"), GenericMessage::RemoteReadRequest(request) => self.on_remote_read_request(who, request), - GenericMessage::RemoteReadResponse(response) => - self.on_remote_read_response(who, response), + GenericMessage::RemoteReadResponse(_) => + warn!(target: "sub-libp2p", "Received unexpected RemoteReadResponse"), GenericMessage::RemoteHeaderRequest(request) => self.on_remote_header_request(who, request), - GenericMessage::RemoteHeaderResponse(response) => - self.on_remote_header_response(who, response), + GenericMessage::RemoteHeaderResponse(_) => + warn!(target: "sub-libp2p", "Received unexpected RemoteHeaderResponse"), GenericMessage::RemoteChangesRequest(request) => self.on_remote_changes_request(who, request), - GenericMessage::RemoteChangesResponse(response) => - self.on_remote_changes_response(who, response), + GenericMessage::RemoteChangesResponse(_) => + warn!(target: "sub-libp2p", "Received unexpected RemoteChangesResponse"), GenericMessage::FinalityProofRequest(request) => self.on_finality_proof_request(who, request), GenericMessage::FinalityProofResponse(response) => @@ -805,10 +657,6 @@ impl Protocol { }; if let Some(_peer_data) = removed { self.sync.peer_disconnected(peer.clone()); - self.light_dispatch.on_disconnect(LightDispatchIn { - behaviour: &mut self.behaviour, - peerset: self.peerset_handle.clone(), - }, &peer); // Notify all the notification protocols as closed. CustomMessageOutcome::NotificationStreamClosed { @@ -989,10 +837,6 @@ impl Protocol { /// > **Note**: This method normally doesn't have to be called except for testing purposes. pub fn tick(&mut self) { self.maintain_peers(); - self.light_dispatch.maintain_peers(LightDispatchIn { - behaviour: &mut self.behaviour, - peerset: self.peerset_handle.clone(), - }); self.report_metrics() } @@ -1140,10 +984,7 @@ impl Protocol { }; let info = self.context_data.peers.get(&who).expect("We just inserted above; QED").info.clone(); - self.light_dispatch.on_connect(LightDispatchIn { - behaviour: &mut self.behaviour, - peerset: self.peerset_handle.clone(), - }, who.clone(), status.roles, status.best_number); + self.pending_messages.push_back(CustomMessageOutcome::PeerNewBest(who.clone(), status.best_number)); if info.roles.is_full() { match self.sync.new_peer(who.clone(), info.best_hash, info.best_number) { Ok(None) => (), @@ -1408,13 +1249,11 @@ impl Protocol { announce: BlockAnnounce, ) -> CustomMessageOutcome { let hash = announce.header.hash(); + let number = *announce.header.number(); + if let Some(ref mut peer) = self.context_data.peers.get_mut(&who) { peer.known_blocks.insert(hash.clone()); } - self.light_dispatch.update_best_number(LightDispatchIn { - behaviour: &mut self.behaviour, - peerset: self.peerset_handle.clone(), - }, who.clone(), *announce.header.number()); let is_their_best = match announce.state.unwrap_or(message::BlockState::Best) { message::BlockState::Best => true, @@ -1429,7 +1268,11 @@ impl Protocol { // 1) we're on light client; // AND // 2) parent block is already imported and not pruned. - return CustomMessageOutcome::None + if is_their_best { + return CustomMessageOutcome::PeerNewBest(who, number); + } else { + return CustomMessageOutcome::None; + } } sync::OnBlockAnnounce::ImportHeader => () // We proceed with the import. } @@ -1454,15 +1297,28 @@ impl Protocol { }, ); match blocks_to_import { - Ok(sync::OnBlockData::Import(origin, blocks)) => CustomMessageOutcome::BlockImport(origin, blocks), + Ok(sync::OnBlockData::Import(origin, blocks)) => { + if is_their_best { + self.pending_messages.push_back(CustomMessageOutcome::PeerNewBest(who, number)); + } + CustomMessageOutcome::BlockImport(origin, blocks) + }, Ok(sync::OnBlockData::Request(peer, req)) => { self.send_request(&peer, GenericMessage::BlockRequest(req)); - CustomMessageOutcome::None + if is_their_best { + CustomMessageOutcome::PeerNewBest(who, number) + } else { + CustomMessageOutcome::None + } } Err(sync::BadPeer(id, repu)) => { self.behaviour.disconnect_peer(&id); self.peerset_handle.report_peer(id, repu); - CustomMessageOutcome::None + if is_their_best { + CustomMessageOutcome::PeerNewBest(who, number) + } else { + CustomMessageOutcome::None + } } } } @@ -1597,18 +1453,6 @@ impl Protocol { self.sync.on_finality_proof_import(request_block, finalization_result) } - fn on_remote_call_response( - &mut self, - who: PeerId, - response: message::RemoteCallResponse - ) { - trace!(target: "sync", "Remote call response {} from {}", response.id, who); - self.light_dispatch.on_remote_call_response(LightDispatchIn { - behaviour: &mut self.behaviour, - peerset: self.peerset_handle.clone(), - }, who, response); - } - fn on_remote_read_request( &mut self, who: PeerId, @@ -1723,18 +1567,6 @@ impl Protocol { ); } - fn on_remote_read_response( - &mut self, - who: PeerId, - response: message::RemoteReadResponse - ) { - trace!(target: "sync", "Remote read response {} from {}", response.id, who); - self.light_dispatch.on_remote_read_response(LightDispatchIn { - behaviour: &mut self.behaviour, - peerset: self.peerset_handle.clone(), - }, who, response); - } - fn on_remote_header_request( &mut self, who: PeerId, @@ -1765,18 +1597,6 @@ impl Protocol { ); } - fn on_remote_header_response( - &mut self, - who: PeerId, - response: message::RemoteHeaderResponse, - ) { - trace!(target: "sync", "Remote header proof response {} from {}", response.id, who); - self.light_dispatch.on_remote_header_response(LightDispatchIn { - behaviour: &mut self.behaviour, - peerset: self.peerset_handle.clone(), - }, who, response); - } - fn on_remote_changes_request( &mut self, who: PeerId, @@ -1838,22 +1658,6 @@ impl Protocol { ); } - fn on_remote_changes_response( - &mut self, - who: PeerId, - response: message::RemoteChangesResponse, B::Hash>, - ) { - trace!(target: "sync", "Remote changes proof response {} from {} (max={})", - response.id, - who, - response.max - ); - self.light_dispatch.on_remote_changes_response(LightDispatchIn { - behaviour: &mut self.behaviour, - peerset: self.peerset_handle.clone(), - }, who, response); - } - fn on_finality_proof_request( &mut self, who: PeerId, @@ -1905,17 +1709,6 @@ impl Protocol { } } - fn on_remote_body_response( - &mut self, - peer: PeerId, - response: message::BlockResponse - ) { - self.light_dispatch.on_remote_body_response(LightDispatchIn { - behaviour: &mut self.behaviour, - peerset: self.peerset_handle.clone(), - }, peer, response); - } - fn format_stats(&self) -> String { let mut out = String::new(); for (id, stats) in &self.context_data.stats { @@ -1987,6 +1780,8 @@ pub enum CustomMessageOutcome { NotificationStreamClosed { remote: PeerId, protocols: Vec }, /// Messages have been received on one or more notifications protocols. NotificationsReceived { remote: PeerId, messages: Vec<(ConsensusEngineId, Bytes)> }, + /// Peer has a reported a new head of chain. + PeerNewBest(PeerId, NumberFor), None, } @@ -2067,6 +1862,10 @@ impl NetworkBehaviour for Protocol { Self::OutEvent > > { + if let Some(message) = self.pending_messages.pop_front() { + return Poll::Ready(NetworkBehaviourAction::GenerateEvent(message)); + } + while let Poll::Ready(Some(())) = self.tick_timeout.poll_next_unpin(cx) { self.tick(); } @@ -2221,7 +2020,6 @@ impl Drop for Protocol { #[cfg(test)] mod tests { use crate::PeerId; - use crate::protocol::light_dispatch::AlwaysBadChecker; use crate::config::{EmptyTransactionPool, Roles}; use super::{CustomMessageOutcome, Protocol, ProtocolConfig}; @@ -2240,7 +2038,6 @@ mod tests { max_parallel_downloads: 10, }, client.clone(), - Arc::new(AlwaysBadChecker), Arc::new(EmptyTransactionPool), None, None, diff --git a/client/network/src/protocol/light_client_handler.rs b/client/network/src/protocol/light_client_handler.rs index 4c228205d3..3c39be124c 100644 --- a/client/network/src/protocol/light_client_handler.rs +++ b/client/network/src/protocol/light_client_handler.rs @@ -29,7 +29,7 @@ use codec::{self, Encode, Decode}; use crate::{ chain::Client, config::ProtocolId, - protocol::{api, light_dispatch::TIMEOUT_REPUTATION_CHANGE} + protocol::{api, message::BlockAttributes} }; use futures::{channel::oneshot, future::BoxFuture, prelude::*, stream::FuturesUnordered}; use libp2p::{ @@ -74,6 +74,9 @@ use std::{ use void::Void; use wasm_timer::Instant; +/// Reputation change for a peer when a request timed out. +pub(crate) const TIMEOUT_REPUTATION_CHANGE: i32 = -(1 << 8); + /// Configuration options for `LightClientHandler` behaviour. #[derive(Debug, Clone)] pub struct Config { @@ -82,7 +85,8 @@ pub struct Config { max_pending_requests: usize, inactivity_timeout: Duration, request_timeout: Duration, - protocol: Bytes, + light_protocol: Bytes, + block_protocol: Bytes, } impl Config { @@ -100,7 +104,8 @@ impl Config { max_pending_requests: 128, inactivity_timeout: Duration::from_secs(15), request_timeout: Duration::from_secs(15), - protocol: Bytes::new(), + light_protocol: Bytes::new(), + block_protocol: Bytes::new(), }; c.set_protocol(id); c @@ -138,11 +143,18 @@ impl Config { /// Set protocol to use for upgrade negotiation. pub fn set_protocol(&mut self, id: &ProtocolId) -> &mut Self { - let mut v = Vec::new(); - v.extend_from_slice(b"/"); - v.extend_from_slice(id.as_bytes()); - v.extend_from_slice(b"/light/2"); - self.protocol = v.into(); + let mut vl = Vec::new(); + vl.extend_from_slice(b"/"); + vl.extend_from_slice(id.as_bytes()); + vl.extend_from_slice(b"/light/2"); + self.light_protocol = vl.into(); + + let mut vb = Vec::new(); + vb.extend_from_slice(b"/"); + vb.extend_from_slice(id.as_bytes()); + vb.extend_from_slice(b"/sync/2"); + self.block_protocol = vb.into(); + self } } @@ -176,6 +188,10 @@ pub enum Error { // used because we currently only support a subset of those. #[derive(Debug)] pub enum Request { + Body { + request: fetcher::RemoteBodyRequest, + sender: oneshot::Sender, ClientError>> + }, Header { request: fetcher::RemoteHeaderRequest, sender: oneshot::Sender> @@ -208,7 +224,8 @@ enum Reply { VecU8(Vec), VecNumberU32(Vec<(::Number, u32)>), MapVecU8OptVecU8(HashMap, Option>>), - Header(B::Header) + Header(B::Header), + Extrinsics(Vec), } /// Augments a light client request with metadata. @@ -291,6 +308,7 @@ where /// means to determine it ourselves. pub fn update_best_block(&mut self, peer: &PeerId, num: NumberFor) { if let Some(info) = self.peers.get_mut(peer) { + log::trace!("new best block for {:?}: {:?}", peer, num); info.best_block = Some(num) } } @@ -360,10 +378,23 @@ where ( &mut self , peer: &PeerId , request: &Request - , response: api::v1::light::Response + , response: Response ) -> Result, Error> { log::trace!("response from {}", peer); + match response { + Response::Light(r) => self.on_response_light(peer, request, r), + Response::Block(r) => self.on_response_block(peer, request, r), + } + } + + fn on_response_light + ( &mut self + , peer: &PeerId + , request: &Request + , response: api::v1::light::Response + ) -> Result, Error> + { use api::v1::light::response::Response; match response.response { Some(Response::RemoteCallResponse(response)) => @@ -429,6 +460,32 @@ where } } + fn on_response_block + ( &mut self + , peer: &PeerId + , request: &Request + , response: api::v1::BlockResponse + ) -> Result, Error> + { + let request = if let Request::Body { request , .. } = &request { + request + } else { + return Err(Error::UnexpectedResponse); + }; + + let body: Vec<_> = match response.blocks.into_iter().next() { + Some(b) => b.body, + None => return Err(Error::UnexpectedResponse), + }; + + let body = body.into_iter() + .map(|mut extrinsic| B::Extrinsic::decode(&mut &extrinsic[..])) + .collect::>()?; + + let body = self.checker.check_body_proof(&request, body)?; + Ok(Reply::Extrinsics(body)) + } + fn on_remote_call_request ( &mut self , peer: &PeerId @@ -664,7 +721,7 @@ where fn new_handler(&mut self) -> Self::ProtocolsHandler { let p = InboundProtocol { max_request_size: self.config.max_request_size, - protocol: self.config.protocol.clone(), + protocol: self.config.light_protocol.clone(), }; OneShotHandler::new(SubstreamProtocol::new(p), self.config.inactivity_timeout) } @@ -839,30 +896,40 @@ where } }; if let Some(peer) = available_peer { - let rq = serialize_request(&request.request); - let mut buf = Vec::with_capacity(rq.encoded_len()); - if let Err(e) = rq.encode(&mut buf) { - log::debug!("failed to serialize request: {}", e); - send_reply(Err(ClientError::RemoteFetchFailed), request.request) - } else { - let id = self.next_request_id(); - log::trace!("sending request {} to peer {}", id, peer); - let protocol = OutboundProtocol { - request: buf, - request_id: id, - max_response_size: self.config.max_response_size, - protocol: self.config.protocol.clone(), - }; - self.peers.get_mut(&peer).map(|info| info.status = PeerStatus::BusyWith(id)); - let rw = RequestWrapper { - timestamp: request.timestamp, - retries: request.retries, - request: request.request, - peer: peer.clone(), - }; - self.outstanding.insert(id, rw); - return Poll::Ready(NetworkBehaviourAction::SendEvent { peer_id: peer, event: protocol }) - } + let buf = match serialize_request(&request.request) { + Ok(b) => b, + Err(e) => { + log::debug!("failed to serialize request: {}", e); + send_reply(Err(ClientError::RemoteFetchFailed), request.request); + continue; + } + }; + + let id = self.next_request_id(); + log::trace!("sending request {} to peer {}", id, peer); + let protocol = OutboundProtocol { + request: buf, + request_id: id, + expected: match request.request { + Request::Body { .. } => ExpectedResponseTy::Block, + _ => ExpectedResponseTy::Light, + }, + max_response_size: self.config.max_response_size, + protocol: match request.request { + Request::Body { .. } => self.config.block_protocol.clone(), + _ => self.config.light_protocol.clone(), + }, + }; + self.peers.get_mut(&peer).map(|info| info.status = PeerStatus::BusyWith(id)); + let rw = RequestWrapper { + timestamp: request.timestamp, + retries: request.retries, + request: request.request, + peer: peer.clone(), + }; + self.outstanding.insert(id, rw); + return Poll::Ready(NetworkBehaviourAction::SendEvent { peer_id: peer, event: protocol }) + } else { self.pending_requests.push_front(request); log::debug!("no peer available to send request to"); @@ -903,6 +970,7 @@ where fn required_block(request: &Request) -> NumberFor { match request { + Request::Body { request, .. } => *request.header.number(), Request::Header { request, .. } => request.block, Request::Read { request, .. } => *request.header.number(), Request::ReadChild { request, .. } => *request.header.number(), @@ -913,6 +981,7 @@ fn required_block(request: &Request) -> NumberFor { fn retries(request: &Request) -> usize { let rc = match request { + Request::Body { request, .. } => request.retry_count, Request::Header { request, .. } => request.retry_count, Request::Read { request, .. } => request.retry_count, Request::ReadChild { request, .. } => request.retry_count, @@ -922,8 +991,20 @@ fn retries(request: &Request) -> usize { rc.unwrap_or(0) } -fn serialize_request(request: &Request) -> api::v1::light::Request { +fn serialize_request(request: &Request) -> Result, prost::EncodeError> { let request = match request { + Request::Body { request, .. } => { + let rq = api::v1::BlockRequest { + fields: u32::from(BlockAttributes::BODY.bits()), + from_block: Some(api::v1::block_request::FromBlock::Hash(request.header.hash().encode())), + to_block: Vec::new(), + direction: api::v1::Direction::Ascending as i32, + max_blocks: 1, + }; + let mut buf = Vec::with_capacity(rq.encoded_len()); + rq.encode(&mut buf)?; + return Ok(buf); + } Request::Header { request, .. } => { let r = api::v1::light::RemoteHeaderRequest { block: request.block.encode() }; api::v1::light::request::Request::RemoteHeaderRequest(r) @@ -966,7 +1047,10 @@ fn serialize_request(request: &Request) -> api::v1::light::Request } }; - api::v1::light::Request { request: Some(request) } + let rq = api::v1::light::Request { request: Some(request) }; + let mut buf = Vec::with_capacity(rq.encoded_len()); + rq.encode(&mut buf)?; + Ok(buf) } fn send_reply(result: Result, ClientError>, request: Request) { @@ -974,6 +1058,11 @@ fn send_reply(result: Result, ClientError>, request: Request< let _ = sender.send(item); // It is okay if the other end already hung up. } match request { + Request::Body { request, sender } => match result { + Err(e) => send(Err(e), sender), + Ok(Reply::Extrinsics(x)) => send(Ok(x), sender), + reply => log::error!("invalid reply for body request: {:?}, {:?}", reply, request), + } Request::Header { request, sender } => match result { Err(e) => send(Err(e), sender), Ok(Reply::Header(x)) => send(Ok(x), sender), @@ -1008,7 +1097,16 @@ pub enum Event { /// Incoming request from remote and substream to use for the response. Request(api::v1::light::Request, T), /// Incoming response from remote. - Response(u64, api::v1::light::Response), + Response(u64, Response), +} + +/// Incoming response from remote. +#[derive(Debug, Clone)] +pub enum Response { + /// Incoming light response from remote. + Light(api::v1::light::Response), + /// Incoming block response from remote. + Block(api::v1::BlockResponse), } /// Substream upgrade protocol. @@ -1023,23 +1121,23 @@ pub struct InboundProtocol { } impl UpgradeInfo for InboundProtocol { - type Info = Bytes; - type InfoIter = iter::Once; + type Info = Bytes; + type InfoIter = iter::Once; - fn protocol_info(&self) -> Self::InfoIter { - iter::once(self.protocol.clone()) - } + fn protocol_info(&self) -> Self::InfoIter { + iter::once(self.protocol.clone()) + } } impl InboundUpgrade for InboundProtocol where T: AsyncRead + AsyncWrite + Unpin + Send + 'static { - type Output = Event; - type Error = ReadOneError; - type Future = BoxFuture<'static, Result>; + type Output = Event; + type Error = ReadOneError; + type Future = BoxFuture<'static, Result>; - fn upgrade_inbound(self, mut s: T, _: Self::Info) -> Self::Future { + fn upgrade_inbound(self, mut s: T, _: Self::Info) -> Self::Future { let future = async move { let vec = read_one(&mut s, self.max_request_size).await?; match api::v1::light::Request::decode(&vec[..]) { @@ -1060,38 +1158,59 @@ pub struct OutboundProtocol { request: Vec, /// Local identifier for the request. Used to associate it with a response. request_id: u64, + /// Kind of response expected for this request. + expected: ExpectedResponseTy, /// The max. response length in bytes. max_response_size: usize, /// The protocol to use for upgrade negotiation. protocol: Bytes, } +/// Type of response expected from the remote for this request. +#[derive(Debug, Clone)] +enum ExpectedResponseTy { + Light, + Block, +} + impl UpgradeInfo for OutboundProtocol { - type Info = Bytes; - type InfoIter = iter::Once; + type Info = Bytes; + type InfoIter = iter::Once; - fn protocol_info(&self) -> Self::InfoIter { - iter::once(self.protocol.clone()) - } + fn protocol_info(&self) -> Self::InfoIter { + iter::once(self.protocol.clone()) + } } impl OutboundUpgrade for OutboundProtocol where T: AsyncRead + AsyncWrite + Unpin + Send + 'static { - type Output = Event; - type Error = ReadOneError; - type Future = BoxFuture<'static, Result>; + type Output = Event; + type Error = ReadOneError; + type Future = BoxFuture<'static, Result>; - fn upgrade_outbound(self, mut s: T, _: Self::Info) -> Self::Future { + fn upgrade_outbound(self, mut s: T, _: Self::Info) -> Self::Future { let future = async move { write_one(&mut s, &self.request).await?; let vec = read_one(&mut s, self.max_response_size).await?; - api::v1::light::Response::decode(&vec[..]) - .map(|r| Event::Response(self.request_id, r)) - .map_err(|e| { - ReadOneError::Io(io::Error::new(io::ErrorKind::Other, e)) - }) + + match self.expected { + ExpectedResponseTy::Light => { + api::v1::light::Response::decode(&vec[..]) + .map(|r| Event::Response(self.request_id, Response::Light(r))) + .map_err(|e| { + ReadOneError::Io(io::Error::new(io::ErrorKind::Other, e)) + }) + }, + ExpectedResponseTy::Block => { + api::v1::BlockResponse::decode(&vec[..]) + .map(|r| Event::Response(self.request_id, Response::Block(r))) + .map_err(|e| { + ReadOneError::Io(io::Error::new(io::ErrorKind::Other, e)) + }) + } + } }; future.boxed() } @@ -1117,7 +1236,7 @@ mod tests { use crate::{ chain::Client, config::ProtocolId, - protocol::{api, light_dispatch::tests::{DummyFetchChecker, dummy_header}} + protocol::api, }; use futures::{channel::oneshot, prelude::*}; use libp2p::{ @@ -1139,15 +1258,15 @@ mod tests { use sp_blockchain::{Error as ClientError}; use sp_core::storage::ChildInfo; use std::{ - collections::HashSet, + collections::{HashMap, HashSet}, io, iter::{self, FromIterator}, pin::Pin, sync::Arc, task::{Context, Poll} }; - use sp_runtime::{generic::Header, traits::BlakeTwo256}; - use super::{Event, LightClientHandler, Request, OutboundProtocol, PeerStatus}; + use sp_runtime::{generic::Header, traits::{BlakeTwo256, Block as BlockT, NumberFor}}; + use super::{Event, LightClientHandler, Request, Response, OutboundProtocol, PeerStatus}; use void::Void; const CHILD_INFO: ChildInfo<'static> = ChildInfo::new_default(b"foobarbaz"); @@ -1162,7 +1281,7 @@ mod tests { fn make_swarm(ok: bool, ps: sc_peerset::PeersetHandle, cf: super::Config) -> Swarm { let client = Arc::new(substrate_test_runtime_client::new()); - let checker = Arc::new(DummyFetchChecker::new(ok)); + let checker = Arc::new(DummyFetchChecker { ok, _mark: std::marker::PhantomData }); let id_key = identity::Keypair::generate_ed25519(); let dh_key = Keypair::::new().into_authentic(&id_key).unwrap(); let local_peer = id_key.public().into_peer_id(); @@ -1176,10 +1295,104 @@ mod tests { Swarm::new(transport, LightClientHandler::new(cf, client, checker, ps), local_peer) } + struct DummyFetchChecker { + ok: bool, + _mark: std::marker::PhantomData + } + + impl fetcher::FetchChecker for DummyFetchChecker { + fn check_header_proof( + &self, + _request: &fetcher::RemoteHeaderRequest, + header: Option, + _remote_proof: fetcher::StorageProof, + ) -> Result { + match self.ok { + true if header.is_some() => Ok(header.unwrap()), + _ => Err(ClientError::Backend("Test error".into())), + } + } + + fn check_read_proof( + &self, + request: &fetcher::RemoteReadRequest, + _: fetcher::StorageProof, + ) -> Result, Option>>, ClientError> { + match self.ok { + true => Ok(request.keys + .iter() + .cloned() + .map(|k| (k, Some(vec![42]))) + .collect() + ), + false => Err(ClientError::Backend("Test error".into())), + } + } + + fn check_read_child_proof( + &self, + request: &fetcher::RemoteReadChildRequest, + _: fetcher::StorageProof, + ) -> Result, Option>>, ClientError> { + match self.ok { + true => Ok(request.keys + .iter() + .cloned() + .map(|k| (k, Some(vec![42]))) + .collect() + ), + false => Err(ClientError::Backend("Test error".into())), + } + } + + fn check_execution_proof( + &self, + _: &fetcher::RemoteCallRequest, + _: fetcher::StorageProof, + ) -> Result, ClientError> { + match self.ok { + true => Ok(vec![42]), + false => Err(ClientError::Backend("Test error".into())), + } + } + + fn check_changes_proof( + &self, + _: &fetcher::RemoteChangesRequest, + _: fetcher::ChangesProof + ) -> Result, u32)>, ClientError> { + match self.ok { + true => Ok(vec![(100.into(), 2)]), + false => Err(ClientError::Backend("Test error".into())), + } + } + + fn check_body_proof( + &self, + _: &fetcher::RemoteBodyRequest, + body: Vec + ) -> Result, ClientError> { + match self.ok { + true => Ok(body), + false => Err(ClientError::Backend("Test error".into())), + } + } + } + fn make_config() -> super::Config { super::Config::new(&ProtocolId::from(&b"foo"[..])) } + fn dummy_header() -> sp_test_primitives::Header { + sp_test_primitives::Header { + parent_hash: Default::default(), + number: 0, + state_root: Default::default(), + extrinsics_root: Default::default(), + digest: Default::default(), + } + } + struct EmptyPollParams(PeerId); impl PollParameters for EmptyPollParams { @@ -1222,7 +1435,7 @@ mod tests { ) -> LightClientHandler { let client = Arc::new(substrate_test_runtime_client::new()); - let checker = Arc::new(DummyFetchChecker::new(ok)); + let checker = Arc::new(DummyFetchChecker { ok, _mark: std::marker::PhantomData }); LightClientHandler::new(cf, client, checker, ps) } @@ -1349,7 +1562,7 @@ mod tests { } }; - behaviour.inject_node_event(peer.clone(), Event::Response(request_id, response)); + behaviour.inject_node_event(peer.clone(), Event::Response(request_id, Response::Light(response))); assert!(behaviour.peers.is_empty()); poll(&mut behaviour); // More progress @@ -1378,7 +1591,7 @@ mod tests { } }; - behaviour.inject_node_event(peer.clone(), Event::Response(2347895932, response)); + behaviour.inject_node_event(peer.clone(), Event::Response(2347895932, Response::Light(response))); assert!(behaviour.peers.is_empty()); poll(&mut behaviour); @@ -1420,7 +1633,7 @@ mod tests { } }; - behaviour.inject_node_event(peer.clone(), Event::Response(request_id, response)); + behaviour.inject_node_event(peer.clone(), Event::Response(request_id, Response::Light(response))); assert!(behaviour.peers.is_empty()); poll(&mut behaviour); // More progress @@ -1472,7 +1685,7 @@ mod tests { response: Some(api::v1::light::response::Response::RemoteCallResponse(r)) } }; - behaviour.inject_node_event(responding_peer, Event::Response(request_id, response.clone())); + behaviour.inject_node_event(responding_peer, Event::Response(request_id, Response::Light(response.clone()))); assert_matches!(poll(&mut behaviour), Poll::Ready(NetworkBehaviourAction::SendEvent { .. })); assert_matches!(chan.1.try_recv(), Ok(None)) } @@ -1485,7 +1698,7 @@ mod tests { response: Some(api::v1::light::response::Response::RemoteCallResponse(r)), } }; - behaviour.inject_node_event(responding_peer, Event::Response(request_id, response)); + behaviour.inject_node_event(responding_peer, Event::Response(request_id, Response::Light(response))); assert_matches!(poll(&mut behaviour), Poll::Pending); assert_matches!(chan.1.try_recv(), Ok(Some(Err(ClientError::RemoteFetchFailed)))) } @@ -1499,6 +1712,7 @@ mod tests { assert_eq!(1, behaviour.peers.len()); let response = match request { + Request::Body { .. } => unimplemented!(), Request::Header{..} => { let r = api::v1::light::RemoteHeaderResponse { header: dummy_header().encode(), @@ -1548,7 +1762,7 @@ mod tests { assert_eq!(1, behaviour.outstanding.len()); assert_eq!(1, *behaviour.outstanding.keys().next().unwrap()); - behaviour.inject_node_event(peer.clone(), Event::Response(1, response)); + behaviour.inject_node_event(peer.clone(), Event::Response(1, Response::Light(response))); poll(&mut behaviour); diff --git a/client/network/src/protocol/light_dispatch.rs b/client/network/src/protocol/light_dispatch.rs deleted file mode 100644 index 39e90881fb..0000000000 --- a/client/network/src/protocol/light_dispatch.rs +++ /dev/null @@ -1,1313 +0,0 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Light client requests service. -//! -//! Handles requests for data coming from our local light client and that must be answered by -//! nodes on the network. - -use std::collections::{HashMap, VecDeque}; -use std::sync::Arc; -use std::time::Duration; -use wasm_timer::Instant; -use log::{trace, info}; -use futures::channel::oneshot::{Sender as OneShotSender}; -use linked_hash_map::{Entry, LinkedHashMap}; -use sp_blockchain::Error as ClientError; -use sc_client_api::{FetchChecker, RemoteHeaderRequest, - RemoteCallRequest, RemoteReadRequest, RemoteChangesRequest, ChangesProof, - RemoteReadChildRequest, RemoteBodyRequest, StorageProof}; -use crate::protocol::message::{self, BlockAttributes, Direction, FromBlock, RequestId}; -use libp2p::PeerId; -use crate::config::Roles; -use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; -use sc_peerset::ReputationChange; - -/// Remote request timeout. -const REQUEST_TIMEOUT: Duration = Duration::from_secs(15); -/// Default request retry count. -const RETRY_COUNT: usize = 1; -/// Reputation change for a peer when a request timed out. -pub(crate) const TIMEOUT_REPUTATION_CHANGE: i32 = -(1 << 8); - -/// Trait used by the `LightDispatch` service to communicate messages back to the network. -pub trait LightDispatchNetwork { - /// Adjusts the reputation of the given peer. - fn report_peer(&mut self, who: &PeerId, reputation_change: ReputationChange); - - /// Disconnect from the given peer. Used in case of misbehaviour. - fn disconnect_peer(&mut self, who: &PeerId); - - /// Send to `who` a request for a header. - fn send_header_request(&mut self, who: &PeerId, id: RequestId, block: <::Header as HeaderT>::Number); - - /// Send to `who` a read request. - fn send_read_request( - &mut self, - who: &PeerId, - id: RequestId, - block: ::Hash, - keys: Vec>, - ); - - /// Send to `who` a child read request. - fn send_read_child_request( - &mut self, - who: &PeerId, - id: RequestId, - block: ::Hash, - storage_key: Vec, - child_info: Vec, - child_type: u32, - keys: Vec>, - ); - - /// Send to `who` a call request. - fn send_call_request( - &mut self, - who: &PeerId, - id: RequestId, - block: ::Hash, - method: String, - data: Vec - ); - - /// Send to `who` a changes request. - fn send_changes_request( - &mut self, - who: &PeerId, - id: RequestId, - first: ::Hash, - last: ::Hash, - min: ::Hash, - max: ::Hash, - storage_key: Option>, - key: Vec, - ); - - /// Send to `who` a body request. - fn send_body_request( - &mut self, - who: &PeerId, - id: RequestId, - fields: BlockAttributes, - from: FromBlock<::Hash, <::Header as HeaderT>::Number>, - to: Option, - direction: Direction, - max: Option - ); -} - -/// Light client requests service. Dispatches requests to appropriate peers. -pub struct LightDispatch { - /// Verifies that responses are correct. Passed at initialization. - checker: Arc>, - /// Numeric ID to assign to the next outgoing request. Used to assign responses to their - /// corresponding request. - next_request_id: u64, - /// Requests that we have yet to send out on the network. - pending_requests: VecDeque>, - /// List of nodes to which we have sent a request and that are yet to answer. - active_peers: LinkedHashMap>, - /// List of nodes that we know of that aren't doing anything and that are available for new - /// requests. - idle_peers: VecDeque, - /// Best known block for each node in `active_peers` and `idle_peers`. - best_blocks: HashMap>, -} - -struct Request { - id: u64, - /// When the request got created or sent out to the network. - timestamp: Instant, - /// Number of remaining attempts to fulfill this request. If it reaches 0, we interrupt the - /// attempt. - retry_count: usize, - data: RequestData, -} - -/// One request for data made by the `Client`. -/// -/// Contains a `Sender` where to send the result. -pub(crate) enum RequestData { - RemoteBody(RemoteBodyRequest, OneShotSender, ClientError>>), - RemoteHeader(RemoteHeaderRequest, OneShotSender>), - RemoteRead( - RemoteReadRequest, - OneShotSender, Option>>, ClientError>>, - ), - RemoteReadChild( - RemoteReadChildRequest, - OneShotSender, Option>>, ClientError>> - ), - RemoteCall(RemoteCallRequest, OneShotSender, ClientError>>), - RemoteChanges( - RemoteChangesRequest, - OneShotSender, u32)>, ClientError>> - ), -} - -enum Accept { - Ok, - CheckFailed(ClientError, RequestData), - Unexpected(RequestData), -} - -/// Dummy implementation of `FetchChecker` that always assumes that responses are bad. -/// -/// Considering that it is the responsibility of the client to build the fetcher, it can use this -/// implementation if it knows that it will never perform any request. -#[derive(Default, Clone)] -pub struct AlwaysBadChecker; - -impl FetchChecker for AlwaysBadChecker { - fn check_header_proof( - &self, - _request: &RemoteHeaderRequest, - _remote_header: Option, - _remote_proof: StorageProof, - ) -> Result { - Err(ClientError::Msg("AlwaysBadChecker".into())) - } - - fn check_read_proof( - &self, - _request: &RemoteReadRequest, - _remote_proof: StorageProof, - ) -> Result,Option>>, ClientError> { - Err(ClientError::Msg("AlwaysBadChecker".into())) - } - - fn check_read_child_proof( - &self, - _request: &RemoteReadChildRequest, - _remote_proof: StorageProof, - ) -> Result, Option>>, ClientError> { - Err(ClientError::Msg("AlwaysBadChecker".into())) - } - - fn check_execution_proof( - &self, - _request: &RemoteCallRequest, - _remote_proof: StorageProof, - ) -> Result, ClientError> { - Err(ClientError::Msg("AlwaysBadChecker".into())) - } - - fn check_changes_proof( - &self, - _request: &RemoteChangesRequest, - _remote_proof: ChangesProof - ) -> Result, u32)>, ClientError> { - Err(ClientError::Msg("AlwaysBadChecker".into())) - } - - fn check_body_proof( - &self, - _request: &RemoteBodyRequest, - _body: Vec - ) -> Result, ClientError> { - Err(ClientError::Msg("AlwaysBadChecker".into())) - } -} - -impl LightDispatch where - B::Header: HeaderT, -{ - /// Creates new light client requests processor. - pub fn new(checker: Arc>) -> Self { - LightDispatch { - checker, - next_request_id: 0, - pending_requests: VecDeque::new(), - active_peers: LinkedHashMap::new(), - idle_peers: VecDeque::new(), - best_blocks: HashMap::new(), - } - } - - /// Inserts a new request in the list of requests to execute. - pub(crate) fn add_request(&mut self, network: impl LightDispatchNetwork, data: RequestData) { - self.insert(RETRY_COUNT, data); - self.dispatch(network); - } - - /// Inserts a new request in the list of requests to execute. - fn insert(&mut self, retry_count: usize, data: RequestData) { - let request_id = self.next_request_id; - self.next_request_id += 1; - - self.pending_requests.push_back(Request { - id: request_id, - timestamp: Instant::now(), - retry_count, - data, - }); - } - - /// Try to accept response from given peer. - fn accept_response( - &mut self, - rtype: &str, - mut network: impl LightDispatchNetwork, - peer: PeerId, - request_id: u64, - try_accept: impl FnOnce(Request, &Arc>) -> Accept - ) { - let request = match self.remove(peer.clone(), request_id) { - Some(request) => request, - None => { - info!("💔 Invalid remote {} response from peer {}", rtype, peer); - network.report_peer(&peer, ReputationChange::new_fatal("Invalid remote response")); - network.disconnect_peer(&peer); - self.remove_peer(&peer); - return; - }, - }; - - let retry_count = request.retry_count; - let (retry_count, retry_request_data) = match try_accept(request, &self.checker) { - Accept::Ok => (retry_count, None), - Accept::CheckFailed(error, retry_request_data) => { - info!("💔 Failed to check remote {} response from peer {}: {}", rtype, peer, error); - network.report_peer(&peer, ReputationChange::new_fatal("Failed remote response check")); - network.disconnect_peer(&peer); - self.remove_peer(&peer); - - if retry_count > 0 { - (retry_count - 1, Some(retry_request_data)) - } else { - trace!(target: "sync", "Failed to get remote {} response for given number of retries", rtype); - retry_request_data.fail(ClientError::RemoteFetchFailed.into()); - (0, None) - } - }, - Accept::Unexpected(retry_request_data) => { - info!("💔 Unexpected response to remote {} from peer", rtype); - network.report_peer(&peer, ReputationChange::new_fatal("Unexpected remote response")); - network.disconnect_peer(&peer); - self.remove_peer(&peer); - - (retry_count, Some(retry_request_data)) - }, - }; - - if let Some(request_data) = retry_request_data { - self.insert(retry_count, request_data); - } - - self.dispatch(network); - } - - /// Call this when we connect to a node on the network. - pub fn on_connect( - &mut self, - network: impl LightDispatchNetwork, - peer: PeerId, - role: Roles, - best_number: NumberFor - ) { - if !role.is_full() { - return; - } - - self.idle_peers.push_back(peer.clone()); - self.best_blocks.insert(peer, best_number); - - self.dispatch(network); - } - - /// Sets the best seen block for the given node. - pub fn update_best_number(&mut self, network: impl LightDispatchNetwork, peer: PeerId, best_number: NumberFor) { - self.best_blocks.insert(peer, best_number); - self.dispatch(network); - } - - /// Call this when we disconnect from a node. - pub fn on_disconnect(&mut self, network: impl LightDispatchNetwork, peer: &PeerId) { - self.remove_peer(peer); - self.dispatch(network); - } - - /// Must be called periodically in order to perform maintenance. - pub fn maintain_peers(&mut self, mut network: impl LightDispatchNetwork) { - let now = Instant::now(); - - loop { - match self.active_peers.front() { - Some((_, request)) if now - request.timestamp >= REQUEST_TIMEOUT => (), - _ => break, - } - - let (bad_peer, request) = self.active_peers.pop_front().expect("front() is Some as checked above"); - self.pending_requests.push_front(request); - network.report_peer(&bad_peer, ReputationChange::new(TIMEOUT_REPUTATION_CHANGE, "Light request timeout")); - network.disconnect_peer(&bad_peer); - } - - self.dispatch(network); - } - - /// Handles a remote header response message from on the network. - pub fn on_remote_header_response( - &mut self, - network: impl LightDispatchNetwork, - peer: PeerId, - response: message::RemoteHeaderResponse - ) { - self.accept_response("header", network, peer, response.id, |request, checker| match request.data { - RequestData::RemoteHeader(request, sender) => match checker.check_header_proof( - &request, - response.header, - response.proof - ) { - Ok(response) => { - // we do not bother if receiver has been dropped already - let _ = sender.send(Ok(response)); - Accept::Ok - }, - Err(error) => Accept::CheckFailed(error, RequestData::RemoteHeader(request, sender)), - }, - data => Accept::Unexpected(data), - }) - } - - /// Handles a remote read response message from on the network. - pub fn on_remote_read_response( - &mut self, - network: impl LightDispatchNetwork, - peer: PeerId, - response: message::RemoteReadResponse - ) { - self.accept_response("read", network, peer, response.id, |request, checker| match request.data { - RequestData::RemoteRead(request, sender) => { - match checker.check_read_proof(&request, response.proof) { - Ok(response) => { - // we do not bother if receiver has been dropped already - let _ = sender.send(Ok(response)); - Accept::Ok - }, - Err(error) => Accept::CheckFailed( - error, - RequestData::RemoteRead(request, sender) - ), - }}, - RequestData::RemoteReadChild(request, sender) => { - match checker.check_read_child_proof(&request, response.proof) { - Ok(response) => { - // we do not bother if receiver has been dropped already - let _ = sender.send(Ok(response)); - Accept::Ok - }, - Err(error) => Accept::CheckFailed( - error, - RequestData::RemoteReadChild(request, sender) - ), - }}, - data => Accept::Unexpected(data), - }) - } - - /// Handles a remote call response message from on the network. - pub fn on_remote_call_response( - &mut self, - network: impl LightDispatchNetwork, - peer: PeerId, - response: message::RemoteCallResponse - ) { - self.accept_response("call", network, peer, response.id, |request, checker| match request.data { - RequestData::RemoteCall(request, sender) => match checker.check_execution_proof(&request, response.proof) { - Ok(response) => { - // we do not bother if receiver has been dropped already - let _ = sender.send(Ok(response)); - Accept::Ok - }, - Err(error) => Accept::CheckFailed(error, RequestData::RemoteCall(request, sender)), - }, - data => Accept::Unexpected(data), - }) - } - - /// Handles a remote changes response message from on the network. - pub fn on_remote_changes_response( - &mut self, - network: impl LightDispatchNetwork, - peer: PeerId, - response: message::RemoteChangesResponse, B::Hash> - ) { - self.accept_response("changes", network, peer, response.id, |request, checker| match request.data { - RequestData::RemoteChanges(request, sender) => match checker.check_changes_proof( - &request, ChangesProof { - max_block: response.max, - proof: response.proof, - roots: response.roots.into_iter().collect(), - roots_proof: response.roots_proof, - }) { - Ok(response) => { - // we do not bother if receiver has been dropped already - let _ = sender.send(Ok(response)); - Accept::Ok - }, - Err(error) => Accept::CheckFailed(error, RequestData::RemoteChanges(request, sender)), - }, - data => Accept::Unexpected(data), - }) - } - - /// Handles a remote body response message from on the network. - pub fn on_remote_body_response( - &mut self, - network: impl LightDispatchNetwork, - peer: PeerId, - response: message::BlockResponse - ) { - self.accept_response("body", network, peer, response.id, |request, checker| match request.data { - RequestData::RemoteBody(request, sender) => { - let mut bodies: Vec<_> = response - .blocks - .into_iter() - .filter_map(|b| b.body) - .collect(); - - // Number of bodies are hardcoded to 1 for valid `RemoteBodyResponses` - if bodies.len() != 1 { - return Accept::CheckFailed( - "RemoteBodyResponse: invalid number of blocks".into(), - RequestData::RemoteBody(request, sender), - ) - } - let body = bodies.remove(0); - - match checker.check_body_proof(&request, body) { - Ok(body) => { - let _ = sender.send(Ok(body)); - Accept::Ok - } - Err(error) => Accept::CheckFailed(error, RequestData::RemoteBody(request, sender)), - } - } - other => Accept::Unexpected(other), - }) - } - - pub fn is_light_response(&self, peer: &PeerId, request_id: message::RequestId) -> bool { - self.active_peers.get(peer).map_or(false, |r| r.id == request_id) - } - - fn remove(&mut self, peer: PeerId, id: u64) -> Option> { - match self.active_peers.entry(peer.clone()) { - Entry::Occupied(entry) => match entry.get().id == id { - true => { - self.idle_peers.push_back(peer); - Some(entry.remove()) - }, - false => None, - }, - Entry::Vacant(_) => None, - } - } - - /// Removes a peer from the list of known peers. - /// - /// Puts back the active request that this node was performing into `pending_requests`. - fn remove_peer(&mut self, peer: &PeerId) { - self.best_blocks.remove(peer); - - if let Some(request) = self.active_peers.remove(peer) { - self.pending_requests.push_front(request); - return; - } - - if let Some(idle_index) = self.idle_peers.iter().position(|i| i == peer) { - self.idle_peers.swap_remove_back(idle_index); - } - } - - /// Dispatches pending requests. - fn dispatch(&mut self, mut network: impl LightDispatchNetwork) { - let mut last_peer = self.idle_peers.back().cloned(); - let mut unhandled_requests = VecDeque::new(); - - loop { - let peer = match self.idle_peers.pop_front() { - Some(peer) => peer, - None => break, - }; - - // check if request can (optimistically) be processed by the peer - let can_be_processed_by_peer = { - let request = match self.pending_requests.front() { - Some(r) => r, - None => { - self.idle_peers.push_front(peer); - break; - }, - }; - let peer_best_block = self.best_blocks.get(&peer) - .expect("entries are inserted into best_blocks when peer is connected; - entries are removed from best_blocks when peer is disconnected; - peer is in idle_peers and thus connected; qed"); - request.required_block() <= *peer_best_block - }; - - if !can_be_processed_by_peer { - // return peer to the back of the queue - self.idle_peers.push_back(peer.clone()); - - // we have enumerated all peers and no one can handle request - if Some(peer) == last_peer { - let request = self.pending_requests.pop_front().expect("checked in loop condition; qed"); - unhandled_requests.push_back(request); - last_peer = self.idle_peers.back().cloned(); - } - - continue; - } - - last_peer = self.idle_peers.back().cloned(); - - let mut request = self.pending_requests.pop_front().expect("checked in loop condition; qed"); - request.timestamp = Instant::now(); - trace!(target: "sync", "Dispatching remote request {} to peer {}", request.id, peer); - request.send_to(&mut network, &peer); - self.active_peers.insert(peer, request); - } - - self.pending_requests.append(&mut unhandled_requests); - } -} - -impl Request { - /// Returns the block that the remote needs to have in order to be able to fulfill - /// this request. - fn required_block(&self) -> NumberFor { - match self.data { - RequestData::RemoteHeader(ref data, _) => data.block, - RequestData::RemoteRead(ref data, _) => *data.header.number(), - RequestData::RemoteReadChild(ref data, _) => *data.header.number(), - RequestData::RemoteCall(ref data, _) => *data.header.number(), - RequestData::RemoteChanges(ref data, _) => data.max_block.0, - RequestData::RemoteBody(ref data, _) => *data.header.number(), - } - } - - fn send_to(&self, out: &mut impl LightDispatchNetwork, peer: &PeerId) { - match self.data { - RequestData::RemoteHeader(ref data, _) => - out.send_header_request( - peer, - self.id, - data.block, - ), - RequestData::RemoteRead(ref data, _) => - out.send_read_request( - peer, - self.id, - data.block, - data.keys.clone(), - ), - RequestData::RemoteReadChild(ref data, _) => - out.send_read_child_request( - peer, - self.id, - data.block, - data.storage_key.clone(), - data.child_info.clone(), - data.child_type, - data.keys.clone(), - ), - RequestData::RemoteCall(ref data, _) => - out.send_call_request( - peer, - self.id, - data.block, - data.method.clone(), - data.call_data.clone(), - ), - RequestData::RemoteChanges(ref data, _) => - out.send_changes_request( - peer, - self.id, - data.first_block.1.clone(), - data.last_block.1.clone(), - data.tries_roots.1.clone(), - data.max_block.1.clone(), - data.storage_key.clone(), - data.key.clone(), - ), - RequestData::RemoteBody(ref data, _) => - out.send_body_request( - peer, - self.id, - message::BlockAttributes::BODY, - message::FromBlock::Hash(data.header.hash()), - None, - message::Direction::Ascending, - Some(1) - ), - } - } -} - -impl RequestData { - fn fail(self, error: ClientError) { - // don't care if anyone is listening - match self { - RequestData::RemoteHeader(_, sender) => { let _ = sender.send(Err(error)); }, - RequestData::RemoteCall(_, sender) => { let _ = sender.send(Err(error)); }, - RequestData::RemoteRead(_, sender) => { let _ = sender.send(Err(error)); }, - RequestData::RemoteReadChild(_, sender) => { let _ = sender.send(Err(error)); }, - RequestData::RemoteChanges(_, sender) => { let _ = sender.send(Err(error)); }, - RequestData::RemoteBody(_, sender) => { let _ = sender.send(Err(error)); }, - } - } -} - -#[cfg(test)] -pub mod tests { - use std::collections::{HashMap, HashSet}; - use std::sync::Arc; - use std::time::Instant; - use futures::channel::oneshot; - use sp_core::storage::ChildInfo; - use sp_runtime::traits::{Block as BlockT, NumberFor, Header as HeaderT}; - use sp_blockchain::{Error as ClientError, Result as ClientResult}; - use sc_client_api::{FetchChecker, RemoteHeaderRequest, - ChangesProof, RemoteCallRequest, RemoteReadRequest, - RemoteReadChildRequest, RemoteChangesRequest, RemoteBodyRequest}; - use crate::config::Roles; - use crate::protocol::message::{self, BlockAttributes, Direction, FromBlock, RequestId}; - use libp2p::PeerId; - use super::{REQUEST_TIMEOUT, LightDispatch, LightDispatchNetwork, RequestData, StorageProof}; - use sp_test_primitives::{Block, Header}; - - pub(crate) struct DummyFetchChecker { - pub(crate) ok: bool, - _mark: std::marker::PhantomData - } - - impl DummyFetchChecker { - pub(crate) fn new(ok: bool) -> Self { - DummyFetchChecker { ok, _mark: std::marker::PhantomData } - } - } - - impl FetchChecker for DummyFetchChecker { - fn check_header_proof( - &self, - _request: &RemoteHeaderRequest, - header: Option, - _remote_proof: StorageProof, - ) -> ClientResult { - match self.ok { - true if header.is_some() => Ok(header.unwrap()), - _ => Err(ClientError::Backend("Test error".into())), - } - } - - fn check_read_proof( - &self, - request: &RemoteReadRequest, - _: StorageProof, - ) -> ClientResult, Option>>> { - match self.ok { - true => Ok(request.keys - .iter() - .cloned() - .map(|k| (k, Some(vec![42]))) - .collect() - ), - false => Err(ClientError::Backend("Test error".into())), - } - } - - fn check_read_child_proof( - &self, - request: &RemoteReadChildRequest, - _: StorageProof, - ) -> ClientResult, Option>>> { - match self.ok { - true => Ok(request.keys - .iter() - .cloned() - .map(|k| (k, Some(vec![42]))) - .collect() - ), - false => Err(ClientError::Backend("Test error".into())), - } - } - - fn check_execution_proof( - &self, - _: &RemoteCallRequest, - _: StorageProof, - ) -> ClientResult> { - match self.ok { - true => Ok(vec![42]), - false => Err(ClientError::Backend("Test error".into())), - } - } - - fn check_changes_proof( - &self, - _: &RemoteChangesRequest, - _: ChangesProof - ) -> ClientResult, u32)>> { - match self.ok { - true => Ok(vec![(100.into(), 2)]), - false => Err(ClientError::Backend("Test error".into())), - } - } - - fn check_body_proof( - &self, - _: &RemoteBodyRequest, - body: Vec - ) -> ClientResult> { - match self.ok { - true => Ok(body), - false => Err(ClientError::Backend("Test error".into())), - } - } - } - - fn dummy(ok: bool) -> LightDispatch { - LightDispatch::new(Arc::new(DummyFetchChecker::new(ok))) - } - - fn total_peers(light_dispatch: &LightDispatch) -> usize { - light_dispatch.idle_peers.len() + light_dispatch.active_peers.len() - } - - fn receive_call_response( - network_interface: impl LightDispatchNetwork, - light_dispatch: &mut LightDispatch, - peer: PeerId, - id: message::RequestId - ) { - light_dispatch.on_remote_call_response(network_interface, peer, message::RemoteCallResponse { - id: id, - proof: StorageProof::empty(), - }); - } - - pub(crate) fn dummy_header() -> Header { - Header { - parent_hash: Default::default(), - number: 0, - state_root: Default::default(), - extrinsics_root: Default::default(), - digest: Default::default(), - } - } - - #[derive(Default)] - struct DummyNetwork { - disconnected_peers: HashSet, - } - - impl<'a, B: BlockT> LightDispatchNetwork for &'a mut DummyNetwork { - fn report_peer(&mut self, _: &PeerId, _: crate::ReputationChange) {} - fn disconnect_peer(&mut self, who: &PeerId) { - self.disconnected_peers.insert(who.clone()); - } - fn send_header_request(&mut self, _: &PeerId, _: RequestId, _: <::Header as HeaderT>::Number) {} - fn send_read_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: Vec>) {} - fn send_read_child_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: Vec, - _: Vec, _: u32, _: Vec>) {} - fn send_call_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: String, _: Vec) {} - fn send_changes_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: ::Hash, - _: ::Hash, _: ::Hash, _: Option>, _: Vec) {} - fn send_body_request(&mut self, _: &PeerId, _: RequestId, _: BlockAttributes, _: FromBlock<::Hash, - <::Header as HeaderT>::Number>, _: Option, _: Direction, _: Option) {} - } - - fn assert_disconnected_peer(dummy: &DummyNetwork) { - assert_eq!(dummy.disconnected_peers.len(), 1); - } - - #[test] - fn knows_about_peers_roles() { - let mut network_interface = DummyNetwork::default(); - let mut light_dispatch = dummy(true); - let peer0 = PeerId::random(); - let peer1 = PeerId::random(); - let peer2 = PeerId::random(); - light_dispatch.on_connect(&mut network_interface, peer0, Roles::LIGHT, 1000); - light_dispatch.on_connect(&mut network_interface, peer1.clone(), Roles::FULL, 2000); - light_dispatch.on_connect(&mut network_interface, peer2.clone(), Roles::AUTHORITY, 3000); - assert_eq!(vec![peer1.clone(), peer2.clone()], light_dispatch.idle_peers.iter().cloned().collect::>()); - assert_eq!(light_dispatch.best_blocks.get(&peer1), Some(&2000)); - assert_eq!(light_dispatch.best_blocks.get(&peer2), Some(&3000)); - } - - #[test] - fn disconnects_from_idle_peer() { - let peer0 = PeerId::random(); - - let mut network_interface = DummyNetwork::default(); - let mut light_dispatch = dummy(true); - light_dispatch.on_connect(&mut network_interface, peer0.clone(), Roles::FULL, 100); - assert_eq!(1, total_peers(&light_dispatch)); - assert!(!light_dispatch.best_blocks.is_empty()); - - light_dispatch.on_disconnect(&mut network_interface, &peer0); - assert_eq!(0, total_peers(&light_dispatch)); - assert!(light_dispatch.best_blocks.is_empty()); - } - - #[test] - fn disconnects_from_timeouted_peer() { - let mut light_dispatch = dummy(true); - let mut network_interface = DummyNetwork::default(); - let peer0 = PeerId::random(); - let peer1 = PeerId::random(); - light_dispatch.on_connect(&mut network_interface, peer0.clone(), Roles::FULL, 1000); - light_dispatch.on_connect(&mut network_interface, peer1.clone(), Roles::FULL, 1000); - assert_eq!(vec![peer0.clone(), peer1.clone()], light_dispatch.idle_peers.iter().cloned().collect::>()); - assert!(light_dispatch.active_peers.is_empty()); - - light_dispatch.add_request(&mut network_interface, RequestData::RemoteCall(RemoteCallRequest { - block: Default::default(), - header: dummy_header(), - method: "test".into(), - call_data: vec![], - retry_count: None, - }, oneshot::channel().0)); - assert_eq!(vec![peer1.clone()], light_dispatch.idle_peers.iter().cloned().collect::>()); - assert_eq!(vec![peer0.clone()], light_dispatch.active_peers.keys().cloned().collect::>()); - - light_dispatch.active_peers[&peer0].timestamp = Instant::now() - REQUEST_TIMEOUT - REQUEST_TIMEOUT; - light_dispatch.maintain_peers(&mut network_interface); - assert!(light_dispatch.idle_peers.is_empty()); - assert_eq!(vec![peer1.clone()], light_dispatch.active_peers.keys().cloned().collect::>()); - assert_disconnected_peer(&network_interface); - } - - #[test] - fn disconnects_from_peer_on_response_with_wrong_id() { - let mut light_dispatch = dummy(true); - let peer0 = PeerId::random(); - let mut network_interface = DummyNetwork::default(); - light_dispatch.on_connect(&mut network_interface, peer0.clone(), Roles::FULL, 1000); - - light_dispatch.add_request(&mut network_interface, RequestData::RemoteCall(RemoteCallRequest { - block: Default::default(), - header: dummy_header(), - method: "test".into(), - call_data: vec![], - retry_count: None, - }, oneshot::channel().0)); - receive_call_response(&mut network_interface, &mut light_dispatch, peer0, 1); - assert_disconnected_peer(&network_interface); - assert_eq!(light_dispatch.pending_requests.len(), 1); - } - - #[test] - fn disconnects_from_peer_on_incorrect_response() { - let mut light_dispatch = dummy(false); - let mut network_interface = DummyNetwork::default(); - let peer0 = PeerId::random(); - light_dispatch.add_request(&mut network_interface, RequestData::RemoteCall(RemoteCallRequest { - block: Default::default(), - header: dummy_header(), - method: "test".into(), - call_data: vec![], - retry_count: Some(1), - }, oneshot::channel().0)); - - light_dispatch.on_connect(&mut network_interface, peer0.clone(), Roles::FULL, 1000); - receive_call_response(&mut network_interface, &mut light_dispatch, peer0.clone(), 0); - assert_disconnected_peer(&network_interface); - assert_eq!(light_dispatch.pending_requests.len(), 1); - } - - #[test] - fn disconnects_from_peer_on_unexpected_response() { - let mut light_dispatch = dummy(true); - let mut network_interface = DummyNetwork::default(); - let peer0 = PeerId::random(); - light_dispatch.on_connect(&mut network_interface, peer0.clone(), Roles::FULL, 1000); - - receive_call_response(&mut network_interface, &mut light_dispatch, peer0, 0); - assert_disconnected_peer(&network_interface); - } - - #[test] - fn disconnects_from_peer_on_wrong_response_type() { - let mut light_dispatch = dummy(false); - let peer0 = PeerId::random(); - let mut network_interface = DummyNetwork::default(); - light_dispatch.on_connect(&mut network_interface, peer0.clone(), Roles::FULL, 1000); - - light_dispatch.add_request(&mut network_interface, RequestData::RemoteCall(RemoteCallRequest { - block: Default::default(), - header: dummy_header(), - method: "test".into(), - call_data: vec![], - retry_count: Some(1), - }, oneshot::channel().0)); - - light_dispatch.on_remote_read_response(&mut network_interface, peer0.clone(), message::RemoteReadResponse { - id: 0, - proof: StorageProof::empty(), - }); - assert_disconnected_peer(&network_interface); - assert_eq!(light_dispatch.pending_requests.len(), 1); - } - - #[test] - fn receives_remote_failure_after_retry_count_failures() { - let retry_count = 2; - let peer_ids = (0 .. retry_count + 1).map(|_| PeerId::random()).collect::>(); - let mut light_dispatch = dummy(false); - let mut network_interface = DummyNetwork::default(); - for i in 0..retry_count+1 { - light_dispatch.on_connect(&mut network_interface, peer_ids[i].clone(), Roles::FULL, 1000); - } - - let (tx, mut response) = oneshot::channel(); - light_dispatch.add_request(&mut network_interface, RequestData::RemoteCall(RemoteCallRequest { - block: Default::default(), - header: dummy_header(), - method: "test".into(), - call_data: vec![], - retry_count: Some(retry_count) - }, tx)); - - for i in 0..retry_count { - assert!(response.try_recv().unwrap().is_none()); - receive_call_response(&mut network_interface, &mut light_dispatch, peer_ids[i].clone(), i as u64); - } - - assert!(response.try_recv().unwrap().unwrap().is_err()); - } - - #[test] - fn receives_remote_call_response() { - let mut light_dispatch = dummy(true); - let mut network_interface = DummyNetwork::default(); - let peer0 = PeerId::random(); - light_dispatch.on_connect(&mut network_interface, peer0.clone(), Roles::FULL, 1000); - - let (tx, response) = oneshot::channel(); - light_dispatch.add_request(&mut network_interface, RequestData::RemoteCall(RemoteCallRequest { - block: Default::default(), - header: dummy_header(), - method: "test".into(), - call_data: vec![], - retry_count: None, - }, tx)); - - receive_call_response(&mut network_interface, &mut light_dispatch, peer0.clone(), 0); - assert_eq!(futures::executor::block_on(response).unwrap().unwrap(), vec![42]); - } - - #[test] - fn receives_remote_read_response() { - let mut light_dispatch = dummy(true); - let mut network_interface = DummyNetwork::default(); - let peer0 = PeerId::random(); - light_dispatch.on_connect(&mut network_interface, peer0.clone(), Roles::FULL, 1000); - - let (tx, response) = oneshot::channel(); - light_dispatch.add_request(&mut network_interface, RequestData::RemoteRead(RemoteReadRequest { - header: dummy_header(), - block: Default::default(), - keys: vec![b":key".to_vec()], - retry_count: None, - }, tx)); - - light_dispatch.on_remote_read_response(&mut network_interface, peer0.clone(), message::RemoteReadResponse { - id: 0, - proof: StorageProof::empty(), - }); - assert_eq!( - futures::executor::block_on(response).unwrap().unwrap().remove(b":key".as_ref()).unwrap(), - Some(vec![42]) - ); - } - - #[test] - fn receives_remote_read_child_response() { - let mut light_dispatch = dummy(true); - let mut network_interface = DummyNetwork::default(); - let peer0 = PeerId::random(); - light_dispatch.on_connect(&mut network_interface, peer0.clone(), Roles::FULL, 1000); - - let (tx, response) = oneshot::channel(); - let child_info = ChildInfo::new_default(b"unique_id_1"); - let (child_info, child_type) = child_info.info(); - light_dispatch.add_request(&mut network_interface, RequestData::RemoteReadChild(RemoteReadChildRequest { - header: dummy_header(), - block: Default::default(), - storage_key: b":child_storage:sub".to_vec(), - child_info: child_info.to_vec(), - child_type, - keys: vec![b":key".to_vec()], - retry_count: None, - }, tx)); - - light_dispatch.on_remote_read_response(&mut network_interface, - peer0.clone(), message::RemoteReadResponse { - id: 0, - proof: StorageProof::empty(), - }); - assert_eq!(futures::executor::block_on(response).unwrap().unwrap().remove(b":key".as_ref()).unwrap(), Some(vec![42])); - } - - #[test] - fn receives_remote_header_response() { - let mut light_dispatch = dummy(true); - let mut network_interface = DummyNetwork::default(); - let peer0 = PeerId::random(); - light_dispatch.on_connect(&mut network_interface, peer0.clone(), Roles::FULL, 1000); - - let (tx, response) = oneshot::channel(); - light_dispatch.add_request(&mut network_interface, RequestData::RemoteHeader(RemoteHeaderRequest { - cht_root: Default::default(), - block: 1, - retry_count: None, - }, tx)); - - light_dispatch.on_remote_header_response(&mut network_interface, peer0.clone(), message::RemoteHeaderResponse { - id: 0, - header: Some(Header { - parent_hash: Default::default(), - number: 1, - state_root: Default::default(), - extrinsics_root: Default::default(), - digest: Default::default(), - }), - proof: StorageProof::empty(), - }); - assert_eq!( - futures::executor::block_on(response).unwrap().unwrap().hash(), - "6443a0b46e0412e626363028115a9f2cf963eeed526b8b33e5316f08b50d0dc3".parse().unwrap(), - ); - } - - #[test] - fn receives_remote_changes_response() { - let mut light_dispatch = dummy(true); - let mut network_interface = DummyNetwork::default(); - let peer0 = PeerId::random(); - light_dispatch.on_connect(&mut network_interface, peer0.clone(), Roles::FULL, 1000); - - let (tx, response) = oneshot::channel(); - light_dispatch.add_request(&mut network_interface, RequestData::RemoteChanges(RemoteChangesRequest { - changes_trie_configs: vec![sp_core::ChangesTrieConfigurationRange { - zero: (0, Default::default()), - end: None, - config: Some(sp_core::ChangesTrieConfiguration::new(4, 2)), - }], - first_block: (1, Default::default()), - last_block: (100, Default::default()), - max_block: (100, Default::default()), - tries_roots: (1, Default::default(), vec![]), - key: vec![], - storage_key: None, - retry_count: None, - }, tx)); - - light_dispatch.on_remote_changes_response(&mut network_interface, peer0.clone(), message::RemoteChangesResponse { - id: 0, - max: 1000, - proof: vec![vec![2]], - roots: vec![], - roots_proof: StorageProof::empty(), - }); - assert_eq!(futures::executor::block_on(response).unwrap().unwrap(), vec![(100, 2)]); - } - - #[test] - fn does_not_sends_request_to_peer_who_has_no_required_block() { - let mut light_dispatch = dummy(true); - let mut network_interface = DummyNetwork::default(); - let peer1 = PeerId::random(); - let peer2 = PeerId::random(); - - light_dispatch.on_connect(&mut network_interface, peer1.clone(), Roles::FULL, 100); - - light_dispatch.add_request(&mut network_interface, RequestData::RemoteHeader(RemoteHeaderRequest { - cht_root: Default::default(), - block: 200, - retry_count: None, - }, oneshot::channel().0)); - light_dispatch.add_request(&mut network_interface, RequestData::RemoteHeader(RemoteHeaderRequest { - cht_root: Default::default(), - block: 250, - retry_count: None, - }, oneshot::channel().0)); - light_dispatch.add_request(&mut network_interface, RequestData::RemoteHeader(RemoteHeaderRequest { - cht_root: Default::default(), - block: 250, - retry_count: None, - }, oneshot::channel().0)); - - light_dispatch.on_connect(&mut network_interface, peer2.clone(), Roles::FULL, 150); - - assert_eq!(vec![peer1.clone(), peer2.clone()], light_dispatch.idle_peers.iter().cloned().collect::>()); - assert_eq!(light_dispatch.pending_requests.len(), 3); - - light_dispatch.update_best_number(&mut network_interface, peer1.clone(), 250); - - assert_eq!(vec![peer2.clone()], light_dispatch.idle_peers.iter().cloned().collect::>()); - assert_eq!(light_dispatch.pending_requests.len(), 2); - - light_dispatch.update_best_number(&mut network_interface, peer2.clone(), 250); - - assert!(!light_dispatch.idle_peers.iter().any(|_| true)); - assert_eq!(light_dispatch.pending_requests.len(), 1); - - light_dispatch.on_remote_header_response(&mut network_interface, peer1.clone(), message::RemoteHeaderResponse { - id: 0, - header: Some(dummy_header()), - proof: StorageProof::empty(), - }); - - assert!(!light_dispatch.idle_peers.iter().any(|_| true)); - assert_eq!(light_dispatch.pending_requests.len(), 0); - } - - #[test] - fn does_not_loop_forever_after_dispatching_request_to_last_peer() { - // this test is a regression for a bug where the dispatch function would - // loop forever after dispatching a request to the last peer, since the - // last peer was not updated - let mut light_dispatch = dummy(true); - let mut network_interface = DummyNetwork::default(); - let peer1 = PeerId::random(); - let peer2 = PeerId::random(); - let peer3 = PeerId::random(); - - light_dispatch.add_request(&mut network_interface, RequestData::RemoteHeader(RemoteHeaderRequest { - cht_root: Default::default(), - block: 250, - retry_count: None, - }, oneshot::channel().0)); - light_dispatch.add_request(&mut network_interface, RequestData::RemoteHeader(RemoteHeaderRequest { - cht_root: Default::default(), - block: 250, - retry_count: None, - }, oneshot::channel().0)); - - light_dispatch.on_connect(&mut network_interface, peer1.clone(), Roles::FULL, 200); - light_dispatch.on_connect(&mut network_interface, peer2.clone(), Roles::FULL, 200); - light_dispatch.on_connect(&mut network_interface, peer3.clone(), Roles::FULL, 250); - - assert_eq!(vec![peer1.clone(), peer2.clone()], light_dispatch.idle_peers.iter().cloned().collect::>()); - assert_eq!(light_dispatch.pending_requests.len(), 1); - } - - #[test] - fn tries_to_send_all_pending_requests() { - let mut light_dispatch = dummy(true); - let mut network_interface = DummyNetwork::default(); - let peer1 = PeerId::random(); - - light_dispatch.add_request(&mut network_interface, RequestData::RemoteHeader(RemoteHeaderRequest { - cht_root: Default::default(), - block: 300, - retry_count: None, - }, oneshot::channel().0)); - light_dispatch.add_request(&mut network_interface, RequestData::RemoteHeader(RemoteHeaderRequest { - cht_root: Default::default(), - block: 250, - retry_count: None, - }, oneshot::channel().0)); - - light_dispatch.on_connect(&mut network_interface, peer1.clone(), Roles::FULL, 250); - - assert!(light_dispatch.idle_peers.iter().cloned().collect::>().is_empty()); - assert_eq!(light_dispatch.pending_requests.len(), 1); - } - - #[test] - fn remote_body_with_one_block_body_should_succeed() { - let mut light_dispatch = dummy(true); - let mut network_interface = DummyNetwork::default(); - let peer1 = PeerId::random(); - - let header = dummy_header(); - light_dispatch.on_connect(&mut network_interface, peer1.clone(), Roles::FULL, 250); - - light_dispatch.add_request(&mut network_interface, RequestData::RemoteBody(RemoteBodyRequest { - header: header.clone(), - retry_count: None, - }, oneshot::channel().0)); - - assert!(light_dispatch.pending_requests.is_empty()); - assert_eq!(light_dispatch.active_peers.len(), 1); - - let block = message::BlockData:: { - hash: sp_core::H256::random(), - header: None, - body: Some(Vec::new()), - message_queue: None, - receipt: None, - justification: None, - }; - - let response = message::generic::BlockResponse { - id: 0, - blocks: vec![block], - }; - - light_dispatch.on_remote_body_response(&mut network_interface, peer1.clone(), response); - - assert!(light_dispatch.active_peers.is_empty()); - assert_eq!(light_dispatch.idle_peers.len(), 1); - } - - #[test] - fn remote_body_with_three_bodies_should_fail() { - let mut light_dispatch = dummy(true); - let mut network_interface = DummyNetwork::default(); - let peer1 = PeerId::random(); - - let header = dummy_header(); - light_dispatch.on_connect(&mut network_interface, peer1.clone(), Roles::FULL, 250); - - light_dispatch.add_request(&mut network_interface, RequestData::RemoteBody(RemoteBodyRequest { - header: header.clone(), - retry_count: None, - }, oneshot::channel().0)); - - assert!(light_dispatch.pending_requests.is_empty()); - assert_eq!(light_dispatch.active_peers.len(), 1); - - let response = { - let blocks: Vec<_> = (0..3).map(|_| message::BlockData:: { - hash: sp_core::H256::random(), - header: None, - body: Some(Vec::new()), - message_queue: None, - receipt: None, - justification: None, - }).collect(); - - message::generic::BlockResponse { - id: 0, - blocks, - } - }; - - light_dispatch.on_remote_body_response(&mut network_interface, peer1.clone(), response); - assert!(light_dispatch.active_peers.is_empty()); - assert!(light_dispatch.idle_peers.is_empty(), "peer should be disconnected after bad response"); - } -} diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 4b77bdccaa..de22f203bc 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -25,31 +25,42 @@ //! The methods of the [`NetworkService`] are implemented by sending a message over a channel, //! which is then processed by [`NetworkWorker::poll`]. -use std::{borrow::Cow, collections::{HashMap, HashSet}, fs, marker::PhantomData, io, path::Path, str}; -use std::sync::{Arc, atomic::{AtomicBool, AtomicUsize, Ordering}}; -use std::pin::Pin; -use std::task::Poll; - -use sp_consensus::import_queue::{ImportQueue, Link}; -use sp_consensus::import_queue::{BlockImportResult, BlockImportError}; +use crate::{ + behaviour::{Behaviour, BehaviourOut}, + config::{parse_addr, parse_str_addr, NonReservedPeerMode, Params, TransportConfig}, + error::Error, + network_state::{ + NetworkState, NotConnectedPeer as NetworkStateNotConnectedPeer, Peer as NetworkStatePeer, + }, + on_demand_layer::AlwaysBadChecker, + protocol::{self, event::Event, light_client_handler, sync::SyncState, PeerInfo, Protocol}, + transport, ReputationChange, +}; use futures::{prelude::*, channel::mpsc}; -use log::{warn, error, info, trace}; -use libp2p::{PeerId, Multiaddr, kad::record}; use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent}; +use libp2p::{kad::record, Multiaddr, PeerId}; +use log::{error, info, trace, warn}; use parking_lot::Mutex; +use prometheus_endpoint::{ + register, Counter, CounterVec, Gauge, GaugeVec, Opts, PrometheusError, Registry, U64, +}; use sc_peerset::PeersetHandle; -use sp_runtime::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId}; -use prometheus_endpoint::{Registry, Counter, CounterVec, Gauge, GaugeVec, Opts, U64, register, PrometheusError}; - -use crate::{behaviour::{Behaviour, BehaviourOut}, config::{parse_str_addr, parse_addr}}; -use crate::{transport, config::NonReservedPeerMode, ReputationChange}; -use crate::config::{Params, TransportConfig}; -use crate::error::Error; -use crate::network_state::{NetworkState, NotConnectedPeer as NetworkStateNotConnectedPeer, Peer as NetworkStatePeer}; -use crate::protocol::{self, Protocol, PeerInfo}; -use crate::protocol::{event::Event, light_dispatch::{AlwaysBadChecker, RequestData}}; -use crate::protocol::sync::SyncState; - +use sp_consensus::import_queue::{BlockImportError, BlockImportResult, ImportQueue, Link}; +use sp_runtime::{ + traits::{Block as BlockT, NumberFor}, + ConsensusEngineId, +}; +use std::{ + borrow::Cow, + collections::{HashMap, HashSet}, + fs, io, + marker::PhantomData, + path::Path, + pin::Pin, + str, + sync::{atomic::{AtomicBool, AtomicUsize, Ordering}, Arc}, + task::Poll, +}; /// Minimum Requirements for a Hash within Networking pub trait ExHashT: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static {} @@ -240,7 +251,6 @@ impl NetworkWorker { max_parallel_downloads: params.network_config.max_parallel_downloads, }, params.chain.clone(), - checker.clone(), params.transaction_pool, params.finality_proof_provider.clone(), params.finality_proof_request_builder, @@ -773,7 +783,7 @@ pub struct NetworkWorker { /// Messages from the `NetworkService` and that must be processed. from_worker: mpsc::UnboundedReceiver>, /// Receiver for queries from the light client that must be processed. - light_client_rqs: Option>>, + light_client_rqs: Option>>, /// Senders for events that happen on the network. event_streams: Vec>, /// Prometheus network metrics. @@ -789,6 +799,7 @@ struct Metrics { import_queue_finality_proofs_submitted: Counter, import_queue_justifications_submitted: Counter, is_major_syncing: Gauge, + issued_light_requests: Counter, kbuckets_num_nodes: Gauge, network_per_sec_bytes: GaugeVec, notifications_total: CounterVec, @@ -822,6 +833,10 @@ impl Metrics { is_major_syncing: register(Gauge::new( "sub_libp2p_is_major_syncing", "Whether the node is performing a major sync or not.", )?, registry)?, + issued_light_requests: register(Counter::new( + "issued_light_requests", + "Number of light client requests that our node has issued.", + )?, registry)?, kbuckets_num_nodes: register(Gauge::new( "sub_libp2p_kbuckets_num_nodes", "Number of nodes in the Kademlia k-buckets" )?, registry)?, @@ -897,7 +912,13 @@ impl Future for NetworkWorker { // Check for new incoming light client requests. if let Some(light_client_rqs) = this.light_client_rqs.as_mut() { while let Poll::Ready(Some(rq)) = light_client_rqs.poll_next_unpin(cx) { - this.network_service.user_protocol_mut().add_light_client_request(rq); + // This can error if there are too many queued requests already. + if this.network_service.light_client_request(rq).is_err() { + log::warn!("Couldn't start light client request: too many pending requests"); + } + if let Some(metrics) = this.metrics.as_ref() { + metrics.issued_light_requests.inc(); + } } } -- GitLab From 41ded05195e6422746d6efbf433eaa65bf0557d7 Mon Sep 17 00:00:00 2001 From: cheme Date: Wed, 1 Apr 2020 19:46:40 +0200 Subject: [PATCH 134/300] State metrics possible changes (#5168) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Registering state from overlay. * fix * fix2 * Apply suggestions from code review Co-authored-by: Bastian Köcher --- client/api/src/client.rs | 10 ++- client/db/src/bench.rs | 8 +++ client/db/src/lib.rs | 34 ++++++++-- client/db/src/light.rs | 4 +- client/db/src/stats.rs | 32 ++++++++- client/db/src/storage_cache.rs | 15 ++++- client/src/call_executor.rs | 22 ++++--- client/src/light/backend.rs | 6 ++ primitives/state-machine/src/backend.rs | 13 ++-- .../state-machine/src/changes_trie/build.rs | 1 + primitives/state-machine/src/ext.rs | 1 + .../state-machine/src/in_memory_backend.rs | 7 ++ primitives/state-machine/src/lib.rs | 18 +++-- .../state-machine/src/overlayed_changes.rs | 17 ++++- .../state-machine/src/proving_backend.rs | 6 ++ primitives/state-machine/src/stats.rs | 65 ++++++++++++++++++- primitives/state-machine/src/trie_backend.rs | 6 ++ 17 files changed, 232 insertions(+), 33 deletions(-) diff --git a/client/api/src/client.rs b/client/api/src/client.rs index 06d49da640..16a5c07c34 100644 --- a/client/api/src/client.rs +++ b/client/api/src/client.rs @@ -179,8 +179,12 @@ pub struct IoInfo { pub state_reads: u64, /// State reads (keys) from cache. pub state_reads_cache: u64, - /// State reads (keys) from cache. + /// State reads (keys) pub state_writes: u64, + /// State write (keys) already cached. + pub state_writes_cache: u64, + /// State write (trie nodes) to backend db. + pub state_writes_nodes: u64, } /// Usage statistics for running client instance. @@ -202,7 +206,7 @@ impl fmt::Display for UsageInfo { f, "caches: ({} state, {} db overlay), \ state db: ({} non-canonical, {} pruning, {} pinned), \ - i/o: ({} tx, {} write, {} read, {} avg tx, {}/{} key cache reads/total, {} key writes)", + i/o: ({} tx, {} write, {} read, {} avg tx, {}/{} key cache reads/total, {} trie nodes writes)", self.memory.state_cache, self.memory.database_cache, self.memory.state_db.non_canonical, @@ -214,7 +218,7 @@ impl fmt::Display for UsageInfo { self.io.average_transaction_size, self.io.state_reads_cache, self.io.state_reads, - self.io.state_writes, + self.io.state_writes_nodes, ) } } diff --git a/client/db/src/bench.rs b/client/db/src/bench.rs index f90e85c2bf..02b30a085a 100644 --- a/client/db/src/bench.rs +++ b/client/db/src/bench.rs @@ -305,6 +305,14 @@ impl StateBackend> for BenchmarkingState { self.reopen()?; Ok(()) } + + fn register_overlay_stats(&mut self, stats: &sp_state_machine::StateMachineStats) { + self.state.borrow_mut().as_mut().map(|s| s.register_overlay_stats(stats)); + } + + fn usage_info(&self) -> sp_state_machine::UsageInfo { + self.state.borrow().as_ref().map_or(sp_state_machine::UsageInfo::empty(), |s| s.usage_info()) + } } impl std::fmt::Debug for BenchmarkingState { diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 62a8a5b43e..c5726a6cf5 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -73,7 +73,7 @@ use sc_executor::RuntimeInfo; use sp_state_machine::{ DBValue, ChangesTrieTransaction, ChangesTrieCacheAction, UsageInfo as StateUsageInfo, StorageCollection, ChildStorageCollection, - backend::Backend as StateBackend, + backend::Backend as StateBackend, StateMachineStats, }; use crate::utils::{DatabaseType, Meta, db_err, meta_keys, read_db, read_meta}; use crate::changes_tries_storage::{DbChangesTrieStorage, DbChangesTrieStorageTransaction}; @@ -256,6 +256,14 @@ impl StateBackend> for RefTrackingState { { self.state.as_trie_backend() } + + fn register_overlay_stats(&mut self, stats: &StateMachineStats) { + self.state.register_overlay_stats(stats); + } + + fn usage_info(&self) -> StateUsageInfo { + self.state.usage_info() + } } /// Database settings. @@ -1116,6 +1124,8 @@ impl Backend { let mut changeset: sc_state_db::ChangeSet> = sc_state_db::ChangeSet::default(); let mut ops: u64 = 0; let mut bytes: u64 = 0; + let mut removal: u64 = 0; + let mut bytes_removal: u64 = 0; for (key, (val, rc)) in operation.db_updates.drain() { if rc > 0 { ops += 1; @@ -1123,14 +1133,26 @@ impl Backend { changeset.inserted.push((key, val.to_vec())); } else if rc < 0 { - ops += 1; - bytes += key.len() as u64; + removal += 1; + bytes_removal += key.len() as u64; changeset.deleted.push(key); } } - self.state_usage.tally_writes(ops, bytes); + self.state_usage.tally_writes_nodes(ops, bytes); + self.state_usage.tally_removed_nodes(removal, bytes_removal); + let mut ops: u64 = 0; + let mut bytes: u64 = 0; + for (key, value) in operation.storage_updates.iter() + .chain(operation.child_storage_updates.iter().flat_map(|(_, s)| s.iter())) { + ops += 1; + bytes += key.len() as u64; + if let Some(v) = value.as_ref() { + bytes += v.len() as u64; + } + } + self.state_usage.tally_writes(ops, bytes); let number_u64 = number.saturated_into::(); let commit = self.storage.state_db.insert_block( &hash, @@ -1498,8 +1520,10 @@ impl sc_client_api::backend::Backend for Backend { reads: io_stats.reads, average_transaction_size: io_stats.avg_transaction_size() as u64, state_reads: state_stats.reads.ops, - state_reads_cache: state_stats.cache_reads.ops, state_writes: state_stats.writes.ops, + state_writes_cache: state_stats.overlay_writes.ops, + state_reads_cache: state_stats.cache_reads.ops, + state_writes_nodes: state_stats.nodes_writes.ops, }, }) } diff --git a/client/db/src/light.rs b/client/db/src/light.rs index cda1a11952..166d3ab0e1 100644 --- a/client/db/src/light.rs +++ b/client/db/src/light.rs @@ -592,8 +592,10 @@ impl LightBlockchainStorage for LightStorage average_transaction_size: io_stats.avg_transaction_size() as u64, // Light client does not track those state_reads: 0, - state_reads_cache: 0, state_writes: 0, + state_reads_cache: 0, + state_writes_cache: 0, + state_writes_nodes: 0, } }) } diff --git a/client/db/src/stats.rs b/client/db/src/stats.rs index 1d6ed8e7f0..8bc93b5b64 100644 --- a/client/db/src/stats.rs +++ b/client/db/src/stats.rs @@ -25,6 +25,10 @@ pub struct StateUsageStats { bytes_read: AtomicU64, writes: AtomicU64, bytes_written: AtomicU64, + writes_nodes: AtomicU64, + bytes_written_nodes: AtomicU64, + removed_nodes: AtomicU64, + bytes_removed_nodes: AtomicU64, reads_cache: AtomicU64, bytes_read_cache: AtomicU64, } @@ -38,6 +42,10 @@ impl StateUsageStats { bytes_read: 0.into(), writes: 0.into(), bytes_written: 0.into(), + writes_nodes: 0.into(), + bytes_written_nodes: 0.into(), + removed_nodes: 0.into(), + bytes_removed_nodes: 0.into(), reads_cache: 0.into(), bytes_read_cache: 0.into(), } @@ -70,7 +78,19 @@ impl StateUsageStats { val } - /// Tally some write operations, including their byte count. + /// Tally some write trie nodes operations, including their byte count. + pub fn tally_writes_nodes(&self, ops: u64, data_bytes: u64) { + self.writes_nodes.fetch_add(ops, AtomicOrdering::Relaxed); + self.bytes_written_nodes.fetch_add(data_bytes, AtomicOrdering::Relaxed); + } + + /// Tally some removed trie nodes operations, including their byte count. + pub fn tally_removed_nodes(&self, ops: u64, data_bytes: u64) { + self.removed_nodes.fetch_add(ops, AtomicOrdering::Relaxed); + self.bytes_removed_nodes.fetch_add(data_bytes, AtomicOrdering::Relaxed); + } + + /// Tally some write trie nodes operations, including their byte count. pub fn tally_writes(&self, ops: u64, data_bytes: u64) { self.writes.fetch_add(ops, AtomicOrdering::Relaxed); self.bytes_written.fetch_add(data_bytes, AtomicOrdering::Relaxed); @@ -80,8 +100,10 @@ impl StateUsageStats { pub fn merge_sm(&self, info: sp_state_machine::UsageInfo) { self.reads.fetch_add(info.reads.ops, AtomicOrdering::Relaxed); self.bytes_read.fetch_add(info.reads.bytes, AtomicOrdering::Relaxed); - self.writes.fetch_add(info.writes.ops, AtomicOrdering::Relaxed); - self.bytes_written.fetch_add(info.writes.bytes, AtomicOrdering::Relaxed); + self.writes_nodes.fetch_add(info.nodes_writes.ops, AtomicOrdering::Relaxed); + self.bytes_written_nodes.fetch_add(info.nodes_writes.bytes, AtomicOrdering::Relaxed); + self.removed_nodes.fetch_add(info.removed_nodes.ops, AtomicOrdering::Relaxed); + self.bytes_removed_nodes.fetch_add(info.removed_nodes.bytes, AtomicOrdering::Relaxed); self.reads_cache.fetch_add(info.cache_reads.ops, AtomicOrdering::Relaxed); self.bytes_read_cache.fetch_add(info.cache_reads.bytes, AtomicOrdering::Relaxed); } @@ -100,7 +122,11 @@ impl StateUsageStats { sp_state_machine::UsageInfo { reads: unit(&self.reads, &self.bytes_read), writes: unit(&self.writes, &self.bytes_written), + nodes_writes: unit(&self.writes_nodes, &self.bytes_written_nodes), + removed_nodes: unit(&self.removed_nodes, &self.bytes_removed_nodes), cache_reads: unit(&self.reads_cache, &self.bytes_read_cache), + modified_reads: Default::default(), + overlay_writes: Default::default(), // TODO: Proper tracking state of memory footprint here requires // imposing `MallocSizeOf` requirement on half of the codebase, // so it is an open question how to do it better diff --git a/client/db/src/storage_cache.rs b/client/db/src/storage_cache.rs index 2ac1ee3dbd..6326899263 100644 --- a/client/db/src/storage_cache.rs +++ b/client/db/src/storage_cache.rs @@ -299,6 +299,8 @@ pub struct CacheChanges { pub struct CachingState { /// Usage statistics usage: StateUsageStats, + /// State machine registered stats + overlay_stats: sp_state_machine::StateMachineStats, /// Backing state. state: S, /// Cache data. @@ -428,6 +430,7 @@ impl>, B: BlockT> CachingState { ) -> Self { CachingState { usage: StateUsageStats::new(), + overlay_stats: sp_state_machine::StateMachineStats::default(), state, cache: CacheChanges { shared_cache, @@ -663,8 +666,14 @@ impl>, B: BlockT> StateBackend> for Cachin self.state.as_trie_backend() } + fn register_overlay_stats(&mut self, stats: &sp_state_machine::StateMachineStats) { + self.overlay_stats.add(stats); + } + fn usage_info(&self) -> sp_state_machine::UsageInfo { - self.usage.take() + let mut info = self.usage.take(); + info.include_state_machine_states(&self.overlay_stats); + info } } @@ -852,6 +861,10 @@ impl>, B: BlockT> StateBackend> for Syncin .as_trie_backend() } + fn register_overlay_stats(&mut self, stats: &sp_state_machine::StateMachineStats) { + self.caching_state().register_overlay_stats(stats); + } + fn usage_info(&self) -> sp_state_machine::UsageInfo { self.caching_state().usage_info() } diff --git a/client/src/call_executor.rs b/client/src/call_executor.rs index 5a374a8102..1160449eee 100644 --- a/client/src/call_executor.rs +++ b/client/src/call_executor.rs @@ -160,36 +160,38 @@ where recorder.clone(), ); - StateMachine::new( + let changes = &mut *changes.borrow_mut(); + let mut state_machine = StateMachine::new( &backend, changes_trie_state, - &mut *changes.borrow_mut(), + changes, &self.executor, method, call_data, extensions.unwrap_or_default(), &runtime_code, self.spawn_handle.clone(), - ) + ); // TODO: https://github.com/paritytech/substrate/issues/4455 // .with_storage_transaction_cache(storage_transaction_cache.as_mut().map(|c| &mut **c)) - .execute_using_consensus_failure_handler(execution_manager, native_call) + state_machine.execute_using_consensus_failure_handler(execution_manager, native_call) }, None => { let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&state); - StateMachine::new( + let runtime_code = state_runtime_code.runtime_code()?; + let changes = &mut *changes.borrow_mut(); + let mut state_machine = StateMachine::new( &state, changes_trie_state, - &mut *changes.borrow_mut(), + changes, &self.executor, method, call_data, extensions.unwrap_or_default(), - &state_runtime_code.runtime_code()?, + &runtime_code, self.spawn_handle.clone(), - ) - .with_storage_transaction_cache(storage_transaction_cache.as_mut().map(|c| &mut **c)) - .execute_using_consensus_failure_handler(execution_manager, native_call) + ).with_storage_transaction_cache(storage_transaction_cache.as_mut().map(|c| &mut **c)); + state_machine.execute_using_consensus_failure_handler(execution_manager, native_call) } }.map_err(Into::into) } diff --git a/client/src/light/backend.rs b/client/src/light/backend.rs index 749e24af04..0b334d48b7 100644 --- a/client/src/light/backend.rs +++ b/client/src/light/backend.rs @@ -505,6 +505,12 @@ impl StateBackend for GenesisOrUnavailableState } } + fn register_overlay_stats(&mut self, _stats: &sp_state_machine::StateMachineStats) { } + + fn usage_info(&self) -> sp_state_machine::UsageInfo { + sp_state_machine::UsageInfo::empty() + } + fn as_trie_backend(&mut self) -> Option<&TrieBackend> { match self { GenesisOrUnavailableState::Genesis(ref mut state) => state.as_trie_backend(), diff --git a/primitives/state-machine/src/backend.rs b/primitives/state-machine/src/backend.rs index 4fb59556e3..94144fdb90 100644 --- a/primitives/state-machine/src/backend.rs +++ b/primitives/state-machine/src/backend.rs @@ -206,13 +206,16 @@ pub trait Backend: std::fmt::Debug { (root, txs) } + /// Register stats from overlay of state machine. + /// + /// By default nothing is registered. + fn register_overlay_stats(&mut self, _stats: &crate::stats::StateMachineStats); + /// Query backend usage statistics (i/o, memory) /// /// Not all implementations are expected to be able to do this. In the /// case when they don't, empty statistics is returned. - fn usage_info(&self) -> UsageInfo { - UsageInfo::empty() - } + fn usage_info(&self) -> UsageInfo; /// Wipe the state database. fn wipe(&self) -> Result<(), Self::Error> { @@ -308,10 +311,12 @@ impl<'a, T: Backend, H: Hasher> Backend for &'a T { (*self).for_key_values_with_prefix(prefix, f); } + fn register_overlay_stats(&mut self, _stats: &crate::stats::StateMachineStats) { } + fn usage_info(&self) -> UsageInfo { (*self).usage_info() } - } +} /// Trait that allows consolidate two transactions together. pub trait Consolidate { diff --git a/primitives/state-machine/src/changes_trie/build.rs b/primitives/state-machine/src/changes_trie/build.rs index c731d4104b..39ad81ed59 100644 --- a/primitives/state-machine/src/changes_trie/build.rs +++ b/primitives/state-machine/src/changes_trie/build.rs @@ -469,6 +469,7 @@ mod test { ].into_iter().collect(), }, collect_extrinsics: true, + stats: Default::default(), }; let config = Configuration { digest_interval: 4, digest_levels: 2 }; diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index b29446de2e..133af7ccd9 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -587,6 +587,7 @@ mod tests { ].into_iter().collect(), committed: Default::default(), collect_extrinsics: true, + stats: Default::default(), } } diff --git a/primitives/state-machine/src/in_memory_backend.rs b/primitives/state-machine/src/in_memory_backend.rs index 7e474d45b6..8cbed90e9a 100644 --- a/primitives/state-machine/src/in_memory_backend.rs +++ b/primitives/state-machine/src/in_memory_backend.rs @@ -20,6 +20,7 @@ use crate::{ StorageKey, StorageValue, StorageCollection, trie_backend::TrieBackend, backend::{Backend, insert_into_memory_db}, + stats::UsageInfo, }; use std::{error, fmt, collections::{BTreeMap, HashMap}, marker::PhantomData, ops}; use hash_db::Hasher; @@ -357,6 +358,12 @@ impl Backend for InMemory where H::Out: Codec { self.trie = Some(TrieBackend::new(mdb, root)); self.trie.as_ref() } + + fn register_overlay_stats(&mut self, _stats: &crate::stats::StateMachineStats) { } + + fn usage_info(&self) -> UsageInfo { + UsageInfo::empty() + } } #[cfg(test)] diff --git a/primitives/state-machine/src/lib.rs b/primitives/state-machine/src/lib.rs index 2d992e778e..9a2dc52cca 100644 --- a/primitives/state-machine/src/lib.rs +++ b/primitives/state-machine/src/lib.rs @@ -18,7 +18,7 @@ #![warn(missing_docs)] -use std::{fmt, result, collections::HashMap, panic::UnwindSafe, marker::PhantomData}; +use std::{fmt, result, collections::HashMap, panic::UnwindSafe}; use log::{warn, trace}; use hash_db::Hasher; use codec::{Decode, Encode, Codec}; @@ -73,7 +73,7 @@ pub use trie_backend_essence::{TrieBackendStorage, Storage}; pub use trie_backend::TrieBackend; pub use error::{Error, ExecutionError}; pub use in_memory_backend::InMemory as InMemoryBackend; -pub use stats::{UsageInfo, UsageUnit}; +pub use stats::{UsageInfo, UsageUnit, StateMachineStats}; pub use sp_core::traits::CloneableSpawn; type CallResult = Result, E>; @@ -189,9 +189,19 @@ pub struct StateMachine<'a, B, H, N, Exec> overlay: &'a mut OverlayedChanges, extensions: Extensions, changes_trie_state: Option>, - _marker: PhantomData<(H, N)>, storage_transaction_cache: Option<&'a mut StorageTransactionCache>, runtime_code: &'a RuntimeCode<'a>, + stats: StateMachineStats, +} + +impl<'a, B, H, N, Exec> Drop for StateMachine<'a, B, H, N, Exec> where + H: Hasher, + B: Backend, + N: ChangesTrieBlockNumber, +{ + fn drop(&mut self) { + self.backend.register_overlay_stats(&self.stats); + } } impl<'a, B, H, N, Exec> StateMachine<'a, B, H, N, Exec> where @@ -224,9 +234,9 @@ impl<'a, B, H, N, Exec> StateMachine<'a, B, H, N, Exec> where extensions, overlay, changes_trie_state, - _marker: PhantomData, storage_transaction_cache: None, runtime_code, + stats: StateMachineStats::default(), } } diff --git a/primitives/state-machine/src/overlayed_changes.rs b/primitives/state-machine/src/overlayed_changes.rs index 4eb44de7c5..ab50c61391 100644 --- a/primitives/state-machine/src/overlayed_changes.rs +++ b/primitives/state-machine/src/overlayed_changes.rs @@ -22,6 +22,7 @@ use crate::{ NO_EXTRINSIC_INDEX, BlockNumber, build_changes_trie, State as ChangesTrieState, }, + stats::StateMachineStats, }; #[cfg(test)] @@ -57,6 +58,8 @@ pub struct OverlayedChanges { pub(crate) committed: OverlayedChangeSet, /// True if extrinsics stats must be collected. pub(crate) collect_extrinsics: bool, + /// Collect statistic on this execution. + pub(crate) stats: StateMachineStats, } /// The storage value, used inside OverlayedChanges. @@ -206,7 +209,11 @@ impl OverlayedChanges { pub fn storage(&self, key: &[u8]) -> Option> { self.prospective.top.get(key) .or_else(|| self.committed.top.get(key)) - .map(|x| x.value.as_ref().map(AsRef::as_ref)) + .map(|x| { + let size_read = x.value.as_ref().map(|x| x.len() as u64).unwrap_or(0); + self.stats.tally_read_modified(size_read); + x.value.as_ref().map(AsRef::as_ref) + }) } /// Returns a double-Option: None if the key is unknown (i.e. and the query should be referred @@ -215,12 +222,16 @@ impl OverlayedChanges { pub fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Option> { if let Some(map) = self.prospective.children.get(storage_key) { if let Some(val) = map.0.get(key) { + let size_read = val.value.as_ref().map(|x| x.len() as u64).unwrap_or(0); + self.stats.tally_read_modified(size_read); return Some(val.value.as_ref().map(AsRef::as_ref)); } } if let Some(map) = self.committed.children.get(storage_key) { if let Some(val) = map.0.get(key) { + let size_read = val.value.as_ref().map(|x| x.len() as u64).unwrap_or(0); + self.stats.tally_read_modified(size_read); return Some(val.value.as_ref().map(AsRef::as_ref)); } } @@ -232,6 +243,8 @@ impl OverlayedChanges { /// /// `None` can be used to delete a value specified by the given key. pub(crate) fn set_storage(&mut self, key: StorageKey, val: Option) { + let size_write = val.as_ref().map(|x| x.len() as u64).unwrap_or(0); + self.stats.tally_write_overlay(size_write); let extrinsic_index = self.extrinsic_index(); let entry = self.prospective.top.entry(key).or_default(); entry.value = val; @@ -252,6 +265,8 @@ impl OverlayedChanges { key: StorageKey, val: Option, ) { + let size_write = val.as_ref().map(|x| x.len() as u64).unwrap_or(0); + self.stats.tally_write_overlay(size_write); let extrinsic_index = self.extrinsic_index(); let map_entry = self.prospective.children.entry(storage_key) .or_insert_with(|| (Default::default(), child_info.to_owned())); diff --git a/primitives/state-machine/src/proving_backend.rs b/primitives/state-machine/src/proving_backend.rs index 119fb59a72..747872af83 100644 --- a/primitives/state-machine/src/proving_backend.rs +++ b/primitives/state-machine/src/proving_backend.rs @@ -283,6 +283,12 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> { self.0.child_storage_root(storage_key, child_info, delta) } + + fn register_overlay_stats(&mut self, _stats: &crate::stats::StateMachineStats) { } + + fn usage_info(&self) -> crate::stats::UsageInfo { + self.0.usage_info() + } } /// Create proof check backend. diff --git a/primitives/state-machine/src/stats.rs b/primitives/state-machine/src/stats.rs index aa69b5be9d..8fa03344ad 100644 --- a/primitives/state-machine/src/stats.rs +++ b/primitives/state-machine/src/stats.rs @@ -17,6 +17,7 @@ //! Usage statistics for state db use std::time::{Instant, Duration}; +use std::cell::RefCell; /// Measured count of operations and total bytes. #[derive(Clone, Debug, Default)] @@ -32,10 +33,19 @@ pub struct UsageUnit { pub struct UsageInfo { /// Read statistics (total). pub reads: UsageUnit, - /// Write statistics. + /// Write statistics (total). pub writes: UsageUnit, + /// Write trie nodes statistics. + pub nodes_writes: UsageUnit, + /// Write into cached state machine + /// change overlay. + pub overlay_writes: UsageUnit, + /// Removed trie nodes statistics. + pub removed_nodes: UsageUnit, /// Cache read statistics. pub cache_reads: UsageUnit, + /// Modified value read statistics. + pub modified_reads: UsageUnit, /// Memory used. pub memory: usize, @@ -45,6 +55,35 @@ pub struct UsageInfo { pub span: Duration, } +/// Accumulated usage statistics specific to state machine +/// crate. +#[derive(Debug, Default, Clone)] +pub struct StateMachineStats { + /// Number of read query from runtime + /// that hit a modified value (in state + /// machine overlay). + pub reads_modified: RefCell, + /// Size in byte of read queries that + /// hit a modified value. + pub bytes_read_modified: RefCell, + /// Number of time a write operation + /// occurs into the state machine overlay. + pub writes_overlay: RefCell, + /// Size in bytes of the writes overlay + /// operation. + pub bytes_writes_overlay: RefCell, +} + +impl StateMachineStats { + /// Accumulates some registered stats. + pub fn add(&self, other: &StateMachineStats) { + *self.reads_modified.borrow_mut() += *other.reads_modified.borrow(); + *self.bytes_read_modified.borrow_mut() += *other.bytes_read_modified.borrow(); + *self.writes_overlay.borrow_mut() += *other.writes_overlay.borrow(); + *self.bytes_writes_overlay.borrow_mut() += *other.bytes_writes_overlay.borrow(); + } +} + impl UsageInfo { /// Empty statistics. /// @@ -53,10 +92,34 @@ impl UsageInfo { Self { reads: UsageUnit::default(), writes: UsageUnit::default(), + overlay_writes: UsageUnit::default(), + nodes_writes: UsageUnit::default(), + removed_nodes: UsageUnit::default(), cache_reads: UsageUnit::default(), + modified_reads: UsageUnit::default(), memory: 0, started: Instant::now(), span: Default::default(), } } + /// Add collected state machine to this state. + pub fn include_state_machine_states(&mut self, count: &StateMachineStats) { + self.modified_reads.ops += *count.reads_modified.borrow(); + self.modified_reads.bytes += *count.bytes_read_modified.borrow(); + self.overlay_writes.ops += *count.writes_overlay.borrow(); + self.overlay_writes.bytes += *count.bytes_writes_overlay.borrow(); + } +} + +impl StateMachineStats { + /// Tally one read modified operation, of some length. + pub fn tally_read_modified(&self, data_bytes: u64) { + *self.reads_modified.borrow_mut() += 1; + *self.bytes_read_modified.borrow_mut() += data_bytes; + } + /// Tally one write overlay operation, of some length. + pub fn tally_write_overlay(&self, data_bytes: u64) { + *self.writes_overlay.borrow_mut() += 1; + *self.bytes_writes_overlay.borrow_mut() += data_bytes; + } } diff --git a/primitives/state-machine/src/trie_backend.rs b/primitives/state-machine/src/trie_backend.rs index e64dd590e5..f88e306a2f 100644 --- a/primitives/state-machine/src/trie_backend.rs +++ b/primitives/state-machine/src/trie_backend.rs @@ -240,6 +240,12 @@ impl, H: Hasher> Backend for TrieBackend where fn as_trie_backend(&mut self) -> Option<&TrieBackend> { Some(self) } + + fn register_overlay_stats(&mut self, _stats: &crate::stats::StateMachineStats) { } + + fn usage_info(&self) -> crate::UsageInfo { + crate::UsageInfo::empty() + } } #[cfg(test)] -- GitLab From 42c06547743d5fc923be7265ef65b7cd1cb2218c Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Thu, 2 Apr 2020 11:58:30 +0200 Subject: [PATCH 135/300] ci: divide cache between branches (#5494) --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 06afc35058..ddbd74d1bf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -32,7 +32,7 @@ stages: variables: GIT_STRATEGY: fetch GIT_DEPTH: 100 - CARGO_HOME: "/ci-cache/${CI_PROJECT_NAME}/cargo/${CI_JOB_NAME}" + CARGO_HOME: "/ci-cache/${CI_PROJECT_NAME}/cargo/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME}" SCCACHE_DIR: "/ci-cache/${CI_PROJECT_NAME}/sccache" CARGO_INCREMENTAL: 0 CI_SERVER_NAME: "GitLab CI" -- GitLab From 9974d35764c7c711fd29f4fa052b455e847c6250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 2 Apr 2020 12:38:02 +0200 Subject: [PATCH 136/300] Use saturating sub in basic authorship (#5493) This pr ensures that we don't panic because of a deadline that is already reached in basic authorship. This is mainly useful for debug builds, as release builds normally don't have debug assertions enabled. --- .../basic-authorship/src/basic_authorship.rs | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index a24ba31242..b3bf486aae 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -212,7 +212,7 @@ impl ProposerInner let mut unqueue_invalid = Vec::new(); let pending_iterator = match executor::block_on(future::select( self.transaction_pool.ready_at(self.parent_number), - futures_timer::Delay::new((deadline - (self.now)()) / 8), + futures_timer::Delay::new(deadline.saturating_duration_since((self.now)()) / 8), )) { Either::Left((iterator, _)) => iterator, Either::Right(_) => { @@ -393,6 +393,36 @@ mod tests { assert_eq!(txpool.ready().count(), 2); } + #[test] + fn should_not_panic_when_deadline_is_reached() { + let client = Arc::new(substrate_test_runtime_client::new()); + let txpool = Arc::new( + BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))).0 + ); + + let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone()); + + let cell = Mutex::new((false, time::Instant::now())); + let mut proposer = proposer_factory.init_with_now( + &client.header(&BlockId::number(0)).unwrap().unwrap(), + Box::new(move || { + let mut value = cell.lock(); + if !value.0 { + value.0 = true; + return value.1; + } + let new = value.1 + time::Duration::from_secs(160); + *value = (true, new); + new + }) + ); + + let deadline = time::Duration::from_secs(1); + futures::executor::block_on( + proposer.propose(Default::default(), Default::default(), deadline, RecordProof::No) + ).map(|r| r.block).unwrap(); + } + #[test] fn proposed_storage_changes_should_match_execute_block_storage_changes() { let (client, backend) = substrate_test_runtime_client::TestClientBuilder::new() -- GitLab From 7c8f3935b9a952ba2811dd6d0ca4f16e85f63e32 Mon Sep 17 00:00:00 2001 From: cheme Date: Thu, 2 Apr 2020 15:49:08 +0200 Subject: [PATCH 137/300] companion fix --- .maintain/gitlab/check_polkadot_companion_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index 04524a736a..65e3af5c7a 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -57,7 +57,7 @@ then # get the last reference to a pr in polkadot pr_data="$(curl -sSL -H "${github_header}" -s ${github_api_substrate_pull_url}/${CI_COMMIT_REF_NAME})" pr_ref="$(echo $pr_data | grep -Po '"ref"\s*:\s*"\K(?!master)[^"]*')" - pr_body="$(echo $pr_data | sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p')" + pr_body="$(echo "$pr_data" | sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p')" pr_companion="$(echo "${pr_body}" | sed -n -r \ -e 's;^.*polkadot companion: paritytech/polkadot#([0-9]+).*$;\1;p' \ -- GitLab From b2240f16f4bd4d2224f88566209fc17a6385eaea Mon Sep 17 00:00:00 2001 From: cheme Date: Thu, 2 Apr 2020 16:28:39 +0200 Subject: [PATCH 138/300] Update .maintain/gitlab/check_polkadot_companion_build.sh --- .maintain/gitlab/check_polkadot_companion_build.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index 65e3af5c7a..e6ea27679a 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -57,7 +57,7 @@ then # get the last reference to a pr in polkadot pr_data="$(curl -sSL -H "${github_header}" -s ${github_api_substrate_pull_url}/${CI_COMMIT_REF_NAME})" pr_ref="$(echo $pr_data | grep -Po '"ref"\s*:\s*"\K(?!master)[^"]*')" - pr_body="$(echo "$pr_data" | sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p')" + pr_body="$(echo "${pr_data}" | sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p')" pr_companion="$(echo "${pr_body}" | sed -n -r \ -e 's;^.*polkadot companion: paritytech/polkadot#([0-9]+).*$;\1;p' \ @@ -102,4 +102,3 @@ cargo update # Test Polkadot pr or master branch with this Substrate commit. time cargo test --all --release --verbose - -- GitLab From f3b9f234d88bdfb63020b772736cb45c47f1d3e3 Mon Sep 17 00:00:00 2001 From: cheme Date: Thu, 2 Apr 2020 17:00:05 +0200 Subject: [PATCH 139/300] Fix compilation errors. --- client/db/src/bench.rs | 16 ++++++++++++++-- client/db/src/lib.rs | 2 +- frame/contracts/src/account_db.rs | 2 +- frame/contracts/src/exec.rs | 2 +- frame/contracts/src/lib.rs | 2 +- frame/contracts/src/tests.rs | 4 ++-- primitives/state-machine/src/backend.rs | 2 +- .../state-machine/src/changes_trie/storage.rs | 3 ++- .../state-machine/src/overlayed_changes.rs | 5 +---- .../state-machine/src/trie_backend_essence.rs | 1 - 10 files changed, 24 insertions(+), 15 deletions(-) diff --git a/client/db/src/bench.rs b/client/db/src/bench.rs index c626942084..8f55f00766 100644 --- a/client/db/src/bench.rs +++ b/client/db/src/bench.rs @@ -98,7 +98,19 @@ impl BenchmarkingState { child_delta, false, ); - state.genesis = transaction.clone().drain(); + let mut keyspace = crate::Keyspaced::new(&[]); + for (info, mut updates) in transaction.clone().into_iter() { + keyspace.change_keyspace(info.keyspace()); + for (key, rc_val) in updates.drain() { + let key = if info.is_top_trie() { + key + } else { + keyspace.prefix_key(key.as_slice()).to_vec() + }; + + state.genesis.insert(key, rc_val); + } + } state.genesis_root = root.clone(); state.commit(root, transaction)?; Ok(state) @@ -287,8 +299,8 @@ impl StateBackend> for BenchmarkingState { } else if rc < 0 { db_transaction.delete(0, &key); } + keys.push(key); } - keys.push(key); } self.record.set(keys); db.write(db_transaction).map_err(|_| String::from("Error committing transaction"))?; diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 6e8fd4eeba..f5cc98ad82 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -1169,7 +1169,7 @@ impl Backend { let mut ops: u64 = 0; let mut bytes: u64 = 0; for (key, value) in operation.storage_updates.iter() - .chain(operation.child_storage_updates.iter().flat_map(|(_, s)| s.iter())) { + .chain(operation.child_storage_updates.iter().flat_map(|(_, s, _)| s.iter())) { ops += 1; bytes += key.len() as u64; if let Some(v) = value.as_ref() { diff --git a/frame/contracts/src/account_db.rs b/frame/contracts/src/account_db.rs index 524fb376e6..14c9ead7e6 100644 --- a/frame/contracts/src/account_db.rs +++ b/frame/contracts/src/account_db.rs @@ -215,7 +215,7 @@ impl AccountDb for DirectAccountDb { new_info.last_write = Some(>::block_number()); } - let child_info = &new_info.child_trie_unique_id(); + let child_info = &new_info.child_trie_info(); for (k, v) in changed.storage.into_iter() { if let Some(value) = child::get_raw( child_info, diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index 847bfc2cc4..d8b42b2f9e 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -577,7 +577,7 @@ where { let (output, change_set, deferred) = { let mut nested = self.nested(dest, trie_id.map(|trie_id| { - crate::trie_unique_id(&trie_id) + crate::child_trie_info(&trie_id) })); let output = func(&mut nested)?; (output, nested.overlay.into_change_set(), nested.deferred) diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 52a397995f..5a439ed316 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -690,7 +690,7 @@ impl Module { .get_alive() .ok_or(ContractAccessError::IsTombstone)?; - let child_info = trie_unique_id(&contract_info.trie_id); + let child_info = child_trie_info(&contract_info.trie_id); let maybe_value = AccountDb::::get_storage( &DirectAccountDb, &address, diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 0c358b92ef..0839aa7ea6 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -311,8 +311,8 @@ fn account_removal_does_not_remove_storage() { ExtBuilder::default().existential_deposit(100).build().execute_with(|| { let trie_id1 = ::TrieIdGenerator::trie_id(&1); let trie_id2 = ::TrieIdGenerator::trie_id(&2); - let child_info1 = crate::trie_unique_id(trie_id1.as_ref()); - let child_info2 = crate::trie_unique_id(trie_id2.as_ref()); + let child_info1 = crate::child_trie_info(trie_id1.as_ref()); + let child_info2 = crate::child_trie_info(trie_id2.as_ref()); let child_info1 = Some(&child_info1); let child_info2 = Some(&child_info2); let key1 = &[1; 32]; diff --git a/primitives/state-machine/src/backend.rs b/primitives/state-machine/src/backend.rs index 32e7d41c68..0f3af4466c 100644 --- a/primitives/state-machine/src/backend.rs +++ b/primitives/state-machine/src/backend.rs @@ -21,7 +21,7 @@ use sp_core::{Hasher, InnerHasher}; use codec::{Decode, Encode}; use sp_core::{traits::RuntimeCode, - storage::{ChildInfo, ChildrenMap, well_known_keys}}; + storage::{ChildInfo, ChildrenMap, well_known_keys, PrefixedStorageKey}}; use sp_trie::{TrieMut, MemoryDB, trie_types::TrieDBMut}; use crate::{ trie_backend::TrieBackend, diff --git a/primitives/state-machine/src/changes_trie/storage.rs b/primitives/state-machine/src/changes_trie/storage.rs index 4fc32ed82f..df731b699e 100644 --- a/primitives/state-machine/src/changes_trie/storage.rs +++ b/primitives/state-machine/src/changes_trie/storage.rs @@ -17,7 +17,8 @@ //! Changes trie storage utilities. use std::collections::{BTreeMap, HashSet, HashMap}; -use hash_db::{Hasher, Prefix, EMPTY_PREFIX}; +use hash_db::{Prefix, EMPTY_PREFIX}; +use sp_core::Hasher; use sp_core::storage::PrefixedStorageKey; use sp_core::storage::ChildInfo; use sp_trie::DBValue; diff --git a/primitives/state-machine/src/overlayed_changes.rs b/primitives/state-machine/src/overlayed_changes.rs index fbdf3a5c1c..c9b6a6f6de 100644 --- a/primitives/state-machine/src/overlayed_changes.rs +++ b/primitives/state-machine/src/overlayed_changes.rs @@ -29,7 +29,7 @@ use crate::{ use std::iter::FromIterator; use std::collections::{HashMap, BTreeMap, BTreeSet}; use codec::{Decode, Encode}; -use sp_core::storage::{well_known_keys::EXTRINSIC_INDEX, ChildInfo}; +use sp_core::storage::{well_known_keys::EXTRINSIC_INDEX, ChildInfo, PrefixedStorageKey}; use std::{mem, ops}; use sp_core::Hasher; @@ -37,9 +37,6 @@ use sp_core::Hasher; /// Storage key. pub type StorageKey = Vec; -/// Storage key. -pub type PrefixedStorageKey = Vec; - /// Storage value. pub type StorageValue = Vec; diff --git a/primitives/state-machine/src/trie_backend_essence.rs b/primitives/state-machine/src/trie_backend_essence.rs index 0dc7174c20..4c8cde131c 100644 --- a/primitives/state-machine/src/trie_backend_essence.rs +++ b/primitives/state-machine/src/trie_backend_essence.rs @@ -383,7 +383,6 @@ impl<'a, S, H> hash_db::HashDBRef for BackendStorageDBRef<'a, S, H> } } - /// Key-value pairs storage that is used by trie backend essence. pub trait TrieBackendStorageRef { /// Type of in-memory overlay. -- GitLab From 63943ee00a222a1a910e7261b33f3c9d2bb92605 Mon Sep 17 00:00:00 2001 From: cheme Date: Thu, 2 Apr 2020 17:28:17 +0200 Subject: [PATCH 140/300] last attempt --- .maintain/gitlab/check_polkadot_companion_build.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index e6ea27679a..49d247da4e 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -56,19 +56,24 @@ then # get the last reference to a pr in polkadot pr_data="$(curl -sSL -H "${github_header}" -s ${github_api_substrate_pull_url}/${CI_COMMIT_REF_NAME})" + boldprint "pr_dta: #${pr_data}" pr_ref="$(echo $pr_data | grep -Po '"ref"\s*:\s*"\K(?!master)[^"]*')" + boldprint "pr_ref: #${pr_ref}" pr_body="$(echo "${pr_data}" | sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p')" + boldprint "pr_body: #${pr_body}" pr_companion="$(echo "${pr_body}" | sed -n -r \ -e 's;^.*polkadot companion: paritytech/polkadot#([0-9]+).*$;\1;p' \ -e 's;^.*polkadot companion: https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ | tail -n 1)" + boldprint "pr_comp: #${pr_companion}" if [ -z "${pr_companion}" ] then pr_companion="$(echo "${pr_body}" | sed -n -r \ 's;^.*https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ | tail -n 1)" fi + boldprint "pr_com2: #${pr_companion}" if [ "${pr_companion}" ] then -- GitLab From 784cb2211dfa33f8a73f5fd011295a963f87239a Mon Sep 17 00:00:00 2001 From: cheme Date: Thu, 2 Apr 2020 19:13:50 +0200 Subject: [PATCH 141/300] Forcing companion pr. --- .maintain/gitlab/check_polkadot_companion_build.sh | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index 49d247da4e..e98316eb3f 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -56,24 +56,19 @@ then # get the last reference to a pr in polkadot pr_data="$(curl -sSL -H "${github_header}" -s ${github_api_substrate_pull_url}/${CI_COMMIT_REF_NAME})" - boldprint "pr_dta: #${pr_data}" pr_ref="$(echo $pr_data | grep -Po '"ref"\s*:\s*"\K(?!master)[^"]*')" - boldprint "pr_ref: #${pr_ref}" - pr_body="$(echo "${pr_data}" | sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p')" - boldprint "pr_body: #${pr_body}" + pr_body="$(echo $pr_data | sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p')" - pr_companion="$(echo "${pr_body}" | sed -n -r \ + pr_companion="$(echo "${pr_data}" | sed -n -r \ -e 's;^.*polkadot companion: paritytech/polkadot#([0-9]+).*$;\1;p' \ -e 's;^.*polkadot companion: https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ | tail -n 1)" - boldprint "pr_comp: #${pr_companion}" if [ -z "${pr_companion}" ] then pr_companion="$(echo "${pr_body}" | sed -n -r \ 's;^.*https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ | tail -n 1)" fi - boldprint "pr_com2: #${pr_companion}" if [ "${pr_companion}" ] then @@ -107,3 +102,4 @@ cargo update # Test Polkadot pr or master branch with this Substrate commit. time cargo test --all --release --verbose + -- GitLab From 4897109e228c987dd42aeabefa0992d0163d5feb Mon Sep 17 00:00:00 2001 From: cheme Date: Thu, 2 Apr 2020 19:46:50 +0200 Subject: [PATCH 142/300] fixing merge. --- Cargo.lock | 39 ++++----------------------------------- Cargo.toml | 14 +++++++------- client/db/src/bench.rs | 4 ++-- client/db/src/lib.rs | 2 +- 4 files changed, 14 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 440c516cf7..61579a849f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2270,12 +2270,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" -[[package]] -name = "interleaved-ordered" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" - [[package]] name = "intervalier" version = "0.3.1" @@ -2481,8 +2475,7 @@ dependencies = [ [[package]] name = "kvdb" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cad096c6849b2ef027fabe35c4aed356d0e3d3f586d0a8361e5e17f1e50a7ce5" +source = "git+https://github.com/cheme/parity-common?branch=upgraded_del_range_pr#cf619698bb98b4868538f74eb05da10aebb78b26" dependencies = [ "parity-util-mem", "smallvec 1.2.0", @@ -2491,8 +2484,7 @@ dependencies = [ [[package]] name = "kvdb-memorydb" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aa954d12cfac958822dfd77aab34f3eec71f103b918c4ab79ab59a36ee594ea" +source = "git+https://github.com/cheme/parity-common?branch=upgraded_del_range_pr#cf619698bb98b4868538f74eb05da10aebb78b26" dependencies = [ "kvdb", "parity-util-mem", @@ -2502,11 +2494,9 @@ dependencies = [ [[package]] name = "kvdb-rocksdb" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3f14c3a10c8894d26175e57e9e26032e6d6c49c30cbe2468c5bf5f6b64bb0be" +source = "git+https://github.com/cheme/parity-common?branch=upgraded_del_range_pr#cf619698bb98b4868538f74eb05da10aebb78b26" dependencies = [ "fs-swap", - "interleaved-ordered", "kvdb", "log", "num_cpus", @@ -2521,8 +2511,7 @@ dependencies = [ [[package]] name = "kvdb-web" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f96eec962af83cdf7c83036b3dbb0ae6a1249ddab746820618e2567ca8ebcd" +source = "git+https://github.com/cheme/parity-common?branch=upgraded_del_range_pr#cf619698bb98b4868538f74eb05da10aebb78b26" dependencies = [ "futures 0.3.4", "js-sys", @@ -9240,23 +9229,3 @@ dependencies = [ "glob 0.3.0", "libc", ] - -[[patch.unused]] -name = "kvdb" -version = "0.4.0" -source = "git+https://github.com/cheme/parity-common?branch=upgraded_del_range#1b90fa8716fabc5f94a0d8d83c5fdd6cf1da8d3e" - -[[patch.unused]] -name = "kvdb-memorydb" -version = "0.4.0" -source = "git+https://github.com/cheme/parity-common?branch=upgraded_del_range#1b90fa8716fabc5f94a0d8d83c5fdd6cf1da8d3e" - -[[patch.unused]] -name = "kvdb-rocksdb" -version = "0.6.0" -source = "git+https://github.com/cheme/parity-common?branch=upgraded_del_range#1b90fa8716fabc5f94a0d8d83c5fdd6cf1da8d3e" - -[[patch.unused]] -name = "kvdb-web" -version = "0.4.0" -source = "git+https://github.com/cheme/parity-common?branch=upgraded_del_range#1b90fa8716fabc5f94a0d8d83c5fdd6cf1da8d3e" diff --git a/Cargo.toml b/Cargo.toml index 4793635200..6c609e4f37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -175,10 +175,10 @@ members = [ panic = "unwind" [patch.crates-io] -kvdb = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range" } -kvdb-rocksdb = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range" } -kvdb-web = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range" } -kvdb-memorydb = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range" } -#parity-util-mem = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range" } -#fixed-hash = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range" } -#primitive-types = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range" } +kvdb = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range_pr" } +kvdb-rocksdb = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range_pr" } +kvdb-web = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range_pr" } +kvdb-memorydb = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range_pr" } +#parity-util-mem = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range_pr" } +#fixed-hash = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range_pr" } +#primitive-types = { git = "https://github.com/cheme/parity-common", branch="upgraded_del_range_pr" } diff --git a/client/db/src/bench.rs b/client/db/src/bench.rs index c58bacdd84..fefd39620d 100644 --- a/client/db/src/bench.rs +++ b/client/db/src/bench.rs @@ -102,7 +102,7 @@ impl BenchmarkingState { let mut keyspace = crate::Keyspaced::new(&[]); for (info, mut updates) in transaction.clone().into_iter() { keyspace.change_keyspace(info.keyspace()); - for (key, rc_val) in updates.drain() { + for (key, rc_val) in updates.1.drain() { let key = if info.is_top_trie() { key } else { @@ -305,8 +305,8 @@ impl StateBackend> for BenchmarkingState { } else if rc < 0 { db_transaction.delete(0, &key); } + keys.push(key); } - keys.push(key); } } self.record.set(keys); diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 061c87af5c..27fe5e3736 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -1176,7 +1176,7 @@ impl Backend { let mut ops: u64 = 0; let mut bytes: u64 = 0; for (key, value) in operation.storage_updates.iter() - .chain(operation.child_storage_updates.iter().flat_map(|(_, s, _)| s.iter())) { + .chain(operation.child_storage_updates.iter().flat_map(|(_, _, s)| s.iter())) { ops += 1; bytes += key.len() as u64; if let Some(v) = value.as_ref() { -- GitLab From 4bbb24dedda0d5eef20ea2d88d15c90ffb8befba Mon Sep 17 00:00:00 2001 From: cheme Date: Thu, 2 Apr 2020 19:54:48 +0200 Subject: [PATCH 143/300] revert ci changes. --- .maintain/gitlab/check_polkadot_companion_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index e98316eb3f..04524a736a 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -59,7 +59,7 @@ then pr_ref="$(echo $pr_data | grep -Po '"ref"\s*:\s*"\K(?!master)[^"]*')" pr_body="$(echo $pr_data | sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p')" - pr_companion="$(echo "${pr_data}" | sed -n -r \ + pr_companion="$(echo "${pr_body}" | sed -n -r \ -e 's;^.*polkadot companion: paritytech/polkadot#([0-9]+).*$;\1;p' \ -e 's;^.*polkadot companion: https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ | tail -n 1)" -- GitLab From 270711597853d62581852afa9fddfe612219dcce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Thu, 2 Apr 2020 19:16:45 +0100 Subject: [PATCH 144/300] cli: fix milliseconds formatting on logs (#5507) --- client/cli/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index 18a5991e39..ba59b94c82 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -186,8 +186,8 @@ pub fn init_logger(pattern: &str) { let name = ::std::thread::current() .name() .map_or_else(Default::default, |x| format!("{}", Colour::Blue.bold().paint(x))); - let millis = (now.tm_nsec as f32 / 1000000.0).round() as usize; - let timestamp = format!("{}.{:03}", timestamp, millis); + let millis = (now.tm_nsec as f32 / 1000000.0).floor() as usize; + let timestamp = format!("{}.{}", timestamp, millis); format!( "{} {} {} {} {}", Colour::Black.bold().paint(timestamp), -- GitLab From 499f9a5714d837c41151fee128f85639f14c7484 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Thu, 2 Apr 2020 20:17:39 +0200 Subject: [PATCH 145/300] More emojies and spaces (#5498) * More emojies and spaces * Sync emojis * More emoji --- bin/node/cli/src/browser.rs | 4 ++-- client/cli/src/commands/runcmd.rs | 4 ++-- client/finality-grandpa/src/authorities.rs | 4 ++-- client/informant/src/display.rs | 4 ++-- client/network/src/protocol/sync.rs | 24 +++++++++++----------- client/service/src/lib.rs | 2 +- client/telemetry/src/worker/node.rs | 4 ++-- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/bin/node/cli/src/browser.rs b/bin/node/cli/src/browser.rs index ea380b3ffd..d9377de5d7 100644 --- a/bin/node/cli/src/browser.rs +++ b/bin/node/cli/src/browser.rs @@ -41,8 +41,8 @@ async fn start_inner(chain_spec: String, log_level: String) -> Result ?change.canon_height @@ -328,7 +328,7 @@ where self.pending_forced_changes.clear(); if let Some(change) = change { - info!(target: "afg", "Applying authority set change scheduled at block #{:?}", + info!(target: "afg", "👴 Applying authority set change scheduled at block #{:?}", change.canon_height); telemetry!(CONSENSUS_INFO; "afg.applying_scheduled_authority_set_change"; "block" => ?change.canon_height diff --git a/client/informant/src/display.rs b/client/informant/src/display.rs index ecc19753e1..42f4989983 100644 --- a/client/informant/src/display.rs +++ b/client/informant/src/display.rs @@ -69,8 +69,8 @@ impl InformantDisplay { let (status, target) = match (net_status.sync_state, net_status.best_seen_block) { (SyncState::Idle, _) => ("💤 Idle".into(), "".into()), - (SyncState::Downloading, None) => (format!("⚙️ Syncing{}", speed), "".into()), - (SyncState::Downloading, Some(n)) => (format!("⚙️ Syncing{}", speed), format!(", target=#{}", n)), + (SyncState::Downloading, None) => (format!("⚙️ Preparing{}", speed), "".into()), + (SyncState::Downloading, Some(n)) => (format!("⚙️ Syncing{}", speed), format!(", target=#{}", n)), }; if self.format == OutputFormat::Coloured { diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index df12522d37..4c0f930bb0 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -818,7 +818,7 @@ impl ChainSync { if let Some(peer) = self.peers.get_mut(&who) { peer } else { - error!(target: "sync", "Called on_block_justification with a bad peer ID"); + error!(target: "sync", "💔 Called on_block_justification with a bad peer ID"); return Ok(OnBlockJustification::Nothing) }; @@ -831,7 +831,7 @@ impl ChainSync { if hash != block.hash { info!( target: "sync", - "Invalid block justification provided by {}: requested: {:?} got: {:?}", who, hash, block.hash + "💔 Invalid block justification provided by {}: requested: {:?} got: {:?}", who, hash, block.hash ); return Err(BadPeer(who, rep::BAD_JUSTIFICATION)); } @@ -865,7 +865,7 @@ impl ChainSync { if let Some(peer) = self.peers.get_mut(&who) { peer } else { - error!(target: "sync", "Called on_block_finality_proof_data with a bad peer ID"); + error!(target: "sync", "💔 Called on_block_finality_proof_data with a bad peer ID"); return Ok(OnBlockFinalityProof::Nothing) }; @@ -877,7 +877,7 @@ impl ChainSync { if hash != resp.block { info!( target: "sync", - "Invalid block finality proof provided: requested: {:?} got: {:?}", + "💔 Invalid block finality proof provided: requested: {:?} got: {:?}", hash, resp.block ); @@ -959,14 +959,14 @@ impl ChainSync { }, Err(BlockImportError::IncompleteHeader(who)) => { if let Some(peer) = who { - warn!("Peer sent block with incomplete header to import"); + warn!("💔 Peer sent block with incomplete header to import"); output.push(Err(BadPeer(peer, rep::INCOMPLETE_HEADER))); output.extend(self.restart()); } }, Err(BlockImportError::VerificationFailed(who, e)) => { if let Some(peer) = who { - warn!("Verification failed for block {:?} received from peer: {}, {:?}", hash, peer, e); + warn!("💔 Verification failed for block {:?} received from peer: {}, {:?}", hash, peer, e); output.push(Err(BadPeer(peer, rep::VERIFICATION_FAIL))); output.extend(self.restart()); } @@ -985,7 +985,7 @@ impl ChainSync { }, e @ Err(BlockImportError::UnknownParent) | e @ Err(BlockImportError::Other(_)) => { - warn!(target: "sync", "Error importing block {:?}: {:?}", hash, e); + warn!(target: "sync", "💔 Error importing block {:?}: {:?}", hash, e); output.extend(self.restart()); }, Err(BlockImportError::Cancelled) => {} @@ -1017,7 +1017,7 @@ impl ChainSync { }); if let Err(err) = r { - warn!(target: "sync", "Error cleaning up pending extra finality proof data requests: {:?}", err) + warn!(target: "sync", "💔 Error cleaning up pending extra finality proof data requests: {:?}", err) } let client = &self.client; @@ -1026,7 +1026,7 @@ impl ChainSync { }); if let Err(err) = r { - warn!(target: "sync", "Error cleaning up pending extra justification data requests: {:?}", err); + warn!(target: "sync", "💔 Error cleaning up pending extra justification data requests: {:?}", err); } } @@ -1080,7 +1080,7 @@ impl ChainSync { let number = *header.number(); debug!(target: "sync", "Received block announcement {:?} with number {:?} from {}", hash, number, who); if number.is_zero() { - warn!(target: "sync", "Ignored genesis block (#0) announcement from {}: {}", who, hash); + warn!(target: "sync", "💔 Ignored genesis block (#0) announcement from {}: {}", who, hash); return OnBlockAnnounce::Nothing } let parent_status = self.block_status(header.parent_hash()).ok().unwrap_or(BlockStatus::Unknown); @@ -1091,7 +1091,7 @@ impl ChainSync { let peer = if let Some(peer) = self.peers.get_mut(&who) { peer } else { - error!(target: "sync", "Called on_block_announce with a bad peer ID"); + error!(target: "sync", "💔 Called on_block_announce with a bad peer ID"); return OnBlockAnnounce::Nothing }; while peer.recently_announced.len() >= ANNOUNCE_HISTORY_SIZE { @@ -1137,7 +1137,7 @@ impl ChainSync { return OnBlockAnnounce::Nothing } Err(e) => { - error!(target: "sync", "Block announcement validation errored: {}", e); + error!(target: "sync", "💔 Block announcement validation errored: {}", e); return OnBlockAnnounce::Nothing } } diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 7bcddd7ad7..137442f7e0 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -441,7 +441,7 @@ fn build_network_future< log!( target: "service", if polling_dur >= Duration::from_secs(1) { Level::Warn } else { Level::Trace }, - "Polling the network future took {:?}", + "⚠️ Polling the network future took {:?}", polling_dur ); diff --git a/client/telemetry/src/worker/node.rs b/client/telemetry/src/worker/node.rs index d28c3854f0..454f504d66 100644 --- a/client/telemetry/src/worker/node.rs +++ b/client/telemetry/src/worker/node.rs @@ -116,7 +116,7 @@ where TTrans: Clone + Unpin, TTrans::Dial: Unpin, pending.push_back(payload.into()); Ok(()) } else { - warn!(target: "telemetry", "⚠️ Rejected log entry because queue is full for {:?}", + warn!(target: "telemetry", "⚠️ Rejected log entry because queue is full for {:?}", self.addr); Err(()) } @@ -137,7 +137,7 @@ where TTrans: Clone + Unpin, TTrans::Dial: Unpin, break NodeSocket::Connected(conn) }, Poll::Ready(Err(err)) => { - warn!(target: "telemetry", "⚠️ Disconnected from {}: {:?}", self.addr, err); + warn!(target: "telemetry", "⚠️ Disconnected from {}: {:?}", self.addr, err); let timeout = gen_rand_reconnect_delay(); self.socket = NodeSocket::WaitingReconnect(timeout); return Poll::Ready(NodeEvent::Disconnected(err)) -- GitLab From 318016ac4671f7ef6444c5b4b654305855a84f2c Mon Sep 17 00:00:00 2001 From: Joshy Orndorff Date: Thu, 2 Apr 2020 19:25:13 -0400 Subject: [PATCH 146/300] Remove unused dependency on safe-mix (#5495) --- Cargo.lock | 1 - bin/node-template/pallets/template/Cargo.toml | 2 -- 2 files changed, 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77852437f2..a54fe1f64c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4458,7 +4458,6 @@ dependencies = [ "frame-support", "frame-system", "parity-scale-codec", - "safe-mix", "sp-core", "sp-io", "sp-runtime", diff --git a/bin/node-template/pallets/template/Cargo.toml b/bin/node-template/pallets/template/Cargo.toml index 8e53a9a53a..69fcd84352 100644 --- a/bin/node-template/pallets/template/Cargo.toml +++ b/bin/node-template/pallets/template/Cargo.toml @@ -10,7 +10,6 @@ description = "FRAME pallet template" [dependencies] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -safe-mix = { default-features = false, version = '1.0.0' } [dependencies.frame-support] default-features = false @@ -42,7 +41,6 @@ default = ['std'] std = [ 'codec/std', 'frame-support/std', - 'safe-mix/std', 'frame-system/std' ] -- GitLab From 3e18235999e4c9bc08ece890eb0a950063be7f76 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 3 Apr 2020 08:43:55 +0200 Subject: [PATCH 147/300] Add a sub_libp2p_notifications_queues_size Prometheus metric (#5503) * Add a sub_libp2p_notifications_queues_size Prometheus metric * Fix network tests * Address review --- client/network/src/protocol.rs | 6 +++-- .../src/protocol/generic_proto/behaviour.rs | 15 ++++++++++- .../protocol/generic_proto/handler/group.rs | 23 +++++++++++++++-- .../generic_proto/handler/notif_out.rs | 13 +++++++++- .../src/protocol/generic_proto/tests.rs | 2 +- .../generic_proto/upgrade/notifications.rs | 9 ++++++- client/network/src/service.rs | 25 +++++++++++++++---- utils/prometheus/src/lib.rs | 1 + 8 files changed, 81 insertions(+), 13 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 357cd3baca..24d502ef2f 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -40,7 +40,7 @@ use sp_runtime::traits::{ use sp_arithmetic::traits::SaturatedConversion; use message::{BlockAnnounce, Message}; use message::generic::{Message as GenericMessage, ConsensusMessage}; -use prometheus_endpoint::{Registry, Gauge, GaugeVec, PrometheusError, Opts, register, U64}; +use prometheus_endpoint::{Registry, Gauge, GaugeVec, HistogramVec, PrometheusError, Opts, register, U64}; use sync::{ChainSync, SyncState}; use crate::service::{TransactionPool, ExHashT}; use crate::config::{BoxFinalityProofRequestBuilder, Roles}; @@ -324,6 +324,7 @@ impl Protocol { block_announce_validator: Box + Send>, metrics_registry: Option<&Registry>, boot_node_ids: Arc>, + queue_size_report: Option, ) -> error::Result<(Protocol, sc_peerset::PeersetHandle)> { let info = chain.info(); let sync = ChainSync::new( @@ -346,7 +347,7 @@ impl Protocol { let (peerset, peerset_handle) = sc_peerset::Peerset::from_config(peerset_config); let versions = &((MIN_VERSION as u8)..=(CURRENT_VERSION as u8)).collect::>(); - let mut behaviour = GenericProto::new(protocol_id.clone(), versions, peerset); + let mut behaviour = GenericProto::new(protocol_id.clone(), versions, peerset, queue_size_report); let mut legacy_equiv_by_name = HashMap::new(); @@ -2052,6 +2053,7 @@ mod tests { Box::new(DefaultBlockAnnounceValidator::new(client.clone())), None, Default::default(), + None, ).unwrap(); let dummy_peer_id = PeerId::random(); diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index e52ac5575f..c398f6df2d 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -24,6 +24,7 @@ use futures::prelude::*; use libp2p::core::{ConnectedPoint, Multiaddr, PeerId}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use log::{debug, error, trace, warn}; +use prometheus_endpoint::HistogramVec; use rand::distributions::{Distribution as _, Uniform}; use smallvec::SmallVec; use std::task::{Context, Poll}; @@ -99,6 +100,9 @@ pub struct GenericProto { /// Events to produce from `poll()`. events: SmallVec<[NetworkBehaviourAction; 4]>, + + /// If `Some`, report the message queue sizes on this `Histogram`. + queue_size_report: Option, } /// State of a peer we're connected to. @@ -267,10 +271,14 @@ pub enum GenericProtoOut { impl GenericProto { /// Creates a `CustomProtos`. + /// + /// The `queue_size_report` is an optional Prometheus metric that can report the size of the + /// messages queue. If passed, it must have one label for the protocol name. pub fn new( protocol: impl Into, versions: &[u8], peerset: sc_peerset::Peerset, + queue_size_report: Option, ) -> Self { let legacy_protocol = RegisteredProtocol::new(protocol, versions); @@ -282,6 +290,7 @@ impl GenericProto { incoming: SmallVec::new(), next_incoming_index: sc_peerset::IncomingIndex(0), events: SmallVec::new(), + queue_size_report, } } @@ -723,7 +732,11 @@ impl NetworkBehaviour for GenericProto { type OutEvent = GenericProtoOut; fn new_handler(&mut self) -> Self::ProtocolsHandler { - NotifsHandlerProto::new(self.legacy_protocol.clone(), self.notif_protocols.clone()) + NotifsHandlerProto::new( + self.legacy_protocol.clone(), + self.notif_protocols.clone(), + self.queue_size_report.clone() + ) } fn addresses_of_peer(&mut self, _: &PeerId) -> Vec { diff --git a/client/network/src/protocol/generic_proto/handler/group.rs b/client/network/src/protocol/generic_proto/handler/group.rs index 6b23263b14..21dc4091c0 100644 --- a/client/network/src/protocol/generic_proto/handler/group.rs +++ b/client/network/src/protocol/generic_proto/handler/group.rs @@ -64,6 +64,7 @@ use libp2p::swarm::{ NegotiatedSubstream, }; use log::{debug, error}; +use prometheus_endpoint::HistogramVec; use std::{borrow::Cow, error, io, str, task::{Context, Poll}}; /// Implements the `IntoProtocolsHandler` trait of libp2p. @@ -225,12 +226,30 @@ pub enum NotifsHandlerOut { impl NotifsHandlerProto { /// Builds a new handler. - pub fn new(legacy: RegisteredProtocol, list: impl Into, Vec)>>) -> Self { + /// + /// The `queue_size_report` is an optional Prometheus metric that can report the size of the + /// messages queue. If passed, it must have one label for the protocol name. + pub fn new(legacy: RegisteredProtocol, list: impl Into, Vec)>>, queue_size_report: Option) -> Self { let list = list.into(); + let out_handlers = list + .clone() + .into_iter() + .map(|(p, _)| { + let queue_size_report = queue_size_report.as_ref().and_then(|qs| { + if let Ok(utf8) = str::from_utf8(&p) { + Some(qs.with_label_values(&[utf8])) + } else { + log::warn!("Ignoring Prometheus metric because {:?} isn't UTF-8", p); + None + } + }); + NotifsOutHandlerProto::new(p, queue_size_report) + }).collect(); + NotifsHandlerProto { in_handlers: list.clone().into_iter().map(|(p, _)| NotifsInHandlerProto::new(p)).collect(), - out_handlers: list.clone().into_iter().map(|(p, _)| NotifsOutHandlerProto::new(p)).collect(), + out_handlers, legacy: LegacyProtoHandlerProto::new(legacy), } } diff --git a/client/network/src/protocol/generic_proto/handler/notif_out.rs b/client/network/src/protocol/generic_proto/handler/notif_out.rs index 62d2409be8..63b460bf8c 100644 --- a/client/network/src/protocol/generic_proto/handler/notif_out.rs +++ b/client/network/src/protocol/generic_proto/handler/notif_out.rs @@ -34,6 +34,7 @@ use libp2p::swarm::{ NegotiatedSubstream, }; use log::error; +use prometheus_endpoint::Histogram; use smallvec::SmallVec; use std::{borrow::Cow, fmt, mem, pin::Pin, task::{Context, Poll}, time::Duration}; use wasm_timer::Instant; @@ -56,14 +57,17 @@ const INITIAL_KEEPALIVE_TIME: Duration = Duration::from_secs(5); pub struct NotifsOutHandlerProto { /// Name of the protocol to negotiate. protocol_name: Cow<'static, [u8]>, + /// Optional Prometheus histogram to report message queue size variations. + queue_size_report: Option, } impl NotifsOutHandlerProto { /// Builds a new [`NotifsOutHandlerProto`]. Will use the given protocol name for the /// notifications substream. - pub fn new(protocol_name: impl Into>) -> Self { + pub fn new(protocol_name: impl Into>, queue_size_report: Option) -> Self { NotifsOutHandlerProto { protocol_name: protocol_name.into(), + queue_size_report, } } } @@ -79,6 +83,7 @@ impl IntoProtocolsHandler for NotifsOutHandlerProto { NotifsOutHandler { protocol_name: self.protocol_name, when_connection_open: Instant::now(), + queue_size_report: self.queue_size_report, state: State::Disabled, events_queue: SmallVec::new(), } @@ -103,6 +108,9 @@ pub struct NotifsOutHandler { /// When the connection with the remote has been successfully established. when_connection_open: Instant, + /// Optional prometheus histogram to report message queue sizes variations. + queue_size_report: Option, + /// Queue of events to send to the outside. /// /// This queue must only ever be modified to insert elements at the back, or remove the first @@ -301,6 +309,9 @@ impl ProtocolsHandler for NotifsOutHandler { NotifsOutHandlerIn::Send(msg) => if let State::Open { substream, .. } = &mut self.state { if let Some(Ok(_)) = substream.send(msg).now_or_never() { + if let Some(metric) = &self.queue_size_report { + metric.observe(substream.queue_len() as f64); + } } else { log::warn!( target: "sub-libp2p", diff --git a/client/network/src/protocol/generic_proto/tests.rs b/client/network/src/protocol/generic_proto/tests.rs index 00b840d581..c0582d5f5c 100644 --- a/client/network/src/protocol/generic_proto/tests.rs +++ b/client/network/src/protocol/generic_proto/tests.rs @@ -82,7 +82,7 @@ fn build_nodes() -> (Swarm, Swarm) { }); let behaviour = CustomProtoWithAddr { - inner: GenericProto::new(&b"test"[..], &[1], peerset), + inner: GenericProto::new(&b"test"[..], &[1], peerset, None), addrs: addrs .iter() .enumerate() diff --git a/client/network/src/protocol/generic_proto/upgrade/notifications.rs b/client/network/src/protocol/generic_proto/upgrade/notifications.rs index b6ae1425f1..de42d85c80 100644 --- a/client/network/src/protocol/generic_proto/upgrade/notifications.rs +++ b/client/network/src/protocol/generic_proto/upgrade/notifications.rs @@ -38,7 +38,7 @@ use futures::{prelude::*, ready}; use futures_codec::Framed; use libp2p::core::{UpgradeInfo, InboundUpgrade, OutboundUpgrade, upgrade}; use log::error; -use std::{borrow::Cow, collections::VecDeque, io, iter, mem, pin::Pin, task::{Context, Poll}}; +use std::{borrow::Cow, collections::VecDeque, convert::TryFrom as _, io, iter, mem, pin::Pin, task::{Context, Poll}}; use unsigned_varint::codec::UviBytes; /// Maximum allowed size of the two handshake messages, in bytes. @@ -280,6 +280,13 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin + Send + 'static, } } +impl NotificationsOutSubstream { + /// Returns the number of items in the queue, capped to `u32::max_value()`. + pub fn queue_len(&self) -> u32 { + u32::try_from(self.messages_queue.len()).unwrap_or(u32::max_value()) + } +} + impl Sink> for NotificationsOutSubstream where TSubstream: AsyncRead + AsyncWrite + Unpin, { diff --git a/client/network/src/service.rs b/client/network/src/service.rs index de22f203bc..8d2f0e033f 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -42,7 +42,7 @@ use libp2p::{kad::record, Multiaddr, PeerId}; use log::{error, info, trace, warn}; use parking_lot::Mutex; use prometheus_endpoint::{ - register, Counter, CounterVec, Gauge, GaugeVec, Opts, PrometheusError, Registry, U64, + register, Counter, CounterVec, Gauge, GaugeVec, HistogramOpts, HistogramVec, Opts, PrometheusError, Registry, U64, }; use sc_peerset::PeersetHandle; use sp_consensus::import_queue::{BlockImportError, BlockImportResult, ImportQueue, Link}; @@ -239,6 +239,12 @@ impl NetworkWorker { let local_peer_id = local_public.clone().into_peer_id(); info!(target: "sub-libp2p", "🏷 Local node identity is: {}", local_peer_id.to_base58()); + // Initialize the metrics. + let metrics = match ¶ms.metrics_registry { + Some(registry) => Some(Metrics::register(®istry)?), + None => None + }; + let checker = params.on_demand.as_ref() .map(|od| od.checker().clone()) .unwrap_or(Arc::new(AlwaysBadChecker)); @@ -259,6 +265,7 @@ impl NetworkWorker { params.block_announce_validator, params.metrics_registry.as_ref(), boot_node_ids.clone(), + metrics.as_ref().map(|m| m.notifications_queues_size.clone()), )?; // Build the swarm. @@ -343,10 +350,7 @@ impl NetworkWorker { from_worker, light_client_rqs: params.on_demand.and_then(|od| od.extract_receiver()), event_streams: Vec::new(), - metrics: match params.metrics_registry { - Some(registry) => Some(Metrics::register(®istry)?), - None => None - }, + metrics, boot_node_ids, }) } @@ -802,6 +806,7 @@ struct Metrics { issued_light_requests: Counter, kbuckets_num_nodes: Gauge, network_per_sec_bytes: GaugeVec, + notifications_queues_size: HistogramVec, notifications_total: CounterVec, num_event_stream_channels: Gauge, opened_notification_streams: GaugeVec, @@ -847,6 +852,16 @@ impl Metrics { ), &["direction"] )?, registry)?, + notifications_queues_size: register(HistogramVec::new( + HistogramOpts { + common_opts: Opts::new( + "sub_libp2p_notifications_queues_size", + "Total size of all the notification queues" + ), + buckets: vec![0.0, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0], + }, + &["protocol"] + )?, registry)?, notifications_total: register(CounterVec::new( Opts::new( "sub_libp2p_notifications_total", diff --git a/utils/prometheus/src/lib.rs b/utils/prometheus/src/lib.rs index 4a8f05d929..9dab2a2695 100644 --- a/utils/prometheus/src/lib.rs +++ b/utils/prometheus/src/lib.rs @@ -17,6 +17,7 @@ use futures_util::{FutureExt, future::Future}; pub use prometheus::{ Registry, Error as PrometheusError, Opts, + Histogram, HistogramOpts, HistogramVec, core::{ GenericGauge as Gauge, GenericCounter as Counter, GenericGaugeVec as GaugeVec, GenericCounterVec as CounterVec, -- GitLab From 64740cdbf6e1c8e3b12cea9a861fe984d7c07449 Mon Sep 17 00:00:00 2001 From: Alexander Krupenkin Date: Fri, 3 Apr 2020 17:19:52 +0900 Subject: [PATCH 148/300] Added Robonomics network standard account prefix (#5506) --- primitives/core/src/crypto.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index f16c160960..79a36b2ad2 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -459,6 +459,8 @@ ss58_address_format!( (16, "kulupu", "Kulupu mainnet, standard account (*25519).") DarwiniaAccount => (18, "darwinia", "Darwinia Chain mainnet, standard account (*25519).") + RobonomicsAccount => + (32, "robonomics", "Any Robonomics network standard account (*25519).") CentrifugeAccount => (36, "centrifuge", "Centrifuge Chain mainnet, standard account (*25519).") SubstrateAccount => -- GitLab From ff11e76891347944fe9002e347ba8687a820f563 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Fri, 3 Apr 2020 11:53:38 +0200 Subject: [PATCH 149/300] Update CONTRIBUTING.adoc (#5511) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update CONTRIBUTING.adoc * Update docs/CONTRIBUTING.adoc Co-Authored-By: Bastian Köcher Co-authored-by: Bastian Köcher --- docs/CONTRIBUTING.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CONTRIBUTING.adoc b/docs/CONTRIBUTING.adoc index 5a1a4466b0..b573aef50d 100644 --- a/docs/CONTRIBUTING.adoc +++ b/docs/CONTRIBUTING.adoc @@ -56,7 +56,7 @@ To create a Polkadot companion PR: . Pull latest Polkadot master (or clone it, if you haven't yet). . Override your local cargo config to point to your local substrate (pointing to your WIP branch): place `paths = ["path/to/substrate"]` in `~/.cargo/config`. . Make the changes required and build polkadot locally. -. Submit all this as a PR against the Polkadot Repo. Link to your Polkadot PR in the _description_ of your Substrate PR as "polkadot companion: [URL]". +. Submit all this as a PR against the Polkadot Repo. Link to your Polkadot PR in the _description_ of your Substrate PR as "polkadot companion: [URL]" OR use the same name for your Polkdadot branch as the Substrate branch. . Now you should see that the `check_polkadot` CI job will build your Substrate PR agains the mentioned Polkadot branch in your PR description. . Wait for reviews on both . Once both PRs have been green lit, they can both be merged 🍻. -- GitLab From 62a6d9ed160d9558643288ef68dc45e9481125b0 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 3 Apr 2020 14:14:55 +0200 Subject: [PATCH 150/300] Improve warning about notifications queue and remove spurious triggers (#5512) * Better logging for notifications and buffer size increase * Address review * Improve warning about notifications queue and remove spurious triggers --- .../generic_proto/handler/notif_out.rs | 19 ++++++++++------ .../generic_proto/upgrade/notifications.rs | 22 ++++++++++++------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/client/network/src/protocol/generic_proto/handler/notif_out.rs b/client/network/src/protocol/generic_proto/handler/notif_out.rs index 63b460bf8c..dd38826496 100644 --- a/client/network/src/protocol/generic_proto/handler/notif_out.rs +++ b/client/network/src/protocol/generic_proto/handler/notif_out.rs @@ -79,13 +79,14 @@ impl IntoProtocolsHandler for NotifsOutHandlerProto { DeniedUpgrade } - fn into_handler(self, _: &PeerId, _: &ConnectedPoint) -> Self::Handler { + fn into_handler(self, peer_id: &PeerId, _: &ConnectedPoint) -> Self::Handler { NotifsOutHandler { protocol_name: self.protocol_name, when_connection_open: Instant::now(), queue_size_report: self.queue_size_report, state: State::Disabled, events_queue: SmallVec::new(), + peer_id: peer_id.clone(), } } } @@ -116,6 +117,9 @@ pub struct NotifsOutHandler { /// This queue must only ever be modified to insert elements at the back, or remove the first /// element. events_queue: SmallVec<[ProtocolsHandlerEvent; 16]>, + + /// Who we are connected to. + peer_id: PeerId, } /// Our relationship with the node we're connected to. @@ -308,16 +312,17 @@ impl ProtocolsHandler for NotifsOutHandler { NotifsOutHandlerIn::Send(msg) => if let State::Open { substream, .. } = &mut self.state { - if let Some(Ok(_)) = substream.send(msg).now_or_never() { - if let Some(metric) = &self.queue_size_report { - metric.observe(substream.queue_len() as f64); - } - } else { + if substream.push_message(msg).is_err() { log::warn!( target: "sub-libp2p", - "📞 Failed to push message to queue, dropped it" + "📞 Notifications queue with peer {} is full, dropped message (protocol: {:?})", + self.peer_id, + self.protocol_name, ); } + if let Some(metric) = &self.queue_size_report { + metric.observe(substream.queue_len() as f64); + } } else { // This is an API misuse. log::warn!( diff --git a/client/network/src/protocol/generic_proto/upgrade/notifications.rs b/client/network/src/protocol/generic_proto/upgrade/notifications.rs index de42d85c80..f626110a33 100644 --- a/client/network/src/protocol/generic_proto/upgrade/notifications.rs +++ b/client/network/src/protocol/generic_proto/upgrade/notifications.rs @@ -43,8 +43,7 @@ use unsigned_varint::codec::UviBytes; /// Maximum allowed size of the two handshake messages, in bytes. const MAX_HANDSHAKE_SIZE: usize = 1024; -/// Maximum number of buffered messages before we consider the remote unresponsive and kill the -/// substream. +/// Maximum number of buffered messages before we refuse to accept more. const MAX_PENDING_MESSAGES: usize = 256; /// Upgrade that accepts a substream, sends back a status message, then becomes a unidirectional @@ -285,6 +284,18 @@ impl NotificationsOutSubstream { pub fn queue_len(&self) -> u32 { u32::try_from(self.messages_queue.len()).unwrap_or(u32::max_value()) } + + /// Push a message to the queue of messages. + /// + /// This has the same effect as the `Sink::start_send` implementation. + pub fn push_message(&mut self, item: Vec) -> Result<(), NotificationsOutError> { + if self.messages_queue.len() >= MAX_PENDING_MESSAGES { + return Err(NotificationsOutError::Clogged); + } + + self.messages_queue.push_back(item); + Ok(()) + } } impl Sink> for NotificationsOutSubstream @@ -297,12 +308,7 @@ impl Sink> for NotificationsOutSubstream } fn start_send(mut self: Pin<&mut Self>, item: Vec) -> Result<(), Self::Error> { - if self.messages_queue.len() >= MAX_PENDING_MESSAGES { - return Err(NotificationsOutError::Clogged); - } - - self.messages_queue.push_back(item); - Ok(()) + self.push_message(item) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { -- GitLab From 55a0e6935c751e9049d97157bfbe0b4ca1884db4 Mon Sep 17 00:00:00 2001 From: cheme Date: Fri, 3 Apr 2020 14:21:21 +0200 Subject: [PATCH 151/300] Companion PR ci sed issue. (#5508) * ci: fix echo sed failure Co-authored-by: gabriel --- .maintain/gitlab/check_polkadot_companion_build.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index 04524a736a..2258c9505c 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -40,7 +40,6 @@ substrate's branch. if it can't find anything, it will uses master instead EOT - SUBSTRATE_PATH=$(pwd) # Clone the current Polkadot master branch into ./polkadot. @@ -54,15 +53,18 @@ if expr match "${CI_COMMIT_REF_NAME}" '^[0-9]\+$' >/dev/null then boldprint "this is pull request no ${CI_COMMIT_REF_NAME}" + pr_data_file="$(mktemp)" # get the last reference to a pr in polkadot - pr_data="$(curl -sSL -H "${github_header}" -s ${github_api_substrate_pull_url}/${CI_COMMIT_REF_NAME})" - pr_ref="$(echo $pr_data | grep -Po '"ref"\s*:\s*"\K(?!master)[^"]*')" - pr_body="$(echo $pr_data | sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p')" + curl -sSL -H "${github_header}" -o "${pr_data_file}" \ + "${github_api_substrate_pull_url}/${CI_COMMIT_REF_NAME}" + + pr_body="$(sed -n -r 's/^[[:space:]]+"body": (".*")[^"]+$/\1/p' "${pr_data_file}")" pr_companion="$(echo "${pr_body}" | sed -n -r \ -e 's;^.*polkadot companion: paritytech/polkadot#([0-9]+).*$;\1;p' \ -e 's;^.*polkadot companion: https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ | tail -n 1)" + if [ -z "${pr_companion}" ] then pr_companion="$(echo "${pr_body}" | sed -n -r \ @@ -76,7 +78,8 @@ then git fetch --depth 1 origin refs/pull/${pr_companion}/head:pr/${pr_companion} git checkout pr/${pr_companion} else - if git fetch --depth 1 origin "$pr_ref":branch/"$pr_ref" + pr_ref="$(grep -Po '"ref"\s*:\s*"\K(?!master)[^"]*' "${pr_data_file}")" + if git fetch --depth 1 origin "$pr_ref":branch/"$pr_ref" 2>/dev/null then boldprint "companion branch detected: $pr_ref" git checkout branch/"$pr_ref" @@ -84,6 +87,7 @@ then boldprint "no companion branch found - building polkadot:master" fi fi + rm -f "${pr_data_file}" else boldprint "this is not a pull request - building polkadot:master" fi -- GitLab From 04276e749c40e6cd3de9c1f94e69b461b1e43d55 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 3 Apr 2020 15:13:04 +0200 Subject: [PATCH 152/300] Can't have zero nominations (#5510) --- frame/staking/src/benchmarking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index a88c00c144..9a1f6a215c 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -313,7 +313,7 @@ benchmarks! { }: _(RawOrigin::Signed(validator), current_era) payout_nominator { - let v in 0 .. MAX_NOMINATIONS as u32; + let v in 1 .. MAX_NOMINATIONS as u32; let (nominator, validators) = create_nominator_with_validators::(v)?; let current_era = CurrentEra::get().unwrap(); let find_nominator = validators.into_iter().map(|x| (x, 0)).collect(); -- GitLab From ba622580b1023ac201890eb4a3e8de5e03706a89 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 3 Apr 2020 16:29:59 +0200 Subject: [PATCH 153/300] Run Runtime Benchmarks on Block One (#5509) * Run benchmarks on block 1 * Put example benchmarks behind feature flag * add feature to cargo.toml * typo * Add `frame_system` trait bound * Update instance benchmarks too --- frame/benchmarking/src/lib.rs | 12 +++++- frame/example/Cargo.toml | 4 +- frame/example/src/lib.rs | 72 +++++++++++++++++++---------------- 3 files changed, 52 insertions(+), 36 deletions(-) diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index 4cd6072ce4..b1427b792d 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -504,7 +504,9 @@ macro_rules! impl_benchmark { ( NO_INSTANCE $( $name:ident ),* ) => { - impl $crate::Benchmarking<$crate::BenchmarkResults> for Module { + impl $crate::Benchmarking<$crate::BenchmarkResults> for Module + where T: frame_system::Trait + { fn benchmarks() -> Vec<&'static [u8]> { vec![ $( stringify!($name).as_ref() ),* ] } @@ -567,6 +569,8 @@ macro_rules! impl_benchmark { // Run the benchmark `repeat` times. for _ in 0..repeat { + // Set the block number to 1 so events are deposited. + frame_system::Module::::set_block_number(1.into()); // Set up the externalities environment for the setup we want to benchmark. let closure_to_benchmark = >::instance(&selected_benchmark, &c)?; @@ -600,7 +604,9 @@ macro_rules! impl_benchmark { ( INSTANCE $( $name:ident ),* ) => { - impl, I: Instance> $crate::Benchmarking<$crate::BenchmarkResults> for Module { + impl, I: Instance> $crate::Benchmarking<$crate::BenchmarkResults> for Module + where T: frame_system::Trait + { fn benchmarks() -> Vec<&'static [u8]> { vec![ $( stringify!($name).as_ref() ),* ] } @@ -663,6 +669,8 @@ macro_rules! impl_benchmark { // Run the benchmark `repeat` times. for _ in 0..repeat { + // Set the block number to 1 so events are deposited. + frame_system::Module::::set_block_number(1.into()); // Set up the externalities environment for the setup we want to benchmark. let closure_to_benchmark = >::instance(&selected_benchmark, &c)?; diff --git a/frame/example/Cargo.toml b/frame/example/Cargo.toml index 014bcc91d4..4053cc0b1a 100644 --- a/frame/example/Cargo.toml +++ b/frame/example/Cargo.toml @@ -11,7 +11,6 @@ description = "FRAME example pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking" } frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../support" } frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../system" } pallet-balances = { version = "2.0.0-alpha.5", default-features = false, path = "../balances" } @@ -19,6 +18,8 @@ sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../. sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-io = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/io" } +frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../benchmarking", optional = true } + [dev-dependencies] sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core", default-features = false } @@ -35,6 +36,7 @@ std = [ "sp-io/std", "sp-std/std" ] +runtime-benchmarks = ["frame-benchmarking"] [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 70b3472ea0..e8ce89a863 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -262,8 +262,7 @@ use frame_support::{ }, }; use sp_std::prelude::*; -use frame_benchmarking::{benchmarks, account}; -use frame_system::{self as system, ensure_signed, ensure_root, RawOrigin}; +use frame_system::{self as system, ensure_signed, ensure_root}; use codec::{Encode, Decode}; use sp_runtime::{ traits::{SignedExtension, Bounded, SaturatedConversion}, @@ -651,39 +650,46 @@ impl SignedExtension for WatchDummy { } } -benchmarks!{ - _ { - // Define a common range for `b`. - let b in 1 .. 1000 => (); - } +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking { + use super::*; + use frame_benchmarking::{benchmarks, account}; + use frame_system::RawOrigin; - // This will measure the execution time of `accumulate_dummy` for b in [1..1000] range. - accumulate_dummy { - let b in ...; - let caller = account("caller", 0, 0); - }: _ (RawOrigin::Signed(caller), b.into()) - - // This will measure the execution time of `set_dummy` for b in [1..1000] range. - set_dummy { - let b in ...; - let caller = account("caller", 0, 0); - }: set_dummy (RawOrigin::Signed(caller), b.into()) - - // This will measure the execution time of `set_dummy` for b in [1..10] range. - another_set_dummy { - let b in 1 .. 10; - let caller = account("caller", 0, 0); - }: set_dummy (RawOrigin::Signed(caller), b.into()) - - // This will measure the execution time of sorting a vector. - sort_vector { - let x in 0 .. 10000; - let mut m = Vec::::new(); - for i in 0..x { - m.push(i); + benchmarks!{ + _ { + // Define a common range for `b`. + let b in 1 .. 1000 => (); + } + + // This will measure the execution time of `accumulate_dummy` for b in [1..1000] range. + accumulate_dummy { + let b in ...; + let caller = account("caller", 0, 0); + }: _ (RawOrigin::Signed(caller), b.into()) + + // This will measure the execution time of `set_dummy` for b in [1..1000] range. + set_dummy { + let b in ...; + let caller = account("caller", 0, 0); + }: set_dummy (RawOrigin::Signed(caller), b.into()) + + // This will measure the execution time of `set_dummy` for b in [1..10] range. + another_set_dummy { + let b in 1 .. 10; + let caller = account("caller", 0, 0); + }: set_dummy (RawOrigin::Signed(caller), b.into()) + + // This will measure the execution time of sorting a vector. + sort_vector { + let x in 0 .. 10000; + let mut m = Vec::::new(); + for i in 0..x { + m.push(i); + } + }: { + m.sort(); } - }: { - m.sort(); } } -- GitLab From 5d14d4554e4d2dc6228dbfb93a6a9761b1f7ac73 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Fri, 3 Apr 2020 07:41:33 -0700 Subject: [PATCH 154/300] Use custom runner for import benchmarks (#5477) * custom benchmark runner * add license preamble * delete old benchmarks * update toml * imporove macro * tabs * add size * size fixes * add docs for cli --- Cargo.lock | 15 ++ Cargo.toml | 1 + bin/node/bench/Cargo.toml | 20 +++ bin/node/bench/src/core.rs | 140 ++++++++++++++++ bin/node/bench/src/import.rs | 136 +++++++++++++++ bin/node/bench/src/main.rs | 95 +++++++++++ bin/node/testing/Cargo.toml | 4 - bin/node/testing/benches/import.rs | 259 ----------------------------- 8 files changed, 407 insertions(+), 263 deletions(-) create mode 100644 bin/node/bench/Cargo.toml create mode 100644 bin/node/bench/src/core.rs create mode 100644 bin/node/bench/src/import.rs create mode 100644 bin/node/bench/src/main.rs delete mode 100644 bin/node/testing/benches/import.rs diff --git a/Cargo.lock b/Cargo.lock index a54fe1f64c..b7e9322937 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3314,6 +3314,21 @@ dependencies = [ "void", ] +[[package]] +name = "node-bench" +version = "0.8.0-alpha.5" +dependencies = [ + "log", + "node-primitives", + "node-testing", + "sc-cli", + "sc-client-api", + "serde", + "serde_json", + "sp-runtime", + "structopt", +] + [[package]] name = "node-cli" version = "2.0.0-alpha.5" diff --git a/Cargo.toml b/Cargo.toml index 9b30bfd39e..4fb7b58a43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ members = [ "bin/node-template/node", "bin/node-template/runtime", "bin/node-template/pallets/template", + "bin/node/bench", "bin/node/cli", "bin/node/executor", "bin/node/primitives", diff --git a/bin/node/bench/Cargo.toml b/bin/node/bench/Cargo.toml new file mode 100644 index 0000000000..22e7fe51d8 --- /dev/null +++ b/bin/node/bench/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "node-bench" +version = "0.8.0-alpha.5" +authors = ["Parity Technologies "] +description = "Substrate node integration benchmarks." +edition = "2018" +license = "GPL-3.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +log = "0.4.8" +node-primitives = { version = "2.0.0-alpha.5", path = "../primitives" } +node-testing = { version = "2.0.0-alpha.5", path = "../testing" } +sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0-alpha.5", path = "../../../client/api/" } +sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } +serde = "1.0.101" +serde_json = "1.0.41" +structopt = "0.3" \ No newline at end of file diff --git a/bin/node/bench/src/core.rs b/bin/node/bench/src/core.rs new file mode 100644 index 0000000000..a8164db75a --- /dev/null +++ b/bin/node/bench/src/core.rs @@ -0,0 +1,140 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use std::{fmt, borrow::{Cow, ToOwned}}; +use serde::Serialize; + +pub struct Path(Vec); + +impl Path { + pub fn new(initial: &'static [&'static str]) -> Self { + Path(initial.iter().map(|x| x.to_string()).collect()) + } +} + +impl Path { + pub fn push(&mut self, item: &str) { + self.0.push(item.to_string()); + } + + pub fn full(&self) -> String { + self.0.iter().fold(String::new(), |mut val, next| { val.push_str("::"); val.push_str(next); val }) + } + + pub fn has(&self, path: &str) -> bool { + self.full().contains(path) + } +} + +pub trait BenchmarkDescription { + fn path(&self) -> Path; + + fn setup(self: Box) -> Box; + + fn name(&self) -> Cow<'static, str>; +} + +pub trait Benchmark { + fn run(&mut self) -> std::time::Duration; +} + +#[derive(Debug, Clone, Serialize)] +pub struct BenchmarkOutput { + name: String, + raw_average: u64, + average: u64, +} + +struct NsFormatter(u64); + +impl fmt::Display for NsFormatter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let v = self.0; + + if v < 100 { + return write!(f, "{} ns", v) + } + + if self.0 < 10_000 { + return write!(f, "{:.1} µs", v as f64 / 1000.0) + } + + if self.0 < 1_000_000 { + return write!(f, "{:.1} ms", v as f64 / 1_000_000.0) + } + + if self.0 < 100_000_000 { + return write!(f, "{} ms", v as f64 / 1_000_000.0) + } + + write!(f, "{:.2} s", v as f64 / 1_000_000_000.0) + } +} + +impl fmt::Display for BenchmarkOutput { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "({}: avg {}, w_avg {})", + self.name, + NsFormatter(self.raw_average), + NsFormatter(self.average), + ) + } +} + +pub fn run_benchmark(benchmark: Box) -> BenchmarkOutput { + let name = benchmark.name().to_owned(); + let mut benchmark = benchmark.setup(); + + let mut durations: Vec = vec![]; + for _ in 0..50 { + let duration = benchmark.run(); + durations.push(duration.as_nanos()); + } + + durations.sort(); + + let raw_average = (durations.iter().sum::() / (durations.len() as u128)) as u64; + let average = (durations.iter().skip(10).take(30).sum::() / 30) as u64; + + BenchmarkOutput { + name: name.into(), + raw_average, + average, + } +} + +macro_rules! matrix( + ( $var:ident in $over:expr => $tt:expr, $( $rest:tt )* ) => { + { + let mut res = Vec::>::new(); + for $var in $over.iter() { + res.push(Box::new($tt)); + } + res.extend(matrix!( $($rest)* )); + res + } + }; + ( $var:expr, $( $rest:tt )*) => { + { + let mut res = vec![Box::new($var) as Box]; + res.extend(matrix!( $($rest)* )); + res + } + }; + () => { vec![] } +); \ No newline at end of file diff --git a/bin/node/bench/src/import.rs b/bin/node/bench/src/import.rs new file mode 100644 index 0000000000..20181bf4c7 --- /dev/null +++ b/bin/node/bench/src/import.rs @@ -0,0 +1,136 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Block import benchmark. +//! +//! This benchmark is expected to measure block import operation of +//! some more or less full block. +//! +//! As we also want to protect against cold-cache attacks, this +//! benchmark should not rely on any caching (except those that +//! DO NOT depend on user input). Thus block generation should be +//! based on randomized operation. +//! +//! This is supposed to be very simple benchmark and is not subject +//! to much configuring - just block full of randomized transactions. +//! It is not supposed to measure runtime modules weight correctness + +use std::borrow::Cow; + +use node_testing::bench::{BenchDb, Profile, BlockType, KeyTypes}; +use node_primitives::Block; +use sc_client_api::backend::Backend; +use sp_runtime::generic::BlockId; + +use crate::core::{self, Path}; + +#[derive(Clone, Copy, Debug)] +pub enum SizeType { Small, Medium, Large } + +impl SizeType { + fn transactions(&self) -> usize { + match self { + SizeType::Small => 10, + SizeType::Medium => 100, + SizeType::Large => 500, + } + } +} + +pub struct ImportBenchmarkDescription { + pub profile: Profile, + pub key_types: KeyTypes, + pub size: SizeType, +} + +pub struct ImportBenchmark { + profile: Profile, + database: BenchDb, + block: Block, +} + +impl core::BenchmarkDescription for ImportBenchmarkDescription { + fn path(&self) -> Path { + + let mut path = Path::new(&["node", "import"]); + + match self.profile { + Profile::Wasm => path.push("wasm"), + Profile::Native => path.push("native"), + } + + match self.key_types { + KeyTypes::Sr25519 => path.push("sr25519"), + KeyTypes::Ed25519 => path.push("ed25519"), + } + + match self.size { + SizeType::Small => path.push("small"), + SizeType::Medium => path.push("medium"), + SizeType::Large => path.push("large"), + } + + path + } + + fn setup(self: Box) -> Box { + let profile = self.profile; + let mut bench_db = BenchDb::with_key_types(self.size.transactions(), self.key_types); + let block = bench_db.generate_block(BlockType::RandomTransfers(self.size.transactions())); + Box::new(ImportBenchmark { + database: bench_db, + block, + profile, + }) + } + + fn name(&self) -> Cow<'static, str> { + match self.profile { + Profile::Wasm => "Import benchmark (random transfers, wasm)".into(), + Profile::Native => "Import benchmark (random transfers, native)".into(), + } + } +} + +impl core::Benchmark for ImportBenchmark { + fn run(&mut self) -> std::time::Duration { + let mut context = self.database.create_context(self.profile); + + let _ = context.client.runtime_version_at(&BlockId::Number(0)) + .expect("Failed to get runtime version") + .spec_version; + + let start = std::time::Instant::now(); + context.import_block(self.block.clone()); + let elapsed = start.elapsed(); + + log::info!( + target: "bench-logistics", + "imported block with {} tx, took: {:#?}", + self.block.extrinsics.len(), + elapsed, + ); + + log::info!( + target: "bench-logistics", + "usage info: {}", + context.backend.usage_info() + .expect("RocksDB backend always provides usage info!"), + ); + + elapsed + } +} \ No newline at end of file diff --git a/bin/node/bench/src/main.rs b/bin/node/bench/src/main.rs new file mode 100644 index 0000000000..8f04546526 --- /dev/null +++ b/bin/node/bench/src/main.rs @@ -0,0 +1,95 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +#[macro_use] mod core; +mod import; + +use crate::core::run_benchmark; +use import::{ImportBenchmarkDescription, SizeType}; +use node_testing::bench::{Profile, KeyTypes}; +use structopt::StructOpt; + +#[derive(Debug, StructOpt)] +#[structopt(name = "node-bench", about = "Node integration benchmarks")] +struct Opt { + /// Show list of all available benchmarks. + /// + /// Will output ("name", "path"). Benchmarks can then be filtered by path. + #[structopt(short, long)] + list: bool, + + /// Machine readable json output. + /// + /// This also suppresses all regular output (except to stderr) + #[structopt(short, long)] + json: bool, + + /// Filter benchmarks. + /// + /// Run with `--list` for the hint of what to filter. + filter: Option, +} + +fn main() { + let opt = Opt::from_args(); + + if !opt.json { + sc_cli::init_logger(""); + } + + let benchmarks = matrix!( + profile in [Profile::Wasm, Profile::Native] => + ImportBenchmarkDescription { + profile: *profile, + key_types: KeyTypes::Sr25519, + size: SizeType::Medium, + }, + ImportBenchmarkDescription { + profile: Profile::Native, + key_types: KeyTypes::Ed25519, + size: SizeType::Medium, + }, + size in [SizeType::Small, SizeType::Large] => + ImportBenchmarkDescription { + profile: Profile::Native, + key_types: KeyTypes::Sr25519, + size: *size, + }, + ); + + if opt.list { + for benchmark in benchmarks.iter() { + log::info!("{}: {}", benchmark.name(), benchmark.path().full()) + } + return; + } + + let mut results = Vec::new(); + for benchmark in benchmarks { + if opt.filter.as_ref().map(|f| benchmark.path().has(f)).unwrap_or(true) { + log::info!("Starting {}", benchmark.name()); + let result = run_benchmark(benchmark); + log::info!("{}", result); + + results.push(result); + } + } + + if opt.json { + let json_result: String = serde_json::to_string(&results).expect("Failed to construct json"); + println!("{}", json_result); + } +} \ No newline at end of file diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index b16e313574..df73e20070 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -53,9 +53,5 @@ criterion = "0.3.0" sc-cli = { version = "0.8.0-alpha.5", path = "../../../client/cli" } sc-service = { version = "0.8.0-alpha.5", path = "../../../client/service", features = ["rocksdb"] } -[[bench]] -name = "import" -harness = false - [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/bin/node/testing/benches/import.rs b/bin/node/testing/benches/import.rs deleted file mode 100644 index b36d2e1181..0000000000 --- a/bin/node/testing/benches/import.rs +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Block import benchmark. -//! -//! This benchmark is expected to measure block import operation of -//! some more or less full block. -//! -//! As we also want to protect against cold-cache attacks, this -//! benchmark should not rely on any caching (except those that -//! DO NOT depend on user input). Thus block generation should be -//! based on randomized operation. -//! -//! This is supposed to be very simple benchmark and is not subject -//! to much configuring - just block full of randomized transactions. -//! It is not supposed to measure runtime modules weight correctness - -use std::fmt; -use node_testing::bench::{BenchDb, Profile, BlockType, KeyTypes}; -use node_primitives::Block; -use sp_runtime::generic::BlockId; -use criterion::{Criterion, criterion_group, criterion_main}; -use sc_client_api::backend::Backend; - -criterion_group!( - name = benches; - config = Criterion::default().sample_size(50).warm_up_time(std::time::Duration::from_secs(20)); - targets = bench_block_import, bench_account_reaping, bench_account_ed25519 -); -criterion_group!( - name = wasm_size; - config = Criterion::default().sample_size(10); - targets = bench_wasm_size_import -); -criterion_group!( - name = profile; - config = Criterion::default().sample_size(10); - targets = profile_block_import -); -criterion_main!(benches, profile); - -fn bench_block_import(c: &mut Criterion) { - sc_cli::init_logger(""); - // for future uses, uncomment if something wrong. - // sc_cli::init_logger("sc_client=debug"); - - let mut bench_db = BenchDb::new(100); - let block = bench_db.generate_block(BlockType::RandomTransfers(100)); - - log::trace!( - target: "bench-logistics", - "Seed database directory: {}", - bench_db.path().display(), - ); - - c.bench_function_over_inputs("import-block-B-0001", - move |bencher, profile| { - bencher.iter_batched( - || { - let context = bench_db.create_context(*profile); - - // mostly to just launch compiler before benching! - let version = context.client.runtime_version_at(&BlockId::Number(0)) - .expect("Failed to get runtime version") - .spec_version; - - log::trace!( - target: "bench-logistics", - "Next iteration database directory: {}, runtime version: {}", - context.path().display(), version, - ); - - context - }, - |mut context| { - let start = std::time::Instant::now(); - context.import_block(block.clone()); - let elapsed = start.elapsed(); - - log::info!( - target: "bench-logistics", - "imported block with {} tx, took: {:#?}", - block.extrinsics.len(), - elapsed, - ); - - log::info!( - target: "bench-logistics", - "usage info: {}", - context.backend.usage_info() - .expect("RocksDB backend always provides usage info!"), - ); - }, - criterion::BatchSize::LargeInput, - ); - }, - vec![Profile::Wasm, Profile::Native], - ); -} - -fn bench_account_reaping(c: &mut Criterion) { - sc_cli::init_logger(""); - - let mut bench_db = BenchDb::new(100); - let block = bench_db.generate_block(BlockType::RandomTransfersReaping(100)); - - c.bench_function_over_inputs("import-block-reaping-B-0002", - move |bencher, profile| { - bencher.iter_batched( - || { - let context = bench_db.create_context(*profile); - - // mostly to just launch compiler before benching! - context.client.runtime_version_at(&BlockId::Number(0)) - .expect("Failed to get runtime version"); - - context - }, - |mut context| { - context.import_block(block.clone()); - }, - criterion::BatchSize::LargeInput, - ); - }, - vec![Profile::Wasm, Profile::Native], - ); -} - -fn bench_account_ed25519(c: &mut Criterion) { - sc_cli::init_logger(""); - - let mut bench_db = BenchDb::with_key_types(100, KeyTypes::Ed25519); - let block = bench_db.generate_block(BlockType::RandomTransfers(100)); - - c.bench_function_over_inputs("import-block-ed25519-B-0003", - move |bencher, profile| { - bencher.iter_batched( - || { - let context = bench_db.create_context(*profile); - context.client.runtime_version_at(&BlockId::Number(0)) - .expect("Failed to get runtime version"); - - context - }, - |mut context| { - context.import_block(block.clone()); - }, - criterion::BatchSize::LargeInput, - ); - }, - vec![Profile::Wasm, Profile::Native], - ); -} - -// This is not an actual benchmark, so don't use it to measure anything. -// It just produces special pattern of cpu load that allows easy picking -// the part of block import for the profiling in the tool of choice. -fn profile_block_import(c: &mut Criterion) { - sc_cli::init_logger(""); - - let mut bench_db = BenchDb::new(128); - let block = bench_db.generate_block(BlockType::RandomTransfers(100)); - - c.bench_function("profile block", - move |bencher| { - bencher.iter_batched( - || { - bench_db.create_context(Profile::Native) - }, - |mut context| { - // until better osx signpost/callgrind signal is possible to use - // in rust, we just pause everything completely to help choosing - // actual profiling interval - std::thread::park_timeout(std::time::Duration::from_secs(2)); - context.import_block(block.clone()); - // and here as well - std::thread::park_timeout(std::time::Duration::from_secs(2)); - log::info!( - target: "bench-logistics", - "imported block, usage info: {}", - context.backend.usage_info() - .expect("RocksDB backend always provides usage info!"), - ) - }, - criterion::BatchSize::PerIteration, - ); - }, - ); -} - -struct Setup { - db: BenchDb, - block: Block, -} - -struct SetupIterator { - current: usize, - finish: usize, - multiplier: usize, -} - -impl SetupIterator { - fn new(current: usize, finish: usize, multiplier: usize) -> Self { - SetupIterator { current, finish, multiplier } - } -} - -impl Iterator for SetupIterator { - type Item = Setup; - - fn next(&mut self) -> Option { - if self.current >= self.finish { return None } - - self.current += 1; - - let size = self.current * self.multiplier; - let mut db = BenchDb::new(size); - let block = db.generate_block(BlockType::RandomTransfers(size)); - Some(Setup { db, block }) - } -} - -impl fmt::Debug for Setup { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "Setup: {} tx/block", self.block.extrinsics.len()) - } -} - -fn bench_wasm_size_import(c: &mut Criterion) { - sc_cli::init_logger(""); - - c.bench_function_over_inputs("wasm_size_import", - move |bencher, setup| { - bencher.iter_batched( - || { - setup.db.create_context(Profile::Wasm) - }, - |mut context| { - context.import_block(setup.block.clone()); - }, - criterion::BatchSize::PerIteration, - ); - }, - SetupIterator::new(5, 15, 50), - ); -} -- GitLab From 351e7dc7a551a86db686821611230be43d086628 Mon Sep 17 00:00:00 2001 From: gabriel klawitter Date: Fri, 3 Apr 2020 20:12:18 +0530 Subject: [PATCH 155/300] ci: check_polkadot: check for companion (#5429) --- .maintain/gitlab/check_polkadot_companion_build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index 2258c9505c..eb4c6440f4 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -68,7 +68,8 @@ then if [ -z "${pr_companion}" ] then pr_companion="$(echo "${pr_body}" | sed -n -r \ - 's;^.*https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ + -e 's;^.*paritytech/polkadot/#([0-9]+).*$;\1;p' \ + -e 's;^.*https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ | tail -n 1)" fi -- GitLab From 1193bc2e9520442c6c58ac0ac9cf009f3d1d8001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Fri, 3 Apr 2020 16:45:30 +0200 Subject: [PATCH 156/300] Make Dispatchable return the actual weight consumed (#5458) * Make Dispatchable return the actual weight consumed Add PostInfo associated type to Dispatchable and have frame implement Dispatchable { type PostInfo = PostDispatchInfo } where PostDispatchInfo contains the actual weight consumed. * Fix whitespace issues in docs --- frame/recovery/src/lib.rs | 4 +- frame/scheduler/src/lib.rs | 6 +- frame/sudo/src/lib.rs | 4 +- frame/support/src/dispatch.rs | 73 +++++++++++++++++-- frame/support/src/lib.rs | 6 +- frame/support/src/weights.rs | 59 +++++++++++++++ frame/utility/src/lib.rs | 11 ++- .../runtime/src/generic/checked_extrinsic.rs | 4 +- primitives/runtime/src/lib.rs | 51 ++++++++++++- primitives/runtime/src/testing.rs | 2 +- primitives/runtime/src/traits.rs | 5 +- 11 files changed, 202 insertions(+), 23 deletions(-) diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index c59ba85bdc..c055f2bd97 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -161,6 +161,7 @@ use frame_support::{ decl_module, decl_event, decl_storage, decl_error, ensure, Parameter, RuntimeDebug, weights::{GetDispatchInfo, SimpleDispatchInfo, FunctionOf}, traits::{Currency, ReservableCurrency, Get, BalanceStatus}, + dispatch::PostDispatchInfo, }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -178,7 +179,7 @@ pub trait Trait: frame_system::Trait { type Event: From> + Into<::Event>; /// The overarching call type. - type Call: Parameter + Dispatchable + GetDispatchInfo; + type Call: Parameter + Dispatchable + GetDispatchInfo; /// The currency mechanism. type Currency: ReservableCurrency; @@ -348,6 +349,7 @@ decl_module! { let target = Self::proxy(&who).ok_or(Error::::NotAllowed)?; ensure!(&target == &account, Error::::NotAllowed); call.dispatch(frame_system::RawOrigin::Signed(account).into()) + .map(|_| ()).map_err(|e| e.error) } /// Allow ROOT to bypass the recovery process and set an a rescuer account diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index 8c60df3527..f70204cb1a 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -150,7 +150,11 @@ decl_module! { Lookup::::remove(id); } } - Self::deposit_event(RawEvent::Dispatched((now, index), maybe_id, r)); + Self::deposit_event(RawEvent::Dispatched( + (now, index), + maybe_id, + r.map(|_| ()).map_err(|e| e.error) + )); result = cumulative_weight; None } else { diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index 462a84c0a1..3f2eacdbf8 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -87,7 +87,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use sp_std::prelude::*; -use sp_runtime::{traits::{StaticLookup, Dispatchable}, DispatchError}; +use sp_runtime::traits::{StaticLookup, Dispatchable}; use frame_support::{ Parameter, decl_module, decl_event, decl_storage, decl_error, ensure, @@ -133,7 +133,6 @@ decl_module! { let res = match call.dispatch(frame_system::RawOrigin::Root.into()) { Ok(_) => true, Err(e) => { - let e: DispatchError = e.into(); sp_runtime::print(e); false } @@ -192,7 +191,6 @@ decl_module! { let res = match call.dispatch(frame_system::RawOrigin::Signed(who).into()) { Ok(_) => true, Err(e) => { - let e: DispatchError = e.into(); sp_runtime::print(e); false } diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index dadeb5cf82..026b30d0f4 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -25,18 +25,35 @@ pub use frame_metadata::{ }; pub use crate::weights::{ SimpleDispatchInfo, GetDispatchInfo, DispatchInfo, WeighData, ClassifyDispatch, - TransactionPriority, Weight, PaysFee, + TransactionPriority, Weight, PaysFee, PostDispatchInfo, WithPostDispatchInfo, }; -pub use sp_runtime::{traits::Dispatchable, DispatchError, DispatchResult}; +pub use sp_runtime::{traits::Dispatchable, DispatchError}; pub use crate::traits::{CallMetadata, GetCallMetadata, GetCallName}; +/// The return typ of a `Dispatchable` in frame. When returned explicitly from +/// a dispatchable function it allows overriding the default `PostDispatchInfo` +/// returned from a dispatch. +pub type DispatchResultWithPostInfo = + sp_runtime::DispatchResultWithInfo; + +/// Unaugmented version of `DispatchResultWithPostInfo` that can be returned from +/// dispatchable functions and is automatically converted to the augmented type. Should be +/// used whenever the `PostDispatchInfo` does not need to be overwritten. As this should +/// be the common case it is the implicit return type when none is specified. +pub type DispatchResult = Result<(), sp_runtime::DispatchError>; + +/// The error type contained in a `DispatchResultWithPostInfo`. +pub type DispatchErrorWithPostInfo = + sp_runtime::DispatchErrorWithPostInfo; + + /// A type that cannot be instantiated. pub enum Never {} /// Serializable version of Dispatchable. /// This value can be used as a "function" in an extrinsic. pub trait Callable { - type Call: Dispatchable + Codec + Clone + PartialEq + Eq; + type Call: Dispatchable + Codec + Clone + PartialEq + Eq; } // dirty hack to work around serde_derive issue @@ -119,6 +136,44 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # fn main() {} /// ``` /// +/// ### Consuming only portions of the annotated static weight +/// +/// Per default a callable function consumes all of its static weight as declared via +/// the #[weight] attribute. However, there are use cases where only a portion of this +/// weight should be consumed. In that case the static weight is charged pre dispatch and +/// the difference is refunded post dispatch. +/// +/// In order to make use of this feature the function must return `DispatchResultWithPostInfo` +/// in place of the default `DispatchResult`. Then the actually consumed weight can be returned. +/// To consume a non default weight while returning an error +/// [`WithPostDispatchInfo::with_weight`](./weight/trait.WithPostDispatchInfo.html) can be used +/// to augment any error with custom weight information. +/// +/// ``` +/// # #[macro_use] +/// # extern crate frame_support; +/// # use frame_support::dispatch::{DispatchResultWithPostInfo, WithPostDispatchInfo}; +/// # use frame_support::weights::SimpleDispatchInfo; +/// # use frame_system::{self as system, Trait, ensure_signed}; +/// decl_module! { +/// pub struct Module for enum Call where origin: T::Origin { +/// #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] +/// fn my_long_function(origin, do_expensive_calc: bool) -> DispatchResultWithPostInfo { +/// ensure_signed(origin).map_err(|e| e.with_weight(100_000))?; +/// if do_expensive_calc { +/// // do the expensive calculation +/// // ... +/// // return None to indicate that we are using all weight (the default) +/// return Ok(None.into()); +/// } +/// // expensive calculation not executed: use only a portion of the weight +/// Ok(Some(100_000).into()) +/// } +/// } +/// } +/// # fn main() {} +/// ``` +/// /// ### Privileged Function Example /// /// A privileged function checks that the origin of the call is `ROOT`. @@ -938,7 +993,7 @@ macro_rules! decl_module { $ignore:ident $mod_type:ident<$trait_instance:ident $(, $instance:ident)?> $fn_name:ident $origin:ident $system:ident [ $( $param_name:ident),* ] ) => { - <$mod_type<$trait_instance $(, $instance)?>>::$fn_name( $origin $(, $param_name )* ) + <$mod_type<$trait_instance $(, $instance)?>>::$fn_name( $origin $(, $param_name )* ).map(Into::into).map_err(Into::into) }; // no `deposit_event` function wanted @@ -1538,7 +1593,8 @@ macro_rules! decl_module { { type Trait = $trait_instance; type Origin = $origin_type; - fn dispatch(self, _origin: Self::Origin) -> $crate::sp_runtime::DispatchResult { + type PostInfo = $crate::weights::PostDispatchInfo; + fn dispatch(self, _origin: Self::Origin) -> $crate::dispatch::DispatchResultWithPostInfo { match self { $( $call_type::$fn_name( $( $param_name ),* ) => { @@ -1563,10 +1619,10 @@ macro_rules! decl_module { where $( $other_where_bounds )* { #[doc(hidden)] - pub fn dispatch>( + pub fn dispatch>( d: D, origin: D::Origin - ) -> $crate::sp_runtime::DispatchResult { + ) -> $crate::dispatch::DispatchResultWithPostInfo { d.dispatch(origin) } } @@ -1664,10 +1720,11 @@ macro_rules! impl_outer_dispatch { impl $crate::dispatch::Dispatchable for $call_type { type Origin = $origin; type Trait = $call_type; + type PostInfo = $crate::weights::PostDispatchInfo; fn dispatch( self, origin: $origin, - ) -> $crate::sp_runtime::DispatchResult { + ) -> $crate::dispatch::DispatchResultWithPostInfo { $crate::impl_outer_dispatch! { @DISPATCH_MATCH self diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index f242efecc4..81438ea1bd 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -209,7 +209,11 @@ macro_rules! assert_err { #[cfg(feature = "std")] macro_rules! assert_ok { ( $x:expr $(,)? ) => { - assert_eq!($x, Ok(())); + let is = $x; + match is { + Ok(_) => (), + _ => assert!(false, "Expected Ok(_). Got {:#?}", is), + } }; ( $x:expr, $y:expr $(,)? ) => { assert_eq!($x, Ok($y)); diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index 7e8174ca7b..4d501305f0 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -44,6 +44,7 @@ use sp_runtime::{ traits::SignedExtension, generic::{CheckedExtrinsic, UncheckedExtrinsic}, }; +use crate::dispatch::{DispatchErrorWithPostInfo, DispatchError}; /// Re-export priority as type pub use sp_runtime::transaction_validity::TransactionPriority; @@ -116,6 +117,64 @@ pub struct DispatchInfo { pub pays_fee: bool, } +/// Weight information that is only available post dispatch. +#[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode)] +pub struct PostDispatchInfo { + /// Actual weight consumed by a call or `None` which stands for the worst case static weight. + pub actual_weight: Option, +} + +impl From> for PostDispatchInfo { + fn from(actual_weight: Option) -> Self { + Self { + actual_weight, + } + } +} + +impl From<()> for PostDispatchInfo { + fn from(_: ()) -> Self { + Self { + actual_weight: None, + } + } +} + +impl sp_runtime::traits::Printable for PostDispatchInfo { + fn print(&self) { + "actual_weight=".print(); + match self.actual_weight { + Some(weight) => weight.print(), + None => "max-weight".print(), + } + } +} + +/// Allows easy conversion from `DispatchError` to `DispatchErrorWithPostInfo` for dispatchables +/// that want to return a custom a posteriori weight on error. +pub trait WithPostDispatchInfo { + /// Call this on your modules custom errors type in order to return a custom weight on error. + /// + /// # Example + /// + /// ```ignore + /// let who = ensure_signed(origin).map_err(|e| e.with_weight(100))?; + /// ensure!(who == me, Error::::NotMe.with_weight(200_000)); + /// ``` + fn with_weight(self, actual_weight: Weight) -> DispatchErrorWithPostInfo; +} + +impl WithPostDispatchInfo for T where + T: Into +{ + fn with_weight(self, actual_weight: Weight) -> DispatchErrorWithPostInfo { + DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { actual_weight: Some(actual_weight) }, + error: self.into(), + } + } +} + /// A `Dispatchable` function (aka transaction) that can carry some static information along with /// it, using the `#[weight]` attribute. pub trait GetDispatchInfo { diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 927d8b8786..49aea15a0f 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -68,6 +68,7 @@ use sp_io::hashing::blake2_256; use frame_support::{decl_module, decl_event, decl_error, decl_storage, Parameter, ensure, RuntimeDebug}; use frame_support::{traits::{Get, ReservableCurrency, Currency}, weights::{GetDispatchInfo, DispatchClass,FunctionOf}, + dispatch::PostDispatchInfo, }; use frame_system::{self as system, ensure_signed}; use sp_runtime::{DispatchError, DispatchResult, traits::Dispatchable}; @@ -83,7 +84,7 @@ pub trait Trait: frame_system::Trait { type Event: From> + Into<::Event>; /// The overarching call type. - type Call: Parameter + Dispatchable + GetDispatchInfo + From>; + type Call: Parameter + Dispatchable + GetDispatchInfo + From>; /// The currency mechanism. type Currency: ReservableCurrency; @@ -246,7 +247,7 @@ decl_module! { for (index, call) in calls.into_iter().enumerate() { let result = call.dispatch(origin.clone()); if let Err(e) = result { - Self::deposit_event(Event::::BatchInterrupted(index as u32, e)); + Self::deposit_event(Event::::BatchInterrupted(index as u32, e.error)); return Ok(()); } } @@ -269,6 +270,7 @@ decl_module! { let who = ensure_signed(origin)?; let pseudonym = Self::sub_account_id(who, index); call.dispatch(frame_system::RawOrigin::Signed(pseudonym).into()) + .map(|_| ()).map_err(|e| e.error) } /// Register approval for a dispatch to be made from a deterministic composite account if @@ -357,7 +359,9 @@ decl_module! { let result = call.dispatch(frame_system::RawOrigin::Signed(id.clone()).into()); let _ = T::Currency::unreserve(&m.depositor, m.deposit); >::remove(&id, call_hash); - Self::deposit_event(RawEvent::MultisigExecuted(who, timepoint, id, result)); + Self::deposit_event(RawEvent::MultisigExecuted( + who, timepoint, id, result.map(|_| ()).map_err(|e| e.error) + )); } else { ensure!(maybe_timepoint.is_none(), Error::::UnexpectedTimepoint); if threshold > 1 { @@ -373,6 +377,7 @@ decl_module! { Self::deposit_event(RawEvent::NewMultisig(who, id)); } else { return call.dispatch(frame_system::RawOrigin::Signed(id).into()) + .map(|_| ()).map_err(|e| e.error) } } Ok(()) diff --git a/primitives/runtime/src/generic/checked_extrinsic.rs b/primitives/runtime/src/generic/checked_extrinsic.rs index 911a1131bb..7a71ef5218 100644 --- a/primitives/runtime/src/generic/checked_extrinsic.rs +++ b/primitives/runtime/src/generic/checked_extrinsic.rs @@ -79,7 +79,7 @@ where (None, pre) }; let res = self.function.dispatch(Origin::from(maybe_who)); - Extra::post_dispatch(pre, info.clone(), len); - Ok(res.map_err(Into::into)) + Extra::post_dispatch(pre, info, len); + Ok(res.map(|_| ()).map_err(|e| e.error)) } } diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 1a9aad6bdf..c80971b576 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -353,10 +353,15 @@ impl From for DispatchOutcome { } } -/// Result of a module function call; either nothing (functions are only called for "side effects") -/// or an error message. +/// This is the legacy return type of `Dispatchable`. It is still exposed for compatibilty +/// reasons. The new return type is `DispatchResultWithInfo`. +/// FRAME runtimes should use frame_support::dispatch::DispatchResult pub type DispatchResult = sp_std::result::Result<(), DispatchError>; +/// Return type of a `Dispatchable` which contains the `DispatchResult` and additional information +/// about the `Dispatchable` that is only known post dispatch. +pub type DispatchResultWithInfo = sp_std::result::Result>; + /// Reason why a dispatch call failed #[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize))] @@ -379,6 +384,18 @@ pub enum DispatchError { }, } +/// Result of a `Dispatchable` which contains the `DispatchResult` and additional information +/// about the `Dispatchable` that is only known post dispatch. +#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug)] +pub struct DispatchErrorWithPostInfo where + Info: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable +{ + /// Addditional information about the `Dispatchable` which is only known post dispatch. + pub post_info: Info, + /// The actual `DispatchResult` indicating whether the dispatch was succesfull. + pub error: DispatchError, +} + impl DispatchError { /// Return the same error but without the attached message. pub fn stripped(self) -> Self { @@ -390,6 +407,18 @@ impl DispatchError { } } +impl From for DispatchErrorWithPostInfo where + T: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable + Default, + E: Into +{ + fn from(error: E) -> Self { + Self { + post_info: Default::default(), + error: error.into(), + } + } +} + impl From for DispatchError { fn from(_: crate::traits::LookupError) -> Self { Self::CannotLookup @@ -419,6 +448,14 @@ impl From for &'static str { } } +impl From> for &'static str where + T: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable +{ + fn from(err: DispatchErrorWithPostInfo) -> &'static str { + err.error.into() + } +} + impl traits::Printable for DispatchError { fn print(&self) { "DispatchError".print(); @@ -437,6 +474,16 @@ impl traits::Printable for DispatchError { } } +impl traits::Printable for DispatchErrorWithPostInfo where + T: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable +{ + fn print(&self) { + self.error.print(); + "PostInfo: ".print(); + self.post_info.print(); + } +} + /// This type specifies the outcome of dispatching a call to a module. /// /// In case of failure an error specific to the module is returned. diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index b3139828c1..f5fc35fe8e 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -379,6 +379,6 @@ impl Applyable for TestXt where None }; - Ok(self.call.dispatch(maybe_who.into()).map_err(Into::into)) + Ok(self.call.dispatch(maybe_who.into()).map(|_| ()).map_err(|e| e.error)) } } diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 6bd4b263c3..b5e37944c9 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -642,8 +642,11 @@ pub trait Dispatchable { type Origin; /// ... type Trait; + /// Additional information that is returned by `dispatch`. Can be used to supply the caller + /// with information about a `Dispatchable` that is ownly known post dispatch. + type PostInfo: Eq + PartialEq + Clone + Copy + Encode + Decode + Printable; /// Actually dispatch this call and result the result of it. - fn dispatch(self, origin: Self::Origin) -> crate::DispatchResult; + fn dispatch(self, origin: Self::Origin) -> crate::DispatchResultWithInfo; } /// Means by which a transaction may be extended. This type embodies both the data and the logic -- GitLab From 25fb92ab97614c69e496f5fe628196ad910849d4 Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Fri, 3 Apr 2020 16:48:07 +0200 Subject: [PATCH 157/300] prepopulate CARGO_HOME caches (#5505) * test (ci): prepopulate caches with debug * test (ci): error in path * optimization (ci): CARGO_HOME cache prepopulation --- .gitlab-ci.yml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ddbd74d1bf..1227153028 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -63,6 +63,24 @@ variables: - rustup show - cargo --version - sccache -s + # if there is no directory for this $CI_COMMIT_REF_NAME/$CI_JOB_NAME + # create such directory and + # copy recursively all the files from the newest dir which has $CI_JOB_NAME, if it exists + - | + if [[ ! -d $CARGO_HOME ]]; then + mkdir -p /ci-cache/${CI_PROJECT_NAME}/cargo/${CI_COMMIT_REF_NAME}; + FRESH_CACHE=$(find /ci-cache/${CI_PROJECT_NAME}/cargo -mindepth 2 -maxdepth 2 \ + -type d -name ${CI_JOB_NAME} -exec stat --printf="%Y\t%n\n" {} \; |sort -n -r |head -1 |cut -f2); + if [[ -d $FRESH_CACHE ]]; then + echo "____Using" "$FRESH_CACHE" "to prepopulate the cache____"; + cp -r "${FRESH_CACHE}" "${CARGO_HOME}"; + touch ${CARGO_HOME}/config; + else + echo "_____No such cargo dir, proceeding from scratch_____"; + fi + else + echo "____No need to prepopulate the cache____"; + fi only: - master - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 @@ -78,7 +96,7 @@ variables: dependencies: [] interruptible: true tags: - - linux-docker + - ci2 .build-only: &build-only only: -- GitLab From 525cb7a10a465407c7e057cfdea659e7af95caaa Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 3 Apr 2020 19:08:14 +0200 Subject: [PATCH 158/300] Split the Roles in three types (#5520) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Split the Roles bitfield in three * Forgot to include some changes * Fix cli test * More test fixes * Oh God, merging master broke other tests * Didn't run the doctests * Address review * I'm trying to fix the build blindly because it's taking a good hour to compile on my machine * Address some review * Also update the peerset's API to make sense * Fix peerset tests * Fix browser node * client: distinguish between local and network authority Co-authored-by: André Silva --- bin/node-template/node/src/service.rs | 19 +- bin/node/cli/src/browser.rs | 2 +- bin/node/cli/src/command.rs | 4 +- bin/node/cli/src/service.rs | 19 +- bin/node/inspect/src/command.rs | 2 +- client/authority-discovery/src/lib.rs | 18 +- client/chain-spec/src/chain_spec.rs | 16 +- client/chain-spec/src/lib.rs | 6 +- client/cli/src/commands/build_spec_cmd.rs | 11 +- client/cli/src/commands/check_block_cmd.rs | 4 +- client/cli/src/commands/export_blocks_cmd.rs | 4 +- client/cli/src/commands/import_blocks_cmd.rs | 4 +- client/cli/src/commands/revert_cmd.rs | 4 +- client/cli/src/commands/runcmd.rs | 38 ++-- client/cli/src/params/import_params.rs | 2 +- .../params/network_configuration_params.rs | 24 +- client/cli/src/params/pruning_params.rs | 6 +- .../src/communication/gossip.rs | 205 ++++++++++-------- .../src/communication/tests.rs | 14 +- client/finality-grandpa/src/tests.rs | 15 +- client/network-gossip/src/bridge.rs | 4 +- client/network-gossip/src/state_machine.rs | 22 +- client/network-gossip/src/validator.rs | 4 +- client/network/src/behaviour.rs | 68 +++++- client/network/src/config.rs | 146 +++++++++---- client/network/src/lib.rs | 2 +- client/network/src/protocol.rs | 36 ++- client/network/src/protocol/event.rs | 28 ++- .../src/protocol/generic_proto/tests.rs | 2 +- .../src/protocol/light_client_handler.rs | 2 +- client/network/src/protocol/message.rs | 61 +++++- client/network/src/protocol/sync.rs | 4 +- client/network/src/service.rs | 61 ++++-- client/network/test/src/lib.rs | 23 +- client/network/test/src/sync.rs | 20 +- client/peerset/src/lib.rs | 19 +- client/peerset/tests/fuzz.rs | 15 +- client/rpc-api/src/system/helpers.rs | 4 +- client/rpc/src/system/tests.rs | 4 +- client/service/src/builder.rs | 23 +- client/service/src/config.rs | 23 +- client/service/src/lib.rs | 23 +- client/service/test/src/lib.rs | 14 +- utils/browser/src/lib.rs | 4 +- 44 files changed, 594 insertions(+), 435 deletions(-) diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index 8269017072..b8c1b32b56 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -72,16 +72,11 @@ macro_rules! new_full_start { pub fn new_full(config: Configuration) -> Result { - let is_authority = config.roles.is_authority(); + let role = config.role.clone(); let force_authoring = config.force_authoring; let name = config.name.clone(); let disable_grandpa = config.disable_grandpa; - // sentry nodes announce themselves as authorities to the network - // and should run the same protocols authorities do, but it should - // never actively participate in any consensus process. - let participates_in_consensus = is_authority && !config.sentry_mode; - let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config); let (block_import, grandpa_link) = @@ -96,11 +91,9 @@ pub fn new_full(config: Configuration) })? .build()?; - if participates_in_consensus { - let proposer = sc_basic_authorship::ProposerFactory::new( - service.client(), - service.transaction_pool() - ); + if role.is_authority() { + let proposer = + sc_basic_authorship::ProposerFactory::new(service.client(), service.transaction_pool()); let client = service.client(); let select_chain = service.select_chain() @@ -129,7 +122,7 @@ pub fn new_full(config: Configuration) // 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 = if participates_in_consensus { + let keystore = if role.is_authority() { Some(service.keystore()) } else { None @@ -142,7 +135,7 @@ pub fn new_full(config: Configuration) name: Some(name), observer_enabled: false, keystore, - is_authority, + is_authority: role.is_network_authority(), }; let enable_grandpa = !disable_grandpa; diff --git a/bin/node/cli/src/browser.rs b/bin/node/cli/src/browser.rs index d9377de5d7..e7dd1e78b4 100644 --- a/bin/node/cli/src/browser.rs +++ b/bin/node/cli/src/browser.rs @@ -45,7 +45,7 @@ async fn start_inner(chain_spec: String, log_level: String) -> Result. use sc_cli::VersionInfo; -use sc_service::{Roles as ServiceRoles}; +use sc_service::{Role as ServiceRole}; use node_transaction_factory::RuntimeAdapter; use crate::{Cli, service, ChainSpec, load_spec, Subcommand, factory_impl::FactoryState}; @@ -65,7 +65,7 @@ where cli_args.shared_params.update_config(&mut config, load_spec, &version)?; cli_args.import_params.update_config( &mut config, - ServiceRoles::FULL, + &ServiceRole::Full, cli_args.shared_params.dev, )?; diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 452b1fa3e6..3e09802ccd 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -120,24 +120,17 @@ macro_rules! new_full { use sc_client_api::ExecutorProvider; let ( - is_authority, + role, force_authoring, name, disable_grandpa, - sentry_nodes, ) = ( - $config.roles.is_authority(), + $config.role.clone(), $config.force_authoring, $config.name.clone(), $config.disable_grandpa, - $config.network.sentry_nodes.clone(), ); - // sentry nodes announce themselves as authorities to the network - // and should run the same protocols authorities do, but it should - // never actively participate in any consensus process. - let participates_in_consensus = is_authority && !$config.sentry_mode; - let (builder, mut import_setup, inherent_data_providers) = new_full_start!($config); let service = builder @@ -153,7 +146,7 @@ macro_rules! new_full { ($with_startup_data)(&block_import, &babe_link); - if participates_in_consensus { + if let sc_service::config::Role::Authority { sentry_nodes } = &role { let proposer = sc_basic_authorship::ProposerFactory::new( service.client(), service.transaction_pool() @@ -190,7 +183,7 @@ macro_rules! new_full { let authority_discovery = sc_authority_discovery::AuthorityDiscovery::new( service.client(), network, - sentry_nodes, + sentry_nodes.clone(), service.keystore(), dht_event_stream, service.prometheus_registry(), @@ -201,7 +194,7 @@ macro_rules! new_full { // 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 = if participates_in_consensus { + let keystore = if role.is_authority() { Some(service.keystore()) } else { None @@ -214,7 +207,7 @@ macro_rules! new_full { name: Some(name), observer_enabled: false, keystore, - is_authority, + is_authority: role.is_network_authority(), }; let enable_grandpa = !disable_grandpa; diff --git a/bin/node/inspect/src/command.rs b/bin/node/inspect/src/command.rs index 16bfda2bd9..335b6c8531 100644 --- a/bin/node/inspect/src/command.rs +++ b/bin/node/inspect/src/command.rs @@ -45,7 +45,7 @@ impl InspectCmd { // and all import params (especially pruning that has to match db meta) self.import_params.update_config( &mut config, - sc_service::Roles::FULL, + &sc_service::Role::Full, self.shared_params.dev, )?; diff --git a/client/authority-discovery/src/lib.rs b/client/authority-discovery/src/lib.rs index ec103ab8a0..176e8b2e81 100644 --- a/client/authority-discovery/src/lib.rs +++ b/client/authority-discovery/src/lib.rs @@ -56,12 +56,11 @@ use futures_timer::Delay; use codec::{Decode, Encode}; use error::{Error, Result}; -use libp2p::Multiaddr; use log::{debug, error, log_enabled, warn}; use prometheus_endpoint::{Counter, CounterVec, Gauge, Opts, U64, register}; use prost::Message; use sc_client_api::blockchain::HeaderBackend; -use sc_network::{DhtEvent, ExHashT, NetworkStateInfo}; +use sc_network::{Multiaddr, config::MultiaddrWithPeerId, DhtEvent, ExHashT, NetworkStateInfo}; use sp_authority_discovery::{AuthorityDiscoveryApi, AuthorityId, AuthoritySignature, AuthorityPair}; use sp_core::crypto::{key_types, CryptoTypePublicPair, Pair}; use sp_core::traits::BareCryptoStorePtr; @@ -187,7 +186,7 @@ where pub fn new( client: Arc, network: Arc, - sentry_nodes: Vec, + sentry_nodes: Vec, key_store: BareCryptoStorePtr, dht_event_rx: Pin + Send>>, prometheus_registry: Option, @@ -210,18 +209,7 @@ where ); let sentry_nodes = if !sentry_nodes.is_empty() { - let addrs = sentry_nodes.into_iter().filter_map(|a| match a.parse() { - Ok(addr) => Some(addr), - Err(e) => { - error!( - target: "sub-authority-discovery", - "Failed to parse sentry node public address '{:?}', continuing anyways.", e, - ); - None - } - }).collect::>(); - - Some(addrs) + Some(sentry_nodes.into_iter().map(|ma| ma.concat()).collect::>()) } else { None }; diff --git a/client/chain-spec/src/chain_spec.rs b/client/chain-spec/src/chain_spec.rs index 33f217cb4e..a7cf1d8aac 100644 --- a/client/chain-spec/src/chain_spec.rs +++ b/client/chain-spec/src/chain_spec.rs @@ -27,7 +27,7 @@ use sp_runtime::BuildStorage; use serde_json as json; use crate::RuntimeGenesis; use crate::extension::GetExtension; -use sc_network::Multiaddr; +use sc_network::config::MultiaddrWithPeerId; use sc_telemetry::TelemetryEndpoints; enum GenesisSource { @@ -137,7 +137,7 @@ enum Genesis { struct ClientSpec { name: String, id: String, - boot_nodes: Vec, + boot_nodes: Vec, telemetry_endpoints: Option, protocol_id: Option, properties: Option, @@ -174,7 +174,7 @@ impl Clone for ChainSpec { impl ChainSpec { /// A list of bootnode addresses. - pub fn boot_nodes(&self) -> &[String] { + pub fn boot_nodes(&self) -> &[MultiaddrWithPeerId] { &self.client_spec.boot_nodes } @@ -206,8 +206,8 @@ impl ChainSpec { } /// Add a bootnode to the list. - pub fn add_boot_node(&mut self, addr: Multiaddr) { - self.client_spec.boot_nodes.push(addr.to_string()) + pub fn add_boot_node(&mut self, addr: MultiaddrWithPeerId) { + self.client_spec.boot_nodes.push(addr) } /// Returns a reference to defined chain spec extensions. @@ -220,7 +220,7 @@ impl ChainSpec { name: &str, id: &str, constructor: F, - boot_nodes: Vec, + boot_nodes: Vec, telemetry_endpoints: Option, protocol_id: Option<&str>, properties: Option, @@ -320,7 +320,7 @@ where G: RuntimeGenesis, E: GetExtension + serde::Serialize + Clone + Send, { - fn boot_nodes(&self) -> &[String] { + fn boot_nodes(&self) -> &[MultiaddrWithPeerId] { ChainSpec::boot_nodes(self) } @@ -344,7 +344,7 @@ where ChainSpec::properties(self) } - fn add_boot_node(&mut self, addr: Multiaddr) { + fn add_boot_node(&mut self, addr: MultiaddrWithPeerId) { ChainSpec::add_boot_node(self, addr) } diff --git a/client/chain-spec/src/lib.rs b/client/chain-spec/src/lib.rs index 353c386f36..b7875fdbb4 100644 --- a/client/chain-spec/src/lib.rs +++ b/client/chain-spec/src/lib.rs @@ -117,7 +117,7 @@ pub use sc_chain_spec_derive::{ChainSpecExtension, ChainSpecGroup}; use serde::{Serialize, de::DeserializeOwned}; use sp_runtime::BuildStorage; -use sc_network::Multiaddr; +use sc_network::config::MultiaddrWithPeerId; use sc_telemetry::TelemetryEndpoints; /// A set of traits for the runtime genesis config. @@ -131,7 +131,7 @@ pub trait ChainSpec: BuildStorage + Send { /// Spec id. fn id(&self) -> &str; /// A list of bootnode addresses. - fn boot_nodes(&self) -> &[String]; + fn boot_nodes(&self) -> &[MultiaddrWithPeerId]; /// Telemetry endpoints (if any) fn telemetry_endpoints(&self) -> &Option; /// Network protocol id. @@ -143,7 +143,7 @@ pub trait ChainSpec: BuildStorage + Send { /// Returns a reference to defined chain spec extensions. fn extensions(&self) -> &dyn GetExtension; /// Add a bootnode to the list. - fn add_boot_node(&mut self, addr: Multiaddr); + fn add_boot_node(&mut self, addr: MultiaddrWithPeerId); /// Return spec as JSON. fn as_json(&self, raw: bool) -> Result; /// Return StorageBuilder for this spec. diff --git a/client/cli/src/commands/build_spec_cmd.rs b/client/cli/src/commands/build_spec_cmd.rs index 59f7fbb4e9..67aaf998fc 100644 --- a/client/cli/src/commands/build_spec_cmd.rs +++ b/client/cli/src/commands/build_spec_cmd.rs @@ -16,7 +16,7 @@ use structopt::StructOpt; use log::info; -use sc_network::config::build_multiaddr; +use sc_network::config::{build_multiaddr, MultiaddrWithPeerId}; use sc_service::{Configuration, ChainSpec}; use crate::error; @@ -60,11 +60,10 @@ impl BuildSpecCmd { if spec.boot_nodes().is_empty() && !self.disable_default_bootnode { let keys = config.network.node_key.into_keypair()?; let peer_id = keys.public().into_peer_id(); - let addr = build_multiaddr![ - Ip4([127, 0, 0, 1]), - Tcp(30333u16), - P2p(peer_id) - ]; + let addr = MultiaddrWithPeerId { + multiaddr: build_multiaddr![Ip4([127, 0, 0, 1]), Tcp(30333u16)], + peer_id, + }; spec.add_boot_node(addr) } diff --git a/client/cli/src/commands/check_block_cmd.rs b/client/cli/src/commands/check_block_cmd.rs index 88248c5969..ba267bbf4b 100644 --- a/client/cli/src/commands/check_block_cmd.rs +++ b/client/cli/src/commands/check_block_cmd.rs @@ -18,7 +18,7 @@ use std::fmt::Debug; use std::str::FromStr; use structopt::StructOpt; use sc_service::{ - Configuration, ServiceBuilderCommand, Roles, ChainSpec, + Configuration, ServiceBuilderCommand, Role, ChainSpec, }; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use sp_runtime::generic::BlockId; @@ -93,7 +93,7 @@ impl CheckBlockCmd { F: FnOnce(&str) -> Result, String>, { self.shared_params.update_config(&mut config, spec_factory, version)?; - self.import_params.update_config(&mut config, Roles::FULL, self.shared_params.dev)?; + self.import_params.update_config(&mut config, &Role::Full, self.shared_params.dev)?; config.use_in_memory_keystore()?; Ok(()) diff --git a/client/cli/src/commands/export_blocks_cmd.rs b/client/cli/src/commands/export_blocks_cmd.rs index 61a63806d2..26cfcf61bf 100644 --- a/client/cli/src/commands/export_blocks_cmd.rs +++ b/client/cli/src/commands/export_blocks_cmd.rs @@ -22,7 +22,7 @@ use log::info; use structopt::StructOpt; use sc_service::{ Configuration, ServiceBuilderCommand, ChainSpec, - config::DatabaseConfig, Roles, + config::DatabaseConfig, Role, }; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; @@ -105,7 +105,7 @@ impl ExportBlocksCmd { F: FnOnce(&str) -> Result, String>, { self.shared_params.update_config(&mut config, spec_factory, version)?; - self.pruning_params.update_config(&mut config, Roles::FULL, true)?; + self.pruning_params.update_config(&mut config, &Role::Full, true)?; config.use_in_memory_keystore()?; Ok(()) diff --git a/client/cli/src/commands/import_blocks_cmd.rs b/client/cli/src/commands/import_blocks_cmd.rs index b43407add1..5dc8debe06 100644 --- a/client/cli/src/commands/import_blocks_cmd.rs +++ b/client/cli/src/commands/import_blocks_cmd.rs @@ -20,7 +20,7 @@ use std::fs; use std::path::PathBuf; use structopt::StructOpt; use sc_service::{ - Configuration, ServiceBuilderCommand, ChainSpec, Roles, + Configuration, ServiceBuilderCommand, ChainSpec, Role, }; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; @@ -95,7 +95,7 @@ impl ImportBlocksCmd { F: FnOnce(&str) -> Result, String>, { self.shared_params.update_config(&mut config, spec_factory, version)?; - self.import_params.update_config(&mut config, Roles::FULL, self.shared_params.dev)?; + self.import_params.update_config(&mut config, &Role::Full, self.shared_params.dev)?; config.use_in_memory_keystore()?; Ok(()) diff --git a/client/cli/src/commands/revert_cmd.rs b/client/cli/src/commands/revert_cmd.rs index 8eba199dff..9617f8eda4 100644 --- a/client/cli/src/commands/revert_cmd.rs +++ b/client/cli/src/commands/revert_cmd.rs @@ -17,7 +17,7 @@ use std::fmt::Debug; use structopt::StructOpt; use sc_service::{ - Configuration, ServiceBuilderCommand, ChainSpec, Roles, + Configuration, ServiceBuilderCommand, ChainSpec, Role, }; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; @@ -71,7 +71,7 @@ impl RevertCmd { F: FnOnce(&str) -> Result, String>, { self.shared_params.update_config(&mut config, spec_factory, version)?; - self.pruning_params.update_config(&mut config, Roles::FULL, true)?; + self.pruning_params.update_config(&mut config, &Role::Full, true)?; config.use_in_memory_keystore()?; Ok(()) diff --git a/client/cli/src/commands/runcmd.rs b/client/cli/src/commands/runcmd.rs index ea144ceea4..bdc57a38c3 100644 --- a/client/cli/src/commands/runcmd.rs +++ b/client/cli/src/commands/runcmd.rs @@ -23,8 +23,8 @@ use names::{Generator, Name}; use regex::Regex; use chrono::prelude::*; use sc_service::{ - AbstractService, Configuration, ChainSpec, Roles, - config::{KeystoreConfig, PrometheusConfig}, + AbstractService, Configuration, ChainSpec, Role, + config::{MultiaddrWithPeerId, KeystoreConfig, PrometheusConfig}, }; use sc_telemetry::TelemetryEndpoints; @@ -78,9 +78,10 @@ pub struct RunCmd { /// available to relay to private nodes. #[structopt( long = "sentry", - conflicts_with_all = &[ "validator", "light" ] + conflicts_with_all = &[ "validator", "light" ], + parse(try_from_str) )] - pub sentry: bool, + pub sentry: Vec, /// Disable GRANDPA voter when running in validator mode, otherwise disable the GRANDPA observer. #[structopt(long = "no-grandpa")] @@ -329,18 +330,20 @@ impl RunCmd { let keyring = self.get_keyring(); let is_dev = self.shared_params.dev; let is_light = self.light; - let is_authority = (self.validator || self.sentry || is_dev || keyring.is_some()) + let is_authority = (self.validator || is_dev || keyring.is_some()) && !is_light; let role = if is_light { - sc_service::Roles::LIGHT + sc_service::Role::Light } else if is_authority { - sc_service::Roles::AUTHORITY + sc_service::Role::Authority { sentry_nodes: self.network_config.sentry_nodes.clone() } + } else if !self.sentry.is_empty() { + sc_service::Role::Sentry { validators: self.sentry.clone() } } else { - sc_service::Roles::FULL + sc_service::Role::Full }; - self.import_params.update_config(&mut config, role, is_dev)?; + self.import_params.update_config(&mut config, &role, is_dev)?; config.name = match (self.name.as_ref(), keyring) { (Some(name), _) => name.to_string(), @@ -356,17 +359,14 @@ impl RunCmd { )); } - // set sentry mode (i.e. act as an authority but **never** actively participate) - config.sentry_mode = self.sentry; - - config.offchain_worker = match (&self.offchain_worker, role) { - (OffchainWorkerEnabled::WhenValidating, sc_service::Roles::AUTHORITY) => true, + config.offchain_worker = match (&self.offchain_worker, &role) { + (OffchainWorkerEnabled::WhenValidating, sc_service::Role::Authority { .. }) => true, (OffchainWorkerEnabled::Always, _) => true, (OffchainWorkerEnabled::Never, _) => false, (OffchainWorkerEnabled::WhenValidating, _) => false, }; - config.roles = role; + config.role = role; config.disable_grandpa = self.no_grandpa; let client_id = config.client_id(); @@ -463,10 +463,10 @@ impl RunCmd { info!("❤️ by {}, {}-{}", version.author, version.copyright_start_year, Local::today().year()); info!("📋 Chain specification: {}", config.expect_chain_spec().name()); info!("🏷 Node name: {}", config.name); - info!("👤 Roles: {}", config.display_role()); + info!("👤 Role: {}", config.display_role()); - match config.roles { - Roles::LIGHT => run_service_until_exit( + match config.role { + Role::Light => run_service_until_exit( config, new_light, ), @@ -688,7 +688,7 @@ mod tests { "test", "test-id", || (), - vec!["boo".to_string()], + vec!["/ip4/127.0.0.1/tcp/30333/p2p/QmdSHZLmwEL5Axz5JvWNE2mmxU7qyd7xHBFpyUfktgAdg7".parse().unwrap()], Some(TelemetryEndpoints::new(vec![("wss://foo/bar".to_string(), 42)]) .expect("provided url should be valid")), None, diff --git a/client/cli/src/params/import_params.rs b/client/cli/src/params/import_params.rs index b647feeece..8d34b706f5 100644 --- a/client/cli/src/params/import_params.rs +++ b/client/cli/src/params/import_params.rs @@ -82,7 +82,7 @@ impl ImportParams { pub fn update_config( &self, mut config: &mut Configuration, - role: sc_service::Roles, + role: &sc_service::Role, is_dev: bool, ) -> error::Result<()> { use sc_client_api::execution_extensions::ExecutionStrategies; diff --git a/client/cli/src/params/network_configuration_params.rs b/client/cli/src/params/network_configuration_params.rs index 4de5e44fb5..b01cdeeb1c 100644 --- a/client/cli/src/params/network_configuration_params.rs +++ b/client/cli/src/params/network_configuration_params.rs @@ -19,7 +19,7 @@ use std::iter; use std::net::Ipv4Addr; use structopt::StructOpt; use sc_network::{ - config::{NonReservedPeerMode, TransportConfig}, multiaddr::Protocol, + config::{MultiaddrWithPeerId, NonReservedPeerMode, TransportConfig}, multiaddr::Protocol, Multiaddr, }; use sc_service::Configuration; @@ -30,12 +30,12 @@ use crate::params::node_key_params::NodeKeyParams; #[derive(Debug, StructOpt, Clone)] pub struct NetworkConfigurationParams { /// Specify a list of bootnodes. - #[structopt(long = "bootnodes", value_name = "URL")] - pub bootnodes: Vec, + #[structopt(long = "bootnodes", value_name = "ADDR")] + pub bootnodes: Vec, /// Specify a list of reserved node addresses. - #[structopt(long = "reserved-nodes", value_name = "URL")] - pub reserved_nodes: Vec, + #[structopt(long = "reserved-nodes", value_name = "ADDR")] + pub reserved_nodes: Vec, /// Whether to only allow connections to/from reserved nodes. /// @@ -47,14 +47,14 @@ pub struct NetworkConfigurationParams { /// Specify a list of sentry node public addresses. #[structopt( long = "sentry-nodes", - value_name = "URL", + value_name = "ADDR", conflicts_with_all = &[ "sentry" ] )] - pub sentry_nodes: Vec, + pub sentry_nodes: Vec, /// Listen on this multiaddress. #[structopt(long = "listen-addr", value_name = "LISTEN_ADDR")] - pub listen_addr: Vec, + pub listen_addr: Vec, /// Specify p2p protocol TCP port. /// @@ -117,13 +117,7 @@ impl NetworkConfigurationParams { config.network.non_reserved_mode = NonReservedPeerMode::Deny; } - config.network.sentry_nodes.extend(self.sentry_nodes.clone()); - - for addr in self.listen_addr.iter() { - let addr = addr.parse().ok().ok_or(error::Error::InvalidListenMultiaddress)?; - config.network.listen_addresses.push(addr); - } - + config.network.listen_addresses.extend(self.listen_addr.iter().cloned()); if config.network.listen_addresses.is_empty() { let port = match self.port { Some(port) => port, diff --git a/client/cli/src/params/pruning_params.rs b/client/cli/src/params/pruning_params.rs index ec1066df95..8d069a299f 100644 --- a/client/cli/src/params/pruning_params.rs +++ b/client/cli/src/params/pruning_params.rs @@ -36,7 +36,7 @@ impl PruningParams { pub fn update_config( &self, mut config: &mut Configuration, - role: sc_service::Roles, + role: &sc_service::Role, unsafe_pruning: bool, ) -> error::Result<()> { // by default we disable pruning if the node is an authority (i.e. @@ -45,10 +45,10 @@ impl PruningParams { // unless `unsafe_pruning` is set. config.pruning = match &self.pruning { Some(ref s) if s == "archive" => PruningMode::ArchiveAll, - None if role == sc_service::Roles::AUTHORITY => PruningMode::ArchiveAll, + None if role.is_network_authority() => PruningMode::ArchiveAll, None => PruningMode::default(), Some(s) => { - if role == sc_service::Roles::AUTHORITY && !unsafe_pruning { + if role.is_network_authority() && !unsafe_pruning { return Err(error::Error::Input( "Validators should run with state pruning disabled (i.e. archive). \ You can ignore this check with `--unsafe-pruning`.".to_string() diff --git a/client/finality-grandpa/src/communication/gossip.rs b/client/finality-grandpa/src/communication/gossip.rs index 6b245a4652..683a26a66b 100644 --- a/client/finality-grandpa/src/communication/gossip.rs +++ b/client/finality-grandpa/src/communication/gossip.rs @@ -84,7 +84,7 @@ use sp_runtime::traits::{NumberFor, Block as BlockT, Zero}; use sc_network_gossip::{MessageIntent, ValidatorContext}; -use sc_network::{config::Roles, PeerId, ReputationChange}; +use sc_network::{ObservedRole, PeerId, ReputationChange}; use parity_scale_codec::{Encode, Decode}; use sp_finality_grandpa::AuthorityId; @@ -439,11 +439,11 @@ impl Misbehavior { struct PeerInfo { view: View, - roles: Roles, + roles: ObservedRole, } impl PeerInfo { - fn new(roles: Roles) -> Self { + fn new(roles: ObservedRole) -> Self { PeerInfo { view: View::default(), roles, @@ -469,14 +469,17 @@ impl Default for Peers { } impl Peers { - fn new_peer(&mut self, who: PeerId, roles: Roles) { - if roles.is_authority() && self.lucky_authorities.len() < MIN_LUCKY { - self.lucky_authorities.insert(who.clone()); - } - if !roles.is_authority() && self.lucky_peers.len() < MIN_LUCKY { - self.lucky_peers.insert(who.clone()); + fn new_peer(&mut self, who: PeerId, role: ObservedRole) { + match role { + ObservedRole::Authority if self.lucky_authorities.len() < MIN_LUCKY => { + self.lucky_authorities.insert(who.clone()); + }, + ObservedRole::Full | ObservedRole::Light if self.lucky_peers.len() < MIN_LUCKY => { + self.lucky_peers.insert(who.clone()); + }, + _ => {} } - self.inner.insert(who, PeerInfo::new(roles)); + self.inner.insert(who, PeerInfo::new(role)); } fn peer_disconnected(&mut self, who: &PeerId) { @@ -539,21 +542,28 @@ impl Peers { } fn authorities(&self) -> usize { - self.inner.iter().filter(|(_, info)| info.roles.is_authority()).count() + // Note that our sentry and our validator are neither authorities nor non-authorities. + self.inner.iter().filter(|(_, info)| matches!(info.roles, ObservedRole::Authority)).count() } fn non_authorities(&self) -> usize { - self.inner.iter().filter(|(_, info)| !info.roles.is_authority()).count() + // Note that our sentry and our validator are neither authorities nor non-authorities. + self.inner + .iter() + .filter(|(_, info)| matches!(info.roles, ObservedRole::Full | ObservedRole::Light)) + .count() } fn reshuffle(&mut self) { let mut lucky_peers: Vec<_> = self.inner .iter() - .filter_map(|(id, info)| if !info.roles.is_authority() { Some(id.clone()) } else { None }) + .filter_map(|(id, info)| + if matches!(info.roles, ObservedRole::Full | ObservedRole::Light) { Some(id.clone()) } else { None }) .collect(); let mut lucky_authorities: Vec<_> = self.inner .iter() - .filter_map(|(id, info)| if info.roles.is_authority() { Some(id.clone()) } else { None }) + .filter_map(|(id, info)| + if matches!(info.roles, ObservedRole::Authority) { Some(id.clone()) } else { None }) .collect(); let num_non_authorities = ((lucky_peers.len() as f32).sqrt() as usize) @@ -633,8 +643,11 @@ impl CatchUpConfig { fn request_allowed(&self, peer: &PeerInfo) -> bool { match self { CatchUpConfig::Disabled => false, - CatchUpConfig::Enabled { only_from_authorities, .. } => - !only_from_authorities || peer.roles.is_authority(), + CatchUpConfig::Enabled { only_from_authorities, .. } => match peer.roles { + ObservedRole::Authority | ObservedRole::OurSentry | + ObservedRole::OurGuardedAuthority => true, + _ => !only_from_authorities + } } } } @@ -1121,34 +1134,38 @@ impl Inner { return false; } - if peer.roles.is_authority() { - let authorities = self.peers.authorities(); + match peer.roles { + ObservedRole::OurGuardedAuthority | ObservedRole::OurSentry => true, + ObservedRole::Authority => { + let authorities = self.peers.authorities(); - // the target node is an authority, on the first round duration we start by - // sending the message to only `sqrt(authorities)` (if we're - // connected to at least `MIN_LUCKY`). - if round_elapsed < round_duration * PROPAGATION_ALL_AUTHORITIES - && authorities > MIN_LUCKY - { - self.peers.lucky_authorities.contains(who) - } else { - // otherwise we already went through the step above, so - // we won't filter the message and send it to all - // authorities for whom it is polite to do so - true - } - } else { - // the node is not an authority so we apply stricter filters - if round_elapsed >= round_duration * PROPAGATION_ALL { - // if we waited for 3 (or more) rounds - // then it is allowed to be sent to all peers. - true - } else if round_elapsed >= round_duration * PROPAGATION_SOME_NON_AUTHORITIES { - // otherwise we only send it to `sqrt(non-authorities)`. - self.peers.lucky_peers.contains(who) - } else { - false - } + // the target node is an authority, on the first round duration we start by + // sending the message to only `sqrt(authorities)` (if we're + // connected to at least `MIN_LUCKY`). + if round_elapsed < round_duration * PROPAGATION_ALL_AUTHORITIES + && authorities > MIN_LUCKY + { + self.peers.lucky_authorities.contains(who) + } else { + // otherwise we already went through the step above, so + // we won't filter the message and send it to all + // authorities for whom it is polite to do so + true + } + }, + ObservedRole::Full | ObservedRole::Light => { + // the node is not an authority so we apply stricter filters + if round_elapsed >= round_duration * PROPAGATION_ALL { + // if we waited for 3 (or more) rounds + // then it is allowed to be sent to all peers. + true + } else if round_elapsed >= round_duration * PROPAGATION_SOME_NON_AUTHORITIES { + // otherwise we only send it to `sqrt(non-authorities)`. + self.peers.lucky_peers.contains(who) + } else { + false + } + }, } } @@ -1170,38 +1187,42 @@ impl Inner { let round_duration = self.config.gossip_duration * ROUND_DURATION; let round_elapsed = self.round_start.elapsed(); - if peer.roles.is_authority() { - let authorities = self.peers.authorities(); - - // the target node is an authority, on the first round duration we start by - // sending the message to only `sqrt(authorities)` (if we're - // connected to at least `MIN_LUCKY`). - if round_elapsed < round_duration * PROPAGATION_ALL_AUTHORITIES - && authorities > MIN_LUCKY - { - self.peers.lucky_authorities.contains(who) - } else { - // otherwise we already went through the step above, so - // we won't filter the message and send it to all - // authorities for whom it is polite to do so - true - } - } else { - let non_authorities = self.peers.non_authorities(); - - // the target node is not an authority, on the first and second - // round duration we start by sending the message to only - // `sqrt(non_authorities)` (if we're connected to at least - // `MIN_LUCKY`). - if round_elapsed < round_duration * PROPAGATION_SOME_NON_AUTHORITIES - && non_authorities > MIN_LUCKY - { - self.peers.lucky_peers.contains(who) - } else { - // otherwise we already went through the step above, so - // we won't filter the message and send it to all - // non-authorities for whom it is polite to do so - true + match peer.roles { + ObservedRole::OurSentry | ObservedRole::OurGuardedAuthority => true, + ObservedRole::Authority => { + let authorities = self.peers.authorities(); + + // the target node is an authority, on the first round duration we start by + // sending the message to only `sqrt(authorities)` (if we're + // connected to at least `MIN_LUCKY`). + if round_elapsed < round_duration * PROPAGATION_ALL_AUTHORITIES + && authorities > MIN_LUCKY + { + self.peers.lucky_authorities.contains(who) + } else { + // otherwise we already went through the step above, so + // we won't filter the message and send it to all + // authorities for whom it is polite to do so + true + } + }, + ObservedRole::Full | ObservedRole::Light => { + let non_authorities = self.peers.non_authorities(); + + // the target node is not an authority, on the first and second + // round duration we start by sending the message to only + // `sqrt(non_authorities)` (if we're connected to at least + // `MIN_LUCKY`). + if round_elapsed < round_duration * PROPAGATION_SOME_NON_AUTHORITIES + && non_authorities > MIN_LUCKY + { + self.peers.lucky_peers.contains(who) + } else { + // otherwise we already went through the step above, so + // we won't filter the message and send it to all + // non-authorities for whom it is polite to do so + true + } } } } @@ -1397,7 +1418,7 @@ impl GossipValidator { } impl sc_network_gossip::Validator for GossipValidator { - fn new_peer(&self, context: &mut dyn ValidatorContext, who: &PeerId, roles: Roles) { + fn new_peer(&self, context: &mut dyn ValidatorContext, who: &PeerId, roles: ObservedRole) { let packet = { let mut inner = self.inner.write(); inner.peers.new_peer(who.clone(), roles); @@ -1657,7 +1678,7 @@ mod tests { assert!(res.unwrap().is_none()); // connect & disconnect. - peers.new_peer(id.clone(), Roles::AUTHORITY); + peers.new_peer(id.clone(), ObservedRole::Authority); peers.peer_disconnected(&id); let res = peers.update_peer_state(&id, update.clone()); @@ -1693,7 +1714,7 @@ mod tests { let mut peers = Peers::default(); let id = PeerId::random(); - peers.new_peer(id.clone(), Roles::AUTHORITY); + peers.new_peer(id.clone(), ObservedRole::Authority); let mut check_update = move |update: NeighborPacket<_>| { let view = peers.update_peer_state(&id, update.clone()).unwrap().unwrap(); @@ -1713,7 +1734,7 @@ mod tests { let mut peers = Peers::default(); let id = PeerId::random(); - peers.new_peer(id.clone(), Roles::AUTHORITY); + peers.new_peer(id.clone(), ObservedRole::Authority); peers.update_peer_state(&id, NeighborPacket { round: Round(10), @@ -1914,7 +1935,7 @@ mod tests { // add the peer making the request to the validator, // otherwise it is discarded let mut inner = val.inner.write(); - inner.peers.new_peer(peer.clone(), Roles::AUTHORITY); + inner.peers.new_peer(peer.clone(), ObservedRole::Authority); let res = inner.handle_catch_up_request( &peer, @@ -1965,7 +1986,7 @@ mod tests { // add the peer making the request to the validator, // otherwise it is discarded let peer = PeerId::random(); - val.inner.write().peers.new_peer(peer.clone(), Roles::AUTHORITY); + val.inner.write().peers.new_peer(peer.clone(), ObservedRole::Authority); let send_request = |set_id, round| { let mut inner = val.inner.write(); @@ -2045,7 +2066,7 @@ mod tests { // add the peer making the request to the validator, // otherwise it is discarded. let peer = PeerId::random(); - val.inner.write().peers.new_peer(peer.clone(), Roles::AUTHORITY); + val.inner.write().peers.new_peer(peer.clone(), ObservedRole::Authority); let import_neighbor_message = |set_id, round| { let (_, _, catch_up_request, _) = val.inner.write().import_neighbor_message( @@ -2119,7 +2140,7 @@ mod tests { // add the peer making the request to the validator, // otherwise it is discarded. let peer = PeerId::random(); - val.inner.write().peers.new_peer(peer.clone(), Roles::AUTHORITY); + val.inner.write().peers.new_peer(peer.clone(), ObservedRole::Authority); // importing a neighbor message from a peer in the same set in a later // round should lead to a catch up request but since they're disabled @@ -2155,8 +2176,8 @@ mod tests { let peer_authority = PeerId::random(); let peer_full = PeerId::random(); - val.inner.write().peers.new_peer(peer_authority.clone(), Roles::AUTHORITY); - val.inner.write().peers.new_peer(peer_full.clone(), Roles::FULL); + val.inner.write().peers.new_peer(peer_authority.clone(), ObservedRole::Authority); + val.inner.write().peers.new_peer(peer_full.clone(), ObservedRole::Full); let import_neighbor_message = |peer| { let (_, _, catch_up_request, _) = val.inner.write().import_neighbor_message( @@ -2213,7 +2234,7 @@ mod tests { // add the peer making the requests to the validator, otherwise it is // discarded. let peer_full = PeerId::random(); - val.inner.write().peers.new_peer(peer_full.clone(), Roles::FULL); + val.inner.write().peers.new_peer(peer_full.clone(), ObservedRole::Full); let (_, _, catch_up_request, _) = val.inner.write().import_neighbor_message( &peer_full, @@ -2290,8 +2311,8 @@ mod tests { full_nodes.resize_with(30, || PeerId::random()); for i in 0..30 { - val.inner.write().peers.new_peer(authorities[i].clone(), Roles::AUTHORITY); - val.inner.write().peers.new_peer(full_nodes[i].clone(), Roles::FULL); + val.inner.write().peers.new_peer(authorities[i].clone(), ObservedRole::Authority); + val.inner.write().peers.new_peer(full_nodes[i].clone(), ObservedRole::Full); } let test = |num_round, peers| { @@ -2363,7 +2384,7 @@ mod tests { let mut authorities = Vec::new(); for _ in 0..5 { let peer_id = PeerId::random(); - val.inner.write().peers.new_peer(peer_id.clone(), Roles::AUTHORITY); + val.inner.write().peers.new_peer(peer_id.clone(), ObservedRole::Authority); authorities.push(peer_id); } @@ -2403,7 +2424,7 @@ mod tests { let mut authorities = Vec::new(); for _ in 0..100 { let peer_id = PeerId::random(); - val.inner.write().peers.new_peer(peer_id.clone(), Roles::AUTHORITY); + val.inner.write().peers.new_peer(peer_id.clone(), ObservedRole::Authority); authorities.push(peer_id); } @@ -2454,7 +2475,7 @@ mod tests { val.inner .write() .peers - .new_peer(peer1.clone(), Roles::AUTHORITY); + .new_peer(peer1.clone(), ObservedRole::Authority); val.inner .write() @@ -2474,7 +2495,7 @@ mod tests { val.inner .write() .peers - .new_peer(peer2.clone(), Roles::AUTHORITY); + .new_peer(peer2.clone(), ObservedRole::Authority); // create a commit for round 1 of set id 1 // targeting a block at height 2 diff --git a/client/finality-grandpa/src/communication/tests.rs b/client/finality-grandpa/src/communication/tests.rs index 7c9170a48e..eb5ff6fccf 100644 --- a/client/finality-grandpa/src/communication/tests.rs +++ b/client/finality-grandpa/src/communication/tests.rs @@ -18,7 +18,7 @@ use futures::channel::mpsc; use futures::prelude::*; -use sc_network::{Event as NetworkEvent, PeerId, config::Roles}; +use sc_network::{Event as NetworkEvent, ObservedRole, PeerId}; use sc_network_test::{Block, Hash}; use sc_network_gossip::Validator; use std::sync::Arc; @@ -256,7 +256,7 @@ fn good_commit_leads_to_relay() { let test = make_test_network().0 .then(move |tester| { // register a peer. - tester.gossip_validator.new_peer(&mut NoopContext, &id, sc_network::config::Roles::FULL); + tester.gossip_validator.new_peer(&mut NoopContext, &id, ObservedRole::Full); future::ready((tester, id)) }) .then(move |(tester, id)| { @@ -284,7 +284,7 @@ fn good_commit_leads_to_relay() { let _ = sender.unbounded_send(NetworkEvent::NotificationStreamOpened { remote: sender_id.clone(), engine_id: GRANDPA_ENGINE_ID, - roles: Roles::FULL, + role: ObservedRole::Full, }); let _ = sender.unbounded_send(NetworkEvent::NotificationsReceived { @@ -297,7 +297,7 @@ fn good_commit_leads_to_relay() { let _ = sender.unbounded_send(NetworkEvent::NotificationStreamOpened { remote: receiver_id.clone(), engine_id: GRANDPA_ENGINE_ID, - roles: Roles::FULL, + role: ObservedRole::Full, }); // Announce its local set has being on the current set id through a neighbor @@ -404,7 +404,7 @@ fn bad_commit_leads_to_report() { let test = make_test_network().0 .map(move |tester| { // register a peer. - tester.gossip_validator.new_peer(&mut NoopContext, &id, sc_network::config::Roles::FULL); + tester.gossip_validator.new_peer(&mut NoopContext, &id, ObservedRole::Full); (tester, id) }) .then(move |(tester, id)| { @@ -431,7 +431,7 @@ fn bad_commit_leads_to_report() { let _ = sender.unbounded_send(NetworkEvent::NotificationStreamOpened { remote: sender_id.clone(), engine_id: GRANDPA_ENGINE_ID, - roles: Roles::FULL, + role: ObservedRole::Full, }); let _ = sender.unbounded_send(NetworkEvent::NotificationsReceived { remote: sender_id.clone(), @@ -482,7 +482,7 @@ fn peer_with_higher_view_leads_to_catch_up_request() { let test = tester .map(move |tester| { // register a peer with authority role. - tester.gossip_validator.new_peer(&mut NoopContext, &id, sc_network::config::Roles::AUTHORITY); + tester.gossip_validator.new_peer(&mut NoopContext, &id, ObservedRole::Authority); (tester, id) }) .then(move |(tester, id)| { diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 05ce90d3f1..312f7976bc 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -22,7 +22,7 @@ use sc_network_test::{ Block, Hash, TestNetFactory, BlockImportAdapter, Peer, PeersClient, PassThroughVerifier, PeersFullClient, }; -use sc_network::config::{ProtocolConfig, Roles, BoxFinalityProofRequestBuilder}; +use sc_network::config::{ProtocolConfig, BoxFinalityProofRequestBuilder}; use parking_lot::Mutex; use futures_timer::Delay; use tokio::runtime::{Runtime, Handle}; @@ -74,9 +74,8 @@ impl GrandpaTestNet { peers: Vec::with_capacity(n_peers), test_config, }; - let config = Self::default_config(); for _ in 0..n_peers { - net.add_full_peer(&config); + net.add_full_peer(); } net } @@ -95,10 +94,8 @@ impl TestNetFactory for GrandpaTestNet { } fn default_config() -> ProtocolConfig { - // the authority role ensures gossip hits all nodes here. - let mut config = ProtocolConfig::default(); - config.roles = Roles::AUTHORITY; - config + // This is unused. + ProtocolConfig::default() } fn make_verifier( @@ -1303,7 +1300,7 @@ fn finality_proof_is_fetched_by_light_client_when_consensus_data_changes() { let peers = &[Ed25519Keyring::Alice]; let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 1); - net.add_light_peer(&GrandpaTestNet::default_config()); + net.add_light_peer(); // import block#1 WITH consensus data change. Light client ignores justification // && instead fetches finality proof for block #1 @@ -1380,7 +1377,7 @@ fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_differ run_to_completion(&mut runtime, 11, net.clone(), peers_a); // request finalization by light client - net.lock().add_light_peer(&GrandpaTestNet::default_config()); + net.lock().add_light_peer(); net.lock().block_until_sync(); // check block, finalized on light client diff --git a/client/network-gossip/src/bridge.rs b/client/network-gossip/src/bridge.rs index 0b3a58bba2..270376be19 100644 --- a/client/network-gossip/src/bridge.rs +++ b/client/network-gossip/src/bridge.rs @@ -137,11 +137,11 @@ impl Future for GossipEngine { loop { match this.network_event_stream.poll_next_unpin(cx) { Poll::Ready(Some(event)) => match event { - Event::NotificationStreamOpened { remote, engine_id: msg_engine_id, roles } => { + Event::NotificationStreamOpened { remote, engine_id: msg_engine_id, role } => { if msg_engine_id != this.engine_id { continue; } - this.state_machine.new_peer(&mut *this.network, remote, roles); + this.state_machine.new_peer(&mut *this.network, remote, role); } Event::NotificationStreamClosed { remote, engine_id: msg_engine_id } => { if msg_engine_id != this.engine_id { diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index e2d7ec45b5..20eb4aaf89 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -26,7 +26,7 @@ use lru::LruCache; use libp2p::PeerId; use sp_runtime::traits::{Block as BlockT, Hash, HashFor}; use sp_runtime::ConsensusEngineId; -use sc_network::config::Roles; +use sc_network::ObservedRole; use wasm_timer::Instant; // FIXME: Add additional spam/DoS attack protection: https://github.com/paritytech/substrate/issues/1115 @@ -51,7 +51,7 @@ mod rep { struct PeerConsensus { known_messages: HashSet, - roles: Roles, + role: ObservedRole, } /// Topic stream message with sender. @@ -192,10 +192,10 @@ impl ConsensusGossip { validator: Arc> ) { self.register_validator_internal(engine_id, validator.clone()); - let peers: Vec<_> = self.peers.iter().map(|(id, peer)| (id.clone(), peer.roles)).collect(); - for (id, roles) in peers { + let peers: Vec<_> = self.peers.iter().map(|(id, peer)| (id.clone(), peer.role.clone())).collect(); + for (id, role) in peers { let mut context = NetworkContext { gossip: self, network, engine_id: engine_id.clone() }; - validator.new_peer(&mut context, &id, roles); + validator.new_peer(&mut context, &id, role); } } @@ -204,20 +204,20 @@ impl ConsensusGossip { } /// Handle new connected peer. - pub fn new_peer(&mut self, network: &mut dyn Network, who: PeerId, roles: Roles) { + pub fn new_peer(&mut self, network: &mut dyn Network, who: PeerId, role: ObservedRole) { // light nodes are not valid targets for consensus gossip messages - if !roles.is_full() { + if role.is_light() { return; } - trace!(target:"gossip", "Registering {:?} {}", roles, who); + trace!(target:"gossip", "Registering {:?} {}", role, who); self.peers.insert(who.clone(), PeerConsensus { known_messages: HashSet::new(), - roles, + role: role.clone(), }); for (engine_id, v) in self.validators.clone() { let mut context = NetworkContext { gossip: self, network, engine_id: engine_id.clone() }; - v.new_peer(&mut context, &who, roles); + v.new_peer(&mut context, &who, role.clone()); } } @@ -696,7 +696,7 @@ mod tests { let mut network = TestNetwork; let peer_id = PeerId::random(); - consensus.new_peer(&mut network, peer_id.clone(), Roles::FULL); + consensus.new_peer(&mut network, peer_id.clone(), ObservedRole::Full); assert!(consensus.peers.contains_key(&peer_id)); consensus.peer_disconnected(&mut network, peer_id.clone()); diff --git a/client/network-gossip/src/validator.rs b/client/network-gossip/src/validator.rs index 74b5307ee9..6b330d7b61 100644 --- a/client/network-gossip/src/validator.rs +++ b/client/network-gossip/src/validator.rs @@ -14,13 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use sc_network::{config::Roles, PeerId}; +use sc_network::{ObservedRole, PeerId}; use sp_runtime::traits::Block as BlockT; /// Validates consensus messages. pub trait Validator: Send + Sync { /// New peer is connected. - fn new_peer(&self, _context: &mut dyn ValidatorContext, _who: &PeerId, _roles: Roles) { + fn new_peer(&self, _context: &mut dyn ValidatorContext, _who: &PeerId, _role: ObservedRole) { } /// New connection is dropped. diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index 26a020aae0..203435134c 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -15,18 +15,19 @@ // along with Substrate. If not, see . use crate::{ + config::Role, debug_info, discovery::DiscoveryBehaviour, discovery::DiscoveryOut, - Event, protocol::event::DhtEvent, ExHashT, + Event, ObservedRole, DhtEvent, ExHashT, }; -use crate::protocol::{self, light_client_handler, CustomMessageOutcome, Protocol}; +use crate::protocol::{self, light_client_handler, message::Roles, CustomMessageOutcome, Protocol}; use libp2p::NetworkBehaviour; use libp2p::core::{Multiaddr, PeerId, PublicKey}; use libp2p::kad::record; use libp2p::swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters}; use log::debug; use sp_consensus::{BlockOrigin, import_queue::{IncomingBlock, Origin}}; -use sp_runtime::{traits::{Block as BlockT, NumberFor}, Justification}; -use std::{iter, task::Context, task::Poll}; +use sp_runtime::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId, Justification}; +use std::{borrow::Cow, iter, task::Context, task::Poll}; use void; /// General behaviour of the network. Combines all protocols together. @@ -44,9 +45,14 @@ pub struct Behaviour { block_requests: protocol::BlockRequests, /// Light client request handling. light_client_handler: protocol::LightClientHandler, + /// Queue of events to produce for the outside. #[behaviour(ignore)] events: Vec>, + + /// Role of our local node, as originally passed from the configuration. + #[behaviour(ignore)] + role: Role, } /// Event generated by `Behaviour`. @@ -63,6 +69,7 @@ impl Behaviour { /// Builds a new `Behaviour`. pub async fn new( substrate: Protocol, + role: Role, user_agent: String, local_public_key: PublicKey, known_addresses: Vec<(PeerId, Multiaddr)>, @@ -84,7 +91,8 @@ impl Behaviour { ).await, block_requests, light_client_handler, - events: Vec::new() + events: Vec::new(), + role, } } @@ -112,6 +120,32 @@ impl Behaviour { self.debug_info.node(peer_id) } + /// Registers a new notifications protocol. + /// + /// After that, you can call `write_notifications`. + /// + /// Please call `event_stream` before registering a protocol, otherwise you may miss events + /// about the protocol that you have registered. + /// + /// You are very strongly encouraged to call this method very early on. Any connection open + /// will retain the protocols that were registered then, and not any new one. + pub fn register_notifications_protocol( + &mut self, + engine_id: ConsensusEngineId, + protocol_name: impl Into>, + ) { + let list = self.substrate.register_notifications_protocol(engine_id, protocol_name); + for (remote, roles) in list { + let role = reported_roles_to_observed_role(&self.role, remote, roles); + let ev = Event::NotificationStreamOpened { + remote: remote.clone(), + engine_id, + role, + }; + self.events.push(BehaviourOut::Event(ev)); + } + } + /// Returns a shared reference to the user protocol. pub fn user_protocol(&self) -> &Protocol { &self.substrate @@ -138,6 +172,22 @@ impl Behaviour { } } +fn reported_roles_to_observed_role(local_role: &Role, remote: &PeerId, roles: Roles) -> ObservedRole { + if roles.is_authority() { + match local_role { + Role::Authority { sentry_nodes } + if sentry_nodes.iter().any(|s| s.peer_id == *remote) => ObservedRole::OurSentry, + Role::Sentry { validators } + if validators.iter().any(|s| s.peer_id == *remote) => ObservedRole::OurGuardedAuthority, + _ => ObservedRole::Authority + } + } else if roles.is_full() { + ObservedRole::Full + } else { + ObservedRole::Light + } +} + impl NetworkBehaviourEventProcess for Behaviour { fn inject_event(&mut self, event: void::Void) { @@ -155,14 +205,16 @@ Behaviour { self.events.push(BehaviourOut::JustificationImport(origin, hash, nb, justification)), CustomMessageOutcome::FinalityProofImport(origin, hash, nb, proof) => self.events.push(BehaviourOut::FinalityProofImport(origin, hash, nb, proof)), - CustomMessageOutcome::NotificationStreamOpened { remote, protocols, roles } => + CustomMessageOutcome::NotificationStreamOpened { remote, protocols, roles } => { + let role = reported_roles_to_observed_role(&self.role, &remote, roles); for engine_id in protocols { self.events.push(BehaviourOut::Event(Event::NotificationStreamOpened { remote: remote.clone(), engine_id, - roles, + role: role.clone(), })); - }, + } + }, CustomMessageOutcome::NotificationStreamClosed { remote, protocols } => for engine_id in protocols { self.events.push(BehaviourOut::Event(Event::NotificationStreamClosed { diff --git a/client/network/src/config.rs b/client/network/src/config.rs index b8031654df..c9290927eb 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -31,23 +31,21 @@ pub use crate::protocol::ProtocolConfig; use crate::service::ExHashT; -use bitflags::bitflags; use sp_consensus::{block_validation::BlockAnnounceValidator, import_queue::ImportQueue}; use sp_runtime::traits::{Block as BlockT}; use libp2p::identity::{Keypair, ed25519}; use libp2p::wasm_ext; use libp2p::{PeerId, Multiaddr, multiaddr}; use core::{fmt, iter}; -use std::{future::Future, pin::Pin}; +use std::{convert::TryFrom, future::Future, pin::Pin, str::FromStr}; use std::{error::Error, fs, io::{self, Write}, net::Ipv4Addr, path::{Path, PathBuf}, sync::Arc}; use zeroize::Zeroize; use prometheus_endpoint::Registry; - /// Network initialization parameters. pub struct Params { - /// Assigned roles for our node (full, light, ...). - pub roles: Roles, + /// Assigned role for our node (full, light, ...). + pub role: Role, /// How to spawn background tasks. If you pass `None`, then a threads pool will be used by /// default. @@ -97,54 +95,48 @@ pub struct Params { pub metrics_registry: Option, } -bitflags! { - /// Bitmask of the roles that a node fulfills. - pub struct Roles: u8 { - /// No network. - const NONE = 0b00000000; - /// Full node, does not participate in consensus. - const FULL = 0b00000001; - /// Light client node. - const LIGHT = 0b00000010; - /// Act as an authority - const AUTHORITY = 0b00000100; +/// Role of the local node. +#[derive(Debug, Clone)] +pub enum Role { + /// Regular full node. + Full, + /// Regular light node. + Light, + /// Sentry node that guards an authority. Will be reported as "authority" on the wire protocol. + Sentry { + /// Address and identity of the validator nodes that we're guarding. + /// + /// The nodes will be granted some priviledged status. + validators: Vec, + }, + /// Actual authority. + Authority { + /// List of public addresses and identities of our sentry nodes. + sentry_nodes: Vec, } } -impl Roles { - /// Does this role represents a client that holds full chain data locally? - pub fn is_full(&self) -> bool { - self.intersects(Roles::FULL | Roles::AUTHORITY) - } - - /// Does this role represents a client that does not participates in the consensus? +impl Role { + /// True for `Role::Authority` pub fn is_authority(&self) -> bool { - *self == Roles::AUTHORITY + matches!(self, Role::Authority { .. }) } - /// Does this role represents a client that does not hold full chain data locally? - pub fn is_light(&self) -> bool { - !self.is_full() + /// True for `Role::Authority` and `Role::Sentry` since they're both + /// announced as having the authority role to the network. + pub fn is_network_authority(&self) -> bool { + matches!(self, Role::Authority { .. } | Role::Sentry { .. }) } } -impl fmt::Display for Roles { +impl fmt::Display for Role { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self) - } -} - -impl codec::Encode for Roles { - fn encode_to(&self, dest: &mut T) { - dest.push_byte(self.bits()) - } -} - -impl codec::EncodeLike for Roles {} - -impl codec::Decode for Roles { - fn decode(input: &mut I) -> Result { - Self::from_bits(input.read_byte()?).ok_or_else(|| codec::Error::from("Invalid bytes")) + match self { + Role::Full => write!(f, "FULL"), + Role::Light => write!(f, "LIGHT"), + Role::Sentry { .. } => write!(f, "SENTRY"), + Role::Authority { .. } => write!(f, "AUTHORITY"), + } } } @@ -214,6 +206,67 @@ pub fn parse_addr(mut addr: Multiaddr)-> Result<(PeerId, Multiaddr), ParseErr> { Ok((who, addr)) } +/// Address of a node, including its identity. +/// +/// This struct represents a decoded version of a multiaddress that ends with `/p2p/`. +/// +/// # Example +/// +/// ``` +/// # use sc_network::{Multiaddr, PeerId, config::MultiaddrWithPeerId}; +/// let addr: MultiaddrWithPeerId = +/// "/ip4/198.51.100.19/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV".parse().unwrap(); +/// assert_eq!(addr.peer_id.to_base58(), "QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV"); +/// assert_eq!(addr.multiaddr.to_string(), "/ip4/198.51.100.19/tcp/30333"); +/// ``` +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[serde(try_from = "String", into = "String")] +pub struct MultiaddrWithPeerId { + /// Address of the node. + pub multiaddr: Multiaddr, + /// Its identity. + pub peer_id: PeerId, +} + +impl MultiaddrWithPeerId { + /// Concatenates the multiaddress and peer ID into one multiaddress containing both. + pub fn concat(&self) -> Multiaddr { + let proto = multiaddr::Protocol::P2p(From::from(self.peer_id.clone())); + self.multiaddr.clone().with(proto) + } +} + +impl fmt::Display for MultiaddrWithPeerId { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.concat(), f) + } +} + +impl FromStr for MultiaddrWithPeerId { + type Err = ParseErr; + + fn from_str(s: &str) -> Result { + let (peer_id, multiaddr) = parse_str_addr(s)?; + Ok(MultiaddrWithPeerId { + peer_id, + multiaddr, + }) + } +} + +impl From for String { + fn from(ma: MultiaddrWithPeerId) -> String { + format!("{}", ma) + } +} + +impl TryFrom for MultiaddrWithPeerId { + type Error = ParseErr; + fn try_from(string: String) -> Result { + string.parse() + } +} + /// Error that can be generated by `parse_str_addr`. #[derive(Debug)] pub enum ParseErr { @@ -263,7 +316,7 @@ pub struct NetworkConfiguration { /// Multiaddresses to advertise. Detected automatically if empty. pub public_addresses: Vec, /// List of initial node addresses - pub boot_nodes: Vec, + pub boot_nodes: Vec, /// The node key configuration, which determines the node's network identity keypair. pub node_key: NodeKeyConfig, /// Maximum allowed number of incoming connections. @@ -271,11 +324,9 @@ pub struct NetworkConfiguration { /// Number of outgoing connections we're trying to maintain. pub out_peers: u32, /// List of reserved node addresses. - pub reserved_nodes: Vec, + pub reserved_nodes: Vec, /// The non-reserved peer mode. pub non_reserved_mode: NonReservedPeerMode, - /// List of sentry node public addresses. - pub sentry_nodes: Vec, /// Client identifier. Sent over the wire for debugging purposes. pub client_version: String, /// Name of the node. Sent over the wire for debugging purposes. @@ -299,7 +350,6 @@ impl Default for NetworkConfiguration { out_peers: 75, reserved_nodes: Vec::new(), non_reserved_mode: NonReservedPeerMode::Accept, - sentry_nodes: Vec::new(), client_version: "unknown".into(), node_name: "unknown".into(), transport: TransportConfig::Normal { diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index bb58f8c7bf..b425a7763b 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -248,7 +248,7 @@ pub mod network_state; pub use service::{NetworkService, NetworkStateInfo, NetworkWorker, ExHashT, ReportHandle}; pub use protocol::PeerInfo; -pub use protocol::event::{Event, DhtEvent}; +pub use protocol::event::{Event, DhtEvent, ObservedRole}; pub use protocol::sync::SyncState; pub use libp2p::{Multiaddr, PeerId}; #[doc(inline)] diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 24d502ef2f..bfe8226c8d 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -39,11 +39,11 @@ use sp_runtime::traits::{ }; use sp_arithmetic::traits::SaturatedConversion; use message::{BlockAnnounce, Message}; -use message::generic::{Message as GenericMessage, ConsensusMessage}; +use message::generic::{Message as GenericMessage, ConsensusMessage, Roles}; use prometheus_endpoint::{Registry, Gauge, GaugeVec, HistogramVec, PrometheusError, Opts, register, U64}; use sync::{ChainSync, SyncState}; use crate::service::{TransactionPool, ExHashT}; -use crate::config::{BoxFinalityProofRequestBuilder, Roles}; +use crate::config::BoxFinalityProofRequestBuilder; use std::borrow::Cow; use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; use std::sync::Arc; @@ -338,7 +338,7 @@ impl Protocol { let important_peers = { let mut imp_p = HashSet::new(); - for reserved in &peerset_config.reserved_nodes { + for reserved in peerset_config.priority_groups.iter().flat_map(|(_, l)| l.iter()) { imp_p.insert(reserved.clone()); } imp_p.shrink_to_fit(); @@ -1033,13 +1033,14 @@ impl Protocol { /// Registers a new notifications protocol. /// - /// You are very strongly encouraged to call this method very early on. Any connection open - /// will retain the protocols that were registered then, and not any new one. - pub fn register_notifications_protocol( - &mut self, + /// While registering a protocol while we already have open connections is discouraged, we + /// nonetheless handle it by notifying that we opened channels with everyone. This function + /// returns a list of substreams to open as a result. + pub fn register_notifications_protocol<'a>( + &'a mut self, engine_id: ConsensusEngineId, protocol_name: impl Into>, - ) -> Vec { + ) -> impl ExactSizeIterator + 'a { let protocol_name = protocol_name.into(); if self.protocol_name_by_engine.insert(engine_id, protocol_name.clone()).is_some() { error!(target: "sub-libp2p", "Notifications protocol already registered: {:?}", protocol_name); @@ -1048,16 +1049,8 @@ impl Protocol { self.legacy_equiv_by_name.insert(protocol_name, Fallback::Consensus(engine_id)); } - // Registering a protocol while we already have open connections isn't great, but for now - // we handle it by notifying that we opened channels with everyone. self.context_data.peers.iter() - .map(|(peer_id, peer)| - event::Event::NotificationStreamOpened { - remote: peer_id.clone(), - engine_id, - roles: peer.info.roles, - }) - .collect() + .map(|(peer_id, peer)| (peer_id, peer.info.roles)) } /// Called when peer sends us new extrinsics @@ -2021,7 +2014,7 @@ impl Drop for Protocol { #[cfg(test)] mod tests { use crate::PeerId; - use crate::config::{EmptyTransactionPool, Roles}; + use crate::config::EmptyTransactionPool; use super::{CustomMessageOutcome, Protocol, ProtocolConfig}; use sp_consensus::block_validation::DefaultBlockAnnounceValidator; @@ -2034,10 +2027,7 @@ mod tests { let client = Arc::new(TestClientBuilder::with_default_backend().build_with_longest_chain().0); let (mut protocol, _) = Protocol::::new( - ProtocolConfig { - roles: Roles::FULL, - max_parallel_downloads: 10, - }, + ProtocolConfig::default(), client.clone(), Arc::new(EmptyTransactionPool), None, @@ -2048,7 +2038,7 @@ mod tests { out_peers: 10, bootnodes: Vec::new(), reserved_only: false, - reserved_nodes: Vec::new(), + priority_groups: Vec::new(), }, Box::new(DefaultBlockAnnounceValidator::new(client.clone())), None, diff --git a/client/network/src/protocol/event.rs b/client/network/src/protocol/event.rs index 78490863be..637bf805b5 100644 --- a/client/network/src/protocol/event.rs +++ b/client/network/src/protocol/event.rs @@ -17,7 +17,6 @@ //! Network event types. These are are not the part of the protocol, but rather //! events that happen on the network like DHT get/put results received. -use crate::config::Roles; use bytes::Bytes; use libp2p::core::PeerId; use libp2p::kad::record::Key; @@ -55,8 +54,8 @@ pub enum Event { remote: PeerId, /// The concerned protocol. Each protocol uses a different substream. engine_id: ConsensusEngineId, - /// Roles that the remote . - roles: Roles, + /// Role of the remote. + role: ObservedRole, }, /// Closed a substream with the given node. Always matches a corresponding previous @@ -76,3 +75,26 @@ pub enum Event { messages: Vec<(ConsensusEngineId, Bytes)>, }, } + +/// Role that the peer sent to us during the handshake, with the addition of what our local node +/// knows about that peer. +#[derive(Debug, Clone)] +pub enum ObservedRole { + /// Full node. + Full, + /// Light node. + Light, + /// When we are a validator node, this is a sentry that protects us. + OurSentry, + /// When we are a sentry node, this is the authority we are protecting. + OurGuardedAuthority, + /// Third-party authority. + Authority, +} + +impl ObservedRole { + /// Returns `true` for `ObservedRole::Light`. + pub fn is_light(&self) -> bool { + matches!(self, ObservedRole::Light) + } +} diff --git a/client/network/src/protocol/generic_proto/tests.rs b/client/network/src/protocol/generic_proto/tests.rs index c0582d5f5c..4548859ac4 100644 --- a/client/network/src/protocol/generic_proto/tests.rs +++ b/client/network/src/protocol/generic_proto/tests.rs @@ -78,7 +78,7 @@ fn build_nodes() -> (Swarm, Swarm) { vec![] }, reserved_only: false, - reserved_nodes: Vec::new(), + priority_groups: Vec::new(), }); let behaviour = CustomProtoWithAddr { diff --git a/client/network/src/protocol/light_client_handler.rs b/client/network/src/protocol/light_client_handler.rs index 3c39be124c..88a9519149 100644 --- a/client/network/src/protocol/light_client_handler.rs +++ b/client/network/src/protocol/light_client_handler.rs @@ -1423,7 +1423,7 @@ mod tests { out_peers: 128, bootnodes: Vec::new(), reserved_only: false, - reserved_nodes: Vec::new(), + priority_groups: Vec::new(), }; sc_peerset::Peerset::from_config(cfg) } diff --git a/client/network/src/protocol/message.rs b/client/network/src/protocol/message.rs index a12c26da2e..ae83b49e60 100644 --- a/client/network/src/protocol/message.rs +++ b/client/network/src/protocol/message.rs @@ -24,7 +24,7 @@ pub use self::generic::{ RemoteHeaderRequest, RemoteHeaderResponse, RemoteChangesRequest, RemoteChangesResponse, FinalityProofRequest, FinalityProofResponse, - FromBlock, RemoteReadChildRequest, + FromBlock, RemoteReadChildRequest, Roles, }; use sc_client_api::StorageProof; @@ -137,14 +137,71 @@ pub struct RemoteReadResponse { /// Generic types. pub mod generic { + use bitflags::bitflags; use codec::{Encode, Decode, Input, Output}; use sp_runtime::Justification; - use crate::config::Roles; use super::{ RemoteReadResponse, Transactions, Direction, RequestId, BlockAttributes, RemoteCallResponse, ConsensusEngineId, BlockState, StorageProof, }; + + bitflags! { + /// Bitmask of the roles that a node fulfills. + pub struct Roles: u8 { + /// No network. + const NONE = 0b00000000; + /// Full node, does not participate in consensus. + const FULL = 0b00000001; + /// Light client node. + const LIGHT = 0b00000010; + /// Act as an authority + const AUTHORITY = 0b00000100; + } + } + + impl Roles { + /// Does this role represents a client that holds full chain data locally? + pub fn is_full(&self) -> bool { + self.intersects(Roles::FULL | Roles::AUTHORITY) + } + + /// Does this role represents a client that does not participates in the consensus? + pub fn is_authority(&self) -> bool { + *self == Roles::AUTHORITY + } + + /// Does this role represents a client that does not hold full chain data locally? + pub fn is_light(&self) -> bool { + !self.is_full() + } + } + + impl<'a> From<&'a crate::config::Role> for Roles { + fn from(roles: &'a crate::config::Role) -> Self { + match roles { + crate::config::Role::Full => Roles::FULL, + crate::config::Role::Light => Roles::LIGHT, + crate::config::Role::Sentry { .. } => Roles::AUTHORITY, + crate::config::Role::Authority { .. } => Roles::AUTHORITY, + } + } + } + + impl codec::Encode for Roles { + fn encode_to(&self, dest: &mut T) { + dest.push_byte(self.bits()) + } + } + + impl codec::EncodeLike for Roles {} + + impl codec::Decode for Roles { + fn decode(input: &mut I) -> Result { + Self::from_bits(input.read_byte()?).ok_or_else(|| codec::Error::from("Invalid bytes")) + } + } + /// Consensus is mostly opaque to us #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub struct ConsensusMessage { diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index 4c0f930bb0..9feded784f 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -34,9 +34,9 @@ use sp_consensus::{BlockOrigin, BlockStatus, import_queue::{IncomingBlock, BlockImportResult, BlockImportError} }; use crate::{ - config::{Roles, BoxFinalityProofRequestBuilder}, + config::BoxFinalityProofRequestBuilder, protocol::message::{self, generic::FinalityProofRequest, BlockAnnounce, BlockAttributes, BlockRequest, BlockResponse, - FinalityProofResponse}, + FinalityProofResponse, Roles}, }; use either::Either; use extra_requests::ExtraRequests; diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 8d2f0e033f..9c286cd520 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -27,7 +27,7 @@ use crate::{ behaviour::{Behaviour, BehaviourOut}, - config::{parse_addr, parse_str_addr, NonReservedPeerMode, Params, TransportConfig}, + config::{parse_addr, parse_str_addr, NonReservedPeerMode, Params, Role, TransportConfig}, error::Error, network_state::{ NetworkState, NotConnectedPeer as NetworkStateNotConnectedPeer, Peer as NetworkStatePeer, @@ -181,19 +181,13 @@ impl NetworkWorker { // List of multiaddresses that we know in the network. let mut known_addresses = Vec::new(); let mut bootnodes = Vec::new(); - let mut reserved_nodes = Vec::new(); let mut boot_node_ids = HashSet::new(); // Process the bootnodes. for bootnode in params.network_config.boot_nodes.iter() { - match parse_str_addr(bootnode) { - Ok((peer_id, addr)) => { - bootnodes.push(peer_id.clone()); - boot_node_ids.insert(peer_id.clone()); - known_addresses.push((peer_id, addr)); - }, - Err(_) => warn!(target: "sub-libp2p", "Not a valid bootnode address: {}", bootnode), - } + bootnodes.push(bootnode.peer_id.clone()); + boot_node_ids.insert(bootnode.peer_id.clone()); + known_addresses.push((bootnode.peer_id.clone(), bootnode.multiaddr.clone())); } let boot_node_ids = Arc::new(boot_node_ids); @@ -215,22 +209,43 @@ impl NetworkWorker { } )?; - // Initialize the reserved peers. - for reserved in params.network_config.reserved_nodes.iter() { - if let Ok((peer_id, addr)) = parse_str_addr(reserved) { - reserved_nodes.push(peer_id.clone()); - known_addresses.push((peer_id, addr)); - } else { - warn!(target: "sub-libp2p", "Not a valid reserved node address: {}", reserved); + // Initialize the peers we should always be connected to. + let priority_groups = { + let mut reserved_nodes = HashSet::new(); + for reserved in params.network_config.reserved_nodes.iter() { + reserved_nodes.insert(reserved.peer_id.clone()); + known_addresses.push((reserved.peer_id.clone(), reserved.multiaddr.clone())); + } + + let mut sentries_and_validators = HashSet::new(); + match ¶ms.role { + Role::Sentry { validators } => { + for validator in validators { + sentries_and_validators.insert(validator.peer_id.clone()); + known_addresses.push((validator.peer_id.clone(), validator.multiaddr.clone())); + } + } + Role::Authority { sentry_nodes } => { + for sentry_node in sentry_nodes { + sentries_and_validators.insert(sentry_node.peer_id.clone()); + known_addresses.push((sentry_node.peer_id.clone(), sentry_node.multiaddr.clone())); + } + } + _ => {} } - } + + vec![ + ("reserved".to_owned(), reserved_nodes), + ("sentries_and_validators".to_owned(), sentries_and_validators), + ] + }; let peerset_config = sc_peerset::PeersetConfig { in_peers: params.network_config.in_peers, out_peers: params.network_config.out_peers, bootnodes, reserved_only: params.network_config.non_reserved_mode == NonReservedPeerMode::Deny, - reserved_nodes, + priority_groups, }; // Private and public keys configuration. @@ -253,7 +268,7 @@ impl NetworkWorker { let is_major_syncing = Arc::new(AtomicBool::new(false)); let (protocol, peerset_handle) = Protocol::new( protocol::ProtocolConfig { - roles: params.roles, + roles: From::from(¶ms.role), max_parallel_downloads: params.network_config.max_parallel_downloads, }, params.chain.clone(), @@ -285,6 +300,7 @@ impl NetworkWorker { }; let behaviour = futures::executor::block_on(Behaviour::new( protocol, + params.role, user_agent, local_public, known_addresses, @@ -971,11 +987,8 @@ impl Future for NetworkWorker { this.network_service.user_protocol_mut().write_notification(target, engine_id, message) }, ServiceToWorkerMsg::RegisterNotifProtocol { engine_id, protocol_name } => { - let events = this.network_service.user_protocol_mut() + this.network_service .register_notifications_protocol(engine_id, protocol_name); - for event in events { - this.event_streams.retain(|sender| sender.unbounded_send(event.clone()).is_ok()); - } }, ServiceToWorkerMsg::DisconnectPeer(who) => this.network_service.user_protocol_mut().disconnect_peer(&who), diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 8a4909277c..aa887bf5ca 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -32,7 +32,7 @@ use sp_blockchain::{ use sc_client_api::{BlockchainEvents, BlockImportNotification, FinalityNotifications, ImportNotifications, FinalityNotification, backend::{TransactionFor, AuxStore, Backend, Finalizer}, BlockBackend}; use sc_block_builder::{BlockBuilder, BlockBuilderProvider}; use sc_client::LongestChain; -use sc_network::config::Roles; +use sc_network::config::Role; use sp_consensus::block_validation::DefaultBlockAnnounceValidator; use sp_consensus::import_queue::{ BasicQueue, BoxJustificationImport, Verifier, BoxFinalityProofImport, @@ -557,17 +557,17 @@ pub trait TestNetFactory: Sized { for i in 0..n { trace!(target: "test_network", "Adding peer {}", i); - net.add_full_peer(&config); + net.add_full_peer(); } net } - fn add_full_peer(&mut self, config: &ProtocolConfig) { - self.add_full_peer_with_states(config, None) + fn add_full_peer(&mut self) { + self.add_full_peer_with_states(None) } /// Add a full peer. - fn add_full_peer_with_states(&mut self, config: &ProtocolConfig, keep_blocks: Option) { + fn add_full_peer_with_states(&mut self, keep_blocks: Option) { let test_client_builder = match keep_blocks { Some(keep_blocks) => TestClientBuilder::with_pruning_window(keep_blocks), None => TestClientBuilder::with_default_backend(), @@ -586,7 +586,7 @@ pub trait TestNetFactory: Sized { let verifier = self.make_verifier( PeersClient::Full(client.clone(), backend.clone()), - config, + &Default::default(), &data, ); let verifier = VerifierAdapter::new(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); @@ -601,7 +601,7 @@ pub trait TestNetFactory: Sized { let listen_addr = build_multiaddr![Memory(rand::random::())]; let network = NetworkWorker::new(sc_network::config::Params { - roles: config.roles, + role: Role::Full, executor: None, network_config: NetworkConfiguration { listen_addresses: vec![listen_addr.clone()], @@ -644,10 +644,7 @@ pub trait TestNetFactory: Sized { } /// Add a light peer. - fn add_light_peer(&mut self, config: &ProtocolConfig) { - let mut config = config.clone(); - config.roles = Roles::LIGHT; - + fn add_light_peer(&mut self) { let (c, backend) = substrate_test_runtime_client::new_light(); let client = Arc::new(c); let ( @@ -660,7 +657,7 @@ pub trait TestNetFactory: Sized { let verifier = self.make_verifier( PeersClient::Light(client.clone(), backend.clone()), - &config, + &Default::default(), &data, ); let verifier = VerifierAdapter::new(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); @@ -675,7 +672,7 @@ pub trait TestNetFactory: Sized { let listen_addr = build_multiaddr![Memory(rand::random::())]; let network = NetworkWorker::new(sc_network::config::Params { - roles: config.roles, + role: Role::Light, executor: None, network_config: NetworkConfiguration { listen_addresses: vec![listen_addr.clone()], diff --git a/client/network/test/src/sync.rs b/client/network/test/src/sync.rs index 785b71cb79..8acf265e91 100644 --- a/client/network/test/src/sync.rs +++ b/client/network/test/src/sync.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use sc_network::config::Roles; use sp_consensus::BlockOrigin; use std::time::Duration; use futures::executor::block_on; @@ -372,10 +371,8 @@ fn blocks_are_not_announced_by_light_nodes() { // full peer0 is connected to light peer // light peer1 is connected to full peer2 - let mut light_config = ProtocolConfig::default(); - light_config.roles = Roles::LIGHT; - net.add_full_peer(&ProtocolConfig::default()); - net.add_light_peer(&light_config); + net.add_full_peer(); + net.add_light_peer(); // Sync between 0 and 1. net.peer(0).push_blocks(1, false); @@ -384,7 +381,7 @@ fn blocks_are_not_announced_by_light_nodes() { assert_eq!(net.peer(1).client.info().best_number, 1); // Add another node and remove node 0. - net.add_full_peer(&ProtocolConfig::default()); + net.add_full_peer(); net.peers.remove(0); // Poll for a few seconds and make sure 1 and 2 (now 0 and 1) don't sync together. @@ -465,7 +462,7 @@ fn can_not_sync_from_light_peer() { // given the network with 1 full nodes (#0) and 1 light node (#1) let mut net = TestNet::new(1); - net.add_light_peer(&Default::default()); + net.add_light_peer(); // generate some blocks on #0 net.peer(0).push_blocks(1, false); @@ -481,7 +478,7 @@ fn can_not_sync_from_light_peer() { assert_eq!(light_info.best_hash, full0_info.best_hash); // add new full client (#2) && remove #0 - net.add_full_peer(&Default::default()); + net.add_full_peer(); net.peers.remove(0); // ensure that the #2 (now #1) fails to sync block #1 even after 5 seconds @@ -511,7 +508,7 @@ fn light_peer_imports_header_from_announce() { // given the network with 1 full nodes (#0) and 1 light node (#1) let mut net = TestNet::new(1); - net.add_light_peer(&Default::default()); + net.add_light_peer(); // let them connect to each other net.block_until_sync(); @@ -583,9 +580,8 @@ fn can_sync_explicit_forks() { fn syncs_header_only_forks() { let _ = ::env_logger::try_init(); let mut net = TestNet::new(0); - let config = ProtocolConfig::default(); - net.add_full_peer_with_states(&config, None); - net.add_full_peer_with_states(&config, Some(3)); + net.add_full_peer_with_states(None); + net.add_full_peer_with_states(Some(3)); net.peer(0).push_blocks(2, false); net.peer(1).push_blocks(2, false); diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index 87ed2336ae..476780024b 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -163,14 +163,14 @@ pub struct PeersetConfig { /// > otherwise it will not be able to connect to them. pub bootnodes: Vec, - /// If true, we only accept reserved nodes. + /// If true, we only accept nodes in [`PeersetConfig::priority_groups`]. pub reserved_only: bool, - /// List of nodes that we should always be connected to. + /// Lists of nodes we should always be connected to. /// /// > **Note**: Keep in mind that the networking has to know an address for these nodes, /// > otherwise it will not be able to connect to them. - pub reserved_nodes: Vec, + pub priority_groups: Vec<(String, HashSet)>, } /// Side of the peer set manager owned by the network. In other words, the "receiving" side. @@ -215,7 +215,10 @@ impl Peerset { latest_time_update: now, }; - peerset.data.set_priority_group(RESERVED_NODES, config.reserved_nodes.into_iter().collect()); + for (group, nodes) in config.priority_groups { + peerset.data.set_priority_group(&group, nodes); + } + for peer_id in config.bootnodes { if let peersstate::Peer::Unknown(entry) = peerset.data.peer(&peer_id) { entry.discover(); @@ -597,7 +600,7 @@ mod tests { out_peers: 2, bootnodes: vec![bootnode], reserved_only: true, - reserved_nodes: Vec::new(), + priority_groups: Vec::new(), }; let (peerset, handle) = Peerset::from_config(config); @@ -625,7 +628,7 @@ mod tests { out_peers: 1, bootnodes: vec![bootnode.clone()], reserved_only: false, - reserved_nodes: Vec::new(), + priority_groups: Vec::new(), }; let (mut peerset, _handle) = Peerset::from_config(config); @@ -652,7 +655,7 @@ mod tests { out_peers: 2, bootnodes: vec![bootnode.clone()], reserved_only: false, - reserved_nodes: vec![], + priority_groups: vec![], }; let (mut peerset, _handle) = Peerset::from_config(config); @@ -673,7 +676,7 @@ mod tests { out_peers: 25, bootnodes: vec![], reserved_only: false, - reserved_nodes: vec![], + priority_groups: vec![], }); // We ban a node by setting its reputation under the threshold. diff --git a/client/peerset/tests/fuzz.rs b/client/peerset/tests/fuzz.rs index c2b0b44a3a..44477cec65 100644 --- a/client/peerset/tests/fuzz.rs +++ b/client/peerset/tests/fuzz.rs @@ -43,12 +43,15 @@ fn test_once() { known_nodes.insert(id.clone()); id }).collect(), - reserved_nodes: (0 .. Uniform::new_inclusive(0, 2).sample(&mut rng)).map(|_| { - let id = PeerId::random(); - known_nodes.insert(id.clone()); - reserved_nodes.insert(id.clone()); - id - }).collect(), + priority_groups: { + let list = (0 .. Uniform::new_inclusive(0, 2).sample(&mut rng)).map(|_| { + let id = PeerId::random(); + known_nodes.insert(id.clone()); + reserved_nodes.insert(id.clone()); + id + }).collect(); + vec![("reserved".to_owned(), list)] + }, reserved_only: Uniform::new_inclusive(0, 10).sample(&mut rng) == 0, in_peers: Uniform::new_inclusive(0, 25).sample(&mut rng), out_peers: Uniform::new_inclusive(0, 25).sample(&mut rng), diff --git a/client/rpc-api/src/system/helpers.rs b/client/rpc-api/src/system/helpers.rs index 572136aeb6..80718cf487 100644 --- a/client/rpc-api/src/system/helpers.rs +++ b/client/rpc-api/src/system/helpers.rs @@ -83,8 +83,8 @@ pub enum NodeRole { LightClient, /// The node is an authority Authority, - /// An unknown role with a bit number - UnknownRole(u8) + /// The node is a sentry + Sentry, } #[cfg(test)] diff --git a/client/rpc/src/system/tests.rs b/client/rpc/src/system/tests.rs index 4487566e44..d45894743c 100644 --- a/client/rpc/src/system/tests.rs +++ b/client/rpc/src/system/tests.rs @@ -17,7 +17,7 @@ use super::*; use sc_network::{self, PeerId}; -use sc_network::config::Roles; +use sc_network::config::Role; use substrate_test_runtime_client::runtime::Block; use assert_matches::assert_matches; use futures::{prelude::*, channel::mpsc}; @@ -60,7 +60,7 @@ fn api>>(sync: T) -> System { for _peer in 0..status.peers { peers.push(PeerInfo { peer_id: status.peer_id.to_base58(), - roles: format!("{:?}", Roles::FULL), + roles: format!("{}", Role::Full), protocol_version: 1, best_hash: Default::default(), best_number: 1, diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 6f8610a612..b9c98dbf2e 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -35,7 +35,7 @@ use futures::{ }; use sc_keystore::{Store as Keystore}; use log::{info, warn, error}; -use sc_network::config::{FinalityProofProvider, OnDemand, BoxFinalityProofRequestBuilder}; +use sc_network::config::{Role, FinalityProofProvider, OnDemand, BoxFinalityProofRequestBuilder}; use sc_network::{NetworkService, NetworkStateInfo}; use parking_lot::{Mutex, RwLock}; use sp_runtime::generic::BlockId; @@ -840,7 +840,7 @@ ServiceBuilder< .register_transaction_pool(Arc::downgrade(&transaction_pool) as _); let transaction_pool_adapter = Arc::new(TransactionPoolAdapter { - imports_external_transactions: !config.roles.is_light(), + imports_external_transactions: !matches!(config.role, Role::Light), pool: transaction_pool.clone(), client: client.clone(), executor: tasks_builder.spawn_handle(), @@ -863,7 +863,7 @@ ServiceBuilder< Box::new(sp_consensus::block_validation::DefaultBlockAnnounceValidator::new(client.clone())); let network_params = sc_network::config::Params { - roles: config.roles, + role: config.role.clone(), executor: { let spawn_handle = tasks_builder.spawn_handle(); Some(Box::new(move |fut| { @@ -913,7 +913,7 @@ ServiceBuilder< let offchain = offchain_workers.as_ref().map(Arc::downgrade); let notifications_spawn_handle = tasks_builder.spawn_handle(); let network_state_info: Arc = network.clone(); - let is_validator = config.roles.is_authority(); + let is_validator = config.role.is_authority(); let (import_stream, finality_stream) = ( client.import_notification_stream().map(|n| ChainEvent::NewBlock { @@ -1003,9 +1003,16 @@ ServiceBuilder< .const_label("version", config.impl_version) .const_label("commit", config.impl_commit), )?, ®istry)?.set(1); + + let role_bits = match config.role { + Role::Full => 1, + Role::Light => 2, + Role::Sentry { .. } => 3, + Role::Authority { .. } => 4, + }; register(Gauge::::new( - "node_roles", "The roles the node is running as", - )?, ®istry)?.set(u64::from(config.roles.bits())); + "node_role", "The role the node is running as", + )?, ®istry)?.set(role_bits); let metrics = ServiceMetrics::register(®istry)?; @@ -1198,7 +1205,7 @@ ServiceBuilder< spawn_handle.spawn( "network-worker", build_network_future( - config.roles, + config.role.clone(), network_mut, client.clone(), network_status_sinks.clone(), @@ -1212,7 +1219,7 @@ ServiceBuilder< // Telemetry let telemetry = config.telemetry_endpoints.clone().map(|endpoints| { - let is_authority = config.roles.is_authority(); + let is_authority = config.role.is_authority(); let network_id = network.local_peer_id().to_base58(); let name = config.name.clone(); let impl_name = config.impl_name.to_owned(); diff --git a/client/service/src/config.rs b/client/service/src/config.rs index 7eb1d501ce..109ff1bfd5 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -18,7 +18,7 @@ pub use sc_client::ExecutionStrategies; pub use sc_client_db::{kvdb::KeyValueDB, PruningMode}; -pub use sc_network::config::{ExtTransport, NetworkConfiguration, Roles}; +pub use sc_network::{Multiaddr, config::{MultiaddrWithPeerId, ExtTransport, NetworkConfiguration, Role}}; pub use sc_executor::WasmExecutionMethod; use std::{future::Future, path::{PathBuf, Path}, pin::Pin, net::SocketAddr, sync::Arc}; @@ -58,8 +58,8 @@ pub struct Configuration { pub impl_version: &'static str, /// Git commit if any. pub impl_commit: &'static str, - /// Node roles. - pub roles: Roles, + /// Node role. + pub role: Role, /// How to spawn background tasks. Mandatory, otherwise creating a `Service` will error. pub task_executor: Option + Send>>) + Send + Sync>>, /// Extrinsic pool configuration. @@ -105,10 +105,6 @@ pub struct Configuration { pub default_heap_pages: Option, /// Should offchain workers be executed. pub offchain_worker: bool, - /// Sentry mode is enabled, the node's role is AUTHORITY but it should not - /// actively participate in consensus (i.e. no keystores should be passed to - /// consensus modules). - pub sentry_mode: bool, /// Enable authoring even when offline. pub force_authoring: bool, /// Disable GRANDPA when running in validator mode @@ -204,7 +200,7 @@ impl Default for Configuration { chain_spec: None, config_dir: None, name: Default::default(), - roles: Roles::FULL, + role: Role::Full, task_executor: None, transaction_pool: Default::default(), network: Default::default(), @@ -224,7 +220,6 @@ impl Default for Configuration { telemetry_external_transport: None, default_heap_pages: None, offchain_worker: Default::default(), - sentry_mode: false, force_authoring: false, disable_grandpa: false, dev_key_seed: None, @@ -286,15 +281,9 @@ impl Configuration { self.database.as_ref().expect("database must be specified") } - /// Returns a string displaying the node role, special casing the sentry mode - /// (returning `SENTRY`), since the node technically has an `AUTHORITY` role but - /// doesn't participate. + /// Returns a string displaying the node role. pub fn display_role(&self) -> String { - if self.sentry_mode { - "SENTRY".to_string() - } else { - self.roles.to_string() - } + self.role.to_string() } /// Use in memory keystore config when it is not required at all. diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 137442f7e0..9c680bbbc9 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -58,7 +58,7 @@ pub use self::builder::{ ServiceBuilder, ServiceBuilderCommand, TFullClient, TLightClient, TFullBackend, TLightBackend, TFullCallExecutor, TLightCallExecutor, }; -pub use config::{Configuration, Roles, PruningMode, DatabaseConfig}; +pub use config::{Configuration, Role, PruningMode, DatabaseConfig}; pub use sc_chain_spec::{ ChainSpec, GenericChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension }; @@ -322,7 +322,7 @@ fn build_network_future< C: sc_client::BlockchainEvents, H: sc_network::ExHashT > ( - roles: Roles, + role: Role, mut network: sc_network::NetworkWorker, client: Arc, status_sinks: Arc, NetworkState)>>>, @@ -399,17 +399,14 @@ fn build_network_future< sc_rpc::system::Request::NodeRoles(sender) => { use sc_rpc::system::NodeRole; - let node_roles = (0 .. 8) - .filter(|&bit_number| (roles.bits() >> bit_number) & 1 == 1) - .map(|bit_number| match Roles::from_bits(1 << bit_number) { - Some(Roles::AUTHORITY) => NodeRole::Authority, - Some(Roles::LIGHT) => NodeRole::LightClient, - Some(Roles::FULL) => NodeRole::Full, - _ => NodeRole::UnknownRole(bit_number), - }) - .collect(); - - let _ = sender.send(node_roles); + let node_role = match role { + Role::Authority { .. } => NodeRole::Authority, + Role::Light => NodeRole::LightClient, + Role::Full => NodeRole::Full, + Role::Sentry { .. } => NodeRole::Sentry, + }; + + let _ = sender.send(vec![node_role]); } }; } diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 57aed116ef..d63fd4009e 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -34,7 +34,7 @@ use sc_service::{ Configuration, config::{DatabaseConfig, KeystoreConfig}, RuntimeGenesis, - Roles, + Role, Error, }; use sc_network::{multiaddr, Multiaddr, NetworkStateInfo}; @@ -134,7 +134,7 @@ where F: Send + 'static, L: Send +'static, U: Clone + Send + 'static fn node_config ( index: usize, spec: &GenericChainSpec, - role: Roles, + role: Role, task_executor: Arc + Send>>) + Send + Sync>, key_seed: Option, base_port: u16, @@ -161,7 +161,6 @@ fn node_config TestNet where let node_config = node_config( self.nodes, &self.chain_spec, - Roles::AUTHORITY, + Role::Authority { sentry_nodes: Vec::new() }, task_executor, Some(key), self.base_port, @@ -288,7 +286,7 @@ impl TestNet where let executor = executor.clone(); Arc::new(move |fut: Pin + Send>>| executor.spawn(fut.unit_error().compat())) }; - let node_config = node_config(self.nodes, &self.chain_spec, Roles::FULL, task_executor, None, self.base_port, &temp); + let node_config = node_config(self.nodes, &self.chain_spec, Role::Full, task_executor, None, self.base_port, &temp); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); let (service, user_data) = full(node_config).expect("Error creating test node service"); let service = SyncService::from(service); @@ -304,7 +302,7 @@ impl TestNet where let executor = executor.clone(); Arc::new(move |fut: Pin + Send>>| executor.spawn(fut.unit_error().compat())) }; - let node_config = node_config(self.nodes, &self.chain_spec, Roles::LIGHT, task_executor, None, self.base_port, &temp); + let node_config = node_config(self.nodes, &self.chain_spec, Role::Light, task_executor, None, self.base_port, &temp); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); let service = SyncService::from(light(node_config).expect("Error creating test node service")); diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index 3a0162bd90..80dfa5e2d2 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -18,7 +18,7 @@ use futures01::sync::mpsc as mpsc01; use log::{debug, info}; use std::sync::Arc; use sc_service::{ - AbstractService, RpcSession, Roles, Configuration, config::{DatabaseConfig, KeystoreConfig}, + AbstractService, RpcSession, Role, Configuration, config::{DatabaseConfig, KeystoreConfig}, GenericChainSpec, RuntimeGenesis }; use wasm_bindgen::prelude::*; @@ -57,7 +57,7 @@ where wasm_bindgen_futures::spawn_local(fut) })); config.telemetry_external_transport = Some(transport); - config.roles = Roles::LIGHT; + config.role = Role::Light; config.name = format!("{} (Browser)", name); config.database = Some({ info!("Opening Indexed DB database '{}'...", name); -- GitLab From 0c7f8b22029941d5d7304719de4d308d2fba8025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Sat, 4 Apr 2020 08:59:15 +0100 Subject: [PATCH 159/300] support: add lateness trait (#5519) * support: add lateness trait * babe: implement the lateness trait * babe: add docs about lateness entry lifetime * babe: don't use option for lateness storage entry --- frame/babe/src/lib.rs | 26 +++++++++++++++++++++++++- frame/support/src/traits.rs | 17 ++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 32d5d3c7a5..5f85b91088 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -152,6 +152,13 @@ decl_storage! { /// Temporary value (cleared at block finalization) which is `Some` /// if per-block initialization has already been called for current block. Initialized get(fn initialized): Option; + + /// How late the current block is compared to its parent. + /// + /// This entry is populated as part of block execution and is cleaned up + /// on block finalization. Querying this storage entry outside of block + /// execution context should always yield zero. + Lateness get(fn lateness): T::BlockNumber; } add_extra_genesis { config(authorities): Vec<(AuthorityId, BabeAuthorityWeight)>; @@ -190,6 +197,9 @@ decl_module! { if let Some(Some(vrf_output)) = Initialized::take() { Self::deposit_vrf_output(&vrf_output); } + + // remove temporary "environment" entry from storage + Lateness::::kill(); } } } @@ -443,7 +453,15 @@ impl Module { Self::deposit_consensus(ConsensusLog::NextEpochData(next)) } - CurrentSlot::put(digest.slot_number()); + // the slot number of the current block being initialized + let current_slot = digest.slot_number(); + + // how many slots were skipped between current and last block + let lateness = current_slot.saturating_sub(CurrentSlot::get() + 1); + let lateness = T::BlockNumber::from(lateness as u32); + + Lateness::::put(lateness); + CurrentSlot::put(current_slot); if let RawPreDigest::Primary(primary) = digest { // place the VRF output into the `Initialized` storage item @@ -498,6 +516,12 @@ impl frame_support::traits::EstimateNextSessionRotation frame_support::traits::Lateness for Module { + fn lateness(&self) -> T::BlockNumber { + Self::lateness() + } +} + impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = AuthorityId; } diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index f19d3995ea..bb446ab692 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -24,7 +24,7 @@ use sp_core::u32_trait::Value as U32; use sp_runtime::{ RuntimeDebug, ConsensusEngineId, DispatchResult, DispatchError, - traits::{MaybeSerializeDeserialize, AtLeast32Bit, Saturating, TrailingZeroInput, Bounded}, + traits::{MaybeSerializeDeserialize, AtLeast32Bit, Saturating, TrailingZeroInput, Bounded, Zero}, }; use crate::dispatch::Parameter; use crate::storage::StorageMap; @@ -1032,6 +1032,21 @@ impl Randomness for () { } } +/// Trait to be used by block producing consensus engine modules to determine +/// how late the current block is (e.g. in a slot-based proposal mechanism how +/// many slots were skipped since the previous block). +pub trait Lateness { + /// Returns a generic measure of how late the current block is compared to + /// its parent. + fn lateness(&self) -> N; +} + +impl Lateness for () { + fn lateness(&self) -> N { + Zero::zero() + } +} + /// Implementors of this trait provide information about whether or not some validator has /// been registered with them. The [Session module](../../pallet_session/index.html) is an implementor. pub trait ValidatorRegistration { -- GitLab From bbf4df60c0af9f106c3cfa994f7442bfd62bac0b Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sat, 4 Apr 2020 12:58:05 +0200 Subject: [PATCH 160/300] EnsureOrigin is a frame abstraction - it should be in frame_support (#5521) * EnsureOrigin is a frame abstraction - it should be in frame_support * Fixes --- frame/collective/src/lib.rs | 4 ++-- frame/democracy/src/benchmarking.rs | 4 ++-- frame/democracy/src/lib.rs | 4 ++-- frame/identity/src/lib.rs | 4 ++-- frame/membership/src/lib.rs | 3 +-- frame/nicks/src/lib.rs | 4 ++-- frame/scored-pool/src/lib.rs | 4 ++-- frame/society/src/lib.rs | 4 ++-- frame/staking/src/lib.rs | 4 ++-- frame/support/src/traits.rs | 25 ++++++++++++++++++++++--- frame/system/src/lib.rs | 4 ++-- frame/timestamp/src/lib.rs | 4 +++- frame/treasury/src/lib.rs | 5 +++-- primitives/runtime/src/traits.rs | 20 +------------------- 14 files changed, 48 insertions(+), 45 deletions(-) diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index d06d83b5be..49c1bd3891 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -39,11 +39,11 @@ use sp_std::{prelude::*, result}; use sp_core::u32_trait::Value as U32; use sp_runtime::RuntimeDebug; -use sp_runtime::traits::{Hash, EnsureOrigin}; +use sp_runtime::traits::Hash; use frame_support::weights::SimpleDispatchInfo; use frame_support::{ dispatch::{Dispatchable, Parameter}, codec::{Encode, Decode}, - traits::{Get, ChangeMembers, InitializeMembers}, decl_module, decl_event, + traits::{Get, ChangeMembers, InitializeMembers, EnsureOrigin}, decl_module, decl_event, decl_storage, decl_error, ensure, }; use frame_system::{self as system, ensure_signed, ensure_root}; diff --git a/frame/democracy/src/benchmarking.rs b/frame/democracy/src/benchmarking.rs index a483269c43..1df205a4f5 100644 --- a/frame/democracy/src/benchmarking.rs +++ b/frame/democracy/src/benchmarking.rs @@ -19,9 +19,9 @@ use super::*; use frame_benchmarking::{benchmarks, account}; -use frame_support::traits::{Currency, Get}; +use frame_support::traits::{Currency, Get, EnsureOrigin}; use frame_system::{RawOrigin, Module as System, self}; -use sp_runtime::traits::{Bounded, EnsureOrigin, One}; +use sp_runtime::traits::{Bounded, One}; use crate::Module as Democracy; diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index 5f50ee04da..b09f305c64 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -166,7 +166,7 @@ use sp_std::prelude::*; use sp_runtime::{ DispatchResult, DispatchError, RuntimeDebug, - traits::{Zero, EnsureOrigin, Hash, Dispatchable, Saturating}, + traits::{Zero, Hash, Dispatchable, Saturating}, }; use codec::{Ref, Encode, Decode}; use frame_support::{ @@ -174,7 +174,7 @@ use frame_support::{ weights::{SimpleDispatchInfo, Weight, WeighData}, traits::{ Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, - OnUnbalanced, BalanceStatus, schedule::Named as ScheduleNamed + OnUnbalanced, BalanceStatus, schedule::Named as ScheduleNamed, EnsureOrigin } }; use frame_system::{self as system, ensure_signed, ensure_root}; diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index e5b1fe68bb..e18689001b 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -70,10 +70,10 @@ use sp_std::{fmt::Debug, ops::Add, iter::once}; use enumflags2::BitFlags; use codec::{Encode, Decode}; use sp_runtime::{DispatchResult, RuntimeDebug}; -use sp_runtime::traits::{StaticLookup, EnsureOrigin, Zero, AppendZerosInput}; +use sp_runtime::traits::{StaticLookup, Zero, AppendZerosInput}; use frame_support::{ decl_module, decl_event, decl_storage, ensure, decl_error, - traits::{Currency, ReservableCurrency, OnUnbalanced, Get, BalanceStatus}, + traits::{Currency, ReservableCurrency, OnUnbalanced, Get, BalanceStatus, EnsureOrigin}, weights::SimpleDispatchInfo, }; use frame_system::{self as system, ensure_signed, ensure_root}; diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index 129f3c4003..8f086fa2f3 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -25,11 +25,10 @@ use sp_std::prelude::*; use frame_support::{ decl_module, decl_storage, decl_event, decl_error, - traits::{ChangeMembers, InitializeMembers}, + traits::{ChangeMembers, InitializeMembers, EnsureOrigin}, weights::SimpleDispatchInfo, }; use frame_system::{self as system, ensure_root, ensure_signed}; -use sp_runtime::traits::EnsureOrigin; pub trait Trait: frame_system::Trait { /// The overarching event type. diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 125d1fd198..ae005e2500 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -40,11 +40,11 @@ use sp_std::prelude::*; use sp_runtime::{ - traits::{StaticLookup, EnsureOrigin, Zero} + traits::{StaticLookup, Zero} }; use frame_support::{ decl_module, decl_event, decl_storage, ensure, decl_error, - traits::{Currency, ReservableCurrency, OnUnbalanced, Get}, + traits::{Currency, EnsureOrigin, ReservableCurrency, OnUnbalanced, Get}, weights::SimpleDispatchInfo, }; use frame_system::{self as system, ensure_signed, ensure_root}; diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index 2c2bfc6a12..d162f42c3f 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -96,12 +96,12 @@ use sp_std::{ }; use frame_support::{ decl_module, decl_storage, decl_event, ensure, decl_error, - traits::{ChangeMembers, InitializeMembers, Currency, Get, ReservableCurrency}, + traits::{EnsureOrigin, ChangeMembers, InitializeMembers, Currency, Get, ReservableCurrency}, weights::{Weight, SimpleDispatchInfo, WeighData}, }; use frame_system::{self as system, ensure_root, ensure_signed}; use sp_runtime::{ - traits::{EnsureOrigin, AtLeast32Bit, MaybeSerializeDeserialize, Zero, StaticLookup}, + traits::{AtLeast32Bit, MaybeSerializeDeserialize, Zero, StaticLookup}, }; type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index 49f48697f9..2061c21d9c 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -256,14 +256,14 @@ use codec::{Encode, Decode}; use sp_runtime::{Percent, ModuleId, RuntimeDebug, traits::{ StaticLookup, AccountIdConversion, Saturating, Zero, IntegerSquareRoot, Hash, - TrailingZeroInput, CheckedSub, EnsureOrigin + TrailingZeroInput, CheckedSub } }; use frame_support::{decl_error, decl_module, decl_storage, decl_event, ensure, dispatch::DispatchResult}; use frame_support::weights::{SimpleDispatchInfo, Weight, WeighData}; use frame_support::traits::{ Currency, ReservableCurrency, Randomness, Get, ChangeMembers, BalanceStatus, - ExistenceRequirement::AllowDeath + ExistenceRequirement::AllowDeath, EnsureOrigin }; use frame_system::{self as system, ensure_signed, ensure_root}; diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index b19caec258..b6b1bb32de 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -278,7 +278,7 @@ use frame_support::{ dispatch::{IsSubType, DispatchResult}, traits::{ Currency, LockIdentifier, LockableCurrency, WithdrawReasons, OnUnbalanced, Imbalance, Get, - UnixTime, EstimateNextNewSession, + UnixTime, EstimateNextNewSession, EnsureOrigin, } }; use pallet_session::historical; @@ -287,7 +287,7 @@ use sp_runtime::{ curve::PiecewiseLinear, traits::{ Convert, Zero, StaticLookup, CheckedSub, Saturating, SaturatedConversion, AtLeast32Bit, - EnsureOrigin, SignedExtension, + SignedExtension, }, transaction_validity::{ TransactionValidityError, TransactionValidity, ValidTransaction, InvalidTransaction, diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index bb446ab692..7e2040ee23 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -22,9 +22,10 @@ use sp_std::{prelude::*, result, marker::PhantomData, ops::Div, fmt::Debug}; use codec::{FullCodec, Codec, Encode, Decode, EncodeLike}; use sp_core::u32_trait::Value as U32; use sp_runtime::{ - RuntimeDebug, - ConsensusEngineId, DispatchResult, DispatchError, - traits::{MaybeSerializeDeserialize, AtLeast32Bit, Saturating, TrailingZeroInput, Bounded, Zero}, + RuntimeDebug, ConsensusEngineId, DispatchResult, DispatchError, traits::{ + MaybeSerializeDeserialize, AtLeast32Bit, Saturating, TrailingZeroInput, Bounded, Zero, + BadOrigin + }, }; use crate::dispatch::Parameter; use crate::storage::StorageMap; @@ -1237,6 +1238,24 @@ pub mod schedule { } } +/// Some sort of check on the origin is performed by this object. +pub trait EnsureOrigin { + /// A return type. + type Success; + /// Perform the origin check. + fn ensure_origin(o: OuterOrigin) -> result::Result { + Self::try_origin(o).map_err(|_| BadOrigin) + } + /// Perform the origin check. + fn try_origin(o: OuterOrigin) -> result::Result; + + /// Returns an outer origin capable of passing `try_origin` check. + /// + /// ** Should be used for benchmarking only!!! ** + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> OuterOrigin; +} + #[cfg(test)] mod tests { use super::*; diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 2d965b44f0..7823916347 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -107,7 +107,7 @@ use sp_runtime::{ }, traits::{ self, CheckEqual, AtLeast32Bit, Zero, SignedExtension, Lookup, LookupError, - SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, BadOrigin, SaturatedConversion, + SimpleBitOps, Hash, Member, MaybeDisplay, BadOrigin, SaturatedConversion, MaybeSerialize, MaybeSerializeDeserialize, MaybeMallocSizeOf, StaticLookup, One, Bounded, }, }; @@ -117,7 +117,7 @@ use frame_support::{ decl_module, decl_event, decl_storage, decl_error, storage, Parameter, ensure, debug, traits::{ Contains, Get, ModuleToIndex, OnNewAccount, OnKilledAccount, IsDeadAccount, Happened, - StoredMap, + StoredMap, EnsureOrigin, }, weights::{Weight, DispatchInfo, DispatchClass, SimpleDispatchInfo, FunctionOf}, }; diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 5d5180314e..54b4eeca6b 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -95,8 +95,10 @@ mod benchmarking; use sp_std::{result, cmp}; use sp_inherents::{ProvideInherent, InherentData, InherentIdentifier}; +#[cfg(feature = "std")] +use frame_support::debug; use frame_support::{ - Parameter, decl_storage, decl_module, debug, + Parameter, decl_storage, decl_module, traits::{Time, UnixTime, Get}, weights::SimpleDispatchInfo, }; diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 27e0e852d6..f07b9b511e 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -96,9 +96,10 @@ use frame_support::traits::{ ReservableCurrency, WithdrawReason }; use sp_runtime::{Permill, ModuleId, Percent, RuntimeDebug, traits::{ - Zero, EnsureOrigin, StaticLookup, AccountIdConversion, Saturating, Hash, BadOrigin + Zero, StaticLookup, AccountIdConversion, Saturating, Hash, BadOrigin }}; -use frame_support::{weights::{Weight, WeighData, SimpleDispatchInfo}, traits::Contains}; +use frame_support::weights::{Weight, WeighData, SimpleDispatchInfo}; +use frame_support::traits::{Contains, EnsureOrigin}; use codec::{Encode, Decode}; use frame_system::{self as system, ensure_signed, ensure_root}; diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index b5e37944c9..8bbaa50266 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -17,7 +17,7 @@ //! Primitives for the runtime modules. use sp_std::prelude::*; -use sp_std::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}, fmt::Debug}; +use sp_std::{self, marker::PhantomData, convert::{TryFrom, TryInto}, fmt::Debug}; use sp_io; #[cfg(feature = "std")] use std::fmt::Display; @@ -147,24 +147,6 @@ impl From for &'static str { } } -/// Some sort of check on the origin is performed by this object. -pub trait EnsureOrigin { - /// A return type. - type Success; - /// Perform the origin check. - fn ensure_origin(o: OuterOrigin) -> result::Result { - Self::try_origin(o).map_err(|_| BadOrigin) - } - /// Perform the origin check. - fn try_origin(o: OuterOrigin) -> result::Result; - - /// Returns an outer origin capable of passing `try_origin` check. - /// - /// ** Should be used for benchmarking only!!! ** - #[cfg(feature = "runtime-benchmarks")] - fn successful_origin() -> OuterOrigin; -} - /// An error that indicates that a lookup failed. #[derive(Encode, Decode, RuntimeDebug)] pub struct LookupError; -- GitLab From e33dae6488c0d0d334f84e99cc0bfc7a42c8d68d Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sat, 4 Apr 2020 14:50:08 +0200 Subject: [PATCH 161/300] Simple Staking Payouts (#5406) * Simple Payouts * explicit test for out of order claiming * Add `payout_all` benchmark * Fix merge * add docs * change event to controller * Fix timestamp test warnings * Revert "change event to controller" This reverts commit 5d4a97832d47fe1273602d5410774d5421940c4e. * Update Reward event doc * Add "non-production" test * add unlock chunk to test * fix merge * End payout early if no reward points * payout_validator -> payout_stakers * bring back payout nominator/validator, but limit their use to before migration era * Add test for before migration * New payout works for the era that we migrate * Fix logic, check that migration era works * Migrate Era tests (copypasta) * Move comment * Add mock back to external functions * Fixes based on review from gui * Update Cargo.lock * Update Cargo.lock * small docs update Co-authored-by: joepetrowski --- Cargo.lock | 1 + frame/staking/Cargo.toml | 1 + frame/staking/src/benchmarking.rs | 145 ++--- frame/staking/src/lib.rs | 248 ++++++++- frame/staking/src/mock.rs | 26 +- frame/staking/src/tests.rs | 867 +++++++++++++++++++++++++----- 6 files changed, 1034 insertions(+), 254 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b7e9322937..eedb622227 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4437,6 +4437,7 @@ dependencies = [ "sp-runtime", "sp-staking", "sp-std", + "sp-storage", "static_assertions", "substrate-test-utils", ] diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index 228b7b60f8..aac5616e4e 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -34,6 +34,7 @@ rand_chacha = { version = "0.2", default-features = false, optional = true } [dev-dependencies] sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } +sp-storage = { version = "2.0.0-alpha.5", path = "../../primitives/storage" } pallet-balances = { version = "2.0.0-alpha.5", path = "../balances" } pallet-timestamp = { version = "2.0.0-alpha.5", path = "../timestamp" } pallet-staking-reward-curve = { version = "2.0.0-alpha.5", path = "../staking/reward-curve" } diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index 9a1f6a215c..d4edac63d2 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -20,7 +20,7 @@ use super::*; use rand_chacha::{rand_core::{RngCore, SeedableRng}, ChaChaRng}; -use sp_runtime::traits::One; +use sp_runtime::traits::{Dispatchable, One}; use sp_io::hashing::blake2_256; use frame_system::RawOrigin; @@ -147,61 +147,6 @@ pub fn create_validator_with_nominators(n: u32, upper_bound: u32) -> R Ok(v_controller) } -// This function generates one nominator nominating v validators. -// It starts an era and creates pending payouts. -pub fn create_nominator_with_validators(v: u32) -> Result<(T::AccountId, Vec), &'static str> { - let mut validators = Vec::new(); - let mut points_total = 0; - let mut points_individual = Vec::new(); - - MinimumValidatorCount::put(0); - - // Create v validators - let mut validator_lookups = Vec::new(); - for i in 0 .. v { - let (v_stash, v_controller) = create_stash_controller::(i)?; - let validator_prefs = ValidatorPrefs { - commission: Perbill::from_percent(50), - }; - Staking::::validate(RawOrigin::Signed(v_controller.clone()).into(), validator_prefs)?; - let stash_lookup: ::Source = T::Lookup::unlookup(v_stash.clone()); - - points_total += 10; - points_individual.push((v_stash.clone(), 10)); - validator_lookups.push(stash_lookup); - // Add to the list if it is less than the number we want the nominator to have - if validators.len() < v as usize { - validators.push(v_stash.clone()) - } - } - - // Create a nominator - let (_n_stash, n_controller) = create_stash_controller::(u32::max_value())?; - Staking::::nominate(RawOrigin::Signed(n_controller.clone()).into(), validator_lookups)?; - - ValidatorCount::put(v); - - // Start a new Era - let new_validators = Staking::::new_era(SessionIndex::one()).unwrap(); - - assert!(new_validators.len() == v as usize); - - // Give Era Points - let reward = EraRewardPoints:: { - total: points_total, - individual: points_individual.into_iter().collect(), - }; - - let current_era = CurrentEra::get().unwrap(); - ErasRewardPoints::::insert(current_era, reward); - - // Create reward pool - let total_payout = T::Currency::minimum_balance() * 1000.into(); - >::insert(current_era, total_payout); - - Ok((n_controller, validators)) -} - benchmarks! { _{ // User account seed @@ -306,18 +251,12 @@ benchmarks! { let slash_indices: Vec = (0 .. s).collect(); }: _(RawOrigin::Root, era, slash_indices) - payout_validator { + payout_stakers { let n in 1 .. MAX_NOMINATIONS as u32; let validator = create_validator_with_nominators::(n, MAX_NOMINATIONS as u32)?; let current_era = CurrentEra::get().unwrap(); - }: _(RawOrigin::Signed(validator), current_era) - - payout_nominator { - let v in 1 .. MAX_NOMINATIONS as u32; - let (nominator, validators) = create_nominator_with_validators::(v)?; - let current_era = CurrentEra::get().unwrap(); - let find_nominator = validators.into_iter().map(|x| (x, 0)).collect(); - }: _(RawOrigin::Signed(nominator), current_era, find_nominator) + let caller = account("caller", n, SEED); + }: _(RawOrigin::Signed(caller), validator, current_era) rebond { let l in 1 .. 1000; @@ -386,6 +325,45 @@ benchmarks! { &mut NegativeImbalanceOf::::zero() ); } + + payout_all { + let v in 1 .. 10; + let n in 1 .. 100; + MinimumValidatorCount::put(0); + create_validators_with_nominators_for_era::(v, n)?; + // Start a new Era + let new_validators = Staking::::new_era(SessionIndex::one()).unwrap(); + assert!(new_validators.len() == v as usize); + + let current_era = CurrentEra::get().unwrap(); + let mut points_total = 0; + let mut points_individual = Vec::new(); + let mut payout_calls = Vec::new(); + + for validator in new_validators.iter() { + points_total += 10; + points_individual.push((validator.clone(), 10)); + payout_calls.push(Call::::payout_stakers(validator.clone(), current_era)) + } + + // Give Era Points + let reward = EraRewardPoints:: { + total: points_total, + individual: points_individual.into_iter().collect(), + }; + + ErasRewardPoints::::insert(current_era, reward); + + // Create reward pool + let total_payout = T::Currency::minimum_balance() * 1000.into(); + >::insert(current_era, total_payout); + + let caller: T::AccountId = account("caller", 0, SEED); + }: { + for call in payout_calls { + call.dispatch(RawOrigin::Signed(caller.clone()).into())?; + } + } } #[cfg(test)] @@ -397,7 +375,7 @@ mod tests { use crate::benchmarking::{ create_validators_with_nominators_for_era, create_validator_with_nominators, - create_nominator_with_validators, + SelectedBenchmark, }; #[test] @@ -429,36 +407,31 @@ mod tests { let current_era = CurrentEra::get().unwrap(); let controller = validator; let ledger = Staking::ledger(&controller).unwrap(); - let stash = &ledger.stash; + let stash = ledger.stash; - let original_free_balance = Balances::free_balance(stash); - assert_ok!(Staking::payout_validator(Origin::signed(controller), current_era)); - let new_free_balance = Balances::free_balance(stash); + let original_free_balance = Balances::free_balance(&stash); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), stash, current_era)); + let new_free_balance = Balances::free_balance(&stash); assert!(original_free_balance < new_free_balance); }); } #[test] - fn create_nominator_with_validators_works() { + fn test_payout_all() { ExtBuilder::default().has_stakers(false).build().execute_with(|| { - let v = 5; - - let (nominator, validators) = create_nominator_with_validators::(v).unwrap(); - - let current_era = CurrentEra::get().unwrap(); - let controller = nominator; - let ledger = Staking::ledger(&controller).unwrap(); - let stash = &ledger.stash; - - let find_nominator = validators.into_iter().map(|x| (x, 0)).collect(); + let v = 10; + let n = 100; - let original_free_balance = Balances::free_balance(stash); - assert_ok!(Staking::payout_nominator(Origin::signed(controller), current_era, find_nominator)); - let new_free_balance = Balances::free_balance(stash); + let selected_benchmark = SelectedBenchmark::payout_all; + let c = vec![(frame_benchmarking::BenchmarkParameter::v, v), (frame_benchmarking::BenchmarkParameter::n, n)]; + let closure_to_benchmark = + >::instance( + &selected_benchmark, + &c + ).unwrap(); - assert!(original_free_balance < new_free_balance); + assert_ok!(closure_to_benchmark()); }); } - } diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index b6b1bb32de..b566d616a8 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -104,10 +104,11 @@ //! The **reward and slashing** procedure is the core of the Staking module, attempting to _embrace //! valid behavior_ while _punishing any misbehavior or lack of availability_. //! -//! Reward must be claimed by stakers for each era before it gets too old by $HISTORY_DEPTH using -//! `payout_nominator` and `payout_validator` calls. +//! Rewards must be claimed for each era before it gets too old by `$HISTORY_DEPTH` using the +//! `payout_stakers` call. Any account can call `payout_stakers`, which pays the reward to +//! the validator as well as its nominators. //! Only the [`T::MaxNominatorRewardedPerValidator`] biggest stakers can claim their reward. This -//! limit the i/o cost to compute nominators payout. +//! is to limit the i/o cost to mutate storage for each nominator's account. //! //! Slashing can occur at any point in time, once misbehavior is reported. Once slashing is //! determined, a value is deducted from the balance of the validator and all the nominators who @@ -452,8 +453,9 @@ pub struct StakingLedger { /// Any balance that is becoming free, which may eventually be transferred out /// of the stash (assuming it doesn't get slashed first). pub unlocking: Vec>, - /// The latest and highest era which the staker has claimed reward for. - pub last_reward: Option, + /// List of eras for which the stakers behind a validator have claimed rewards. Only updated + /// for validators. + pub claimed_rewards: Vec, } impl< @@ -478,7 +480,7 @@ impl< total, active: self.active, unlocking, - last_reward: self.last_reward + claimed_rewards: self.claimed_rewards } } @@ -775,7 +777,7 @@ pub trait Trait: frame_system::Trait { /// A transaction submitter. type SubmitTransaction: SubmitUnsignedTransaction::Call>; - /// The maximum number of nominator rewarded for each validator. + /// The maximum number of nominators rewarded for each validator. /// /// For each validator only the `$MaxNominatorRewardedPerValidator` biggest stakers can claim /// their reward. This used to limit the i/o cost for the nominator payout. @@ -818,13 +820,13 @@ impl Default for Releases { decl_storage! { trait Store for Module as Staking { - /// Number of era to keep in history. + /// Number of eras to keep in history. /// - /// Information is kept for eras in `[current_era - history_depth; current_era] + /// Information is kept for eras in `[current_era - history_depth; current_era]`. /// - /// Must be more than the number of era delayed by session otherwise. - /// i.e. active era must always be in history. - /// i.e. `active_era > current_era - history_depth` must be guaranteed. + /// Must be more than the number of eras delayed by session otherwise. + /// I.e. active era must always be in history. + /// I.e. `active_era > current_era - history_depth` must be guaranteed. HistoryDepth get(fn history_depth) config(): u32 = 84; /// The ideal number of staking participants. @@ -860,7 +862,7 @@ decl_storage! { /// The current era index. /// - /// This is the latest planned era, depending on how session module queues the validator + /// This is the latest planned era, depending on how the Session pallet queues the validator /// set, it might be active or not. pub CurrentEra get(fn current_era): Option; @@ -870,7 +872,7 @@ decl_storage! { /// Validator set of this era must be equal to `SessionInterface::validators`. pub ActiveEra get(fn active_era): Option; - /// The session index at which the era start for the last `HISTORY_DEPTH` eras + /// The session index at which the era start for the last `HISTORY_DEPTH` eras. pub ErasStartSessionIndex get(fn eras_start_session_index): map hasher(twox_64_concat) EraIndex => Option; @@ -886,7 +888,7 @@ decl_storage! { /// Clipped Exposure of validator at era. /// - /// This is similar to [`ErasStakers`] but number of nominators exposed is reduce to the + /// This is similar to [`ErasStakers`] but number of nominators exposed is reduced to the /// `T::MaxNominatorRewardedPerValidator` biggest stakers. /// (Note: the field `total` and `own` of the exposure remains unchanged). /// This is used to limit the i/o cost for the nominator payout. @@ -899,7 +901,7 @@ decl_storage! { double_map hasher(twox_64_concat) EraIndex, hasher(twox_64_concat) T::AccountId => Exposure>; - /// Similarly to `ErasStakers` this holds the preferences of validators. + /// Similar to `ErasStakers`, this holds the preferences of validators. /// /// This is keyed first by the era index to allow bulk deletion and then the stash account. /// @@ -998,6 +1000,9 @@ decl_storage! { /// /// This is set to v3.0.0 for new networks. StorageVersion build(|_: &GenesisConfig| Releases::V3_0_0): Releases; + + /// The era where we migrated from Lazy Payouts to Simple Payouts + MigrateEra: Option; } add_extra_genesis { config(stakers): @@ -1035,7 +1040,7 @@ decl_storage! { decl_event!( pub enum Event where Balance = BalanceOf, ::AccountId { - /// The staker has been rewarded by this amount. AccountId is controller account. + /// The staker has been rewarded by this amount. `AccountId` is the stash account. Reward(AccountId, Balance), /// One validator (and its nominators) has been slashed by the given amount. Slash(AccountId, Balance), @@ -1088,6 +1093,8 @@ decl_error! { InvalidNumberOfNominations, /// Items are not sorted and unique. NotSortedAndUnique, + /// Rewards for this era have already been claimed for this validator. + AlreadyClaimed, /// The submitted result is received out of the open window. PhragmenEarlySubmission, /// The submitted result is not as good as the one stored on chain. @@ -1223,6 +1230,7 @@ decl_module! { // For Kusama the type hasn't actually changed as Moment was u64 and was the number of // millisecond since unix epoch. StorageVersion::put(Releases::V3_0_0); + Self::migrate_last_reward_to_claimed_rewards(); 0 } @@ -1273,6 +1281,10 @@ decl_module! { system::Module::::inc_ref(&stash); + let current_era = CurrentEra::get().unwrap_or(0); + let history_depth = Self::history_depth(); + let last_reward_era = current_era.saturating_sub(history_depth); + let stash_balance = T::Currency::free_balance(&stash); let value = value.min(stash_balance); Self::deposit_event(RawEvent::Bonded(stash.clone(), value)); @@ -1281,7 +1293,7 @@ decl_module! { total: value, active: value, unlocking: vec![], - last_reward: Self::current_era(), + claimed_rewards: (last_reward_era..current_era).collect(), }; Self::update_ledger(&controller, &item); } @@ -1629,6 +1641,10 @@ decl_module! { ::UnappliedSlashes::insert(&era, &unapplied); } + /// **This extrinsic will be removed after `MigrationEra + HistoryDepth` has passed, giving + /// opportunity for users to claim all rewards before moving to Simple Payouts. After this + /// time, you should use `payout_stakers` instead.** + /// /// Make one nominator's payout for one era. /// /// - `who` is the controller account of the nominator to pay out. @@ -1663,6 +1679,10 @@ decl_module! { Self::do_payout_nominator(who, era, validators) } + /// **This extrinsic will be removed after `MigrationEra + HistoryDepth` has passed, giving + /// opportunity for users to claim all rewards before moving to Simple Payouts. After this + /// time, you should use `payout_stakers` instead.** + /// /// Make one validator's payout for one era. /// /// - `who` is the controller account of the validator to pay out. @@ -1684,6 +1704,25 @@ decl_module! { Self::do_payout_validator(who, era) } + /// Pay out all the stakers behind a single validator for a single era. + /// + /// - `validator_stash` is the stash account of the validator. Their nominators, up to + /// `T::MaxNominatorRewardedPerValidator`, will also receive their rewards. + /// - `era` may be any era between `[current_era - history_depth; current_era]`. + /// + /// The origin of this call must be _Signed_. Any account can call this function, even if + /// it is not one of the stakers. + /// + /// # + /// - Time complexity: at most O(MaxNominatorRewardedPerValidator). + /// - Contains a limited number of reads and writes. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + fn payout_stakers(origin, validator_stash: T::AccountId, era: EraIndex) -> DispatchResult { + ensure_signed(origin)?; + Self::do_payout_stakers(validator_stash, era) + } + /// Rebond a portion of the stash scheduled to be unlocked. /// /// # @@ -1857,6 +1896,43 @@ decl_module! { } impl Module { + /// Migrate `last_reward` to `claimed_rewards` + pub fn migrate_last_reward_to_claimed_rewards() { + use frame_support::migration::{StorageIterator, put_storage_value}; + // Migrate from `last_reward` to `claimed_rewards`. + // We will construct a vector from `current_era - history_depth` to `last_reward` + // for each validator and nominator. + // + // Old Staking Ledger + #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] + struct OldStakingLedger { + pub stash: AccountId, + #[codec(compact)] + pub total: Balance, + #[codec(compact)] + pub active: Balance, + pub unlocking: Vec>, + pub last_reward: Option, + } + // Current era and history depth + let current_era = Self::current_era().unwrap_or(0); + let history_depth = Self::history_depth(); + let last_payout_era = current_era.saturating_sub(history_depth); + // Convert all ledgers to the new format. + for (hash, old_ledger) in StorageIterator::>>::new(b"Staking", b"Ledger").drain() { + let last_reward = old_ledger.last_reward.unwrap_or(0); + let new_ledger = StakingLedger { + stash: old_ledger.stash, + total: old_ledger.total, + active: old_ledger.active, + unlocking: old_ledger.unlocking, + claimed_rewards: (last_payout_era..=last_reward).collect(), + }; + put_storage_value(b"Staking", b"Ledger", &hash, new_ledger); + } + MigrateEra::put(current_era); + } + /// The total balance that can be slashed from a stash account as of right now. pub fn slashable_balance_of(stash: &T::AccountId) -> BalanceOf { Self::bonded(stash).and_then(Self::ledger).map(|l| l.active).unwrap_or_default() @@ -1916,6 +1992,15 @@ impl Module { if validators.len() > MAX_NOMINATIONS { return Err(Error::::InvalidNumberOfNominations.into()); } + // If migrate_era is not populated, then you should use `payout_stakers` + let migrate_era = MigrateEra::get().ok_or(Error::::InvalidEraToReward)?; + // This payout mechanism will only work for eras before the migration. + // Subsequent payouts should use `payout_stakers`. + ensure!(era < migrate_era, Error::::InvalidEraToReward); + let current_era = CurrentEra::get().ok_or(Error::::InvalidEraToReward)?; + ensure!(era <= current_era, Error::::InvalidEraToReward); + let history_depth = Self::history_depth(); + ensure!(era >= current_era.saturating_sub(history_depth), Error::::InvalidEraToReward); // Note: if era has no reward to be claimed, era may be future. better not to update // `nominator_ledger.last_reward` in this case. @@ -1924,11 +2009,12 @@ impl Module { let mut nominator_ledger = >::get(&who).ok_or_else(|| Error::::NotController)?; - if nominator_ledger.last_reward.map(|last_reward| last_reward >= era).unwrap_or(false) { - return Err(Error::::InvalidEraToReward.into()); + nominator_ledger.claimed_rewards.retain(|&x| x >= current_era.saturating_sub(history_depth)); + match nominator_ledger.claimed_rewards.binary_search(&era) { + Ok(_) => Err(Error::::AlreadyClaimed)?, + Err(pos) => nominator_ledger.claimed_rewards.insert(pos, era), } - nominator_ledger.last_reward = Some(era); >::insert(&who, &nominator_ledger); let mut reward = Perbill::zero(); @@ -1972,17 +2058,29 @@ impl Module { } fn do_payout_validator(who: T::AccountId, era: EraIndex) -> DispatchResult { + // If migrate_era is not populated, then you should use `payout_stakers` + let migrate_era = MigrateEra::get().ok_or(Error::::InvalidEraToReward)?; + // This payout mechanism will only work for eras before the migration. + // Subsequent payouts should use `payout_stakers`. + ensure!(era < migrate_era, Error::::InvalidEraToReward); + let current_era = CurrentEra::get().ok_or(Error::::InvalidEraToReward)?; + ensure!(era <= current_era, Error::::InvalidEraToReward); + let history_depth = Self::history_depth(); + ensure!(era >= current_era.saturating_sub(history_depth), Error::::InvalidEraToReward); + // Note: if era has no reward to be claimed, era may be future. better not to update // `ledger.last_reward` in this case. let era_payout = >::get(&era) .ok_or_else(|| Error::::InvalidEraToReward)?; let mut ledger = >::get(&who).ok_or_else(|| Error::::NotController)?; - if ledger.last_reward.map(|last_reward| last_reward >= era).unwrap_or(false) { - return Err(Error::::InvalidEraToReward.into()); + + ledger.claimed_rewards.retain(|&x| x >= current_era.saturating_sub(history_depth)); + match ledger.claimed_rewards.binary_search(&era) { + Ok(_) => Err(Error::::AlreadyClaimed)?, + Err(pos) => ledger.claimed_rewards.insert(pos, era), } - ledger.last_reward = Some(era); >::insert(&who, &ledger); let era_reward_points = >::get(&era); @@ -2013,6 +2111,108 @@ impl Module { Ok(()) } + fn do_payout_stakers( + validator_stash: T::AccountId, + era: EraIndex, + ) -> DispatchResult { + /* Validate input data */ + let current_era = CurrentEra::get().ok_or(Error::::InvalidEraToReward)?; + ensure!(era <= current_era, Error::::InvalidEraToReward); + let history_depth = Self::history_depth(); + ensure!(era >= current_era.saturating_sub(history_depth), Error::::InvalidEraToReward); + + // If there was no migration, then this function is always valid. + if let Some(migrate_era) = MigrateEra::get() { + // This payout mechanism will only work for eras on and after the migration. + // Payouts before then should use `payout_nominator`/`payout_validator`. + ensure!(migrate_era <= era, Error::::InvalidEraToReward); + } + + // Note: if era has no reward to be claimed, era may be future. better not to update + // `ledger.claimed_rewards` in this case. + let era_payout = >::get(&era) + .ok_or_else(|| Error::::InvalidEraToReward)?; + + let controller = Self::bonded(&validator_stash).ok_or(Error::::NotStash)?; + let mut ledger = >::get(&controller).ok_or_else(|| Error::::NotController)?; + + ledger.claimed_rewards.retain(|&x| x >= current_era.saturating_sub(history_depth)); + match ledger.claimed_rewards.binary_search(&era) { + Ok(_) => Err(Error::::AlreadyClaimed)?, + Err(pos) => ledger.claimed_rewards.insert(pos, era), + } + + let exposure = >::get(&era, &ledger.stash); + + /* Input data seems good, no errors allowed after this point */ + + >::insert(&controller, &ledger); + + // Get Era reward points. It has TOTAL and INDIVIDUAL + // Find the fraction of the era reward that belongs to the validator + // Take that fraction of the eras rewards to split to nominator and validator + // + // Then look at the validator, figure out the proportion of their reward + // which goes to them and each of their nominators. + + let era_reward_points = >::get(&era); + let total_reward_points = era_reward_points.total; + let validator_reward_points = era_reward_points.individual.get(&ledger.stash) + .map(|points| *points) + .unwrap_or_else(|| Zero::zero()); + + // Nothing to do if they have no reward points. + if validator_reward_points.is_zero() { return Ok(())} + + // This is the fraction of the total reward that the validator and the + // nominators will get. + let validator_total_reward_part = Perbill::from_rational_approximation( + validator_reward_points, + total_reward_points, + ); + + // This is how much validator + nominators are entitled to. + let validator_total_payout = validator_total_reward_part * era_payout; + + let validator_prefs = Self::eras_validator_prefs(&era, &validator_stash); + // Validator first gets a cut off the top. + let validator_commission = validator_prefs.commission; + let validator_commission_payout = validator_commission * validator_total_payout; + + let validator_leftover_payout = validator_total_payout - validator_commission_payout; + // Now let's calculate how this is split to the validator. + let validator_exposure_part = Perbill::from_rational_approximation( + exposure.own, + exposure.total, + ); + let validator_staking_payout = validator_exposure_part * validator_leftover_payout; + + // We can now make total validator payout: + if let Some(imbalance) = Self::make_payout( + &ledger.stash, + validator_staking_payout + validator_commission_payout + ) { + Self::deposit_event(RawEvent::Reward(ledger.stash, imbalance.peek())); + } + + // Lets now calculate how this is split to the nominators. + // Sort nominators by highest to lowest exposure, but only keep `max_nominator_payouts` of them. + for nominator in exposure.others.iter() { + let nominator_exposure_part = Perbill::from_rational_approximation( + nominator.value, + exposure.total, + ); + + let nominator_reward: BalanceOf = nominator_exposure_part * validator_leftover_payout; + // We can now make nominator payout: + if let Some(imbalance) = Self::make_payout(&nominator.who, nominator_reward) { + Self::deposit_event(RawEvent::Reward(nominator.who.clone(), imbalance.peek())); + } + } + + Ok(()) + } + /// Update the ledger for a controller. This will also update the stash lock. The lock will /// will lock the entire funds except paying for further transactions. fn update_ledger( diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index b90064ae47..f812341653 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -34,11 +34,7 @@ use sp_io; use sp_phragmen::{ build_support_map, evaluate_support, reduce, ExtendedBalance, StakedAssignment, PhragmenScore, }; -use crate::{ - EraIndex, GenesisConfig, Module, Trait, StakerStatus, ValidatorPrefs, RewardDestination, - Nominators, inflation, SessionInterface, Exposure, ErasStakers, ErasRewardPoints, - CompactAssignments, ValidatorIndex, NominatorIndex, Validators, OffchainAccuracy, -}; +use crate::*; const INIT_TIMESTAMP: u64 = 30_000; @@ -559,6 +555,7 @@ pub fn assert_ledger_consistent(stash: AccountId) { pub fn bond_validator(stash: u64, ctrl: u64, val: u64) { let _ = Balances::make_free_balance_be(&stash, val); + let _ = Balances::make_free_balance_be(&ctrl, val); assert_ok!(Staking::bond( Origin::signed(stash), ctrl, @@ -573,6 +570,7 @@ pub fn bond_validator(stash: u64, ctrl: u64, val: u64) { pub fn bond_nominator(stash: u64, ctrl: u64, val: u64, target: Vec) { let _ = Balances::make_free_balance_be(&stash, val); + let _ = Balances::make_free_balance_be(&ctrl, val); assert_ok!(Staking::bond( Origin::signed(stash), ctrl, @@ -684,8 +682,6 @@ pub fn on_offence_now( pub fn horrible_phragmen_with_post_processing( do_reduce: bool, ) -> (CompactAssignments, Vec, PhragmenScore) { - use std::collections::BTreeMap; - let mut backing_stake_of: BTreeMap = BTreeMap::new(); // self stake @@ -867,7 +863,7 @@ pub fn prepare_submission_with( } /// Make all validator and nominator request their payment -pub fn make_all_reward_payment(era: EraIndex) { +pub fn make_all_reward_payment_before_migration(era: EraIndex) { let validators_with_reward = ErasRewardPoints::::get(era).individual.keys() .cloned() .collect::>(); @@ -898,6 +894,20 @@ pub fn make_all_reward_payment(era: EraIndex) { } } +/// Make all validator and nominator request their payment +pub fn make_all_reward_payment(era: EraIndex) { + let validators_with_reward = ErasRewardPoints::::get(era).individual.keys() + .cloned() + .collect::>(); + + // reward validators + for validator_controller in validators_with_reward.iter().filter_map(Staking::bonded) { + let ledger = >::get(&validator_controller).unwrap(); + + assert_ok!(Staking::payout_stakers(Origin::signed(1337), ledger.stash, era)); + } +} + #[macro_export] macro_rules! assert_session_era { ($session:expr, $era:expr) => { diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 01334b918f..1777081769 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -66,12 +66,12 @@ fn basic_setup_works() { // Account 10 controls the stash from account 11, which is 100 * balance_factor units assert_eq!( Staking::ledger(&10), - Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![], last_reward: None }) + Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![], claimed_rewards: vec![] }) ); // Account 20 controls the stash from account 21, which is 200 * balance_factor units assert_eq!( Staking::ledger(&20), - Some(StakingLedger { stash: 21, total: 1000, active: 1000, unlocking: vec![], last_reward: None }) + Some(StakingLedger { stash: 21, total: 1000, active: 1000, unlocking: vec![], claimed_rewards: vec![] }) ); // Account 1 does not control any stash assert_eq!(Staking::ledger(&1), None); @@ -85,7 +85,7 @@ fn basic_setup_works() { assert_eq!( Staking::ledger(100), - Some(StakingLedger { stash: 101, total: 500, active: 500, unlocking: vec![], last_reward: None }) + Some(StakingLedger { stash: 101, total: 500, active: 500, unlocking: vec![], claimed_rewards: vec![] }) ); assert_eq!(Staking::nominators(101).unwrap().targets, vec![11, 21]); @@ -140,7 +140,7 @@ fn change_controller_works() { assert_ok!(Staking::set_controller(Origin::signed(11), 5)); - start_era(1); + mock::start_era(1); assert_noop!( Staking::validate(Origin::signed(10), ValidatorPrefs::default()), @@ -222,7 +222,7 @@ fn rewards_should_work() { let total_payout_1 = current_total_payout_for_duration(3 * 1000); assert!(total_payout_1 > 10); // Test is meaningful if reward something - start_era(2); + mock::start_era(2); mock::make_all_reward_payment(1); assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * (total_payout_0 * 2/3 + total_payout_1), 2); @@ -264,7 +264,6 @@ fn staking_should_work() { start_session(2); // add a new candidate for being a validator. account 3 controlled by 4. assert_ok!(Staking::bond(Origin::signed(3), 4, 1500, RewardDestination::Controller)); - let current_era_at_bond = Staking::current_era(); assert_ok!(Staking::validate(Origin::signed(4), ValidatorPrefs::default())); // No effects will be seen so far. @@ -311,7 +310,7 @@ fn staking_should_work() { total: 1500, active: 1500, unlocking: vec![], - last_reward: current_era_at_bond, + claimed_rewards: vec![0], }) ); // e.g. it cannot spend more than 500 that it has free from the total 2000 @@ -336,7 +335,7 @@ fn less_than_needed_candidates_works() { assert_eq!(Staking::minimum_validator_count(), 1); assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]); - start_era(1); + mock::start_era(1); // Previous set is selected. NO election algorithm is even executed. assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]); @@ -374,7 +373,7 @@ fn no_candidate_emergency_condition() { let _ = Staking::chill(Origin::signed(10)); // trigger era - start_era(1); + mock::start_era(1); // Previous ones are elected. chill is invalidates. TODO: #2494 assert_eq_uvec!(validator_controllers(), vec![10, 20, 30, 40]); @@ -454,7 +453,7 @@ fn nominating_and_rewards_should_work() { >::reward_by_ids(vec![(41, 1)]); >::reward_by_ids(vec![(31, 1)]); - start_era(1); + mock::start_era(1); // 10 and 20 have more votes, they will be chosen by phragmen. assert_eq_uvec!(validator_controllers(), vec![20, 10]); @@ -497,7 +496,7 @@ fn nominating_and_rewards_should_work() { >::reward_by_ids(vec![(21, 2)]); >::reward_by_ids(vec![(11, 1)]); - start_era(2); + mock::start_era(2); // nothing else will happen, era ends and rewards are paid again, // it is expected that nominators will also be paid. See below @@ -565,7 +564,7 @@ fn nominators_also_get_slashed() { >::reward_by_ids(vec![(11, 1)]); // new era, pay rewards, - start_era(1); + mock::start_era(1); // Nominator stash didn't collect any. assert_eq!(Balances::total_balance(&2), initial_balance); @@ -819,7 +818,7 @@ fn reward_destination_works() { total: 1000, active: 1000, unlocking: vec![], - last_reward: None, + claimed_rewards: vec![], })); // Compute total payout now for whole duration as other parameter won't change @@ -827,7 +826,7 @@ fn reward_destination_works() { assert!(total_payout_0 > 100); // Test is meaningful if reward something >::reward_by_ids(vec![(11, 1)]); - start_era(1); + mock::start_era(1); mock::make_all_reward_payment(0); // Check that RewardDestination is Staked (default) @@ -840,7 +839,7 @@ fn reward_destination_works() { total: 1000 + total_payout_0, active: 1000 + total_payout_0, unlocking: vec![], - last_reward: Some(0), + claimed_rewards: vec![0], })); //Change RewardDestination to Stash @@ -851,7 +850,7 @@ fn reward_destination_works() { assert!(total_payout_1 > 100); // Test is meaningful if reward something >::reward_by_ids(vec![(11, 1)]); - start_era(2); + mock::start_era(2); mock::make_all_reward_payment(1); // Check that RewardDestination is Stash @@ -866,7 +865,7 @@ fn reward_destination_works() { total: 1000 + total_payout_0, active: 1000 + total_payout_0, unlocking: vec![], - last_reward: Some(1), + claimed_rewards: vec![0,1], })); // Change RewardDestination to Controller @@ -880,7 +879,7 @@ fn reward_destination_works() { assert!(total_payout_2 > 100); // Test is meaningful if reward something >::reward_by_ids(vec![(11, 1)]); - start_era(3); + mock::start_era(3); mock::make_all_reward_payment(2); // Check that RewardDestination is Controller @@ -893,7 +892,7 @@ fn reward_destination_works() { total: 1000 + total_payout_0, active: 1000 + total_payout_0, unlocking: vec![], - last_reward: Some(2), + claimed_rewards: vec![0,1,2], })); // Check that amount in staked account is NOT increased. assert_eq!(Balances::free_balance(11), recorded_stash_balance); @@ -915,7 +914,7 @@ fn validator_payment_prefs_work() { >::insert(&11, RewardDestination::Controller); >::insert(&101, RewardDestination::Controller); - start_era(1); + mock::start_era(1); mock::make_all_reward_payment(0); let balance_era_1_10 = Balances::total_balance(&10); @@ -927,7 +926,7 @@ fn validator_payment_prefs_work() { let exposure_1 = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); >::reward_by_ids(vec![(11, 1)]); - start_era(2); + mock::start_era(2); mock::make_all_reward_payment(1); let taken_cut = commission * total_payout_1; @@ -959,7 +958,7 @@ fn bond_extra_works() { total: 1000, active: 1000, unlocking: vec![], - last_reward: None, + claimed_rewards: vec![], })); // Give account 11 some large free balance greater than total @@ -973,7 +972,7 @@ fn bond_extra_works() { total: 1000 + 100, active: 1000 + 100, unlocking: vec![], - last_reward: None, + claimed_rewards: vec![], })); // Call the bond_extra function with a large number, should handle it @@ -984,7 +983,7 @@ fn bond_extra_works() { total: 1000000, active: 1000000, unlocking: vec![], - last_reward: None, + claimed_rewards: vec![], })); }); } @@ -1011,7 +1010,7 @@ fn bond_extra_and_withdraw_unbonded_works() { assert_eq!(Balances::total_balance(&10), 1); // confirm that 10 is a normal validator and gets paid at the end of the era. - start_era(1); + mock::start_era(1); // Initial state of 10 assert_eq!(Staking::ledger(&10), Some(StakingLedger { @@ -1019,7 +1018,7 @@ fn bond_extra_and_withdraw_unbonded_works() { total: 1000, active: 1000, unlocking: vec![], - last_reward: None, + claimed_rewards: vec![], })); assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11), Exposure { total: 1000, own: 1000, others: vec![] }); @@ -1031,13 +1030,13 @@ fn bond_extra_and_withdraw_unbonded_works() { total: 1000 + 100, active: 1000 + 100, unlocking: vec![], - last_reward: None, + claimed_rewards: vec![], })); // Exposure is a snapshot! only updated after the next era update. assert_ne!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11), Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] }); // trigger next era. - start_era(2); + mock::start_era(2); assert_eq!(Staking::active_era().unwrap().index, 2); // ledger should be the same. @@ -1046,7 +1045,7 @@ fn bond_extra_and_withdraw_unbonded_works() { total: 1000 + 100, active: 1000 + 100, unlocking: vec![], - last_reward: None, + claimed_rewards: vec![], })); // Exposure is now updated. assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11), Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] }); @@ -1054,29 +1053,29 @@ fn bond_extra_and_withdraw_unbonded_works() { // Unbond almost all of the funds in stash. Staking::unbond(Origin::signed(10), 1000).unwrap(); assert_eq!(Staking::ledger(&10), Some(StakingLedger { - stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}], last_reward: None }) + stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}], claimed_rewards: vec![] }) ); // Attempting to free the balances now will fail. 2 eras need to pass. Staking::withdraw_unbonded(Origin::signed(10)).unwrap(); assert_eq!(Staking::ledger(&10), Some(StakingLedger { - stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}], last_reward: None })); + stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}], claimed_rewards: vec![] })); // trigger next era. - start_era(3); + mock::start_era(3); // nothing yet Staking::withdraw_unbonded(Origin::signed(10)).unwrap(); assert_eq!(Staking::ledger(&10), Some(StakingLedger { - stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}], last_reward: None })); + stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}], claimed_rewards: vec![] })); // trigger next era. - start_era(5); + mock::start_era(5); Staking::withdraw_unbonded(Origin::signed(10)).unwrap(); // Now the value is free and the staking ledger is updated. assert_eq!(Staking::ledger(&10), Some(StakingLedger { - stash: 11, total: 100, active: 100, unlocking: vec![], last_reward: None })); + stash: 11, total: 100, active: 100, unlocking: vec![], claimed_rewards: vec![] })); }) } @@ -1088,14 +1087,14 @@ fn too_many_unbond_calls_should_not_work() { assert_ok!(Staking::unbond(Origin::signed(10), 1)); } - start_era(1); + mock::start_era(1); // locked at era 1 until 4 assert_ok!(Staking::unbond(Origin::signed(10), 1)); // can't do more. assert_noop!(Staking::unbond(Origin::signed(10), 1), Error::::NoMoreChunks); - start_era(3); + mock::start_era(3); assert_noop!(Staking::unbond(Origin::signed(10), 1), Error::::NoMoreChunks); // free up. @@ -1127,7 +1126,7 @@ fn rebond_works() { let _ = Balances::make_free_balance_be(&11, 1000000); // confirm that 10 is a normal validator and gets paid at the end of the era. - start_era(1); + mock::start_era(1); // Initial state of 10 assert_eq!( @@ -1137,11 +1136,11 @@ fn rebond_works() { total: 1000, active: 1000, unlocking: vec![], - last_reward: None, + claimed_rewards: vec![], }) ); - start_era(2); + mock::start_era(2); assert_eq!(Staking::active_era().unwrap().index, 2); // Try to rebond some funds. We get an error since no fund is unbonded. @@ -1162,7 +1161,7 @@ fn rebond_works() { value: 900, era: 2 + 3, }], - last_reward: None, + claimed_rewards: vec![], }) ); @@ -1175,7 +1174,7 @@ fn rebond_works() { total: 1000, active: 1000, unlocking: vec![], - last_reward: None, + claimed_rewards: vec![], }) ); @@ -1188,7 +1187,7 @@ fn rebond_works() { total: 1000, active: 100, unlocking: vec![UnlockChunk { value: 900, era: 5 }], - last_reward: None, + claimed_rewards: vec![], }) ); @@ -1201,7 +1200,7 @@ fn rebond_works() { total: 1000, active: 600, unlocking: vec![UnlockChunk { value: 400, era: 5 }], - last_reward: None, + claimed_rewards: vec![], }) ); @@ -1214,7 +1213,7 @@ fn rebond_works() { total: 1000, active: 1000, unlocking: vec![], - last_reward: None, + claimed_rewards: vec![], }) ); @@ -1233,7 +1232,7 @@ fn rebond_works() { UnlockChunk { value: 300, era: 5 }, UnlockChunk { value: 300, era: 5 }, ], - last_reward: None, + claimed_rewards: vec![], }) ); @@ -1249,7 +1248,7 @@ fn rebond_works() { UnlockChunk { value: 300, era: 5 }, UnlockChunk { value: 100, era: 5 }, ], - last_reward: None, + claimed_rewards: vec![], }) ); }) @@ -1272,7 +1271,7 @@ fn rebond_is_fifo() { let _ = Balances::make_free_balance_be(&11, 1000000); // confirm that 10 is a normal validator and gets paid at the end of the era. - start_era(1); + mock::start_era(1); // Initial state of 10 assert_eq!( @@ -1282,11 +1281,11 @@ fn rebond_is_fifo() { total: 1000, active: 1000, unlocking: vec![], - last_reward: None, + claimed_rewards: vec![], }) ); - start_era(2); + mock::start_era(2); // Unbond some of the funds in stash. Staking::unbond(Origin::signed(10), 400).unwrap(); @@ -1299,11 +1298,11 @@ fn rebond_is_fifo() { unlocking: vec![ UnlockChunk { value: 400, era: 2 + 3 }, ], - last_reward: None, + claimed_rewards: vec![], }) ); - start_era(3); + mock::start_era(3); // Unbond more of the funds in stash. Staking::unbond(Origin::signed(10), 300).unwrap(); @@ -1317,11 +1316,11 @@ fn rebond_is_fifo() { UnlockChunk { value: 400, era: 2 + 3 }, UnlockChunk { value: 300, era: 3 + 3 }, ], - last_reward: None, + claimed_rewards: vec![], }) ); - start_era(4); + mock::start_era(4); // Unbond yet more of the funds in stash. Staking::unbond(Origin::signed(10), 200).unwrap(); @@ -1336,7 +1335,7 @@ fn rebond_is_fifo() { UnlockChunk { value: 300, era: 3 + 3 }, UnlockChunk { value: 200, era: 4 + 3 }, ], - last_reward: None, + claimed_rewards: vec![], }) ); @@ -1352,7 +1351,7 @@ fn rebond_is_fifo() { UnlockChunk { value: 400, era: 2 + 3 }, UnlockChunk { value: 100, era: 3 + 3 }, ], - last_reward: None, + claimed_rewards: vec![], }) ); }) @@ -1378,7 +1377,7 @@ fn reward_to_stake_works() { // Now lets lower account 20 stake assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 21).total, 69); - >::insert(&20, StakingLedger { stash: 21, total: 69, active: 69, unlocking: vec![], last_reward: None }); + >::insert(&20, StakingLedger { stash: 21, total: 69, active: 69, unlocking: vec![], claimed_rewards: vec![] }); // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(3000); @@ -1387,7 +1386,7 @@ fn reward_to_stake_works() { >::reward_by_ids(vec![(21, 1)]); // New era --> rewards are paid --> stakes are changed - start_era(1); + mock::start_era(1); mock::make_all_reward_payment(0); assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11).total, 1000); @@ -1397,7 +1396,7 @@ fn reward_to_stake_works() { assert_eq!(_11_balance, 1000 + total_payout_0 / 2); // Trigger another new era as the info are frozen before the era start. - start_era(2); + mock::start_era(2); // -- new infos assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11).total, 1000 + total_payout_0 / 2); @@ -1541,7 +1540,7 @@ fn switching_roles() { assert_ok!(Staking::bond(Origin::signed(5), 6, 1000, RewardDestination::Controller)); assert_ok!(Staking::validate(Origin::signed(6), ValidatorPrefs::default())); - start_era(1); + mock::start_era(1); // with current nominators 10 and 5 have the most stake assert_eq_uvec!(validator_controllers(), vec![6, 10]); @@ -1555,7 +1554,7 @@ fn switching_roles() { // 2 : 2000 self vote + 250 vote. // Winners: 20 and 2 - start_era(2); + mock::start_era(2); assert_eq_uvec!(validator_controllers(), vec![2, 20]); @@ -1580,7 +1579,7 @@ fn wrong_vote_is_null() { ])); // new block - start_era(1); + mock::start_era(1); assert_eq_uvec!(validator_controllers(), vec![20, 10]); }); @@ -1604,7 +1603,6 @@ fn bond_with_no_staked_value() { ); // bonded with absolute minimum value possible. assert_ok!(Staking::bond(Origin::signed(1), 2, 5, RewardDestination::Controller)); - let current_era_at_bond = Staking::current_era(); assert_eq!(Balances::locks(&1)[0].amount, 5); // unbonding even 1 will cause all to be unbonded. @@ -1616,19 +1614,19 @@ fn bond_with_no_staked_value() { active: 0, total: 5, unlocking: vec![UnlockChunk {value: 5, era: 3}], - last_reward: current_era_at_bond, + claimed_rewards: vec![], }) ); - start_era(1); - start_era(2); + mock::start_era(1); + mock::start_era(2); // not yet removed. assert_ok!(Staking::withdraw_unbonded(Origin::signed(2))); assert!(Staking::ledger(2).is_some()); assert_eq!(Balances::locks(&1)[0].amount, 5); - start_era(3); + mock::start_era(3); // poof. Account 1 is removed from the staking system. assert_ok!(Staking::withdraw_unbonded(Origin::signed(2))); @@ -1661,7 +1659,7 @@ fn bond_with_little_staked_value_bounded() { let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 100); // Test is meaningful if reward something reward_all_elected(); - start_era(1); + mock::start_era(1); mock::make_all_reward_payment(0); // 2 is elected. @@ -1678,7 +1676,7 @@ fn bond_with_little_staked_value_bounded() { let total_payout_1 = current_total_payout_for_duration(3000); assert!(total_payout_1 > 100); // Test is meaningful if reward something reward_all_elected(); - start_era(2); + mock::start_era(2); mock::make_all_reward_payment(1); assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]); @@ -1726,7 +1724,7 @@ fn phragmen_should_not_overflow_validators() { bond_nominator(7, 6, u64::max_value() / 2, vec![3, 5]); bond_nominator(9, 8, u64::max_value() / 2, vec![3, 5]); - start_era(1); + mock::start_era(1); assert_eq_uvec!(validator_controllers(), vec![4, 2]); @@ -1749,7 +1747,7 @@ fn phragmen_should_not_overflow_nominators() { bond_nominator(7, 6, u64::max_value(), vec![3, 5]); bond_nominator(9, 8, u64::max_value(), vec![3, 5]); - start_era(1); + mock::start_era(1); assert_eq_uvec!(validator_controllers(), vec![4, 2]); @@ -1768,7 +1766,7 @@ fn phragmen_should_not_overflow_ultimate() { bond_nominator(7, 6, u64::max_value(), vec![3, 5]); bond_nominator(9, 8, u64::max_value(), vec![3, 5]); - start_era(1); + mock::start_era(1); assert_eq_uvec!(validator_controllers(), vec![4, 2]); @@ -1801,7 +1799,7 @@ fn reward_validator_slashing_validator_doesnt_overflow() { ErasStakers::::insert(0, 11, &exposure); ErasStakersClipped::::insert(0, 11, exposure); ErasValidatorReward::::insert(0, stake); - assert_ok!(Staking::payout_validator(Origin::signed(10), 0)); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 0)); assert_eq!(Balances::total_balance(&11), stake * 2); // Set staker @@ -1909,10 +1907,10 @@ fn era_is_always_same_length() { ExtBuilder::default().build().execute_with(|| { let session_per_era = >::get(); - start_era(1); + mock::start_era(1); assert_eq!(Staking::eras_start_session_index(active_era()).unwrap(), session_per_era); - start_era(2); + mock::start_era(2); assert_eq!(Staking::eras_start_session_index(active_era()).unwrap(), session_per_era * 2u32); let session = Session::current_index(); @@ -1922,7 +1920,7 @@ fn era_is_always_same_length() { assert_eq!(Staking::active_era().unwrap().index, 3); assert_eq!(Staking::eras_start_session_index(active_era()).unwrap(), session + 2); - start_era(4); + mock::start_era(4); assert_eq!(Staking::eras_start_session_index(active_era()).unwrap(), session + 2u32 + session_per_era); }); } @@ -1986,7 +1984,7 @@ fn offence_deselects_validator_even_when_slash_is_zero() { assert_eq!(Staking::force_era(), Forcing::ForceNew); assert!(!>::contains_key(11)); - start_era(1); + mock::start_era(1); assert!(!Session::validators().contains(&11)); assert!(!>::contains_key(11)); @@ -2024,7 +2022,7 @@ fn slashing_performed_according_exposure() { #[test] fn slash_in_old_span_does_not_deselect() { ExtBuilder::default().build().execute_with(|| { - start_era(1); + mock::start_era(1); assert!(>::contains_key(11)); assert!(Session::validators().contains(&11)); @@ -2043,14 +2041,14 @@ fn slash_in_old_span_does_not_deselect() { assert_eq!(Staking::force_era(), Forcing::ForceNew); assert!(!>::contains_key(11)); - start_era(2); + mock::start_era(2); Staking::validate(Origin::signed(10), Default::default()).unwrap(); assert_eq!(Staking::force_era(), Forcing::NotForcing); assert!(>::contains_key(11)); assert!(!Session::validators().contains(&11)); - start_era(3); + mock::start_era(3); // this staker is in a new slashing span now, having re-registered after // their prior slash. @@ -2338,7 +2336,7 @@ fn garbage_collection_on_window_pruning() { // ensures that `ValidatorSlashInEra` and `NominatorSlashInEra` are cleared after // `BondingDuration`. ExtBuilder::default().build().execute_with(|| { - start_era(1); + mock::start_era(1); assert_eq!(Balances::free_balance(11), 1000); let now = Staking::active_era().unwrap().index; @@ -2368,7 +2366,7 @@ fn garbage_collection_on_window_pruning() { assert!(::ValidatorSlashInEra::get(&now, &11).is_some()); assert!(::NominatorSlashInEra::get(&now, &101).is_some()); - start_era(era); + mock::start_era(era); } assert!(::ValidatorSlashInEra::get(&now, &11).is_none()); @@ -2379,9 +2377,9 @@ fn garbage_collection_on_window_pruning() { #[test] fn slashing_nominators_by_span_max() { ExtBuilder::default().build().execute_with(|| { - start_era(1); - start_era(2); - start_era(3); + mock::start_era(1); + mock::start_era(2); + mock::start_era(3); assert_eq!(Balances::free_balance(11), 1000); assert_eq!(Balances::free_balance(21), 2000); @@ -2477,9 +2475,9 @@ fn slashing_nominators_by_span_max() { #[test] fn slashes_are_summed_across_spans() { ExtBuilder::default().build().execute_with(|| { - start_era(1); - start_era(2); - start_era(3); + mock::start_era(1); + mock::start_era(2); + mock::start_era(3); assert_eq!(Balances::free_balance(21), 2000); assert_eq!(Staking::slashable_balance_of(&21), 1000); @@ -2507,7 +2505,7 @@ fn slashes_are_summed_across_spans() { // 21 has been force-chilled. re-signal intent to validate. Staking::validate(Origin::signed(20), Default::default()).unwrap(); - start_era(4); + mock::start_era(4); assert_eq!(Staking::slashable_balance_of(&21), 900); @@ -2535,7 +2533,7 @@ fn slashes_are_summed_across_spans() { #[test] fn deferred_slashes_are_deferred() { ExtBuilder::default().slash_defer_duration(2).build().execute_with(|| { - start_era(1); + mock::start_era(1); assert_eq!(Balances::free_balance(11), 1000); @@ -2556,19 +2554,19 @@ fn deferred_slashes_are_deferred() { assert_eq!(Balances::free_balance(11), 1000); assert_eq!(Balances::free_balance(101), 2000); - start_era(2); + mock::start_era(2); assert_eq!(Balances::free_balance(11), 1000); assert_eq!(Balances::free_balance(101), 2000); - start_era(3); + mock::start_era(3); assert_eq!(Balances::free_balance(11), 1000); assert_eq!(Balances::free_balance(101), 2000); // at the start of era 4, slashes from era 1 are processed, // after being deferred for at least 2 full eras. - start_era(4); + mock::start_era(4); assert_eq!(Balances::free_balance(11), 900); assert_eq!(Balances::free_balance(101), 2000 - (nominated_value / 10)); @@ -2578,7 +2576,7 @@ fn deferred_slashes_are_deferred() { #[test] fn remove_deferred() { ExtBuilder::default().slash_defer_duration(2).build().execute_with(|| { - start_era(1); + mock::start_era(1); assert_eq!(Balances::free_balance(11), 1000); @@ -2599,7 +2597,7 @@ fn remove_deferred() { assert_eq!(Balances::free_balance(11), 1000); assert_eq!(Balances::free_balance(101), 2000); - start_era(2); + mock::start_era(2); on_offence_in_era( &[ @@ -2623,20 +2621,20 @@ fn remove_deferred() { assert_eq!(Balances::free_balance(11), 1000); assert_eq!(Balances::free_balance(101), 2000); - start_era(3); + mock::start_era(3); assert_eq!(Balances::free_balance(11), 1000); assert_eq!(Balances::free_balance(101), 2000); // at the start of era 4, slashes from era 1 are processed, // after being deferred for at least 2 full eras. - start_era(4); + mock::start_era(4); // the first slash for 10% was cancelled, so no effect. assert_eq!(Balances::free_balance(11), 1000); assert_eq!(Balances::free_balance(101), 2000); - start_era(5); + mock::start_era(5); let slash_10 = Perbill::from_percent(10); let slash_15 = Perbill::from_percent(15); @@ -2654,7 +2652,7 @@ fn remove_deferred() { #[test] fn remove_multi_deferred() { ExtBuilder::default().slash_defer_duration(2).build().execute_with(|| { - start_era(1); + mock::start_era(1); assert_eq!(Balances::free_balance(11), 1000); @@ -2796,7 +2794,7 @@ mod offchain_phragmen { .session_per_era(3) .build() .execute_with(|| { - start_era(1); + mock::start_era(1); assert_eq!(Session::current_index(), 3); assert_eq!(Staking::current_era(), Some(1)); assert_eq!(Staking::is_current_session_final(), false); @@ -3609,7 +3607,7 @@ mod offchain_phragmen { // are in era zero and we want this one to pass with no problems. run_to_block(15); - // go to the next session to trigger start_era and bump the active era + // go to the next session to trigger mock::start_era and bump the active era run_to_block(20); // slash 10. This must happen outside of the election window. @@ -3799,7 +3797,7 @@ mod offchain_phragmen { #[test] fn slash_kicks_validators_not_nominators_and_disables_nominator_for_kicked_validator() { ExtBuilder::default().build().execute_with(|| { - start_era(1); + mock::start_era(1); assert_eq_uvec!(Session::validators(), vec![11, 21]); // pre-slash balance @@ -3847,7 +3845,7 @@ fn slash_kicks_validators_not_nominators_and_disables_nominator_for_kicked_valid // actually re-bond the slashed validator assert_ok!(Staking::validate(Origin::signed(10), Default::default())); - start_era(2); + mock::start_era(2); let exposure_11 = Staking::eras_stakers(active_era(), &11); let exposure_21 = Staking::eras_stakers(active_era(), &21); @@ -3881,7 +3879,7 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 10); // Test is meaningful if reward something - start_era(1); + mock::start_era(1); >::reward_by_ids(vec![(11, 1)]); // Change total issuance in order to modify total payout @@ -3891,7 +3889,7 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { assert!(total_payout_1 > 10); // Test is meaningful if reward something assert!(total_payout_1 != total_payout_0); - start_era(2); + mock::start_era(2); >::reward_by_ids(vec![(11, 1)]); // Change total issuance in order to modify total payout @@ -3902,7 +3900,7 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { assert!(total_payout_2 != total_payout_0); assert!(total_payout_2 != total_payout_1); - start_era(Staking::history_depth() + 1); + mock::start_era(Staking::history_depth() + 1); let active_era = Staking::active_era().unwrap().index; @@ -3912,37 +3910,19 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { // Last kept is 1: assert!(current_era - Staking::history_depth() == 1); assert_noop!( - Staking::payout_validator(Origin::signed(10), 0), - // Fail: Era out of history - Error::::InvalidEraToReward - ); - assert_ok!(Staking::payout_validator(Origin::signed(10), 1)); - assert_ok!(Staking::payout_validator(Origin::signed(10), 2)); - assert_noop!( - Staking::payout_validator(Origin::signed(10), 2), - // Fail: Double claim - Error::::InvalidEraToReward - ); - assert_noop!( - Staking::payout_validator(Origin::signed(10), active_era), - // Fail: Era not finished yet - Error::::InvalidEraToReward - ); - - assert_noop!( - Staking::payout_nominator(Origin::signed(100), 0, vec![(11, 0)]), + Staking::payout_stakers(Origin::signed(1337), 11, 0), // Fail: Era out of history Error::::InvalidEraToReward ); - assert_ok!(Staking::payout_nominator(Origin::signed(100), 1, vec![(11, 0)])); - assert_ok!(Staking::payout_nominator(Origin::signed(100), 2, vec![(11, 0)])); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 1)); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 2)); assert_noop!( - Staking::payout_nominator(Origin::signed(100), 2, vec![(11, 0)]), + Staking::payout_stakers(Origin::signed(1337), 11, 2), // Fail: Double claim - Error::::InvalidEraToReward + Error::::AlreadyClaimed ); assert_noop!( - Staking::payout_nominator(Origin::signed(100), active_era, vec![(11, 0)]), + Staking::payout_stakers(Origin::signed(1337), 11, active_era), // Fail: Era not finished yet Error::::InvalidEraToReward ); @@ -3964,7 +3944,7 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { #[test] fn zero_slash_keeps_nominators() { ExtBuilder::default().build().execute_with(|| { - start_era(1); + mock::start_era(1); assert_eq!(Balances::free_balance(11), 1000); @@ -4081,10 +4061,6 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( mock::start_era(2); mock::make_all_reward_payment(1); - // nominator 10_000 can't get its reward because exposure is clipped. However it will try - // to query other people reward. - assert_ok!(Staking::payout_nominator(Origin::signed(20_000), 1, vec![(11, 0)])); - // Assert only nominators from 1 to Max are rewarded for i in 0..=::MaxNominatorRewardedPerValidator::get() { let stash = 10_000 + i as u64; @@ -4101,7 +4077,7 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( #[test] fn set_history_depth_works() { ExtBuilder::default().build().execute_with(|| { - start_era(10); + mock::start_era(10); Staking::set_history_depth(Origin::ROOT, 20).unwrap(); assert!(::ErasTotalStake::contains_key(10 - 4)); assert!(::ErasTotalStake::contains_key(10 - 5)); @@ -4117,6 +4093,176 @@ fn set_history_depth_works() { }); } +#[test] +fn test_payout_stakers() { + // Here we will test validator can set `max_nominators_payout` and it works. + // We also test that `payout_extra_nominators` works. + ExtBuilder::default().has_stakers(false).build().execute_with(|| { + let balance = 1000; + // Create three validators: + bond_validator(11, 10, balance); // Default(64) + + // Create nominators, targeting stash of validators + for i in 0..100 { + bond_nominator(1000 + i, 100 + i, balance + i, vec![11]); + } + + mock::start_era(1); + Staking::reward_by_ids(vec![(11, 1)]); + // Compute total payout now for whole duration as other parameter won't change + let total_payout_0 = current_total_payout_for_duration(3 * 1000); + assert!(total_payout_0 > 100); // Test is meaningful if reward something + mock::start_era(2); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 1)); + + // Top 64 nominators of validator 11 automatically paid out, including the validator + // Validator payout goes to controller. + assert!(Balances::free_balance(&10) > balance); + for i in 36..100 { + assert!(Balances::free_balance(&(100 + i)) > balance + i); + } + // The bottom 36 do not + for i in 0..36 { + assert_eq!(Balances::free_balance(&(100 + i)), balance + i); + } + + // We track rewards in `claimed_rewards` vec + assert_eq!( + Staking::ledger(&10), + Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![], claimed_rewards: vec![1] }) + ); + + for i in 3..16 { + Staking::reward_by_ids(vec![(11, 1)]); + // Compute total payout now for whole duration as other parameter won't change + let total_payout_0 = current_total_payout_for_duration(3 * 1000); + assert!(total_payout_0 > 100); // Test is meaningful if reward something + mock::start_era(i); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, i - 1)); + } + + // We track rewards in `claimed_rewards` vec + assert_eq!( + Staking::ledger(&10), + Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![], claimed_rewards: (1..=14).collect() }) + ); + + for i in 16..100 { + Staking::reward_by_ids(vec![(11, 1)]); + // Compute total payout now for whole duration as other parameter won't change + let total_payout_0 = current_total_payout_for_duration(3 * 1000); + assert!(total_payout_0 > 100); // Test is meaningful if reward something + mock::start_era(i); + } + + // We clean it up as history passes + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 15)); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 98)); + assert_eq!( + Staking::ledger(&10), + Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![], claimed_rewards: vec![15, 98] }) + ); + + // Out of order claims works. + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 69)); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 23)); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 42)); + assert_eq!( + Staking::ledger(&10), + Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![], claimed_rewards: vec![15, 23, 42, 69, 98] }) + ); + }); +} + +#[test] +fn payout_stakers_handles_basic_errors() { + // Here we will test payouts handle all errors. + ExtBuilder::default().has_stakers(false).build().execute_with(|| { + // Same setup as the test above + let balance = 1000; + bond_validator(11, 10, balance); // Default(64) + + // Create nominators, targeting stash + for i in 0..100 { + bond_nominator(1000 + i, 100 + i, balance + i, vec![11]); + } + + mock::start_era(1); + Staking::reward_by_ids(vec![(11, 1)]); + // Compute total payout now for whole duration as other parameter won't change + let total_payout_0 = current_total_payout_for_duration(3 * 1000); + assert!(total_payout_0 > 100); // Test is meaningful if reward something + mock::start_era(2); + + // Wrong Era, too big + assert_noop!(Staking::payout_stakers(Origin::signed(1337), 11, 2), Error::::InvalidEraToReward); + // Wrong Staker + assert_noop!(Staking::payout_stakers(Origin::signed(1337), 10, 1), Error::::NotStash); + + for i in 3..100 { + Staking::reward_by_ids(vec![(11, 1)]); + // Compute total payout now for whole duration as other parameter won't change + let total_payout_0 = current_total_payout_for_duration(3 * 1000); + assert!(total_payout_0 > 100); // Test is meaningful if reward something + mock::start_era(i); + } + // We are at era 99, with history depth of 84 + // We should be able to payout era 15 through 98 (84 total eras), but not 14 or 99. + assert_noop!(Staking::payout_stakers(Origin::signed(1337), 11, 14), Error::::InvalidEraToReward); + assert_noop!(Staking::payout_stakers(Origin::signed(1337), 11, 99), Error::::InvalidEraToReward); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 15)); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 98)); + + // Can't claim again + assert_noop!(Staking::payout_stakers(Origin::signed(1337), 11, 15), Error::::AlreadyClaimed); + assert_noop!(Staking::payout_stakers(Origin::signed(1337), 11, 98), Error::::AlreadyClaimed); + }); +} + +#[test] +fn bond_during_era_correctly_populates_claimed_rewards() { + ExtBuilder::default().has_stakers(false).build().execute_with(|| { + // Era = None + bond_validator(9, 8, 1000); + assert_eq!( + Staking::ledger(&8), + Some(StakingLedger { + stash: 9, + total: 1000, + active: 1000, + unlocking: vec![], + claimed_rewards: vec![], + }) + ); + mock::start_era(5); + bond_validator(11, 10, 1000); + assert_eq!( + Staking::ledger(&10), + Some(StakingLedger { + stash: 11, + total: 1000, + active: 1000, + unlocking: vec![], + claimed_rewards: (0..5).collect(), + }) + ); + mock::start_era(99); + bond_validator(13, 12, 1000); + assert_eq!( + Staking::ledger(&12), + Some(StakingLedger { + stash: 13, + total: 1000, + active: 1000, + unlocking: vec![], + claimed_rewards: (15..99).collect(), + }) + ); + }); +} + +/* These migration tests below can be removed once migration code is removed */ + #[test] fn assert_migration_is_noop() { let kusama_active_era = "4a0200000190e2721171010000"; @@ -4124,3 +4270,452 @@ fn assert_migration_is_noop() { assert_eq!(era.index, 586); assert_eq!(era.start, Some(1585135674000)); } + +#[test] +fn test_last_reward_migration() { + use sp_storage::Storage; + + let mut s = Storage::default(); + + #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] + struct OldStakingLedger { + pub stash: AccountId, + #[codec(compact)] + pub total: Balance, + #[codec(compact)] + pub active: Balance, + pub unlocking: Vec>, + pub last_reward: Option, + } + + let old_staking10 = OldStakingLedger:: { + stash: 0, + total: 10, + active: 10, + unlocking: vec![UnlockChunk{ value: 1234, era: 56}], + last_reward: Some(8), + }; + + let old_staking11 = OldStakingLedger:: { + stash: 1, + total: 0, + active: 0, + unlocking: vec![], + last_reward: None, + }; + + let old_staking12 = OldStakingLedger:: { + stash: 2, + total: 100, + active: 100, + unlocking: vec![UnlockChunk{ value: 9876, era: 54}, UnlockChunk{ value: 98, era: 76}], + last_reward: Some(23), + }; + + let old_staking13 = OldStakingLedger:: { + stash: 3, + total: 100, + active: 100, + unlocking: vec![], + last_reward: Some(23), + }; + + let data = vec![ + ( + Ledger::::hashed_key_for(10), + old_staking10.encode().to_vec() + ), + ( + Ledger::::hashed_key_for(11), + old_staking11.encode().to_vec() + ), + ( + Ledger::::hashed_key_for(12), + old_staking12.encode().to_vec() + ), + ( + Ledger::::hashed_key_for(13), + old_staking13.encode().to_vec() + ), + ]; + + s.top = data.into_iter().collect(); + sp_io::TestExternalities::new(s).execute_with(|| { + HistoryDepth::put(84); + CurrentEra::put(99); + let nominations = Nominations:: { + targets: vec![], + submitted_in: 0, + suppressed: false + }; + Nominators::::insert(3, nominations); + Bonded::::insert(3, 13); + Staking::migrate_last_reward_to_claimed_rewards(); + // Test staker out of range + assert_eq!( + Ledger::::get(10), + Some(StakingLedger { + stash: 0, + total: 10, + active: 10, + unlocking: vec![UnlockChunk{ value: 1234, era: 56}], + claimed_rewards: vec![], + }) + ); + // Test staker none + assert_eq!( + Ledger::::get(11), + Some(StakingLedger { + stash: 1, + total: 0, + active: 0, + unlocking: vec![], + claimed_rewards: vec![], + }) + ); + // Test staker migration + assert_eq!( + Ledger::::get(12), + Some(StakingLedger { + stash: 2, + total: 100, + active: 100, + unlocking: vec![UnlockChunk{ value: 9876, era: 54}, UnlockChunk{ value: 98, era: 76}], + claimed_rewards: vec![15,16,17,18,19,20,21,22,23], + }) + ); + // Test nominator migration + assert_eq!( + Ledger::::get(13), + Some(StakingLedger { + stash: 3, + total: 100, + active: 100, + unlocking: vec![], + claimed_rewards: vec![15,16,17,18,19,20,21,22,23], + }) + ); + }); +} + +#[test] +fn rewards_should_work_before_migration() { + // should check that before migration: + // * rewards get recorded per session + // * rewards get paid per Era + // * Check that nominators are also rewarded + ExtBuilder::default().nominate(true).build().execute_with(|| { + MigrateEra::put(10); + let init_balance_10 = Balances::total_balance(&10); + let init_balance_11 = Balances::total_balance(&11); + let init_balance_20 = Balances::total_balance(&20); + let init_balance_21 = Balances::total_balance(&21); + let init_balance_100 = Balances::total_balance(&100); + let init_balance_101 = Balances::total_balance(&101); + + // Check state + Payee::::insert(11, RewardDestination::Controller); + Payee::::insert(21, RewardDestination::Controller); + Payee::::insert(101, RewardDestination::Controller); + + >::reward_by_ids(vec![(11, 50)]); + >::reward_by_ids(vec![(11, 50)]); + // This is the second validator of the current elected set. + >::reward_by_ids(vec![(21, 50)]); + + // Compute total payout now for whole duration as other parameter won't change + let total_payout_0 = current_total_payout_for_duration(3 * 1000); + assert!(total_payout_0 > 10); // Test is meaningful if reward something + + start_session(1); + + assert_eq!(Balances::total_balance(&10), init_balance_10); + assert_eq!(Balances::total_balance(&11), init_balance_11); + assert_eq!(Balances::total_balance(&20), init_balance_20); + assert_eq!(Balances::total_balance(&21), init_balance_21); + assert_eq!(Balances::total_balance(&100), init_balance_100); + assert_eq!(Balances::total_balance(&101), init_balance_101); + assert_eq_uvec!(Session::validators(), vec![11, 21]); + assert_eq!(Staking::eras_reward_points(Staking::active_era().unwrap().index), EraRewardPoints { + total: 50*3, + individual: vec![(11, 100), (21, 50)].into_iter().collect(), + }); + let part_for_10 = Perbill::from_rational_approximation::(1000, 1125); + let part_for_20 = Perbill::from_rational_approximation::(1000, 1375); + let part_for_100_from_10 = Perbill::from_rational_approximation::(125, 1125); + let part_for_100_from_20 = Perbill::from_rational_approximation::(375, 1375); + + start_session(2); + start_session(3); + + assert_eq!(Staking::active_era().unwrap().index, 1); + mock::make_all_reward_payment_before_migration(0); + + assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * total_payout_0*2/3, 2); + assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); + assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0*1/3, 2); + assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); + assert_eq_error_rate!( + Balances::total_balance(&100), + init_balance_100 + + part_for_100_from_10 * total_payout_0 * 2/3 + + part_for_100_from_20 * total_payout_0 * 1/3, + 2 + ); + assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); + + assert_eq_uvec!(Session::validators(), vec![11, 21]); + >::reward_by_ids(vec![(11, 1)]); + + // Compute total payout now for whole duration as other parameter won't change + let total_payout_1 = current_total_payout_for_duration(3 * 1000); + assert!(total_payout_1 > 10); // Test is meaningful if reward something + + mock::start_era(2); + mock::make_all_reward_payment_before_migration(1); + + assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * (total_payout_0 * 2/3 + total_payout_1), 2); + assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); + assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0 * 1/3, 2); + assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); + assert_eq_error_rate!( + Balances::total_balance(&100), + init_balance_100 + + part_for_100_from_10 * (total_payout_0 * 2/3 + total_payout_1) + + part_for_100_from_20 * total_payout_0 * 1/3, + 2 + ); + assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); + }); +} + +#[test] +fn migrate_era_should_work() { + // should check that before and after migration: + // * rewards get recorded per session + // * rewards get paid per Era + // * Check that nominators are also rewarded + ExtBuilder::default().nominate(true).build().execute_with(|| { + MigrateEra::put(1); + let init_balance_10 = Balances::total_balance(&10); + let init_balance_11 = Balances::total_balance(&11); + let init_balance_20 = Balances::total_balance(&20); + let init_balance_21 = Balances::total_balance(&21); + let init_balance_100 = Balances::total_balance(&100); + let init_balance_101 = Balances::total_balance(&101); + + // Check state + Payee::::insert(11, RewardDestination::Controller); + Payee::::insert(21, RewardDestination::Controller); + Payee::::insert(101, RewardDestination::Controller); + + >::reward_by_ids(vec![(11, 50)]); + >::reward_by_ids(vec![(11, 50)]); + // This is the second validator of the current elected set. + >::reward_by_ids(vec![(21, 50)]); + + // Compute total payout now for whole duration as other parameter won't change + let total_payout_0 = current_total_payout_for_duration(3 * 1000); + assert!(total_payout_0 > 10); // Test is meaningful if reward something + + start_session(1); + + assert_eq!(Balances::total_balance(&10), init_balance_10); + assert_eq!(Balances::total_balance(&11), init_balance_11); + assert_eq!(Balances::total_balance(&20), init_balance_20); + assert_eq!(Balances::total_balance(&21), init_balance_21); + assert_eq!(Balances::total_balance(&100), init_balance_100); + assert_eq!(Balances::total_balance(&101), init_balance_101); + assert_eq_uvec!(Session::validators(), vec![11, 21]); + assert_eq!(Staking::eras_reward_points(Staking::active_era().unwrap().index), EraRewardPoints { + total: 50*3, + individual: vec![(11, 100), (21, 50)].into_iter().collect(), + }); + let part_for_10 = Perbill::from_rational_approximation::(1000, 1125); + let part_for_20 = Perbill::from_rational_approximation::(1000, 1375); + let part_for_100_from_10 = Perbill::from_rational_approximation::(125, 1125); + let part_for_100_from_20 = Perbill::from_rational_approximation::(375, 1375); + + start_session(2); + start_session(3); + + assert_eq!(Staking::active_era().unwrap().index, 1); + mock::make_all_reward_payment_before_migration(0); + + assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * total_payout_0*2/3, 2); + assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); + assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0*1/3, 2); + assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); + assert_eq_error_rate!( + Balances::total_balance(&100), + init_balance_100 + + part_for_100_from_10 * total_payout_0 * 2/3 + + part_for_100_from_20 * total_payout_0 * 1/3, + 2 + ); + assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); + + assert_eq_uvec!(Session::validators(), vec![11, 21]); + >::reward_by_ids(vec![(11, 1)]); + + // Compute total payout now for whole duration as other parameter won't change + let total_payout_1 = current_total_payout_for_duration(3 * 1000); + assert!(total_payout_1 > 10); // Test is meaningful if reward something + + mock::start_era(2); + mock::make_all_reward_payment(1); + + assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * (total_payout_0 * 2/3 + total_payout_1), 2); + assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); + assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0 * 1/3, 2); + assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); + assert_eq_error_rate!( + Balances::total_balance(&100), + init_balance_100 + + part_for_100_from_10 * (total_payout_0 * 2/3 + total_payout_1) + + part_for_100_from_20 * total_payout_0 * 1/3, + 2 + ); + assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); + }); +} + +#[test] +#[should_panic] +fn migrate_era_should_handle_error() { + ExtBuilder::default().nominate(true).build().execute_with(|| { + MigrateEra::put(1); + let init_balance_10 = Balances::total_balance(&10); + let init_balance_11 = Balances::total_balance(&11); + let init_balance_20 = Balances::total_balance(&20); + let init_balance_21 = Balances::total_balance(&21); + let init_balance_100 = Balances::total_balance(&100); + let init_balance_101 = Balances::total_balance(&101); + + // Check state + Payee::::insert(11, RewardDestination::Controller); + Payee::::insert(21, RewardDestination::Controller); + Payee::::insert(101, RewardDestination::Controller); + + >::reward_by_ids(vec![(11, 50)]); + >::reward_by_ids(vec![(11, 50)]); + // This is the second validator of the current elected set. + >::reward_by_ids(vec![(21, 50)]); + + // Compute total payout now for whole duration as other parameter won't change + let total_payout_0 = current_total_payout_for_duration(3 * 1000); + assert!(total_payout_0 > 10); // Test is meaningful if reward something + + start_session(1); + + assert_eq!(Balances::total_balance(&10), init_balance_10); + assert_eq!(Balances::total_balance(&11), init_balance_11); + assert_eq!(Balances::total_balance(&20), init_balance_20); + assert_eq!(Balances::total_balance(&21), init_balance_21); + assert_eq!(Balances::total_balance(&100), init_balance_100); + assert_eq!(Balances::total_balance(&101), init_balance_101); + assert_eq_uvec!(Session::validators(), vec![11, 21]); + assert_eq!(Staking::eras_reward_points(Staking::active_era().unwrap().index), EraRewardPoints { + total: 50*3, + individual: vec![(11, 100), (21, 50)].into_iter().collect(), + }); + + start_session(2); + start_session(3); + + assert_eq!(Staking::active_era().unwrap().index, 1); + mock::make_all_reward_payment(0); + }); +} + +#[test] +#[should_panic] +fn migrate_era_should_handle_errors_2() { + // should check that before and after migration: + // * rewards get recorded per session + // * rewards get paid per Era + // * Check that nominators are also rewarded + ExtBuilder::default().nominate(true).build().execute_with(|| { + MigrateEra::put(1); + let init_balance_10 = Balances::total_balance(&10); + let init_balance_11 = Balances::total_balance(&11); + let init_balance_20 = Balances::total_balance(&20); + let init_balance_21 = Balances::total_balance(&21); + let init_balance_100 = Balances::total_balance(&100); + let init_balance_101 = Balances::total_balance(&101); + + // Check state + Payee::::insert(11, RewardDestination::Controller); + Payee::::insert(21, RewardDestination::Controller); + Payee::::insert(101, RewardDestination::Controller); + + >::reward_by_ids(vec![(11, 50)]); + >::reward_by_ids(vec![(11, 50)]); + // This is the second validator of the current elected set. + >::reward_by_ids(vec![(21, 50)]); + + // Compute total payout now for whole duration as other parameter won't change + let total_payout_0 = current_total_payout_for_duration(3 * 1000); + assert!(total_payout_0 > 10); // Test is meaningful if reward something + + start_session(1); + + assert_eq!(Balances::total_balance(&10), init_balance_10); + assert_eq!(Balances::total_balance(&11), init_balance_11); + assert_eq!(Balances::total_balance(&20), init_balance_20); + assert_eq!(Balances::total_balance(&21), init_balance_21); + assert_eq!(Balances::total_balance(&100), init_balance_100); + assert_eq!(Balances::total_balance(&101), init_balance_101); + assert_eq_uvec!(Session::validators(), vec![11, 21]); + assert_eq!(Staking::eras_reward_points(Staking::active_era().unwrap().index), EraRewardPoints { + total: 50*3, + individual: vec![(11, 100), (21, 50)].into_iter().collect(), + }); + let part_for_10 = Perbill::from_rational_approximation::(1000, 1125); + let part_for_20 = Perbill::from_rational_approximation::(1000, 1375); + let part_for_100_from_10 = Perbill::from_rational_approximation::(125, 1125); + let part_for_100_from_20 = Perbill::from_rational_approximation::(375, 1375); + + start_session(2); + start_session(3); + + assert_eq!(Staking::active_era().unwrap().index, 1); + mock::make_all_reward_payment_before_migration(0); + + assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * total_payout_0*2/3, 2); + assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); + assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0*1/3, 2); + assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); + assert_eq_error_rate!( + Balances::total_balance(&100), + init_balance_100 + + part_for_100_from_10 * total_payout_0 * 2/3 + + part_for_100_from_20 * total_payout_0 * 1/3, + 2 + ); + assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); + + assert_eq_uvec!(Session::validators(), vec![11, 21]); + >::reward_by_ids(vec![(11, 1)]); + + // Compute total payout now for whole duration as other parameter won't change + let total_payout_1 = current_total_payout_for_duration(3 * 1000); + assert!(total_payout_1 > 10); // Test is meaningful if reward something + + mock::start_era(2); + mock::make_all_reward_payment_before_migration(1); + + assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * (total_payout_0 * 2/3 + total_payout_1), 2); + assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); + assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0 * 1/3, 2); + assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); + assert_eq_error_rate!( + Balances::total_balance(&100), + init_balance_100 + + part_for_100_from_10 * (total_payout_0 * 2/3 + total_payout_1) + + part_for_100_from_20 * total_payout_0 * 1/3, + 2 + ); + assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); + }); +} -- GitLab From 8991aab9d98da49e3a7e608cb0a0162b610e25c7 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Sat, 4 Apr 2020 15:13:35 +0200 Subject: [PATCH 162/300] Additional Metrics collected and exposed via prometheus (#5414) This PR refactors the metrics measuring and Prometheus exposing entity in sc-service into its own submodule and extends the parameters it exposes by: - system load average (over one, five and 15min) - the TCP connection state of the process (lsof), refs #5304 - number of tokio threads - number of known forks - counter for items in each unbounded queue (with internal unbounded channels) - number of file descriptors opened by this process (*nix only at this point) - number of system threads (*nix only at this point) refs #4679 Co-authored-by: Max Inden Co-authored-by: Ashley --- Cargo.lock | 601 +++++++++++------- Cargo.toml | 1 + client/Cargo.toml | 1 + client/api/Cargo.toml | 2 + client/api/src/client.rs | 6 +- client/api/src/notifications.rs | 8 +- client/authority-discovery/src/tests.rs | 1 + client/cli/Cargo.toml | 1 + client/cli/src/runtime.rs | 8 + client/db/src/lib.rs | 1 + client/db/src/light.rs | 1 + client/finality-grandpa/Cargo.toml | 1 + .../src/communication/gossip.rs | 8 +- .../finality-grandpa/src/communication/mod.rs | 3 +- .../src/communication/periodic.rs | 10 +- .../src/communication/tests.rs | 12 +- client/finality-grandpa/src/import.rs | 6 +- client/finality-grandpa/src/lib.rs | 12 +- client/finality-grandpa/src/observer.rs | 11 +- client/finality-grandpa/src/tests.rs | 6 +- client/finality-grandpa/src/until_imported.rs | 16 +- client/network-gossip/Cargo.toml | 1 + client/network-gossip/src/bridge.rs | 5 +- client/network-gossip/src/state_machine.rs | 8 +- client/network/Cargo.toml | 1 + client/network/src/on_demand_layer.rs | 15 +- client/network/src/service.rs | 17 +- client/offchain/Cargo.toml | 1 + client/offchain/src/api/http.rs | 13 +- client/peerset/Cargo.toml | 1 + client/peerset/src/lib.rs | 11 +- client/rpc/Cargo.toml | 1 + client/rpc/src/system/mod.rs | 7 +- client/service/Cargo.toml | 9 + client/service/src/builder.rs | 176 +---- client/service/src/lib.rs | 23 +- client/service/src/metrics.rs | 428 +++++++++++++ client/service/src/status_sinks.rs | 9 +- client/service/src/task_manager.rs | 11 +- client/src/client.rs | 10 +- client/src/in_mem.rs | 1 + client/src/leaves.rs | 5 + client/transaction-pool/Cargo.toml | 1 + client/transaction-pool/graph/Cargo.toml | 1 + client/transaction-pool/graph/src/pool.rs | 8 +- .../graph/src/validated_pool.rs | 6 +- client/transaction-pool/graph/src/watcher.rs | 12 +- client/transaction-pool/src/revalidation.rs | 9 +- primitives/blockchain/src/backend.rs | 2 + primitives/consensus/common/Cargo.toml | 1 + .../common/src/import_queue/basic_queue.rs | 9 +- .../common/src/import_queue/buffered_link.rs | 9 +- primitives/transaction-pool/Cargo.toml | 1 + primitives/transaction-pool/src/pool.rs | 8 +- primitives/utils/Cargo.toml | 19 + primitives/utils/src/lib.rs | 20 + primitives/utils/src/metrics.rs | 58 ++ primitives/utils/src/mpsc.rs | 232 +++++++ utils/prometheus/Cargo.toml | 2 +- utils/prometheus/src/lib.rs | 1 + 60 files changed, 1343 insertions(+), 525 deletions(-) create mode 100644 client/service/src/metrics.rs create mode 100644 primitives/utils/Cargo.toml create mode 100644 primitives/utils/src/lib.rs create mode 100644 primitives/utils/src/metrics.rs create mode 100644 primitives/utils/src/mpsc.rs diff --git a/Cargo.lock b/Cargo.lock index eedb622227..6038064ab0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,13 +70,14 @@ dependencies = [ [[package]] name = "alga" -version = "0.9.3" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2" +checksum = "658f9468113d34781f6ca9d014d174c74b73de870f1e0e3ad32079bbab253b19" dependencies = [ "approx", + "libm", "num-complex", - "num-traits", + "num-traits 0.2.11", ] [[package]] @@ -99,9 +100,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.28" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff" +checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" [[package]] name = "app_dirs" @@ -121,7 +122,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" dependencies = [ - "num-traits", + "num-traits 0.2.11", ] [[package]] @@ -132,9 +133,9 @@ checksum = "75153c95fdedd7db9732dfbfc3702324a1627eec91ba56e37cd0ac78314ab2ed" [[package]] name = "arc-swap" -version = "0.4.5" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d663a8e9a99154b5fb793032533f6328da35e23aac63d5c152279aa8ba356825" +checksum = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" [[package]] name = "arrayref" @@ -172,8 +173,8 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" dependencies = [ - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -268,9 +269,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.46" +version = "0.3.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e692897359247cc6bb902933361652380af0f1b7651ae5c5013407f30e109e" +checksum = "ad235dabf00f36301792cfe82499880ba54c6486be094d1047b02bacb67c14e8" dependencies = [ "backtrace-sys", "cfg-if", @@ -280,9 +281,9 @@ dependencies = [ [[package]] name = "backtrace-sys" -version = "0.1.35" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8aba10a69c8e8d7622c5710229485ec32e9d55fdad160ea559c086fdcd118" +checksum = "ca797db0057bae1a7aa2eef3283a874695455cecf08a43bfb8507ee0ebc1ed69" dependencies = [ "cc", "libc", @@ -336,7 +337,7 @@ dependencies = [ "log", "peeking_take_while", "proc-macro2", - "quote", + "quote 1.0.3", "regex", "rustc-hash", "shlex", @@ -450,9 +451,9 @@ checksum = "b170cd256a3f9fa6b9edae3e44a7dfdfc77e8124dbc3e2612d75f9c3e2396dae" [[package]] name = "bstr" -version = "0.2.12" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2889e6d50f394968c8bf4240dc3f2a7eb4680844d27308f798229ac9d4725f41" +checksum = "502ae1441a0a5adb8fbd38a5955a6416b9493e92b465de5e4a9bde6a539c2c48" dependencies = [ "lazy_static", "memchr", @@ -596,16 +597,16 @@ checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" dependencies = [ "js-sys", "num-integer", - "num-traits", + "num-traits 0.2.11", "time", "wasm-bindgen", ] [[package]] name = "clang-sys" -version = "0.29.3" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a" +checksum = "f92986241798376849e1a007827041fed9bb36195822c2049d18e174420e0534" dependencies = [ "glob 0.3.0", "libc", @@ -830,7 +831,7 @@ dependencies = [ "itertools", "lazy_static", "libc", - "num-traits", + "num-traits 0.2.11", "rand_core 0.3.1", "rand_os", "rand_xoshiro", @@ -856,7 +857,7 @@ dependencies = [ "csv", "itertools", "lazy_static", - "num-traits", + "num-traits 0.2.11", "oorandom", "plotters", "rayon", @@ -999,8 +1000,8 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47c5e5ac752e18207b12e16b10631ae5f7f68f8805f335f9b817ead83d9ffce1" dependencies = [ - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -1044,13 +1045,13 @@ checksum = "11c0346158a19b3627234e15596f5e465c360fcdb97d817bcb255e0510f5a788" [[package]] name = "derive_more" -version = "0.99.5" +version = "0.99.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2323f3f47db9a0e77ce7a300605d8d2098597fc451ed1a97bb1f6411bb550a7" +checksum = "a806e96c59a76a5ba6e18735b6cf833344671e61e7863f2edb5c518ea2cac95c" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -1102,9 +1103,9 @@ dependencies = [ [[package]] name = "doc-comment" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +checksum = "807e5847c39ad6a11eac66de492ed1406f76a260eb8656e8740cad9eabc69c27" [[package]] name = "ed25519-dalek" @@ -1124,6 +1125,17 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" +[[package]] +name = "enum-primitive-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2b90e520ec62c1864c8c78d637acbfe8baf5f63240f2fb8165b8325c07812dd" +dependencies = [ + "num-traits 0.1.43", + "quote 0.3.15", + "syn 0.11.11", +] + [[package]] name = "enumflags2" version = "0.6.2" @@ -1140,8 +1152,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecf634c5213044b8d54a46dd282cf5dd1f86bb5cb53e92c409cb4680a7fb9894" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -1178,18 +1190,18 @@ checksum = "516aa8d7a71cb00a1c4146f0798549b93d083d4f189b3ced8f3de6b8f11ee6c4" [[package]] name = "erased-serde" -version = "0.3.11" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d88b6d1705e16a4d62e05ea61cc0496c2bd190f4fa8e5c1f11ce747be6bcf3d1" +checksum = "cd7d80305c9bd8cd78e3c753eb9fb110f83621e5211f1a3afffcc812b104daf9" dependencies = [ "serde", ] [[package]] name = "errno" -version = "0.2.5" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b480f641ccf0faf324e20c1d3e53d81b7484c698b42ea677f6907ae4db195371" +checksum = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" dependencies = [ "errno-dragonfly", "libc", @@ -1321,8 +1333,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", "synstructure", ] @@ -1366,7 +1378,7 @@ dependencies = [ "futures 0.3.4", "futures-timer 2.0.2", "log", - "num-traits", + "num-traits 0.2.11", "parity-scale-codec", "parking_lot 0.9.0", "rand 0.6.5", @@ -1392,9 +1404,9 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" -version = "1.0.14" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" +checksum = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" dependencies = [ "cfg-if", "crc32fast", @@ -1509,8 +1521,8 @@ version = "2.0.0-alpha.5" dependencies = [ "frame-support-procedural-tools", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -1520,8 +1532,8 @@ dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -1529,8 +1541,8 @@ name = "frame-support-procedural-tools-derive" version = "2.0.0-alpha.5" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -1729,8 +1741,8 @@ checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" dependencies = [ "proc-macro-hack", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -1883,9 +1895,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "globset" -version = "0.4.5" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120" +checksum = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" dependencies = [ "aho-corasick", "bstr", @@ -1938,16 +1950,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.2.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "377038bf3c89d18d6ca1431e7a5027194fbd724ca10592b9487ede5e8e144f42" +checksum = "9d5c295d1c0c68e4e42003d75f908f5e16a1edd1cbe0b0d02e4dc2006a384f47" dependencies = [ "bytes 0.5.4", "fnv", "futures-core", "futures-sink", "futures-util", - "http 0.2.1", + "http 0.2.0", "indexmap", "log", "slab", @@ -1991,9 +2003,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.10" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e" +checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8" dependencies = [ "libc", ] @@ -2068,9 +2080,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" +checksum = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" dependencies = [ "bytes 0.5.4", "fnv", @@ -2096,7 +2108,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" dependencies = [ "bytes 0.5.4", - "http 0.2.1", + "http 0.2.0", ] [[package]] @@ -2146,16 +2158,16 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.4" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6081100e960d9d74734659ffc9cc91daf1c0fc7aceb8eaa94ee1a3f5046f2e" +checksum = "e7b15203263d1faa615f9337d79c1d37959439dc46c2b4faab33286fadc2a1c5" dependencies = [ "bytes 0.5.4", "futures-channel", "futures-core", "futures-util", - "h2 0.2.4", - "http 0.2.1", + "h2 0.2.2", + "http 0.2.0", "http-body 0.3.1", "httparse", "itoa", @@ -2177,7 +2189,7 @@ dependencies = [ "bytes 0.5.4", "ct-logs", "futures-util", - "hyper 0.13.4", + "hyper 0.13.3", "log", "rustls 0.17.0", "rustls-native-certs", @@ -2251,8 +2263,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -2297,9 +2309,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" +checksum = "a859057dc563d1388c1e816f98a1892629075fc046ed06e845b883bb8b2916fb" [[package]] name = "itertools" @@ -2327,9 +2339,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.37" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055" +checksum = "1cb931d43e71f560c81badb0191596562bafad2be06a3f9025b845c847c60df5" dependencies = [ "wasm-bindgen", ] @@ -2381,8 +2393,8 @@ checksum = "8609af8f63b626e8e211f52441fcdb6ec54f1a446606b10d5c89ae9bf8a20058" dependencies = [ "proc-macro-crate", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -2555,9 +2567,21 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" [[package]] name = "libc" -version = "0.2.68" +version = "0.2.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" + +[[package]] +name = "libflate" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" +checksum = "d9135df43b1f5d0e333385cb6e7897ecd1a43d7d11b91ac003f4d2c2d2401fdd" +dependencies = [ + "adler32", + "crc32fast", + "rle-decode-fast", + "take_mut", +] [[package]] name = "libloading" @@ -2571,9 +2595,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.1" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" +checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" [[package]] name = "libp2p" @@ -2652,8 +2676,8 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d472e9d522f588805c77801de10b957be84e10f019ca5f869fa1825b15ea9b" dependencies = [ - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -3138,11 +3162,11 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.5.4" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" +checksum = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" dependencies = [ - "autocfg 1.0.0", + "rustc_version", ] [[package]] @@ -3246,9 +3270,9 @@ checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" [[package]] name = "multimap" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8883adfde9756c1d30b0f519c9b8c502a94b41ac62f696453c37c7fc0a958ce" +checksum = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc" [[package]] name = "multistream-select" @@ -3276,7 +3300,7 @@ dependencies = [ "matrixmultiply", "num-complex", "num-rational", - "num-traits", + "num-traits 0.2.11", "rand 0.6.5", "typenum", ] @@ -3301,6 +3325,20 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "netstat2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29449d242064c48d3057a194b049a2bdcccadda16faa18a91468677b44e8d422" +dependencies = [ + "bitflags", + "byteorder 1.3.4", + "enum-primitive-derive", + "libc", + "num-traits 0.2.11", + "thiserror", +] + [[package]] name = "nix" version = "0.17.0" @@ -3725,7 +3763,7 @@ checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ "autocfg 1.0.0", "num-integer", - "num-traits", + "num-traits 0.2.11", ] [[package]] @@ -3735,7 +3773,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" dependencies = [ "autocfg 1.0.0", - "num-traits", + "num-traits 0.2.11", ] [[package]] @@ -3745,19 +3783,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" dependencies = [ "autocfg 1.0.0", - "num-traits", + "num-traits 0.2.11", ] [[package]] name = "num-rational" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +checksum = "da4dc79f9e6c81bef96148c8f6b8e72ad4541caa4a24373e900a36da07de03a3" dependencies = [ "autocfg 1.0.0", "num-bigint", "num-integer", - "num-traits", + "num-traits 0.2.11", +] + +[[package]] +name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +dependencies = [ + "num-traits 0.2.11", ] [[package]] @@ -3767,7 +3814,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" dependencies = [ "autocfg 1.0.0", - "libm", ] [[package]] @@ -4448,9 +4494,9 @@ version = "2.0.0-alpha.5" dependencies = [ "proc-macro-crate", "proc-macro2", - "quote", + "quote 1.0.3", "sp-runtime", - "syn", + "syn 1.0.16", ] [[package]] @@ -4647,8 +4693,8 @@ checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245" dependencies = [ "proc-macro-crate", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -4682,7 +4728,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ "proc-macro2", - "syn", + "syn 1.0.16", "synstructure", ] @@ -4753,9 +4799,9 @@ dependencies = [ [[package]] name = "paste" -version = "0.1.9" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092d791bf7847f70bbd49085489fba25fc2c193571752bff9e36e74e72403932" +checksum = "63e1afe738d71b1ebab5f1207c055054015427dbfc7bbe9ee1266894156ec046" dependencies = [ "paste-impl", "proc-macro-hack", @@ -4763,14 +4809,14 @@ dependencies = [ [[package]] name = "paste-impl" -version = "0.1.9" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406c23fb4c45cc6f68a9bbabb8ec7bd6f8cfcbd17e9e8f72c2460282f8325729" +checksum = "6d4dc4a7f6f743211c5aab239640a65091535d97d43d92a52bca435a640892bb" dependencies = [ "proc-macro-hack", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -4833,8 +4879,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -4868,7 +4914,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e3bb8da247d27ae212529352020f3e5ee16e83c0c258061d27b08ab92675eeb" dependencies = [ "js-sys", - "num-traits", + "num-traits 0.2.11", "wasm-bindgen", "web-sys", ] @@ -4941,63 +4987,83 @@ dependencies = [ [[package]] name = "proc-macro-error" -version = "0.4.12" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7" +checksum = "e7959c6467d962050d639361f7703b2051c43036d03493c36f01d440fdd3138a" dependencies = [ "proc-macro-error-attr", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", "version_check", ] [[package]] name = "proc-macro-error-attr" -version = "0.4.12" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de" +checksum = "e4002d9f55991d5e019fb940a90e1a95eb80c24e77cb2462dd4dc869604d543a" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", "syn-mid", "version_check", ] [[package]] name = "proc-macro-hack" -version = "0.5.15" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" +checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" +dependencies = [ + "proc-macro2", + "quote 1.0.3", + "syn 1.0.16", +] [[package]] name = "proc-macro-nested" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" +checksum = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" [[package]] name = "proc-macro2" -version = "1.0.10" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" +checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" dependencies = [ - "unicode-xid", + "unicode-xid 0.2.0", +] + +[[package]] +name = "procfs" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe50036aa1b71e553a4a0c48ab7baabf8aa8c7a5a61aae06bf38c2eab7430475" +dependencies = [ + "bitflags", + "byteorder 1.3.4", + "chrono", + "hex", + "lazy_static", + "libc", + "libflate", ] [[package]] name = "prometheus" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5567486d5778e2c6455b1b90ff1c558f29e751fc018130fa182e15828e728af1" +checksum = "b0575e258dab62268e7236d7307caa38848acbda7ec7ab87bd9093791e999d20" dependencies = [ "cfg-if", "fnv", "lazy_static", "protobuf", - "quick-error", "spin", + "thiserror", ] [[package]] @@ -5037,8 +5103,8 @@ dependencies = [ "anyhow", "itertools", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -5053,9 +5119,9 @@ dependencies = [ [[package]] name = "protobuf" -version = "2.12.0" +version = "2.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71964f34fd51cf04882d7ae3325fa0794d4cad66a03d0003f38d8ae4f63ba126" +checksum = "37a5325d019a4d837d3abde0a836920f959e33d350f77b5f1e289e061e774942" [[package]] name = "pwasm-utils" @@ -5097,6 +5163,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" + [[package]] name = "quote" version = "1.0.3" @@ -5375,9 +5447,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.3.6" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3" +checksum = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" dependencies = [ "aho-corasick", "memchr", @@ -5396,9 +5468,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.17" +version = "0.6.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" +checksum = "1132f845907680735a84409c3bebc64d1364a5683ffbce899550cd09d5eaefc1" [[package]] name = "region" @@ -5423,9 +5495,9 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.12" +version = "0.16.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba5a8ec64ee89a76c98c549af81ff14813df09c3e6dc4766c3856da48597a0c" +checksum = "741ba1704ae21999c00942f9f5944f801e977f54302af346b596287599ad1862" dependencies = [ "cc", "lazy_static", @@ -5436,11 +5508,17 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "rle-decode-fast" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" + [[package]] name = "rlp" -version = "0.4.5" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a7d3f9bed94764eac15b8f14af59fac420c236adaff743b7bcc88e265cb4345" +checksum = "3a44d5ae8afcb238af8b75640907edc6c931efcfab2c854e81ed35fa080f84cd" dependencies = [ "rustc-hex", ] @@ -5549,8 +5627,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -5566,9 +5644,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76" +checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" [[package]] name = "safe-mix" @@ -5699,8 +5777,8 @@ version = "2.0.0-alpha.5" dependencies = [ "proc-macro-crate", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -5736,6 +5814,7 @@ dependencies = [ "sp-panic-handler", "sp-runtime", "sp-state-machine", + "sp-utils", "structopt", "substrate-prometheus-endpoint", "tempfile", @@ -5774,6 +5853,7 @@ dependencies = [ "sp-state-machine", "sp-std", "sp-trie", + "sp-utils", "sp-version", "substrate-prometheus-endpoint", "substrate-test-runtime-client", @@ -5791,6 +5871,7 @@ dependencies = [ "hash-db", "hex-literal", "kvdb", + "lazy_static", "log", "parity-scale-codec", "parking_lot 0.10.0", @@ -5810,6 +5891,7 @@ dependencies = [ "sp-test-primitives", "sp-transaction-pool", "sp-trie", + "sp-utils", "sp-version", ] @@ -5896,7 +5978,7 @@ dependencies = [ "merlin", "num-bigint", "num-rational", - "num-traits", + "num-traits 0.2.11", "parity-scale-codec", "parking_lot 0.10.0", "pdqselect", @@ -6170,6 +6252,7 @@ dependencies = [ "sp-keyring", "sp-runtime", "sp-state-machine", + "sp-utils", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", @@ -6255,6 +6338,7 @@ dependencies = [ "sp-keyring", "sp-runtime", "sp-test-primitives", + "sp-utils", "substrate-prometheus-endpoint", "substrate-test-runtime", "substrate-test-runtime-client", @@ -6277,6 +6361,7 @@ dependencies = [ "lru", "sc-network", "sp-runtime", + "sp-utils", "substrate-test-runtime-client", "wasm-timer", ] @@ -6316,7 +6401,7 @@ dependencies = [ "fnv", "futures 0.3.4", "futures-timer 3.0.2", - "hyper 0.13.4", + "hyper 0.13.3", "hyper-rustls", "log", "num_cpus", @@ -6333,6 +6418,7 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-transaction-pool", + "sp-utils", "substrate-test-runtime-client", "threadpool", "tokio 0.2.13", @@ -6347,6 +6433,7 @@ dependencies = [ "log", "rand 0.7.3", "serde_json", + "sp-utils", "wasm-timer", ] @@ -6382,6 +6469,7 @@ dependencies = [ "sp-session", "sp-state-machine", "sp-transaction-pool", + "sp-utils", "sp-version", "substrate-test-runtime-client", "tokio 0.1.22", @@ -6448,10 +6536,12 @@ dependencies = [ "futures-timer 3.0.2", "lazy_static", "log", + "netstat2", "parity-multiaddr", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.0", + "procfs", "sc-chain-spec", "sc-client", "sc-client-api", @@ -6480,6 +6570,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-transaction-pool", + "sp-utils", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "sysinfo", @@ -6576,6 +6667,7 @@ dependencies = [ "sp-core", "sp-runtime", "sp-transaction-pool", + "sp-utils", "substrate-test-runtime", "wasm-timer", ] @@ -6602,6 +6694,7 @@ dependencies = [ "sp-keyring", "sp-runtime", "sp-transaction-pool", + "sp-utils", "substrate-test-runtime-client", "substrate-test-runtime-transaction-pool", "wasm-timer", @@ -6609,9 +6702,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.18" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "039c25b130bd8c1321ee2d7de7fde2659fa9c2744e4bb29711cfc852ea53cd19" +checksum = "507a9e6e8ffe0a4e0ebb9a10293e62fdf7657c06f1b8bb07a8fcf697d2abf295" dependencies = [ "lazy_static", "winapi 0.3.8", @@ -6663,8 +6756,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8584eea9b9ff42825b46faf46a8c24d2cff13ec152fa2a50df788b87c07ee28" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -6679,22 +6772,21 @@ dependencies = [ [[package]] name = "security-framework" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572dfa3a0785509e7a44b5b4bebcf94d41ba34e9ed9eb9df722545c3b3c4144a" +checksum = "97bbedbe81904398b6ebb054b3e912f99d55807125790f3198ac990d98def5b0" dependencies = [ "bitflags", "core-foundation", "core-foundation-sys", - "libc", "security-framework-sys", ] [[package]] name = "security-framework-sys" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb15a5fec93b7021b8a9e96009c5d8d51c15673569f7c0f6b7204e5b7b404f" +checksum = "06fd2f23e31ef68dd2328cc383bd493142e46107a3a0e24f7d734e3f3b80fe4c" dependencies = [ "core-foundation-sys", "libc", @@ -6759,15 +6851,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] name = "serde_json" -version = "1.0.50" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78a7a12c167809363ec3bd7329fc0a3369056996de43c4b37ef3cd54a6ce4867" +checksum = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25" dependencies = [ "itoa", "ryu", @@ -6889,8 +6981,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a945ec7f7ce853e89ffa36be1e27dce9a43e82ff9093bf3461c30d5da74ed11b" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -6936,7 +7028,7 @@ dependencies = [ "bytes 0.5.4", "flate2", "futures 0.3.4", - "http 0.2.1", + "http 0.2.0", "httparse", "log", "rand 0.7.3", @@ -6979,8 +7071,8 @@ dependencies = [ "blake2-rfc", "proc-macro-crate", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -7030,7 +7122,7 @@ version = "2.0.0-alpha.5" dependencies = [ "criterion 0.3.1", "integer-sqrt", - "num-traits", + "num-traits 0.2.11", "parity-scale-codec", "primitive-types", "rand 0.7.3", @@ -7045,7 +7137,7 @@ version = "2.0.0-alpha.5" dependencies = [ "honggfuzz", "num-bigint", - "num-traits", + "num-traits 0.2.11", "primitive-types", "sp-arithmetic", ] @@ -7116,6 +7208,7 @@ dependencies = [ "sp-state-machine", "sp-std", "sp-test-primitives", + "sp-utils", "sp-version", ] @@ -7187,7 +7280,7 @@ dependencies = [ "lazy_static", "libsecp256k1", "log", - "num-traits", + "num-traits 0.2.11", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.0", @@ -7218,8 +7311,8 @@ name = "sp-debug-derive" version = "2.0.0-alpha.5" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -7326,8 +7419,8 @@ version = "2.0.0-dev" dependencies = [ "proc-macro-crate", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -7386,8 +7479,8 @@ dependencies = [ "Inflector", "proc-macro-crate", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -7473,7 +7566,7 @@ dependencies = [ "hash-db", "hex-literal", "log", - "num-traits", + "num-traits 0.2.11", "parity-scale-codec", "parking_lot 0.10.0", "rand 0.7.3", @@ -7536,6 +7629,7 @@ dependencies = [ "serde", "sp-api", "sp-runtime", + "sp-utils", ] [[package]] @@ -7556,6 +7650,16 @@ dependencies = [ "trie-standardmap", ] +[[package]] +name = "sp-utils" +version = "2.0.0-alpha.5" +dependencies = [ + "futures 0.3.4", + "futures-core", + "lazy_static", + "prometheus", +] + [[package]] name = "sp-version" version = "2.0.0-alpha.5" @@ -7639,9 +7743,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.12" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8faa2719539bbe9d77869bfb15d4ee769f99525e707931452c97b693b3f159d" +checksum = "3fe43617218c0805c6eb37160119dc3c548110a67786da7218d1c6555212f073" dependencies = [ "clap", "lazy_static", @@ -7650,15 +7754,15 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.5" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f88b8e18c69496aad6f9ddf4630dd7d585bcaf765786cb415b9aec2fe5a0430" +checksum = "c6e79c80e0f4efd86ca960218d4e056249be189ff1c42824dcd9a7f51a56f0bd" dependencies = [ "heck", "proc-macro-error", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -7678,8 +7782,8 @@ checksum = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81" dependencies = [ "heck", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -7798,7 +7902,7 @@ dependencies = [ "async-std", "derive_more", "futures-util", - "hyper 0.13.4", + "hyper 0.13.3", "log", "prometheus", "tokio 0.2.13", @@ -8003,13 +8107,24 @@ checksum = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" [[package]] name = "syn" -version = "1.0.17" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" +checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +dependencies = [ + "quote 0.3.15", + "synom", + "unicode-xid 0.0.4", +] + +[[package]] +name = "syn" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" dependencies = [ "proc-macro2", - "quote", - "unicode-xid", + "quote 1.0.3", + "unicode-xid 0.2.0", ] [[package]] @@ -8019,8 +8134,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", +] + +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +dependencies = [ + "unicode-xid 0.0.4", ] [[package]] @@ -8030,9 +8154,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ "proc-macro2", - "quote", - "syn", - "unicode-xid", + "quote 1.0.3", + "syn 1.0.16", + "unicode-xid 0.2.0", ] [[package]] @@ -8099,8 +8223,8 @@ checksum = "a605baa797821796a751f4a959e1206079b24a4b7e1ed302b7d785d81a9276c9" dependencies = [ "lazy_static", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", "version_check", ] @@ -8115,22 +8239,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.14" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0570dc61221295909abdb95c739f2e74325e14293b2026b0a7e195091ec54ae" +checksum = "ee14bf8e6767ab4c687c9e8bc003879e042a96fd67a3ba5934eadb6536bef4db" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.14" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "227362df41d566be41a28f64401e07a043157c21c14b9785a0d8e256f940a8fd" +checksum = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -8164,9 +8288,9 @@ dependencies = [ [[package]] name = "tiny-bip39" -version = "0.7.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" +checksum = "a6848cd8f566953ce1e8faeba12ee23cbdbb0437754792cd857d44628b5685e3" dependencies = [ "failure", "hmac", @@ -8238,7 +8362,6 @@ checksum = "0fa5e81d6bc4e67fe889d5783bd2a128ab2e0cfa487e0be16b6a8d177b101616" dependencies = [ "bytes 0.5.4", "fnv", - "futures-core", "iovec", "lazy_static", "libc", @@ -8335,8 +8458,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -8469,9 +8592,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.3.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" +checksum = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" dependencies = [ "bytes 0.5.4", "futures-core", @@ -8513,8 +8636,8 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fbad39da2f9af1cae3016339ad7f2c7a9e870f12e8fd04c4fd7ef35b30c0d2b" dependencies = [ - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", ] [[package]] @@ -8677,6 +8800,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" + [[package]] name = "unicode-xid" version = "0.2.0" @@ -8777,9 +8906,9 @@ dependencies = [ [[package]] name = "wabt-sys" -version = "0.7.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7043ebb3e5d96fad7a8d3ca22ee9880748ff8c3e18092cfb2a49d3b8f9084" +checksum = "af5d153dc96aad7dc13ab90835b892c69867948112d95299e522d370c4e13a08" dependencies = [ "cc", "cmake", @@ -8835,9 +8964,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" -version = "0.2.60" +version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f" +checksum = "3557c397ab5a8e347d434782bcd31fc1483d927a6826804cec05cc792ee2519d" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -8845,24 +8974,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.60" +version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd" +checksum = "e0da9c9a19850d3af6df1cb9574970b566d617ecfaf36eb0b706b6f3ef9bd2f8" dependencies = [ "bumpalo", "lazy_static", "log", "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7add542ea1ac7fdaa9dc25e031a6af33b7d63376292bd24140c637d00d1c312a" +checksum = "457414a91863c0ec00090dba537f88ab955d93ca6555862c29b6d860990b8a8a" dependencies = [ "cfg-if", "js-sys", @@ -8872,32 +9001,32 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.60" +version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4" +checksum = "0f6fde1d36e75a714b5fe0cffbb78978f222ea6baebb726af13c78869fdb4205" dependencies = [ - "quote", + "quote 1.0.3", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.60" +version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931" +checksum = "25bda4168030a6412ea8a047e27238cadf56f0e53516e1e83fec0a8b7c786f6d" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.60" +version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639" +checksum = "fc9f36ad51f25b0219a3d4d13b90eb44cd075dff8b6280cca015775d7acaddd8" [[package]] name = "wasm-gc-api" @@ -8936,7 +9065,7 @@ dependencies = [ "libc", "memory_units", "num-rational", - "num-traits", + "num-traits 0.2.11", "parity-wasm 0.41.0", "wasmi-validation", ] @@ -9019,27 +9148,27 @@ dependencies = [ [[package]] name = "wast" -version = "12.0.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0615ba420811bcda39cf80e8a1bd75997aec09222bda35165920a07ef15cc695" +checksum = "4efb62ecebf5cc9dbf2954309a20d816289c6550c0597a138b9e811cefc05007" dependencies = [ "leb128", ] [[package]] name = "wat" -version = "1.0.13" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "095f615fbfcae695e3a4cea7d9f02f70561c81274c0142f45a12bf1e154d08bd" +checksum = "ffdea5e25273cc3a62f3ae3a1a4c7d7996625875b50c0b4475fee6698c2b069c" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.37" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6f51648d8c56c366144378a33290049eafdd784071077f6fe37dae64c1c4cb" +checksum = "721c6263e2c66fd44501cc5efbfa2b7dfa775d13e4ea38c46299646ed1f9c70a" dependencies = [ "js-sys", "wasm-bindgen", @@ -9112,9 +9241,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa515c5163a99cc82bab70fd3bfdd36d827be85de63737b40fcef2ce084a436e" +checksum = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" dependencies = [ "winapi 0.3.8", ] @@ -9200,8 +9329,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.16", "synstructure", ] diff --git a/Cargo.toml b/Cargo.toml index 4fb7b58a43..b582907385 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -157,6 +157,7 @@ members = [ "primitives/test-primitives", "primitives/transaction-pool", "primitives/trie", + "primitives/utils", "primitives/wasm-interface", "test-utils/client", "test-utils/runtime", diff --git a/client/Cargo.toml b/client/Cargo.toml index 66ef4da458..5d4b592711 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -30,6 +30,7 @@ sp-std = { version = "2.0.0-alpha.5", path = "../primitives/std" } sp-version = { version = "2.0.0-alpha.5", path = "../primitives/version" } sp-api = { version = "2.0.0-alpha.5", path = "../primitives/api" } sp-runtime = { version = "2.0.0-alpha.5", path = "../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.5", path = "../primitives/utils" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../primitives/blockchain" } sp-state-machine = { version = "0.8.0-alpha.5", path = "../primitives/state-machine" } sc-telemetry = { version = "2.0.0-alpha.5", path = "telemetry" } diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index 1d5b0be5e4..dbe6afe9c7 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -26,10 +26,12 @@ sp-keyring = { version = "2.0.0-alpha.5", path = "../../primitives/keyring" } kvdb = "0.5.0" log = { version = "0.4.8" } parking_lot = "0.10.0" +lazy_static = "1.4.0" sp-core = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/core" } sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/std" } sp-version = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/version" } sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } +sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" } sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } sc-telemetry = { version = "2.0.0-alpha.5", path = "../telemetry" } diff --git a/client/api/src/client.rs b/client/api/src/client.rs index 16a5c07c34..c855cd3a08 100644 --- a/client/api/src/client.rs +++ b/client/api/src/client.rs @@ -17,7 +17,6 @@ //! A set of APIs supported by the client along with their primitives. use std::{fmt, collections::HashSet}; -use futures::channel::mpsc; use sp_core::storage::StorageKey; use sp_runtime::{ traits::{Block as BlockT, NumberFor}, @@ -28,13 +27,14 @@ use sp_consensus::BlockOrigin; use crate::blockchain::Info; use crate::notifications::StorageEventStream; +use sp_utils::mpsc::TracingUnboundedReceiver; use sp_blockchain; /// Type that implements `futures::Stream` of block import events. -pub type ImportNotifications = mpsc::UnboundedReceiver>; +pub type ImportNotifications = TracingUnboundedReceiver>; /// A stream of block finality notifications. -pub type FinalityNotifications = mpsc::UnboundedReceiver>; +pub type FinalityNotifications = TracingUnboundedReceiver>; /// Expected hashes of blocks at given heights. /// diff --git a/client/api/src/notifications.rs b/client/api/src/notifications.rs index 72a9f357fc..f154eade44 100644 --- a/client/api/src/notifications.rs +++ b/client/api/src/notifications.rs @@ -22,9 +22,9 @@ use std::{ }; use fnv::{FnvHashSet, FnvHashMap}; -use futures::channel::mpsc; use sp_core::storage::{StorageKey, StorageData}; use sp_runtime::traits::Block as BlockT; +use sp_utils::mpsc::{TracingUnboundedSender, TracingUnboundedReceiver, tracing_unbounded}; /// Storage change set #[derive(Debug)] @@ -67,7 +67,7 @@ impl StorageChangeSet { } /// Type that implements `futures::Stream` of storage change events. -pub type StorageEventStream = mpsc::UnboundedReceiver<(H, StorageChangeSet)>; +pub type StorageEventStream = TracingUnboundedReceiver<(H, StorageChangeSet)>; type SubscriberId = u64; @@ -82,7 +82,7 @@ pub struct StorageNotifications { FnvHashSet )>, sinks: FnvHashMap, + TracingUnboundedSender<(Block::Hash, StorageChangeSet)>, Option>, Option>>>, )>, @@ -299,7 +299,7 @@ impl StorageNotifications { // insert sink - let (tx, rx) = mpsc::unbounded(); + let (tx, rx) = tracing_unbounded("mpsc_storage_notification_items"); self.sinks.insert(current_id, (tx, keys, child_keys)); rx } diff --git a/client/authority-discovery/src/tests.rs b/client/authority-discovery/src/tests.rs index 3178a06d90..d23836d6fa 100644 --- a/client/authority-discovery/src/tests.rs +++ b/client/authority-discovery/src/tests.rs @@ -119,6 +119,7 @@ impl HeaderBackend for TestApi { finalized_hash: Default::default(), finalized_number: Zero::zero(), genesis_hash: Default::default(), + number_leaves: Default::default(), } } diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index b5d7213e4f..89247cf016 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -29,6 +29,7 @@ sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } sc-network = { version = "0.8.0-alpha.5", path = "../network" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } sc-service = { version = "0.8.0-alpha.5", default-features = false, path = "../service" } sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } diff --git a/client/cli/src/runtime.rs b/client/cli/src/runtime.rs index 183196139f..5c9bc75088 100644 --- a/client/cli/src/runtime.rs +++ b/client/cli/src/runtime.rs @@ -20,6 +20,7 @@ use futures::{Future, future, future::FutureExt}; use futures::select; use futures::pin_mut; use sc_service::{AbstractService, Configuration}; +use sp_utils::metrics::{TOKIO_THREADS_ALIVE, TOKIO_THREADS_TOTAL}; use crate::error; #[cfg(target_family = "unix")] @@ -73,6 +74,13 @@ fn build_runtime() -> Result { tokio::runtime::Builder::new() .thread_name("main-tokio-") .threaded_scheduler() + .on_thread_start(||{ + TOKIO_THREADS_ALIVE.inc(); + TOKIO_THREADS_TOTAL.inc(); + }) + .on_thread_stop(||{ + TOKIO_THREADS_ALIVE.dec(); + }) .enable_all() .build() } diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index c5726a6cf5..f1cb5f9a79 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -425,6 +425,7 @@ impl sc_client::blockchain::HeaderBackend for BlockchainDb genesis_hash: meta.genesis_hash, finalized_hash: meta.finalized_hash, finalized_number: meta.finalized_number, + number_leaves: self.leaves.read().count(), } } diff --git a/client/db/src/light.rs b/client/db/src/light.rs index 166d3ab0e1..808a209f52 100644 --- a/client/db/src/light.rs +++ b/client/db/src/light.rs @@ -153,6 +153,7 @@ impl BlockchainHeaderBackend for LightStorage genesis_hash: meta.genesis_hash, finalized_hash: meta.finalized_hash, finalized_number: meta.finalized_number, + number_leaves: 1, } } diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index 6be790dc19..b684c814d1 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -21,6 +21,7 @@ assert_matches = "1.3.0" parity-scale-codec = { version = "1.3.0", features = ["derive"] } sp-arithmetic = { version = "2.0.0-alpha.5", path = "../../primitives/arithmetic" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } diff --git a/client/finality-grandpa/src/communication/gossip.rs b/client/finality-grandpa/src/communication/gossip.rs index 683a26a66b..2d39ed7ec4 100644 --- a/client/finality-grandpa/src/communication/gossip.rs +++ b/client/finality-grandpa/src/communication/gossip.rs @@ -90,7 +90,7 @@ use sp_finality_grandpa::AuthorityId; use sc_telemetry::{telemetry, CONSENSUS_DEBUG}; use log::{trace, debug}; -use futures::channel::mpsc; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; use prometheus_endpoint::{CounterVec, Opts, PrometheusError, register, Registry, U64}; use rand::seq::SliceRandom; @@ -1254,7 +1254,7 @@ impl Metrics { pub(super) struct GossipValidator { inner: parking_lot::RwLock>, set_state: environment::SharedVoterSetState, - report_sender: mpsc::UnboundedSender, + report_sender: TracingUnboundedSender, metrics: Option, } @@ -1266,7 +1266,7 @@ impl GossipValidator { config: crate::Config, set_state: environment::SharedVoterSetState, prometheus_registry: Option<&Registry>, - ) -> (GossipValidator, mpsc::UnboundedReceiver) { + ) -> (GossipValidator, TracingUnboundedReceiver) { let metrics = match prometheus_registry.map(Metrics::register) { Some(Ok(metrics)) => Some(metrics), Some(Err(e)) => { @@ -1276,7 +1276,7 @@ impl GossipValidator { None => None, }; - let (tx, rx) = mpsc::unbounded(); + let (tx, rx) = tracing_unbounded("mpsc_grandpa_gossip_validator"); let val = GossipValidator { inner: parking_lot::RwLock::new(Inner::new(config)), set_state, diff --git a/client/finality-grandpa/src/communication/mod.rs b/client/finality-grandpa/src/communication/mod.rs index 52bfdbc818..7daa121513 100644 --- a/client/finality-grandpa/src/communication/mod.rs +++ b/client/finality-grandpa/src/communication/mod.rs @@ -58,6 +58,7 @@ use gossip::{ use sp_finality_grandpa::{ AuthorityPair, AuthorityId, AuthoritySignature, SetId as SetIdNumber, RoundNumber, }; +use sp_utils::mpsc::TracingUnboundedReceiver; pub mod gossip; mod periodic; @@ -165,7 +166,7 @@ pub(crate) struct NetworkBridge> { // thus one has to wrap gossip_validator_report_stream with an `Arc` `Mutex`. Given that it is // just an `UnboundedReceiver`, one could also switch to a multi-producer-*multi*-consumer // channel implementation. - gossip_validator_report_stream: Arc>>, + gossip_validator_report_stream: Arc>>, } impl> Unpin for NetworkBridge {} diff --git a/client/finality-grandpa/src/communication/periodic.rs b/client/finality-grandpa/src/communication/periodic.rs index f2e79e8f14..f894624bdf 100644 --- a/client/finality-grandpa/src/communication/periodic.rs +++ b/client/finality-grandpa/src/communication/periodic.rs @@ -17,9 +17,10 @@ //! Periodic rebroadcast of neighbor packets. use futures_timer::Delay; -use futures::{channel::mpsc, future::{FutureExt as _}, prelude::*, ready, stream::Stream}; +use futures::{future::{FutureExt as _}, prelude::*, ready, stream::Stream}; use log::debug; use std::{pin::Pin, task::{Context, Poll}, time::Duration}; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; use sc_network::PeerId; use sp_runtime::traits::{NumberFor, Block as BlockT}; @@ -31,7 +32,7 @@ const REBROADCAST_AFTER: Duration = Duration::from_secs(2 * 60); /// A sender used to send neighbor packets to a background job. #[derive(Clone)] pub(super) struct NeighborPacketSender( - mpsc::UnboundedSender<(Vec, NeighborPacket>)> + TracingUnboundedSender<(Vec, NeighborPacket>)> ); impl NeighborPacketSender { @@ -54,14 +55,15 @@ impl NeighborPacketSender { pub(super) struct NeighborPacketWorker { last: Option<(Vec, NeighborPacket>)>, delay: Delay, - rx: mpsc::UnboundedReceiver<(Vec, NeighborPacket>)>, + rx: TracingUnboundedReceiver<(Vec, NeighborPacket>)>, } impl Unpin for NeighborPacketWorker {} impl NeighborPacketWorker { pub(super) fn new() -> (Self, NeighborPacketSender){ - let (tx, rx) = mpsc::unbounded::<(Vec, NeighborPacket>)>(); + let (tx, rx) = tracing_unbounded::<(Vec, NeighborPacket>)> + ("mpsc_grandpa_neighbor_packet_worker"); let delay = Delay::new(REBROADCAST_AFTER); (NeighborPacketWorker { diff --git a/client/finality-grandpa/src/communication/tests.rs b/client/finality-grandpa/src/communication/tests.rs index eb5ff6fccf..ea995eff63 100644 --- a/client/finality-grandpa/src/communication/tests.rs +++ b/client/finality-grandpa/src/communication/tests.rs @@ -16,7 +16,7 @@ //! Tests for the communication portion of the GRANDPA crate. -use futures::channel::mpsc; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; use futures::prelude::*; use sc_network::{Event as NetworkEvent, ObservedRole, PeerId}; use sc_network_test::{Block, Hash}; @@ -33,7 +33,7 @@ use super::{AuthorityId, VoterSet, Round, SetId}; #[derive(Debug)] pub(crate) enum Event { - EventStream(mpsc::UnboundedSender), + EventStream(TracingUnboundedSender), WriteNotification(sc_network::PeerId, Vec), Report(sc_network::PeerId, sc_network::ReputationChange), Announce(Hash), @@ -41,12 +41,12 @@ pub(crate) enum Event { #[derive(Clone)] pub(crate) struct TestNetwork { - sender: mpsc::UnboundedSender, + sender: TracingUnboundedSender, } impl sc_network_gossip::Network for TestNetwork { fn event_stream(&self) -> Pin + Send>> { - let (tx, rx) = mpsc::unbounded(); + let (tx, rx) = tracing_unbounded("test"); let _ = self.sender.unbounded_send(Event::EventStream(tx)); Box::pin(rx) } @@ -97,7 +97,7 @@ impl sc_network_gossip::ValidatorContext for TestNetwork { pub(crate) struct Tester { pub(crate) net_handle: super::NetworkBridge, gossip_validator: Arc>, - pub(crate) events: mpsc::UnboundedReceiver, + pub(crate) events: TracingUnboundedReceiver, } impl Tester { @@ -161,7 +161,7 @@ pub(crate) fn make_test_network() -> ( impl Future, TestNetwork, ) { - let (tx, rx) = mpsc::unbounded(); + let (tx, rx) = tracing_unbounded("test"); let net = TestNetwork { sender: tx }; #[derive(Clone)] diff --git a/client/finality-grandpa/src/import.rs b/client/finality-grandpa/src/import.rs index 004e14bcba..faf3193641 100644 --- a/client/finality-grandpa/src/import.rs +++ b/client/finality-grandpa/src/import.rs @@ -18,11 +18,11 @@ use std::{sync::Arc, collections::HashMap}; use log::{debug, trace, info}; use parity_scale_codec::Encode; -use futures::channel::mpsc; use parking_lot::RwLockWriteGuard; use sp_blockchain::{BlockStatus, well_known_cache_keys}; use sc_client_api::{backend::Backend, utils::is_descendent_of}; +use sp_utils::mpsc::TracingUnboundedSender; use sp_api::{TransactionFor}; use sp_consensus::{ @@ -57,7 +57,7 @@ pub struct GrandpaBlockImport { inner: Arc, select_chain: SC, authority_set: SharedAuthoritySet>, - send_voter_commands: mpsc::UnboundedSender>>, + send_voter_commands: TracingUnboundedSender>>, consensus_changes: SharedConsensusChanges>, authority_set_hard_forks: HashMap>>, _phantom: PhantomData, @@ -536,7 +536,7 @@ impl GrandpaBlockImport, select_chain: SC, authority_set: SharedAuthoritySet>, - send_voter_commands: mpsc::UnboundedSender>>, + send_voter_commands: TracingUnboundedSender>>, consensus_changes: SharedConsensusChanges>, authority_set_hard_forks: Vec<(SetId, PendingChange>)>, ) -> GrandpaBlockImport { diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index d8e5846a56..800fe3442e 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -55,7 +55,6 @@ use futures::prelude::*; use futures::StreamExt; use log::{debug, info}; -use futures::channel::mpsc; use sc_client_api::{ backend::{AuxStore, Backend}, LockImportRun, BlockchainEvents, CallExecutor, @@ -70,6 +69,7 @@ use sc_keystore::KeyStorePtr; use sp_inherents::InherentDataProviders; use sp_consensus::{SelectChain, BlockImport}; use sp_core::Pair; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver}; use sc_telemetry::{telemetry, CONSENSUS_INFO, CONSENSUS_DEBUG}; use serde_json; @@ -379,7 +379,7 @@ pub struct LinkHalf { client: Arc, select_chain: SC, persistent_data: PersistentData, - voter_commands_rx: mpsc::UnboundedReceiver>>, + voter_commands_rx: TracingUnboundedReceiver>>, } /// Provider for the Grandpa authority set configured on the genesis block. @@ -476,7 +476,7 @@ where } )?; - let (voter_commands_tx, voter_commands_rx) = mpsc::unbounded(); + let (voter_commands_tx, voter_commands_rx) = tracing_unbounded("mpsc_grandpa_voter_command"); // create pending change objects with 0 delay and enacted on finality // (i.e. standard changes) for each authority set hard fork. @@ -598,7 +598,7 @@ pub struct GrandpaParams { /// The inherent data providers. pub inherent_data_providers: InherentDataProviders, /// If supplied, can be used to hook on telemetry connection established events. - pub telemetry_on_connect: Option>, + pub telemetry_on_connect: Option>, /// A voting rule used to potentially restrict target votes. pub voting_rule: VR, /// The prometheus metrics registry. @@ -718,7 +718,7 @@ impl Metrics { struct VoterWork, SC, VR> { voter: Pin>>> + Send>>, env: Arc>, - voter_commands_rx: mpsc::UnboundedReceiver>>, + voter_commands_rx: TracingUnboundedReceiver>>, network: NetworkBridge, /// Prometheus metrics. @@ -742,7 +742,7 @@ where select_chain: SC, voting_rule: VR, persistent_data: PersistentData, - voter_commands_rx: mpsc::UnboundedReceiver>>, + voter_commands_rx: TracingUnboundedReceiver>>, prometheus_registry: Option, ) -> Self { let metrics = match prometheus_registry.as_ref().map(Metrics::register) { diff --git a/client/finality-grandpa/src/observer.rs b/client/finality-grandpa/src/observer.rs index 2382c6e249..fbe19a0716 100644 --- a/client/finality-grandpa/src/observer.rs +++ b/client/finality-grandpa/src/observer.rs @@ -18,7 +18,7 @@ use std::pin::Pin; use std::sync::Arc; use std::task::{Context, Poll}; -use futures::{prelude::*, channel::mpsc}; +use futures::prelude::*; use finality_grandpa::{ BlockNumberOps, Error as GrandpaError, voter, voter_set::VoterSet @@ -27,8 +27,10 @@ use log::{debug, info, warn}; use sp_consensus::SelectChain; use sc_client_api::backend::Backend; +use sp_utils::mpsc::TracingUnboundedReceiver; use sp_runtime::traits::{NumberFor, Block as BlockT}; use sp_blockchain::HeaderMetadata; + use crate::{ global_communication, CommandOrError, CommunicationIn, Config, environment, LinkHalf, Error, aux_schema::PersistentData, VoterCommand, VoterSetState, @@ -206,7 +208,7 @@ struct ObserverWork> { network: NetworkBridge, persistent_data: PersistentData, keystore: Option, - voter_commands_rx: mpsc::UnboundedReceiver>>, + voter_commands_rx: TracingUnboundedReceiver>>, _phantom: PhantomData, } @@ -223,7 +225,7 @@ where network: NetworkBridge, persistent_data: PersistentData, keystore: Option, - voter_commands_rx: mpsc::UnboundedReceiver>>, + voter_commands_rx: TracingUnboundedReceiver>>, ) -> Self { let mut work = ObserverWork { @@ -376,6 +378,7 @@ mod tests { use super::*; use assert_matches::assert_matches; + use sp_utils::mpsc::tracing_unbounded; use crate::{aux_schema, communication::tests::{Event, make_test_network}}; use substrate_test_runtime_client::{TestClientBuilder, TestClientBuilderExt}; use sc_network::PeerId; @@ -412,7 +415,7 @@ mod tests { || Ok(vec![]), ).unwrap(); - let (_tx, voter_command_rx) = mpsc::unbounded(); + let (_tx, voter_command_rx) = tracing_unbounded(""); let observer = ObserverWork::new( client, tester.net_handle.clone(), diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 312f7976bc..d7d1d1e48d 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -993,7 +993,7 @@ fn voter_persists_its_votes() { use std::iter::FromIterator; use std::sync::atomic::{AtomicUsize, Ordering}; use futures::future; - use futures::channel::mpsc; + use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver}; let _ = env_logger::try_init(); let mut runtime = Runtime::new().unwrap(); @@ -1018,7 +1018,7 @@ fn voter_persists_its_votes() { // channel between the voter and the main controller. // sending a message on the `voter_tx` restarts the voter. - let (voter_tx, voter_rx) = mpsc::unbounded::<()>(); + let (voter_tx, voter_rx) = tracing_unbounded::<()>(""); let mut keystore_paths = Vec::new(); @@ -1031,7 +1031,7 @@ fn voter_persists_its_votes() { struct ResettableVoter { voter: Pin + Send + Unpin>>, - voter_rx: mpsc::UnboundedReceiver<()>, + voter_rx: TracingUnboundedReceiver<()>, net: Arc>, client: PeersClient, keystore: KeyStorePtr, diff --git a/client/finality-grandpa/src/until_imported.rs b/client/finality-grandpa/src/until_imported.rs index 95bcceaded..40da7707b6 100644 --- a/client/finality-grandpa/src/until_imported.rs +++ b/client/finality-grandpa/src/until_imported.rs @@ -29,10 +29,10 @@ use super::{ }; use log::{debug, warn}; +use sp_utils::mpsc::TracingUnboundedReceiver; use futures::prelude::*; use futures::stream::Fuse; use futures_timer::Delay; -use futures::channel::mpsc::UnboundedReceiver; use finality_grandpa::voter; use parking_lot::Mutex; use prometheus_endpoint::{ @@ -140,7 +140,7 @@ impl Drop for Metrics { /// Buffering imported messages until blocks with given hashes are imported. #[pin_project::pin_project] pub(crate) struct UntilImported> { - import_notifications: Fuse>>, + import_notifications: Fuse>>, block_sync_requester: BlockSyncRequester, status_check: BlockStatus, #[pin] @@ -541,18 +541,18 @@ mod tests { use sc_client_api::BlockImportNotification; use futures::future::Either; use futures_timer::Delay; - use futures::channel::mpsc; + use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender}; use finality_grandpa::Precommit; #[derive(Clone)] struct TestChainState { - sender: mpsc::UnboundedSender>, + sender: TracingUnboundedSender>, known_blocks: Arc>>, } impl TestChainState { fn new() -> (Self, ImportNotifications) { - let (tx, rx) = mpsc::unbounded(); + let (tx, rx) = tracing_unbounded("test"); let state = TestChainState { sender: tx, known_blocks: Arc::new(Mutex::new(HashMap::new())), @@ -649,7 +649,7 @@ mod tests { // enact all dependencies before importing the message enact_dependencies(&chain_state); - let (global_tx, global_rx) = futures::channel::mpsc::unbounded(); + let (global_tx, global_rx) = tracing_unbounded("test"); let until_imported = UntilGlobalMessageBlocksImported::new( import_notifications, @@ -676,7 +676,7 @@ mod tests { let (chain_state, import_notifications) = TestChainState::new(); let block_status = chain_state.block_status(); - let (global_tx, global_rx) = futures::channel::mpsc::unbounded(); + let (global_tx, global_rx) = tracing_unbounded("test"); let until_imported = UntilGlobalMessageBlocksImported::new( import_notifications, @@ -929,7 +929,7 @@ mod tests { let (chain_state, import_notifications) = TestChainState::new(); let block_status = chain_state.block_status(); - let (global_tx, global_rx) = futures::channel::mpsc::unbounded(); + let (global_tx, global_rx) = tracing_unbounded("test"); let block_sync_requester = TestBlockSyncRequester::default(); diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index 153e8103de..ad2eb2ae0e 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -18,6 +18,7 @@ log = "0.4.8" lru = "0.4.3" sc-network = { version = "0.8.0-alpha.5", path = "../network" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } wasm-timer = "0.2" [dev-dependencies] diff --git a/client/network-gossip/src/bridge.rs b/client/network-gossip/src/bridge.rs index 270376be19..6a00b3d5a1 100644 --- a/client/network-gossip/src/bridge.rs +++ b/client/network-gossip/src/bridge.rs @@ -19,10 +19,11 @@ use crate::state_machine::{ConsensusGossip, TopicNotification, PERIODIC_MAINTENA use sc_network::{Event, ReputationChange}; -use futures::{prelude::*, channel::mpsc}; +use futures::prelude::*; use libp2p::PeerId; use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; use std::{borrow::Cow, pin::Pin, sync::Arc, task::{Context, Poll}}; +use sp_utils::mpsc::TracingUnboundedReceiver; /// Wraps around an implementation of the `Network` crate and provides gossiping capabilities on /// top of it. @@ -86,7 +87,7 @@ impl GossipEngine { /// Get data of valid, incoming messages for a topic (but might have expired meanwhile). pub fn messages_for(&mut self, topic: B::Hash) - -> mpsc::UnboundedReceiver + -> TracingUnboundedReceiver { self.state_machine.messages_for(self.engine_id, topic) } diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index 20eb4aaf89..c846534488 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -21,10 +21,10 @@ use std::sync::Arc; use std::iter; use std::time; use log::trace; -use futures::channel::mpsc; use lru::LruCache; use libp2p::PeerId; use sp_runtime::traits::{Block as BlockT, Hash, HashFor}; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; use sp_runtime::ConsensusEngineId; use sc_network::ObservedRole; use wasm_timer::Instant; @@ -164,7 +164,7 @@ fn propagate<'a, B: BlockT, I>( /// Consensus network protocol handler. Manages statements and candidate requests. pub struct ConsensusGossip { peers: HashMap>, - live_message_sinks: HashMap<(ConsensusEngineId, B::Hash), Vec>>, + live_message_sinks: HashMap<(ConsensusEngineId, B::Hash), Vec>>, messages: Vec>, known_messages: LruCache, validators: HashMap>>, @@ -333,9 +333,9 @@ impl ConsensusGossip { /// Get data of valid, incoming messages for a topic (but might have expired meanwhile) pub fn messages_for(&mut self, engine_id: ConsensusEngineId, topic: B::Hash) - -> mpsc::UnboundedReceiver + -> TracingUnboundedReceiver { - let (tx, rx) = mpsc::unbounded(); + let (tx, rx) = tracing_unbounded("mpsc_gossip_messages_for"); for entry in self.messages.iter_mut() .filter(|e| e.topic == topic && e.engine_id == engine_id) { diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 465cb2632f..8d67a15c35 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -47,6 +47,7 @@ slog = { version = "2.5.2", features = ["nested-values"] } slog_derive = "0.2.0" smallvec = "0.6.10" sp-arithmetic = { version = "2.0.0-alpha.5", path = "../../primitives/arithmetic" } +sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } sp-consensus = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/common" } sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/babe" } diff --git a/client/network/src/on_demand_layer.rs b/client/network/src/on_demand_layer.rs index 822901e677..d881bf6fe2 100644 --- a/client/network/src/on_demand_layer.rs +++ b/client/network/src/on_demand_layer.rs @@ -18,12 +18,13 @@ use crate::protocol::light_client_handler; -use futures::{channel::mpsc, channel::oneshot, prelude::*}; +use futures::{channel::oneshot, prelude::*}; use parking_lot::Mutex; use sc_client_api::{ FetchChecker, Fetcher, RemoteBodyRequest, RemoteCallRequest, RemoteChangesRequest, RemoteHeaderRequest, RemoteReadChildRequest, RemoteReadRequest, StorageProof, ChangesProof, }; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; use sp_blockchain::Error as ClientError; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use std::{collections::HashMap, pin::Pin, sync::Arc, task::Context, task::Poll}; @@ -42,10 +43,10 @@ pub struct OnDemand { /// Note that a better alternative would be to use a MPMC queue here, and add a `poll` method /// from the `OnDemand`. However there exists no popular implementation of MPMC channels in /// asynchronous Rust at the moment - requests_queue: Mutex>>>, + requests_queue: Mutex>>>, /// Sending side of `requests_queue`. - requests_send: mpsc::UnboundedSender>, + requests_send: TracingUnboundedSender>, } /// Dummy implementation of `FetchChecker` that always assumes that responses are bad. @@ -112,7 +113,7 @@ where { /// Creates new on-demand service. pub fn new(checker: Arc>) -> Self { - let (requests_send, requests_queue) = mpsc::unbounded(); + let (requests_send, requests_queue) = tracing_unbounded("mpsc_ondemand"); let requests_queue = Mutex::new(Some(requests_queue)); OnDemand { @@ -134,9 +135,9 @@ where /// /// If this function returns `None`, that means that the receiver has already been extracted in /// the past, and therefore that something already handles the requests. - pub(crate) fn extract_receiver( - &self, - ) -> Option>> { + pub(crate) fn extract_receiver(&self) + -> Option>> + { self.requests_queue.lock().take() } } diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 9c286cd520..abe9231abf 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -36,7 +36,8 @@ use crate::{ protocol::{self, event::Event, light_client_handler, sync::SyncState, PeerInfo, Protocol}, transport, ReputationChange, }; -use futures::{prelude::*, channel::mpsc}; +use futures::prelude::*; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent}; use libp2p::{kad::record, Multiaddr, PeerId}; use log::{error, info, trace, warn}; @@ -159,7 +160,7 @@ pub struct NetworkService { /// nodes it should be connected to or not. peerset: PeersetHandle, /// Channel that sends messages to the actual worker. - to_worker: mpsc::UnboundedSender>, + to_worker: TracingUnboundedSender>, /// Marker to pin the `H` generic. Serves no purpose except to not break backwards /// compatibility. _marker: PhantomData, @@ -172,7 +173,7 @@ impl NetworkWorker { /// for the network processing to advance. From it, you can extract a `NetworkService` using /// `worker.service()`. The `NetworkService` can be shared through the codebase. pub fn new(params: Params) -> Result, Error> { - let (to_worker, from_worker) = mpsc::unbounded(); + let (to_worker, from_worker) = tracing_unbounded("mpsc_network_worker"); if let Some(ref path) = params.network_config.net_config_path { fs::create_dir_all(Path::new(path))?; @@ -550,7 +551,7 @@ impl NetworkService { /// The stream never ends (unless the `NetworkWorker` gets shut down). pub fn event_stream(&self) -> impl Stream { // Note: when transitioning to stable futures, remove the `Error` entirely - let (tx, rx) = mpsc::unbounded(); + let (tx, rx) = tracing_unbounded("mpsc_network_event_stream"); let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::EventStream(tx)); rx } @@ -770,7 +771,7 @@ enum ServiceToWorkerMsg { PutValue(record::Key, Vec), AddKnownAddress(PeerId, Multiaddr), SyncFork(Vec, B::Hash, NumberFor), - EventStream(mpsc::UnboundedSender), + EventStream(TracingUnboundedSender), WriteNotification { message: Vec, engine_id: ConsensusEngineId, @@ -801,11 +802,11 @@ pub struct NetworkWorker { /// The import queue that was passed as initialization. import_queue: Box>, /// Messages from the `NetworkService` and that must be processed. - from_worker: mpsc::UnboundedReceiver>, + from_worker: TracingUnboundedReceiver>, /// Receiver for queries from the light client that must be processed. - light_client_rqs: Option>>, + light_client_rqs: Option>>, /// Senders for events that happen on the network. - event_streams: Vec>, + event_streams: Vec>, /// Prometheus network metrics. metrics: Option, /// The `PeerId`'s of all boot nodes. diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index 594f21a636..e7292439e8 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -24,6 +24,7 @@ parking_lot = "0.10.0" sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } rand = "0.7.2" sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } sc-network = { version = "0.8.0-alpha.5", path = "../network" } sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } diff --git a/client/offchain/src/api/http.rs b/client/offchain/src/api/http.rs index 7923a767f1..a64fe03897 100644 --- a/client/offchain/src/api/http.rs +++ b/client/offchain/src/api/http.rs @@ -32,11 +32,12 @@ use futures::{prelude::*, future, channel::mpsc}; use log::error; use sp_core::offchain::{HttpRequestId, Timestamp, HttpRequestStatus, HttpError}; use std::{fmt, io::Read as _, mem, pin::Pin, task::Context, task::Poll}; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; /// Creates a pair of [`HttpApi`] and [`HttpWorker`]. pub fn http() -> (HttpApi, HttpWorker) { - let (to_worker, from_api) = mpsc::unbounded(); - let (to_api, from_worker) = mpsc::unbounded(); + let (to_worker, from_api) = tracing_unbounded("mpsc_ocw_to_worker"); + let (to_api, from_worker) = tracing_unbounded("mpsc_ocw_to_api"); let api = HttpApi { to_worker, @@ -63,10 +64,10 @@ pub fn http() -> (HttpApi, HttpWorker) { /// to offchain workers. pub struct HttpApi { /// Used to sends messages to the worker. - to_worker: mpsc::UnboundedSender, + to_worker: TracingUnboundedSender, /// Used to receive messages from the worker. /// We use a `Fuse` in order to have an extra protection against panicking. - from_worker: stream::Fuse>, + from_worker: stream::Fuse>, /// Id to assign to the next HTTP request that is started. next_id: HttpRequestId, /// List of HTTP requests in preparation or in progress. @@ -546,9 +547,9 @@ enum WorkerToApi { /// Must be continuously polled for the [`HttpApi`] to properly work. pub struct HttpWorker { /// Used to sends messages to the `HttpApi`. - to_api: mpsc::UnboundedSender, + to_api: TracingUnboundedSender, /// Used to receive messages from the `HttpApi`. - from_api: mpsc::UnboundedReceiver, + from_api: TracingUnboundedReceiver, /// The engine that runs HTTP requests. http_client: hyper::Client, hyper::Body>, /// HTTP requests that are being worked on by the engine. diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 0ad96c0c6e..78d488a989 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -13,6 +13,7 @@ documentation = "https://docs.rs/sc-peerset" [dependencies] futures = "0.3.4" libp2p = { version = "0.16.2", default-features = false } +sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils"} log = "0.4.8" serde_json = "1.0.41" wasm-timer = "0.2" diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index 476780024b..9376e9594b 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -20,11 +20,12 @@ mod peersstate; use std::{collections::{HashSet, HashMap}, collections::VecDeque}; -use futures::{prelude::*, channel::mpsc}; +use futures::prelude::*; use log::{debug, error, trace}; use serde_json::json; use std::{pin::Pin, task::{Context, Poll}, time::Duration}; use wasm_timer::Instant; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; pub use libp2p::PeerId; @@ -73,7 +74,7 @@ impl ReputationChange { /// Shared handle to the peer set manager (PSM). Distributed around the code. #[derive(Debug, Clone)] pub struct PeersetHandle { - tx: mpsc::UnboundedSender, + tx: TracingUnboundedSender, } impl PeersetHandle { @@ -183,9 +184,9 @@ pub struct Peerset { /// If true, we only accept reserved nodes. reserved_only: bool, /// Receiver for messages from the `PeersetHandle` and from `tx`. - rx: mpsc::UnboundedReceiver, + rx: TracingUnboundedReceiver, /// Sending side of `rx`. - tx: mpsc::UnboundedSender, + tx: TracingUnboundedSender, /// Queue of messages to be emitted when the `Peerset` is polled. message_queue: VecDeque, /// When the `Peerset` was created. @@ -197,7 +198,7 @@ pub struct Peerset { impl Peerset { /// Builds a new peerset from the given configuration. pub fn from_config(config: PeersetConfig) -> (Peerset, PeersetHandle) { - let (tx, rx) = mpsc::unbounded(); + let (tx, rx) = tracing_unbounded("mpsc_peerset_messages"); let handle = PeersetHandle { tx: tx.clone(), diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index 7b06113dda..7092959b83 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -24,6 +24,7 @@ serde_json = "1.0.41" sp-session = { version = "2.0.0-alpha.5", path = "../../primitives/session" } sp-offchain = { version = "2.0.0-alpha.5", path = "../../primitives/offchain" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } sp-rpc = { version = "2.0.0-alpha.5", path = "../../primitives/rpc" } sp-state-machine = { version = "0.8.0-alpha.5", path = "../../primitives/state-machine" } sc-executor = { version = "0.8.0-alpha.5", path = "../executor" } diff --git a/client/rpc/src/system/mod.rs b/client/rpc/src/system/mod.rs index 3a9ed9f2dc..9565992cf4 100644 --- a/client/rpc/src/system/mod.rs +++ b/client/rpc/src/system/mod.rs @@ -20,8 +20,9 @@ mod tests; use futures::{future::BoxFuture, FutureExt, TryFutureExt}; -use futures::{channel::{mpsc, oneshot}, compat::Compat}; +use futures::{channel::oneshot, compat::Compat}; use sc_rpc_api::Receiver; +use sp_utils::mpsc::TracingUnboundedSender; use sp_runtime::traits::{self, Header as HeaderT}; use self::error::Result; @@ -33,7 +34,7 @@ pub use self::gen_client::Client as SystemClient; /// System API implementation pub struct System { info: SystemInfo, - send_back: mpsc::UnboundedSender>, + send_back: TracingUnboundedSender>, } /// Request to be processed. @@ -59,7 +60,7 @@ impl System { /// reading from that channel and answering the requests. pub fn new( info: SystemInfo, - send_back: mpsc::UnboundedSender>, + send_back: TracingUnboundedSender>, ) -> Self { System { info, diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 3811ea079d..7dc987b303 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -36,6 +36,7 @@ target_info = "0.1.0" sc-keystore = { version = "2.0.0-alpha.5", path = "../keystore" } sp-io = { version = "2.0.0-alpha.5", path = "../../primitives/io" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } sp-blockchain = { version = "2.0.0-alpha.5", path = "../../primitives/blockchain" } sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } sp-session = { version = "2.0.0-alpha.5", path = "../../primitives/session" } @@ -61,6 +62,14 @@ sc-tracing = { version = "2.0.0-alpha.5", path = "../tracing" } tracing = "0.1.10" parity-util-mem = { version = "0.6.0", default-features = false, features = ["primitive-types"] } +[target.'cfg(unix)'.dependencies] +procfs = '0.7.8' +netstat2 = "0.8.1" + +[target.'cfg(windows)'.dependencies] +netstat2 = "0.8.1" + + [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } sp-consensus-babe = { version = "0.8.0-alpha.5", path = "../../primitives/consensus/babe" } diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index b9c98dbf2e..205f877999 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -18,6 +18,7 @@ use crate::{Service, NetworkStatus, NetworkState, error::Error, DEFAULT_PROTOCOL use crate::{TaskManagerBuilder, start_rpc_servers, build_network_future, TransactionPoolAdapter}; use crate::status_sinks; use crate::config::{Configuration, DatabaseConfig, KeystoreConfig, PrometheusConfig}; +use crate::metrics::MetricsService; use sc_client_api::{ self, BlockchainEvents, @@ -25,12 +26,12 @@ use sc_client_api::{ execution_extensions::ExtensionsFactory, ExecutorProvider, CallExecutor }; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender}; use sc_client::Client; use sc_chain_spec::get_extension; use sp_consensus::import_queue::ImportQueue; use futures::{ Future, FutureExt, StreamExt, - channel::mpsc, future::ready, }; use sc_keystore::{Store as Keystore}; @@ -40,7 +41,7 @@ use sc_network::{NetworkService, NetworkStateInfo}; use parking_lot::{Mutex, RwLock}; use sp_runtime::generic::BlockId; use sp_runtime::traits::{ - Block as BlockT, NumberFor, SaturatedConversion, HashFor, UniqueSaturatedInto, + Block as BlockT, NumberFor, SaturatedConversion, HashFor, }; use sp_api::ProvideRuntimeApi; use sc_executor::{NativeExecutor, NativeExecutionDispatch}; @@ -49,56 +50,9 @@ use std::{ marker::PhantomData, sync::Arc, pin::Pin }; use wasm_timer::SystemTime; -use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; use sp_transaction_pool::{MaintainedTransactionPool, ChainEvent}; use sp_blockchain; -use prometheus_endpoint::{register, Gauge, U64, F64, Registry, PrometheusError, Opts, GaugeVec}; - -struct ServiceMetrics { - block_height_number: GaugeVec, - ready_transactions_number: Gauge, - memory_usage_bytes: Gauge, - cpu_usage_percentage: Gauge, - network_per_sec_bytes: GaugeVec, - database_cache: Gauge, - state_cache: Gauge, - state_db: GaugeVec, -} - -impl ServiceMetrics { - fn register(registry: &Registry) -> Result { - Ok(Self { - block_height_number: register(GaugeVec::new( - Opts::new("block_height_number", "Height of the chain"), - &["status"] - )?, registry)?, - ready_transactions_number: register(Gauge::new( - "ready_transactions_number", "Number of transactions in the ready queue", - )?, registry)?, - memory_usage_bytes: register(Gauge::new( - "memory_usage_bytes", "Node memory (resident set size) usage", - )?, registry)?, - cpu_usage_percentage: register(Gauge::new( - "cpu_usage_percentage", "Node CPU usage", - )?, registry)?, - network_per_sec_bytes: register(GaugeVec::new( - Opts::new("network_per_sec_bytes", "Networking bytes per second"), - &["direction"] - )?, registry)?, - database_cache: register(Gauge::new( - "database_cache_bytes", "RocksDB cache size in bytes", - )?, registry)?, - state_cache: register(Gauge::new( - "state_cache_bytes", "State cache size in bytes", - )?, registry)?, - state_db: register(GaugeVec::new( - Opts::new("state_db_cache_bytes", "State DB cache in bytes"), - &["subtype"] - )?, registry)?, - }) - } -} pub type BackgroundTask = Pin + Send>>; @@ -820,7 +774,7 @@ ServiceBuilder< )?; // A side-channel for essential tasks to communicate shutdown. - let (essential_failed_tx, essential_failed_rx) = mpsc::unbounded(); + let (essential_failed_tx, essential_failed_rx) = tracing_unbounded("mpsc_essential_tasks"); let import_queue = Box::new(import_queue); let chain_info = client.chain_info(); @@ -992,122 +946,44 @@ ServiceBuilder< } // Prometheus metrics. - let metrics = if let Some(PrometheusConfig { port, registry }) = config.prometheus_config.clone() { + let mut metrics_service = if let Some(PrometheusConfig { port, registry }) = config.prometheus_config.clone() { // Set static metrics. - register(Gauge::::with_opts( - Opts::new( - "build_info", - "A metric with a constant '1' value labeled by name, version, and commit." - ) - .const_label("name", config.impl_name) - .const_label("version", config.impl_version) - .const_label("commit", config.impl_commit), - )?, ®istry)?.set(1); + let role_bits = match config.role { - Role::Full => 1, - Role::Light => 2, - Role::Sentry { .. } => 3, - Role::Authority { .. } => 4, + Role::Full => 1u64, + Role::Light => 2u64, + Role::Sentry { .. } => 3u64, + Role::Authority { .. } => 4u64, }; - register(Gauge::::new( - "node_role", "The role the node is running as", - )?, ®istry)?.set(role_bits); - - let metrics = ServiceMetrics::register(®istry)?; - + let metrics = MetricsService::with_prometheus( + ®istry, + &config.name, + &config.impl_version, + role_bits, + )?; spawn_handle.spawn( "prometheus-endpoint", prometheus_endpoint::init_prometheus(port, registry).map(drop) ); - Some(metrics) + metrics } else { - None + MetricsService::new() }; // Periodically notify the telemetry. let transaction_pool_ = transaction_pool.clone(); let client_ = client.clone(); - let mut sys = System::new(); - let self_pid = get_current_pid().ok(); - let (state_tx, state_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); + let (state_tx, state_rx) = tracing_unbounded::<(NetworkStatus<_>, NetworkState)>("mpsc_netstat1"); network_status_sinks.lock().push(std::time::Duration::from_millis(5000), state_tx); let tel_task = state_rx.for_each(move |(net_status, _)| { let info = client_.usage_info(); - let best_number = info.chain.best_number.saturated_into::(); - let best_hash = info.chain.best_hash; - let num_peers = net_status.num_connected_peers; - let txpool_status = transaction_pool_.status(); - let finalized_number: u64 = info.chain.finalized_number.saturated_into::(); - let bandwidth_download = net_status.average_download_per_sec; - let bandwidth_upload = net_status.average_upload_per_sec; - let best_seen_block = net_status.best_seen_block - .map(|num: NumberFor| num.unique_saturated_into() as u64); - - // get cpu usage and memory usage of this process - let (cpu_usage, memory) = if let Some(self_pid) = self_pid { - if sys.refresh_process(self_pid) { - let proc = sys.get_process(self_pid) - .expect("Above refresh_process succeeds, this should be Some(), qed"); - (proc.cpu_usage(), proc.memory()) - } else { (0.0, 0) } - } else { (0.0, 0) }; - - telemetry!( - SUBSTRATE_INFO; - "system.interval"; - "peers" => num_peers, - "height" => best_number, - "best" => ?best_hash, - "txcount" => txpool_status.ready, - "cpu" => cpu_usage, - "memory" => memory, - "finalized_height" => finalized_number, - "finalized_hash" => ?info.chain.finalized_hash, - "bandwidth_download" => bandwidth_download, - "bandwidth_upload" => bandwidth_upload, - "used_state_cache_size" => info.usage.as_ref() - .map(|usage| usage.memory.state_cache.as_bytes()) - .unwrap_or(0), - "used_db_cache_size" => info.usage.as_ref() - .map(|usage| usage.memory.database_cache.as_bytes()) - .unwrap_or(0), - "disk_read_per_sec" => info.usage.as_ref() - .map(|usage| usage.io.bytes_read) - .unwrap_or(0), - "disk_write_per_sec" => info.usage.as_ref() - .map(|usage| usage.io.bytes_written) - .unwrap_or(0), + metrics_service.tick( + &info, + &transaction_pool_.status(), + &net_status, ); - if let Some(metrics) = metrics.as_ref() { - // `sysinfo::Process::memory` returns memory usage in KiB and not bytes. - metrics.memory_usage_bytes.set(memory * 1024); - metrics.cpu_usage_percentage.set(f64::from(cpu_usage)); - metrics.ready_transactions_number.set(txpool_status.ready as u64); - - metrics.network_per_sec_bytes.with_label_values(&["download"]).set(net_status.average_download_per_sec); - metrics.network_per_sec_bytes.with_label_values(&["upload"]).set(net_status.average_upload_per_sec); - - metrics.block_height_number.with_label_values(&["finalized"]).set(finalized_number); - metrics.block_height_number.with_label_values(&["best"]).set(best_number); - - if let Some(best_seen_block) = best_seen_block { - metrics.block_height_number.with_label_values(&["sync_target"]).set(best_seen_block); - } - - if let Some(info) = info.usage.as_ref() { - metrics.database_cache.set(info.memory.database_cache.as_bytes() as u64); - metrics.state_cache.set(info.memory.state_cache.as_bytes() as u64); - - metrics.state_db.with_label_values(&["non_canonical"]).set(info.memory.state_db.non_canonical.as_bytes() as u64); - if let Some(pruning) = info.memory.state_db.pruning { - metrics.state_db.with_label_values(&["pruning"]).set(pruning.as_bytes() as u64); - } - metrics.state_db.with_label_values(&["pinned"]).set(info.memory.state_db.pinned.as_bytes() as u64); - } - } - ready(()) }); @@ -1117,7 +993,7 @@ ServiceBuilder< ); // Periodically send the network state to the telemetry. - let (netstat_tx, netstat_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); + let (netstat_tx, netstat_rx) = tracing_unbounded::<(NetworkStatus<_>, NetworkState)>("mpsc_netstat2"); network_status_sinks.lock().push(std::time::Duration::from_secs(30), netstat_tx); let tel_task_2 = netstat_rx.for_each(move |(_, network_state)| { telemetry!( @@ -1133,7 +1009,7 @@ ServiceBuilder< ); // RPC - let (system_rpc_tx, system_rpc_rx) = mpsc::unbounded(); + let (system_rpc_tx, system_rpc_rx) = tracing_unbounded("mpsc_system_rpc"); let gen_handler = || { use sc_rpc::{chain, state, author, system, offchain}; @@ -1215,7 +1091,7 @@ ServiceBuilder< ), ); - let telemetry_connection_sinks: Arc>>> = Default::default(); + let telemetry_connection_sinks: Arc>>> = Default::default(); // Telemetry let telemetry = config.telemetry_endpoints.clone().map(|endpoints| { diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 9c680bbbc9..0ceb310d07 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -24,6 +24,7 @@ pub mod config; pub mod chain_ops; pub mod error; +mod metrics; mod builder; mod status_sinks; mod task_manager; @@ -40,7 +41,6 @@ use parking_lot::Mutex; use sc_client::Client; use futures::{ Future, FutureExt, Stream, StreamExt, - channel::mpsc, compat::*, sink::SinkExt, task::{Spawn, FutureObj, SpawnError}, @@ -51,6 +51,7 @@ use codec::{Encode, Decode}; use sp_runtime::generic::BlockId; use sp_runtime::traits::{NumberFor, Block as BlockT}; use parity_util_mem::MallocSizeOf; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; pub use self::error::Error; pub use self::builder::{ @@ -98,13 +99,13 @@ pub struct Service { transaction_pool: Arc, /// Send a signal when a spawned essential task has concluded. The next time /// the service future is polled it should complete with an error. - essential_failed_tx: mpsc::UnboundedSender<()>, + essential_failed_tx: TracingUnboundedSender<()>, /// A receiver for spawned essential-tasks concluding. - essential_failed_rx: mpsc::UnboundedReceiver<()>, + essential_failed_rx: TracingUnboundedReceiver<()>, rpc_handlers: sc_rpc_server::RpcHandler, _rpc: Box, _telemetry: Option, - _telemetry_on_connect_sinks: Arc>>>, + _telemetry_on_connect_sinks: Arc>>>, _offchain_workers: Option>, keystore: sc_keystore::KeyStorePtr, marker: PhantomData, @@ -130,7 +131,7 @@ pub trait AbstractService: 'static + Future> + type TransactionPool: TransactionPool + MallocSizeOfWasm; /// Get event stream for telemetry connection established events. - fn telemetry_on_connect_stream(&self) -> futures::channel::mpsc::UnboundedReceiver<()>; + fn telemetry_on_connect_stream(&self) -> TracingUnboundedReceiver<()>; /// return a shared instance of Telemetry (if enabled) fn telemetry(&self) -> Option; @@ -171,7 +172,7 @@ pub trait AbstractService: 'static + Future> + -> Arc::Hash>>; /// Returns a receiver that periodically receives a status of the network. - fn network_status(&self, interval: Duration) -> mpsc::UnboundedReceiver<(NetworkStatus, NetworkState)>; + fn network_status(&self, interval: Duration) -> TracingUnboundedReceiver<(NetworkStatus, NetworkState)>; /// Get shared transaction pool instance. fn transaction_pool(&self) -> Arc; @@ -203,8 +204,8 @@ where type SelectChain = TSc; type TransactionPool = TExPool; - fn telemetry_on_connect_stream(&self) -> futures::channel::mpsc::UnboundedReceiver<()> { - let (sink, stream) = futures::channel::mpsc::unbounded(); + fn telemetry_on_connect_stream(&self) -> TracingUnboundedReceiver<()> { + let (sink, stream) = tracing_unbounded("mpsc_telemetry_on_connect"); self._telemetry_on_connect_sinks.lock().push(sink); stream } @@ -259,8 +260,8 @@ where self.network.clone() } - fn network_status(&self, interval: Duration) -> mpsc::UnboundedReceiver<(NetworkStatus, NetworkState)> { - let (sink, stream) = mpsc::unbounded(); + fn network_status(&self, interval: Duration) -> TracingUnboundedReceiver<(NetworkStatus, NetworkState)> { + let (sink, stream) = tracing_unbounded("mpsc_network_status"); self.network_status_sinks.lock().push(interval, sink); stream } @@ -326,7 +327,7 @@ fn build_network_future< mut network: sc_network::NetworkWorker, client: Arc, status_sinks: Arc, NetworkState)>>>, - mut rpc_rx: mpsc::UnboundedReceiver>, + mut rpc_rx: TracingUnboundedReceiver>, should_have_peers: bool, announce_imported_blocks: bool, ) -> impl Future { diff --git a/client/service/src/metrics.rs b/client/service/src/metrics.rs new file mode 100644 index 0000000000..931d59b5f1 --- /dev/null +++ b/client/service/src/metrics.rs @@ -0,0 +1,428 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use crate::NetworkStatus; +use prometheus_endpoint::{register, Gauge, U64, F64, Registry, PrometheusError, Opts, GaugeVec}; +use sc_client::ClientInfo; +use sc_telemetry::{telemetry, SUBSTRATE_INFO}; +use std::convert::TryFrom; +use sp_runtime::traits::{NumberFor, Block, SaturatedConversion, UniqueSaturatedInto}; +use sp_transaction_pool::PoolStatus; +use sp_utils::metrics::register_globals; + +#[cfg(any(windows, unix))] +use sysinfo::{ProcessExt, System, SystemExt}; + +#[cfg(any(unix, windows))] +use netstat2::{TcpState, ProtocolSocketInfo, iterate_sockets_info, AddressFamilyFlags, ProtocolFlags}; + +#[cfg(not(unix))] +use sysinfo::get_current_pid; + +#[cfg(unix)] +use procfs; + +struct PrometheusMetrics { + // system + #[cfg(any(unix, windows))] + load_avg: GaugeVec, + + // process + cpu_usage_percentage: Gauge, + memory_usage_bytes: Gauge, + threads: Gauge, + open_files: GaugeVec, + + #[cfg(any(unix, windows))] + netstat: GaugeVec, + + // -- inner counters + // generic info + block_height: GaugeVec, + number_leaves: Gauge, + ready_transactions_number: Gauge, + + // I/O + network_per_sec_bytes: GaugeVec, + database_cache: Gauge, + state_cache: Gauge, + state_db: GaugeVec, +} + +impl PrometheusMetrics { + fn setup(registry: &Registry, name: &str, version: &str, roles: u64) + -> Result + { + register(Gauge::::with_opts( + Opts::new( + "build_info", + "A metric with a constant '1' value labeled by name, version" + ) + .const_label("name", name) + .const_label("version", version) + )?, ®istry)?.set(1); + + register(Gauge::::new( + "node_roles", "The roles the node is running as", + )?, ®istry)?.set(roles); + + register_globals(registry)?; + + Ok(Self { + // system + #[cfg(any(unix, windows))] + load_avg: register(GaugeVec::new( + Opts::new("load_avg", "System load average"), + &["over"] + )?, registry)?, + + // process + memory_usage_bytes: register(Gauge::new( + "memory_usage_bytes", "Node memory (resident set size) usage", + )?, registry)?, + + cpu_usage_percentage: register(Gauge::new( + "cpu_usage_percentage", "Node CPU usage", + )?, registry)?, + + #[cfg(any(unix, windows))] + netstat: register(GaugeVec::new( + Opts::new("netstat_tcp", "Current TCP connections "), + &["status"] + )?, registry)?, + + threads: register(Gauge::new( + "threads", "Number of threads used by the process", + )?, registry)?, + + open_files: register(GaugeVec::new( + Opts::new("open_file_handles", "Open file handlers held by the process"), + &["fd_type"] + )?, registry)?, + + // --- internal + + // generic internals + + block_height: register(GaugeVec::new( + Opts::new("block_height", "Block height info of the chain"), + &["status"] + )?, registry)?, + + number_leaves: register(Gauge::new( + "number_leaves", "Number of known chain leaves (aka forks)", + )?, registry)?, + + ready_transactions_number: register(Gauge::new( + "ready_transactions_number", "Number of transactions in the ready queue", + )?, registry)?, + + // I/ O + + network_per_sec_bytes: register(GaugeVec::new( + Opts::new("network_per_sec_bytes", "Networking bytes per second"), + &["direction"] + )?, registry)?, + database_cache: register(Gauge::new( + "database_cache_bytes", "RocksDB cache size in bytes", + )?, registry)?, + state_cache: register(Gauge::new( + "state_cache_bytes", "State cache size in bytes", + )?, registry)?, + state_db: register(GaugeVec::new( + Opts::new("state_db_cache_bytes", "State DB cache in bytes"), + &["subtype"] + )?, registry)?, + }) + } +} + +#[cfg(any(unix, windows))] +#[derive(Default)] +struct ConnectionsCount { + listen: u64, + established: u64, + starting: u64, + closing: u64, + closed: u64, + other: u64 +} + +#[derive(Default)] +struct FdCounter { + paths: u64, + sockets: u64, + net: u64, + pipes: u64, + anon_inode: u64, + mem: u64, + other: u64, +} + +#[derive(Default)] +struct ProcessInfo { + cpu_usage: f64, + memory: u64, + threads: Option, + open_fd: Option, +} + +pub struct MetricsService { + metrics: Option, + #[cfg(any(windows, unix))] + system: System, + pid: Option, +} + +#[cfg(unix)] +impl MetricsService { + fn inner_new(metrics: Option) -> Self { + let process = procfs::process::Process::myself() + .expect("Procfs doesn't fail on unix. qed"); + + Self { + metrics, + system: System::new(), + pid: Some(process.pid), + } + } + fn process_info(&mut self) -> ProcessInfo { + let pid = self.pid.clone().expect("unix always has a pid. qed"); + let mut info = self._process_info_for(&pid); + let process = procfs::process::Process::new(pid).expect("Our process exists. qed."); + info.threads = process.stat().ok().map(|s| + u64::try_from(s.num_threads).expect("There are no negative thread counts. qed")); + info.open_fd = process.fd().ok().map(|i| + i.into_iter().fold(FdCounter::default(), |mut f, info| { + match info.target { + procfs::process::FDTarget::Path(_) => f.paths += 1, + procfs::process::FDTarget::Socket(_) => f.sockets += 1, + procfs::process::FDTarget::Net(_) => f.net += 1, + procfs::process::FDTarget::Pipe(_) => f.pipes += 1, + procfs::process::FDTarget::AnonInode(_) => f.anon_inode += 1, + procfs::process::FDTarget::MemFD(_) => f.mem += 1, + procfs::process::FDTarget::Other(_,_) => f.other += 1, + }; + f + }) + ); + info + } + +} + + +#[cfg(windows)] +impl MetricsService { + fn inner_new(metrics: Option) -> Self { + Self { + metrics, + system: System(), + pid: get_current_pid().ok() + } + } + + fn process_info(&mut self) -> ProcessInfo { + self.pid.map(|pid| self._process_info_for(pid)).or_else(ProcessInfo::default) + } +} + +#[cfg(not(any(unix, windows)))] +impl MetricsService { + fn inner_new(metrics: Option) -> Self { + Self { + metrics, + pid: None + } + } + + fn process_info(&mut self) -> ProcessInfo { + ProcessInfo::default() + } +} + + +impl MetricsService { + + pub fn with_prometheus(registry: &Registry, name: &str, version: &str, roles: u64) + -> Result + { + PrometheusMetrics::setup(registry, name, version, roles).map(|p| { + Self::inner_new(Some(p)) + }) + } + + pub fn new() -> Self { + Self::inner_new(None) + } + + #[cfg(any(windows, unix))] + fn _process_info_for(&mut self, pid: &i32) -> ProcessInfo { + let mut info = ProcessInfo::default(); + if self.system.refresh_process(*pid) { + let prc = self.system.get_process(*pid) + .expect("Above refresh_process succeeds, this must be Some(), qed"); + info.cpu_usage = prc.cpu_usage().into(); + info.memory = prc.memory(); + } + info + } + + #[cfg(any(unix, windows))] + fn connections_info(&self) -> Option { + self.pid.as_ref().and_then(|pid| { + let af_flags = AddressFamilyFlags::IPV4 | AddressFamilyFlags::IPV6; + let proto_flags = ProtocolFlags::TCP; + let netstat_pid = *pid as u32; + + iterate_sockets_info(af_flags, proto_flags).ok().map(|iter| + iter.filter_map(|r| + r.ok().and_then(|s| { + if s.associated_pids.contains(&netstat_pid) { + match s.protocol_socket_info { + ProtocolSocketInfo::Tcp(info) => Some(info.state), + _ => None + } + } else { + None + } + }) + ).fold(ConnectionsCount::default(), |mut counter, socket_state| { + match socket_state { + TcpState::Listen => counter.listen += 1, + TcpState::Established => counter.established += 1, + TcpState::Closed => counter.closed += 1, + TcpState::SynSent | TcpState::SynReceived => counter.starting += 1, + TcpState::FinWait1 | TcpState::FinWait2 | TcpState::CloseWait + | TcpState::Closing | TcpState::LastAck => counter.closing += 1, + _ => counter.other += 1 + } + + counter + }) + ) + }) + } + + pub fn tick( + &mut self, + info: &ClientInfo, + txpool_status: &PoolStatus, + net_status: &NetworkStatus + ) { + + let best_number = info.chain.best_number.saturated_into::(); + let best_hash = info.chain.best_hash; + let num_peers = net_status.num_connected_peers; + let finalized_number: u64 = info.chain.finalized_number.saturated_into::(); + let bandwidth_download = net_status.average_download_per_sec; + let bandwidth_upload = net_status.average_upload_per_sec; + let best_seen_block = net_status.best_seen_block + .map(|num: NumberFor| num.unique_saturated_into() as u64); + let process_info = self.process_info(); + + telemetry!( + SUBSTRATE_INFO; + "system.interval"; + "peers" => num_peers, + "height" => best_number, + "best" => ?best_hash, + "txcount" => txpool_status.ready, + "cpu" => process_info.cpu_usage, + "memory" => process_info.memory, + "finalized_height" => finalized_number, + "finalized_hash" => ?info.chain.finalized_hash, + "bandwidth_download" => bandwidth_download, + "bandwidth_upload" => bandwidth_upload, + "used_state_cache_size" => info.usage.as_ref() + .map(|usage| usage.memory.state_cache.as_bytes()) + .unwrap_or(0), + "used_db_cache_size" => info.usage.as_ref() + .map(|usage| usage.memory.database_cache.as_bytes()) + .unwrap_or(0), + "disk_read_per_sec" => info.usage.as_ref() + .map(|usage| usage.io.bytes_read) + .unwrap_or(0), + "disk_write_per_sec" => info.usage.as_ref() + .map(|usage| usage.io.bytes_written) + .unwrap_or(0), + ); + + if let Some(metrics) = self.metrics.as_ref() { + metrics.cpu_usage_percentage.set(process_info.cpu_usage as f64); + // `sysinfo::Process::memory` returns memory usage in KiB and not bytes. + metrics.memory_usage_bytes.set(process_info.memory * 1024); + + if let Some(threads) = process_info.threads { + metrics.threads.set(threads); + } + + if let Some(fd_info) = process_info.open_fd { + metrics.open_files.with_label_values(&["paths"]).set(fd_info.paths); + metrics.open_files.with_label_values(&["mem"]).set(fd_info.mem); + metrics.open_files.with_label_values(&["sockets"]).set(fd_info.sockets); + metrics.open_files.with_label_values(&["net"]).set(fd_info.net); + metrics.open_files.with_label_values(&["pipe"]).set(fd_info.pipes); + metrics.open_files.with_label_values(&["anon_inode"]).set(fd_info.anon_inode); + metrics.open_files.with_label_values(&["other"]).set(fd_info.other); + } + + + metrics.network_per_sec_bytes.with_label_values(&["download"]).set(net_status.average_download_per_sec); + metrics.network_per_sec_bytes.with_label_values(&["upload"]).set(net_status.average_upload_per_sec); + + metrics.block_height.with_label_values(&["finalized"]).set(finalized_number); + metrics.block_height.with_label_values(&["best"]).set(best_number); + if let Ok(leaves) = u64::try_from(info.chain.number_leaves) { + metrics.number_leaves.set(leaves); + } + + metrics.ready_transactions_number.set(txpool_status.ready as u64); + + if let Some(best_seen_block) = best_seen_block { + metrics.block_height.with_label_values(&["sync_target"]).set(best_seen_block); + } + + if let Some(info) = info.usage.as_ref() { + metrics.database_cache.set(info.memory.database_cache.as_bytes() as u64); + metrics.state_cache.set(info.memory.state_cache.as_bytes() as u64); + + metrics.state_db.with_label_values(&["non_canonical"]).set(info.memory.state_db.non_canonical.as_bytes() as u64); + if let Some(pruning) = info.memory.state_db.pruning { + metrics.state_db.with_label_values(&["pruning"]).set(pruning.as_bytes() as u64); + } + metrics.state_db.with_label_values(&["pinned"]).set(info.memory.state_db.pinned.as_bytes() as u64); + } + + #[cfg(any(unix, windows))] + { + let load = self.system.get_load_average(); + metrics.load_avg.with_label_values(&["1min"]).set(load.one); + metrics.load_avg.with_label_values(&["5min"]).set(load.five); + metrics.load_avg.with_label_values(&["15min"]).set(load.fifteen); + + if let Some(conns) = self.connections_info() { + metrics.netstat.with_label_values(&["listen"]).set(conns.listen); + metrics.netstat.with_label_values(&["established"]).set(conns.established); + metrics.netstat.with_label_values(&["starting"]).set(conns.starting); + metrics.netstat.with_label_values(&["closing"]).set(conns.closing); + metrics.netstat.with_label_values(&["closed"]).set(conns.closed); + metrics.netstat.with_label_values(&["other"]).set(conns.other); + } + } + } + } +} diff --git a/client/service/src/status_sinks.rs b/client/service/src/status_sinks.rs index 8e189be157..4b1dce52f9 100644 --- a/client/service/src/status_sinks.rs +++ b/client/service/src/status_sinks.rs @@ -14,11 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use futures::{Stream, stream::futures_unordered::FuturesUnordered, channel::mpsc}; +use futures::{Stream, stream::futures_unordered::FuturesUnordered}; use std::time::Duration; use std::pin::Pin; use std::task::{Poll, Context}; use futures_timer::Delay; +use sp_utils::mpsc::TracingUnboundedSender; /// Holds a list of `UnboundedSender`s, each associated with a certain time period. Every time the /// period elapses, we push an element on the sender. @@ -31,7 +32,7 @@ pub struct StatusSinks { struct YieldAfter { delay: Delay, interval: Duration, - sender: Option>, + sender: Option>, } impl StatusSinks { @@ -45,7 +46,7 @@ impl StatusSinks { /// Adds a sender to the collection. /// /// The `interval` is the time period between two pushes on the sender. - pub fn push(&mut self, interval: Duration, sender: mpsc::UnboundedSender) { + pub fn push(&mut self, interval: Duration, sender: TracingUnboundedSender) { self.entries.push(YieldAfter { delay: Delay::new(interval), interval, @@ -88,7 +89,7 @@ impl StatusSinks { } impl futures::Future for YieldAfter { - type Output = (mpsc::UnboundedSender, Duration); + type Output = (TracingUnboundedSender, Duration); fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { let this = Pin::into_inner(self); diff --git a/client/service/src/task_manager.rs b/client/service/src/task_manager.rs index 15dc33abfa..7c5862e853 100644 --- a/client/service/src/task_manager.rs +++ b/client/service/src/task_manager.rs @@ -22,17 +22,18 @@ use exit_future::Signal; use log::{debug, error}; use futures::{ Future, FutureExt, Stream, - future::select, channel::mpsc, + future::select, compat::*, task::{Spawn, FutureObj, SpawnError}, }; use sc_client_api::CloneableSpawn; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; /// Type alias for service task executor (usually runtime). pub type ServiceTaskExecutor = Arc + Send>>) + Send + Sync>; /// Type alias for the task scheduler. -pub type TaskScheduler = mpsc::UnboundedSender<(Pin + Send>>, Cow<'static, str>)>; +pub type TaskScheduler = TracingUnboundedSender<(Pin + Send>>, Cow<'static, str>)>; /// Helper struct to setup background tasks execution for service. pub struct TaskManagerBuilder { @@ -44,14 +45,14 @@ pub struct TaskManagerBuilder { /// Sender for futures that must be spawned as background tasks. to_spawn_tx: TaskScheduler, /// Receiver for futures that must be spawned as background tasks. - to_spawn_rx: mpsc::UnboundedReceiver<(Pin + Send>>, Cow<'static, str>)>, + to_spawn_rx: TracingUnboundedReceiver<(Pin + Send>>, Cow<'static, str>)>, } impl TaskManagerBuilder { /// New asynchronous task manager setup. pub fn new() -> Self { let (signal, on_exit) = exit_future::signal(); - let (to_spawn_tx, to_spawn_rx) = mpsc::unbounded(); + let (to_spawn_tx, to_spawn_rx) = tracing_unbounded("mpsc_task_manager"); Self { on_exit, signal: Some(signal), @@ -144,7 +145,7 @@ pub struct TaskManager { /// Sender for futures that must be spawned as background tasks. to_spawn_tx: TaskScheduler, /// Receiver for futures that must be spawned as background tasks. - to_spawn_rx: mpsc::UnboundedReceiver<(Pin + Send>>, Cow<'static, str>)>, + to_spawn_rx: TracingUnboundedReceiver<(Pin + Send>>, Cow<'static, str>)>, /// How to spawn background tasks. executor: ServiceTaskExecutor, } diff --git a/client/src/client.rs b/client/src/client.rs index 7ec941ee7a..13d654a7c2 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -21,7 +21,6 @@ use std::{ result, }; use log::{info, trace, warn}; -use futures::channel::mpsc; use parking_lot::{Mutex, RwLock}; use codec::{Encode, Decode}; use hash_db::Prefix; @@ -78,6 +77,7 @@ pub use sc_client_api::{ notifications::{StorageNotifications, StorageEventStream}, CallExecutor, ExecutorProvider, ProofProvider, CloneableSpawn, }; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender}; use sp_blockchain::Error; use prometheus_endpoint::Registry; @@ -93,8 +93,8 @@ pub struct Client where Block: BlockT { backend: Arc, executor: E, storage_notifications: Mutex>, - import_notification_sinks: Mutex>>>, - finality_notification_sinks: Mutex>>>, + import_notification_sinks: Mutex>>>, + finality_notification_sinks: Mutex>>>, // holds the block hash currently being imported. TODO: replace this with block queue importing_block: RwLock>, block_rules: BlockRules, @@ -1764,13 +1764,13 @@ where { /// Get block import event stream. fn import_notification_stream(&self) -> ImportNotifications { - let (sink, stream) = mpsc::unbounded(); + let (sink, stream) = tracing_unbounded("mpsc_import_notification_stream"); self.import_notification_sinks.lock().push(sink); stream } fn finality_notification_stream(&self) -> FinalityNotifications { - let (sink, stream) = mpsc::unbounded(); + let (sink, stream) = tracing_unbounded("mpsc_finality_notification_stream"); self.finality_notification_sinks.lock().push(sink); stream } diff --git a/client/src/in_mem.rs b/client/src/in_mem.rs index bdbfdbc7ec..3672da1822 100644 --- a/client/src/in_mem.rs +++ b/client/src/in_mem.rs @@ -304,6 +304,7 @@ impl HeaderBackend for Blockchain { genesis_hash: storage.genesis_hash, finalized_hash: storage.finalized_hash, finalized_number: storage.finalized_number, + number_leaves: storage.leaves.count() } } diff --git a/client/src/leaves.rs b/client/src/leaves.rs index 1082e6ca07..7c169488dd 100644 --- a/client/src/leaves.rs +++ b/client/src/leaves.rs @@ -195,6 +195,11 @@ impl LeafSet where self.storage.iter().flat_map(|(_, hashes)| hashes.iter()).cloned().collect() } + /// Number of known leaves + pub fn count(&self) -> usize { + self.storage.len() + } + /// Write the leaf list to the database transaction. pub fn prepare_transaction(&mut self, tx: &mut DBTransaction, column: u32, prefix: &[u8]) { let mut buf = prefix.to_vec(); diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index dee1d23fcb..29b8069842 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -19,6 +19,7 @@ wasm-timer = "0.2" sp-core = { version = "2.0.0-alpha.5", path = "../../primitives/core" } sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-alpha.5", path = "../../primitives/utils" } sc-transaction-graph = { version = "2.0.0-alpha.5", path = "./graph" } sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../primitives/transaction-pool" } sc-client-api = { version = "2.0.0-alpha.5", path = "../api" } diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index a88ce6a2e4..df2fd8546a 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -16,6 +16,7 @@ parking_lot = "0.10.0" serde = { version = "1.0.101", features = ["derive"] } wasm-timer = "0.2" sp-blockchain = { version = "2.0.0-alpha.5", path = "../../../primitives/blockchain" } +sp-utils = { version = "2.0.0-alpha.5", path = "../../../primitives/utils" } sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../../primitives/runtime" } sp-transaction-pool = { version = "2.0.0-alpha.5", path = "../../../primitives/transaction-pool" } diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index a7e4ab554d..0b817b155d 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -24,10 +24,7 @@ use crate::base_pool as base; use crate::watcher::Watcher; use serde::Serialize; -use futures::{ - Future, FutureExt, - channel::mpsc, -}; +use futures::{Future, FutureExt}; use sp_runtime::{ generic::BlockId, traits::{self, SaturatedConversion}, @@ -37,12 +34,13 @@ use sp_runtime::{ }; use sp_transaction_pool::error; use wasm_timer::Instant; +use sp_utils::mpsc::TracingUnboundedReceiver; use crate::validated_pool::ValidatedPool; pub use crate::validated_pool::ValidatedTransaction; /// Modification notification event stream type; -pub type EventStream = mpsc::UnboundedReceiver; +pub type EventStream = TracingUnboundedReceiver; /// Extrinsic hash type for a pool. pub type ExHash = ::Hash; diff --git a/client/transaction-pool/graph/src/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index b63e56e481..2ff2acfe24 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -27,7 +27,6 @@ use crate::watcher::Watcher; use serde::Serialize; use log::{debug, warn}; -use futures::channel::mpsc; use parking_lot::{Mutex, RwLock}; use sp_runtime::{ generic::BlockId, @@ -36,6 +35,7 @@ use sp_runtime::{ }; use sp_transaction_pool::{error, PoolStatus}; use wasm_timer::Instant; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender}; use crate::base_pool::PruneStatus; use crate::pool::{EventStream, Options, ChainApi, ExHash, ExtrinsicFor, TransactionFor}; @@ -95,7 +95,7 @@ pub struct ValidatedPool { ExHash, ExtrinsicFor, >>, - import_notification_sinks: Mutex>>>, + import_notification_sinks: Mutex>>>, rotator: PoolRotator>, } @@ -504,7 +504,7 @@ impl ValidatedPool { /// Consumers of this stream should use the `ready` method to actually get the /// pending transactions in the right order. pub fn import_notification_stream(&self) -> EventStream> { - let (sink, stream) = mpsc::unbounded(); + let (sink, stream) = tracing_unbounded("mpsc_import_notifications"); self.import_notification_sinks.lock().push(sink); stream } diff --git a/client/transaction-pool/graph/src/watcher.rs b/client/transaction-pool/graph/src/watcher.rs index d28f6814e4..d54cc2718b 100644 --- a/client/transaction-pool/graph/src/watcher.rs +++ b/client/transaction-pool/graph/src/watcher.rs @@ -16,18 +16,16 @@ //! Extrinsics status updates. -use futures::{ - Stream, - channel::mpsc, -}; +use futures::Stream; use sp_transaction_pool::TransactionStatus; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; /// Extrinsic watcher. /// /// Represents a stream of status updates for particular extrinsic. #[derive(Debug)] pub struct Watcher { - receiver: mpsc::UnboundedReceiver>, + receiver: TracingUnboundedReceiver>, hash: H, } @@ -48,7 +46,7 @@ impl Watcher { /// Sender part of the watcher. Exposed only for testing purposes. #[derive(Debug)] pub struct Sender { - receivers: Vec>>, + receivers: Vec>>, is_finalized: bool, } @@ -64,7 +62,7 @@ impl Default for Sender { impl Sender { /// Add a new watcher to this sender object. pub fn new_watcher(&mut self, hash: H) -> Watcher { - let (tx, receiver) = mpsc::unbounded(); + let (tx, receiver) = tracing_unbounded("mpsc_txpool_watcher"); self.receivers.push(tx); Watcher { receiver, diff --git a/client/transaction-pool/src/revalidation.rs b/client/transaction-pool/src/revalidation.rs index 5a3b2521c3..9bcb2dac39 100644 --- a/client/transaction-pool/src/revalidation.rs +++ b/client/transaction-pool/src/revalidation.rs @@ -22,8 +22,9 @@ use sc_transaction_graph::{ChainApi, Pool, ExHash, NumberFor, ValidatedTransacti use sp_runtime::traits::{Zero, SaturatedConversion}; use sp_runtime::generic::BlockId; use sp_runtime::transaction_validity::TransactionValidityError; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; -use futures::{prelude::*, channel::mpsc}; +use futures::prelude::*; use std::time::Duration; #[cfg(not(test))] @@ -202,7 +203,7 @@ impl RevalidationWorker { /// transactions from the pool. pub async fn run( mut self, - from_queue: mpsc::UnboundedReceiver>, + from_queue: TracingUnboundedReceiver>, interval: R, ) where R: Send, R::Guard: Send { @@ -252,7 +253,7 @@ impl RevalidationWorker { pub struct RevalidationQueue { pool: Arc>, api: Arc, - background: Option>>, + background: Option>>, } impl RevalidationQueue @@ -275,7 +276,7 @@ where ) -> (Self, Pin + Send>>) where R: Send + 'static, R::Guard: Send { - let (to_worker, from_queue) = mpsc::unbounded(); + let (to_worker, from_queue) = tracing_unbounded("mpsc_revalidation_queue"); let worker = RevalidationWorker::new(api.clone(), pool.clone()); diff --git a/primitives/blockchain/src/backend.rs b/primitives/blockchain/src/backend.rs index 35cac1e481..e92dfd8c98 100644 --- a/primitives/blockchain/src/backend.rs +++ b/primitives/blockchain/src/backend.rs @@ -254,6 +254,8 @@ pub struct Info { pub finalized_hash: Block::Hash, /// Last finalized block number. pub finalized_number: <::Header as HeaderT>::Number, + /// Number of concurrent leave forks. + pub number_leaves: usize } /// Block status. diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index d942d7975a..112b9499a7 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -23,6 +23,7 @@ futures-diagnose = "1.0" sp-std = { version = "2.0.0-alpha.5", path = "../../std" } sp-version = { version = "2.0.0-alpha.5", path = "../../version" } sp-runtime = { version = "2.0.0-alpha.5", path = "../../runtime" } +sp-utils = { version = "2.0.0-alpha.5", path = "../../utils" } codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } parking_lot = "0.10.0" serde = { version = "1.0", features = ["derive"] } diff --git a/primitives/consensus/common/src/import_queue/basic_queue.rs b/primitives/consensus/common/src/import_queue/basic_queue.rs index 0d1aed7fb1..024e473849 100644 --- a/primitives/consensus/common/src/import_queue/basic_queue.rs +++ b/primitives/consensus/common/src/import_queue/basic_queue.rs @@ -15,10 +15,11 @@ // along with Substrate. If not, see . use std::{mem, pin::Pin, time::Duration, marker::PhantomData, sync::Arc}; -use futures::{prelude::*, channel::mpsc, task::Context, task::Poll}; +use futures::{prelude::*, task::Context, task::Poll}; use futures_timer::Delay; use parking_lot::{Mutex, Condvar}; use sp_runtime::{Justification, traits::{Block as BlockT, Header as HeaderT, NumberFor}}; +use sp_utils::mpsc::{TracingUnboundedSender, tracing_unbounded}; use crate::block_import::BlockOrigin; use crate::import_queue::{ @@ -32,7 +33,7 @@ use crate::import_queue::{ /// task, with plugable verification. pub struct BasicQueue { /// Channel to send messages to the background task. - sender: mpsc::UnboundedSender>, + sender: TracingUnboundedSender>, /// Results coming from the worker task. result_port: BufferedLinkReceiver, /// If it isn't possible to spawn the future in `future_to_spawn` (which is notably the case in @@ -195,8 +196,8 @@ impl BlockImportWorker { block_import: BoxBlockImport, justification_import: Option>, finality_proof_import: Option>, - ) -> (impl Future + Send, mpsc::UnboundedSender>) { - let (sender, mut port) = mpsc::unbounded(); + ) -> (impl Future + Send, TracingUnboundedSender>) { + let (sender, mut port) = tracing_unbounded("mpsc_block_import_worker"); let mut worker = BlockImportWorker { result_sender, diff --git a/primitives/consensus/common/src/import_queue/buffered_link.rs b/primitives/consensus/common/src/import_queue/buffered_link.rs index d0f6c87951..ea77fc97f0 100644 --- a/primitives/consensus/common/src/import_queue/buffered_link.rs +++ b/primitives/consensus/common/src/import_queue/buffered_link.rs @@ -37,8 +37,9 @@ //! ``` //! -use futures::{prelude::*, channel::mpsc}; +use futures::prelude::*; use sp_runtime::traits::{Block as BlockT, NumberFor}; +use sp_utils::mpsc::{TracingUnboundedSender, TracingUnboundedReceiver, tracing_unbounded}; use std::{pin::Pin, task::Context, task::Poll}; use crate::import_queue::{Origin, Link, BlockImportResult, BlockImportError}; @@ -46,7 +47,7 @@ use crate::import_queue::{Origin, Link, BlockImportResult, BlockImportError}; /// can be used to buffer commands, and the receiver can be used to poll said commands and transfer /// them to another link. pub fn buffered_link() -> (BufferedLinkSender, BufferedLinkReceiver) { - let (tx, rx) = mpsc::unbounded(); + let (tx, rx) = tracing_unbounded("mpsc_buffered_link"); let tx = BufferedLinkSender { tx }; let rx = BufferedLinkReceiver { rx }; (tx, rx) @@ -54,7 +55,7 @@ pub fn buffered_link() -> (BufferedLinkSender, BufferedLinkReceive /// See [`buffered_link`]. pub struct BufferedLinkSender { - tx: mpsc::UnboundedSender>, + tx: TracingUnboundedSender>, } impl BufferedLinkSender { @@ -125,7 +126,7 @@ impl Link for BufferedLinkSender { /// See [`buffered_link`]. pub struct BufferedLinkReceiver { - rx: mpsc::UnboundedReceiver>, + rx: TracingUnboundedReceiver>, } impl BufferedLinkReceiver { diff --git a/primitives/transaction-pool/Cargo.toml b/primitives/transaction-pool/Cargo.toml index 003212613e..6e30fb4ddc 100644 --- a/primitives/transaction-pool/Cargo.toml +++ b/primitives/transaction-pool/Cargo.toml @@ -18,6 +18,7 @@ log = { version = "0.4.8", optional = true } serde = { version = "1.0.101", features = ["derive"], optional = true} sp-api = { version = "2.0.0-alpha.5", default-features = false, path = "../api" } sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" } +sp-utils = { version = "2.0.0-alpha.5", default-features = false, path = "../utils" } [features] default = [ "std" ] diff --git a/primitives/transaction-pool/src/pool.rs b/primitives/transaction-pool/src/pool.rs index 2c9d0e33e8..ddc3fffa15 100644 --- a/primitives/transaction-pool/src/pool.rs +++ b/primitives/transaction-pool/src/pool.rs @@ -22,11 +22,9 @@ use std::{ sync::Arc, pin::Pin, }; -use futures::{ - Future, Stream, - channel::mpsc, -}; +use futures::{Future, Stream,}; use serde::{Deserialize, Serialize}; +use sp_utils::mpsc; use sp_runtime::{ generic::BlockId, traits::{Block as BlockT, Member, NumberFor}, @@ -132,7 +130,7 @@ pub enum TransactionStatus { pub type TransactionStatusStream = dyn Stream> + Send + Unpin; /// The import notification event stream. -pub type ImportNotificationStream = mpsc::UnboundedReceiver; +pub type ImportNotificationStream = mpsc::TracingUnboundedReceiver; /// Transaction hash type for a pool. pub type TxHash