mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 23:31:07 +00:00
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:
@@ -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!()
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
))
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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(),
|
||||
};
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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])));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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| {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
})
|
||||
|
||||
@@ -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, ×tamp)
|
||||
.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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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 },
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
pub mod bench;
|
||||
pub mod client;
|
||||
pub mod genesis;
|
||||
pub mod keyring;
|
||||
pub mod bench;
|
||||
|
||||
Reference in New Issue
Block a user