Add chain RPCs and getHeader. (#124)

* Add chain RPCs and getHeader.

Also:
- finish renaming transaction -> extrinsic;
- rejig development chain spec to be more useful.

* Fix.

* Remove invalid comments.

* Fix.
This commit is contained in:
Gav Wood
2018-04-13 14:21:32 +02:00
committed by Tomasz Drwięga
parent e9cdd45145
commit 808d762158
12 changed files with 79 additions and 60 deletions
+1 -1
View File
@@ -130,7 +130,7 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
let client = Arc::new(client::new_in_mem(executor, prepare_genesis)?); let client = Arc::new(client::new_in_mem(executor, prepare_genesis)?);
let address = "127.0.0.1:9933".parse().unwrap(); let address = "127.0.0.1:9933".parse().unwrap();
let handler = rpc::rpc_handler(client, DummyPool); let handler = rpc::rpc_handler(client.clone(), DummyPool, client);
let server = rpc::start_http(&address, handler)?; let server = rpc::start_http(&address, handler)?;
if let Some(_) = matches.subcommand_matches("validator") { if let Some(_) = matches.subcommand_matches("validator") {
+1 -1
View File
@@ -141,7 +141,7 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
address.set_port(rpc_port); address.set_port(rpc_port);
} }
let handler = rpc::rpc_handler(service.client(), service.transaction_pool()); let handler = rpc::rpc_handler(service.client(), service.transaction_pool(), service.client());
let _server = rpc::start_http(&address, handler)?; let _server = rpc::start_http(&address, handler)?;
informant::start(&service, core.handle()); informant::start(&service, core.handle());
+37 -29
View File
@@ -123,7 +123,12 @@ impl network::TransactionPool for TransactionPoolAdapter {
} }
} }
fn poc_1_testnet_config() -> GenesisConfig { pub struct ChainConfig {
genesis_config: GenesisConfig,
boot_nodes: Vec<String>,
}
fn poc_1_testnet_config() -> ChainConfig {
let initial_authorities = vec![ let initial_authorities = vec![
hex!["82c39b31a2b79a90f8e66e7a77fdb85a4ed5517f2ae39f6a80565e8ecae85cf5"].into(), hex!["82c39b31a2b79a90f8e66e7a77fdb85a4ed5517f2ae39f6a80565e8ecae85cf5"].into(),
hex!["4de37a07567ebcbf8c64568428a835269a566723687058e017b6d69db00a77e7"].into(), hex!["4de37a07567ebcbf8c64568428a835269a566723687058e017b6d69db00a77e7"].into(),
@@ -132,13 +137,12 @@ fn poc_1_testnet_config() -> GenesisConfig {
let endowed_accounts = vec![ let endowed_accounts = vec![
hex!["24d132eb1a4cbf8e46de22652019f1e07fadd5037a6a057c75dbbfd4641ba85d"].into(), hex!["24d132eb1a4cbf8e46de22652019f1e07fadd5037a6a057c75dbbfd4641ba85d"].into(),
]; ];
GenesisConfig { let genesis_config = GenesisConfig {
consensus: Some(ConsensusConfig { consensus: Some(ConsensusConfig {
code: include_bytes!("../../runtime/wasm/genesis.wasm").to_vec(), // TODO change code: include_bytes!("../../runtime/wasm/genesis.wasm").to_vec(), // TODO change
authorities: initial_authorities.clone(), authorities: initial_authorities.clone(),
}), }),
system: None, system: None,
// block_time: 5, // 5 second block time.
session: Some(SessionConfig { session: Some(SessionConfig {
validators: initial_authorities.clone(), validators: initial_authorities.clone(),
session_length: 720, // that's 1 hour per session. session_length: 720, // that's 1 hour per session.
@@ -173,10 +177,12 @@ fn poc_1_testnet_config() -> GenesisConfig {
voting_period: 7 * 120 * 24, // 7 day voting period for council members. voting_period: 7 * 120 * 24, // 7 day voting period for council members.
}), }),
parachains: Some(Default::default()), parachains: Some(Default::default()),
} };
let boot_nodes = Vec::new();
ChainConfig { genesis_config, boot_nodes }
} }
fn local_testnet_config() -> GenesisConfig { fn local_testnet_config() -> ChainConfig {
let initial_authorities = vec![ let initial_authorities = vec![
ed25519::Pair::from_seed(b"Alice ").public().into(), ed25519::Pair::from_seed(b"Alice ").public().into(),
ed25519::Pair::from_seed(b"Bob ").public().into(), ed25519::Pair::from_seed(b"Bob ").public().into(),
@@ -189,53 +195,54 @@ fn local_testnet_config() -> GenesisConfig {
ed25519::Pair::from_seed(b"Eve ").public().into(), ed25519::Pair::from_seed(b"Eve ").public().into(),
ed25519::Pair::from_seed(b"Ferdie ").public().into(), ed25519::Pair::from_seed(b"Ferdie ").public().into(),
]; ];
GenesisConfig { let genesis_config = GenesisConfig {
consensus: Some(ConsensusConfig { consensus: Some(ConsensusConfig {
code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm").to_vec(), code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm").to_vec(),
authorities: initial_authorities.clone(), authorities: initial_authorities.clone(),
}), }),
system: None, system: None,
// block_time: 5, // 5 second block time.
session: Some(SessionConfig { session: Some(SessionConfig {
validators: initial_authorities.clone(), validators: initial_authorities.clone(),
session_length: 720, // that's 1 hour per session. session_length: 10,
}), }),
staking: Some(StakingConfig { staking: Some(StakingConfig {
current_era: 0, current_era: 0,
intentions: vec![], intentions: vec![],
transaction_fee: 100, transaction_fee: 1,
balances: endowed_accounts.iter().map(|&k|(k, 1u64 << 60)).collect(), balances: endowed_accounts.iter().map(|&k|(k, 1u64 << 60)).collect(),
validator_count: 12, validator_count: 2,
sessions_per_era: 24, // 24 hours per era. sessions_per_era: 5,
bonding_duration: 90, // 90 days per bond. bonding_duration: 2,
}), }),
democracy: Some(DemocracyConfig { democracy: Some(DemocracyConfig {
launch_period: 120 * 24 * 14, // 2 weeks per public referendum launch_period: 9,
voting_period: 120 * 24 * 28, // 4 weeks to discuss & vote on an active referendum voting_period: 18,
minimum_deposit: 1000, // 1000 as the minimum deposit for a referendum minimum_deposit: 10,
}), }),
council: Some(CouncilConfig { council: Some(CouncilConfig {
active_council: vec![], active_council: vec![],
candidacy_bond: 1000, // 1000 to become a council candidate candidacy_bond: 10,
voter_bond: 100, // 100 down to vote for a candidate voter_bond: 2,
present_slash_per_voter: 1, // slash by 1 per voter for an invalid presentation. present_slash_per_voter: 1,
carry_count: 24, // carry over the 24 runners-up to the next council election carry_count: 4,
presentation_duration: 120 * 24, // one day for presenting winners. presentation_duration: 10,
approval_voting_period: 7 * 120 * 24, // one week period between possible council elections. approval_voting_period: 20,
term_duration: 180 * 120 * 24, // 180 day term duration for the council. term_duration: 40,
desired_seats: 0, // start with no council: we'll raise this once the stake has been dispersed a bit. desired_seats: 0,
inactive_grace_period: 1, // one addition vote should go by before an inactive voter can be reaped. inactive_grace_period: 1,
cooloff_period: 90 * 120 * 24, // 90 day cooling off period if council member vetoes a proposal. cooloff_period: 75,
voting_period: 7 * 120 * 24, // 7 day voting period for council members. voting_period: 20,
}), }),
parachains: Some(Default::default()), parachains: Some(Default::default()),
} };
let boot_nodes = Vec::new();
ChainConfig { genesis_config, boot_nodes }
} }
impl Service { impl Service {
/// Creates and register protocol with the network service /// Creates and register protocol with the network service
pub fn new(config: Configuration) -> Result<Service, error::Error> { pub fn new(mut config: Configuration) -> Result<Service, error::Error> {
// Create client // Create client
let executor = polkadot_executor::Executor::new(); let executor = polkadot_executor::Executor::new();
let mut storage = Default::default(); let mut storage = Default::default();
@@ -250,10 +257,11 @@ impl Service {
info!("Generated a new keypair: {:?}", key.public()); info!("Generated a new keypair: {:?}", key.public());
} }
let genesis_config = match config.chain_spec { let ChainConfig { genesis_config, boot_nodes } = match config.chain_spec {
ChainSpec::Development => local_testnet_config(), ChainSpec::Development => local_testnet_config(),
ChainSpec::PoC1Testnet => poc_1_testnet_config(), ChainSpec::PoC1Testnet => poc_1_testnet_config(),
}; };
config.network.boot_nodes.extend(boot_nodes);
let prepare_genesis = || { let prepare_genesis = || {
storage = genesis_config.build_externalities(); storage = genesis_config.build_externalities();
@@ -55,7 +55,7 @@ impl<B, E> BlockBuilder<B, E> where
number: client.block_number_from_id(block_id)?.ok_or(error::ErrorKind::UnknownBlock(*block_id))? + 1, number: client.block_number_from_id(block_id)?.ok_or(error::ErrorKind::UnknownBlock(*block_id))? + 1,
parent_hash: client.block_hash_from_id(block_id)?.ok_or(error::ErrorKind::UnknownBlock(*block_id))?, parent_hash: client.block_hash_from_id(block_id)?.ok_or(error::ErrorKind::UnknownBlock(*block_id))?,
state_root: Default::default(), state_root: Default::default(),
transaction_root: Default::default(), extrinsics_root: Default::default(),
digest: Default::default(), digest: Default::default(),
}, },
transactions: Default::default(), transactions: Default::default(),
@@ -78,7 +78,7 @@ impl<B, E> BlockBuilder<B, E> where
/// Consume the builder to return a valid `Block` containing all pushed transactions. /// Consume the builder to return a valid `Block` containing all pushed transactions.
pub fn bake(mut self) -> error::Result<Block> { pub fn bake(mut self) -> error::Result<Block> {
self.header.transaction_root = ordered_trie_root(self.transactions.iter().map(Slicable::encode)).0.into(); self.header.extrinsics_root = ordered_trie_root(self.transactions.iter().map(Slicable::encode)).0.into();
let output = state_machine::execute(&self.state, &mut self.changes, &self.executor, "finalise_block", let output = state_machine::execute(&self.state, &mut self.changes, &self.executor, "finalise_block",
&self.header.encode())?; &self.header.encode())?;
self.header = Header::decode(&mut &output[..]).expect("Header came straight out of runtime so must be valid"); self.header = Header::decode(&mut &output[..]).expect("Header came straight out of runtime so must be valid");
+3 -3
View File
@@ -27,7 +27,7 @@ pub fn construct_genesis_block(storage: &HashMap<Vec<u8>, Vec<u8>>) -> Block {
parent_hash: Default::default(), parent_hash: Default::default(),
number: 0, number: 0,
state_root, state_root,
transaction_root: trie_root(vec![].into_iter()).0.into(), extrinsics_root: trie_root(vec![].into_iter()).0.into(),
digest: Default::default(), digest: Default::default(),
}; };
Block { Block {
@@ -62,13 +62,13 @@ mod tests {
UncheckedTransaction { tx, signature } UncheckedTransaction { tx, signature }
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::encode)).0.into(); let extrinsics_root = ordered_trie_root(transactions.iter().map(Slicable::encode)).0.into();
let mut header = Header { let mut header = Header {
parent_hash, parent_hash,
number, number,
state_root, state_root,
transaction_root, extrinsics_root,
digest: Digest { logs: vec![], }, digest: Digest { logs: vec![], },
}; };
let hash = header.blake2_256(); let hash = header.blake2_256();
+9 -9
View File
@@ -146,7 +146,7 @@ pub struct Header {
/// State root after this transition. /// State root after this transition.
pub state_root: Hash, pub state_root: Hash,
/// The root of the trie that represents this block's transactions, indexed by a 32-byte integer. /// The root of the trie that represents this block's transactions, indexed by a 32-byte integer.
pub transaction_root: Hash, pub extrinsics_root: Hash,
// TODO... // TODO...
// /// The root of the trie that represents the receipts from this block's transactions // /// The root of the trie that represents the receipts from this block's transactions
// pub receipts_root: Hash, // pub receipts_root: Hash,
@@ -161,7 +161,7 @@ impl Header {
parent_hash: Default::default(), parent_hash: Default::default(),
number, number,
state_root: Default::default(), state_root: Default::default(),
transaction_root: Default::default(), extrinsics_root: Default::default(),
digest: Default::default(), digest: Default::default(),
} }
} }
@@ -173,7 +173,7 @@ impl Slicable for Header {
parent_hash: Slicable::decode(input)?, parent_hash: Slicable::decode(input)?,
number: Slicable::decode(input)?, number: Slicable::decode(input)?,
state_root: Slicable::decode(input)?, state_root: Slicable::decode(input)?,
transaction_root: Slicable::decode(input)?, extrinsics_root: Slicable::decode(input)?,
digest: Slicable::decode(input)?, digest: Slicable::decode(input)?,
}) })
} }
@@ -184,7 +184,7 @@ impl Slicable for Header {
self.parent_hash.using_encoded(|s| v.extend(s)); self.parent_hash.using_encoded(|s| v.extend(s));
self.number.using_encoded(|s| v.extend(s)); self.number.using_encoded(|s| v.extend(s));
self.state_root.using_encoded(|s| v.extend(s)); self.state_root.using_encoded(|s| v.extend(s));
self.transaction_root.using_encoded(|s| v.extend(s)); self.extrinsics_root.using_encoded(|s| v.extend(s));
self.digest.using_encoded(|s| v.extend(s)); self.digest.using_encoded(|s| v.extend(s));
v v
@@ -222,7 +222,7 @@ mod tests {
parent_hash: 5.into(), parent_hash: 5.into(),
number: 67, number: 67,
state_root: 3.into(), state_root: 3.into(),
transaction_root: 6.into(), extrinsics_root: 6.into(),
digest: Digest { logs: vec![Log(vec![1]), Log(vec![2])] }, digest: Digest { logs: vec![Log(vec![1]), Log(vec![2])] },
}; };
@@ -233,7 +233,7 @@ mod tests {
67, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0,
// state_root // state_root
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
// transaction_root // extrinsics_root
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
// digest (length, log1, log2) // digest (length, log1, log2)
2, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 2 2, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 2
@@ -246,7 +246,7 @@ mod tests {
parent_hash: 5.into(), parent_hash: 5.into(),
number: 67, number: 67,
state_root: 3.into(), state_root: 3.into(),
transaction_root: 6.into(), extrinsics_root: 6.into(),
digest: Digest { logs: vec![Log(vec![1])] }, digest: Digest { logs: vec![Log(vec![1])] },
}; };
@@ -254,7 +254,7 @@ mod tests {
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000005", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000005",
"number": 67, "number": 67,
"stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000003", "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000003",
"transactionRoot": "0x0000000000000000000000000000000000000000000000000000000000000006", "extrinsicsRoot": "0x0000000000000000000000000000000000000000000000000000000000000006",
"digest": { "digest": {
"logs": [ "logs": [
"0x01" "0x01"
@@ -280,7 +280,7 @@ mod tests {
12, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
// state_root // state_root
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// transaction_root // extrinsics_root
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// digest // digest
0, 0, 0, 0, 0, 0, 0, 0,
+3 -1
View File
@@ -26,13 +26,15 @@ extern crate jsonrpc_http_server as http;
use std::io; use std::io;
/// Construct rpc `IoHandler` /// Construct rpc `IoHandler`
pub fn rpc_handler<S, T>(state: S, transaction_pool: T) -> rpc::IoHandler where pub fn rpc_handler<S, T, C>(state: S, transaction_pool: T, chain: C) -> rpc::IoHandler where
S: apis::state::StateApi, S: apis::state::StateApi,
T: apis::author::AuthorApi, T: apis::author::AuthorApi,
C: apis::chain::ChainApi,
{ {
let mut io = rpc::IoHandler::new(); let mut io = rpc::IoHandler::new();
io.extend_with(state.to_delegate()); io.extend_with(state.to_delegate());
io.extend_with(transaction_pool.to_delegate()); io.extend_with(transaction_pool.to_delegate());
io.extend_with(chain.to_delegate());
io io
} }
+11 -2
View File
@@ -16,8 +16,9 @@
//! Substrate blockchain API. //! Substrate blockchain API.
use std::sync::Arc;
use primitives::block; use primitives::block;
use client; use client::{self, Client};
use state_machine; use state_machine;
mod error; mod error;
@@ -33,10 +34,14 @@ build_rpc_trait! {
/// Get header of a relay chain block. /// Get header of a relay chain block.
#[rpc(name = "chain_getHeader")] #[rpc(name = "chain_getHeader")]
fn header(&self, block::HeaderHash) -> Result<Option<block::Header>>; fn header(&self, block::HeaderHash) -> Result<Option<block::Header>>;
/// Get hash of the head.
#[rpc(name = "chain_getHead")]
fn head(&self) -> Result<block::HeaderHash>;
} }
} }
impl<B, E> ChainApi for client::Client<B, E> where impl<B, E> ChainApi for Arc<Client<B, E>> where
B: client::backend::Backend + Send + Sync + 'static, B: client::backend::Backend + Send + Sync + 'static,
E: state_machine::CodeExecutor + Send + Sync + 'static, E: state_machine::CodeExecutor + Send + Sync + 'static,
client::error::Error: From<<<B as client::backend::Backend>::State as state_machine::backend::Backend>::Error>, client::error::Error: From<<<B as client::backend::Backend>::State as state_machine::backend::Backend>::Error>,
@@ -44,4 +49,8 @@ impl<B, E> ChainApi for client::Client<B, E> where
fn header(&self, hash: block::HeaderHash) -> Result<Option<block::Header>> { fn header(&self, hash: block::HeaderHash) -> Result<Option<block::Header>> {
client::Client::header(self, &block::Id::Hash(hash)).chain_err(|| "Blockchain error") client::Client::header(self, &block::Id::Hash(hash)).chain_err(|| "Blockchain error")
} }
fn head(&self) -> Result<block::HeaderHash> {
Ok(client::Client::info(self).chain_err(|| "Blockchain error")?.chain.best_hash)
}
} }
+3 -3
View File
@@ -25,11 +25,11 @@ fn should_return_header() {
parent_hash: 0.into(), parent_hash: 0.into(),
number: 0, number: 0,
state_root: 0.into(), state_root: 0.into(),
transaction_root: Default::default(), extrinsics_root: Default::default(),
digest: Default::default(), digest: Default::default(),
}; };
let client = client::new_in_mem(executor::WasmExecutor, || (test_genesis_block.clone(), vec![])).unwrap(); let client = Arc::new(client::new_in_mem(executor::WasmExecutor, || (test_genesis_block.clone(), vec![])).unwrap());
assert_matches!( assert_matches!(
ChainApi::header(&client, test_genesis_block.blake2_256().into()), ChainApi::header(&client, test_genesis_block.blake2_256().into()),
@@ -37,7 +37,7 @@ fn should_return_header() {
parent_hash: 0.into(), parent_hash: 0.into(),
number: 0, number: 0,
state_root: 0.into(), state_root: 0.into(),
transaction_root: Default::default(), extrinsics_root: Default::default(),
digest: Default::default(), digest: Default::default(),
} }
); );
+2 -2
View File
@@ -26,7 +26,7 @@ fn should_return_storage() {
parent_hash: 0.into(), parent_hash: 0.into(),
number: 0, number: 0,
state_root: 0.into(), state_root: 0.into(),
transaction_root: Default::default(), extrinsics_root: Default::default(),
digest: Default::default(), digest: Default::default(),
}; };
@@ -47,7 +47,7 @@ fn should_call_contract() {
parent_hash: 0.into(), parent_hash: 0.into(),
number: 0, number: 0,
state_root: 0.into(), state_root: 0.into(),
transaction_root: Default::default(), extrinsics_root: Default::default(),
digest: Default::default(), digest: Default::default(),
}; };
@@ -189,7 +189,7 @@ impl Header for substrate_primitives::Header {
type Hash = substrate_primitives::block::HeaderHash; type Hash = substrate_primitives::block::HeaderHash;
type Digest = substrate_primitives::block::Digest; type Digest = substrate_primitives::block::Digest;
fn number(&self) -> &Self::Number { &self.number } fn number(&self) -> &Self::Number { &self.number }
fn extrinsics_root(&self) -> &Self::Hash { &self.transaction_root } fn extrinsics_root(&self) -> &Self::Hash { &self.extrinsics_root }
fn state_root(&self) -> &Self::Hash { &self.state_root } fn state_root(&self) -> &Self::Hash { &self.state_root }
fn parent_hash(&self) -> &Self::Hash { &self.parent_hash } fn parent_hash(&self) -> &Self::Hash { &self.parent_hash }
fn digest(&self) -> &Self::Digest { &self.digest } fn digest(&self) -> &Self::Digest { &self.digest }
@@ -202,7 +202,7 @@ impl Header for substrate_primitives::Header {
) -> Self { ) -> Self {
substrate_primitives::Header { substrate_primitives::Header {
number: number, number: number,
transaction_root: extrinsics_root, extrinsics_root: extrinsics_root,
state_root: state_root, state_root: state_root,
parent_hash: parent_hash, parent_hash: parent_hash,
digest: digest, digest: digest,
@@ -53,8 +53,8 @@ pub fn execute_block(block: Block) {
let txs = block.transactions.iter().map(Slicable::encode).collect::<Vec<_>>(); let txs = block.transactions.iter().map(Slicable::encode).collect::<Vec<_>>();
let txs = txs.iter().map(Vec::as_slice).collect::<Vec<_>>(); let txs = txs.iter().map(Vec::as_slice).collect::<Vec<_>>();
let txs_root = enumerated_trie_root(&txs).into(); let txs_root = enumerated_trie_root(&txs).into();
info_expect_equal_hash(&header.transaction_root, &txs_root); info_expect_equal_hash(&header.extrinsics_root, &txs_root);
assert!(header.transaction_root == txs_root, "Transaction trie root must be valid."); assert!(header.extrinsics_root == txs_root, "Transaction trie root must be valid.");
// execute transactions // execute transactions
block.transactions.iter().for_each(execute_transaction_backend); block.transactions.iter().for_each(execute_transaction_backend);
@@ -159,7 +159,7 @@ mod tests {
parent_hash: [69u8; 32].into(), parent_hash: [69u8; 32].into(),
number: 1, number: 1,
state_root: hex!("97dfcd1f8cbf8845fcb544f89332f1a94c1137f7d1b199ef0b0a6ed217015c3e").into(), state_root: hex!("97dfcd1f8cbf8845fcb544f89332f1a94c1137f7d1b199ef0b0a6ed217015c3e").into(),
transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(), extrinsics_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(),
digest: Digest { logs: vec![], }, digest: Digest { logs: vec![], },
}; };
@@ -187,7 +187,7 @@ mod tests {
parent_hash: [69u8; 32].into(), parent_hash: [69u8; 32].into(),
number: 1, number: 1,
state_root: hex!("0dd8210adaf581464cc68555814a787ed491f8c608d0a0dbbf2208a6d44190b1").into(), state_root: hex!("0dd8210adaf581464cc68555814a787ed491f8c608d0a0dbbf2208a6d44190b1").into(),
transaction_root: hex!("5e44188712452f900acfa1b4bf4084753122ea1856d58187dd33374a2ca653b1").into(), extrinsics_root: hex!("5e44188712452f900acfa1b4bf4084753122ea1856d58187dd33374a2ca653b1").into(),
digest: Digest { logs: vec![], }, digest: Digest { logs: vec![], },
}, },
transactions: vec![ transactions: vec![
@@ -212,7 +212,7 @@ mod tests {
parent_hash: b.header.blake2_256().into(), parent_hash: b.header.blake2_256().into(),
number: 2, number: 2,
state_root: hex!("aea7c370a9fa4075b703742c22cc4fb12759bdd7d5aa5cdd85895447f838b81b").into(), state_root: hex!("aea7c370a9fa4075b703742c22cc4fb12759bdd7d5aa5cdd85895447f838b81b").into(),
transaction_root: hex!("9ac45fbcc93fa6a8b5a3c44f04d936d53569c72a53fbc12eb58bf884f6dbfae5").into(), extrinsics_root: hex!("9ac45fbcc93fa6a8b5a3c44f04d936d53569c72a53fbc12eb58bf884f6dbfae5").into(),
digest: Digest { logs: vec![], }, digest: Digest { logs: vec![], },
}, },
transactions: vec![ transactions: vec![