mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 09:31:12 +00:00
Make node-template in sync with node. (#3422)
* Make node-template in sync with node. * Update service.rs * Updated babe constants. * Added SignedExtra for CheckVersion in node-template and subkey. * Added CheckVersion SignedExtra for node. * Fixed tests. * Try fix integration test. * Attempt 2 at fixing integration test. * Update node-template/runtime/src/lib.rs
This commit is contained in:
committed by
Gavin Wood
parent
8eacdb54de
commit
0bb44f5024
Generated
+7
-4
@@ -2406,9 +2406,10 @@ dependencies = [
|
||||
"substrate-basic-authorship 2.0.0",
|
||||
"substrate-cli 2.0.0",
|
||||
"substrate-client 2.0.0",
|
||||
"substrate-consensus-aura 2.0.0",
|
||||
"substrate-consensus-aura-primitives 2.0.0",
|
||||
"substrate-consensus-babe 2.0.0",
|
||||
"substrate-consensus-babe-primitives 2.0.0",
|
||||
"substrate-executor 2.0.0",
|
||||
"substrate-finality-grandpa 2.0.0",
|
||||
"substrate-finality-grandpa-primitives 2.0.0",
|
||||
"substrate-inherents 2.0.0",
|
||||
"substrate-network 2.0.0",
|
||||
@@ -2431,16 +2432,18 @@ dependencies = [
|
||||
"sr-primitives 2.0.0",
|
||||
"sr-std 2.0.0",
|
||||
"sr-version 2.0.0",
|
||||
"srml-aura 2.0.0",
|
||||
"srml-babe 2.0.0",
|
||||
"srml-balances 2.0.0",
|
||||
"srml-executive 2.0.0",
|
||||
"srml-grandpa 2.0.0",
|
||||
"srml-indices 2.0.0",
|
||||
"srml-sudo 2.0.0",
|
||||
"srml-support 2.0.0",
|
||||
"srml-system 2.0.0",
|
||||
"srml-timestamp 2.0.0",
|
||||
"substrate-client 2.0.0",
|
||||
"substrate-consensus-aura-primitives 2.0.0",
|
||||
"substrate-consensus-babe-primitives 2.0.0",
|
||||
"substrate-consensus-common-primitives 2.0.0",
|
||||
"substrate-offchain-primitives 2.0.0",
|
||||
"substrate-primitives 2.0.0",
|
||||
"substrate-session 2.0.0",
|
||||
|
||||
@@ -27,8 +27,9 @@ substrate-service = { path = "../core/service" }
|
||||
inherents = { package = "substrate-inherents", path = "../core/inherents" }
|
||||
transaction-pool = { package = "substrate-transaction-pool", path = "../core/transaction-pool" }
|
||||
network = { package = "substrate-network", path = "../core/network" }
|
||||
consensus = { package = "substrate-consensus-aura", path = "../core/consensus/aura" }
|
||||
aura-primitives = { package = "substrate-consensus-aura-primitives", path = "../core/consensus/aura/primitives" }
|
||||
babe = { package = "substrate-consensus-babe", path = "../core/consensus/babe" }
|
||||
babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../core/consensus/babe/primitives" }
|
||||
grandpa = { package = "substrate-finality-grandpa", path = "../core/finality-grandpa" }
|
||||
grandpa-primitives = { package = "substrate-finality-grandpa-primitives", path = "../core/finality-grandpa/primitives" }
|
||||
substrate-client = { path = "../core/client" }
|
||||
basic-authorship = { package = "substrate-basic-authorship", path = "../core/basic-authorship" }
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Template Node
|
||||
# Substrate Node Template
|
||||
|
||||
A new SRML-based Substrate node, ready for hacking.
|
||||
|
||||
# Building
|
||||
## Build
|
||||
|
||||
Install Rust:
|
||||
|
||||
@@ -16,13 +16,15 @@ Install required tools:
|
||||
./scripts/init.sh
|
||||
```
|
||||
|
||||
Build all native code:
|
||||
Build Wasm and native code:
|
||||
|
||||
```bash
|
||||
cargo build
|
||||
```
|
||||
|
||||
# Run
|
||||
## Run
|
||||
|
||||
### Single node development chain
|
||||
|
||||
You can start a development chain with:
|
||||
|
||||
@@ -32,7 +34,13 @@ cargo run -- --dev
|
||||
|
||||
Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run -- --dev`.
|
||||
|
||||
If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain that have been endowed with testnet units. Give each node a name and expose them so they are listed on the Polkadot [telemetry site](https://telemetry.polkadot.io/#/Local%20Testnet). You'll need two terminal windows open.
|
||||
### Multi-node local testnet
|
||||
|
||||
If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain that have been endowed with testnet units.
|
||||
|
||||
Optionally, give each node a name and expose them so they are listed on the Polkadot [telemetry site](https://telemetry.polkadot.io/#/Local%20Testnet).
|
||||
|
||||
You'll need two terminal windows open.
|
||||
|
||||
We'll start Alice's substrate node first on default TCP port 30333 with her chain database stored locally at `/tmp/alice`. The bootnode ID of her node is `QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR`, which is generated from the `--node-key` value that we specify below:
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ authors = ["Anonymous"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
|
||||
serde = { version = "1.0", optional = true, features = ["derive"] }
|
||||
safe-mix = { version = "1.0", default-features = false }
|
||||
codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] }
|
||||
@@ -16,15 +15,17 @@ support = { package = "srml-support", path = "../../srml/support", default_featu
|
||||
primitives = { package = "substrate-primitives", path = "../../core/primitives", default_features = false }
|
||||
substrate-session = { path = "../../core/session", default-features = false }
|
||||
balances = { package = "srml-balances", path = "../../srml/balances", default_features = false }
|
||||
aura = { package = "srml-aura", path = "../../srml/aura", default_features = false }
|
||||
babe = { package = "srml-babe", path = "../../srml/babe", default-features = false }
|
||||
babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false }
|
||||
executive = { package = "srml-executive", path = "../../srml/executive", default_features = false }
|
||||
indices = { package = "srml-indices", path = "../../srml/indices", default_features = false }
|
||||
grandpa = { package = "srml-grandpa", path = "../../srml/grandpa", default-features = false }
|
||||
system = { package = "srml-system", path = "../../srml/system", default_features = false }
|
||||
timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default_features = false }
|
||||
sudo = { package = "srml-sudo", path = "../../srml/sudo", default_features = false }
|
||||
sr-primitives = { path = "../../core/sr-primitives", default_features = false }
|
||||
client = { package = "substrate-client", path = "../../core/client", default_features = false }
|
||||
consensus-aura = { package = "substrate-consensus-aura-primitives", path = "../../core/consensus/aura/primitives", default_features = false }
|
||||
consensus-primitives = { package = "substrate-consensus-common-primitives", path = "../../core/consensus/common/primitives", default-features = false }
|
||||
offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false }
|
||||
|
||||
[build-dependencies]
|
||||
@@ -39,9 +40,11 @@ std = [
|
||||
"runtime-io/std",
|
||||
"support/std",
|
||||
"balances/std",
|
||||
"babe/std",
|
||||
"babe-primitives/std",
|
||||
"executive/std",
|
||||
"aura/std",
|
||||
"indices/std",
|
||||
"grandpa/std",
|
||||
"primitives/std",
|
||||
"sr-primitives/std",
|
||||
"system/std",
|
||||
@@ -50,7 +53,7 @@ std = [
|
||||
"version/std",
|
||||
"serde",
|
||||
"safe-mix/std",
|
||||
"consensus-aura/std",
|
||||
"consensus-primitives/std",
|
||||
"offchain-primitives/std",
|
||||
"substrate-session/std",
|
||||
]
|
||||
|
||||
@@ -9,16 +9,19 @@
|
||||
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
|
||||
|
||||
use rstd::prelude::*;
|
||||
use primitives::{sr25519, OpaqueMetadata, crypto::key_types};
|
||||
use primitives::{OpaqueMetadata, crypto::key_types};
|
||||
use sr_primitives::{
|
||||
ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str,
|
||||
impl_opaque_keys,
|
||||
impl_opaque_keys, AnySignature
|
||||
};
|
||||
use sr_primitives::traits::{NumberFor, BlakeTwo256, Block as BlockT, StaticLookup, Verify, ConvertInto};
|
||||
use sr_primitives::traits::{NumberFor, BlakeTwo256, Block as BlockT, DigestFor, StaticLookup, Verify, ConvertInto};
|
||||
use sr_primitives::weights::Weight;
|
||||
use babe::{AuthorityId as BabeId};
|
||||
use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight};
|
||||
use grandpa::fg_primitives::{self, ScheduledChange};
|
||||
use client::{
|
||||
block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api},
|
||||
runtime_api, impl_runtime_apis
|
||||
runtime_api as client_api, impl_runtime_apis
|
||||
};
|
||||
use version::RuntimeVersion;
|
||||
#[cfg(feature = "std")]
|
||||
@@ -32,29 +35,31 @@ pub use balances::Call as BalancesCall;
|
||||
pub use sr_primitives::{Permill, Perbill};
|
||||
pub use support::{StorageValue, construct_runtime, parameter_types};
|
||||
|
||||
/// Alias to the signature scheme used for Aura authority signatures.
|
||||
pub type AuraSignature = consensus_aura::sr25519::AuthoritySignature;
|
||||
/// An index to a block.
|
||||
pub type BlockNumber = u32;
|
||||
|
||||
/// The Ed25519 pub key of an session that belongs to an Aura authority of the chain.
|
||||
pub type AuraId = consensus_aura::sr25519::AuthorityId;
|
||||
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
|
||||
pub type Signature = AnySignature;
|
||||
|
||||
/// Alias to pubkey that identifies an account on the chain.
|
||||
pub type AccountId = <AccountSignature as Verify>::Signer;
|
||||
/// Some way of identifying an account on the chain. We intentionally make it equivalent
|
||||
/// to the public key of our transaction signing scheme.
|
||||
pub type AccountId = <Signature as Verify>::Signer;
|
||||
|
||||
/// The type used by authorities to prove their ID.
|
||||
pub type AccountSignature = sr25519::Signature;
|
||||
/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
|
||||
/// never know...
|
||||
pub type AccountIndex = u32;
|
||||
|
||||
/// Balance of an account.
|
||||
pub type Balance = u128;
|
||||
|
||||
/// Index of a transaction in the chain.
|
||||
pub type Index = u32;
|
||||
|
||||
/// A hash of some data used by the chain.
|
||||
pub type Hash = primitives::H256;
|
||||
|
||||
/// Index of a block number in the chain.
|
||||
pub type BlockNumber = u32;
|
||||
|
||||
/// Index of an account's extrinsic in the chain.
|
||||
pub type Nonce = u32;
|
||||
|
||||
/// Balance type for the node.
|
||||
pub type Balance = u128;
|
||||
/// Digest item type.
|
||||
pub type DigestItem = generic::DigestItem<Hash>;
|
||||
|
||||
/// Used for the module template in `./template.rs`
|
||||
mod template;
|
||||
@@ -75,10 +80,14 @@ pub mod opaque {
|
||||
/// Opaque block identifier type.
|
||||
pub type BlockId = generic::BlockId<Block>;
|
||||
|
||||
pub type SessionHandlers = (Grandpa, Babe);
|
||||
|
||||
impl_opaque_keys! {
|
||||
pub struct SessionKeys {
|
||||
#[id(key_types::AURA)]
|
||||
pub aura: AuraId,
|
||||
#[id(key_types::GRANDPA)]
|
||||
pub grandpa: GrandpaId,
|
||||
#[id(key_types::BABE)]
|
||||
pub babe: BabeId,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,6 +102,34 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
};
|
||||
|
||||
/// Constants for Babe.
|
||||
|
||||
/// Since BABE is probabilistic this is the average expected block time that
|
||||
/// we are targetting. Blocks will be produced at a minimum duration defined
|
||||
/// by `SLOT_DURATION`, but some slots will not be allocated to any
|
||||
/// authority and hence no block will be produced. We expect to have this
|
||||
/// block time on average following the defined slot duration and the value
|
||||
/// of `c` configured for BABE (where `1 - c` represents the probability of
|
||||
/// a slot being empty).
|
||||
/// This value is only used indirectly to define the unit constants below
|
||||
/// that are expressed in blocks. The rest of the code should use
|
||||
/// `SLOT_DURATION` instead (like the timestamp module for calculating the
|
||||
/// minimum period).
|
||||
/// <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
|
||||
pub const MILLISECS_PER_BLOCK: u64 = 6000;
|
||||
|
||||
pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
|
||||
|
||||
pub const EPOCH_DURATION_IN_BLOCKS: u32 = 10 * MINUTES;
|
||||
|
||||
// These time units are defined in number of blocks.
|
||||
pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
|
||||
pub const HOURS: BlockNumber = MINUTES * 60;
|
||||
pub const DAYS: BlockNumber = HOURS * 24;
|
||||
|
||||
// 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks.
|
||||
pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4);
|
||||
|
||||
/// The version infromation used to identify this runtime when compiled natively.
|
||||
#[cfg(feature = "std")]
|
||||
pub fn native_version() -> NativeVersion {
|
||||
@@ -118,7 +155,7 @@ impl system::Trait for Runtime {
|
||||
/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
|
||||
type Lookup = Indices;
|
||||
/// The index type for storing how many extrinsics an account has signed.
|
||||
type Index = Nonce;
|
||||
type Index = Index;
|
||||
/// The index type for blocks.
|
||||
type BlockNumber = BlockNumber;
|
||||
/// The type for hashing blocks and tries.
|
||||
@@ -144,8 +181,18 @@ impl system::Trait for Runtime {
|
||||
type Version = Version;
|
||||
}
|
||||
|
||||
impl aura::Trait for Runtime {
|
||||
type AuthorityId = AuraId;
|
||||
parameter_types! {
|
||||
pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
|
||||
pub const ExpectedBlockTime: u64 = MILLISECS_PER_BLOCK;
|
||||
}
|
||||
|
||||
impl babe::Trait for Runtime {
|
||||
type EpochDuration = EpochDuration;
|
||||
type ExpectedBlockTime = ExpectedBlockTime;
|
||||
}
|
||||
|
||||
impl grandpa::Trait for Runtime {
|
||||
type Event = Event;
|
||||
}
|
||||
|
||||
impl indices::Trait for Runtime {
|
||||
@@ -167,7 +214,7 @@ parameter_types! {
|
||||
impl timestamp::Trait for Runtime {
|
||||
/// A timestamp: milliseconds since the unix epoch.
|
||||
type Moment = u64;
|
||||
type OnTimestampSet = Aura;
|
||||
type OnTimestampSet = Babe;
|
||||
type MinimumPeriod = MinimumPeriod;
|
||||
}
|
||||
|
||||
@@ -201,7 +248,6 @@ impl balances::Trait for Runtime {
|
||||
}
|
||||
|
||||
impl sudo::Trait for Runtime {
|
||||
/// The ubiquitous event type.
|
||||
type Event = Event;
|
||||
type Proposal = Call;
|
||||
}
|
||||
@@ -219,7 +265,8 @@ construct_runtime!(
|
||||
{
|
||||
System: system::{Module, Call, Storage, Config, Event},
|
||||
Timestamp: timestamp::{Module, Call, Storage, Inherent},
|
||||
Aura: aura::{Module, Config<T>, Inherent(Timestamp)},
|
||||
Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)},
|
||||
Grandpa: grandpa::{Module, Call, Storage, Config, Event},
|
||||
Indices: indices::{default, Config<T>},
|
||||
Balances: balances,
|
||||
Sudo: sudo,
|
||||
@@ -228,28 +275,34 @@ construct_runtime!(
|
||||
}
|
||||
);
|
||||
|
||||
/// The type used as a helper for interpreting the sender of transactions.
|
||||
type Context = system::ChainContext<Runtime>;
|
||||
/// The address format for describing accounts.
|
||||
type Address = <Indices as StaticLookup>::Source;
|
||||
pub type Address = <Indices as StaticLookup>::Source;
|
||||
/// Block header type as expected by this runtime.
|
||||
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
|
||||
/// Block type as expected by this runtime.
|
||||
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
/// A Block signed with a Justification
|
||||
pub type SignedBlock = generic::SignedBlock<Block>;
|
||||
/// BlockId type as expected by this runtime.
|
||||
pub type BlockId = generic::BlockId<Block>;
|
||||
/// The SignedExtension to the basic transaction logic.
|
||||
pub type SignedExtra = (system::CheckNonce<Runtime>, system::CheckWeight<Runtime>, balances::TakeFees<Runtime>);
|
||||
pub type SignedExtra = (
|
||||
system::CheckVersion<Runtime>,
|
||||
system::CheckGenesis<Runtime>,
|
||||
system::CheckEra<Runtime>,
|
||||
system::CheckNonce<Runtime>,
|
||||
system::CheckWeight<Runtime>,
|
||||
balances::TakeFees<Runtime>
|
||||
);
|
||||
/// Unchecked extrinsic type as expected by this runtime.
|
||||
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, AccountSignature, SignedExtra>;
|
||||
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
|
||||
/// Extrinsic type that has already been checked.
|
||||
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Call, SignedExtra>;
|
||||
/// Executive: handles dispatch to the various modules.
|
||||
pub type Executive = executive::Executive<Runtime, Block, Context, Runtime, AllModules>;
|
||||
pub type Executive = executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;
|
||||
|
||||
// Implement our runtime API endpoints. This is just a bunch of proxying.
|
||||
impl_runtime_apis! {
|
||||
impl runtime_api::Core<Block> for Runtime {
|
||||
impl client_api::Core<Block> for Runtime {
|
||||
fn version() -> RuntimeVersion {
|
||||
VERSION
|
||||
}
|
||||
@@ -263,7 +316,7 @@ impl_runtime_apis! {
|
||||
}
|
||||
}
|
||||
|
||||
impl runtime_api::Metadata<Block> for Runtime {
|
||||
impl client_api::Metadata<Block> for Runtime {
|
||||
fn metadata() -> OpaqueMetadata {
|
||||
Runtime::metadata().into()
|
||||
}
|
||||
@@ -291,24 +344,65 @@ impl_runtime_apis! {
|
||||
}
|
||||
}
|
||||
|
||||
impl runtime_api::TaggedTransactionQueue<Block> for Runtime {
|
||||
impl client_api::TaggedTransactionQueue<Block> for Runtime {
|
||||
fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
|
||||
Executive::validate_transaction(tx)
|
||||
}
|
||||
}
|
||||
|
||||
impl consensus_aura::AuraApi<Block, AuraId> for Runtime {
|
||||
fn slot_duration() -> u64 {
|
||||
Aura::slot_duration()
|
||||
}
|
||||
fn authorities() -> Vec<AuraId> {
|
||||
Aura::authorities()
|
||||
impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
|
||||
fn offchain_worker(number: NumberFor<Block>) {
|
||||
Executive::offchain_worker(number)
|
||||
}
|
||||
}
|
||||
|
||||
impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
|
||||
fn offchain_worker(n: NumberFor<Block>) {
|
||||
Executive::offchain_worker(n)
|
||||
impl fg_primitives::GrandpaApi<Block> for Runtime {
|
||||
fn grandpa_pending_change(digest: &DigestFor<Block>)
|
||||
-> Option<ScheduledChange<NumberFor<Block>>>
|
||||
{
|
||||
Grandpa::pending_change(digest)
|
||||
}
|
||||
|
||||
fn grandpa_forced_change(digest: &DigestFor<Block>)
|
||||
-> Option<(NumberFor<Block>, ScheduledChange<NumberFor<Block>>)>
|
||||
{
|
||||
Grandpa::forced_change(digest)
|
||||
}
|
||||
|
||||
fn grandpa_authorities() -> Vec<(GrandpaId, GrandpaWeight)> {
|
||||
Grandpa::grandpa_authorities()
|
||||
}
|
||||
}
|
||||
|
||||
impl babe_primitives::BabeApi<Block> for Runtime {
|
||||
fn startup_data() -> babe_primitives::BabeConfiguration {
|
||||
// The choice of `c` parameter (where `1 - c` represents the
|
||||
// probability of a slot being empty), is done in accordance to the
|
||||
// slot duration and expected target block time, for safely
|
||||
// resisting network delays of maximum two seconds.
|
||||
// <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
|
||||
babe_primitives::BabeConfiguration {
|
||||
median_required_blocks: 1000,
|
||||
slot_duration: Babe::slot_duration(),
|
||||
c: PRIMARY_PROBABILITY,
|
||||
}
|
||||
}
|
||||
|
||||
fn epoch() -> babe_primitives::Epoch {
|
||||
babe_primitives::Epoch {
|
||||
start_slot: Babe::epoch_start_slot(),
|
||||
authorities: Babe::authorities(),
|
||||
epoch_index: Babe::epoch_index(),
|
||||
randomness: Babe::randomness(),
|
||||
duration: EpochDuration::get(),
|
||||
secondary_slots: Babe::secondary_slots().0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl consensus_primitives::ConsensusApi<Block, babe_primitives::AuthorityId> for Runtime {
|
||||
fn authorities() -> Vec<babe_primitives::AuthorityId> {
|
||||
Babe::authorities().into_iter().map(|(a, _)| a).collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use primitives::{sr25519, Pair};
|
||||
use primitives::{Pair, Public};
|
||||
use node_template_runtime::{
|
||||
AccountId, GenesisConfig, AuraConfig, BalancesConfig,
|
||||
SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY, AuraId
|
||||
AccountId, BabeConfig, BalancesConfig, GenesisConfig, GrandpaConfig,
|
||||
SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY,
|
||||
};
|
||||
use aura_primitives::sr25519::AuthorityPair as AuraPair;
|
||||
use babe_primitives::{AuthorityId as BabeId};
|
||||
use grandpa_primitives::{AuthorityId as GrandpaId};
|
||||
use substrate_service;
|
||||
|
||||
// Note this is the URL for the telemetry server
|
||||
@@ -23,16 +24,21 @@ pub enum Alternative {
|
||||
LocalTestnet,
|
||||
}
|
||||
|
||||
fn authority_key(s: &str) -> AuraId {
|
||||
AuraPair::from_string(&format!("//{}", s), None)
|
||||
/// Helper function to generate a crypto pair from seed
|
||||
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
|
||||
TPublic::Pair::from_string(&format!("//{}", seed), None)
|
||||
.expect("static values are valid; qed")
|
||||
.public()
|
||||
}
|
||||
|
||||
fn account_key(s: &str) -> AccountId {
|
||||
sr25519::Pair::from_string(&format!("//{}", s), None)
|
||||
.expect("static values are valid; qed")
|
||||
.public()
|
||||
/// Helper function to generate stash, controller and session key from seed
|
||||
pub fn get_authority_keys_from_seed(seed: &str) -> (AccountId, AccountId, GrandpaId, BabeId) {
|
||||
(
|
||||
get_from_seed::<AccountId>(&format!("{}//stash", seed)),
|
||||
get_from_seed::<AccountId>(seed),
|
||||
get_from_seed::<GrandpaId>(seed),
|
||||
get_from_seed::<BabeId>(seed),
|
||||
)
|
||||
}
|
||||
|
||||
impl Alternative {
|
||||
@@ -43,12 +49,16 @@ impl Alternative {
|
||||
"Development",
|
||||
"dev",
|
||||
|| testnet_genesis(vec![
|
||||
authority_key("Alice")
|
||||
], vec![
|
||||
account_key("Alice")
|
||||
get_authority_keys_from_seed("Alice"),
|
||||
],
|
||||
account_key("Alice")
|
||||
),
|
||||
get_from_seed::<AccountId>("Alice"),
|
||||
vec![
|
||||
get_from_seed::<AccountId>("Alice"),
|
||||
get_from_seed::<AccountId>("Bob"),
|
||||
get_from_seed::<AccountId>("Alice//stash"),
|
||||
get_from_seed::<AccountId>("Bob//stash"),
|
||||
],
|
||||
true),
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
@@ -59,18 +69,25 @@ impl Alternative {
|
||||
"Local Testnet",
|
||||
"local_testnet",
|
||||
|| testnet_genesis(vec![
|
||||
authority_key("Alice"),
|
||||
authority_key("Bob"),
|
||||
], vec![
|
||||
account_key("Alice"),
|
||||
account_key("Bob"),
|
||||
account_key("Charlie"),
|
||||
account_key("Dave"),
|
||||
account_key("Eve"),
|
||||
account_key("Ferdie"),
|
||||
get_authority_keys_from_seed("Alice"),
|
||||
get_authority_keys_from_seed("Bob"),
|
||||
],
|
||||
get_from_seed::<AccountId>("Alice"),
|
||||
vec![
|
||||
get_from_seed::<AccountId>("Alice"),
|
||||
get_from_seed::<AccountId>("Bob"),
|
||||
get_from_seed::<AccountId>("Charlie"),
|
||||
get_from_seed::<AccountId>("Dave"),
|
||||
get_from_seed::<AccountId>("Eve"),
|
||||
get_from_seed::<AccountId>("Ferdie"),
|
||||
get_from_seed::<AccountId>("Alice//stash"),
|
||||
get_from_seed::<AccountId>("Bob//stash"),
|
||||
get_from_seed::<AccountId>("Charlie//stash"),
|
||||
get_from_seed::<AccountId>("Dave//stash"),
|
||||
get_from_seed::<AccountId>("Eve//stash"),
|
||||
get_from_seed::<AccountId>("Ferdie//stash"),
|
||||
],
|
||||
account_key("Alice"),
|
||||
),
|
||||
true),
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
@@ -89,15 +106,15 @@ impl Alternative {
|
||||
}
|
||||
}
|
||||
|
||||
fn testnet_genesis(initial_authorities: Vec<AuraId>, endowed_accounts: Vec<AccountId>, root_key: AccountId) -> GenesisConfig {
|
||||
fn testnet_genesis(initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId)>,
|
||||
root_key: AccountId,
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
_enable_println: bool) -> GenesisConfig {
|
||||
GenesisConfig {
|
||||
system: Some(SystemConfig {
|
||||
code: WASM_BINARY.to_vec(),
|
||||
changes_trie_config: Default::default(),
|
||||
}),
|
||||
aura: Some(AuraConfig {
|
||||
authorities: initial_authorities.clone(),
|
||||
}),
|
||||
indices: Some(IndicesConfig {
|
||||
ids: endowed_accounts.clone(),
|
||||
}),
|
||||
@@ -108,5 +125,11 @@ fn testnet_genesis(initial_authorities: Vec<AuraId>, endowed_accounts: Vec<Accou
|
||||
sudo: Some(SudoConfig {
|
||||
key: root_key,
|
||||
}),
|
||||
babe: Some(BabeConfig {
|
||||
authorities: initial_authorities.iter().map(|x| (x.3.clone(), 1)).collect(),
|
||||
}),
|
||||
grandpa: Some(GrandpaConfig {
|
||||
authorities: initial_authorities.iter().map(|x| (x.2.clone(), 1)).collect(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
//! Service and ServiceFactory implementation. Specialized wrapper over Substrate service.
|
||||
|
||||
#![warn(unused_extern_crates)]
|
||||
|
||||
//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.
|
||||
|
||||
use std::sync::Arc;
|
||||
use transaction_pool::{self, txpool::{Pool as TransactionPool}};
|
||||
use std::time::Duration;
|
||||
use substrate_client::{self as client, LongestChain};
|
||||
use babe::{import_queue, start_babe, BabeImportQueue, Config};
|
||||
use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};
|
||||
use futures::prelude::*;
|
||||
use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi, WASM_BINARY};
|
||||
use substrate_service::{
|
||||
FactoryFullConfiguration, LightComponents, FullComponents, FullBackend,
|
||||
FullClient, LightClient, LightBackend, FullExecutor, LightExecutor,
|
||||
error::{Error as ServiceError},
|
||||
};
|
||||
use basic_authorship::ProposerFactory;
|
||||
use consensus::{import_queue, start_aura, AuraImportQueue, SlotDuration};
|
||||
use futures::prelude::*;
|
||||
use substrate_client::{self as client, LongestChain};
|
||||
use transaction_pool::{self, txpool::{Pool as TransactionPool}};
|
||||
use inherents::InherentDataProviders;
|
||||
use network::{config::DummyFinalityProofRequestBuilder, construct_simple_protocol};
|
||||
use network::construct_simple_protocol;
|
||||
use substrate_executor::native_executor_instance;
|
||||
use substrate_service::construct_service_factory;
|
||||
use aura_primitives::sr25519::AuthorityPair as AuraAuthorityPair;
|
||||
|
||||
use substrate_service::{ServiceFactory, construct_service_factory, TelemetryOnConnect};
|
||||
pub use substrate_executor::NativeExecutor;
|
||||
|
||||
// Our native executor instance.
|
||||
native_executor_instance!(
|
||||
pub Executor,
|
||||
@@ -29,62 +29,168 @@ native_executor_instance!(
|
||||
WASM_BINARY
|
||||
);
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct NodeConfig {
|
||||
inherent_data_providers: InherentDataProviders,
|
||||
}
|
||||
|
||||
construct_simple_protocol! {
|
||||
/// Demo protocol attachment for substrate.
|
||||
pub struct NodeProtocol where Block = Block { }
|
||||
}
|
||||
|
||||
type BabeBlockImportForService<F> = babe::BabeBlockImport<
|
||||
FullBackend<F>,
|
||||
FullExecutor<F>,
|
||||
<F as ServiceFactory>::Block,
|
||||
grandpa::BlockImportForService<F>,
|
||||
<F as ServiceFactory>::RuntimeApi,
|
||||
client::Client<
|
||||
FullBackend<F>,
|
||||
FullExecutor<F>,
|
||||
<F as ServiceFactory>::Block,
|
||||
<F as ServiceFactory>::RuntimeApi
|
||||
>,
|
||||
>;
|
||||
|
||||
pub struct NodeConfig<F: ServiceFactory> {
|
||||
/// GRANDPA and BABE connection to import block.
|
||||
// FIXME #1134 rather than putting this on the config, let's have an actual intermediate setup state
|
||||
pub import_setup: Option<(
|
||||
BabeBlockImportForService<F>,
|
||||
grandpa::LinkHalfForService<F>,
|
||||
babe::BabeLink,
|
||||
)>,
|
||||
/// Tasks that were created by previous setup steps and should be spawned.
|
||||
pub tasks_to_spawn: Option<Vec<Box<dyn Future<Item = (), Error = ()> + Send>>>,
|
||||
inherent_data_providers: InherentDataProviders,
|
||||
}
|
||||
|
||||
impl<F> Default for NodeConfig<F> where F: ServiceFactory {
|
||||
fn default() -> NodeConfig<F> {
|
||||
NodeConfig {
|
||||
import_setup: None,
|
||||
inherent_data_providers: InherentDataProviders::new(),
|
||||
tasks_to_spawn: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
construct_service_factory! {
|
||||
struct Factory {
|
||||
Block = Block,
|
||||
RuntimeApi = RuntimeApi,
|
||||
NetworkProtocol = NodeProtocol { |config| Ok(NodeProtocol::new()) },
|
||||
RuntimeDispatch = Executor,
|
||||
FullTransactionPoolApi = transaction_pool::ChainApi<
|
||||
client::Client<FullBackend<Self>, FullExecutor<Self>, Block, RuntimeApi>,
|
||||
Block
|
||||
> {
|
||||
|config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client)))
|
||||
},
|
||||
LightTransactionPoolApi = transaction_pool::ChainApi<
|
||||
client::Client<LightBackend<Self>, LightExecutor<Self>, Block, RuntimeApi>,
|
||||
Block
|
||||
> {
|
||||
|config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client)))
|
||||
},
|
||||
Genesis = GenesisConfig,
|
||||
Configuration = NodeConfig,
|
||||
FullService = FullComponents<Self>
|
||||
{ |config: FactoryFullConfiguration<Self>|
|
||||
FullComponents::<Factory>::new(config)
|
||||
FullTransactionPoolApi =
|
||||
transaction_pool::ChainApi<
|
||||
client::Client<FullBackend<Self>, FullExecutor<Self>, Block, RuntimeApi>,
|
||||
Block
|
||||
> {
|
||||
|config, client|
|
||||
Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client)))
|
||||
},
|
||||
LightTransactionPoolApi =
|
||||
transaction_pool::ChainApi<
|
||||
client::Client<LightBackend<Self>, LightExecutor<Self>, Block, RuntimeApi>,
|
||||
Block
|
||||
> {
|
||||
|config, client|
|
||||
Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client)))
|
||||
},
|
||||
Genesis = GenesisConfig,
|
||||
Configuration = NodeConfig<Self>,
|
||||
FullService = FullComponents<Self> {
|
||||
|config: FactoryFullConfiguration<Self>| FullComponents::<Factory>::new(config)
|
||||
},
|
||||
AuthoritySetup = {
|
||||
|service: Self::FullService| {
|
||||
|mut service: Self::FullService| {
|
||||
let (block_import, link_half, babe_link) =
|
||||
service.config_mut().custom.import_setup.take()
|
||||
.expect("Link Half and Block Import are present for Full Services or setup failed before. qed");
|
||||
|
||||
// spawn any futures that were created in the previous setup steps
|
||||
if let Some(tasks) = service.config_mut().custom.tasks_to_spawn.take() {
|
||||
for task in tasks {
|
||||
service.spawn_task(
|
||||
task.select(service.on_exit())
|
||||
.map(|_| ())
|
||||
.map_err(|_| ())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if service.config().roles.is_authority() {
|
||||
let proposer = ProposerFactory {
|
||||
let proposer = basic_authorship::ProposerFactory {
|
||||
client: service.client(),
|
||||
transaction_pool: service.transaction_pool(),
|
||||
};
|
||||
|
||||
let client = service.client();
|
||||
let select_chain = service.select_chain()
|
||||
.ok_or_else(|| ServiceError::SelectChainRequired)?;
|
||||
let aura = start_aura::<_, _, _, _, _, AuraAuthorityPair, _, _, _>(
|
||||
SlotDuration::get_or_compute(&*client)?,
|
||||
client.clone(),
|
||||
select_chain,
|
||||
.ok_or(ServiceError::SelectChainRequired)?;
|
||||
|
||||
let babe_config = babe::BabeParams {
|
||||
config: Config::get_or_compute(&*client)?,
|
||||
keystore: service.keystore(),
|
||||
client,
|
||||
proposer,
|
||||
service.network(),
|
||||
service.config().custom.inherent_data_providers.clone(),
|
||||
service.config().force_authoring,
|
||||
Some(service.keystore()),
|
||||
)?;
|
||||
service.spawn_task(Box::new(aura.select(service.on_exit()).then(|_| Ok(()))));
|
||||
select_chain,
|
||||
block_import,
|
||||
env: proposer,
|
||||
sync_oracle: service.network(),
|
||||
inherent_data_providers: service.config()
|
||||
.custom.inherent_data_providers.clone(),
|
||||
force_authoring: service.config().force_authoring,
|
||||
time_source: babe_link,
|
||||
};
|
||||
|
||||
let babe = start_babe(babe_config)?;
|
||||
let select = babe.select(service.on_exit()).then(|_| Ok(()));
|
||||
|
||||
// the BABE authoring task is considered infallible, i.e. if it
|
||||
// fails we take down the service with it.
|
||||
service.spawn_essential_task(select);
|
||||
}
|
||||
|
||||
let config = grandpa::Config {
|
||||
// FIXME #1578 make this available through chainspec
|
||||
gossip_duration: Duration::from_millis(333),
|
||||
justification_period: 4096,
|
||||
name: Some(service.config().name.clone()),
|
||||
keystore: Some(service.keystore()),
|
||||
};
|
||||
|
||||
match (service.config().roles.is_authority(), service.config().disable_grandpa) {
|
||||
(false, false) => {
|
||||
// start the lightweight GRANDPA observer
|
||||
service.spawn_task(Box::new(grandpa::run_grandpa_observer(
|
||||
config,
|
||||
link_half,
|
||||
service.network(),
|
||||
service.on_exit(),
|
||||
)?));
|
||||
},
|
||||
(true, false) => {
|
||||
// start the full GRANDPA voter
|
||||
let telemetry_on_connect = TelemetryOnConnect {
|
||||
telemetry_connection_sinks: service.telemetry_on_connect_stream(),
|
||||
};
|
||||
let grandpa_config = grandpa::GrandpaParams {
|
||||
config: config,
|
||||
link: link_half,
|
||||
network: service.network(),
|
||||
inherent_data_providers:
|
||||
service.config().custom.inherent_data_providers.clone(),
|
||||
on_exit: service.on_exit(),
|
||||
telemetry_on_connect: Some(telemetry_on_connect),
|
||||
};
|
||||
|
||||
// the GRANDPA voter task is considered infallible, i.e.
|
||||
// if it fails we take down the service with it.
|
||||
service.spawn_essential_task(grandpa::run_grandpa_voter(grandpa_config)?);
|
||||
},
|
||||
(_, true) => {
|
||||
grandpa::setup_disabled_grandpa(
|
||||
service.client(),
|
||||
&service.config().custom.inherent_data_providers,
|
||||
service.network(),
|
||||
)?;
|
||||
},
|
||||
}
|
||||
|
||||
Ok(service)
|
||||
@@ -92,50 +198,70 @@ construct_service_factory! {
|
||||
},
|
||||
LightService = LightComponents<Self>
|
||||
{ |config| <LightComponents<Factory>>::new(config) },
|
||||
FullImportQueue = AuraImportQueue<
|
||||
Self::Block,
|
||||
>
|
||||
{ |
|
||||
FullImportQueue = BabeImportQueue<Self::Block> {
|
||||
|
|
||||
config: &mut FactoryFullConfiguration<Self>,
|
||||
client: Arc<FullClient<Self>>,
|
||||
_select_chain: Self::SelectChain,
|
||||
select_chain: Self::SelectChain,
|
||||
transaction_pool: Option<Arc<TransactionPool<Self::FullTransactionPoolApi>>>,
|
||||
| {
|
||||
import_queue::<_, _, aura_primitives::sr25519::AuthorityPair, _>(
|
||||
SlotDuration::get_or_compute(&*client)?,
|
||||
Box::new(client.clone()),
|
||||
None,
|
||||
None,
|
||||
client,
|
||||
config.custom.inherent_data_providers.clone(),
|
||||
transaction_pool,
|
||||
).map_err(Into::into)
|
||||
}
|
||||
},
|
||||
LightImportQueue = AuraImportQueue<
|
||||
Self::Block,
|
||||
>
|
||||
{ |config: &mut FactoryFullConfiguration<Self>, client: Arc<LightClient<Self>>| {
|
||||
let fprb = Box::new(DummyFinalityProofRequestBuilder::default()) as Box<_>;
|
||||
import_queue::<_, _, AuraAuthorityPair, TransactionPool<Self::FullTransactionPoolApi>>(
|
||||
SlotDuration::get_or_compute(&*client)?,
|
||||
Box::new(client.clone()),
|
||||
None,
|
||||
None,
|
||||
client,
|
||||
config.custom.inherent_data_providers.clone(),
|
||||
None,
|
||||
).map(|q| (q, fprb)).map_err(Into::into)
|
||||
}
|
||||
},
|
||||
let (block_import, link_half) =
|
||||
grandpa::block_import::<_, _, _, RuntimeApi, FullClient<Self>, _>(
|
||||
client.clone(), client.clone(), select_chain
|
||||
)?;
|
||||
let justification_import = block_import.clone();
|
||||
let (import_queue, babe_link, babe_block_import, pruning_task) = import_queue(
|
||||
Config::get_or_compute(&*client)?,
|
||||
block_import,
|
||||
Some(Box::new(justification_import)),
|
||||
None,
|
||||
client.clone(),
|
||||
client,
|
||||
config.custom.inherent_data_providers.clone(),
|
||||
transaction_pool,
|
||||
)?;
|
||||
config.custom.import_setup = Some((babe_block_import.clone(), link_half, babe_link));
|
||||
config.custom.tasks_to_spawn = Some(vec![Box::new(pruning_task)]);
|
||||
Ok(import_queue)
|
||||
}
|
||||
},
|
||||
LightImportQueue = BabeImportQueue<Self::Block>
|
||||
{ |config: &FactoryFullConfiguration<Self>, client: Arc<LightClient<Self>>| {
|
||||
#[allow(deprecated)]
|
||||
let fetch_checker = client.backend().blockchain().fetcher()
|
||||
.upgrade()
|
||||
.map(|fetcher| fetcher.checker().clone())
|
||||
.ok_or_else(|| "Trying to start light import queue without active fetch checker")?;
|
||||
let block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, LightClient<Self>>(
|
||||
client.clone(), Arc::new(fetch_checker), client.clone()
|
||||
)?;
|
||||
|
||||
let finality_proof_import = block_import.clone();
|
||||
let finality_proof_request_builder =
|
||||
finality_proof_import.create_finality_proof_request_builder();
|
||||
|
||||
// FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`.
|
||||
let (import_queue, ..) = import_queue::<_, _, _, _, _, _, TransactionPool<Self::FullTransactionPoolApi>>(
|
||||
Config::get_or_compute(&*client)?,
|
||||
block_import,
|
||||
None,
|
||||
Some(Box::new(finality_proof_import)),
|
||||
client.clone(),
|
||||
client,
|
||||
config.custom.inherent_data_providers.clone(),
|
||||
None,
|
||||
)?;
|
||||
|
||||
Ok((import_queue, finality_proof_request_builder))
|
||||
}},
|
||||
SelectChain = LongestChain<FullBackend<Self>, Self::Block>
|
||||
{ |config: &FactoryFullConfiguration<Self>, client: Arc<FullClient<Self>>| {
|
||||
#[allow(deprecated)]
|
||||
Ok(LongestChain::new(client.backend().clone()))
|
||||
}
|
||||
},
|
||||
FinalityProofProvider = { |_client: Arc<FullClient<Self>>| {
|
||||
Ok(None)
|
||||
FinalityProofProvider = { |client: Arc<FullClient<Self>>| {
|
||||
Ok(Some(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _))
|
||||
}},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ type Number = <<node_primitives::Block as BlockT>::Header as HeaderT>::Number;
|
||||
impl<Number> FactoryState<Number> {
|
||||
fn build_extra(index: node_primitives::Index, phase: u64) -> node_runtime::SignedExtra {
|
||||
(
|
||||
system::CheckVersion::new(),
|
||||
system::CheckGenesis::new(),
|
||||
system::CheckEra::from(Era::mortal(256, phase)),
|
||||
system::CheckNonce::from(index),
|
||||
@@ -132,12 +133,12 @@ impl RuntimeAdapter for FactoryState<Number> {
|
||||
key: &Self::Secret,
|
||||
destination: &Self::AccountId,
|
||||
amount: &Self::Balance,
|
||||
version: u32,
|
||||
genesis_hash: &<Self::Block as BlockT>::Hash,
|
||||
prior_block_hash: &<Self::Block as BlockT>::Hash,
|
||||
) -> <Self::Block as BlockT>::Extrinsic {
|
||||
let index = self.extract_index(&sender, prior_block_hash);
|
||||
let phase = self.extract_phase(*prior_block_hash);
|
||||
|
||||
sign::<Self>(CheckedExtrinsic {
|
||||
signed: Some((sender.clone(), Self::build_extra(index, phase))),
|
||||
function: Call::Balances(
|
||||
@@ -146,7 +147,7 @@ impl RuntimeAdapter for FactoryState<Number> {
|
||||
(*amount).into()
|
||||
)
|
||||
)
|
||||
}, key, (genesis_hash.clone(), prior_block_hash.clone(), (), (), ()))
|
||||
}, key, (version, genesis_hash.clone(), prior_block_hash.clone(), (), (), ()))
|
||||
}
|
||||
|
||||
fn inherent_extrinsics(&self) -> InherentData {
|
||||
|
||||
@@ -454,18 +454,21 @@ mod tests {
|
||||
let to = AddressPublic::from_raw(bob.public().0);
|
||||
let from = AddressPublic::from_raw(charlie.public().0);
|
||||
let genesis_hash = service.get().client().block_hash(0).unwrap().unwrap();
|
||||
let best_block_id = BlockId::number(service.get().client().info().chain.best_number);
|
||||
let version = service.get().client().runtime_version_at(&best_block_id).unwrap().spec_version;
|
||||
let signer = charlie.clone();
|
||||
|
||||
let function = Call::Balances(BalancesCall::transfer(to.into(), amount));
|
||||
|
||||
let check_version = system::CheckVersion::new();
|
||||
let check_genesis = system::CheckGenesis::new();
|
||||
let check_era = system::CheckEra::from(Era::Immortal);
|
||||
let check_nonce = system::CheckNonce::from(index);
|
||||
let check_weight = system::CheckWeight::new();
|
||||
let take_fees = balances::TakeFees::from(0);
|
||||
let extra = (check_genesis, check_era, check_nonce, check_weight, take_fees);
|
||||
let extra = (check_version, check_genesis, check_era, check_nonce, check_weight, take_fees);
|
||||
|
||||
let raw_payload = (function, extra.clone(), genesis_hash, genesis_hash);
|
||||
let raw_payload = (function, extra.clone(), version, genesis_hash, genesis_hash);
|
||||
let signature = raw_payload.using_encoded(|payload| if payload.len() > 256 {
|
||||
signer.sign(&blake2_256(payload)[..])
|
||||
} else {
|
||||
|
||||
@@ -44,7 +44,7 @@ mod tests {
|
||||
use keyring::{AccountKeyring, Ed25519Keyring, Sr25519Keyring};
|
||||
use runtime_support::{Hashable, StorageValue, StorageMap, assert_eq_error_rate, traits::Currency};
|
||||
use state_machine::{CodeExecutor, Externalities, TestExternalities as CoreTestExternalities};
|
||||
use primitives::{ twox_128, blake2_256, Blake2Hasher, ChangesTrieConfiguration, NeverNativeValue, NativeOrEncoded};
|
||||
use primitives::{twox_128, blake2_256, Blake2Hasher, ChangesTrieConfiguration, NeverNativeValue, NativeOrEncoded};
|
||||
use node_primitives::{Hash, BlockNumber, AccountId, Balance, Index};
|
||||
use sr_primitives::traits::{Header as HeaderT, Hash as HashT, Convert};
|
||||
use sr_primitives::{generic::Era, ApplyOutcome, ApplyError, ApplyResult, Perbill};
|
||||
@@ -55,7 +55,7 @@ mod tests {
|
||||
Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, BuildStorage,
|
||||
GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, System, SystemConfig,
|
||||
GrandpaConfig, IndicesConfig, ContractsConfig, Event, SessionKeys, SignedExtra,
|
||||
TransferFee, TransactionBaseFee, TransactionByteFee,
|
||||
TransferFee, TransactionBaseFee, TransactionByteFee
|
||||
};
|
||||
use node_runtime::constants::currency::*;
|
||||
use node_runtime::impls::WeightToFee;
|
||||
@@ -79,6 +79,8 @@ mod tests {
|
||||
|
||||
const GENESIS_HASH: [u8; 32] = [69u8; 32];
|
||||
|
||||
const VERSION: u32 = node_runtime::VERSION.spec_version;
|
||||
|
||||
type TestExternalities<H> = CoreTestExternalities<H, u64>;
|
||||
|
||||
/// Default transfer fee
|
||||
@@ -122,7 +124,7 @@ mod tests {
|
||||
fn sign(xt: CheckedExtrinsic) -> UncheckedExtrinsic {
|
||||
match xt.signed {
|
||||
Some((signed, extra)) => {
|
||||
let payload = (xt.function, extra.clone(), GENESIS_HASH, GENESIS_HASH);
|
||||
let payload = (xt.function, extra.clone(), VERSION, GENESIS_HASH, GENESIS_HASH);
|
||||
let key = AccountKeyring::from_public(&signed).unwrap();
|
||||
let signature = payload.using_encoded(|b| {
|
||||
if b.len() > 256 {
|
||||
@@ -145,6 +147,7 @@ mod tests {
|
||||
|
||||
fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra {
|
||||
(
|
||||
system::CheckVersion::new(),
|
||||
system::CheckGenesis::new(),
|
||||
system::CheckEra::from(Era::mortal(256, 0)),
|
||||
system::CheckNonce::from(nonce),
|
||||
|
||||
@@ -463,6 +463,7 @@ pub type SignedBlock = generic::SignedBlock<Block>;
|
||||
pub type BlockId = generic::BlockId<Block>;
|
||||
/// The SignedExtension to the basic transaction logic.
|
||||
pub type SignedExtra = (
|
||||
system::CheckVersion<Runtime>,
|
||||
system::CheckGenesis<Runtime>,
|
||||
system::CheckEra<Runtime>,
|
||||
system::CheckNonce<Runtime>,
|
||||
|
||||
@@ -97,6 +97,7 @@ fn execute<C: Crypto>(matches: clap::ArgMatches) where
|
||||
{
|
||||
let extra = |i: Index, f: Balance| {
|
||||
(
|
||||
system::CheckVersion::<Runtime>::new(),
|
||||
system::CheckGenesis::<Runtime>::new(),
|
||||
system::CheckEra::<Runtime>::from(Era::Immortal),
|
||||
system::CheckNonce::<Runtime>::from(i),
|
||||
|
||||
@@ -54,6 +54,7 @@ use crate::{RuntimeAdapter, create_block};
|
||||
pub fn next<F, RA>(
|
||||
factory_state: &mut RA,
|
||||
client: &Arc<ComponentClient<FullComponents<F>>>,
|
||||
version: u32,
|
||||
genesis_hash: <RA::Block as BlockT>::Hash,
|
||||
prior_block_hash: <RA::Block as BlockT>::Hash,
|
||||
prior_block_id: BlockId<F::Block>,
|
||||
@@ -92,6 +93,7 @@ where
|
||||
&from.1,
|
||||
&to,
|
||||
&amount,
|
||||
version,
|
||||
&genesis_hash,
|
||||
&prior_block_hash,
|
||||
);
|
||||
|
||||
@@ -77,6 +77,7 @@ pub trait RuntimeAdapter {
|
||||
key: &Self::Secret,
|
||||
destination: &Self::AccountId,
|
||||
amount: &Self::Balance,
|
||||
version: u32,
|
||||
genesis_hash: &<Self::Block as BlockT>::Hash,
|
||||
prior_block_hash: &<Self::Block as BlockT>::Hash,
|
||||
) -> <Self::Block as BlockT>::Extrinsic;
|
||||
@@ -119,6 +120,7 @@ where
|
||||
select_chain.best_chain().map_err(|e| format!("{:?}", e).into());
|
||||
let mut best_hash = best_header?.hash();
|
||||
let best_block_id = BlockId::<F::Block>::hash(best_hash);
|
||||
let version = client.runtime_version_at(&best_block_id)?.spec_version;
|
||||
let genesis_hash = client.block_hash(Zero::zero())?
|
||||
.expect("Genesis block always exists; qed").into();
|
||||
|
||||
@@ -126,6 +128,7 @@ where
|
||||
Mode::MasterToNToM => complex_mode::next::<F, RA>(
|
||||
&mut factory_state,
|
||||
&client,
|
||||
version,
|
||||
genesis_hash,
|
||||
best_hash.into(),
|
||||
best_block_id,
|
||||
@@ -133,6 +136,7 @@ where
|
||||
_ => simple_modes::next::<F, RA>(
|
||||
&mut factory_state,
|
||||
&client,
|
||||
version,
|
||||
genesis_hash,
|
||||
best_hash.into(),
|
||||
best_block_id,
|
||||
|
||||
@@ -49,6 +49,7 @@ use crate::{Mode, RuntimeAdapter, create_block};
|
||||
pub fn next<F, RA>(
|
||||
factory_state: &mut RA,
|
||||
client: &Arc<ComponentClient<FullComponents<F>>>,
|
||||
version: u32,
|
||||
genesis_hash: <RA::Block as BlockT>::Hash,
|
||||
prior_block_hash: <RA::Block as BlockT>::Hash,
|
||||
prior_block_id: BlockId<F::Block>,
|
||||
@@ -83,6 +84,7 @@ where
|
||||
&from.1,
|
||||
&to,
|
||||
&amount,
|
||||
version,
|
||||
&genesis_hash,
|
||||
&prior_block_hash,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user