mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 21:31:02 +00:00
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:
@@ -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 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)?;
|
||||
|
||||
if let Some(_) = matches.subcommand_matches("validator") {
|
||||
|
||||
@@ -141,7 +141,7 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
|
||||
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)?;
|
||||
|
||||
informant::start(&service, core.handle());
|
||||
|
||||
@@ -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![
|
||||
hex!["82c39b31a2b79a90f8e66e7a77fdb85a4ed5517f2ae39f6a80565e8ecae85cf5"].into(),
|
||||
hex!["4de37a07567ebcbf8c64568428a835269a566723687058e017b6d69db00a77e7"].into(),
|
||||
@@ -132,13 +137,12 @@ fn poc_1_testnet_config() -> GenesisConfig {
|
||||
let endowed_accounts = vec![
|
||||
hex!["24d132eb1a4cbf8e46de22652019f1e07fadd5037a6a057c75dbbfd4641ba85d"].into(),
|
||||
];
|
||||
GenesisConfig {
|
||||
let genesis_config = GenesisConfig {
|
||||
consensus: Some(ConsensusConfig {
|
||||
code: include_bytes!("../../runtime/wasm/genesis.wasm").to_vec(), // TODO change
|
||||
authorities: initial_authorities.clone(),
|
||||
}),
|
||||
system: None,
|
||||
// block_time: 5, // 5 second block time.
|
||||
session: Some(SessionConfig {
|
||||
validators: initial_authorities.clone(),
|
||||
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.
|
||||
}),
|
||||
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![
|
||||
ed25519::Pair::from_seed(b"Alice ").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"Ferdie ").public().into(),
|
||||
];
|
||||
GenesisConfig {
|
||||
let genesis_config = GenesisConfig {
|
||||
consensus: Some(ConsensusConfig {
|
||||
code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm").to_vec(),
|
||||
authorities: initial_authorities.clone(),
|
||||
}),
|
||||
system: None,
|
||||
// block_time: 5, // 5 second block time.
|
||||
session: Some(SessionConfig {
|
||||
validators: initial_authorities.clone(),
|
||||
session_length: 720, // that's 1 hour per session.
|
||||
session_length: 10,
|
||||
}),
|
||||
staking: Some(StakingConfig {
|
||||
current_era: 0,
|
||||
intentions: vec![],
|
||||
transaction_fee: 100,
|
||||
transaction_fee: 1,
|
||||
balances: endowed_accounts.iter().map(|&k|(k, 1u64 << 60)).collect(),
|
||||
validator_count: 12,
|
||||
sessions_per_era: 24, // 24 hours per era.
|
||||
bonding_duration: 90, // 90 days per bond.
|
||||
validator_count: 2,
|
||||
sessions_per_era: 5,
|
||||
bonding_duration: 2,
|
||||
}),
|
||||
democracy: Some(DemocracyConfig {
|
||||
launch_period: 120 * 24 * 14, // 2 weeks per public referendum
|
||||
voting_period: 120 * 24 * 28, // 4 weeks to discuss & vote on an active referendum
|
||||
minimum_deposit: 1000, // 1000 as the minimum deposit for a referendum
|
||||
launch_period: 9,
|
||||
voting_period: 18,
|
||||
minimum_deposit: 10,
|
||||
}),
|
||||
council: Some(CouncilConfig {
|
||||
active_council: vec![],
|
||||
candidacy_bond: 1000, // 1000 to become a council candidate
|
||||
voter_bond: 100, // 100 down to vote for a candidate
|
||||
present_slash_per_voter: 1, // slash by 1 per voter for an invalid presentation.
|
||||
carry_count: 24, // carry over the 24 runners-up to the next council election
|
||||
presentation_duration: 120 * 24, // one day for presenting winners.
|
||||
approval_voting_period: 7 * 120 * 24, // one week period between possible council elections.
|
||||
term_duration: 180 * 120 * 24, // 180 day term duration for the council.
|
||||
desired_seats: 0, // start with no council: we'll raise this once the stake has been dispersed a bit.
|
||||
inactive_grace_period: 1, // one addition vote should go by before an inactive voter can be reaped.
|
||||
candidacy_bond: 10,
|
||||
voter_bond: 2,
|
||||
present_slash_per_voter: 1,
|
||||
carry_count: 4,
|
||||
presentation_duration: 10,
|
||||
approval_voting_period: 20,
|
||||
term_duration: 40,
|
||||
desired_seats: 0,
|
||||
inactive_grace_period: 1,
|
||||
|
||||
cooloff_period: 90 * 120 * 24, // 90 day cooling off period if council member vetoes a proposal.
|
||||
voting_period: 7 * 120 * 24, // 7 day voting period for council members.
|
||||
cooloff_period: 75,
|
||||
voting_period: 20,
|
||||
}),
|
||||
parachains: Some(Default::default()),
|
||||
}
|
||||
};
|
||||
let boot_nodes = Vec::new();
|
||||
ChainConfig { genesis_config, boot_nodes }
|
||||
}
|
||||
|
||||
impl 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
|
||||
let executor = polkadot_executor::Executor::new();
|
||||
let mut storage = Default::default();
|
||||
@@ -250,10 +257,11 @@ impl Service {
|
||||
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::PoC1Testnet => poc_1_testnet_config(),
|
||||
};
|
||||
config.network.boot_nodes.extend(boot_nodes);
|
||||
|
||||
let prepare_genesis = || {
|
||||
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,
|
||||
parent_hash: client.block_hash_from_id(block_id)?.ok_or(error::ErrorKind::UnknownBlock(*block_id))?,
|
||||
state_root: Default::default(),
|
||||
transaction_root: Default::default(),
|
||||
extrinsics_root: Default::default(),
|
||||
digest: 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.
|
||||
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",
|
||||
&self.header.encode())?;
|
||||
self.header = Header::decode(&mut &output[..]).expect("Header came straight out of runtime so must be valid");
|
||||
|
||||
@@ -27,7 +27,7 @@ pub fn construct_genesis_block(storage: &HashMap<Vec<u8>, Vec<u8>>) -> Block {
|
||||
parent_hash: Default::default(),
|
||||
number: 0,
|
||||
state_root,
|
||||
transaction_root: trie_root(vec![].into_iter()).0.into(),
|
||||
extrinsics_root: trie_root(vec![].into_iter()).0.into(),
|
||||
digest: Default::default(),
|
||||
};
|
||||
Block {
|
||||
@@ -62,13 +62,13 @@ mod tests {
|
||||
UncheckedTransaction { tx, signature }
|
||||
}).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 {
|
||||
parent_hash,
|
||||
number,
|
||||
state_root,
|
||||
transaction_root,
|
||||
extrinsics_root,
|
||||
digest: Digest { logs: vec![], },
|
||||
};
|
||||
let hash = header.blake2_256();
|
||||
|
||||
@@ -146,7 +146,7 @@ pub struct Header {
|
||||
/// State root after this transition.
|
||||
pub state_root: Hash,
|
||||
/// 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...
|
||||
// /// The root of the trie that represents the receipts from this block's transactions
|
||||
// pub receipts_root: Hash,
|
||||
@@ -161,7 +161,7 @@ impl Header {
|
||||
parent_hash: Default::default(),
|
||||
number,
|
||||
state_root: Default::default(),
|
||||
transaction_root: Default::default(),
|
||||
extrinsics_root: Default::default(),
|
||||
digest: Default::default(),
|
||||
}
|
||||
}
|
||||
@@ -173,7 +173,7 @@ impl Slicable for Header {
|
||||
parent_hash: Slicable::decode(input)?,
|
||||
number: Slicable::decode(input)?,
|
||||
state_root: Slicable::decode(input)?,
|
||||
transaction_root: Slicable::decode(input)?,
|
||||
extrinsics_root: 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.number.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));
|
||||
|
||||
v
|
||||
@@ -222,7 +222,7 @@ mod tests {
|
||||
parent_hash: 5.into(),
|
||||
number: 67,
|
||||
state_root: 3.into(),
|
||||
transaction_root: 6.into(),
|
||||
extrinsics_root: 6.into(),
|
||||
digest: Digest { logs: vec![Log(vec![1]), Log(vec![2])] },
|
||||
};
|
||||
|
||||
@@ -233,7 +233,7 @@ mod tests {
|
||||
67, 0, 0, 0, 0, 0, 0, 0,
|
||||
// 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,
|
||||
// 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,
|
||||
// digest (length, log1, log2)
|
||||
2, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 2
|
||||
@@ -246,7 +246,7 @@ mod tests {
|
||||
parent_hash: 5.into(),
|
||||
number: 67,
|
||||
state_root: 3.into(),
|
||||
transaction_root: 6.into(),
|
||||
extrinsics_root: 6.into(),
|
||||
digest: Digest { logs: vec![Log(vec![1])] },
|
||||
};
|
||||
|
||||
@@ -254,7 +254,7 @@ mod tests {
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000005",
|
||||
"number": 67,
|
||||
"stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000003",
|
||||
"transactionRoot": "0x0000000000000000000000000000000000000000000000000000000000000006",
|
||||
"extrinsicsRoot": "0x0000000000000000000000000000000000000000000000000000000000000006",
|
||||
"digest": {
|
||||
"logs": [
|
||||
"0x01"
|
||||
@@ -280,7 +280,7 @@ mod tests {
|
||||
12, 0, 0, 0, 0, 0, 0, 0,
|
||||
// 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,
|
||||
// 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,
|
||||
// digest
|
||||
0, 0, 0, 0,
|
||||
|
||||
@@ -26,13 +26,15 @@ extern crate jsonrpc_http_server as http;
|
||||
use std::io;
|
||||
|
||||
/// 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,
|
||||
T: apis::author::AuthorApi,
|
||||
C: apis::chain::ChainApi,
|
||||
{
|
||||
let mut io = rpc::IoHandler::new();
|
||||
io.extend_with(state.to_delegate());
|
||||
io.extend_with(transaction_pool.to_delegate());
|
||||
io.extend_with(chain.to_delegate());
|
||||
io
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
|
||||
//! Substrate blockchain API.
|
||||
|
||||
use std::sync::Arc;
|
||||
use primitives::block;
|
||||
use client;
|
||||
use client::{self, Client};
|
||||
use state_machine;
|
||||
|
||||
mod error;
|
||||
@@ -33,10 +34,14 @@ build_rpc_trait! {
|
||||
/// Get header of a relay chain block.
|
||||
#[rpc(name = "chain_getHeader")]
|
||||
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,
|
||||
E: state_machine::CodeExecutor + Send + Sync + 'static,
|
||||
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>> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,11 @@ fn should_return_header() {
|
||||
parent_hash: 0.into(),
|
||||
number: 0,
|
||||
state_root: 0.into(),
|
||||
transaction_root: Default::default(),
|
||||
extrinsics_root: 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!(
|
||||
ChainApi::header(&client, test_genesis_block.blake2_256().into()),
|
||||
@@ -37,7 +37,7 @@ fn should_return_header() {
|
||||
parent_hash: 0.into(),
|
||||
number: 0,
|
||||
state_root: 0.into(),
|
||||
transaction_root: Default::default(),
|
||||
extrinsics_root: Default::default(),
|
||||
digest: Default::default(),
|
||||
}
|
||||
);
|
||||
|
||||
@@ -26,7 +26,7 @@ fn should_return_storage() {
|
||||
parent_hash: 0.into(),
|
||||
number: 0,
|
||||
state_root: 0.into(),
|
||||
transaction_root: Default::default(),
|
||||
extrinsics_root: Default::default(),
|
||||
digest: Default::default(),
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ fn should_call_contract() {
|
||||
parent_hash: 0.into(),
|
||||
number: 0,
|
||||
state_root: 0.into(),
|
||||
transaction_root: Default::default(),
|
||||
extrinsics_root: Default::default(),
|
||||
digest: Default::default(),
|
||||
};
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@ impl Header for substrate_primitives::Header {
|
||||
type Hash = substrate_primitives::block::HeaderHash;
|
||||
type Digest = substrate_primitives::block::Digest;
|
||||
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 parent_hash(&self) -> &Self::Hash { &self.parent_hash }
|
||||
fn digest(&self) -> &Self::Digest { &self.digest }
|
||||
@@ -202,7 +202,7 @@ impl Header for substrate_primitives::Header {
|
||||
) -> Self {
|
||||
substrate_primitives::Header {
|
||||
number: number,
|
||||
transaction_root: extrinsics_root,
|
||||
extrinsics_root: extrinsics_root,
|
||||
state_root: state_root,
|
||||
parent_hash: parent_hash,
|
||||
digest: digest,
|
||||
|
||||
@@ -53,8 +53,8 @@ pub fn execute_block(block: Block) {
|
||||
let txs = block.transactions.iter().map(Slicable::encode).collect::<Vec<_>>();
|
||||
let txs = txs.iter().map(Vec::as_slice).collect::<Vec<_>>();
|
||||
let txs_root = enumerated_trie_root(&txs).into();
|
||||
info_expect_equal_hash(&header.transaction_root, &txs_root);
|
||||
assert!(header.transaction_root == txs_root, "Transaction trie root must be valid.");
|
||||
info_expect_equal_hash(&header.extrinsics_root, &txs_root);
|
||||
assert!(header.extrinsics_root == txs_root, "Transaction trie root must be valid.");
|
||||
|
||||
// execute transactions
|
||||
block.transactions.iter().for_each(execute_transaction_backend);
|
||||
@@ -159,7 +159,7 @@ mod tests {
|
||||
parent_hash: [69u8; 32].into(),
|
||||
number: 1,
|
||||
state_root: hex!("97dfcd1f8cbf8845fcb544f89332f1a94c1137f7d1b199ef0b0a6ed217015c3e").into(),
|
||||
transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(),
|
||||
extrinsics_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(),
|
||||
digest: Digest { logs: vec![], },
|
||||
};
|
||||
|
||||
@@ -187,7 +187,7 @@ mod tests {
|
||||
parent_hash: [69u8; 32].into(),
|
||||
number: 1,
|
||||
state_root: hex!("0dd8210adaf581464cc68555814a787ed491f8c608d0a0dbbf2208a6d44190b1").into(),
|
||||
transaction_root: hex!("5e44188712452f900acfa1b4bf4084753122ea1856d58187dd33374a2ca653b1").into(),
|
||||
extrinsics_root: hex!("5e44188712452f900acfa1b4bf4084753122ea1856d58187dd33374a2ca653b1").into(),
|
||||
digest: Digest { logs: vec![], },
|
||||
},
|
||||
transactions: vec![
|
||||
@@ -212,7 +212,7 @@ mod tests {
|
||||
parent_hash: b.header.blake2_256().into(),
|
||||
number: 2,
|
||||
state_root: hex!("aea7c370a9fa4075b703742c22cc4fb12759bdd7d5aa5cdd85895447f838b81b").into(),
|
||||
transaction_root: hex!("9ac45fbcc93fa6a8b5a3c44f04d936d53569c72a53fbc12eb58bf884f6dbfae5").into(),
|
||||
extrinsics_root: hex!("9ac45fbcc93fa6a8b5a3c44f04d936d53569c72a53fbc12eb58bf884f6dbfae5").into(),
|
||||
digest: Digest { logs: vec![], },
|
||||
},
|
||||
transactions: vec![
|
||||
|
||||
Reference in New Issue
Block a user