Run cargo fmt on the whole code base (#9394)

* Run cargo fmt on the whole code base

* Second run

* Add CI check

* Fix compilation

* More unnecessary braces

* Handle weights

* Use --all

* Use correct attributes...

* Fix UI tests

* AHHHHHHHHH

* 🤦

* Docs

* Fix compilation

* 🤷

* Please stop

* 🤦 x 2

* More

* make rustfmt.toml consistent with polkadot

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Bastian Köcher
2021-07-21 16:32:32 +02:00
committed by GitHub
parent d451c38c1c
commit 7b56ab15b4
1010 changed files with 53339 additions and 51208 deletions
+60 -60
View File
@@ -24,36 +24,22 @@
//! DO NOT depend on user input). Thus transaction generation should be
//! based on randomized data.
use std::{
borrow::Cow,
collections::HashMap,
pin::Pin,
sync::Arc,
};
use futures::Future;
use std::{borrow::Cow, collections::HashMap, pin::Pin, sync::Arc};
use node_primitives::Block;
use node_testing::bench::{BenchDb, Profile, BlockType, KeyTypes, DatabaseType};
use sp_runtime::{
generic::BlockId,
traits::NumberFor,
OpaqueExtrinsic,
};
use node_testing::bench::{BenchDb, BlockType, DatabaseType, KeyTypes, Profile};
use sc_transaction_pool_api::{
ImportNotificationStream,
PoolFuture,
PoolStatus,
TransactionFor,
TransactionSource,
TransactionStatusStreamFor,
TxHash,
ImportNotificationStream, PoolFuture, PoolStatus, TransactionFor, TransactionSource,
TransactionStatusStreamFor, TxHash,
};
use sp_consensus::{Environment, Proposer};
use sp_inherents::InherentDataProvider;
use sp_runtime::{generic::BlockId, traits::NumberFor, OpaqueExtrinsic};
use crate::{
common::SizeType,
core::{self, Path, Mode},
core::{self, Mode, Path},
};
pub struct ConstructionBenchmarkDescription {
@@ -72,7 +58,6 @@ pub struct ConstructionBenchmark {
impl core::BenchmarkDescription for ConstructionBenchmarkDescription {
fn path(&self) -> Path {
let mut path = Path::new(&["node", "proposer"]);
match self.profile {
@@ -104,11 +89,7 @@ impl core::BenchmarkDescription for ConstructionBenchmarkDescription {
fn setup(self: Box<Self>) -> Box<dyn core::Benchmark> {
let mut extrinsics: Vec<Arc<PoolTransaction>> = Vec::new();
let mut bench_db = BenchDb::with_key_types(
self.database_type,
50_000,
self.key_types
);
let mut bench_db = BenchDb::with_key_types(self.database_type, 50_000, self.key_types);
let client = bench_db.client();
@@ -127,11 +108,9 @@ impl core::BenchmarkDescription for ConstructionBenchmarkDescription {
fn name(&self) -> Cow<'static, str> {
format!(
"Block construction ({:?}/{}, {:?}, {:?} backend)",
self.block_type,
self.size,
self.profile,
self.database_type,
).into()
self.block_type, self.size, self.profile, self.database_type,
)
.into()
}
}
@@ -139,7 +118,9 @@ impl core::Benchmark for ConstructionBenchmark {
fn run(&mut self, mode: Mode) -> std::time::Duration {
let context = self.database.create_context(self.profile);
let _ = context.client.runtime_version_at(&BlockId::Number(0))
let _ = context
.client
.runtime_version_at(&BlockId::Number(0))
.expect("Failed to get runtime version")
.spec_version;
@@ -158,20 +139,25 @@ impl core::Benchmark for ConstructionBenchmark {
let start = std::time::Instant::now();
let proposer = futures::executor::block_on(proposer_factory.init(
&context.client.header(&BlockId::number(0))
.expect("Database error querying block #0")
.expect("Block #0 should exist"),
)).expect("Proposer initialization failed");
let _block = futures::executor::block_on(
proposer.propose(
timestamp_provider.create_inherent_data().expect("Create inherent data failed"),
Default::default(),
std::time::Duration::from_secs(20),
None,
let proposer = futures::executor::block_on(
proposer_factory.init(
&context
.client
.header(&BlockId::number(0))
.expect("Database error querying block #0")
.expect("Block #0 should exist"),
),
).map(|r| r.block).expect("Proposing failed");
)
.expect("Proposer initialization failed");
let _block = futures::executor::block_on(proposer.propose(
timestamp_provider.create_inherent_data().expect("Create inherent data failed"),
Default::default(),
std::time::Duration::from_secs(20),
None,
))
.map(|r| r.block)
.expect("Proposing failed");
let elapsed = start.elapsed();
@@ -191,10 +177,7 @@ pub struct PoolTransaction {
impl From<OpaqueExtrinsic> for PoolTransaction {
fn from(e: OpaqueExtrinsic) -> Self {
PoolTransaction {
data: e,
hash: node_primitives::Hash::zero(),
}
PoolTransaction { data: e, hash: node_primitives::Hash::zero() }
}
}
@@ -210,15 +193,25 @@ impl sc_transaction_pool_api::InPoolTransaction for PoolTransaction {
&self.hash
}
fn priority(&self) -> &u64 { unimplemented!() }
fn priority(&self) -> &u64 {
unimplemented!()
}
fn longevity(&self) -> &u64 { unimplemented!() }
fn longevity(&self) -> &u64 {
unimplemented!()
}
fn requires(&self) -> &[Vec<u8>] { unimplemented!() }
fn requires(&self) -> &[Vec<u8>] {
unimplemented!()
}
fn provides(&self) -> &[Vec<u8>] { unimplemented!() }
fn provides(&self) -> &[Vec<u8>] {
unimplemented!()
}
fn is_propagable(&self) -> bool { unimplemented!() }
fn is_propagable(&self) -> bool {
unimplemented!()
}
}
#[derive(Clone, Debug)]
@@ -236,7 +229,7 @@ impl sc_transaction_pool_api::TransactionPool for Transactions {
_at: &BlockId<Self::Block>,
_source: TransactionSource,
_xts: Vec<TransactionFor<Self>>,
) -> PoolFuture<Vec<Result<node_primitives::Hash, Self::Error>>, Self::Error> {
) -> PoolFuture<Vec<Result<node_primitives::Hash, Self::Error>>, Self::Error> {
unimplemented!()
}
@@ -259,14 +252,21 @@ impl sc_transaction_pool_api::TransactionPool for Transactions {
unimplemented!()
}
fn ready_at(&self, _at: NumberFor<Self::Block>)
-> Pin<Box<dyn Future<Output=Box<dyn Iterator<Item=Arc<Self::InPoolTransaction>> + Send>> + Send>>
{
let iter: Box<dyn Iterator<Item=Arc<PoolTransaction>> + Send> = Box::new(self.0.clone().into_iter());
fn ready_at(
&self,
_at: NumberFor<Self::Block>,
) -> Pin<
Box<
dyn Future<Output = Box<dyn Iterator<Item = Arc<Self::InPoolTransaction>> + Send>>
+ Send,
>,
> {
let iter: Box<dyn Iterator<Item = Arc<PoolTransaction>> + Send> =
Box::new(self.0.clone().into_iter());
Box::pin(futures::future::ready(iter))
}
fn ready(&self) -> Box<dyn Iterator<Item=Arc<Self::InPoolTransaction>> + Send> {
fn ready(&self) -> Box<dyn Iterator<Item = Arc<Self::InPoolTransaction>> + Send> {
unimplemented!()
}
+11 -11
View File
@@ -16,8 +16,11 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use std::{fmt, borrow::{Cow, ToOwned}};
use serde::Serialize;
use std::{
borrow::{Cow, ToOwned},
fmt,
};
pub struct Path(Vec<String>);
@@ -33,7 +36,11 @@ impl Path {
}
pub fn full(&self) -> String {
self.0.iter().fold(String::new(), |mut val, next| { val.push_str("::"); val.push_str(next); val })
self.0.iter().fold(String::new(), |mut val, next| {
val.push_str("::");
val.push_str(next);
val
})
}
pub fn has(&self, path: &str) -> bool {
@@ -115,10 +122,7 @@ impl fmt::Display for BenchmarkOutput {
}
}
pub fn run_benchmark(
benchmark: Box<dyn BenchmarkDescription>,
mode: Mode,
) -> BenchmarkOutput {
pub fn run_benchmark(benchmark: Box<dyn BenchmarkDescription>, mode: Mode) -> BenchmarkOutput {
let name = benchmark.name().to_owned();
let mut benchmark = benchmark.setup();
@@ -133,11 +137,7 @@ pub fn run_benchmark(
let raw_average = (durations.iter().sum::<u128>() / (durations.len() as u128)) as u64;
let average = (durations.iter().skip(10).take(30).sum::<u128>() / 30) as u64;
BenchmarkOutput {
name: name.into(),
raw_average,
average,
}
BenchmarkOutput { name: name.into(), raw_average, average }
}
macro_rules! matrix(
+4 -3
View File
@@ -30,14 +30,15 @@ use crate::simple_trie::SimpleTrie;
/// return root.
pub fn generate_trie(
db: Arc<dyn KeyValueDB>,
key_values: impl IntoIterator<Item=(Vec<u8>, Vec<u8>)>,
key_values: impl IntoIterator<Item = (Vec<u8>, Vec<u8>)>,
) -> Hash {
let mut root = Hash::default();
let (db, overlay) = {
let mut overlay = HashMap::new();
overlay.insert(
hex::decode("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").expect("null key is valid"),
hex::decode("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314")
.expect("null key is valid"),
Some(vec![0]),
);
let mut trie = SimpleTrie { db, overlay: &mut overlay };
@@ -50,7 +51,7 @@ pub fn generate_trie(
trie_db.commit();
}
( trie.db, overlay )
(trie.db, overlay)
};
let mut transaction = db.transaction();
+13 -19
View File
@@ -32,15 +32,15 @@
use std::borrow::Cow;
use node_testing::bench::{BenchDb, Profile, BlockType, KeyTypes, DatabaseType};
use node_primitives::Block;
use node_testing::bench::{BenchDb, BlockType, DatabaseType, KeyTypes, Profile};
use sc_client_api::backend::Backend;
use sp_runtime::generic::BlockId;
use sp_state_machine::InspectState;
use crate::{
common::SizeType,
core::{self, Path, Mode},
core::{self, Mode, Path},
};
pub struct ImportBenchmarkDescription {
@@ -60,7 +60,6 @@ pub struct ImportBenchmark {
impl core::BenchmarkDescription for ImportBenchmarkDescription {
fn path(&self) -> Path {
let mut path = Path::new(&["node", "import"]);
match self.profile {
@@ -91,11 +90,7 @@ impl core::BenchmarkDescription for ImportBenchmarkDescription {
fn setup(self: Box<Self>) -> Box<dyn core::Benchmark> {
let profile = self.profile;
let mut bench_db = BenchDb::with_key_types(
self.database_type,
50_000,
self.key_types
);
let mut bench_db = BenchDb::with_key_types(self.database_type, 50_000, self.key_types);
let block = bench_db.generate_block(self.block_type.to_content(self.size.transactions()));
Box::new(ImportBenchmark {
database: bench_db,
@@ -108,11 +103,9 @@ impl core::BenchmarkDescription for ImportBenchmarkDescription {
fn name(&self) -> Cow<'static, str> {
format!(
"Block import ({:?}/{}, {:?}, {:?} backend)",
self.block_type,
self.size,
self.profile,
self.database_type,
).into()
self.block_type, self.size, self.profile, self.database_type,
)
.into()
}
}
@@ -120,7 +113,9 @@ impl core::Benchmark for ImportBenchmark {
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))
let _ = context
.client
.runtime_version_at(&BlockId::Number(0))
.expect("Failed to get runtime version")
.spec_version;
@@ -133,7 +128,8 @@ impl core::Benchmark for ImportBenchmark {
let elapsed = start.elapsed();
// Sanity checks.
context.client
context
.client
.state_at(&BlockId::number(1))
.expect("state_at failed for block#1")
.inspect_state(|| {
@@ -155,19 +151,17 @@ impl core::Benchmark for ImportBenchmark {
BlockType::Noop => {
assert_eq!(
node_runtime::System::events().len(),
// should be 2 per signed extrinsic + 1 per unsigned
// we have 1 unsigned and the rest are signed in the block
// those 2 events per signed are:
// - deposit event for charging transaction fee
// - extrinsic success
(self.block.extrinsics.len() - 1) * 2 + 1,
(self.block.extrinsics.len() - 1) * 2 + 1,
);
},
_ => {},
}
}
);
});
if mode == Mode::Profile {
std::thread::park_timeout(std::time::Duration::from_secs(1));
+26 -13
View File
@@ -18,9 +18,10 @@
mod common;
mod construct;
#[macro_use] mod core;
mod import;
#[macro_use]
mod core;
mod generator;
mod import;
mod simple_trie;
mod state_sizes;
mod tempdb;
@@ -29,15 +30,15 @@ mod txpool;
use structopt::StructOpt;
use node_testing::bench::{Profile, KeyTypes, BlockType, DatabaseType as BenchDataBaseType};
use node_testing::bench::{BlockType, DatabaseType as BenchDataBaseType, KeyTypes, Profile};
use crate::{
common::SizeType,
core::{run_benchmark, Mode as BenchmarkMode},
tempdb::DatabaseType,
import::ImportBenchmarkDescription,
trie::{TrieReadBenchmarkDescription, TrieWriteBenchmarkDescription, DatabaseSize},
construct::ConstructionBenchmarkDescription,
core::{run_benchmark, Mode as BenchmarkMode},
import::ImportBenchmarkDescription,
tempdb::DatabaseType,
trie::{DatabaseSize, TrieReadBenchmarkDescription, TrieWriteBenchmarkDescription},
txpool::PoolBenchmarkDescription,
};
@@ -92,14 +93,25 @@ fn main() {
SizeType::Large,
SizeType::Full,
SizeType::Custom(opt.transactions.unwrap_or(0)),
].iter() {
]
.iter()
{
for block_type in [
BlockType::RandomTransfersKeepAlive,
BlockType::RandomTransfersReaping,
BlockType::Noop,
].iter() {
for database_type in [BenchDataBaseType::RocksDb, BenchDataBaseType::ParityDb].iter() {
import_benchmarks.push((profile, size.clone(), block_type.clone(), database_type));
]
.iter()
{
for database_type in
[BenchDataBaseType::RocksDb, BenchDataBaseType::ParityDb].iter()
{
import_benchmarks.push((
profile,
size.clone(),
block_type.clone(),
database_type,
));
}
}
}
@@ -163,7 +175,7 @@ fn main() {
println!("{}: {}", benchmark.name(), benchmark.path().full())
}
}
return;
return
}
let mut results = Vec::new();
@@ -183,7 +195,8 @@ fn main() {
}
if opt.json {
let json_result: String = serde_json::to_string(&results).expect("Failed to construct json");
let json_result: String =
serde_json::to_string(&results).expect("Failed to construct json");
println!("{}", json_result);
}
}
+5 -3
View File
@@ -18,10 +18,10 @@
use std::{collections::HashMap, sync::Arc};
use hash_db::{AsHashDB, HashDB, Hasher as _, Prefix};
use kvdb::KeyValueDB;
use node_primitives::Hash;
use sp_trie::DBValue;
use hash_db::{HashDB, AsHashDB, Prefix, Hasher as _};
pub type Hasher = sp_core::Blake2Hasher;
@@ -32,7 +32,9 @@ pub struct SimpleTrie<'a> {
}
impl<'a> AsHashDB<Hasher, DBValue> for SimpleTrie<'a> {
fn as_hash_db(&self) -> &dyn hash_db::HashDB<Hasher, DBValue> { &*self }
fn as_hash_db(&self) -> &dyn hash_db::HashDB<Hasher, DBValue> {
&*self
}
fn as_hash_db_mut<'b>(&'b mut self) -> &'b mut (dyn HashDB<Hasher, DBValue> + 'b) {
&mut *self
@@ -43,7 +45,7 @@ impl<'a> HashDB<Hasher, DBValue> for SimpleTrie<'a> {
fn get(&self, key: &Hash, prefix: Prefix) -> Option<DBValue> {
let key = sp_trie::prefixed_key::<Hasher>(key, prefix);
if let Some(value) = self.overlay.get(&key) {
return value.clone();
return value.clone()
}
self.db.get(0, &key).expect("Database backend error")
}
+1 -1
View File
@@ -17,7 +17,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/// Kusama value size distribution
pub const KUSAMA_STATE_DISTRIBUTION: &'static[(u32, u32)] = &[
pub const KUSAMA_STATE_DISTRIBUTION: &'static [(u32, u32)] = &[
(32, 35),
(33, 20035),
(34, 5369),
+23 -29
View File
@@ -16,9 +16,9 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use kvdb::{DBTransaction, KeyValueDB};
use kvdb_rocksdb::{Database, DatabaseConfig};
use std::{io, path::PathBuf, sync::Arc};
use kvdb::{KeyValueDB, DBTransaction};
use kvdb_rocksdb::{DatabaseConfig, Database};
#[derive(Debug, Clone, Copy, derive_more::Display)]
pub enum DatabaseType {
@@ -44,13 +44,14 @@ impl KeyValueDB for ParityDbWrapper {
/// Write a transaction of changes to the buffer.
fn write(&self, transaction: DBTransaction) -> io::Result<()> {
self.0.commit(
transaction.ops.iter().map(|op| match op {
kvdb::DBOp::Insert { col, key, value } => (*col as u8, &key[key.len() - 32..], Some(value.to_vec())),
self.0
.commit(transaction.ops.iter().map(|op| match op {
kvdb::DBOp::Insert { col, key, value } =>
(*col as u8, &key[key.len() - 32..], Some(value.to_vec())),
kvdb::DBOp::Delete { col, key } => (*col as u8, &key[key.len() - 32..], None),
kvdb::DBOp::DeletePrefix { col: _, prefix: _ } => unimplemented!()
})
).expect("db error");
kvdb::DBOp::DeletePrefix { col: _, prefix: _ } => unimplemented!(),
}))
.expect("db error");
Ok(())
}
@@ -90,21 +91,19 @@ impl TempDatabase {
match db_type {
DatabaseType::RocksDb => {
let db_cfg = DatabaseConfig::with_columns(1);
let db = Database::open(&db_cfg, &self.0.path().to_string_lossy()).expect("Database backend error");
let db = Database::open(&db_cfg, &self.0.path().to_string_lossy())
.expect("Database backend error");
Arc::new(db)
},
DatabaseType::ParityDb => {
Arc::new(ParityDbWrapper({
let mut options = parity_db::Options::with_columns(self.0.path(), 1);
let mut column_options = &mut options.columns[0];
column_options.ref_counted = true;
column_options.preimage = true;
column_options.uniform = true;
parity_db::Db::open(&options).expect("db open error")
}))
}
DatabaseType::ParityDb => Arc::new(ParityDbWrapper({
let mut options = parity_db::Options::with_columns(self.0.path(), 1);
let mut column_options = &mut options.columns[0];
column_options.ref_counted = true;
column_options.preimage = true;
column_options.uniform = true;
parity_db::Db::open(&options).expect("db open error")
})),
}
}
}
@@ -121,15 +120,10 @@ impl Clone for TempDatabase {
);
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()
).collect::<Vec<PathBuf>>();
fs_extra::copy_items(
&self_db_files,
new_dir.path(),
&fs_extra::dir::CopyOptions::new(),
).expect("Copy of seed database is ok");
.map(|f_result| f_result.expect("failed to read file in seed db").path())
.collect::<Vec<PathBuf>>();
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)
}
+20 -27
View File
@@ -18,13 +18,13 @@
//! Trie benchmark (integrated).
use std::{borrow::Cow, collections::HashMap, sync::Arc};
use hash_db::Prefix;
use kvdb::KeyValueDB;
use lazy_static::lazy_static;
use rand::Rng;
use hash_db::Prefix;
use sp_state_machine::Backend as _;
use sp_trie::{trie_types::TrieDBMut, TrieMut as _};
use std::{borrow::Cow, collections::HashMap, sync::Arc};
use node_primitives::Hash;
@@ -32,7 +32,7 @@ use crate::{
core::{self, Mode, Path},
generator::generate_trie,
simple_trie::SimpleTrie,
tempdb::{TempDatabase, DatabaseType},
tempdb::{DatabaseType, TempDatabase},
};
pub const SAMPLE_SIZE: usize = 100;
@@ -142,10 +142,7 @@ impl core::BenchmarkDescription for TrieReadBenchmarkDescription {
assert_eq!(warmup_keys.len(), SAMPLE_SIZE);
assert_eq!(query_keys.len(), SAMPLE_SIZE);
let root = generate_trie(
database.open(self.database_type),
key_values,
);
let root = generate_trie(database.open(self.database_type), key_values);
Box::new(TrieReadBenchmark {
database,
@@ -162,7 +159,8 @@ impl core::BenchmarkDescription for TrieReadBenchmarkDescription {
self.database_size,
pretty_print(self.database_size.keys()),
self.database_type,
).into()
)
.into()
}
}
@@ -182,12 +180,10 @@ impl core::Benchmark for TrieReadBenchmark {
let storage: Arc<dyn sp_state_machine::Storage<sp_core::Blake2Hasher>> =
Arc::new(Storage(db.open(self.database_type)));
let trie_backend = sp_state_machine::TrieBackend::new(
storage,
self.root,
);
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[..])
let value = trie_backend
.storage(&warmup_key[..])
.expect("Failed to get key: db error")
.expect("Warmup key should exist");
@@ -218,7 +214,6 @@ pub struct TrieWriteBenchmarkDescription {
pub database_type: DatabaseType,
}
impl core::BenchmarkDescription for TrieWriteBenchmarkDescription {
fn path(&self) -> Path {
let mut path = Path::new(&["trie", "write"]);
@@ -253,10 +248,7 @@ impl core::BenchmarkDescription for TrieWriteBenchmarkDescription {
assert_eq!(warmup_keys.len(), SAMPLE_SIZE);
let root = generate_trie(
database.open(self.database_type),
key_values,
);
let root = generate_trie(database.open(self.database_type), key_values);
Box::new(TrieWriteBenchmark {
database,
@@ -272,7 +264,8 @@ impl core::BenchmarkDescription for TrieWriteBenchmarkDescription {
self.database_size,
pretty_print(self.database_size.keys()),
self.database_type,
).into()
)
.into()
}
}
@@ -292,15 +285,13 @@ impl core::Benchmark for TrieWriteBenchmark {
let mut new_root = self.root.clone();
let mut overlay = HashMap::new();
let mut trie = SimpleTrie {
db: kvdb.clone(),
overlay: &mut overlay,
};
let mut trie_db_mut = TrieDBMut::from_existing(&mut trie, &mut new_root)
.expect("Failed to create TrieDBMut");
let mut trie = SimpleTrie { db: kvdb.clone(), overlay: &mut overlay };
let mut trie_db_mut =
TrieDBMut::from_existing(&mut trie, &mut new_root).expect("Failed to create TrieDBMut");
for (warmup_key, warmup_value) in self.warmup_keys.iter() {
let value = trie_db_mut.get(&warmup_key[..])
let value = trie_db_mut
.get(&warmup_key[..])
.expect("Failed to get key: db error")
.expect("Warmup key should exist");
@@ -367,7 +358,9 @@ impl SizePool {
fn value<R: Rng>(&self, rng: &mut R) -> Vec<u8> {
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 mut range = self
.distribution
.range((std::ops::Bound::Included(sr), std::ops::Bound::Unbounded));
let size = *range.next().unwrap().1 as usize;
random_vec(rng, size)
}
+19 -23
View File
@@ -23,13 +23,13 @@
use std::borrow::Cow;
use node_testing::bench::{BenchDb, Profile, BlockType, KeyTypes, DatabaseType};
use node_testing::bench::{BenchDb, BlockType, DatabaseType, KeyTypes, Profile};
use sc_transaction_pool::BasicPool;
use sp_runtime::generic::BlockId;
use sc_transaction_pool_api::{TransactionPool, TransactionSource};
use sp_runtime::generic::BlockId;
use crate::core::{self, Path, Mode};
use crate::core::{self, Mode, Path};
pub struct PoolBenchmarkDescription {
pub database_type: DatabaseType,
@@ -46,11 +46,7 @@ impl core::BenchmarkDescription for PoolBenchmarkDescription {
fn setup(self: Box<Self>) -> Box<dyn core::Benchmark> {
Box::new(PoolBenchmark {
database: BenchDb::with_key_types(
self.database_type,
50_000,
KeyTypes::Sr25519,
),
database: BenchDb::with_key_types(self.database_type, 50_000, KeyTypes::Sr25519),
})
}
@@ -63,7 +59,9 @@ impl core::Benchmark for PoolBenchmark {
fn run(&mut self, mode: Mode) -> std::time::Duration {
let context = self.database.create_context(Profile::Wasm);
let _ = context.client.runtime_version_at(&BlockId::Number(0))
let _ = context
.client
.runtime_version_at(&BlockId::Number(0))
.expect("Failed to get runtime version")
.spec_version;
@@ -80,22 +78,20 @@ impl core::Benchmark for PoolBenchmark {
context.client.clone(),
);
let generated_transactions = self.database.block_content(
BlockType::RandomTransfersKeepAlive.to_content(Some(100)),
&context.client,
).into_iter().collect::<Vec<_>>();
let generated_transactions = self
.database
.block_content(
BlockType::RandomTransfersKeepAlive.to_content(Some(100)),
&context.client,
)
.into_iter()
.collect::<Vec<_>>();
let start = std::time::Instant::now();
let submissions = generated_transactions.into_iter().map(|tx| {
txpool.submit_one(
&BlockId::Number(0),
TransactionSource::External,
tx,
)
});
futures::executor::block_on(
futures::future::join_all(submissions)
);
let submissions = generated_transactions
.into_iter()
.map(|tx| txpool.submit_one(&BlockId::Number(0), TransactionSource::External, tx));
futures::executor::block_on(futures::future::join_all(submissions));
let elapsed = start.elapsed();
if mode == Mode::Profile {
+9 -11
View File
@@ -28,11 +28,11 @@
//! 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 jsonrpc_core::types::{Id, MethodCall, Params, Success, Version};
use serde::de::DeserializeOwned;
use wasm_bindgen::JsValue;
use wasm_bindgen_futures::JsFuture;
use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure};
wasm_bindgen_test_configure!(run_in_browser);
@@ -41,8 +41,9 @@ fn rpc_call(method: &str) -> String {
jsonrpc: Some(Version::V2),
method: method.into(),
params: Params::None,
id: Id::Num(1)
}).unwrap()
id: Id::Num(1),
})
.unwrap()
}
fn deserialize_rpc_result<T: DeserializeOwned>(js_value: JsValue) -> T {
@@ -55,15 +56,12 @@ fn deserialize_rpc_result<T: DeserializeOwned>(js_value: JsValue) -> T {
#[wasm_bindgen_test]
async fn runs() {
let mut client = node_cli::start_client(None, "info".into())
.unwrap();
let mut client = node_cli::start_client(None, "info".into()).unwrap();
// 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()
JsFuture::from(client.rpc_send(&rpc_call("system_chain"))).await.unwrap(),
);
assert_eq!(chain_name, "Development");
}
+7 -4
View File
@@ -25,8 +25,8 @@ fn main() {
mod cli {
include!("src/cli.rs");
use std::{fs, env, path::Path};
use sc_cli::structopt::clap::Shell;
use std::{env, fs, path::Path};
use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed};
pub fn main() {
@@ -51,9 +51,12 @@ mod cli {
Some(dir) => dir,
};
let path = Path::new(&outdir)
.parent().unwrap()
.parent().unwrap()
.parent().unwrap()
.parent()
.unwrap()
.parent()
.unwrap()
.parent()
.unwrap()
.join("completion-scripts");
fs::create_dir(&path).ok();
+5 -10
View File
@@ -17,18 +17,14 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::chain_spec::ChainSpec;
use browser_utils::{browser_configuration, init_logging, set_console_error_panic_hook, Client};
use log::info;
use wasm_bindgen::prelude::*;
use browser_utils::{
Client,
browser_configuration, init_logging, set_console_error_panic_hook,
};
/// Starts the client.
#[wasm_bindgen]
pub fn start_client(chain_spec: Option<String>, log_level: String) -> Result<Client, JsValue> {
start_inner(chain_spec, log_level)
.map_err(|err| JsValue::from_str(&err.to_string()))
start_inner(chain_spec, log_level).map_err(|err| JsValue::from_str(&err.to_string()))
}
fn start_inner(
@@ -53,10 +49,9 @@ fn start_inner(
info!("👤 Role: {:?}", config.role);
// Create the service. This is the most heavy initialization step.
let (task_manager, rpc_handlers) =
crate::service::new_light_base(config)
.map(|(components, rpc_handlers, _, _, _)| (components, rpc_handlers))
.map_err(|e| format!("{:?}", e))?;
let (task_manager, rpc_handlers) = crate::service::new_light_base(config)
.map(|(components, rpc_handlers, _, _, _)| (components, rpc_handlers))
.map_err(|e| format!("{:?}", e))?;
Ok(browser_utils::start_client(task_manager, rpc_handlers))
}
+171 -146
View File
@@ -18,25 +18,26 @@
//! Substrate chain configurations.
use sc_chain_spec::ChainSpecExtension;
use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519};
use serde::{Serialize, Deserialize};
use node_runtime::{
AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, CouncilConfig,
DemocracyConfig, GrandpaConfig, ImOnlineConfig, SessionConfig, SessionKeys, StakerStatus,
StakingConfig, ElectionsConfig, IndicesConfig, SocietyConfig, SudoConfig, SystemConfig,
TechnicalCommitteeConfig, wasm_binary_unwrap, MAX_NOMINATIONS,
};
use node_runtime::Block;
use node_runtime::constants::currency::*;
use sc_service::ChainType;
use grandpa_primitives::AuthorityId as GrandpaId;
use hex_literal::hex;
use node_runtime::{
constants::currency::*, wasm_binary_unwrap, AuthorityDiscoveryConfig, BabeConfig,
BalancesConfig, Block, CouncilConfig, DemocracyConfig, ElectionsConfig, GrandpaConfig,
ImOnlineConfig, IndicesConfig, SessionConfig, SessionKeys, SocietyConfig, StakerStatus,
StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeConfig, MAX_NOMINATIONS,
};
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
use sc_chain_spec::ChainSpecExtension;
use sc_service::ChainType;
use sc_telemetry::TelemetryEndpoints;
use grandpa_primitives::{AuthorityId as GrandpaId};
use sp_consensus_babe::{AuthorityId as BabeId};
use pallet_im_online::sr25519::{AuthorityId as ImOnlineId};
use serde::{Deserialize, Serialize};
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
use sp_runtime::{Perbill, traits::{Verify, IdentifyAccount}};
use sp_consensus_babe::AuthorityId as BabeId;
use sp_core::{crypto::UncheckedInto, sr25519, Pair, Public};
use sp_runtime::{
traits::{IdentifyAccount, Verify},
Perbill,
};
pub use node_primitives::{AccountId, Balance, Signature};
pub use node_runtime::GenesisConfig;
@@ -59,10 +60,7 @@ pub struct Extensions {
}
/// Specialized `ChainSpec`.
pub type ChainSpec = sc_service::GenericChainSpec<
GenesisConfig,
Extensions,
>;
pub type ChainSpec = sc_service::GenericChainSpec<GenesisConfig, Extensions>;
/// Flaming Fir testnet generator
pub fn flaming_fir_config() -> Result<ChainSpec, String> {
ChainSpec::from_json_bytes(&include_bytes!("../res/flaming-fir.json")[..])
@@ -84,65 +82,94 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
// and
// for i in 1 2 3 4 ; do for j in session; do subkey --ed25519 inspect "$secret"//fir//$j//$i; done; done
let initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId)> = vec![(
// 5Fbsd6WXDGiLTxunqeK5BATNiocfCqu9bS1yArVjCgeBLkVy
hex!["9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12"].into(),
// 5EnCiV7wSHeNhjW3FSUwiJNkcc2SBkPLn5Nj93FmbLtBjQUq
hex!["781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276"].into(),
// 5Fb9ayurnxnaXj56CjmyQLBiadfRCqUbL2VWNbbe1nZU6wiC
hex!["9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe9699332"].unchecked_into(),
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(),
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(),
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(),
),(
// 5ERawXCzCWkjVq3xz1W5KGNtVx2VdefvZ62Bw1FEuZW4Vny2
hex!["68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78"].into(),
// 5Gc4vr42hH1uDZc93Nayk5G7i687bAQdHHc9unLuyeawHipF
hex!["c8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e"].into(),
// 5EockCXN6YkiNCDjpqqnbcqd4ad35nU4RmA1ikM4YeRN4WcE
hex!["7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f"].unchecked_into(),
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(),
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(),
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(),
),(
// 5DyVtKWPidondEu8iHZgi6Ffv9yrJJ1NDNLom3X9cTDi98qp
hex!["547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65"].into(),
// 5FeD54vGVNpFX3PndHPXJ2MDakc462vBCD5mgtWRnWYCpZU9
hex!["9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526"].into(),
// 5E1jLYfLdUQKrFrtqoKgFrRvxM3oQPMbf6DfcsrugZZ5Bn8d
hex!["5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440"].unchecked_into(),
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(),
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(),
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(),
),(
// 5HYZnKWe5FVZQ33ZRJK1rG3WaLMztxWrrNDb1JRwaHHVWyP9
hex!["f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663"].into(),
// 5EPQdAQ39WQNLCRjWsCk5jErsCitHiY5ZmjfWzzbXDoAoYbn
hex!["66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f"].into(),
// 5DMa31Hd5u1dwoRKgC4uvqyrdK45RHv3CpwvpUC1EzuwDit4
hex!["3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef"].unchecked_into(),
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"].unchecked_into(),
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"].unchecked_into(),
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"].unchecked_into(),
)];
let initial_authorities: Vec<(
AccountId,
AccountId,
GrandpaId,
BabeId,
ImOnlineId,
AuthorityDiscoveryId,
)> = vec![
(
// 5Fbsd6WXDGiLTxunqeK5BATNiocfCqu9bS1yArVjCgeBLkVy
hex!["9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12"].into(),
// 5EnCiV7wSHeNhjW3FSUwiJNkcc2SBkPLn5Nj93FmbLtBjQUq
hex!["781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276"].into(),
// 5Fb9ayurnxnaXj56CjmyQLBiadfRCqUbL2VWNbbe1nZU6wiC
hex!["9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe9699332"]
.unchecked_into(),
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"]
.unchecked_into(),
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"]
.unchecked_into(),
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"]
.unchecked_into(),
),
(
// 5ERawXCzCWkjVq3xz1W5KGNtVx2VdefvZ62Bw1FEuZW4Vny2
hex!["68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78"].into(),
// 5Gc4vr42hH1uDZc93Nayk5G7i687bAQdHHc9unLuyeawHipF
hex!["c8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e"].into(),
// 5EockCXN6YkiNCDjpqqnbcqd4ad35nU4RmA1ikM4YeRN4WcE
hex!["7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f"]
.unchecked_into(),
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"]
.unchecked_into(),
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"]
.unchecked_into(),
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"]
.unchecked_into(),
),
(
// 5DyVtKWPidondEu8iHZgi6Ffv9yrJJ1NDNLom3X9cTDi98qp
hex!["547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65"].into(),
// 5FeD54vGVNpFX3PndHPXJ2MDakc462vBCD5mgtWRnWYCpZU9
hex!["9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526"].into(),
// 5E1jLYfLdUQKrFrtqoKgFrRvxM3oQPMbf6DfcsrugZZ5Bn8d
hex!["5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440"]
.unchecked_into(),
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"]
.unchecked_into(),
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"]
.unchecked_into(),
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"]
.unchecked_into(),
),
(
// 5HYZnKWe5FVZQ33ZRJK1rG3WaLMztxWrrNDb1JRwaHHVWyP9
hex!["f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663"].into(),
// 5EPQdAQ39WQNLCRjWsCk5jErsCitHiY5ZmjfWzzbXDoAoYbn
hex!["66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f"].into(),
// 5DMa31Hd5u1dwoRKgC4uvqyrdK45RHv3CpwvpUC1EzuwDit4
hex!["3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef"]
.unchecked_into(),
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"]
.unchecked_into(),
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"]
.unchecked_into(),
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"]
.unchecked_into(),
),
];
// generated with secret: subkey inspect "$secret"/fir
let root_key: AccountId = hex![
// 5Ff3iXP75ruzroPWRP2FYBHWnmGGBSb63857BgnzCoXNxfPo
"9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809"
].into();
]
.into();
let endowed_accounts: Vec<AccountId> = vec![root_key.clone()];
@@ -158,8 +185,10 @@ pub fn staging_testnet_config() -> ChainSpec {
ChainType::Live,
staging_testnet_config_genesis,
boot_nodes,
Some(TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)])
.expect("Staging telemetry url is valid; qed")),
Some(
TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)])
.expect("Staging telemetry url is valid; qed"),
),
None,
None,
Default::default(),
@@ -174,21 +203,17 @@ pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Pu
}
/// Helper function to generate an account ID from seed
pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId where
AccountPublic: From<<TPublic::Pair as Pair>::Public>
pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
where
AccountPublic: From<<TPublic::Pair as Pair>::Public>,
{
AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
}
/// Helper function to generate stash, controller and session key from seed
pub fn authority_keys_from_seed(seed: &str) -> (
AccountId,
AccountId,
GrandpaId,
BabeId,
ImOnlineId,
AuthorityDiscoveryId,
) {
pub fn authority_keys_from_seed(
seed: &str,
) -> (AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId) {
(
get_account_id_from_seed::<sr25519::Public>(&format!("{}//stash", seed)),
get_account_id_from_seed::<sr25519::Public>(seed),
@@ -230,11 +255,15 @@ pub fn testnet_genesis(
]
});
// endow all authorities and nominators.
initial_authorities.iter().map(|x| &x.0).chain(initial_nominators.iter()).for_each(|x| {
if !endowed_accounts.contains(&x) {
endowed_accounts.push(x.clone())
}
});
initial_authorities
.iter()
.map(|x| &x.0)
.chain(initial_nominators.iter())
.for_each(|x| {
if !endowed_accounts.contains(&x) {
endowed_accounts.push(x.clone())
}
});
// stakers: all validators and nominators.
let mut rng = rand::thread_rng();
@@ -266,22 +295,20 @@ pub fn testnet_genesis(
changes_trie_config: Default::default(),
},
balances: BalancesConfig {
balances: endowed_accounts.iter().cloned()
.map(|x| (x, ENDOWMENT))
.collect()
},
indices: IndicesConfig {
indices: vec![],
balances: endowed_accounts.iter().cloned().map(|x| (x, ENDOWMENT)).collect(),
},
indices: IndicesConfig { indices: vec![] },
session: SessionConfig {
keys: initial_authorities.iter().map(|x| {
(x.0.clone(), x.0.clone(), session_keys(
x.2.clone(),
x.3.clone(),
x.4.clone(),
x.5.clone(),
))
}).collect::<Vec<_>>(),
keys: initial_authorities
.iter()
.map(|x| {
(
x.0.clone(),
x.0.clone(),
session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone()),
)
})
.collect::<Vec<_>>(),
},
staking: StakingConfig {
validator_count: initial_authorities.len() as u32,
@@ -289,47 +316,42 @@ pub fn testnet_genesis(
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
slash_reward_fraction: Perbill::from_percent(10),
stakers,
.. Default::default()
..Default::default()
},
democracy: DemocracyConfig::default(),
elections: ElectionsConfig {
members: endowed_accounts.iter()
.take((num_endowed_accounts + 1) / 2)
.cloned()
.map(|member| (member, STASH))
.collect(),
members: endowed_accounts
.iter()
.take((num_endowed_accounts + 1) / 2)
.cloned()
.map(|member| (member, STASH))
.collect(),
},
council: CouncilConfig::default(),
technical_committee: TechnicalCommitteeConfig {
members: endowed_accounts.iter()
.take((num_endowed_accounts + 1) / 2)
.cloned()
.collect(),
members: endowed_accounts
.iter()
.take((num_endowed_accounts + 1) / 2)
.cloned()
.collect(),
phantom: Default::default(),
},
sudo: SudoConfig {
key: root_key,
},
sudo: SudoConfig { key: root_key },
babe: BabeConfig {
authorities: vec![],
epoch_config: Some(node_runtime::BABE_GENESIS_EPOCH_CONFIG),
},
im_online: ImOnlineConfig {
keys: vec![],
},
authority_discovery: AuthorityDiscoveryConfig {
keys: vec![],
},
grandpa: GrandpaConfig {
authorities: vec![],
},
im_online: ImOnlineConfig { keys: vec![] },
authority_discovery: AuthorityDiscoveryConfig { keys: vec![] },
grandpa: GrandpaConfig { authorities: vec![] },
technical_membership: Default::default(),
treasury: Default::default(),
society: SocietyConfig {
members: endowed_accounts.iter()
.take((num_endowed_accounts + 1) / 2)
.cloned()
.collect(),
members: endowed_accounts
.iter()
.take((num_endowed_accounts + 1) / 2)
.cloned()
.collect(),
pot: 0,
max_members: 999,
},
@@ -341,9 +363,7 @@ pub fn testnet_genesis(
fn development_config_genesis() -> GenesisConfig {
testnet_genesis(
vec![
authority_keys_from_seed("Alice"),
],
vec![authority_keys_from_seed("Alice")],
vec![],
get_account_id_from_seed::<sr25519::Public>("Alice"),
None,
@@ -367,10 +387,7 @@ pub fn development_config() -> ChainSpec {
fn local_testnet_genesis() -> GenesisConfig {
testnet_genesis(
vec![
authority_keys_from_seed("Alice"),
authority_keys_from_seed("Bob"),
],
vec![authority_keys_from_seed("Alice"), authority_keys_from_seed("Bob")],
vec![],
get_account_id_from_seed::<sr25519::Public>("Alice"),
None,
@@ -401,9 +418,7 @@ pub(crate) mod tests {
fn local_testnet_genesis_instant_single() -> GenesisConfig {
testnet_genesis(
vec![
authority_keys_from_seed("Alice"),
],
vec![authority_keys_from_seed("Alice")],
vec![],
get_account_id_from_seed::<sr25519::Public>("Alice"),
None,
@@ -446,14 +461,24 @@ pub(crate) mod tests {
sc_service_test::connectivity(
integration_test_config_with_two_authorities(),
|config| {
let NewFullBase { task_manager, client, network, transaction_pool, .. }
= new_full_base(config,|_, _| ())?;
Ok(sc_service_test::TestNetComponents::new(task_manager, client, network, transaction_pool))
let NewFullBase { task_manager, client, network, transaction_pool, .. } =
new_full_base(config, |_, _| ())?;
Ok(sc_service_test::TestNetComponents::new(
task_manager,
client,
network,
transaction_pool,
))
},
|config| {
let (keep_alive, _, client, network, transaction_pool) = new_light_base(config)?;
Ok(sc_service_test::TestNetComponents::new(keep_alive, client, network, transaction_pool))
}
Ok(sc_service_test::TestNetComponents::new(
keep_alive,
client,
network,
transaction_pool,
))
},
);
}
+1 -1
View File
@@ -16,7 +16,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use sc_cli::{RunCmd, KeySubcommand, SignCmd, VanityCmd, VerifyCmd};
use sc_cli::{KeySubcommand, RunCmd, SignCmd, VanityCmd, VerifyCmd};
use structopt::StructOpt;
/// An overarching CLI command definition.
+36 -39
View File
@@ -16,12 +16,11 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::{chain_spec, service, Cli, Subcommand};
use crate::{chain_spec, service, service::new_partial, Cli, Subcommand};
use node_executor::Executor;
use node_runtime::{Block, RuntimeApi};
use sc_cli::{Result, SubstrateCli, RuntimeVersion, Role, ChainSpec};
use sc_cli::{ChainSpec, Result, Role, RuntimeVersion, SubstrateCli};
use sc_service::PartialComponents;
use crate::service::new_partial;
impl SubstrateCli for Cli {
fn impl_name() -> String {
@@ -49,17 +48,19 @@ impl SubstrateCli for Cli {
}
fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
let spec =
match id {
"" => return Err("Please specify which chain you want to run, e.g. --dev or --chain=local".into()),
"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),
)?),
};
let spec = match id {
"" =>
return Err(
"Please specify which chain you want to run, e.g. --dev or --chain=local"
.into(),
),
"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))?),
};
Ok(spec)
}
@@ -79,24 +80,25 @@ pub fn run() -> Result<()> {
match config.role {
Role::Light => service::new_light(config),
_ => service::new_full(config),
}.map_err(sc_cli::Error::Service)
}
.map_err(sc_cli::Error::Service)
})
}
},
Some(Subcommand::Inspect(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.sync_run(|config| cmd.run::<Block, RuntimeApi, Executor>(config))
}
Some(Subcommand::Benchmark(cmd)) => {
},
Some(Subcommand::Benchmark(cmd)) =>
if cfg!(feature = "runtime-benchmarks") {
let runner = cli.create_runner(cmd)?;
runner.sync_run(|config| cmd.run::<Block, Executor>(config))
} else {
Err("Benchmarking wasn't enabled when building the node. \
You can enable it with `--features runtime-benchmarks`.".into())
}
}
You can enable it with `--features runtime-benchmarks`."
.into())
},
Some(Subcommand::Key(cmd)) => cmd.run(&cli),
Some(Subcommand::Sign(cmd)) => cmd.run(),
Some(Subcommand::Verify(cmd)) => cmd.run(),
@@ -108,32 +110,30 @@ pub fn run() -> Result<()> {
Some(Subcommand::CheckBlock(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|config| {
let PartialComponents { client, task_manager, import_queue, ..}
= new_partial(&config)?;
let PartialComponents { client, task_manager, import_queue, .. } =
new_partial(&config)?;
Ok((cmd.run(client, import_queue), task_manager))
})
},
Some(Subcommand::ExportBlocks(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|config| {
let PartialComponents { client, task_manager, ..}
= new_partial(&config)?;
let PartialComponents { client, task_manager, .. } = new_partial(&config)?;
Ok((cmd.run(client, config.database), task_manager))
})
},
Some(Subcommand::ExportState(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|config| {
let PartialComponents { client, task_manager, ..}
= new_partial(&config)?;
let PartialComponents { client, task_manager, .. } = new_partial(&config)?;
Ok((cmd.run(client, config.chain_spec), task_manager))
})
},
Some(Subcommand::ImportBlocks(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|config| {
let PartialComponents { client, task_manager, import_queue, ..}
= new_partial(&config)?;
let PartialComponents { client, task_manager, import_queue, .. } =
new_partial(&config)?;
Ok((cmd.run(client, import_queue), task_manager))
})
},
@@ -144,8 +144,7 @@ pub fn run() -> Result<()> {
Some(Subcommand::Revert(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|config| {
let PartialComponents { client, task_manager, backend, ..}
= new_partial(&config)?;
let PartialComponents { client, task_manager, backend, .. } = new_partial(&config)?;
Ok((cmd.run(client, backend), task_manager))
})
},
@@ -156,18 +155,16 @@ pub fn run() -> Result<()> {
// we don't need any of the components of new_partial, just a runtime, or a task
// manager to do `async_run`.
let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry);
let task_manager = sc_service::TaskManager::new(
config.task_executor.clone(),
registry,
).map_err(|e| sc_cli::Error::Service(sc_service::Error::Prometheus(e)))?;
let task_manager =
sc_service::TaskManager::new(config.task_executor.clone(), registry)
.map_err(|e| sc_cli::Error::Service(sc_service::Error::Prometheus(e)))?;
Ok((cmd.run::<Block, Executor>(config), task_manager))
})
},
#[cfg(not(feature = "try-runtime"))]
Some(Subcommand::TryRuntime) => {
Err("TryRuntime wasn't enabled when building the node. \
You can enable it with `--features try-runtime`.".into())
},
Some(Subcommand::TryRuntime) => Err("TryRuntime wasn't enabled when building the node. \
You can enable it with `--features try-runtime`."
.into()),
}
}
+238 -240
View File
@@ -20,20 +20,17 @@
//! Service implementation. Specialized wrapper over substrate service.
use std::sync::Arc;
use sc_consensus_babe;
use futures::prelude::*;
use node_executor::Executor;
use node_primitives::Block;
use node_runtime::RuntimeApi;
use sc_service::{
config::Configuration, error::Error as ServiceError, RpcHandlers, TaskManager,
};
use sc_network::{Event, NetworkService};
use sp_runtime::traits::Block as BlockT;
use futures::prelude::*;
use sc_client_api::{ExecutorProvider, RemoteBackend};
use node_executor::Executor;
use sc_consensus_babe::{self, SlotProportion};
use sc_network::{Event, NetworkService};
use sc_service::{config::Configuration, error::Error as ServiceError, RpcHandlers, TaskManager};
use sc_telemetry::{Telemetry, TelemetryWorker};
use sc_consensus_babe::SlotProportion;
use sp_runtime::traits::Block as BlockT;
use std::sync::Arc;
type FullClient = sc_service::TFullClient<Block, RuntimeApi, Executor>;
type FullBackend = sc_service::TFullBackend<Block>;
@@ -44,25 +41,29 @@ type LightClient = sc_service::TLightClient<Block, RuntimeApi, Executor>;
pub fn new_partial(
config: &Configuration,
) -> Result<sc_service::PartialComponents<
FullClient, FullBackend, FullSelectChain,
sp_consensus::DefaultImportQueue<Block, FullClient>,
sc_transaction_pool::FullPool<Block, FullClient>,
(
impl Fn(
node_rpc::DenyUnsafe,
sc_rpc::SubscriptionTaskExecutor,
) -> node_rpc::IoHandler,
) -> Result<
sc_service::PartialComponents<
FullClient,
FullBackend,
FullSelectChain,
sp_consensus::DefaultImportQueue<Block, FullClient>,
sc_transaction_pool::FullPool<Block, FullClient>,
(
sc_consensus_babe::BabeBlockImport<Block, FullClient, FullGrandpaBlockImport>,
grandpa::LinkHalf<Block, FullClient, FullSelectChain>,
sc_consensus_babe::BabeLink<Block>,
impl Fn(node_rpc::DenyUnsafe, sc_rpc::SubscriptionTaskExecutor) -> node_rpc::IoHandler,
(
sc_consensus_babe::BabeBlockImport<Block, FullClient, FullGrandpaBlockImport>,
grandpa::LinkHalf<Block, FullClient, FullSelectChain>,
sc_consensus_babe::BabeLink<Block>,
),
grandpa::SharedVoterState,
Option<Telemetry>,
),
grandpa::SharedVoterState,
Option<Telemetry>,
)
>, ServiceError> {
let telemetry = config.telemetry_endpoints.clone()
>,
ServiceError,
> {
let telemetry = config
.telemetry_endpoints
.clone()
.filter(|x| !x.is_empty())
.map(|endpoints| -> Result<_, sc_telemetry::Error> {
let worker = TelemetryWorker::new(16)?;
@@ -78,11 +79,10 @@ pub fn new_partial(
)?;
let client = Arc::new(client);
let telemetry = telemetry
.map(|(worker, telemetry)| {
task_manager.spawn_handle().spawn("telemetry", worker.run());
telemetry
});
let telemetry = telemetry.map(|(worker, telemetry)| {
task_manager.spawn_handle().spawn("telemetry", worker.run());
telemetry
});
let select_chain = sc_consensus::LongestChain::new(backend.clone());
@@ -115,21 +115,19 @@ pub fn new_partial(
Some(Box::new(justification_import)),
client.clone(),
select_chain.clone(),
move |_, ()| {
async move {
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
move |_, ()| async move {
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
let slot =
sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_duration(
*timestamp,
slot_duration,
);
let slot =
sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_duration(
*timestamp,
slot_duration,
);
let uncles =
sp_authorship::InherentDataProvider::<<Block as BlockT>::Header>::check_inherents();
let uncles =
sp_authorship::InherentDataProvider::<<Block as BlockT>::Header>::check_inherents();
Ok((timestamp, slot, uncles))
}
Ok((timestamp, slot, uncles))
},
&task_manager.spawn_essential_handle(),
config.prometheus_registry(),
@@ -213,7 +211,7 @@ pub fn new_full_base(
with_startup_data: impl FnOnce(
&sc_consensus_babe::BabeBlockImport<Block, FullClient, FullGrandpaBlockImport>,
&sc_consensus_babe::BabeLink<Block>,
)
),
) -> Result<NewFullBase, ServiceError> {
let sc_service::PartialComponents {
client,
@@ -238,7 +236,7 @@ pub fn new_full_base(
task_manager.spawn_handle(),
backend.clone(),
import_setup.1.shared_authority_set().clone(),
)
),
);
let (network, system_rpc_tx, network_starter) =
@@ -254,7 +252,10 @@ pub fn new_full_base(
if config.offchain_worker.enabled {
sc_service::build_offchain_workers(
&config, task_manager.spawn_handle(), client.clone(), network.clone(),
&config,
task_manager.spawn_handle(),
client.clone(),
network.clone(),
);
}
@@ -266,22 +267,20 @@ pub fn new_full_base(
let enable_grandpa = !config.disable_grandpa;
let prometheus_registry = config.prometheus_registry().cloned();
let _rpc_handlers = sc_service::spawn_tasks(
sc_service::SpawnTasksParams {
config,
backend: backend.clone(),
client: client.clone(),
keystore: keystore_container.sync_keystore(),
network: network.clone(),
rpc_extensions_builder: Box::new(rpc_extensions_builder),
transaction_pool: transaction_pool.clone(),
task_manager: &mut task_manager,
on_demand: None,
remote_blockchain: None,
system_rpc_tx,
telemetry: telemetry.as_mut(),
},
)?;
let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams {
config,
backend: backend.clone(),
client: client.clone(),
keystore: keystore_container.sync_keystore(),
network: network.clone(),
rpc_extensions_builder: Box::new(rpc_extensions_builder),
transaction_pool: transaction_pool.clone(),
task_manager: &mut task_manager,
on_demand: None,
remote_blockchain: None,
system_rpc_tx,
telemetry: telemetry.as_mut(),
})?;
let (block_import, grandpa_link, babe_link) = import_setup;
@@ -343,36 +342,37 @@ pub fn new_full_base(
// Spawn authority discovery module.
if role.is_authority() {
let authority_discovery_role = sc_authority_discovery::Role::PublishAndDiscover(
keystore_container.keystore(),
);
let dht_event_stream = network.event_stream("authority-discovery")
.filter_map(|e| async move { match e {
Event::Dht(e) => Some(e),
_ => None,
}});
let (authority_discovery_worker, _service) = sc_authority_discovery::new_worker_and_service_with_config(
sc_authority_discovery::WorkerConfig {
publish_non_global_ips: auth_disc_publish_non_global_ips,
..Default::default()
},
client.clone(),
network.clone(),
Box::pin(dht_event_stream),
authority_discovery_role,
prometheus_registry.clone(),
);
let authority_discovery_role =
sc_authority_discovery::Role::PublishAndDiscover(keystore_container.keystore());
let dht_event_stream =
network.event_stream("authority-discovery").filter_map(|e| async move {
match e {
Event::Dht(e) => Some(e),
_ => None,
}
});
let (authority_discovery_worker, _service) =
sc_authority_discovery::new_worker_and_service_with_config(
sc_authority_discovery::WorkerConfig {
publish_non_global_ips: auth_disc_publish_non_global_ips,
..Default::default()
},
client.clone(),
network.clone(),
Box::pin(dht_event_stream),
authority_discovery_role,
prometheus_registry.clone(),
);
task_manager.spawn_handle().spawn("authority-discovery-worker", authority_discovery_worker.run());
task_manager
.spawn_handle()
.spawn("authority-discovery-worker", authority_discovery_worker.run());
}
// 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 role.is_authority() {
Some(keystore_container.sync_keystore())
} else {
None
};
let keystore =
if role.is_authority() { Some(keystore_container.sync_keystore()) } else { None };
let config = grandpa::Config {
// FIXME #1578 make this available through chainspec
@@ -404,46 +404,41 @@ pub fn new_full_base(
// the GRANDPA voter task is considered infallible, i.e.
// if it fails we take down the service with it.
task_manager.spawn_essential_handle().spawn_blocking(
"grandpa-voter",
grandpa::run_grandpa_voter(grandpa_config)?
);
task_manager
.spawn_essential_handle()
.spawn_blocking("grandpa-voter", grandpa::run_grandpa_voter(grandpa_config)?);
}
network_starter.start_network();
Ok(NewFullBase {
task_manager,
client,
network,
transaction_pool,
})
Ok(NewFullBase { task_manager, client, network, transaction_pool })
}
/// Builds a new service for a full client.
pub fn new_full(
config: Configuration,
) -> Result<TaskManager, ServiceError> {
new_full_base(config, |_, _| ()).map(|NewFullBase { task_manager, .. }| {
task_manager
})
pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
new_full_base(config, |_, _| ()).map(|NewFullBase { task_manager, .. }| task_manager)
}
pub fn new_light_base(
mut config: Configuration,
) -> Result<(
TaskManager,
RpcHandlers,
Arc<LightClient>,
Arc<NetworkService<Block, <Block as BlockT>::Hash>>,
Arc<sc_transaction_pool::LightPool<Block, LightClient, sc_network::config::OnDemand<Block>>>
), ServiceError> {
let telemetry = config.telemetry_endpoints.clone()
) -> Result<
(
TaskManager,
RpcHandlers,
Arc<LightClient>,
Arc<NetworkService<Block, <Block as BlockT>::Hash>>,
Arc<
sc_transaction_pool::LightPool<Block, LightClient, sc_network::config::OnDemand<Block>>,
>,
),
ServiceError,
> {
let telemetry = config
.telemetry_endpoints
.clone()
.filter(|x| !x.is_empty())
.map(|endpoints| -> Result<_, sc_telemetry::Error> {
#[cfg(feature = "browser")]
let transport = Some(
sc_telemetry::ExtTransport::new(libp2p_wasm_ext::ffi::websocket_transport())
);
let transport = Some(sc_telemetry::ExtTransport::new(libp2p_wasm_ext::ffi::websocket_transport()));
#[cfg(not(feature = "browser"))]
let transport = None;
@@ -459,11 +454,10 @@ pub fn new_light_base(
telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
)?;
let mut telemetry = telemetry
.map(|(worker, telemetry)| {
task_manager.spawn_handle().spawn("telemetry", worker.run());
telemetry
});
let mut telemetry = telemetry.map(|(worker, telemetry)| {
task_manager.spawn_handle().spawn("telemetry", worker.run());
telemetry
});
config.network.extra_sets.push(grandpa::grandpa_peers_set_config());
@@ -567,71 +561,60 @@ pub fn new_light_base(
let rpc_extensions = node_rpc::create_light(light_deps);
let rpc_handlers =
sc_service::spawn_tasks(sc_service::SpawnTasksParams {
on_demand: Some(on_demand),
remote_blockchain: Some(backend.remote_blockchain()),
rpc_extensions_builder: Box::new(sc_service::NoopRpcExtensionBuilder(rpc_extensions)),
client: client.clone(),
transaction_pool: transaction_pool.clone(),
keystore: keystore_container.sync_keystore(),
config, backend, system_rpc_tx,
network: network.clone(),
task_manager: &mut task_manager,
telemetry: telemetry.as_mut(),
})?;
let rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams {
on_demand: Some(on_demand),
remote_blockchain: Some(backend.remote_blockchain()),
rpc_extensions_builder: Box::new(sc_service::NoopRpcExtensionBuilder(rpc_extensions)),
client: client.clone(),
transaction_pool: transaction_pool.clone(),
keystore: keystore_container.sync_keystore(),
config,
backend,
system_rpc_tx,
network: network.clone(),
task_manager: &mut task_manager,
telemetry: telemetry.as_mut(),
})?;
network_starter.start_network();
Ok((
task_manager,
rpc_handlers,
client,
network,
transaction_pool,
))
Ok((task_manager, rpc_handlers, client, network, transaction_pool))
}
/// Builds a new service for a light client.
pub fn new_light(
config: Configuration,
) -> Result<TaskManager, ServiceError> {
new_light_base(config).map(|(task_manager, _, _, _, _)| {
task_manager
})
pub fn new_light(config: Configuration) -> Result<TaskManager, ServiceError> {
new_light_base(config).map(|(task_manager, _, _, _, _)| task_manager)
}
#[cfg(test)]
mod tests {
use std::{sync::Arc, borrow::Cow, convert::TryInto};
use sc_consensus_babe::{CompatibleDigestItem, BabeIntermediate, INTERMEDIATE_KEY};
use sc_consensus_epochs::descendent_query;
use sp_consensus::{
Environment, Proposer, BlockImportParams, BlockOrigin, ForkChoiceStrategy, BlockImport,
};
use node_primitives::{Block, DigestItem, Signature};
use node_runtime::{BalancesCall, Call, UncheckedExtrinsic, Address};
use node_runtime::constants::{currency::CENTS, time::SLOT_DURATION};
use crate::service::{new_full_base, new_light_base, NewFullBase};
use codec::Encode;
use sp_core::{
crypto::Pair as CryptoPair,
H256,
Public
use node_primitives::{Block, DigestItem, Signature};
use node_runtime::{
constants::{currency::CENTS, time::SLOT_DURATION},
Address, BalancesCall, Call, UncheckedExtrinsic,
};
use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore};
use sc_client_api::BlockBackend;
use sc_consensus_babe::{BabeIntermediate, CompatibleDigestItem, INTERMEDIATE_KEY};
use sc_consensus_epochs::descendent_query;
use sc_keystore::LocalKeystore;
use sc_service_test::TestNetNode;
use sc_transaction_pool_api::{ChainEvent, MaintainedTransactionPool};
use sp_consensus::{
BlockImport, BlockImportParams, BlockOrigin, Environment, ForkChoiceStrategy, Proposer,
};
use sp_core::{crypto::Pair as CryptoPair, Public, H256};
use sp_inherents::InherentDataProvider;
use sp_keyring::AccountKeyring;
use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr};
use sp_runtime::{
generic::{BlockId, Era, Digest, SignedPayload},
traits::{Block as BlockT, Header as HeaderT},
traits::Verify,
generic::{BlockId, Digest, Era, SignedPayload},
key_types::BABE,
traits::{Block as BlockT, Header as HeaderT, IdentifyAccount, Verify},
RuntimeAppPublic,
};
use sp_timestamp;
use sp_keyring::AccountKeyring;
use sc_service_test::TestNetNode;
use crate::service::{new_full_base, new_light_base, NewFullBase};
use sp_runtime::{key_types::BABE, traits::IdentifyAccount, RuntimeAppPublic};
use sc_transaction_pool_api::{MaintainedTransactionPool, ChainEvent};
use sc_client_api::BlockBackend;
use sc_keystore::LocalKeystore;
use sp_inherents::InherentDataProvider;
use std::{borrow::Cow, convert::TryInto, sync::Arc};
type AccountPublic = <Signature as Verify>::Signer;
@@ -641,10 +624,12 @@ mod tests {
#[ignore]
fn test_sync() {
let keystore_path = tempfile::tempdir().expect("Creates keystore path");
let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::open(keystore_path.path(), None)
.expect("Creates keystore"));
let alice: sp_consensus_babe::AuthorityId = SyncCryptoStore::sr25519_generate_new(&*keystore, BABE, Some("//Alice"))
.expect("Creates authority pair").into();
let keystore: SyncCryptoStorePtr =
Arc::new(LocalKeystore::open(keystore_path.path(), None).expect("Creates keystore"));
let alice: sp_consensus_babe::AuthorityId =
SyncCryptoStore::sr25519_generate_new(&*keystore, BABE, Some("//Alice"))
.expect("Creates authority pair")
.into();
let chain_spec = crate::chain_spec::tests::integration_test_config_with_single_authority();
@@ -660,25 +645,31 @@ mod tests {
chain_spec,
|config| {
let mut setup_handles = None;
let NewFullBase {
task_manager, client, network, transaction_pool, ..
} = new_full_base(config,
|
block_import: &sc_consensus_babe::BabeBlockImport<Block, _, _>,
babe_link: &sc_consensus_babe::BabeLink<Block>,
| {
setup_handles = Some((block_import.clone(), babe_link.clone()));
}
)?;
let NewFullBase { task_manager, client, network, transaction_pool, .. } =
new_full_base(
config,
|block_import: &sc_consensus_babe::BabeBlockImport<Block, _, _>,
babe_link: &sc_consensus_babe::BabeLink<Block>| {
setup_handles = Some((block_import.clone(), babe_link.clone()));
},
)?;
let node = sc_service_test::TestNetComponents::new(
task_manager, client, network, transaction_pool
task_manager,
client,
network,
transaction_pool,
);
Ok((node, setup_handles.unwrap()))
},
|config| {
let (keep_alive, _, client, network, transaction_pool) = new_light_base(config)?;
Ok(sc_service_test::TestNetComponents::new(keep_alive, client, network, transaction_pool))
Ok(sc_service_test::TestNetComponents::new(
keep_alive,
client,
network,
transaction_pool,
))
},
|service, &mut (ref mut block_import, ref babe_link)| {
let parent_id = BlockId::number(service.client().chain_info().best_number);
@@ -686,14 +677,9 @@ mod tests {
let parent_hash = parent_header.hash();
let parent_number = *parent_header.number();
futures::executor::block_on(
service.transaction_pool().maintain(
ChainEvent::NewBestBlock {
hash: parent_header.hash(),
tree_route: None,
},
)
);
futures::executor::block_on(service.transaction_pool().maintain(
ChainEvent::NewBestBlock { hash: parent_header.hash(), tree_route: None },
));
let mut proposer_factory = sc_basic_authorship::ProposerFactory::new(
service.spawn_handle(),
@@ -708,23 +694,30 @@ mod tests {
// even though there's only one authority some slots might be empty,
// so we must keep trying the next slots until we can claim one.
let (babe_pre_digest, epoch_descriptor) = loop {
let epoch_descriptor = babe_link.epoch_changes().shared_data().epoch_descriptor_for_child_of(
descendent_query(&*service.client()),
&parent_hash,
parent_number,
slot.into(),
).unwrap().unwrap();
let epoch_descriptor = babe_link
.epoch_changes()
.shared_data()
.epoch_descriptor_for_child_of(
descendent_query(&*service.client()),
&parent_hash,
parent_number,
slot.into(),
)
.unwrap()
.unwrap();
let epoch = babe_link.epoch_changes().shared_data().epoch_data(
&epoch_descriptor,
|slot| sc_consensus_babe::Epoch::genesis(&babe_link.config(), slot),
).unwrap();
let epoch = babe_link
.epoch_changes()
.shared_data()
.epoch_data(&epoch_descriptor, |slot| {
sc_consensus_babe::Epoch::genesis(&babe_link.config(), slot)
})
.unwrap();
if let Some(babe_pre_digest) = sc_consensus_babe::authorship::claim_slot(
slot.into(),
&epoch,
&keystore,
).map(|(digest, _)| digest) {
if let Some(babe_pre_digest) =
sc_consensus_babe::authorship::claim_slot(slot.into(), &epoch, &keystore)
.map(|(digest, _)| digest)
{
break (babe_pre_digest, epoch_descriptor)
}
@@ -736,19 +729,21 @@ mod tests {
std::time::Duration::from_millis(SLOT_DURATION * slot).into(),
),
sp_consensus_babe::inherents::InherentDataProvider::new(slot.into()),
).create_inherent_data().expect("Creates inherent data");
)
.create_inherent_data()
.expect("Creates inherent data");
digest.push(<DigestItem as CompatibleDigestItem>::babe_pre_digest(babe_pre_digest));
let new_block = futures::executor::block_on(async move {
let proposer = proposer_factory.init(&parent_header).await;
proposer.unwrap().propose(
inherent_data,
digest,
std::time::Duration::from_secs(1),
None,
).await
}).expect("Error making test block").block;
proposer
.unwrap()
.propose(inherent_data, digest, std::time::Duration::from_secs(1), None)
.await
})
.expect("Error making test block")
.block;
let (new_header, new_body) = new_block.deconstruct();
let pre_hash = new_header.hash();
@@ -760,10 +755,12 @@ mod tests {
sp_consensus_babe::AuthorityId::ID,
&alice.to_public_crypto_pair(),
&to_sign,
).unwrap().unwrap().try_into().unwrap();
let item = <DigestItem as CompatibleDigestItem>::babe_seal(
signature,
);
)
.unwrap()
.unwrap()
.try_into()
.unwrap();
let item = <DigestItem as CompatibleDigestItem>::babe_seal(signature);
slot += 1;
let mut params = BlockImportParams::new(BlockOrigin::File, new_header);
@@ -811,19 +808,13 @@ mod tests {
let raw_payload = SignedPayload::from_raw(
function,
extra,
(spec_version, transaction_version, genesis_hash, genesis_hash, (), (), ())
(spec_version, transaction_version, genesis_hash, genesis_hash, (), (), ()),
);
let signature = raw_payload.using_encoded(|payload| {
signer.sign(payload)
});
let signature = raw_payload.using_encoded(|payload| signer.sign(payload));
let (function, extra, _) = raw_payload.deconstruct();
index += 1;
UncheckedExtrinsic::new_signed(
function,
from.into(),
signature.into(),
extra,
).into()
UncheckedExtrinsic::new_signed(function, from.into(), signature.into(), extra)
.into()
},
);
}
@@ -834,18 +825,25 @@ mod tests {
sc_service_test::consensus(
crate::chain_spec::tests::integration_test_config_with_two_authorities(),
|config| {
let NewFullBase { task_manager, client, network, transaction_pool, .. }
= new_full_base(config,|_, _| ())?;
Ok(sc_service_test::TestNetComponents::new(task_manager, client, network, transaction_pool))
let NewFullBase { task_manager, client, network, transaction_pool, .. } =
new_full_base(config, |_, _| ())?;
Ok(sc_service_test::TestNetComponents::new(
task_manager,
client,
network,
transaction_pool,
))
},
|config| {
let (keep_alive, _, client, network, transaction_pool) = new_light_base(config)?;
Ok(sc_service_test::TestNetComponents::new(keep_alive, client, network, transaction_pool))
Ok(sc_service_test::TestNetComponents::new(
keep_alive,
client,
network,
transaction_pool,
))
},
vec![
"//Alice".into(),
"//Bob".into(),
],
vec!["//Alice".into(), "//Bob".into()],
)
}
}
+12 -10
View File
@@ -18,11 +18,18 @@
#![cfg(unix)]
use std::{process::{Child, ExitStatus}, thread, time::Duration, path::Path};
use assert_cmd::cargo::cargo_bin;
use std::{convert::TryInto, process::Command};
use nix::sys::signal::{kill, Signal::SIGINT};
use nix::unistd::Pid;
use nix::{
sys::signal::{kill, Signal::SIGINT},
unistd::Pid,
};
use std::{
convert::TryInto,
path::Path,
process::{Child, Command, ExitStatus},
thread,
time::Duration,
};
/// Wait for the given `child` the given number of `secs`.
///
@@ -50,12 +57,7 @@ pub fn wait_for(child: &mut Child, secs: usize) -> Option<ExitStatus> {
pub fn run_dev_node_for_a_while(base_path: &Path) {
let mut cmd = Command::new(cargo_bin("substrate"));
let mut cmd = cmd
.args(&["--dev"])
.arg("-d")
.arg(base_path)
.spawn()
.unwrap();
let mut cmd = cmd.args(&["--dev"]).arg("-d").arg(base_path).spawn().unwrap();
// Let it produce some blocks.
thread::sleep(Duration::from_secs(30));
@@ -19,9 +19,9 @@
#![cfg(unix)]
use assert_cmd::cargo::cargo_bin;
use std::{process::Command, fs, path::PathBuf};
use tempfile::{tempdir, TempDir};
use regex::Regex;
use std::{fs, path::PathBuf, process::Command};
use tempfile::{tempdir, TempDir};
pub mod common;
@@ -63,26 +63,23 @@ impl<'a> ExportImportRevertExecutor<'a> {
fn new(
base_path: &'a TempDir,
exported_blocks_file: &'a PathBuf,
db_path: &'a PathBuf
db_path: &'a PathBuf,
) -> Self {
Self {
base_path,
exported_blocks_file,
db_path,
num_exported_blocks: None,
}
Self { base_path, exported_blocks_file, db_path, num_exported_blocks: None }
}
/// Helper method to run a command. Returns a string corresponding to what has been logged.
fn run_block_command(&self,
fn run_block_command(
&self,
sub_command: SubCommand,
format_opt: FormatOpt,
expected_to_fail: bool
expected_to_fail: bool,
) -> String {
let sub_command_str = sub_command.to_string();
// Adding "--binary" if need be.
let arguments: Vec<&str> = match format_opt {
FormatOpt::Binary => vec![&sub_command_str, "--dev", "--pruning", "archive", "--binary", "-d"],
FormatOpt::Binary =>
vec![&sub_command_str, "--dev", "--pruning", "archive", "--binary", "-d"],
FormatOpt::Json => vec![&sub_command_str, "--dev", "--pruning", "archive", "-d"],
};
@@ -94,7 +91,7 @@ impl<'a> ExportImportRevertExecutor<'a> {
SubCommand::ImportBlocks => {
tmp = tempdir().unwrap();
tmp.path()
}
},
};
// Running the command and capturing the output.
@@ -144,16 +141,13 @@ impl<'a> ExportImportRevertExecutor<'a> {
if !expected_to_fail {
// Using regex to find out how much block we imported,
// and what's the best current block.
let re = Regex::new(r"Imported (?P<imported>\d*) blocks. Best: #(?P<best>\d*)").unwrap();
let re =
Regex::new(r"Imported (?P<imported>\d*) blocks. Best: #(?P<best>\d*)").unwrap();
let caps = re.captures(&log).expect("capture should have succeeded");
let imported = caps["imported"].parse::<u64>().unwrap();
let best = caps["best"].parse::<u64>().unwrap();
assert_eq!(
imported,
best,
"numbers of blocks imported and best number differs"
);
assert_eq!(imported, best, "numbers of blocks imported and best number differs");
assert_eq!(
best,
self.num_exported_blocks.expect("number of exported blocks cannot be None; qed"),
@@ -195,11 +189,7 @@ fn export_import_revert() {
common::run_dev_node_for_a_while(base_path.path());
let mut executor = ExportImportRevertExecutor::new(
&base_path,
&exported_blocks_file,
&db_path,
);
let mut executor = ExportImportRevertExecutor::new(&base_path, &exported_blocks_file, &db_path);
// Binary and binary should work.
executor.run(FormatOpt::Binary, FormatOpt::Binary, false);
@@ -25,8 +25,13 @@ pub mod common;
#[test]
#[cfg(unix)]
fn running_the_node_works_and_can_be_interrupted() {
use nix::sys::signal::{kill, Signal::{self, SIGINT, SIGTERM}};
use nix::unistd::Pid;
use nix::{
sys::signal::{
kill,
Signal::{self, SIGINT, SIGTERM},
},
unistd::Pid,
};
fn run_command_and_kill(signal: Signal) {
let base_path = tempdir().expect("could not create a temp dir");
+13 -22
View File
@@ -17,10 +17,11 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use assert_cmd::cargo::cargo_bin;
use nix::sys::signal::{kill, Signal::SIGINT};
use nix::unistd::Pid;
use std::convert::TryInto;
use std::process;
use nix::{
sys::signal::{kill, Signal::SIGINT},
unistd::Pid,
};
use std::{convert::TryInto, process};
pub mod common;
pub mod websocket_server;
@@ -45,27 +46,22 @@ async fn telemetry_works() {
Event::ConnectionOpen { address } => {
println!("New connection from {:?}", address);
server.accept();
}
},
// Received a message from a connection.
Event::BinaryFrame { message, .. } => {
let json: serde_json::Value = serde_json::from_slice(&message).unwrap();
let object = json
.as_object()
.unwrap()
.get("payload")
.unwrap()
.as_object()
.unwrap();
let object =
json.as_object().unwrap().get("payload").unwrap().as_object().unwrap();
if matches!(object.get("best"), Some(serde_json::Value::String(_))) {
break;
break
}
}
},
Event::TextFrame { .. } => panic!("Got a TextFrame over the socket, this is a bug"),
// Connection has been closed.
Event::ConnectionError { .. } => {}
Event::ConnectionError { .. } => {},
}
}
});
@@ -83,16 +79,11 @@ async fn telemetry_works() {
server_task.await;
assert!(
substrate.try_wait().unwrap().is_none(),
"the process should still be running"
);
assert!(substrate.try_wait().unwrap().is_none(), "the process should still be running");
// Stop the process
kill(Pid::from_raw(substrate.id().try_into().unwrap()), SIGINT).unwrap();
assert!(common::wait_for(&mut substrate, 40)
.map(|x| x.success())
.unwrap_or_default());
assert!(common::wait_for(&mut substrate, 40).map(|x| x.success()).unwrap_or_default());
let output = substrate.wait_with_output().unwrap();
@@ -19,15 +19,19 @@
#![cfg(unix)]
use assert_cmd::cargo::cargo_bin;
use nix::sys::signal::{kill, Signal::SIGINT};
use nix::unistd::Pid;
use nix::{
sys::signal::{kill, Signal::SIGINT},
unistd::Pid,
};
use regex::Regex;
use std::convert::TryInto;
use std::io::Read;
use std::path::PathBuf;
use std::process::{Command, Stdio};
use std::thread;
use std::time::Duration;
use std::{
convert::TryInto,
io::Read,
path::PathBuf,
process::{Command, Stdio},
thread,
time::Duration,
};
pub mod common;
@@ -44,29 +48,18 @@ fn temp_base_path_works() {
// Let it produce some blocks.
thread::sleep(Duration::from_secs(30));
assert!(
cmd.try_wait().unwrap().is_none(),
"the process should still be running"
);
assert!(cmd.try_wait().unwrap().is_none(), "the process should still be running");
// Stop the process
kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT).unwrap();
assert!(common::wait_for(&mut cmd, 40)
.map(|x| x.success())
.unwrap_or_default());
assert!(common::wait_for(&mut cmd, 40).map(|x| x.success()).unwrap_or_default());
// Ensure the database has been deleted
let mut stderr = String::new();
cmd.stderr.unwrap().read_to_string(&mut stderr).unwrap();
let re = Regex::new(r"Database: .+ at (\S+)").unwrap();
let db_path = PathBuf::from(
re.captures(stderr.as_str())
.unwrap()
.get(1)
.unwrap()
.as_str()
.to_string(),
);
let db_path =
PathBuf::from(re.captures(stderr.as_str()).unwrap().get(1).unwrap().as_str().to_string());
assert!(!db_path.exists());
}
+9 -25
View File
@@ -22,61 +22,45 @@ use regex::Regex;
use std::process::Command;
fn expected_regex() -> Regex {
Regex::new(r"^substrate (\d+\.\d+\.\d+(?:-.+?)?)-([a-f\d]+|unknown)-(.+?)-(.+?)(?:-(.+))?$").unwrap()
Regex::new(r"^substrate (\d+\.\d+\.\d+(?:-.+?)?)-([a-f\d]+|unknown)-(.+?)-(.+?)(?:-(.+))?$")
.unwrap()
}
#[test]
fn version_is_full() {
let expected = expected_regex();
let output = Command::new(cargo_bin("substrate"))
.args(&["--version"])
.output()
.unwrap();
let output = Command::new(cargo_bin("substrate")).args(&["--version"]).output().unwrap();
assert!(
output.status.success(),
"command returned with non-success exit code"
);
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");
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())
);
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();
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();
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();
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");
@@ -116,7 +116,6 @@ impl WsServer {
/// # Panic
///
/// Panics if no connection is pending.
///
pub fn accept(&mut self) {
let pending_incoming = self.pending_incoming.take().expect("no pending socket");
@@ -129,15 +128,10 @@ impl WsServer {
};
match server
.send_response(&{
Response::Accept {
key: &websocket_key,
protocol: None,
}
})
.send_response(&{ Response::Accept { key: &websocket_key, protocol: None } })
.await
{
Ok(()) => {}
Ok(()) => {},
Err(err) => return Err(Box::new(err) as Box<_>),
};
@@ -153,7 +147,6 @@ impl WsServer {
/// # Panic
///
/// Panics if no connection is pending.
///
pub fn reject(&mut self) {
let _ = self.pending_incoming.take().expect("no pending socket");
}
+100 -92
View File
@@ -16,29 +16,33 @@
// limitations under the License.
use codec::{Decode, Encode};
use criterion::{BatchSize, Criterion, criterion_group, criterion_main};
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
use frame_support::Hashable;
use node_executor::Executor;
use node_primitives::{BlockNumber, Hash};
use node_runtime::{
Block, BuildStorage, Call, CheckedExtrinsic, GenesisConfig, Header, UncheckedExtrinsic,
constants::currency::*, Block, BuildStorage, Call, CheckedExtrinsic, GenesisConfig, Header,
UncheckedExtrinsic,
};
use node_runtime::constants::currency::*;
use node_testing::keyring::*;
use sp_core::{NativeOrEncoded, NeverNativeValue};
use sp_core::storage::well_known_keys;
use sp_core::traits::{CodeExecutor, RuntimeCode};
use frame_support::Hashable;
use sp_state_machine::TestExternalities as CoreTestExternalities;
use sc_executor::{NativeExecutor, RuntimeInfo, WasmExecutionMethod, Externalities};
use sc_executor::{Externalities, NativeExecutor, RuntimeInfo, WasmExecutionMethod};
use sp_core::{
storage::well_known_keys,
traits::{CodeExecutor, RuntimeCode},
NativeOrEncoded, NeverNativeValue,
};
use sp_runtime::traits::BlakeTwo256;
use sp_state_machine::TestExternalities as CoreTestExternalities;
criterion_group!(benches, bench_execute_block);
criterion_main!(benches);
/// The wasm runtime code.
pub fn compact_code_unwrap() -> &'static [u8] {
node_runtime::WASM_BINARY.expect("Development wasm binary is not available. \
Testing is only supported with the flag disabled.")
node_runtime::WASM_BINARY.expect(
"Development wasm binary is not available. \
Testing is only supported with the flag disabled.",
)
}
const GENESIS_HASH: [u8; 32] = [69u8; 32];
@@ -66,7 +70,9 @@ fn new_test_ext(genesis_config: &GenesisConfig) -> TestExternalities<BlakeTwo256
compact_code_unwrap(),
genesis_config.build_storage().unwrap(),
);
test_ext.ext().place_storage(well_known_keys::HEAP_PAGES.to_vec(), Some(HEAP_PAGES.encode()));
test_ext
.ext()
.place_storage(well_known_keys::HEAP_PAGES.to_vec(), Some(HEAP_PAGES.encode()));
test_ext
}
@@ -77,16 +83,16 @@ fn construct_block<E: Externalities>(
parent_hash: Hash,
extrinsics: Vec<CheckedExtrinsic>,
) -> (Vec<u8>, Hash) {
use sp_trie::{TrieConfiguration, trie_types::Layout};
use sp_trie::{trie_types::Layout, TrieConfiguration};
// sign extrinsics.
let extrinsics = extrinsics.into_iter().map(sign).collect::<Vec<_>>();
// calculate the header fields that we can.
let extrinsics_root = Layout::<BlakeTwo256>::ordered_trie_root(
extrinsics.iter().map(Encode::encode)
).to_fixed_bytes()
.into();
let extrinsics_root =
Layout::<BlakeTwo256>::ordered_trie_root(extrinsics.iter().map(Encode::encode))
.to_fixed_bytes()
.into();
let header = Header {
parent_hash,
@@ -103,34 +109,44 @@ fn construct_block<E: Externalities>(
};
// execute the block to get the real header.
executor.call::<NeverNativeValue, fn() -> _>(
ext,
&runtime_code,
"Core_initialize_block",
&header.encode(),
true,
None,
).0.unwrap();
for i in extrinsics.iter() {
executor.call::<NeverNativeValue, fn() -> _>(
executor
.call::<NeverNativeValue, fn() -> _>(
ext,
&runtime_code,
"BlockBuilder_apply_extrinsic",
&i.encode(),
"Core_initialize_block",
&header.encode(),
true,
None,
).0.unwrap();
)
.0
.unwrap();
for i in extrinsics.iter() {
executor
.call::<NeverNativeValue, fn() -> _>(
ext,
&runtime_code,
"BlockBuilder_apply_extrinsic",
&i.encode(),
true,
None,
)
.0
.unwrap();
}
let header = match executor.call::<NeverNativeValue, fn() -> _>(
ext,
&runtime_code,
"BlockBuilder_finalize_block",
&[0u8;0],
true,
None,
).0.unwrap() {
let header = match executor
.call::<NeverNativeValue, fn() -> _>(
ext,
&runtime_code,
"BlockBuilder_finalize_block",
&[0u8; 0],
true,
None,
)
.0
.unwrap()
{
NativeOrEncoded::Native(_) => unreachable!(),
NativeOrEncoded::Encoded(h) => Header::decode(&mut &h[..]).unwrap(),
};
@@ -139,29 +155,21 @@ fn construct_block<E: Externalities>(
(Block { header, extrinsics }.encode(), hash.into())
}
fn test_blocks(genesis_config: &GenesisConfig, executor: &NativeExecutor<Executor>)
-> Vec<(Vec<u8>, Hash)>
{
fn test_blocks(
genesis_config: &GenesisConfig,
executor: &NativeExecutor<Executor>,
) -> Vec<(Vec<u8>, Hash)> {
let mut test_ext = new_test_ext(genesis_config);
let mut block1_extrinsics = vec![
CheckedExtrinsic {
signed: None,
function: Call::Timestamp(pallet_timestamp::Call::set(0)),
},
];
block1_extrinsics.extend((0..20).map(|i| {
CheckedExtrinsic {
signed: Some((alice(), signed_extra(i, 0))),
function: Call::Balances(pallet_balances::Call::transfer(bob().into(), 1 * DOLLARS)),
}
let mut block1_extrinsics = vec![CheckedExtrinsic {
signed: None,
function: Call::Timestamp(pallet_timestamp::Call::set(0)),
}];
block1_extrinsics.extend((0..20).map(|i| CheckedExtrinsic {
signed: Some((alice(), signed_extra(i, 0))),
function: Call::Balances(pallet_balances::Call::transfer(bob().into(), 1 * DOLLARS)),
}));
let block1 = construct_block(
executor,
&mut test_ext.ext(),
1,
GENESIS_HASH.into(),
block1_extrinsics,
);
let block1 =
construct_block(executor, &mut test_ext.ext(), 1, GENESIS_HASH.into(), block1_extrinsics);
vec![block1]
}
@@ -176,47 +184,47 @@ fn bench_execute_block(c: &mut Criterion) {
];
for strategy in execution_methods {
group.bench_function(
format!("{:?}", strategy),
|b| {
let genesis_config = node_testing::genesis::config(false, Some(compact_code_unwrap()));
let (use_native, wasm_method) = match strategy {
ExecutionMethod::Native => (true, WasmExecutionMethod::Interpreted),
ExecutionMethod::Wasm(wasm_method) => (false, wasm_method),
};
group.bench_function(format!("{:?}", strategy), |b| {
let genesis_config = node_testing::genesis::config(false, Some(compact_code_unwrap()));
let (use_native, wasm_method) = match strategy {
ExecutionMethod::Native => (true, WasmExecutionMethod::Interpreted),
ExecutionMethod::Wasm(wasm_method) => (false, wasm_method),
};
let executor = NativeExecutor::new(wasm_method, None, 8);
let runtime_code = RuntimeCode {
code_fetcher: &sp_core::traits::WrappedRuntimeCode(compact_code_unwrap().into()),
hash: vec![1, 2, 3],
heap_pages: None,
};
let executor = NativeExecutor::new(wasm_method, None, 8);
let runtime_code = RuntimeCode {
code_fetcher: &sp_core::traits::WrappedRuntimeCode(compact_code_unwrap().into()),
hash: vec![1, 2, 3],
heap_pages: None,
};
// Get the runtime version to initialize the runtimes cache.
{
let mut test_ext = new_test_ext(&genesis_config);
executor.runtime_version(&mut test_ext.ext(), &runtime_code).unwrap();
}
// Get the runtime version to initialize the runtimes cache.
{
let mut test_ext = new_test_ext(&genesis_config);
executor.runtime_version(&mut test_ext.ext(), &runtime_code).unwrap();
}
let blocks = test_blocks(&genesis_config, &executor);
let blocks = test_blocks(&genesis_config, &executor);
b.iter_batched_ref(
|| new_test_ext(&genesis_config),
|test_ext| {
for block in blocks.iter() {
executor.call::<NeverNativeValue, fn() -> _>(
b.iter_batched_ref(
|| new_test_ext(&genesis_config),
|test_ext| {
for block in blocks.iter() {
executor
.call::<NeverNativeValue, fn() -> _>(
&mut test_ext.ext(),
&runtime_code,
"Core_execute_block",
&block.0,
use_native,
None,
).0.unwrap();
}
},
BatchSize::LargeInput,
);
},
);
)
.0
.unwrap();
}
},
BatchSize::LargeInput,
);
});
}
}
+1 -1
View File
@@ -18,8 +18,8 @@
//! A `CodeExecutor` specialization which uses natively compiled runtime when the wasm to be
//! executed is equivalent to the natively compiled code.
pub use sc_executor::NativeExecutor;
use sc_executor::native_executor_instance;
pub use sc_executor::NativeExecutor;
// Declare an instance of the native executor named `Executor`. Include the wasm binary as the
// equivalent wasm code.
+172 -134
View File
@@ -15,30 +15,28 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use codec::{Encode, Decode, Joiner};
use codec::{Decode, Encode, Joiner};
use frame_support::{
traits::Currency,
weights::{GetDispatchInfo, DispatchInfo, DispatchClass},
weights::{DispatchClass, DispatchInfo, GetDispatchInfo},
};
use sp_core::{NeverNativeValue, traits::Externalities, storage::well_known_keys};
use frame_system::{self, AccountInfo, EventRecord, Phase};
use sp_core::{storage::well_known_keys, traits::Externalities, NeverNativeValue};
use sp_runtime::{
ApplyExtrinsicResult,
traits::Hash as HashT,
transaction_validity::InvalidTransaction,
traits::Hash as HashT, transaction_validity::InvalidTransaction, ApplyExtrinsicResult,
};
use frame_system::{self, EventRecord, Phase, AccountInfo};
use node_runtime::{
Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances,
System, TransactionPayment, Event,
constants::{time::SLOT_DURATION, currency::*},
};
use node_primitives::{Balance, Hash};
use wat;
use node_runtime::{
constants::{currency::*, time::SLOT_DURATION},
Balances, Block, Call, CheckedExtrinsic, Event, Header, Runtime, System, TransactionPayment,
UncheckedExtrinsic,
};
use node_testing::keyring::*;
use wat;
pub mod common;
use self::common::{*, sign};
use self::common::{sign, *};
/// The wasm runtime binary which hasn't undergone the compacting process.
///
@@ -46,8 +44,10 @@ use self::common::{*, sign};
/// have to execute provided wasm code instead of the native equivalent. This trick is used to
/// test code paths that differ between native and wasm versions.
pub fn bloaty_code_unwrap() -> &'static [u8] {
node_runtime::WASM_BINARY_BLOATY.expect("Development wasm binary is not available. \
Testing is only supported with the flag disabled.")
node_runtime::WASM_BINARY_BLOATY.expect(
"Development wasm binary is not available. \
Testing is only supported with the flag disabled.",
)
}
/// Default transfer fee. This will use the same logic that is implemented in transaction-payment module.
@@ -87,7 +87,10 @@ fn changes_trie_block() -> (Vec<u8>, Hash) {
},
CheckedExtrinsic {
signed: Some((alice(), signed_extra(0, 0))),
function: Call::Balances(pallet_balances::Call::transfer(bob().into(), 69 * DOLLARS)),
function: Call::Balances(pallet_balances::Call::transfer(
bob().into(),
69 * DOLLARS,
)),
},
],
(time / SLOT_DURATION).into(),
@@ -111,7 +114,10 @@ fn blocks() -> ((Vec<u8>, Hash), (Vec<u8>, Hash)) {
},
CheckedExtrinsic {
signed: Some((alice(), signed_extra(0, 0))),
function: Call::Balances(pallet_balances::Call::transfer(bob().into(), 69 * DOLLARS)),
function: Call::Balances(pallet_balances::Call::transfer(
bob().into(),
69 * DOLLARS,
)),
},
],
(time1 / SLOT_DURATION).into(),
@@ -128,12 +134,18 @@ fn blocks() -> ((Vec<u8>, Hash), (Vec<u8>, Hash)) {
},
CheckedExtrinsic {
signed: Some((bob(), signed_extra(0, 0))),
function: Call::Balances(pallet_balances::Call::transfer(alice().into(), 5 * DOLLARS)),
function: Call::Balances(pallet_balances::Call::transfer(
alice().into(),
5 * DOLLARS,
)),
},
CheckedExtrinsic {
signed: Some((alice(), signed_extra(1, 0))),
function: Call::Balances(pallet_balances::Call::transfer(bob().into(), 15 * DOLLARS)),
}
function: Call::Balances(pallet_balances::Call::transfer(
bob().into(),
15 * DOLLARS,
)),
},
],
(time2 / SLOT_DURATION).into(),
);
@@ -158,7 +170,7 @@ fn block_with_size(time: u64, nonce: u32, size: usize) -> (Vec<u8>, Hash) {
CheckedExtrinsic {
signed: Some((alice(), signed_extra(nonce, 0))),
function: Call::System(frame_system::Call::remark(vec![0; size])),
}
},
],
(time * 1000 / SLOT_DURATION).into(),
)
@@ -169,7 +181,7 @@ fn panic_execution_with_foreign_code_gives_error() {
let mut t = new_test_ext(bloaty_code_unwrap(), false);
t.insert(
<frame_system::Account<Runtime>>::hashed_key_for(alice()),
(69u128, 0u32, 0u128, 0u128, 0u128).encode()
(69u128, 0u32, 0u128, 0u128, 0u128).encode(),
);
t.insert(<pallet_balances::TotalIssuance<Runtime>>::hashed_key().to_vec(), 69_u128.encode());
t.insert(<frame_system::BlockHash<Runtime>>::hashed_key_for(0), vec![0u8; 32]);
@@ -180,7 +192,8 @@ fn panic_execution_with_foreign_code_gives_error() {
&vec![].and(&from_block_number(1u32)),
true,
None,
).0;
)
.0;
assert!(r.is_ok());
let v = executor_call::<NeverNativeValue, fn() -> _>(
&mut t,
@@ -188,7 +201,9 @@ fn panic_execution_with_foreign_code_gives_error() {
&vec![].and(&xt()),
true,
None,
).0.unwrap();
)
.0
.unwrap();
let r = ApplyExtrinsicResult::decode(&mut &v.as_encoded()[..]).unwrap();
assert_eq!(r, Err(InvalidTransaction::Payment.into()));
}
@@ -198,7 +213,7 @@ fn bad_extrinsic_with_native_equivalent_code_gives_error() {
let mut t = new_test_ext(compact_code_unwrap(), false);
t.insert(
<frame_system::Account<Runtime>>::hashed_key_for(alice()),
(0u32, 0u32, 0u32, 69u128, 0u128, 0u128, 0u128).encode()
(0u32, 0u32, 0u32, 69u128, 0u128, 0u128, 0u128).encode(),
);
t.insert(<pallet_balances::TotalIssuance<Runtime>>::hashed_key().to_vec(), 69_u128.encode());
t.insert(<frame_system::BlockHash<Runtime>>::hashed_key_for(0), vec![0u8; 32]);
@@ -209,7 +224,8 @@ fn bad_extrinsic_with_native_equivalent_code_gives_error() {
&vec![].and(&from_block_number(1u32)),
true,
None,
).0;
)
.0;
assert!(r.is_ok());
let v = executor_call::<NeverNativeValue, fn() -> _>(
&mut t,
@@ -217,7 +233,9 @@ fn bad_extrinsic_with_native_equivalent_code_gives_error() {
&vec![].and(&xt()),
true,
None,
).0.unwrap();
)
.0
.unwrap();
let r = ApplyExtrinsicResult::decode(&mut &v.as_encoded()[..]).unwrap();
assert_eq!(r, Err(InvalidTransaction::Payment.into()));
}
@@ -229,19 +247,21 @@ fn successful_execution_with_native_equivalent_code_gives_ok() {
<frame_system::Account<Runtime>>::hashed_key_for(alice()),
AccountInfo::<<Runtime as frame_system::Config>::Index, _> {
data: (111 * DOLLARS, 0u128, 0u128, 0u128),
.. Default::default()
}.encode(),
..Default::default()
}
.encode(),
);
t.insert(
<frame_system::Account<Runtime>>::hashed_key_for(bob()),
AccountInfo::<<Runtime as frame_system::Config>::Index, _> {
data: (0 * DOLLARS, 0u128, 0u128, 0u128),
.. Default::default()
}.encode(),
..Default::default()
}
.encode(),
);
t.insert(
<pallet_balances::TotalIssuance<Runtime>>::hashed_key().to_vec(),
(111 * DOLLARS).encode()
(111 * DOLLARS).encode(),
);
t.insert(<frame_system::BlockHash<Runtime>>::hashed_key_for(0), vec![0u8; 32]);
@@ -251,7 +271,8 @@ fn successful_execution_with_native_equivalent_code_gives_ok() {
&vec![].and(&from_block_number(1u32)),
true,
None,
).0;
)
.0;
assert!(r.is_ok());
let fees = t.execute_with(|| transfer_fee(&xt()));
@@ -262,7 +283,8 @@ fn successful_execution_with_native_equivalent_code_gives_ok() {
&vec![].and(&xt()),
true,
None,
).0;
)
.0;
assert!(r.is_ok());
t.execute_with(|| {
@@ -278,19 +300,21 @@ fn successful_execution_with_foreign_code_gives_ok() {
<frame_system::Account<Runtime>>::hashed_key_for(alice()),
AccountInfo::<<Runtime as frame_system::Config>::Index, _> {
data: (111 * DOLLARS, 0u128, 0u128, 0u128),
.. Default::default()
}.encode(),
..Default::default()
}
.encode(),
);
t.insert(
<frame_system::Account<Runtime>>::hashed_key_for(bob()),
AccountInfo::<<Runtime as frame_system::Config>::Index, _> {
data: (0 * DOLLARS, 0u128, 0u128, 0u128),
.. Default::default()
}.encode(),
..Default::default()
}
.encode(),
);
t.insert(
<pallet_balances::TotalIssuance<Runtime>>::hashed_key().to_vec(),
(111 * DOLLARS).encode()
(111 * DOLLARS).encode(),
);
t.insert(<frame_system::BlockHash<Runtime>>::hashed_key_for(0), vec![0u8; 32]);
@@ -300,7 +324,8 @@ fn successful_execution_with_foreign_code_gives_ok() {
&vec![].and(&from_block_number(1u32)),
true,
None,
).0;
)
.0;
assert!(r.is_ok());
let fees = t.execute_with(|| transfer_fee(&xt()));
@@ -311,7 +336,8 @@ fn successful_execution_with_foreign_code_gives_ok() {
&vec![].and(&xt()),
true,
None,
).0;
)
.0;
assert!(r.is_ok());
t.execute_with(|| {
@@ -330,7 +356,9 @@ fn full_native_block_import_works() {
let mut fees = t.execute_with(|| transfer_fee(&xt()));
let transfer_weight = default_transfer_call().get_dispatch_info().weight;
let timestamp_weight = pallet_timestamp::Call::set::<Runtime>(Default::default()).get_dispatch_info().weight;
let timestamp_weight = pallet_timestamp::Call::set::<Runtime>(Default::default())
.get_dispatch_info()
.weight;
executor_call::<NeverNativeValue, fn() -> _>(
&mut t,
@@ -338,7 +366,9 @@ fn full_native_block_import_works() {
&block1.0,
true,
None,
).0.unwrap();
)
.0
.unwrap();
t.execute_with(|| {
assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees);
@@ -347,9 +377,11 @@ fn full_native_block_import_works() {
let events = vec![
EventRecord {
phase: Phase::ApplyExtrinsic(0),
event: Event::System(frame_system::Event::ExtrinsicSuccess(
DispatchInfo { weight: timestamp_weight, class: DispatchClass::Mandatory, ..Default::default() }
)),
event: Event::System(frame_system::Event::ExtrinsicSuccess(DispatchInfo {
weight: timestamp_weight,
class: DispatchClass::Mandatory,
..Default::default()
})),
topics: vec![],
},
EventRecord {
@@ -368,9 +400,10 @@ fn full_native_block_import_works() {
},
EventRecord {
phase: Phase::ApplyExtrinsic(1),
event: Event::System(frame_system::Event::ExtrinsicSuccess(
DispatchInfo { weight: transfer_weight, ..Default::default() }
)),
event: Event::System(frame_system::Event::ExtrinsicSuccess(DispatchInfo {
weight: transfer_weight,
..Default::default()
})),
topics: vec![],
},
];
@@ -385,34 +418,33 @@ fn full_native_block_import_works() {
&block2.0,
true,
None,
).0.unwrap();
)
.0
.unwrap();
t.execute_with(|| {
assert_eq!(
Balances::total_balance(&alice()),
alice_last_known_balance - 10 * DOLLARS - fees,
);
assert_eq!(
Balances::total_balance(&bob()),
179 * DOLLARS - fees,
);
assert_eq!(Balances::total_balance(&bob()), 179 * DOLLARS - fees,);
let events = vec![
EventRecord {
phase: Phase::ApplyExtrinsic(0),
event: Event::System(frame_system::Event::ExtrinsicSuccess(
DispatchInfo { weight: timestamp_weight, class: DispatchClass::Mandatory, ..Default::default() }
)),
event: Event::System(frame_system::Event::ExtrinsicSuccess(DispatchInfo {
weight: timestamp_weight,
class: DispatchClass::Mandatory,
..Default::default()
})),
topics: vec![],
},
EventRecord {
phase: Phase::ApplyExtrinsic(1),
event: Event::Balances(
pallet_balances::Event::Transfer(
bob().into(),
alice().into(),
5 * DOLLARS,
)
),
event: Event::Balances(pallet_balances::Event::Transfer(
bob().into(),
alice().into(),
5 * DOLLARS,
)),
topics: vec![],
},
EventRecord {
@@ -422,20 +454,19 @@ fn full_native_block_import_works() {
},
EventRecord {
phase: Phase::ApplyExtrinsic(1),
event: Event::System(frame_system::Event::ExtrinsicSuccess(
DispatchInfo { weight: transfer_weight, ..Default::default() }
)),
event: Event::System(frame_system::Event::ExtrinsicSuccess(DispatchInfo {
weight: transfer_weight,
..Default::default()
})),
topics: vec![],
},
EventRecord {
phase: Phase::ApplyExtrinsic(2),
event: Event::Balances(
pallet_balances::Event::Transfer(
alice().into(),
bob().into(),
15 * DOLLARS,
)
),
event: Event::Balances(pallet_balances::Event::Transfer(
alice().into(),
bob().into(),
15 * DOLLARS,
)),
topics: vec![],
},
EventRecord {
@@ -445,9 +476,10 @@ fn full_native_block_import_works() {
},
EventRecord {
phase: Phase::ApplyExtrinsic(2),
event: Event::System(frame_system::Event::ExtrinsicSuccess(
DispatchInfo { weight: transfer_weight, ..Default::default() }
)),
event: Event::System(frame_system::Event::ExtrinsicSuccess(DispatchInfo {
weight: transfer_weight,
..Default::default()
})),
topics: vec![],
},
];
@@ -470,7 +502,9 @@ fn full_wasm_block_import_works() {
&block1.0,
false,
None,
).0.unwrap();
)
.0
.unwrap();
t.execute_with(|| {
assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees);
@@ -486,17 +520,16 @@ fn full_wasm_block_import_works() {
&block2.0,
false,
None,
).0.unwrap();
)
.0
.unwrap();
t.execute_with(|| {
assert_eq!(
Balances::total_balance(&alice()),
alice_last_known_balance - 10 * DOLLARS - fees,
);
assert_eq!(
Balances::total_balance(&bob()),
179 * DOLLARS - 1 * fees,
);
assert_eq!(Balances::total_balance(&bob()), 179 * DOLLARS - 1 * fees,);
});
}
@@ -600,11 +633,7 @@ fn deploying_wasm_contract_should_work() {
let transfer_code = wat::parse_str(CODE_TRANSFER).unwrap();
let transfer_ch = <Runtime as frame_system::Config>::Hashing::hash(&transfer_code);
let addr = pallet_contracts::Pallet::<Runtime>::contract_address(
&charlie(),
&transfer_ch,
&[],
);
let addr = pallet_contracts::Pallet::<Runtime>::contract_address(&charlie(), &transfer_ch, &[]);
let subsistence = pallet_contracts::Pallet::<Runtime>::subsistence_threshold();
@@ -627,19 +656,17 @@ fn deploying_wasm_contract_should_work() {
transfer_code,
Vec::new(),
Vec::new(),
)
),
),
},
CheckedExtrinsic {
signed: Some((charlie(), signed_extra(1, 0))),
function: Call::Contracts(
pallet_contracts::Call::call::<Runtime>(
sp_runtime::MultiAddress::Id(addr.clone()),
10,
500_000_000,
vec![0x00, 0x01, 0x02, 0x03]
)
),
function: Call::Contracts(pallet_contracts::Call::call::<Runtime>(
sp_runtime::MultiAddress::Id(addr.clone()),
10,
500_000_000,
vec![0x00, 0x01, 0x02, 0x03],
)),
},
],
(time / SLOT_DURATION).into(),
@@ -647,20 +674,14 @@ fn deploying_wasm_contract_should_work() {
let mut t = new_test_ext(compact_code_unwrap(), false);
executor_call::<NeverNativeValue, fn() -> _>(
&mut t,
"Core_execute_block",
&b.0,
false,
None,
).0.unwrap();
executor_call::<NeverNativeValue, fn() -> _>(&mut t, "Core_execute_block", &b.0, false, None)
.0
.unwrap();
t.execute_with(|| {
// Verify that the contract does exist by querying some of its storage items
// It does not matter that the storage item itself does not exist.
assert!(
&pallet_contracts::Pallet::<Runtime>::get_storage(addr, Default::default()).is_ok()
);
assert!(&pallet_contracts::Pallet::<Runtime>::get_storage(addr, Default::default()).is_ok());
});
}
@@ -676,7 +697,8 @@ fn wasm_big_block_import_fails() {
&block_with_size(42, 0, 120_000).0,
false,
None,
).0;
)
.0;
assert!(result.is_err()); // Err(Wasmi(Trap(Trap { kind: Host(AllocatorOutOfSpace) })))
}
@@ -690,7 +712,9 @@ fn native_big_block_import_succeeds() {
&block_with_size(42, 0, 120_000).0,
true,
None,
).0.unwrap();
)
.0
.unwrap();
}
#[test]
@@ -700,15 +724,15 @@ fn native_big_block_import_fails_on_fallback() {
// We set the heap pages to 8 because we know that should give an OOM in WASM with the given block.
set_heap_pages(&mut t.ext(), 8);
assert!(
executor_call::<NeverNativeValue, fn() -> _>(
&mut t,
"Core_execute_block",
&block_with_size(42, 0, 120_000).0,
false,
None,
).0.is_err()
);
assert!(executor_call::<NeverNativeValue, fn() -> _>(
&mut t,
"Core_execute_block",
&block_with_size(42, 0, 120_000).0,
false,
None,
)
.0
.is_err());
}
#[test]
@@ -718,8 +742,9 @@ fn panic_execution_gives_error() {
<frame_system::Account<Runtime>>::hashed_key_for(alice()),
AccountInfo::<<Runtime as frame_system::Config>::Index, _> {
data: (0 * DOLLARS, 0u128, 0u128, 0u128),
.. Default::default()
}.encode(),
..Default::default()
}
.encode(),
);
t.insert(<pallet_balances::TotalIssuance<Runtime>>::hashed_key().to_vec(), 0_u128.encode());
t.insert(<frame_system::BlockHash<Runtime>>::hashed_key_for(0), vec![0u8; 32]);
@@ -730,7 +755,8 @@ fn panic_execution_gives_error() {
&vec![].and(&from_block_number(1u32)),
false,
None,
).0;
)
.0;
assert!(r.is_ok());
let r = executor_call::<NeverNativeValue, fn() -> _>(
&mut t,
@@ -738,7 +764,10 @@ fn panic_execution_gives_error() {
&vec![].and(&xt()),
false,
None,
).0.unwrap().into_encoded();
)
.0
.unwrap()
.into_encoded();
let r = ApplyExtrinsicResult::decode(&mut &r[..]).unwrap();
assert_eq!(r, Err(InvalidTransaction::Payment.into()));
}
@@ -750,19 +779,21 @@ fn successful_execution_gives_ok() {
<frame_system::Account<Runtime>>::hashed_key_for(alice()),
AccountInfo::<<Runtime as frame_system::Config>::Index, _> {
data: (111 * DOLLARS, 0u128, 0u128, 0u128),
.. Default::default()
}.encode(),
..Default::default()
}
.encode(),
);
t.insert(
<frame_system::Account<Runtime>>::hashed_key_for(bob()),
AccountInfo::<<Runtime as frame_system::Config>::Index, _> {
data: (0 * DOLLARS, 0u128, 0u128, 0u128),
.. Default::default()
}.encode(),
..Default::default()
}
.encode(),
);
t.insert(
<pallet_balances::TotalIssuance<Runtime>>::hashed_key().to_vec(),
(111 * DOLLARS).encode()
(111 * DOLLARS).encode(),
);
t.insert(<frame_system::BlockHash<Runtime>>::hashed_key_for(0), vec![0u8; 32]);
@@ -772,7 +803,8 @@ fn successful_execution_gives_ok() {
&vec![].and(&from_block_number(1u32)),
false,
None,
).0;
)
.0;
assert!(r.is_ok());
t.execute_with(|| {
assert_eq!(Balances::total_balance(&alice()), 111 * DOLLARS);
@@ -786,7 +818,10 @@ fn successful_execution_gives_ok() {
&vec![].and(&xt()),
false,
None,
).0.unwrap().into_encoded();
)
.0
.unwrap()
.into_encoded();
ApplyExtrinsicResult::decode(&mut &r[..])
.unwrap()
.expect("Extrinsic could not be applied")
@@ -811,7 +846,9 @@ fn full_native_block_import_works_with_changes_trie() {
&block.encode(),
true,
None,
).0.unwrap();
)
.0
.unwrap();
assert!(t.ext().storage_changes_root(&GENESIS_HASH).unwrap().is_some());
}
@@ -827,7 +864,9 @@ fn full_wasm_block_import_works_with_changes_trie() {
&block1.0,
false,
None,
).0.unwrap();
)
.0
.unwrap();
assert!(t.ext().storage_changes_root(&GENESIS_HASH).unwrap().is_some());
}
@@ -835,8 +874,7 @@ fn full_wasm_block_import_works_with_changes_trie() {
#[test]
fn should_import_block_with_test_client() {
use node_testing::client::{
ClientBlockImportExt, TestClientBuilderExt, TestClientBuilder,
sp_consensus::BlockOrigin,
sp_consensus::BlockOrigin, ClientBlockImportExt, TestClientBuilder, TestClientBuilderExt,
};
let mut client = TestClientBuilder::new().build();
+50 -45
View File
@@ -15,34 +15,32 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use codec::{Encode, Decode};
use frame_system::offchain::AppCrypto;
use codec::{Decode, Encode};
use frame_support::Hashable;
use sp_state_machine::TestExternalities as CoreTestExternalities;
use sp_consensus_babe::{BABE_ENGINE_ID, Slot, digests::{PreDigest, SecondaryPlainPreDigest}};
use frame_system::offchain::AppCrypto;
use sc_executor::{error::Result, NativeExecutor, WasmExecutionMethod};
use sp_consensus_babe::{
digests::{PreDigest, SecondaryPlainPreDigest},
Slot, BABE_ENGINE_ID,
};
use sp_core::{
NeverNativeValue, NativeOrEncoded,
crypto::KeyTypeId,
sr25519::Signature,
traits::{CodeExecutor, RuntimeCode},
NativeOrEncoded, NeverNativeValue,
};
use sp_runtime::{
ApplyExtrinsicResult,
MultiSigner,
MultiSignature,
Digest,
DigestItem,
traits::{Header as HeaderT, BlakeTwo256},
traits::{BlakeTwo256, Header as HeaderT},
ApplyExtrinsicResult, Digest, DigestItem, MultiSignature, MultiSigner,
};
use sc_executor::{NativeExecutor, WasmExecutionMethod};
use sc_executor::error::Result;
use sp_state_machine::TestExternalities as CoreTestExternalities;
use node_executor::Executor;
use node_primitives::{BlockNumber, Hash};
use node_runtime::{
Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Runtime, BuildStorage,
constants::currency::*,
constants::currency::*, Block, BuildStorage, CheckedExtrinsic, Header, Runtime,
UncheckedExtrinsic,
};
use node_primitives::{Hash, BlockNumber};
use node_testing::keyring::*;
use sp_externalities::Externalities;
@@ -50,8 +48,8 @@ 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;
use sp_application_crypto::{app_crypto, sr25519};
app_crypto!(sr25519, TEST_KEY_TYPE_ID);
}
@@ -72,8 +70,10 @@ impl AppCrypto<MultiSigner, MultiSignature> for TestAuthorityId {
/// as canonical. This is why `native_executor_instance` also uses the compact version of the
/// runtime.
pub fn compact_code_unwrap() -> &'static [u8] {
node_runtime::WASM_BINARY.expect("Development wasm binary is not available. \
Testing is only supported with the flag disabled.")
node_runtime::WASM_BINARY.expect(
"Development wasm binary is not available. \
Testing is only supported with the flag disabled.",
)
}
pub const GENESIS_HASH: [u8; 32] = [69u8; 32];
@@ -101,8 +101,9 @@ pub fn executor() -> NativeExecutor<Executor> {
}
pub fn executor_call<
R:Decode + Encode + PartialEq,
NC: FnOnce() -> std::result::Result<R, Box<dyn std::error::Error + Send + Sync>> + std::panic::UnwindSafe
R: Decode + Encode + PartialEq,
NC: FnOnce() -> std::result::Result<R, Box<dyn std::error::Error + Send + Sync>>
+ std::panic::UnwindSafe,
>(
t: &mut TestExternalities<BlakeTwo256>,
method: &str,
@@ -120,20 +121,15 @@ pub fn executor_call<
heap_pages: heap_pages.and_then(|hp| Decode::decode(&mut &hp[..]).ok()),
};
executor().call::<R, NC>(
&mut t,
&runtime_code,
method,
data,
use_native,
native_call,
)
executor().call::<R, NC>(&mut t, &runtime_code, method, data, use_native, native_call)
}
pub fn new_test_ext(code: &[u8], support_changes_trie: bool) -> TestExternalities<BlakeTwo256> {
let mut ext = TestExternalities::new_with_code(
code,
node_testing::genesis::config(support_changes_trie, Some(code)).build_storage().unwrap(),
node_testing::genesis::config(support_changes_trie, Some(code))
.build_storage()
.unwrap(),
);
ext.changes_trie_storage().insert(0, GENESIS_HASH.into(), Default::default());
ext
@@ -150,7 +146,7 @@ pub fn construct_block(
extrinsics: Vec<CheckedExtrinsic>,
babe_slot: Slot,
) -> (Vec<u8>, Hash) {
use sp_trie::{TrieConfiguration, trie_types::Layout};
use sp_trie::{trie_types::Layout, TrieConfiguration};
// sign extrinsics.
let extrinsics = extrinsics.into_iter().map(sign).collect::<Vec<_>>();
@@ -167,15 +163,14 @@ pub fn construct_block(
extrinsics_root,
state_root: Default::default(),
digest: Digest {
logs: vec![
DigestItem::PreRuntime(
BABE_ENGINE_ID,
PreDigest::SecondaryPlain(SecondaryPlainPreDigest {
slot: babe_slot,
authority_index: 42,
}).encode()
),
],
logs: vec![DigestItem::PreRuntime(
BABE_ENGINE_ID,
PreDigest::SecondaryPlain(SecondaryPlainPreDigest {
slot: babe_slot,
authority_index: 42,
})
.encode(),
)],
},
};
@@ -186,7 +181,9 @@ pub fn construct_block(
&header.encode(),
true,
None,
).0.unwrap();
)
.0
.unwrap();
for extrinsic in extrinsics.iter() {
// Try to apply the `extrinsic`. It should be valid, in the sense that it passes
@@ -197,8 +194,13 @@ pub fn construct_block(
&extrinsic.encode(),
true,
None,
).0.expect("application of an extrinsic failed").into_encoded();
match ApplyExtrinsicResult::decode(&mut &r[..]).expect("apply result deserialization failed") {
)
.0
.expect("application of an extrinsic failed")
.into_encoded();
match ApplyExtrinsicResult::decode(&mut &r[..])
.expect("apply result deserialization failed")
{
Ok(_) => {},
Err(e) => panic!("Applying extrinsic failed: {:?}", e),
}
@@ -207,10 +209,13 @@ pub fn construct_block(
let header = match executor_call::<NeverNativeValue, fn() -> _>(
env,
"BlockBuilder_finalize_block",
&[0u8;0],
&[0u8; 0],
true,
None,
).0.unwrap() {
)
.0
.unwrap()
{
NativeOrEncoded::Native(_) => unreachable!(),
NativeOrEncoded::Encoded(h) => Header::decode(&mut &h[..]).unwrap(),
};
+47 -28
View File
@@ -18,20 +18,21 @@
use codec::{Encode, Joiner};
use frame_support::{
traits::Currency,
weights::{GetDispatchInfo, constants::ExtrinsicBaseWeight, IdentityFee, WeightToFeePolynomial},
};
use sp_core::NeverNativeValue;
use sp_runtime::{Perbill, traits::One};
use node_runtime::{
CheckedExtrinsic, Call, Runtime, Balances, TransactionPayment, Multiplier,
TransactionByteFee,
constants::{time::SLOT_DURATION, currency::*},
weights::{
constants::ExtrinsicBaseWeight, GetDispatchInfo, IdentityFee, WeightToFeePolynomial,
},
};
use node_primitives::Balance;
use node_runtime::{
constants::{currency::*, time::SLOT_DURATION},
Balances, Call, CheckedExtrinsic, Multiplier, Runtime, TransactionByteFee, TransactionPayment,
};
use node_testing::keyring::*;
use sp_core::NeverNativeValue;
use sp_runtime::{traits::One, Perbill};
pub mod common;
use self::common::{*, sign};
use self::common::{sign, *};
#[test]
fn fee_multiplier_increases_and_decreases_on_big_weight() {
@@ -60,7 +61,7 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() {
CheckedExtrinsic {
signed: Some((charlie(), signed_extra(0, 0))),
function: Call::System(frame_system::Call::fill_block(Perbill::from_percent(60))),
}
},
],
(time1 / SLOT_DURATION).into(),
);
@@ -79,7 +80,7 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() {
CheckedExtrinsic {
signed: Some((charlie(), signed_extra(1, 0))),
function: Call::System(frame_system::Call::remark(vec![0; 1])),
}
},
],
(time2 / SLOT_DURATION).into(),
);
@@ -97,7 +98,9 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() {
&block1.0,
true,
None,
).0.unwrap();
)
.0
.unwrap();
// weight multiplier is increased for next block.
t.execute_with(|| {
@@ -114,7 +117,9 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() {
&block2.0,
true,
None,
).0.unwrap();
)
.0
.unwrap();
// weight multiplier is increased for next block.
t.execute_with(|| {
@@ -131,7 +136,8 @@ fn new_account_info(free_dollars: u128) -> Vec<u8> {
providers: 0,
sufficients: 0,
data: (free_dollars * DOLLARS, 0 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS),
}.encode()
}
.encode()
}
#[test]
@@ -148,7 +154,7 @@ fn transaction_fee_is_correct() {
t.insert(<frame_system::Account<Runtime>>::hashed_key_for(bob()), new_account_info(10));
t.insert(
<pallet_balances::TotalIssuance<Runtime>>::hashed_key().to_vec(),
(110 * DOLLARS).encode()
(110 * DOLLARS).encode(),
);
t.insert(<frame_system::BlockHash<Runtime>>::hashed_key_for(0), vec![0u8; 32]);
@@ -164,7 +170,8 @@ fn transaction_fee_is_correct() {
&vec![].and(&from_block_number(1u32)),
true,
None,
).0;
)
.0;
assert!(r.is_ok());
let r = executor_call::<NeverNativeValue, fn() -> _>(
@@ -173,7 +180,8 @@ fn transaction_fee_is_correct() {
&vec![].and(&xt.clone()),
true,
None,
).0;
)
.0;
assert!(r.is_ok());
t.execute_with(|| {
@@ -228,15 +236,20 @@ fn block_weight_capacity_report() {
loop {
let num_transfers = block_number * factor;
let mut xts = (0..num_transfers).map(|i| CheckedExtrinsic {
signed: Some((charlie(), signed_extra(nonce + i as Index, 0))),
function: Call::Balances(pallet_balances::Call::transfer(bob().into(), 0)),
}).collect::<Vec<CheckedExtrinsic>>();
let mut xts = (0..num_transfers)
.map(|i| CheckedExtrinsic {
signed: Some((charlie(), signed_extra(nonce + i as Index, 0))),
function: Call::Balances(pallet_balances::Call::transfer(bob().into(), 0)),
})
.collect::<Vec<CheckedExtrinsic>>();
xts.insert(0, CheckedExtrinsic {
signed: None,
function: Call::Timestamp(pallet_timestamp::Call::set(time * 1000)),
});
xts.insert(
0,
CheckedExtrinsic {
signed: None,
function: Call::Timestamp(pallet_timestamp::Call::set(time * 1000)),
},
);
// NOTE: this is super slow. Can probably be improved.
let block = construct_block(
@@ -262,7 +275,8 @@ fn block_weight_capacity_report() {
&block.0,
true,
None,
).0;
)
.0;
println!(" || Result = {:?}", r);
assert!(r.is_ok());
@@ -307,7 +321,11 @@ fn block_length_capacity_report() {
},
CheckedExtrinsic {
signed: Some((charlie(), signed_extra(nonce, 0))),
function: Call::System(frame_system::Call::remark(vec![0u8; (block_number * factor) as usize])),
function: Call::System(frame_system::Call::remark(vec![
0u8;
(block_number * factor)
as usize
])),
},
],
(time * 1000 / SLOT_DURATION).into(),
@@ -327,7 +345,8 @@ fn block_length_capacity_report() {
&block.0,
true,
None,
).0;
)
.0;
println!(" || Result = {:?}", r);
assert!(r.is_ok());
@@ -15,26 +15,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::sync::Arc;
use node_runtime::{
Executive, Indices, Runtime, UncheckedExtrinsic,
};
use sp_application_crypto::AppKey;
use sp_core::{
offchain::{
TransactionPoolExt,
testing::TestTransactionPoolExt,
},
};
use sp_keystore::{KeystoreExt, SyncCryptoStore, testing::KeyStore};
use frame_system::{
offchain::{
Signer,
SubmitTransaction,
SendSignedTransaction,
}
};
use codec::Decode;
use frame_system::offchain::{SendSignedTransaction, Signer, SubmitTransaction};
use node_runtime::{Executive, Indices, Runtime, UncheckedExtrinsic};
use sp_application_crypto::AppKey;
use sp_core::offchain::{testing::TestTransactionPoolExt, TransactionPoolExt};
use sp_keystore::{testing::KeyStore, KeystoreExt, SyncCryptoStore};
use std::sync::Arc;
pub mod common;
use self::common::*;
@@ -56,8 +43,10 @@ fn should_submit_unsigned_transaction() {
};
let call = pallet_im_online::Call::heartbeat(heartbeat_data, signature);
SubmitTransaction::<Runtime, pallet_im_online::Call<Runtime>>::submit_unsigned_transaction(call.into())
.unwrap();
SubmitTransaction::<Runtime, pallet_im_online::Call<Runtime>>::submit_unsigned_transaction(
call.into(),
)
.unwrap();
assert_eq!(state.read().transactions.len(), 1)
});
@@ -75,23 +64,26 @@ fn should_submit_signed_transaction() {
SyncCryptoStore::sr25519_generate_new(
&keystore,
sr25519::AuthorityId::ID,
Some(&format!("{}/hunter1", PHRASE))
).unwrap();
Some(&format!("{}/hunter1", PHRASE)),
)
.unwrap();
SyncCryptoStore::sr25519_generate_new(
&keystore,
sr25519::AuthorityId::ID,
Some(&format!("{}/hunter2", PHRASE))
).unwrap();
Some(&format!("{}/hunter2", PHRASE)),
)
.unwrap();
SyncCryptoStore::sr25519_generate_new(
&keystore,
sr25519::AuthorityId::ID,
Some(&format!("{}/hunter3", PHRASE))
).unwrap();
Some(&format!("{}/hunter3", PHRASE)),
)
.unwrap();
t.register_extension(KeystoreExt(Arc::new(keystore)));
t.execute_with(|| {
let results = Signer::<Runtime, TestAuthorityId>::all_accounts()
.send_signed_transaction(|_| {
let results =
Signer::<Runtime, TestAuthorityId>::all_accounts().send_signed_transaction(|_| {
pallet_balances::Call::transfer(Default::default(), Default::default())
});
@@ -112,18 +104,20 @@ fn should_submit_signed_twice_from_the_same_account() {
SyncCryptoStore::sr25519_generate_new(
&keystore,
sr25519::AuthorityId::ID,
Some(&format!("{}/hunter1", PHRASE))
).unwrap();
Some(&format!("{}/hunter1", PHRASE)),
)
.unwrap();
SyncCryptoStore::sr25519_generate_new(
&keystore,
sr25519::AuthorityId::ID,
Some(&format!("{}/hunter2", PHRASE))
).unwrap();
Some(&format!("{}/hunter2", PHRASE)),
)
.unwrap();
t.register_extension(KeystoreExt(Arc::new(keystore)));
t.execute_with(|| {
let result = Signer::<Runtime, TestAuthorityId>::any_account()
.send_signed_transaction(|_| {
let result =
Signer::<Runtime, TestAuthorityId>::any_account().send_signed_transaction(|_| {
pallet_balances::Call::transfer(Default::default(), Default::default())
});
@@ -131,8 +125,8 @@ fn should_submit_signed_twice_from_the_same_account() {
assert_eq!(state.read().transactions.len(), 1);
// submit another one from the same account. The nonce should be incremented.
let result = Signer::<Runtime, TestAuthorityId>::any_account()
.send_signed_transaction(|_| {
let result =
Signer::<Runtime, TestAuthorityId>::any_account().send_signed_transaction(|_| {
pallet_balances::Call::transfer(Default::default(), Default::default())
});
@@ -147,10 +141,7 @@ fn should_submit_signed_twice_from_the_same_account() {
}
let nonce1 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[0]).unwrap());
let nonce2 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[1]).unwrap());
assert!(
nonce1 != nonce2,
"Transactions should have different nonces. Got: {:?}", nonce1
);
assert!(nonce1 != nonce2, "Transactions should have different nonces. Got: {:?}", nonce1);
});
}
@@ -161,14 +152,12 @@ fn should_submit_signed_twice_from_all_accounts() {
t.register_extension(TransactionPoolExt::new(pool));
let keystore = KeyStore::new();
keystore.sr25519_generate_new(
sr25519::AuthorityId::ID,
Some(&format!("{}/hunter1", PHRASE))
).unwrap();
keystore.sr25519_generate_new(
sr25519::AuthorityId::ID,
Some(&format!("{}/hunter2", PHRASE))
).unwrap();
keystore
.sr25519_generate_new(sr25519::AuthorityId::ID, Some(&format!("{}/hunter1", PHRASE)))
.unwrap();
keystore
.sr25519_generate_new(sr25519::AuthorityId::ID, Some(&format!("{}/hunter2", PHRASE)))
.unwrap();
t.register_extension(KeystoreExt(Arc::new(keystore)));
t.execute_with(|| {
@@ -217,8 +206,10 @@ fn should_submit_signed_twice_from_all_accounts() {
#[test]
fn submitted_transaction_should_be_valid() {
use codec::Encode;
use sp_runtime::transaction_validity::{TransactionSource, TransactionTag};
use sp_runtime::traits::StaticLookup;
use sp_runtime::{
traits::StaticLookup,
transaction_validity::{TransactionSource, TransactionTag},
};
let mut t = new_test_ext(compact_code_unwrap(), false);
let (pool, state) = TestTransactionPoolExt::new();
@@ -227,13 +218,15 @@ fn submitted_transaction_should_be_valid() {
let keystore = KeyStore::new();
SyncCryptoStore::sr25519_generate_new(
&keystore,
sr25519::AuthorityId::ID, Some(&format!("{}/hunter1", PHRASE))
).unwrap();
sr25519::AuthorityId::ID,
Some(&format!("{}/hunter1", PHRASE)),
)
.unwrap();
t.register_extension(KeystoreExt(Arc::new(keystore)));
t.execute_with(|| {
let results = Signer::<Runtime, TestAuthorityId>::all_accounts()
.send_signed_transaction(|_| {
let results =
Signer::<Runtime, TestAuthorityId>::all_accounts().send_signed_transaction(|_| {
pallet_balances::Call::transfer(Default::default(), Default::default())
});
let len = results.len();
@@ -252,7 +245,7 @@ fn submitted_transaction_should_be_valid() {
let author = extrinsic.signature.clone().unwrap().0;
let address = Indices::lookup(author).unwrap();
let data = pallet_balances::AccountData { free: 5_000_000_000_000, ..Default::default() };
let account = frame_system::AccountInfo { data, .. Default::default() };
let account = frame_system::AccountInfo { data, ..Default::default() };
<frame_system::Account<Runtime>>::insert(&address, account);
// check validity
@@ -260,7 +253,8 @@ fn submitted_transaction_should_be_valid() {
source,
extrinsic,
frame_system::BlockHash::<Runtime>::get(0),
).unwrap();
)
.unwrap();
// We ignore res.priority since this number can change based on updates to weights and such.
assert_eq!(res.requires, Vec::<TransactionTag>::new());
+1 -1
View File
@@ -18,8 +18,8 @@
//! Structs to easily compose inspect sub-command for CLI.
use std::fmt::Debug;
use sc_cli::{ImportParams, SharedParams};
use std::fmt::Debug;
use structopt::StructOpt;
/// The `inspect` command used to print decoded chain data.
+6 -4
View File
@@ -18,8 +18,10 @@
//! Command ran by the CLI
use crate::cli::{InspectCmd, InspectSubCmd};
use crate::Inspector;
use crate::{
cli::{InspectCmd, InspectSubCmd},
Inspector,
};
use sc_cli::{CliConfiguration, ImportParams, Result, SharedParams};
use sc_service::{new_full_client, Configuration, NativeExecutionDispatch};
use sp_runtime::traits::Block;
@@ -43,13 +45,13 @@ impl InspectCmd {
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))?;
println!("{}", res);
Ok(())
}
},
}
}
}
+62 -73
View File
@@ -27,33 +27,27 @@
pub mod cli;
pub mod command;
use std::{
fmt,
fmt::Debug,
marker::PhantomData,
str::FromStr,
};
use codec::{Encode, Decode};
use codec::{Decode, Encode};
use sc_client_api::BlockBackend;
use sp_blockchain::HeaderBackend;
use sp_core::hexdisplay::HexDisplay;
use sp_runtime::{
generic::BlockId,
traits::{Block, HashFor, NumberFor, Hash}
traits::{Block, Hash, HashFor, NumberFor},
};
use std::{fmt, fmt::Debug, marker::PhantomData, str::FromStr};
/// A helper type for a generic block input.
pub type BlockAddressFor<TBlock> = BlockAddress<
<HashFor<TBlock> as Hash>::Output,
NumberFor<TBlock>
>;
pub type BlockAddressFor<TBlock> =
BlockAddress<<HashFor<TBlock> as Hash>::Output, NumberFor<TBlock>>;
/// A Pretty formatter implementation.
pub trait PrettyPrinter<TBlock: Block> {
/// Nicely format block.
fn fmt_block(&self, fmt: &mut fmt::Formatter, block: &TBlock) -> fmt::Result;
/// Nicely format extrinsic.
fn fmt_extrinsic(&self, fmt: &mut fmt::Formatter, extrinsic: &TBlock::Extrinsic) -> fmt::Result;
fn fmt_extrinsic(&self, fmt: &mut fmt::Formatter, extrinsic: &TBlock::Extrinsic)
-> fmt::Result;
}
/// Default dummy debug printer.
@@ -72,7 +66,11 @@ impl<TBlock: Block> PrettyPrinter<TBlock> for DebugPrinter {
Ok(())
}
fn fmt_extrinsic(&self, fmt: &mut fmt::Formatter, extrinsic: &TBlock::Extrinsic) -> fmt::Result {
fn fmt_extrinsic(
&self,
fmt: &mut fmt::Formatter,
extrinsic: &TBlock::Extrinsic,
) -> fmt::Result {
writeln!(fmt, " {:#?}", extrinsic)?;
writeln!(fmt, " Bytes: {:?}", HexDisplay::from(&extrinsic.encode()))?;
Ok(())
@@ -101,15 +99,14 @@ impl std::error::Error for Error {
}
/// A helper trait to access block headers and bodies.
pub trait ChainAccess<TBlock: Block>:
HeaderBackend<TBlock> +
BlockBackend<TBlock>
{}
pub trait ChainAccess<TBlock: Block>: HeaderBackend<TBlock> + BlockBackend<TBlock> {}
impl<T, TBlock> ChainAccess<TBlock> for T where
impl<T, TBlock> ChainAccess<TBlock> for T
where
TBlock: Block,
T: sp_blockchain::HeaderBackend<TBlock> + sc_client_api::BlockBackend<TBlock>,
{}
{
}
/// Blockchain inspector.
pub struct Inspector<TBlock: Block, TPrinter: PrettyPrinter<TBlock> = DebugPrinter> {
@@ -120,22 +117,16 @@ pub struct Inspector<TBlock: Block, TPrinter: PrettyPrinter<TBlock> = DebugPrint
impl<TBlock: Block, TPrinter: PrettyPrinter<TBlock>> Inspector<TBlock, TPrinter> {
/// Create new instance of the inspector with default printer.
pub fn new(
chain: impl ChainAccess<TBlock> + 'static,
) -> Self where TPrinter: Default {
pub fn new(chain: impl ChainAccess<TBlock> + 'static) -> Self
where
TPrinter: Default,
{
Self::with_printer(chain, Default::default())
}
/// Customize pretty-printing of the data.
pub fn with_printer(
chain: impl ChainAccess<TBlock> + 'static,
printer: TPrinter,
) -> Self {
Inspector {
chain: Box::new(chain) as _,
printer,
_block: Default::default(),
}
pub fn with_printer(chain: impl ChainAccess<TBlock> + 'static, printer: TPrinter) -> Self {
Inspector { chain: Box::new(chain) as _, printer, _block: Default::default() }
}
/// Get a pretty-printed block.
@@ -153,25 +144,27 @@ impl<TBlock: Block, TPrinter: PrettyPrinter<TBlock>> Inspector<TBlock, TPrinter>
fn get_block(&self, input: BlockAddressFor<TBlock>) -> Result<TBlock, Error> {
Ok(match input {
BlockAddress::Bytes(bytes) => {
TBlock::decode(&mut &*bytes)?
},
BlockAddress::Bytes(bytes) => TBlock::decode(&mut &*bytes)?,
BlockAddress::Number(number) => {
let id = BlockId::number(number);
let not_found = format!("Could not find block {:?}", id);
let body = self.chain.block_body(&id)?
.ok_or_else(|| Error::NotFound(not_found.clone()))?;
let header = self.chain.header(id)?
let body = self
.chain
.block_body(&id)?
.ok_or_else(|| Error::NotFound(not_found.clone()))?;
let header =
self.chain.header(id)?.ok_or_else(|| Error::NotFound(not_found.clone()))?;
TBlock::new(header, body)
},
BlockAddress::Hash(hash) => {
let id = BlockId::hash(hash);
let not_found = format!("Could not find block {:?}", id);
let body = self.chain.block_body(&id)?
.ok_or_else(|| Error::NotFound(not_found.clone()))?;
let header = self.chain.header(id)?
let body = self
.chain
.block_body(&id)?
.ok_or_else(|| Error::NotFound(not_found.clone()))?;
let header =
self.chain.header(id)?.ok_or_else(|| Error::NotFound(not_found.clone()))?;
TBlock::new(header, body)
},
})
@@ -192,16 +185,14 @@ impl<TBlock: Block, TPrinter: PrettyPrinter<TBlock>> Inspector<TBlock, TPrinter>
let ext = match input {
ExtrinsicAddress::Block(block, index) => {
let block = self.get_block(block)?;
block.extrinsics()
.get(index)
.cloned()
.ok_or_else(|| Error::NotFound(format!(
"Could not find extrinsic {} in block {:?}", index, block
)))?
block.extrinsics().get(index).cloned().ok_or_else(|| {
Error::NotFound(format!(
"Could not find extrinsic {} in block {:?}",
index, block
))
})?
},
ExtrinsicAddress::Bytes(bytes) => {
TBlock::Extrinsic::decode(&mut &*bytes)?
}
ExtrinsicAddress::Bytes(bytes) => TBlock::Extrinsic::decode(&mut &*bytes)?,
};
Ok(format!("{}", ExtrinsicPrinter(ext, &self.printer)))
@@ -234,12 +225,12 @@ impl<Hash: FromStr, Number: FromStr> FromStr for BlockAddress<Hash, Number> {
}
// then assume it's bytes (hex-encoded)
sp_core::bytes::from_hex(s)
.map(Self::Bytes)
.map_err(|e| format!(
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
))
)
})
}
}
@@ -263,11 +254,13 @@ impl<Hash: FromStr + Debug, Number: FromStr + Debug> FromStr for ExtrinsicAddres
// split by a bunch of different characters
let mut it = s.split(|c| c == '.' || c == ':' || c == ' ');
let block = it.next()
let block = it
.next()
.expect("First element of split iterator is never empty; qed")
.parse()?;
let index = it.next()
let index = it
.next()
.ok_or_else(|| format!("Extrinsic index missing: example \"5:0\""))?
.parse()
.map_err(|e| format!("Invalid index format: {}", e))?;
@@ -290,10 +283,10 @@ mod tests {
let b2 = BlockAddress::from_str("0");
let b3 = BlockAddress::from_str("0x0012345f");
assert_eq!(b0, Ok(BlockAddress::Hash(
"3BfC20f0B9aFcAcE800D73D2191166FF16540258".parse().unwrap()
)));
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])));
@@ -310,20 +303,16 @@ mod tests {
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!(
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])));
}
}
+3 -2
View File
@@ -18,11 +18,12 @@
//! Low-level types used throughout the Substrate code.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
use sp_runtime::{
generic, traits::{Verify, BlakeTwo256, IdentifyAccount}, OpaqueExtrinsic, MultiSignature
generic,
traits::{BlakeTwo256, IdentifyAccount, Verify},
MultiSignature, OpaqueExtrinsic,
};
/// An index to a block.
+9 -14
View File
@@ -24,15 +24,9 @@
use futures::Future;
use hyper::rt;
use jsonrpc_core_client::{transports::http, RpcError};
use node_primitives::Hash;
use sc_rpc::author::{
AuthorClient,
hash::ExtrinsicOrHash,
};
use jsonrpc_core_client::{
transports::http,
RpcError,
};
use sc_rpc::author::{hash::ExtrinsicOrHash, AuthorClient};
fn main() {
sp_tracing::try_init_simple();
@@ -41,9 +35,7 @@ fn main() {
let uri = "http://localhost:9933";
http::connect(uri)
.and_then(|client: AuthorClient<Hash, Hash>| {
remove_all_extrinsics(client)
})
.and_then(|client: AuthorClient<Hash, Hash>| remove_all_extrinsics(client))
.map_err(|e| {
println!("Error: {:?}", e);
})
@@ -58,11 +50,14 @@ fn main() {
///
/// As the result of running the code the entire content of the transaction pool is going
/// to be removed and the extrinsics are going to be temporarily banned.
fn remove_all_extrinsics(client: AuthorClient<Hash, Hash>) -> impl Future<Item=(), Error=RpcError> {
client.pending_extrinsics()
fn remove_all_extrinsics(
client: AuthorClient<Hash, Hash>,
) -> impl Future<Item = (), Error = RpcError> {
client
.pending_extrinsics()
.and_then(move |pending| {
client.remove_extrinsic(
pending.into_iter().map(|tx| ExtrinsicOrHash::Extrinsic(tx.into())).collect()
pending.into_iter().map(|tx| ExtrinsicOrHash::Extrinsic(tx.into())).collect(),
)
})
.map(|removed| {
+58 -85
View File
@@ -32,24 +32,24 @@
use std::sync::Arc;
use sp_keystore::SyncCryptoStorePtr;
use node_primitives::{Block, BlockNumber, AccountId, Index, Balance, Hash};
use node_primitives::{AccountId, Balance, Block, BlockNumber, Hash, Index};
use sc_client_api::AuxStore;
use sc_consensus_babe::{Config, Epoch};
use sc_consensus_babe_rpc::BabeRpcHandler;
use sc_consensus_epochs::SharedEpochChanges;
use sc_finality_grandpa::{
SharedVoterState, SharedAuthoritySet, FinalityProofProvider, GrandpaJustificationStream
FinalityProofProvider, GrandpaJustificationStream, SharedAuthoritySet, SharedVoterState,
};
use sc_finality_grandpa_rpc::GrandpaRpcHandler;
use sc_rpc::SubscriptionTaskExecutor;
pub use sc_rpc_api::DenyUnsafe;
use sc_transaction_pool_api::TransactionPool;
use sp_api::ProvideRuntimeApi;
use sp_block_builder::BlockBuilder;
use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend};
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
use sp_consensus::SelectChain;
use sp_consensus_babe::BabeApi;
use sc_rpc::SubscriptionTaskExecutor;
use sc_transaction_pool_api::TransactionPool;
use sc_client_api::AuxStore;
use sp_keystore::SyncCryptoStorePtr;
/// Light client extra dependencies.
pub struct LightDeps<C, F, P> {
@@ -111,9 +111,15 @@ pub type IoHandler = jsonrpc_core::IoHandler<sc_rpc::Metadata>;
/// Instantiate all Full RPC extensions.
pub fn create_full<C, P, SC, B>(
deps: FullDeps<C, P, SC, B>,
) -> jsonrpc_core::IoHandler<sc_rpc_api::Metadata> where
C: ProvideRuntimeApi<Block> + HeaderBackend<Block> + AuxStore +
HeaderMetadata<Block, Error=BlockChainError> + Sync + Send + 'static,
) -> jsonrpc_core::IoHandler<sc_rpc_api::Metadata>
where
C: ProvideRuntimeApi<Block>
+ HeaderBackend<Block>
+ AuxStore
+ HeaderMetadata<Block, Error = BlockChainError>
+ Sync
+ Send
+ 'static,
C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
C::Api: pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber, Hash>,
C::Api: pallet_mmr_rpc::MmrRuntimeApi<Block, <Block as sp_runtime::traits::Block>::Hash>,
@@ -121,31 +127,19 @@ pub fn create_full<C, P, SC, B>(
C::Api: BabeApi<Block>,
C::Api: BlockBuilder<Block>,
P: TransactionPool + 'static,
SC: SelectChain<Block> +'static,
SC: SelectChain<Block> + 'static,
B: sc_client_api::Backend<Block> + Send + Sync + 'static,
B::State: sc_client_api::backend::StateBackend<sp_runtime::traits::HashFor<Block>>,
{
use substrate_frame_rpc_system::{FullSystem, SystemApi};
use pallet_contracts_rpc::{Contracts, ContractsApi};
use pallet_mmr_rpc::{MmrApi, Mmr};
use pallet_mmr_rpc::{Mmr, MmrApi};
use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
use substrate_frame_rpc_system::{FullSystem, SystemApi};
let mut io = jsonrpc_core::IoHandler::default();
let FullDeps {
client,
pool,
select_chain,
chain_spec,
deny_unsafe,
babe,
grandpa,
} = deps;
let FullDeps { client, pool, select_chain, chain_spec, deny_unsafe, babe, grandpa } = deps;
let BabeDeps {
keystore,
babe_config,
shared_epoch_changes,
} = babe;
let BabeDeps { keystore, babe_config, shared_epoch_changes } = babe;
let GrandpaDeps {
shared_voter_state,
shared_authority_set,
@@ -154,64 +148,45 @@ pub fn create_full<C, P, SC, B>(
finality_provider,
} = grandpa;
io.extend_with(
SystemApi::to_delegate(FullSystem::new(client.clone(), pool, deny_unsafe))
);
io.extend_with(SystemApi::to_delegate(FullSystem::new(client.clone(), pool, deny_unsafe)));
// Making synchronous calls in light client freezes the browser currently,
// more context: https://github.com/paritytech/substrate/pull/3480
// These RPCs should use an asynchronous caller instead.
io.extend_with(
ContractsApi::to_delegate(Contracts::new(client.clone()))
);
io.extend_with(
MmrApi::to_delegate(Mmr::new(client.clone()))
);
io.extend_with(
TransactionPaymentApi::to_delegate(TransactionPayment::new(client.clone()))
);
io.extend_with(
sc_consensus_babe_rpc::BabeApi::to_delegate(
BabeRpcHandler::new(
client.clone(),
shared_epoch_changes.clone(),
keystore,
babe_config,
select_chain,
deny_unsafe,
),
)
);
io.extend_with(
sc_finality_grandpa_rpc::GrandpaApi::to_delegate(
GrandpaRpcHandler::new(
shared_authority_set.clone(),
shared_voter_state,
justification_stream,
subscription_executor,
finality_provider,
)
)
);
io.extend_with(ContractsApi::to_delegate(Contracts::new(client.clone())));
io.extend_with(MmrApi::to_delegate(Mmr::new(client.clone())));
io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(client.clone())));
io.extend_with(sc_consensus_babe_rpc::BabeApi::to_delegate(BabeRpcHandler::new(
client.clone(),
shared_epoch_changes.clone(),
keystore,
babe_config,
select_chain,
deny_unsafe,
)));
io.extend_with(sc_finality_grandpa_rpc::GrandpaApi::to_delegate(GrandpaRpcHandler::new(
shared_authority_set.clone(),
shared_voter_state,
justification_stream,
subscription_executor,
finality_provider,
)));
io.extend_with(
sc_sync_state_rpc::SyncStateRpcApi::to_delegate(
sc_sync_state_rpc::SyncStateRpcHandler::new(
chain_spec,
client,
shared_authority_set,
shared_epoch_changes,
deny_unsafe,
)
)
);
io.extend_with(sc_sync_state_rpc::SyncStateRpcApi::to_delegate(
sc_sync_state_rpc::SyncStateRpcHandler::new(
chain_spec,
client,
shared_authority_set,
shared_epoch_changes,
deny_unsafe,
),
));
io
}
/// Instantiate all Light RPC extensions.
pub fn create_light<C, P, M, F>(
deps: LightDeps<C, F, P>,
) -> jsonrpc_core::IoHandler<M> where
pub fn create_light<C, P, M, F>(deps: LightDeps<C, F, P>) -> jsonrpc_core::IoHandler<M>
where
C: sp_blockchain::HeaderBackend<Block>,
C: Send + Sync + 'static,
F: sc_client_api::light::Fetcher<Block> + 'static,
@@ -220,16 +195,14 @@ pub fn create_light<C, P, M, F>(
{
use substrate_frame_rpc_system::{LightSystem, SystemApi};
let LightDeps {
client,
pool,
remote_blockchain,
fetcher
} = deps;
let LightDeps { client, pool, remote_blockchain, fetcher } = deps;
let mut io = jsonrpc_core::IoHandler::default();
io.extend_with(
SystemApi::<Hash, AccountId, Index>::to_delegate(LightSystem::new(client, remote_blockchain, fetcher, pool))
);
io.extend_with(SystemApi::<Hash, AccountId, Index>::to_delegate(LightSystem::new(
client,
remote_blockchain,
fetcher,
pool,
)));
io
}
+2 -2
View File
@@ -22,7 +22,7 @@ pub mod currency {
use node_primitives::Balance;
pub const MILLICENTS: Balance = 1_000_000_000;
pub const CENTS: Balance = 1_000 * MILLICENTS; // assume this is worth about a cent.
pub const CENTS: Balance = 1_000 * MILLICENTS; // assume this is worth about a cent.
pub const DOLLARS: Balance = 100 * CENTS;
pub const fn deposit(items: u32, bytes: u32) -> Balance {
@@ -32,7 +32,7 @@ pub mod currency {
/// Time.
pub mod time {
use node_primitives::{Moment, BlockNumber};
use node_primitives::{BlockNumber, Moment};
/// Since BABE is probabilistic this is the average expected block time that
/// we are targeting. Blocks will be produced at a minimum duration defined
+44 -35
View File
@@ -17,8 +17,8 @@
//! Some configurable implementations as associated type for the substrate runtime.
use frame_support::traits::{OnUnbalanced, Currency};
use crate::{Balances, Authorship, NegativeImbalance};
use crate::{Authorship, Balances, NegativeImbalance};
use frame_support::traits::{Currency, OnUnbalanced};
pub struct Author;
impl OnUnbalanced<NegativeImbalance> for Author {
@@ -29,19 +29,24 @@ impl OnUnbalanced<NegativeImbalance> for Author {
#[cfg(test)]
mod multiplier_tests {
use sp_runtime::{assert_eq_error_rate, FixedPointNumber, traits::{Convert, One, Zero}};
use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment};
use sp_runtime::{
assert_eq_error_rate,
traits::{Convert, One, Zero},
FixedPointNumber,
};
use crate::{
constants::{currency::*, time::*},
TransactionPayment, Runtime, TargetBlockFullness,
AdjustmentVariable, System, MinimumMultiplier,
RuntimeBlockWeights as BlockWeights,
AdjustmentVariable, MinimumMultiplier, Runtime, RuntimeBlockWeights as BlockWeights,
System, TargetBlockFullness, TransactionPayment,
};
use frame_support::weights::{Weight, WeightToFeePolynomial, DispatchClass};
use frame_support::weights::{DispatchClass, Weight, WeightToFeePolynomial};
fn max_normal() -> Weight {
BlockWeights::get().get(DispatchClass::Normal).max_total
BlockWeights::get()
.get(DispatchClass::Normal)
.max_total
.unwrap_or_else(|| BlockWeights::get().max_block)
}
@@ -64,7 +69,7 @@ mod multiplier_tests {
}
// update based on reference impl.
fn truth_value_update(block_weight: Weight, previous: Multiplier) -> Multiplier {
fn truth_value_update(block_weight: Weight, previous: Multiplier) -> Multiplier {
let accuracy = Multiplier::accuracy() as f64;
let previous_float = previous.into_inner() as f64 / accuracy;
// bump if it is zero.
@@ -81,15 +86,20 @@ mod multiplier_tests {
// Current saturation in terms of weight
let s = block_weight;
let t1 = v * (s/m - ss/m);
let t2 = v.powi(2) * (s/m - ss/m).powi(2) / 2.0;
let t1 = v * (s / m - ss / m);
let t2 = v.powi(2) * (s / m - ss / m).powi(2) / 2.0;
let next_float = previous_float * (1.0 + t1 + t2);
Multiplier::from_float(next_float)
}
fn run_with_system_weight<F>(w: Weight, assertions: F) where F: Fn() -> () {
let mut t: sp_io::TestExternalities =
frame_system::GenesisConfig::default().build_storage::<Runtime>().unwrap().into();
fn run_with_system_weight<F>(w: Weight, assertions: F)
where
F: Fn() -> (),
{
let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::default()
.build_storage::<Runtime>()
.unwrap()
.into();
t.execute_with(|| {
System::set_block_consumed_resources(w, 0);
assertions()
@@ -157,7 +167,9 @@ mod multiplier_tests {
loop {
let next = runtime_multiplier_update(fm);
fm = next;
if fm == min_multiplier() { break; }
if fm == min_multiplier() {
break
}
iterations += 1;
}
assert!(iterations > 533_333);
@@ -198,7 +210,9 @@ mod multiplier_tests {
loop {
let next = runtime_multiplier_update(fm);
// if no change, panic. This should never happen in this case.
if fm == next { panic!("The fee should ever increase"); }
if fm == next {
panic!("The fee should ever increase");
}
fm = next;
iterations += 1;
let fee =
@@ -225,7 +239,7 @@ mod multiplier_tests {
let next = runtime_multiplier_update(fm);
assert_eq_error_rate!(
next,
truth_value_update(target() / 4 , fm),
truth_value_update(target() / 4, fm),
Multiplier::from_inner(100),
);
@@ -237,12 +251,11 @@ mod multiplier_tests {
let next = runtime_multiplier_update(fm);
assert_eq_error_rate!(
next,
truth_value_update(target() / 2 , fm),
truth_value_update(target() / 2, fm),
Multiplier::from_inner(100),
);
// Light block. Multiplier is reduced a little.
assert!(next < fm);
});
run_with_system_weight(target(), || {
let next = runtime_multiplier_update(fm);
@@ -259,7 +272,7 @@ mod multiplier_tests {
let next = runtime_multiplier_update(fm);
assert_eq_error_rate!(
next,
truth_value_update(target() * 2 , fm),
truth_value_update(target() * 2, fm),
Multiplier::from_inner(100),
);
@@ -326,28 +339,24 @@ mod multiplier_tests {
BlockWeights::get().max_block,
Weight::max_value() / 2,
Weight::max_value(),
].into_iter().for_each(|i| {
]
.into_iter()
.for_each(|i| {
run_with_system_weight(i, || {
let next = runtime_multiplier_update(Multiplier::one());
let truth = truth_value_update(i, Multiplier::one());
assert_eq_error_rate!(
truth,
next,
Multiplier::from_inner(50_000_000)
);
assert_eq_error_rate!(truth, next, Multiplier::from_inner(50_000_000));
});
});
// Some values that are all above the target and will cause an increase.
let t = target();
vec![t + 100, t * 2, t * 4]
.into_iter()
.for_each(|i| {
run_with_system_weight(i, || {
let fm = runtime_multiplier_update(max_fm);
// won't grow. The convert saturates everything.
assert_eq!(fm, max_fm);
})
});
vec![t + 100, t * 2, t * 4].into_iter().for_each(|i| {
run_with_system_weight(i, || {
let fm = runtime_multiplier_update(max_fm);
// won't grow. The convert saturates everything.
assert_eq!(fm, max_fm);
})
});
}
}
+100 -93
View File
@@ -22,67 +22,67 @@
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit = "256"]
use sp_std::prelude::*;
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{
construct_runtime, parameter_types, RuntimeDebug,
weights::{
Weight, IdentityFee,
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
DispatchClass,
},
construct_runtime, parameter_types,
traits::{
Currency, Imbalance, KeyOwnerProofSystem, OnUnbalanced, LockIdentifier,
U128CurrencyToVote, AllowAll, DenyAll,
AllowAll, Currency, DenyAll, Imbalance, InstanceFilter, KeyOwnerProofSystem,
LockIdentifier, OnUnbalanced, U128CurrencyToVote,
},
weights::{
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
DispatchClass, IdentityFee, Weight,
},
PalletId, RuntimeDebug,
};
use frame_system::{
EnsureRoot, EnsureOneOf,
limits::{BlockWeights, BlockLength}
limits::{BlockLength, BlockWeights},
EnsureOneOf, EnsureRoot,
};
use frame_support::{traits::InstanceFilter, PalletId};
use codec::{Encode, Decode, MaxEncodedLen};
pub use node_primitives::{AccountId, Signature};
use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment};
use pallet_contracts::weights::WeightInfo;
use pallet_election_provider_multi_phase::FallbackStrategy;
use pallet_grandpa::{
fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList,
};
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
use pallet_session::historical as pallet_session_historical;
pub use pallet_transaction_payment::{CurrencyAdapter, Multiplier, TargetedFeeAdjustment};
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
use sp_api::impl_runtime_apis;
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
use sp_core::{
crypto::KeyTypeId,
u32_trait::{_1, _2, _3, _4, _5},
OpaqueMetadata,
};
pub use node_primitives::{AccountId, Signature};
use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment};
use sp_api::impl_runtime_apis;
use sp_inherents::{CheckInherentsResult, InherentData};
use sp_runtime::{
Permill, Perbill, Perquintill, Percent, ApplyExtrinsicResult, impl_opaque_keys, generic,
create_runtime_str, FixedPointNumber,
create_runtime_str,
curve::PiecewiseLinear,
generic, impl_opaque_keys,
traits::{
self, BlakeTwo256, Block as BlockT, ConvertInto, NumberFor, OpaqueKeys,
SaturatedConversion, StaticLookup,
},
transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity},
ApplyExtrinsicResult, FixedPointNumber, Perbill, Percent, Permill, Perquintill,
};
use sp_runtime::curve::PiecewiseLinear;
use sp_runtime::transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority};
use sp_runtime::traits::{
self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion, ConvertInto, OpaqueKeys,
NumberFor,
};
use sp_version::RuntimeVersion;
use sp_std::prelude::*;
#[cfg(any(feature = "std", test))]
use sp_version::NativeVersion;
use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
use pallet_grandpa::fg_primitives;
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
pub use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment, CurrencyAdapter};
use pallet_session::{historical as pallet_session_historical};
use sp_inherents::{InherentData, CheckInherentsResult};
use sp_version::RuntimeVersion;
use static_assertions::const_assert;
use pallet_contracts::weights::WeightInfo;
use pallet_election_provider_multi_phase::FallbackStrategy;
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
#[cfg(any(feature = "std", test))]
pub use pallet_balances::Call as BalancesCall;
#[cfg(any(feature = "std", test))]
pub use frame_system::Call as SystemCall;
#[cfg(any(feature = "std", test))]
pub use pallet_balances::Call as BalancesCall;
#[cfg(any(feature = "std", test))]
pub use pallet_staking::StakerStatus;
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
/// Implementations of some helper traits passed into runtime modules as associated types.
pub mod impls;
@@ -90,7 +90,7 @@ use impls::Author;
/// Constant values used within the runtime.
pub mod constants;
use constants::{time::*, currency::*};
use constants::{currency::*, time::*};
use sp_runtime::generic::Era;
// Make the WASM binary available.
@@ -100,9 +100,11 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
/// Wasm binary unwrapped. If built with `SKIP_WASM_BUILD`, the function panics.
#[cfg(feature = "std")]
pub fn wasm_binary_unwrap() -> &'static [u8] {
WASM_BINARY.expect("Development wasm binary is not available. This means the client is \
WASM_BINARY.expect(
"Development wasm binary is not available. This means the client is \
built with `SKIP_WASM_BUILD` flag and it is only usable for \
production chains. Please rebuild with the flag disabled.")
production chains. Please rebuild with the flag disabled.",
)
}
/// Runtime version.
@@ -125,23 +127,20 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
pub const BABE_GENESIS_EPOCH_CONFIG: sp_consensus_babe::BabeEpochConfiguration =
sp_consensus_babe::BabeEpochConfiguration {
c: PRIMARY_PROBABILITY,
allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryPlainSlots
allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryPlainSlots,
};
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
NativeVersion {
runtime_version: VERSION,
can_author_with: Default::default(),
}
NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
}
type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
pub struct DealWithFees;
impl OnUnbalanced<NegativeImbalance> for DealWithFees {
fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item=NegativeImbalance>) {
fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
if let Some(fees) = fees_then_tips.next() {
// for fees, 80% to treasury, 20% to author
let mut split = fees.ration(80, 20);
@@ -256,14 +255,20 @@ parameter_types! {
}
/// The type used to represent the kinds of proxying allowed.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen)]
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen,
)]
pub enum ProxyType {
Any,
NonTransfer,
Governance,
Staking,
}
impl Default for ProxyType { fn default() -> Self { Self::Any } }
impl Default for ProxyType {
fn default() -> Self {
Self::Any
}
}
impl InstanceFilter<Call> for ProxyType {
fn filter(&self, c: &Call) -> bool {
match self {
@@ -271,19 +276,16 @@ impl InstanceFilter<Call> for ProxyType {
ProxyType::NonTransfer => !matches!(
c,
Call::Balances(..) |
Call::Assets(..) |
Call::Uniques(..) |
Call::Vesting(pallet_vesting::Call::vested_transfer(..)) |
Call::Indices(pallet_indices::Call::transfer(..))
Call::Assets(..) | Call::Uniques(..) |
Call::Vesting(pallet_vesting::Call::vested_transfer(..)) |
Call::Indices(pallet_indices::Call::transfer(..))
),
ProxyType::Governance => matches!(
c,
Call::Democracy(..) |
Call::Council(..) |
Call::Society(..) |
Call::TechnicalCommittee(..) |
Call::Elections(..) |
Call::Treasury(..)
Call::Council(..) | Call::Society(..) |
Call::TechnicalCommittee(..) |
Call::Elections(..) | Call::Treasury(..)
),
ProxyType::Staking => matches!(c, Call::Staking(..)),
}
@@ -500,15 +502,16 @@ impl pallet_staking::Config for Runtime {
type SlashCancelOrigin = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>
pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>,
>;
type SessionInterface = Self;
type EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
type NextNewSession = Session;
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type ElectionProvider = ElectionProviderMultiPhase;
type GenesisElectionProvider =
onchain::OnChainSequentialPhragmen<pallet_election_provider_multi_phase::OnChainConfig<Self>>;
type GenesisElectionProvider = onchain::OnChainSequentialPhragmen<
pallet_election_provider_multi_phase::OnChainConfig<Self>,
>;
type WeightInfo = pallet_staking::weights::SubstrateWeight<Runtime>;
}
@@ -618,20 +621,26 @@ impl pallet_democracy::Config for Runtime {
type VotingPeriod = VotingPeriod;
type MinimumDeposit = MinimumDeposit;
/// A straight majority of the council can decide what their next motion is.
type ExternalOrigin = pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
type ExternalOrigin =
pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
/// A super-majority can have the next scheduled referendum be a straight majority-carries vote.
type ExternalMajorityOrigin = pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>;
type ExternalMajorityOrigin =
pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>;
/// A unanimous council can have the next scheduled referendum be a straight default-carries
/// (NTB) vote.
type ExternalDefaultOrigin = pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>;
type ExternalDefaultOrigin =
pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>;
/// 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 InstantOrigin = pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>;
type FastTrackOrigin =
pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>;
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>;
type CancellationOrigin =
pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>;
// To cancel a proposal before it has been passed, the technical committee must be unanimous or
// Root must agree.
type CancelProposalOrigin = EnsureOneOf<
@@ -728,7 +737,7 @@ impl pallet_collective::Config<TechnicalCollective> for Runtime {
type EnsureRootOrHalfCouncil = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>
pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>,
>;
impl pallet_membership::Config<pallet_membership::Instance1> for Runtime {
type Event = Event;
@@ -768,12 +777,12 @@ impl pallet_treasury::Config for Runtime {
type ApproveOrigin = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>
pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>,
>;
type RejectOrigin = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>
pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>,
>;
type Event = Event;
type OnSlash = ();
@@ -876,8 +885,8 @@ parameter_types! {
}
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
where
Call: From<LocalCall>,
where
Call: From<LocalCall>,
{
fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
call: Call,
@@ -887,10 +896,8 @@ impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for R
) -> Option<(Call, <UncheckedExtrinsic as traits::Extrinsic>::SignaturePayload)> {
let tip = 0;
// take the biggest period possible.
let period = BlockHashCount::get()
.checked_next_power_of_two()
.map(|c| c / 2)
.unwrap_or(2) as u64;
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::<u64>()
// The `System::block_number` is initialized with `n+1`,
@@ -911,10 +918,7 @@ impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for R
log::warn!("Unable to create signed payload: {:?}", e);
})
.ok()?;
let signature = raw_payload
.using_encoded(|payload| {
C::sign(payload, public)
})?;
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)))
@@ -926,7 +930,8 @@ impl frame_system::offchain::SigningTypes for Runtime {
type Signature = Signature;
}
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime where
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
where
Call: From<C>,
{
type Extrinsic = UncheckedExtrinsic;
@@ -965,8 +970,11 @@ impl pallet_grandpa::Config for Runtime {
GrandpaId,
)>>::IdentificationTuple;
type HandleEquivocation =
pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
type HandleEquivocation = pallet_grandpa::EquivocationHandler<
Self::KeyOwnerIdentification,
Offences,
ReportLongevity,
>;
type WeightInfo = ();
}
@@ -1036,7 +1044,8 @@ impl pallet_society::Config for Runtime {
type MembershipChanged = ();
type RotationPeriod = RotationPeriod;
type MaxLockDuration = MaxLockDuration;
type FounderSetOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
type FounderSetOrigin =
pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
type SuspensionJudgementOrigin = pallet_society::EnsureFounder<Runtime>;
type MaxCandidateIntake = MaxCandidateIntake;
type ChallengePeriod = ChallengePeriod;
@@ -1261,11 +1270,7 @@ mod mmr {
use super::Runtime;
pub use pallet_mmr::primitives::*;
pub type Leaf = <
<Runtime as pallet_mmr::Config>::LeafData
as
LeafDataProvider
>::LeafData;
pub type Leaf = <<Runtime as pallet_mmr::Config>::LeafData as LeafDataProvider>::LeafData;
pub type Hash = <Runtime as pallet_mmr::Config>::Hash;
pub type Hashing = <Runtime as pallet_mmr::Config>::Hashing;
}
@@ -1613,9 +1618,11 @@ mod tests {
#[test]
fn validate_transaction_submitter_bounds() {
fn is_submit_signed_transaction<T>() where
fn is_submit_signed_transaction<T>()
where
T: CreateSignedTransaction<Call>,
{}
{
}
is_submit_signed_transaction::<Runtime>();
}
@@ -19,12 +19,12 @@
//! Basic example of end to end runtime tests.
use test_runner::{ChainInfo, SignatureVerificationOverride};
use grandpa::GrandpaBlockImport;
use sc_service::{TFullBackend, TFullClient};
use sc_consensus_babe::BabeBlockImport;
use sc_consensus_manual_seal::consensus::babe::SlotTimestampProvider;
use sc_service::{TFullBackend, TFullClient};
use sp_runtime::generic::Era;
use test_runner::{ChainInfo, SignatureVerificationOverride};
type BlockImport<B, BE, C, SC> = BabeBlockImport<B, C, GrandpaBlockImport<BE, B, C, SC>>;
@@ -54,15 +54,20 @@ impl ChainInfo for NodeTemplateChainInfo {
Self::SelectChain,
>;
type SignedExtras = node_runtime::SignedExtra;
type InherentDataProviders = (SlotTimestampProvider, sp_consensus_babe::inherents::InherentDataProvider);
type InherentDataProviders =
(SlotTimestampProvider, sp_consensus_babe::inherents::InherentDataProvider);
fn signed_extras(from: <Self::Runtime as frame_system::Config>::AccountId) -> Self::SignedExtras {
fn signed_extras(
from: <Self::Runtime as frame_system::Config>::AccountId,
) -> Self::SignedExtras {
(
frame_system::CheckSpecVersion::<Self::Runtime>::new(),
frame_system::CheckTxVersion::<Self::Runtime>::new(),
frame_system::CheckGenesis::<Self::Runtime>::new(),
frame_system::CheckMortality::<Self::Runtime>::from(Era::Immortal),
frame_system::CheckNonce::<Self::Runtime>::from(frame_system::Pallet::<Self::Runtime>::account_nonce(from)),
frame_system::CheckNonce::<Self::Runtime>::from(
frame_system::Pallet::<Self::Runtime>::account_nonce(from),
),
frame_system::CheckWeight::<Self::Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<Self::Runtime>::from(0),
)
@@ -72,32 +77,43 @@ impl ChainInfo for NodeTemplateChainInfo {
#[cfg(test)]
mod tests {
use super::*;
use test_runner::{Node, client_parts, ConfigOrChainSpec, build_runtime, task_executor};
use sp_keyring::sr25519::Keyring::Alice;
use node_cli::chain_spec::development_config;
use sp_keyring::sr25519::Keyring::Alice;
use sp_runtime::{traits::IdentifyAccount, MultiSigner};
use test_runner::{build_runtime, client_parts, task_executor, ConfigOrChainSpec, Node};
#[test]
fn test_runner() {
let mut tokio_runtime = build_runtime().unwrap();
let task_executor = task_executor(tokio_runtime.handle().clone());
let (rpc, task_manager, client, pool, command_sink, backend) =
client_parts::<NodeTemplateChainInfo>(
ConfigOrChainSpec::ChainSpec(Box::new(development_config()), task_executor)
).unwrap();
let node = Node::<NodeTemplateChainInfo>::new(rpc, task_manager, client, pool, command_sink, backend);
let (rpc, task_manager, client, pool, command_sink, backend) = client_parts::<
NodeTemplateChainInfo,
>(
ConfigOrChainSpec::ChainSpec(Box::new(development_config()), task_executor),
)
.unwrap();
let node = Node::<NodeTemplateChainInfo>::new(
rpc,
task_manager,
client,
pool,
command_sink,
backend,
);
tokio_runtime.block_on(async {
// seals blocks
node.seal_blocks(1).await;
// submit extrinsics
let alice = MultiSigner::from(Alice.public()).into_account();
let _hash = node.submit_extrinsic(frame_system::Call::remark((b"hello world").to_vec()), alice)
let _hash = node
.submit_extrinsic(frame_system::Call::remark((b"hello world").to_vec()), alice)
.await
.unwrap();
// look ma, I can read state.
let _events = node.with_state(|| frame_system::Pallet::<node_runtime::Runtime>::events());
let _events =
node.with_state(|| frame_system::Pallet::<node_runtime::Runtime>::events());
// get access to the underlying client.
let _client = node.client();
})
+122 -148
View File
@@ -22,44 +22,42 @@
//! can pregenerate seed database and `clone` it for every iteration of your benchmarks
//! or tests to get consistent, smooth benchmark experience!
use std::{sync::Arc, path::{Path, PathBuf}, collections::BTreeMap};
use node_primitives::Block;
use crate::client::{Client, Backend};
use crate::keyring::*;
use sc_client_db::PruningMode;
use sc_executor::{NativeExecutor, WasmExecutionMethod};
use sp_consensus::{
BlockOrigin, BlockImport, BlockImportParams,
ForkChoiceStrategy, ImportResult, ImportedAux
use std::{
collections::BTreeMap,
path::{Path, PathBuf},
sync::Arc,
};
use sp_runtime::{
generic::BlockId,
OpaqueExtrinsic,
traits::{Block as BlockT, Verify, Zero, IdentifyAccount},
use crate::{
client::{Backend, Client},
keyring::*,
};
use codec::{Decode, Encode};
use futures::executor;
use node_primitives::Block;
use node_runtime::{
Call,
CheckedExtrinsic,
constants::currency::DOLLARS,
UncheckedExtrinsic,
MinimumPeriod,
SystemCall,
BalancesCall,
AccountId,
Signature,
};
use sp_core::{ExecutionContext, blake2_256, traits::SpawnNamed, Pair, Public, sr25519, ed25519};
use sp_api::ProvideRuntimeApi;
use sp_block_builder::BlockBuilder;
use sp_inherents::InherentData;
use sc_client_api::{
ExecutionStrategy, BlockBackend,
execution_extensions::{ExecutionExtensions, ExecutionStrategies},
constants::currency::DOLLARS, AccountId, BalancesCall, Call, CheckedExtrinsic, MinimumPeriod,
Signature, SystemCall, UncheckedExtrinsic,
};
use sc_block_builder::BlockBuilderProvider;
use futures::executor;
use sc_client_api::{
execution_extensions::{ExecutionExtensions, ExecutionStrategies},
BlockBackend, ExecutionStrategy,
};
use sc_client_db::PruningMode;
use sc_executor::{NativeExecutor, WasmExecutionMethod};
use sp_api::ProvideRuntimeApi;
use sp_block_builder::BlockBuilder;
use sp_consensus::{
BlockImport, BlockImportParams, BlockOrigin, ForkChoiceStrategy, ImportResult, ImportedAux,
};
use sp_core::{blake2_256, ed25519, sr25519, traits::SpawnNamed, ExecutionContext, Pair, Public};
use sp_inherents::InherentData;
use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, IdentifyAccount, Verify, Zero},
OpaqueExtrinsic,
};
/// Keyring full of accounts for benching.
///
@@ -92,19 +90,21 @@ impl BenchPair {
///
/// Will panic if cache drop is impossbile.
pub fn drop_system_cache() {
#[cfg(target_os = "windows")] {
#[cfg(target_os = "windows")]
{
log::warn!(
target: "bench-logistics",
"Clearing system cache on windows is not supported. Benchmark might totally be wrong.",
);
return;
return
}
std::process::Command::new("sync")
.output()
.expect("Failed to execute system cache clear");
#[cfg(target_os = "linux")] {
#[cfg(target_os = "linux")]
{
log::trace!(target: "bench-logistics", "Clearing system cache...");
std::process::Command::new("echo")
.args(&["3", ">", "/proc/sys/vm/drop_caches", "2>", "/dev/null"])
@@ -133,7 +133,8 @@ pub fn drop_system_cache() {
log::trace!(target: "bench-logistics", "Clearing system cache done!");
}
#[cfg(target_os = "macos")] {
#[cfg(target_os = "macos")]
{
log::trace!(target: "bench-logistics", "Clearing system cache...");
if let Err(err) = std::process::Command::new("purge").output() {
log::error!("purge error {:?}: ", err);
@@ -169,15 +170,10 @@ impl Clone for BenchDb {
);
let seed_db_files = std::fs::read_dir(seed_dir)
.expect("failed to list file in seed dir")
.map(|f_result|
f_result.expect("failed to read file in seed db")
.path()
).collect::<Vec<PathBuf>>();
fs_extra::copy_items(
&seed_db_files,
dir.path(),
&fs_extra::dir::CopyOptions::new(),
).expect("Copy of seed database is ok");
.map(|f_result| f_result.expect("failed to read file in seed db").path())
.collect::<Vec<PathBuf>>();
fs_extra::copy_items(&seed_db_files, dir.path(), &fs_extra::dir::CopyOptions::new())
.expect("Copy of seed database is ok");
// We clear system cache after db clone but before any warmups.
// This populates system cache with some data unrelated to actual
@@ -204,10 +200,7 @@ pub enum BlockType {
impl BlockType {
/// Create block content description with specified number of transactions.
pub fn to_content(self, size: Option<usize>) -> BlockContent {
BlockContent {
block_type: self,
size,
}
BlockContent { block_type: self, size }
}
}
@@ -230,13 +223,8 @@ pub enum DatabaseType {
impl DatabaseType {
fn into_settings(self, path: PathBuf) -> sc_client_db::DatabaseSettingsSrc {
match self {
Self::RocksDb => sc_client_db::DatabaseSettingsSrc::RocksDb {
path,
cache_size: 512,
},
Self::ParityDb => sc_client_db::DatabaseSettingsSrc::ParityDb {
path,
}
Self::RocksDb => sc_client_db::DatabaseSettingsSrc::RocksDb { path, cache_size: 512 },
Self::ParityDb => sc_client_db::DatabaseSettingsSrc::ParityDb { path },
}
}
}
@@ -251,10 +239,7 @@ pub struct TaskExecutor {
impl TaskExecutor {
fn new() -> Self {
Self {
pool: executor::ThreadPool::new()
.expect("Failed to create task executor")
}
Self { pool: executor::ThreadPool::new().expect("Failed to create task executor") }
}
}
@@ -279,21 +264,17 @@ pub struct BlockContentIterator<'a> {
impl<'a> BlockContentIterator<'a> {
fn new(content: BlockContent, keyring: &'a BenchKeyring, client: &Client) -> Self {
let runtime_version = client.runtime_version_at(&BlockId::number(0))
let runtime_version = client
.runtime_version_at(&BlockId::number(0))
.expect("There should be runtime version at 0");
let genesis_hash = client.block_hash(Zero::zero())
let genesis_hash = client
.block_hash(Zero::zero())
.expect("Database error?")
.expect("Genesis block always exists; qed")
.into();
BlockContentIterator {
iteration: 0,
content,
keyring,
runtime_version,
genesis_hash,
}
BlockContentIterator { iteration: 0, content, keyring, runtime_version, genesis_hash }
}
}
@@ -302,41 +283,36 @@ impl<'a> Iterator for BlockContentIterator<'a> {
fn next(&mut self) -> Option<Self::Item> {
if self.content.size.map(|size| size <= self.iteration).unwrap_or(false) {
return None;
return None
}
let sender = self.keyring.at(self.iteration);
let receiver = get_account_id_from_seed::<sr25519::Public>(
&format!("random-user//{}", self.iteration)
);
let receiver = get_account_id_from_seed::<sr25519::Public>(&format!(
"random-user//{}",
self.iteration
));
let signed = self.keyring.sign(
CheckedExtrinsic {
signed: Some((sender, signed_extra(0, node_runtime::ExistentialDeposit::get() + 1))),
signed: Some((
sender,
signed_extra(0, node_runtime::ExistentialDeposit::get() + 1),
)),
function: match self.content.block_type {
BlockType::RandomTransfersKeepAlive => {
Call::Balances(
BalancesCall::transfer_keep_alive(
sp_runtime::MultiAddress::Id(receiver),
node_runtime::ExistentialDeposit::get() + 1,
)
)
},
BlockType::RandomTransfersKeepAlive =>
Call::Balances(BalancesCall::transfer_keep_alive(
sp_runtime::MultiAddress::Id(receiver),
node_runtime::ExistentialDeposit::get() + 1,
)),
BlockType::RandomTransfersReaping => {
Call::Balances(
BalancesCall::transfer(
sp_runtime::MultiAddress::Id(receiver),
// Transfer so that ending balance would be 1 less than existential deposit
// so that we kill the sender account.
100*DOLLARS - (node_runtime::ExistentialDeposit::get() - 1),
)
)
},
BlockType::Noop => {
Call::System(
SystemCall::remark(Vec::new())
)
Call::Balances(BalancesCall::transfer(
sp_runtime::MultiAddress::Id(receiver),
// Transfer so that ending balance would be 1 less than existential deposit
// so that we kill the sender account.
100 * DOLLARS - (node_runtime::ExistentialDeposit::get() - 1),
))
},
BlockType::Noop => Call::System(SystemCall::remark(Vec::new())),
},
},
self.runtime_version.spec_version,
@@ -346,8 +322,7 @@ impl<'a> Iterator for BlockContentIterator<'a> {
let encoded = Encode::encode(&signed);
let opaque = OpaqueExtrinsic::decode(&mut &encoded[..])
.expect("Failed to decode opaque");
let opaque = OpaqueExtrinsic::decode(&mut &encoded[..]).expect("Failed to decode opaque");
self.iteration += 1;
@@ -373,12 +348,8 @@ impl BenchDb {
"Created seed db at {}",
dir.path().to_string_lossy(),
);
let (_client, _backend, _task_executor) = Self::bench_client(
database_type,
dir.path(),
Profile::Native,
&keyring,
);
let (_client, _backend, _task_executor) =
Self::bench_client(database_type, dir.path(), Profile::Native, &keyring);
let directory_guard = Guard(dir);
BenchDb { keyring, directory_guard, database_type }
@@ -408,7 +379,7 @@ impl BenchDb {
keyring: &BenchKeyring,
) -> (Client, std::sync::Arc<Backend>, TaskExecutor) {
let db_config = sc_client_db::DatabaseSettings {
state_cache_size: 16*1024*1024,
state_cache_size: 16 * 1024 * 1024,
state_cache_child_ratio: Some((0, 100)),
state_pruning: PruningMode::ArchiveAll,
source: database_type.into_settings(dir.into()),
@@ -429,7 +400,8 @@ impl BenchDb {
None,
None,
Default::default(),
).expect("Should not fail");
)
.expect("Should not fail");
(client, backend, task_executor)
}
@@ -445,12 +417,14 @@ impl BenchDb {
.put_data(sp_timestamp::INHERENT_IDENTIFIER, &timestamp)
.expect("Put timestamp failed");
client.runtime_api()
client
.runtime_api()
.inherent_extrinsics_with_context(
&BlockId::number(0),
ExecutionContext::BlockConstruction,
inherent_data,
).expect("Get inherents failed")
)
.expect("Get inherents failed")
}
/// Iterate over some block content with transaction signed using this database keyring.
@@ -474,9 +448,7 @@ impl BenchDb {
pub fn generate_block(&mut self, content: BlockContent) -> Block {
let client = self.client();
let mut block = client
.new_block(Default::default())
.expect("Block creation failed");
let mut block = client.new_block(Default::default()).expect("Block creation failed");
for extrinsic in self.generate_inherents(&client) {
block.push(extrinsic).expect("Push inherent failed");
@@ -486,14 +458,12 @@ impl BenchDb {
for opaque in self.block_content(content, &client) {
match block.push(opaque) {
Err(sp_blockchain::Error::ApplyExtrinsicFailed(
sp_blockchain::ApplyExtrinsicFailed::Validity(e)
)) if e.exhausted_resources() => {
break;
},
sp_blockchain::ApplyExtrinsicFailed::Validity(e),
)) if e.exhausted_resources() => break,
Err(err) => panic!("Error pushing transaction: {:?}", err),
Ok(_) => {},
}
};
}
let block = block.build().expect("Block build failed").block;
@@ -514,12 +484,8 @@ impl BenchDb {
/// Clone this database and create context for testing/benchmarking.
pub fn create_context(&self, profile: Profile) -> BenchContext {
let BenchDb { directory_guard, keyring, database_type } = self.clone();
let (client, backend, task_executor) = Self::bench_client(
database_type,
directory_guard.path(),
profile,
&keyring
);
let (client, backend, task_executor) =
Self::bench_client(database_type, directory_guard.path(), profile, &keyring);
BenchContext {
client: Arc::new(client),
@@ -549,7 +515,8 @@ impl BenchKeyring {
let seed = format!("//endowed-user/{}", n);
let (account_id, pair) = match key_types {
KeyTypes::Sr25519 => {
let pair = sr25519::Pair::from_string(&seed, None).expect("failed to generate pair");
let pair =
sr25519::Pair::from_string(&seed, None).expect("failed to generate pair");
let account_id = AccountPublic::from(pair.public()).into_account();
(account_id, BenchPair::Sr25519(pair))
},
@@ -581,28 +548,34 @@ impl BenchKeyring {
xt: CheckedExtrinsic,
spec_version: u32,
tx_version: u32,
genesis_hash: [u8; 32]
genesis_hash: [u8; 32],
) -> UncheckedExtrinsic {
match xt.signed {
Some((signed, extra)) => {
let payload = (xt.function, extra.clone(), spec_version, tx_version, genesis_hash, genesis_hash);
let payload = (
xt.function,
extra.clone(),
spec_version,
tx_version,
genesis_hash,
genesis_hash,
);
let key = self.accounts.get(&signed).expect("Account id not found in keyring");
let signature = payload.using_encoded(|b| {
if b.len() > 256 {
key.sign(&sp_io::hashing::blake2_256(b))
} else {
key.sign(b)
}
}).into();
let signature = payload
.using_encoded(|b| {
if b.len() > 256 {
key.sign(&sp_io::hashing::blake2_256(b))
} else {
key.sign(b)
}
})
.into();
UncheckedExtrinsic {
signature: Some((sp_runtime::MultiAddress::Id(signed), signature, extra)),
function: payload.0,
}
}
None => UncheckedExtrinsic {
signature: None,
function: xt.function,
},
None => UncheckedExtrinsic { signature: None, function: xt.function },
}
}
@@ -641,7 +614,7 @@ impl Profile {
block_construction: ExecutionStrategy::NativeElseWasm,
offchain_worker: ExecutionStrategy::NativeElseWasm,
other: ExecutionStrategy::NativeElseWasm,
}
},
}
}
}
@@ -676,7 +649,7 @@ fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public
fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
where
AccountPublic: From<<TPublic::Pair as Pair>::Public>
AccountPublic: From<<TPublic::Pair as Pair>::Public>,
{
AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
}
@@ -684,24 +657,25 @@ where
impl BenchContext {
/// Import some block.
pub fn import_block(&mut self, block: Block) {
let mut import_params = BlockImportParams::new(BlockOrigin::NetworkBroadcast, block.header.clone());
let mut import_params =
BlockImportParams::new(BlockOrigin::NetworkBroadcast, block.header.clone());
import_params.body = Some(block.extrinsics().to_vec());
import_params.fork_choice = Some(ForkChoiceStrategy::LongestChain);
assert_eq!(self.client.chain_info().best_number, 0);
assert_eq!(
futures::executor::block_on(self.client.import_block(import_params, Default::default()))
.expect("Failed to import block"),
ImportResult::Imported(
ImportedAux {
header_only: false,
clear_justification_requests: false,
needs_justification: false,
bad_justification: false,
is_new_best: true,
}
futures::executor::block_on(
self.client.import_block(import_params, Default::default())
)
.expect("Failed to import block"),
ImportResult::Imported(ImportedAux {
header_only: false,
clear_justification_requests: false,
needs_justification: false,
bad_justification: false,
is_new_best: true,
})
);
assert_eq!(self.client.chain_info().best_number, 1);
+10 -10
View File
@@ -18,8 +18,8 @@
//! Utilities to build a `TestClient` for `node-runtime`.
use sp_runtime::BuildStorage;
use sc_service::client;
use sp_runtime::BuildStorage;
/// Re-export test-client utilities.
pub use substrate_test_client::*;
@@ -61,13 +61,15 @@ pub trait TestClientBuilderExt: Sized {
fn build(self) -> Client;
}
impl TestClientBuilderExt for substrate_test_client::TestClientBuilder<
node_primitives::Block,
client::LocalCallExecutor<node_primitives::Block, Backend, Executor>,
Backend,
GenesisParameters,
> {
fn new() -> Self{
impl TestClientBuilderExt
for substrate_test_client::TestClientBuilder<
node_primitives::Block,
client::LocalCallExecutor<node_primitives::Block, Backend, Executor>,
Backend,
GenesisParameters,
>
{
fn new() -> Self {
Self::default()
}
@@ -75,5 +77,3 @@ impl TestClientBuilderExt for substrate_test_client::TestClientBuilder<
self.build_with_native_executor(None).0
}
}
+25 -46
View File
@@ -19,14 +19,13 @@
//! Genesis Configuration.
use crate::keyring::*;
use sp_keyring::{Ed25519Keyring, Sr25519Keyring};
use node_runtime::{
GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, SystemConfig,
GrandpaConfig, IndicesConfig, SocietyConfig, wasm_binary_unwrap,
AccountId, StakerStatus, BabeConfig, BABE_GENESIS_EPOCH_CONFIG,
constants::currency::*, wasm_binary_unwrap, AccountId, BabeConfig, BalancesConfig,
GenesisConfig, GrandpaConfig, IndicesConfig, SessionConfig, SocietyConfig, StakerStatus,
StakingConfig, SystemConfig, BABE_GENESIS_EPOCH_CONFIG,
};
use node_runtime::constants::currency::*;
use sp_core::ChangesTrieConfiguration;
use sp_keyring::{Ed25519Keyring, Sr25519Keyring};
use sp_runtime::Perbill;
/// Create genesis runtime configuration for tests.
@@ -41,7 +40,6 @@ pub fn config_endowed(
code: Option<&[u8]>,
extra_endowed: Vec<AccountId>,
) -> GenesisConfig {
let mut endowed = vec![
(alice(), 111 * DOLLARS),
(bob(), 100 * DOLLARS),
@@ -51,59 +49,44 @@ pub fn config_endowed(
(ferdie(), 100 * DOLLARS),
];
endowed.extend(
extra_endowed.into_iter().map(|endowed| (endowed, 100*DOLLARS))
);
endowed.extend(extra_endowed.into_iter().map(|endowed| (endowed, 100 * DOLLARS)));
GenesisConfig {
system: SystemConfig {
changes_trie_config: if support_changes_trie { Some(ChangesTrieConfiguration {
digest_interval: 2,
digest_levels: 2,
}) } else { None },
changes_trie_config: if support_changes_trie {
Some(ChangesTrieConfiguration { digest_interval: 2, digest_levels: 2 })
} else {
None
},
code: code.map(|x| x.to_vec()).unwrap_or_else(|| wasm_binary_unwrap().to_vec()),
},
indices: IndicesConfig {
indices: vec![],
},
balances: BalancesConfig {
balances: endowed,
},
indices: IndicesConfig { indices: vec![] },
balances: BalancesConfig { balances: endowed },
session: SessionConfig {
keys: vec![
(dave(), alice(), to_session_keys(
&Ed25519Keyring::Alice,
&Sr25519Keyring::Alice,
)),
(eve(), bob(), to_session_keys(
&Ed25519Keyring::Bob,
&Sr25519Keyring::Bob,
)),
(ferdie(), charlie(), to_session_keys(
&Ed25519Keyring::Charlie,
&Sr25519Keyring::Charlie,
)),
]
(dave(), alice(), to_session_keys(&Ed25519Keyring::Alice, &Sr25519Keyring::Alice)),
(eve(), bob(), to_session_keys(&Ed25519Keyring::Bob, &Sr25519Keyring::Bob)),
(
ferdie(),
charlie(),
to_session_keys(&Ed25519Keyring::Charlie, &Sr25519Keyring::Charlie),
),
],
},
staking: StakingConfig {
stakers: vec![
(dave(), alice(), 111 * DOLLARS, StakerStatus::Validator),
(eve(), bob(), 100 * DOLLARS, StakerStatus::Validator),
(ferdie(), charlie(), 100 * DOLLARS, StakerStatus::Validator)
(ferdie(), charlie(), 100 * DOLLARS, StakerStatus::Validator),
],
validator_count: 3,
minimum_validator_count: 0,
slash_reward_fraction: Perbill::from_percent(10),
invulnerables: vec![alice(), bob(), charlie()],
.. Default::default()
},
babe: BabeConfig {
authorities: vec![],
epoch_config: Some(BABE_GENESIS_EPOCH_CONFIG),
},
grandpa: GrandpaConfig {
authorities: vec![],
..Default::default()
},
babe: BabeConfig { authorities: vec![], epoch_config: Some(BABE_GENESIS_EPOCH_CONFIG) },
grandpa: GrandpaConfig { authorities: vec![] },
im_online: Default::default(),
authority_discovery: Default::default(),
democracy: Default::default(),
@@ -113,11 +96,7 @@ pub fn config_endowed(
elections: Default::default(),
sudo: Default::default(),
treasury: Default::default(),
society: SocietyConfig {
members: vec![alice(), bob()],
pot: 0,
max_members: 999,
},
society: SocietyConfig { members: vec![alice(), bob()], pot: 0, max_members: 999 },
vesting: Default::default(),
gilt: Default::default(),
transaction_storage: Default::default(),
+22 -17
View File
@@ -18,11 +18,11 @@
//! Test accounts.
use sp_keyring::{AccountKeyring, Sr25519Keyring, Ed25519Keyring};
use node_primitives::{AccountId, Balance, Index};
use node_runtime::{CheckedExtrinsic, UncheckedExtrinsic, SessionKeys, SignedExtra};
use sp_runtime::generic::Era;
use codec::Encode;
use node_primitives::{AccountId, Balance, Index};
use node_runtime::{CheckedExtrinsic, SessionKeys, SignedExtra, UncheckedExtrinsic};
use sp_keyring::{AccountKeyring, Ed25519Keyring, Sr25519Keyring};
use sp_runtime::generic::Era;
/// Alice's account id.
pub fn alice() -> AccountId {
@@ -81,26 +81,31 @@ pub fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra {
}
/// Sign given `CheckedExtrinsic`.
pub fn sign(xt: CheckedExtrinsic, spec_version: u32, tx_version: u32, genesis_hash: [u8; 32]) -> UncheckedExtrinsic {
pub fn sign(
xt: CheckedExtrinsic,
spec_version: u32,
tx_version: u32,
genesis_hash: [u8; 32],
) -> UncheckedExtrinsic {
match xt.signed {
Some((signed, extra)) => {
let payload = (xt.function, extra.clone(), spec_version, tx_version, genesis_hash, genesis_hash);
let payload =
(xt.function, extra.clone(), spec_version, tx_version, genesis_hash, genesis_hash);
let key = AccountKeyring::from_account_id(&signed).unwrap();
let signature = payload.using_encoded(|b| {
if b.len() > 256 {
key.sign(&sp_io::hashing::blake2_256(b))
} else {
key.sign(b)
}
}).into();
let signature = payload
.using_encoded(|b| {
if b.len() > 256 {
key.sign(&sp_io::hashing::blake2_256(b))
} else {
key.sign(b)
}
})
.into();
UncheckedExtrinsic {
signature: Some((sp_runtime::MultiAddress::Id(signed), signature, extra)),
function: payload.0,
}
}
None => UncheckedExtrinsic {
signature: None,
function: xt.function,
},
None => UncheckedExtrinsic { signature: None, function: xt.function },
}
}
+1 -1
View File
@@ -20,7 +20,7 @@
#![warn(missing_docs)]
pub mod bench;
pub mod client;
pub mod genesis;
pub mod keyring;
pub mod bench;