mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 12:11:02 +00:00
Additional runtime tests for the test-runtime (#69)
* Remove rustc dependency from ed25519 and refactor a little. * Runtime support provides more extensive test-key functionality. * Additional APIs for ed25519 stuff. * Extensive test for test-runtime. * Fixes for the new test key API. * Additional convenience for tests * Take advantage of more convenient API. * Redo formating. * Remove old test identities. * Remove boilerplate, add test. * Refactor out unneeded code. * Clean up algo for determining authorities. * Remove unneeded API. * Make `to_*` consume * Only export keyring when testing * Fix build & warning * Extract Keyring into separate library. * Add tests for Keyring and a trait-based API. * Address grumbles.
This commit is contained in:
committed by
Robert Habermeier
parent
72fa8f3fe2
commit
f344e15bf8
Generated
+15
-1
@@ -195,8 +195,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
name = "ed25519"
|
name = "ed25519"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"substrate-primitives 0.1.0",
|
"substrate-primitives 0.1.0",
|
||||||
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -1021,6 +1021,7 @@ dependencies = [
|
|||||||
"polkadot-runtime 0.1.0",
|
"polkadot-runtime 0.1.0",
|
||||||
"substrate-codec 0.1.0",
|
"substrate-codec 0.1.0",
|
||||||
"substrate-executor 0.1.0",
|
"substrate-executor 0.1.0",
|
||||||
|
"substrate-keyring 0.1.0",
|
||||||
"substrate-primitives 0.1.0",
|
"substrate-primitives 0.1.0",
|
||||||
"substrate-runtime-io 0.1.0",
|
"substrate-runtime-io 0.1.0",
|
||||||
"substrate-runtime-support 0.1.0",
|
"substrate-runtime-support 0.1.0",
|
||||||
@@ -1050,6 +1051,7 @@ dependencies = [
|
|||||||
"polkadot-primitives 0.1.0",
|
"polkadot-primitives 0.1.0",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"substrate-codec 0.1.0",
|
"substrate-codec 0.1.0",
|
||||||
|
"substrate-keyring 0.1.0",
|
||||||
"substrate-primitives 0.1.0",
|
"substrate-primitives 0.1.0",
|
||||||
"substrate-runtime-io 0.1.0",
|
"substrate-runtime-io 0.1.0",
|
||||||
"substrate-runtime-std 0.1.0",
|
"substrate-runtime-std 0.1.0",
|
||||||
@@ -1387,6 +1389,7 @@ dependencies = [
|
|||||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"substrate-codec 0.1.0",
|
"substrate-codec 0.1.0",
|
||||||
"substrate-executor 0.1.0",
|
"substrate-executor 0.1.0",
|
||||||
|
"substrate-keyring 0.1.0",
|
||||||
"substrate-primitives 0.1.0",
|
"substrate-primitives 0.1.0",
|
||||||
"substrate-runtime-support 0.1.0",
|
"substrate-runtime-support 0.1.0",
|
||||||
"substrate-serializer 0.1.0",
|
"substrate-serializer 0.1.0",
|
||||||
@@ -1424,6 +1427,14 @@ dependencies = [
|
|||||||
"triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "substrate-keyring"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"ed25519 0.1.0",
|
||||||
|
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "substrate-network"
|
name = "substrate-network"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -1515,6 +1526,7 @@ dependencies = [
|
|||||||
name = "substrate-runtime-support"
|
name = "substrate-runtime-support"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ed25519 0.1.0",
|
||||||
"environmental 0.1.0",
|
"environmental 0.1.0",
|
||||||
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"substrate-codec 0.1.0",
|
"substrate-codec 0.1.0",
|
||||||
@@ -1548,9 +1560,11 @@ dependencies = [
|
|||||||
name = "substrate-test-runtime"
|
name = "substrate-test-runtime"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ed25519 0.1.0",
|
||||||
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"substrate-codec 0.1.0",
|
"substrate-codec 0.1.0",
|
||||||
|
"substrate-keyring 0.1.0",
|
||||||
"substrate-primitives 0.1.0",
|
"substrate-primitives 0.1.0",
|
||||||
"substrate-runtime-io 0.1.0",
|
"substrate-runtime-io 0.1.0",
|
||||||
"substrate-runtime-std 0.1.0",
|
"substrate-runtime-std 0.1.0",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ members = [
|
|||||||
"substrate/codec",
|
"substrate/codec",
|
||||||
"substrate/environmental",
|
"substrate/environmental",
|
||||||
"substrate/executor",
|
"substrate/executor",
|
||||||
|
"substrate/keyring",
|
||||||
"substrate/network",
|
"substrate/network",
|
||||||
"substrate/primitives",
|
"substrate/primitives",
|
||||||
"substrate/rpc-servers",
|
"substrate/rpc-servers",
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ use client::backend::Backend;
|
|||||||
use client::blockchain::BlockId;
|
use client::blockchain::BlockId;
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use polkadot_runtime::runtime;
|
use polkadot_runtime::runtime;
|
||||||
use polkadot_executor::LocalNativeExecutionDispatch as LocalDispatch;
|
use polkadot_executor::Executor as LocalDispatch;
|
||||||
use substrate_executor::{NativeExecutionDispatch, NativeExecutor};
|
use substrate_executor::{NativeExecutionDispatch, NativeExecutor};
|
||||||
use primitives::{AccountId, SessionKey};
|
use primitives::{AccountId, SessionKey};
|
||||||
use primitives::parachain::DutyRoster;
|
use primitives::parachain::DutyRoster;
|
||||||
@@ -64,8 +64,8 @@ error_chain! {
|
|||||||
///
|
///
|
||||||
/// All calls should fail when the exact runtime is unknown.
|
/// All calls should fail when the exact runtime is unknown.
|
||||||
pub trait PolkadotApi {
|
pub trait PolkadotApi {
|
||||||
/// Get authorities at a given block.
|
/// Get session keys at a given block.
|
||||||
fn authorities(&self, at: &BlockId) -> Result<Vec<SessionKey>>;
|
fn session_keys(&self, at: &BlockId) -> Result<Vec<SessionKey>>;
|
||||||
|
|
||||||
/// Get validators at a given block.
|
/// Get validators at a given block.
|
||||||
fn validators(&self, at: &BlockId) -> Result<Vec<AccountId>>;
|
fn validators(&self, at: &BlockId) -> Result<Vec<AccountId>>;
|
||||||
@@ -104,7 +104,7 @@ macro_rules! with_runtime {
|
|||||||
impl<B: Backend> PolkadotApi for Client<B, NativeExecutor<LocalDispatch>>
|
impl<B: Backend> PolkadotApi for Client<B, NativeExecutor<LocalDispatch>>
|
||||||
where ::client::error::Error: From<<<B as Backend>::State as state_machine::backend::Backend>::Error>
|
where ::client::error::Error: From<<<B as Backend>::State as state_machine::backend::Backend>::Error>
|
||||||
{
|
{
|
||||||
fn authorities(&self, at: &BlockId) -> Result<Vec<SessionKey>> {
|
fn session_keys(&self, at: &BlockId) -> Result<Vec<SessionKey>> {
|
||||||
with_runtime!(self, at, ::runtime::consensus::authorities)
|
with_runtime!(self, at, ::runtime::consensus::authorities)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
|
|||||||
init_logger(log_pattern);
|
init_logger(log_pattern);
|
||||||
|
|
||||||
// Create client
|
// Create client
|
||||||
let executor = polkadot_executor::executor();
|
let executor = polkadot_executor::Executor::new();
|
||||||
let mut storage = Default::default();
|
let mut storage = Default::default();
|
||||||
let god_key = hex!["3d866ec8a9190c8343c2fc593d21d8a6d0c5c4763aaab2349de3a6111d64d124"];
|
let god_key = hex!["3d866ec8a9190c8343c2fc593d21d8a6d0c5c4763aaab2349de3a6111d64d124"];
|
||||||
|
|
||||||
|
|||||||
@@ -16,3 +16,6 @@ substrate-executor = { path = "../../substrate/executor" }
|
|||||||
substrate-primitives = { path = "../../substrate/primitives" }
|
substrate-primitives = { path = "../../substrate/primitives" }
|
||||||
polkadot-primitives = { path = "../primitives" }
|
polkadot-primitives = { path = "../primitives" }
|
||||||
polkadot-runtime = { path = "../runtime" }
|
polkadot-runtime = { path = "../runtime" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
substrate-keyring = { path = "../../substrate/keyring" }
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
//! executed is equivalent to the natively compiled code.
|
//! executed is equivalent to the natively compiled code.
|
||||||
|
|
||||||
extern crate polkadot_runtime;
|
extern crate polkadot_runtime;
|
||||||
extern crate substrate_executor;
|
#[macro_use] extern crate substrate_executor;
|
||||||
extern crate substrate_codec as codec;
|
extern crate substrate_codec as codec;
|
||||||
extern crate substrate_state_machine as state_machine;
|
extern crate substrate_state_machine as state_machine;
|
||||||
extern crate substrate_runtime_io as runtime_io;
|
extern crate substrate_runtime_io as runtime_io;
|
||||||
@@ -27,48 +27,26 @@ extern crate polkadot_primitives as polkadot_primitives;
|
|||||||
extern crate ed25519;
|
extern crate ed25519;
|
||||||
extern crate triehash;
|
extern crate triehash;
|
||||||
|
|
||||||
|
#[cfg(test)] extern crate substrate_keyring as keyring;
|
||||||
#[cfg(test)] extern crate substrate_runtime_support as runtime_support;
|
#[cfg(test)] extern crate substrate_runtime_support as runtime_support;
|
||||||
#[cfg(test)] #[macro_use] extern crate hex_literal;
|
#[cfg(test)] #[macro_use] extern crate hex_literal;
|
||||||
|
|
||||||
use polkadot_runtime as runtime;
|
native_executor_instance!(pub Executor, polkadot_runtime::api::dispatch, include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm"));
|
||||||
use substrate_executor::error::{Error, ErrorKind};
|
|
||||||
use substrate_executor::{NativeExecutionDispatch, NativeExecutor};
|
|
||||||
use state_machine::Externalities;
|
|
||||||
|
|
||||||
/// A null struct which implements `NativeExecutionDispatch` feeding in the hard-coded runtime.
|
|
||||||
pub struct LocalNativeExecutionDispatch;
|
|
||||||
|
|
||||||
impl NativeExecutionDispatch for LocalNativeExecutionDispatch {
|
|
||||||
fn native_equivalent() -> &'static [u8] {
|
|
||||||
// WARNING!!! This assumes that the runtime was built *before* the main project. Until we
|
|
||||||
// get a proper build script, this must be strictly adhered to or things will go wrong.
|
|
||||||
include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dispatch(ext: &mut Externalities, method: &str, data: &[u8]) -> Result<Vec<u8>, Error> {
|
|
||||||
::substrate_executor::with_native_environment(ext, move || runtime::api::dispatch(method, data))?
|
|
||||||
.ok_or_else(|| ErrorKind::MethodNotFound(method.to_owned()).into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates new RustExecutor for contracts.
|
|
||||||
pub fn executor() -> NativeExecutor<LocalNativeExecutionDispatch> {
|
|
||||||
NativeExecutor { _dummy: ::std::marker::PhantomData }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use runtime_io;
|
use runtime_io;
|
||||||
use super::*;
|
use super::Executor;
|
||||||
use substrate_executor::WasmExecutor;
|
use substrate_executor::WasmExecutor;
|
||||||
use codec::{KeyedVec, Slicable, Joiner};
|
use codec::{KeyedVec, Slicable, Joiner};
|
||||||
use runtime_support::{one, two, Hashable};
|
use keyring::Keyring;
|
||||||
|
use runtime_support::Hashable;
|
||||||
use polkadot_runtime::runtime::staking::balance;
|
use polkadot_runtime::runtime::staking::balance;
|
||||||
use state_machine::{CodeExecutor, TestExternalities};
|
use state_machine::{CodeExecutor, TestExternalities};
|
||||||
use primitives::twox_128;
|
use primitives::twox_128;
|
||||||
use polkadot_primitives::{Hash, Header, BlockNumber, Block, Digest, Transaction,
|
use polkadot_primitives::{Hash, Header, BlockNumber, Block, Digest, Transaction,
|
||||||
UncheckedTransaction, Function, AccountId};
|
UncheckedTransaction, Function};
|
||||||
use ed25519::Pair;
|
use ed25519::{Public, Pair};
|
||||||
|
|
||||||
const BLOATY_CODE: &[u8] = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm");
|
const BLOATY_CODE: &[u8] = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm");
|
||||||
const COMPACT_CODE: &[u8] = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm");
|
const COMPACT_CODE: &[u8] = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm");
|
||||||
@@ -82,11 +60,11 @@ mod tests {
|
|||||||
|
|
||||||
fn tx() -> UncheckedTransaction {
|
fn tx() -> UncheckedTransaction {
|
||||||
let transaction = Transaction {
|
let transaction = Transaction {
|
||||||
signed: one(),
|
signed: Keyring::One.to_raw_public(),
|
||||||
nonce: 0,
|
nonce: 0,
|
||||||
function: Function::StakingTransfer(two(), 69),
|
function: Function::StakingTransfer(Keyring::Two.to_raw_public(), 69),
|
||||||
};
|
};
|
||||||
let signature = secret_for(&transaction.signed).unwrap()
|
let signature = Keyring::from_raw_public(transaction.signed).unwrap()
|
||||||
.sign(&transaction.encode());
|
.sign(&transaction.encode());
|
||||||
|
|
||||||
UncheckedTransaction { transaction, signature }
|
UncheckedTransaction { transaction, signature }
|
||||||
@@ -94,36 +72,36 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn panic_execution_with_foreign_code_gives_error() {
|
fn panic_execution_with_foreign_code_gives_error() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let mut t = TestExternalities { storage: map![
|
let mut t = TestExternalities { storage: map![
|
||||||
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0]
|
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0]
|
||||||
], };
|
], };
|
||||||
|
|
||||||
let r = executor().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
|
let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
|
||||||
assert!(r.is_err());
|
assert!(r.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn panic_execution_with_native_equivalent_code_gives_error() {
|
fn panic_execution_with_native_equivalent_code_gives_error() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let mut t = TestExternalities { storage: map![
|
let mut t = TestExternalities { storage: map![
|
||||||
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0]
|
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0]
|
||||||
], };
|
], };
|
||||||
|
|
||||||
let r = executor().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
|
let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
|
||||||
assert!(r.is_err());
|
assert!(r.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn successful_execution_with_native_equivalent_code_gives_ok() {
|
fn successful_execution_with_native_equivalent_code_gives_ok() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
|
|
||||||
let mut t = TestExternalities { storage: map![
|
let mut t = TestExternalities { storage: map![
|
||||||
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
|
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
|
||||||
], };
|
], };
|
||||||
|
|
||||||
let r = executor().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
|
let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
|
|
||||||
runtime_io::with_externalities(&mut t, || {
|
runtime_io::with_externalities(&mut t, || {
|
||||||
@@ -134,14 +112,14 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn successful_execution_with_foreign_code_gives_ok() {
|
fn successful_execution_with_foreign_code_gives_ok() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
|
|
||||||
let mut t = TestExternalities { storage: map![
|
let mut t = TestExternalities { storage: map![
|
||||||
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
|
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
|
||||||
], };
|
], };
|
||||||
|
|
||||||
let r = executor().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
|
let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
|
|
||||||
runtime_io::with_externalities(&mut t, || {
|
runtime_io::with_externalities(&mut t, || {
|
||||||
@@ -151,8 +129,8 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new_test_ext() -> TestExternalities {
|
fn new_test_ext() -> TestExternalities {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
let three = [3u8; 32];
|
let three = [3u8; 32];
|
||||||
|
|
||||||
TestExternalities { storage: map![
|
TestExternalities { storage: map![
|
||||||
@@ -174,19 +152,11 @@ mod tests {
|
|||||||
], }
|
], }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn secret_for(who: &AccountId) -> Option<Pair> {
|
|
||||||
match who {
|
|
||||||
x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")),
|
|
||||||
x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn construct_block(number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec<Transaction>) -> (Vec<u8>, Hash) {
|
fn construct_block(number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec<Transaction>) -> (Vec<u8>, Hash) {
|
||||||
use triehash::ordered_trie_root;
|
use triehash::ordered_trie_root;
|
||||||
|
|
||||||
let transactions = txs.into_iter().map(|transaction| {
|
let transactions = txs.into_iter().map(|transaction| {
|
||||||
let signature = secret_for(&transaction.signed).unwrap()
|
let signature = Pair::from(Keyring::from_public(Public::from_raw(transaction.signed)).unwrap())
|
||||||
.sign(&transaction.encode());
|
.sign(&transaction.encode());
|
||||||
|
|
||||||
UncheckedTransaction { transaction, signature }
|
UncheckedTransaction { transaction, signature }
|
||||||
@@ -212,9 +182,9 @@ mod tests {
|
|||||||
[69u8; 32].into(),
|
[69u8; 32].into(),
|
||||||
hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db").into(),
|
hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db").into(),
|
||||||
vec![Transaction {
|
vec![Transaction {
|
||||||
signed: one(),
|
signed: Keyring::One.to_raw_public(),
|
||||||
nonce: 0,
|
nonce: 0,
|
||||||
function: Function::StakingTransfer(two(), 69),
|
function: Function::StakingTransfer(Keyring::Two.to_raw_public(), 69),
|
||||||
}]
|
}]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -226,14 +196,14 @@ mod tests {
|
|||||||
hex!("1feb4d3a2e587079e6ce1685fa79994efd995e33cb289d39cded67aac1bb46a9").into(),
|
hex!("1feb4d3a2e587079e6ce1685fa79994efd995e33cb289d39cded67aac1bb46a9").into(),
|
||||||
vec![
|
vec![
|
||||||
Transaction {
|
Transaction {
|
||||||
signed: two(),
|
signed: Keyring::Two.to_raw_public(),
|
||||||
nonce: 0,
|
nonce: 0,
|
||||||
function: Function::StakingTransfer(one(), 5),
|
function: Function::StakingTransfer(Keyring::One.to_raw_public(), 5),
|
||||||
},
|
},
|
||||||
Transaction {
|
Transaction {
|
||||||
signed: one(),
|
signed: Keyring::One.to_raw_public(),
|
||||||
nonce: 1,
|
nonce: 1,
|
||||||
function: Function::StakingTransfer(two(), 15),
|
function: Function::StakingTransfer(Keyring::Two.to_raw_public(), 15),
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -243,18 +213,18 @@ mod tests {
|
|||||||
fn full_native_block_import_works() {
|
fn full_native_block_import_works() {
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
executor().call(&mut t, COMPACT_CODE, "execute_block", &block1().0).unwrap();
|
Executor::new().call(&mut t, COMPACT_CODE, "execute_block", &block1().0).unwrap();
|
||||||
|
|
||||||
runtime_io::with_externalities(&mut t, || {
|
runtime_io::with_externalities(&mut t, || {
|
||||||
assert_eq!(balance(&one()), 42);
|
assert_eq!(balance(&Keyring::One.to_raw_public()), 42);
|
||||||
assert_eq!(balance(&two()), 69);
|
assert_eq!(balance(&Keyring::Two.to_raw_public()), 69);
|
||||||
});
|
});
|
||||||
|
|
||||||
executor().call(&mut t, COMPACT_CODE, "execute_block", &block2().0).unwrap();
|
Executor::new().call(&mut t, COMPACT_CODE, "execute_block", &block2().0).unwrap();
|
||||||
|
|
||||||
runtime_io::with_externalities(&mut t, || {
|
runtime_io::with_externalities(&mut t, || {
|
||||||
assert_eq!(balance(&one()), 32);
|
assert_eq!(balance(&Keyring::One.to_raw_public()), 32);
|
||||||
assert_eq!(balance(&two()), 79);
|
assert_eq!(balance(&Keyring::Two.to_raw_public()), 79);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,21 +235,21 @@ mod tests {
|
|||||||
WasmExecutor.call(&mut t, COMPACT_CODE, "execute_block", &block1().0).unwrap();
|
WasmExecutor.call(&mut t, COMPACT_CODE, "execute_block", &block1().0).unwrap();
|
||||||
|
|
||||||
runtime_io::with_externalities(&mut t, || {
|
runtime_io::with_externalities(&mut t, || {
|
||||||
assert_eq!(balance(&one()), 42);
|
assert_eq!(balance(&Keyring::One.to_raw_public()), 42);
|
||||||
assert_eq!(balance(&two()), 69);
|
assert_eq!(balance(&Keyring::Two.to_raw_public()), 69);
|
||||||
});
|
});
|
||||||
|
|
||||||
WasmExecutor.call(&mut t, COMPACT_CODE, "execute_block", &block2().0).unwrap();
|
WasmExecutor.call(&mut t, COMPACT_CODE, "execute_block", &block2().0).unwrap();
|
||||||
|
|
||||||
runtime_io::with_externalities(&mut t, || {
|
runtime_io::with_externalities(&mut t, || {
|
||||||
assert_eq!(balance(&one()), 32);
|
assert_eq!(balance(&Keyring::One.to_raw_public()), 32);
|
||||||
assert_eq!(balance(&two()), 79);
|
assert_eq!(balance(&Keyring::Two.to_raw_public()), 79);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn panic_execution_gives_error() {
|
fn panic_execution_gives_error() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let mut t = TestExternalities { storage: map![
|
let mut t = TestExternalities { storage: map![
|
||||||
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0]
|
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0]
|
||||||
], };
|
], };
|
||||||
@@ -291,8 +261,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn successful_execution_gives_ok() {
|
fn successful_execution_gives_ok() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
|
|
||||||
let mut t = TestExternalities { storage: map![
|
let mut t = TestExternalities { storage: map![
|
||||||
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
|
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ substrate-runtime-support = { path = "../../substrate/runtime-support" }
|
|||||||
substrate-primitives = { path = "../../substrate/primitives" }
|
substrate-primitives = { path = "../../substrate/primitives" }
|
||||||
polkadot-primitives = { path = "../primitives" }
|
polkadot-primitives = { path = "../primitives" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
substrate-keyring = { path = "../../substrate/keyring" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
std = [
|
std = [
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
extern crate substrate_runtime_std as rstd;
|
extern crate substrate_runtime_std as rstd;
|
||||||
#[macro_use] extern crate substrate_runtime_io as runtime_io;
|
#[macro_use] extern crate substrate_runtime_io as runtime_io;
|
||||||
extern crate substrate_runtime_support as runtime_support;
|
extern crate substrate_runtime_support as runtime_support;
|
||||||
|
#[cfg(all(feature = "std", test))] extern crate substrate_keyring as keyring;
|
||||||
|
|
||||||
#[cfg(feature = "std")] extern crate rustc_hex;
|
#[cfg(feature = "std")] extern crate rustc_hex;
|
||||||
|
|
||||||
|
|||||||
@@ -147,14 +147,14 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use runtime_io::{with_externalities, twox_128, TestExternalities};
|
use runtime_io::{with_externalities, twox_128, TestExternalities};
|
||||||
use codec::{KeyedVec, Joiner};
|
use codec::{KeyedVec, Joiner};
|
||||||
use runtime_support::{one, two};
|
use keyring::Keyring;
|
||||||
use environment::with_env;
|
use environment::with_env;
|
||||||
use polkadot_primitives::{AccountId, Proposal};
|
use polkadot_primitives::{AccountId, Proposal};
|
||||||
use runtime::{staking, session};
|
use runtime::{staking, session};
|
||||||
|
|
||||||
fn new_test_ext() -> TestExternalities {
|
fn new_test_ext() -> TestExternalities {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
let three = [3u8; 32];
|
let three = [3u8; 32];
|
||||||
|
|
||||||
TestExternalities { storage: map![
|
TestExternalities { storage: map![
|
||||||
@@ -176,8 +176,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn majority_voting_should_work() {
|
fn majority_voting_should_work() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
let three = [3u8; 32];
|
let three = [3u8; 32];
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
@@ -199,8 +199,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn majority_voting_should_work_after_unsuccessful_previous() {
|
fn majority_voting_should_work_after_unsuccessful_previous() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
let three = [3u8; 32];
|
let three = [3u8; 32];
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
@@ -228,8 +228,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn minority_voting_should_not_succeed() {
|
fn minority_voting_should_not_succeed() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
let three = [3u8; 32];
|
let three = [3u8; 32];
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
@@ -251,8 +251,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn old_voting_should_be_illegal() {
|
fn old_voting_should_be_illegal() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
let three = [3u8; 32];
|
let three = [3u8; 32];
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
@@ -275,8 +275,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn double_voting_should_be_illegal() {
|
fn double_voting_should_be_illegal() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
let three = [3u8; 32];
|
let three = [3u8; 32];
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
@@ -300,8 +300,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn over_proposing_should_be_illegal() {
|
fn over_proposing_should_be_illegal() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
let three = [3u8; 32];
|
let three = [3u8; 32];
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
@@ -324,8 +324,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn approving_without_proposal_should_be_illegal() {
|
fn approving_without_proposal_should_be_illegal() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
let three = [3u8; 32];
|
let three = [3u8; 32];
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
@@ -347,8 +347,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn non_validator_approving_should_be_illegal() {
|
fn non_validator_approving_should_be_illegal() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
let three = [3u8; 32];
|
let three = [3u8; 32];
|
||||||
let four = [4u8; 32];
|
let four = [4u8; 32];
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use runtime_io::{with_externalities, twox_128, TestExternalities};
|
use runtime_io::{with_externalities, twox_128, TestExternalities};
|
||||||
use codec::{KeyedVec, Joiner};
|
use codec::{KeyedVec, Joiner};
|
||||||
use runtime_support::{one, two};
|
use keyring::Keyring;
|
||||||
use runtime::{consensus, session};
|
use runtime::{consensus, session};
|
||||||
|
|
||||||
fn simple_setup() -> TestExternalities {
|
fn simple_setup() -> TestExternalities {
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ mod tests {
|
|||||||
use super::internal::*;
|
use super::internal::*;
|
||||||
use runtime_io::{with_externalities, twox_128, TestExternalities};
|
use runtime_io::{with_externalities, twox_128, TestExternalities};
|
||||||
use codec::{KeyedVec, Joiner};
|
use codec::{KeyedVec, Joiner};
|
||||||
use runtime_support::{one, two};
|
use keyring::Keyring;
|
||||||
use environment::with_env;
|
use environment::with_env;
|
||||||
use polkadot_primitives::AccountId;
|
use polkadot_primitives::AccountId;
|
||||||
use runtime::{consensus, session};
|
use runtime::{consensus, session};
|
||||||
|
|||||||
@@ -215,15 +215,15 @@ mod tests {
|
|||||||
|
|
||||||
use runtime_io::{with_externalities, twox_128, TestExternalities};
|
use runtime_io::{with_externalities, twox_128, TestExternalities};
|
||||||
use codec::{KeyedVec, Joiner};
|
use codec::{KeyedVec, Joiner};
|
||||||
use runtime_support::{one, two};
|
use keyring::Keyring;
|
||||||
use environment::with_env;
|
use environment::with_env;
|
||||||
use polkadot_primitives::AccountId;
|
use polkadot_primitives::AccountId;
|
||||||
use runtime::{staking, session};
|
use runtime::{staking, session};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn staking_should_work() {
|
fn staking_should_work() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
let three = [3u8; 32];
|
let three = [3u8; 32];
|
||||||
let four = [4u8; 32];
|
let four = [4u8; 32];
|
||||||
|
|
||||||
@@ -360,8 +360,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn staking_balance_works() {
|
fn staking_balance_works() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
|
|
||||||
let mut t = TestExternalities { storage: map![
|
let mut t = TestExternalities { storage: map![
|
||||||
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&42u64)
|
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&42u64)
|
||||||
@@ -375,8 +375,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn staking_balance_transfer_works() {
|
fn staking_balance_transfer_works() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
|
|
||||||
let mut t = TestExternalities { storage: map![
|
let mut t = TestExternalities { storage: map![
|
||||||
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64)
|
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64)
|
||||||
@@ -392,8 +392,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn staking_balance_transfer_when_bonded_doesnt_work() {
|
fn staking_balance_transfer_when_bonded_doesnt_work() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
|
|
||||||
let mut t = TestExternalities { storage: map![
|
let mut t = TestExternalities { storage: map![
|
||||||
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64)
|
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64)
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ mod tests {
|
|||||||
|
|
||||||
use runtime_io::{with_externalities, twox_128, TestExternalities};
|
use runtime_io::{with_externalities, twox_128, TestExternalities};
|
||||||
use codec::{Joiner, KeyedVec, Slicable};
|
use codec::{Joiner, KeyedVec, Slicable};
|
||||||
use runtime_support::{one, two};
|
use keyring::Keyring;
|
||||||
use environment::with_env;
|
use environment::with_env;
|
||||||
use primitives::hexdisplay::HexDisplay;
|
use primitives::hexdisplay::HexDisplay;
|
||||||
use polkadot_primitives::{Header, Digest, UncheckedTransaction, Transaction, Function};
|
use polkadot_primitives::{Header, Digest, UncheckedTransaction, Transaction, Function};
|
||||||
@@ -244,8 +244,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn staking_balance_transfer_dispatch_works() {
|
fn staking_balance_transfer_dispatch_works() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
|
|
||||||
let mut t = TestExternalities { storage: map![
|
let mut t = TestExternalities { storage: map![
|
||||||
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
|
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
|
||||||
@@ -268,8 +268,8 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new_test_ext() -> TestExternalities {
|
fn new_test_ext() -> TestExternalities {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
let three = [3u8; 32];
|
let three = [3u8; 32];
|
||||||
|
|
||||||
TestExternalities { storage: map![
|
TestExternalities { storage: map![
|
||||||
@@ -293,8 +293,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn block_import_works() {
|
fn block_import_works() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
|
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
@@ -319,8 +319,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn block_import_of_bad_state_root_fails() {
|
fn block_import_of_bad_state_root_fails() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
|
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
@@ -345,8 +345,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn block_import_of_bad_transaction_root_fails() {
|
fn block_import_of_bad_transaction_root_fails() {
|
||||||
let one = one();
|
let one = Keyring::One.to_raw_public();
|
||||||
let two = two();
|
let two = Keyring::Two.to_raw_public();
|
||||||
|
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -92,8 +92,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
name = "ed25519"
|
name = "ed25519"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"substrate-primitives 0.1.0",
|
"substrate-primitives 0.1.0",
|
||||||
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -643,6 +643,7 @@ dependencies = [
|
|||||||
name = "substrate-runtime-support"
|
name = "substrate-runtime-support"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ed25519 0.1.0",
|
||||||
"environmental 0.1.0",
|
"environmental 0.1.0",
|
||||||
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"substrate-codec 0.1.0",
|
"substrate-codec 0.1.0",
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -17,3 +17,4 @@ substrate-runtime-support = { path = "../runtime-support" }
|
|||||||
substrate-serializer = { path = "../serializer" }
|
substrate-serializer = { path = "../serializer" }
|
||||||
substrate-state-machine = { path = "../state-machine" }
|
substrate-state-machine = { path = "../state-machine" }
|
||||||
substrate-test-runtime = { path = "../test-runtime" }
|
substrate-test-runtime = { path = "../test-runtime" }
|
||||||
|
substrate-keyring = { path = "../../substrate/keyring" }
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use error;
|
|||||||
use primitives::block;
|
use primitives::block;
|
||||||
use blockchain::{self, BlockId};
|
use blockchain::{self, BlockId};
|
||||||
|
|
||||||
/// Block insertion transction. Keeps hold if the inseted block state and data.
|
/// Block insertion transction. Keeps hold if the inserted block state and data.
|
||||||
pub trait BlockImportOperation {
|
pub trait BlockImportOperation {
|
||||||
/// Associated state backend type.
|
/// Associated state backend type.
|
||||||
type State: state_machine::backend::Backend;
|
type State: state_machine::backend::Backend;
|
||||||
|
|||||||
@@ -45,6 +45,18 @@ error_chain! {
|
|||||||
description("Blockchain error"),
|
description("Blockchain error"),
|
||||||
display("Blockchain: {}", e),
|
display("Blockchain: {}", e),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Invalid state data.
|
||||||
|
AuthLen {
|
||||||
|
description("authority count state error"),
|
||||||
|
display("Current state of blockchain has invalid authority count value"),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invalid state data.
|
||||||
|
Auth(i: u32) {
|
||||||
|
description("authority value state error"),
|
||||||
|
display("Current state of blockchain has invalid authority value for index {}", i),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,49 +40,23 @@ pub fn construct_genesis_block(storage: &HashMap<Vec<u8>, Vec<u8>>) -> Block {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use codec::{Slicable, Joiner};
|
use codec::{Slicable, Joiner};
|
||||||
use runtime_support::{one, two, Hashable};
|
use runtime_support::Hashable;
|
||||||
|
use keyring::Keyring;
|
||||||
use test_runtime::genesismap::{GenesisConfig, additional_storage_with_genesis};
|
use test_runtime::genesismap::{GenesisConfig, additional_storage_with_genesis};
|
||||||
use executor::{NativeExecutionDispatch, NativeExecutor, WasmExecutor, with_native_environment,
|
use executor::WasmExecutor;
|
||||||
error};
|
use state_machine::{execute, OverlayedChanges};
|
||||||
use state_machine::{execute, Externalities, OverlayedChanges};
|
|
||||||
use state_machine::backend::InMemory;
|
use state_machine::backend::InMemory;
|
||||||
use test_runtime::{self, AccountId, Hash, Block, BlockNumber, Header, Digest, Transaction,
|
use test_runtime::{self, Hash, Block, BlockNumber, Header, Digest, Transaction,
|
||||||
UncheckedTransaction};
|
UncheckedTransaction};
|
||||||
use ed25519::Pair;
|
use ed25519::{Public, Pair};
|
||||||
|
|
||||||
/// A null struct which implements `NativeExecutionDispatch` feeding in the hard-coded runtime.
|
native_executor_instance!(Executor, test_runtime::api::dispatch, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm"));
|
||||||
pub struct LocalNativeExecutionDispatch;
|
|
||||||
|
|
||||||
impl NativeExecutionDispatch for LocalNativeExecutionDispatch {
|
|
||||||
fn native_equivalent() -> &'static [u8] {
|
|
||||||
// WARNING!!! This assumes that the runtime was built *before* the main project. Until we
|
|
||||||
// get a proper build script, this must be strictly adhered to or things will go wrong.
|
|
||||||
include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dispatch(ext: &mut Externalities, method: &str, data: &[u8]) -> error::Result<Vec<u8>> {
|
|
||||||
with_native_environment(ext, move || test_runtime::apis::dispatch(method, data))?
|
|
||||||
.ok_or_else(|| error::ErrorKind::MethodNotFound(method.to_owned()).into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn executor() -> NativeExecutor<LocalNativeExecutionDispatch> {
|
|
||||||
NativeExecutor { _dummy: Default::default() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn secret_for(who: &AccountId) -> Option<Pair> {
|
|
||||||
match who {
|
|
||||||
x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")),
|
|
||||||
x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn construct_block(backend: &InMemory, number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec<Transaction>) -> (Vec<u8>, Hash) {
|
fn construct_block(backend: &InMemory, number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec<Transaction>) -> (Vec<u8>, Hash) {
|
||||||
use triehash::ordered_trie_root;
|
use triehash::ordered_trie_root;
|
||||||
|
|
||||||
let transactions = txs.into_iter().map(|tx| {
|
let transactions = txs.into_iter().map(|tx| {
|
||||||
let signature = secret_for(&tx.from).unwrap()
|
let signature = Pair::from(Keyring::from_public(Public::from_raw(tx.from)).unwrap())
|
||||||
.sign(&tx.encode());
|
.sign(&tx.encode());
|
||||||
|
|
||||||
UncheckedTransaction { tx, signature }
|
UncheckedTransaction { tx, signature }
|
||||||
@@ -105,7 +79,7 @@ mod tests {
|
|||||||
let ret_data = execute(
|
let ret_data = execute(
|
||||||
backend,
|
backend,
|
||||||
&mut overlay,
|
&mut overlay,
|
||||||
&executor(),
|
&Executor::new(),
|
||||||
"execute_transaction",
|
"execute_transaction",
|
||||||
&vec![].and(&header).and(tx)
|
&vec![].and(&header).and(tx)
|
||||||
).unwrap();
|
).unwrap();
|
||||||
@@ -115,7 +89,7 @@ mod tests {
|
|||||||
let ret_data = execute(
|
let ret_data = execute(
|
||||||
backend,
|
backend,
|
||||||
&mut overlay,
|
&mut overlay,
|
||||||
&executor(),
|
&Executor::new(),
|
||||||
"finalise_block",
|
"finalise_block",
|
||||||
&vec![].and(&header)
|
&vec![].and(&header)
|
||||||
).unwrap();
|
).unwrap();
|
||||||
@@ -131,8 +105,8 @@ mod tests {
|
|||||||
genesis_hash,
|
genesis_hash,
|
||||||
hex!("25e5b37074063ab75c889326246640729b40d0c86932edc527bc80db0e04fe5c").into(),
|
hex!("25e5b37074063ab75c889326246640729b40d0c86932edc527bc80db0e04fe5c").into(),
|
||||||
vec![Transaction {
|
vec![Transaction {
|
||||||
from: one(),
|
from: Keyring::One.to_raw_public(),
|
||||||
to: two(),
|
to: Keyring::Two.to_raw_public(),
|
||||||
amount: 69,
|
amount: 69,
|
||||||
nonce: 0,
|
nonce: 0,
|
||||||
}]
|
}]
|
||||||
@@ -142,20 +116,29 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn construct_genesis_should_work() {
|
fn construct_genesis_should_work() {
|
||||||
let mut storage = GenesisConfig::new_simple(
|
let mut storage = GenesisConfig::new_simple(
|
||||||
vec![one(), two()], 1000
|
vec![Keyring::One.to_raw_public(), Keyring::Two.to_raw_public()], 1000
|
||||||
).genesis_map();
|
).genesis_map();
|
||||||
let block = construct_genesis_block(&storage);
|
let block = construct_genesis_block(&storage);
|
||||||
let genesis_hash = block.header.blake2_256().into();
|
let genesis_hash = block.header.blake2_256().into();
|
||||||
storage.extend(additional_storage_with_genesis(&block).into_iter());
|
storage.extend(additional_storage_with_genesis(&block).into_iter());
|
||||||
|
|
||||||
let mut overlay = OverlayedChanges::default();
|
|
||||||
let backend = InMemory::from(storage);
|
let backend = InMemory::from(storage);
|
||||||
let (b1data, _b1hash) = block1(genesis_hash, &backend);
|
let (b1data, _b1hash) = block1(genesis_hash, &backend);
|
||||||
|
|
||||||
|
let mut overlay = OverlayedChanges::default();
|
||||||
let _ = execute(
|
let _ = execute(
|
||||||
&backend,
|
&backend,
|
||||||
&mut overlay,
|
&mut overlay,
|
||||||
&executor(),
|
&Executor::new(),
|
||||||
|
"execute_block",
|
||||||
|
&b1data
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let mut overlay = OverlayedChanges::default();
|
||||||
|
let _ = execute(
|
||||||
|
&backend,
|
||||||
|
&mut overlay,
|
||||||
|
&WasmExecutor,
|
||||||
"execute_block",
|
"execute_block",
|
||||||
&b1data
|
&b1data
|
||||||
).unwrap();
|
).unwrap();
|
||||||
@@ -165,42 +148,20 @@ mod tests {
|
|||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn construct_genesis_with_bad_transaction_should_panic() {
|
fn construct_genesis_with_bad_transaction_should_panic() {
|
||||||
let mut storage = GenesisConfig::new_simple(
|
let mut storage = GenesisConfig::new_simple(
|
||||||
vec![one(), two()], 68
|
vec![Keyring::One.to_raw_public(), Keyring::Two.to_raw_public()], 68
|
||||||
).genesis_map();
|
).genesis_map();
|
||||||
let block = construct_genesis_block(&storage);
|
let block = construct_genesis_block(&storage);
|
||||||
let genesis_hash = block.header.blake2_256().into();
|
let genesis_hash = block.header.blake2_256().into();
|
||||||
storage.extend(additional_storage_with_genesis(&block).into_iter());
|
storage.extend(additional_storage_with_genesis(&block).into_iter());
|
||||||
|
|
||||||
let mut overlay = OverlayedChanges::default();
|
|
||||||
let backend = InMemory::from(storage);
|
let backend = InMemory::from(storage);
|
||||||
let (b1data, _b1hash) = block1(genesis_hash, &backend);
|
let (b1data, _b1hash) = block1(genesis_hash, &backend);
|
||||||
|
|
||||||
let _ = execute(
|
|
||||||
&backend,
|
|
||||||
&mut overlay,
|
|
||||||
&executor(),
|
|
||||||
"execute_block",
|
|
||||||
&b1data
|
|
||||||
).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn construct_genesis_should_work_under_wasm() {
|
|
||||||
let mut storage = GenesisConfig::new_simple(
|
|
||||||
vec![one(), two()], 1000
|
|
||||||
).genesis_map();
|
|
||||||
let block = construct_genesis_block(&storage);
|
|
||||||
let genesis_hash = block.header.blake2_256().into();
|
|
||||||
storage.extend(additional_storage_with_genesis(&block).into_iter());
|
|
||||||
|
|
||||||
let mut overlay = OverlayedChanges::default();
|
let mut overlay = OverlayedChanges::default();
|
||||||
let backend = InMemory::from(storage);
|
|
||||||
let (b1data, _b1hash) = block1(genesis_hash, &backend);
|
|
||||||
|
|
||||||
let _ = execute(
|
let _ = execute(
|
||||||
&backend,
|
&backend,
|
||||||
&mut overlay,
|
&mut overlay,
|
||||||
&WasmExecutor,
|
&Executor::new(),
|
||||||
"execute_block",
|
"execute_block",
|
||||||
&b1data
|
&b1data
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|||||||
@@ -22,10 +22,11 @@ extern crate substrate_primitives as primitives;
|
|||||||
extern crate substrate_state_machine as state_machine;
|
extern crate substrate_state_machine as state_machine;
|
||||||
extern crate substrate_serializer as ser;
|
extern crate substrate_serializer as ser;
|
||||||
extern crate substrate_codec as codec;
|
extern crate substrate_codec as codec;
|
||||||
extern crate substrate_executor as executor;
|
#[cfg(test)] #[macro_use] extern crate substrate_executor as executor;
|
||||||
extern crate ed25519;
|
extern crate ed25519;
|
||||||
#[cfg(test)] extern crate substrate_runtime_support as runtime_support;
|
#[cfg(test)] extern crate substrate_runtime_support as runtime_support;
|
||||||
#[cfg(test)] extern crate substrate_test_runtime as test_runtime;
|
#[cfg(test)] extern crate substrate_test_runtime as test_runtime;
|
||||||
|
#[cfg(test)] extern crate substrate_keyring as keyring;
|
||||||
|
|
||||||
extern crate triehash;
|
extern crate triehash;
|
||||||
extern crate parking_lot;
|
extern crate parking_lot;
|
||||||
@@ -42,8 +43,9 @@ pub mod genesis;
|
|||||||
pub use blockchain::Info as ChainInfo;
|
pub use blockchain::Info as ChainInfo;
|
||||||
pub use blockchain::BlockId;
|
pub use blockchain::BlockId;
|
||||||
|
|
||||||
use primitives::block;
|
use primitives::{block, AuthorityId};
|
||||||
use primitives::storage::{StorageKey, StorageData};
|
use primitives::storage::{StorageKey, StorageData};
|
||||||
|
use codec::{KeyedVec, Slicable};
|
||||||
|
|
||||||
use blockchain::Backend as BlockchainBackend;
|
use blockchain::Backend as BlockchainBackend;
|
||||||
use backend::BlockImportOperation;
|
use backend::BlockImportOperation;
|
||||||
@@ -162,7 +164,18 @@ impl<B, E> Client<B, E> where
|
|||||||
|
|
||||||
/// Get the code at a given block.
|
/// Get the code at a given block.
|
||||||
pub fn code_at(&self, id: &BlockId) -> error::Result<Vec<u8>> {
|
pub fn code_at(&self, id: &BlockId) -> error::Result<Vec<u8>> {
|
||||||
self.storage(id, &StorageKey(b":code:".to_vec())).map(|data| data.0)
|
self.storage(id, &StorageKey(b":code".to_vec())).map(|data| data.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the current set of authorities from storage.
|
||||||
|
pub fn authorities_at(&self, id: &BlockId) -> error::Result<Vec<AuthorityId>> {
|
||||||
|
let state = self.state_at(id)?;
|
||||||
|
(0..u32::decode(&mut state.storage(b":auth:len")?).ok_or(error::ErrorKind::AuthLen)?)
|
||||||
|
.map(|i| state.storage(&i.to_keyed_vec(b":auth:"))
|
||||||
|
.map_err(|_| error::ErrorKind::Backend)
|
||||||
|
.and_then(|mut s| AuthorityId::decode(&mut s).ok_or(error::ErrorKind::Auth(i)))
|
||||||
|
.map_err(Into::into)
|
||||||
|
).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute a call to a contract on top of state in a block of given hash.
|
/// Execute a call to a contract on top of state in a block of given hash.
|
||||||
@@ -235,3 +248,37 @@ impl<B, E> Client<B, E> where
|
|||||||
self.backend.blockchain().body(*id)
|
self.backend.blockchain().body(*id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use codec::Slicable;
|
||||||
|
use keyring::Keyring;
|
||||||
|
use test_runtime::genesismap::{GenesisConfig, additional_storage_with_genesis};
|
||||||
|
use test_runtime;
|
||||||
|
|
||||||
|
native_executor_instance!(Executor, test_runtime::api::dispatch, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm"));
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn authorities_call_works() {
|
||||||
|
let genesis_config = GenesisConfig::new_simple(vec![
|
||||||
|
Keyring::Alice.to_raw_public(),
|
||||||
|
Keyring::Bob.to_raw_public(),
|
||||||
|
Keyring::Charlie.to_raw_public()
|
||||||
|
], 1000);
|
||||||
|
|
||||||
|
let prepare_genesis = || {
|
||||||
|
let mut storage = genesis_config.genesis_map();
|
||||||
|
let block = genesis::construct_genesis_block(&storage);
|
||||||
|
storage.extend(additional_storage_with_genesis(&block));
|
||||||
|
(primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect())
|
||||||
|
};
|
||||||
|
let client = new_in_mem(Executor::new(), prepare_genesis).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(client.authorities_at(&BlockId::Number(0)).unwrap(), vec![
|
||||||
|
Keyring::Alice.to_raw_public(),
|
||||||
|
Keyring::Bob.to_raw_public(),
|
||||||
|
Keyring::Charlie.to_raw_public()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,4 +7,4 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
ring = "0.12"
|
ring = "0.12"
|
||||||
untrusted = "0.5"
|
untrusted = "0.5"
|
||||||
substrate-primitives = { version = "0.1", path = "../primitives" }
|
substrate-primitives = { version = "0.1", path = "../primitives" }
|
||||||
rustc-hex = "1.0"
|
hex-literal = "0.1"
|
||||||
|
|||||||
@@ -19,11 +19,10 @@
|
|||||||
extern crate ring;
|
extern crate ring;
|
||||||
extern crate substrate_primitives as primitives;
|
extern crate substrate_primitives as primitives;
|
||||||
extern crate untrusted;
|
extern crate untrusted;
|
||||||
extern crate rustc_hex;
|
#[macro_use] extern crate hex_literal;
|
||||||
|
|
||||||
use ring::{rand, signature};
|
use ring::{rand, signature};
|
||||||
use primitives::hash::H512;
|
use primitives::hash::H512;
|
||||||
use rustc_hex::FromHex;
|
|
||||||
|
|
||||||
/// Alias to 520-bit hash when used in the context of a signature on the relay chain.
|
/// Alias to 520-bit hash when used in the context of a signature on the relay chain.
|
||||||
pub type Signature = H512;
|
pub type Signature = H512;
|
||||||
@@ -49,7 +48,7 @@ pub struct Pair(signature::Ed25519KeyPair);
|
|||||||
|
|
||||||
impl Public {
|
impl Public {
|
||||||
/// A new instance from the given 32-byte `data`.
|
/// A new instance from the given 32-byte `data`.
|
||||||
pub fn from(data: [u8; 32]) -> Self {
|
pub fn from_raw(data: [u8; 32]) -> Self {
|
||||||
Public(data)
|
Public(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +58,23 @@ impl Public {
|
|||||||
r.copy_from_slice(data);
|
r.copy_from_slice(data);
|
||||||
Public(r)
|
Public(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a `Vec<u8>` filled with raw data.
|
||||||
|
pub fn to_raw_vec(self) -> Vec<u8> {
|
||||||
|
let r: &[u8; 32] = self.as_ref();
|
||||||
|
r.to_vec()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a slice filled with raw data.
|
||||||
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
|
let r: &[u8; 32] = self.as_ref();
|
||||||
|
&r[..]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a slice filled with raw data.
|
||||||
|
pub fn as_array_ref(&self) -> &[u8; 32] {
|
||||||
|
self.as_ref()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<[u8; 32]> for Public {
|
impl AsRef<[u8; 32]> for Public {
|
||||||
@@ -80,31 +96,29 @@ impl Pair {
|
|||||||
let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng).unwrap();
|
let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng).unwrap();
|
||||||
Pair(signature::Ed25519KeyPair::from_pkcs8(untrusted::Input::from(&pkcs8_bytes)).unwrap())
|
Pair(signature::Ed25519KeyPair::from_pkcs8(untrusted::Input::from(&pkcs8_bytes)).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a new key pair from a seed phrase.
|
/// Make a new key pair from a seed phrase.
|
||||||
pub fn from_seed(seed: &[u8; 32]) -> Pair {
|
pub fn from_seed(seed: &[u8; 32]) -> Pair {
|
||||||
Pair(signature::Ed25519KeyPair::from_seed_unchecked(untrusted::Input::from(&seed[..])).unwrap())
|
Pair(signature::Ed25519KeyPair::from_seed_unchecked(untrusted::Input::from(&seed[..])).unwrap())
|
||||||
}
|
}
|
||||||
/// Make a new key pair from the raw secret.
|
|
||||||
pub fn from_secret(secret: &[u8; 32]) -> Pair {
|
|
||||||
let mut pkcs8_bytes: Vec<_> = FromHex::from_hex("302e020100300506032b657004220420").unwrap();
|
|
||||||
pkcs8_bytes.extend_from_slice(&secret[..]);
|
|
||||||
Pair(signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(untrusted::Input::from(&pkcs8_bytes)).unwrap())
|
|
||||||
}
|
|
||||||
/// Make a new key pair from the raw secret and public key (it will check to make sure
|
/// Make a new key pair from the raw secret and public key (it will check to make sure
|
||||||
/// they correspond to each other).
|
/// they correspond to each other).
|
||||||
pub fn from_both(secret_public: &[u8; 64]) -> Option<Pair> {
|
pub fn from_both(secret_public: &[u8; 64]) -> Option<Pair> {
|
||||||
let mut pkcs8_bytes: Vec<_> = FromHex::from_hex("3053020101300506032b657004220420").unwrap();
|
let mut pkcs8_bytes: Vec<_> = hex!("3053020101300506032b657004220420").to_vec();
|
||||||
pkcs8_bytes.extend_from_slice(&secret_public[0..32]);
|
pkcs8_bytes.extend_from_slice(&secret_public[0..32]);
|
||||||
pkcs8_bytes.extend_from_slice(&[0xa1u8, 0x23, 0x03, 0x21, 0x00]);
|
pkcs8_bytes.extend_from_slice(&[0xa1u8, 0x23, 0x03, 0x21, 0x00]);
|
||||||
pkcs8_bytes.extend_from_slice(&secret_public[32..64]);
|
pkcs8_bytes.extend_from_slice(&secret_public[32..64]);
|
||||||
signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(untrusted::Input::from(&pkcs8_bytes)).ok().map(Pair)
|
signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(untrusted::Input::from(&pkcs8_bytes)).ok().map(Pair)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sign a message.
|
/// Sign a message.
|
||||||
pub fn sign(&self, message: &[u8]) -> Signature {
|
pub fn sign(&self, message: &[u8]) -> Signature {
|
||||||
let mut r = [0u8; 64];
|
let mut r = [0u8; 64];
|
||||||
r.copy_from_slice(self.0.sign(message).as_ref());
|
r.copy_from_slice(self.0.sign(message).as_ref());
|
||||||
Signature::from(r)
|
Signature::from(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the public key.
|
/// Get the public key.
|
||||||
pub fn public(&self) -> Public {
|
pub fn public(&self) -> Public {
|
||||||
let mut r = [0u8; 32];
|
let mut r = [0u8; 32];
|
||||||
@@ -126,32 +140,15 @@ pub fn verify_strong(sig: &Signature, message: &[u8], pubkey: &Public) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&'static str> for Public {
|
pub trait Verifiable {
|
||||||
fn from(hex: &'static str) -> Self {
|
/// Verify something that acts like a signature.
|
||||||
let mut r = [0u8; 32];
|
fn verify(&self, message: &[u8], pubkey: &Public) -> bool;
|
||||||
let v: Vec<_> = FromHex::from_hex(hex).unwrap();
|
|
||||||
r.copy_from_slice(&v[0..32]);
|
|
||||||
Public(r)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
impl From<&'static str> for Pair {
|
|
||||||
fn from(hex: &'static str) -> Self {
|
impl Verifiable for Signature {
|
||||||
let data: Vec<_> = FromHex::from_hex(hex).expect("Key pair given is static so hex should be good.");
|
/// Verify something that acts like a signature.
|
||||||
match data.len() {
|
fn verify(&self, message: &[u8], pubkey: &Public) -> bool {
|
||||||
32 => {
|
verify_strong(&self, message, pubkey)
|
||||||
let mut r = [0u8; 32];
|
|
||||||
r.copy_from_slice(&data[0..32]);
|
|
||||||
Pair::from_secret(&r)
|
|
||||||
}
|
|
||||||
64 => {
|
|
||||||
let mut r = [0u8; 64];
|
|
||||||
r.copy_from_slice(&data[0..64]);
|
|
||||||
Pair::from_both(&r).expect("Key pair given is static so should be good.")
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
panic!("Key pair given is static so should be correct length.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,11 +158,11 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_vector_should_work() {
|
fn test_vector_should_work() {
|
||||||
let pair: Pair = "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into();
|
let pair: Pair = Pair::from_seed(&hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"));
|
||||||
let public = pair.public();
|
let public = pair.public();
|
||||||
assert_eq!(public, "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".into());
|
assert_eq!(public, Public::from_raw(hex!("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a")));
|
||||||
let message = b"";
|
let message = b"";
|
||||||
let signature: Signature = "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b".into();
|
let signature: Signature = hex!("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b").into();
|
||||||
assert!(&pair.sign(&message[..]) == &signature);
|
assert!(&pair.sign(&message[..]) == &signature);
|
||||||
assert!(verify_strong(&signature, &message[..], &public));
|
assert!(verify_strong(&signature, &message[..], &public));
|
||||||
}
|
}
|
||||||
@@ -185,8 +182,8 @@ mod test {
|
|||||||
|
|
||||||
let pair = Pair::from_seed(b"12345678901234567890123456789012");
|
let pair = Pair::from_seed(b"12345678901234567890123456789012");
|
||||||
let public = pair.public();
|
let public = pair.public();
|
||||||
assert_eq!(public, "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".into());
|
assert_eq!(public, Public::from_raw(hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee")));
|
||||||
let message: Vec<_> = FromHex::from_hex("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000002228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000").unwrap();
|
let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000002228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000");
|
||||||
let signature = pair.sign(&message[..]);
|
let signature = pair.sign(&message[..]);
|
||||||
println!("Correct signature: {}", HexDisplay::from(&signature.0));
|
println!("Correct signature: {}", HexDisplay::from(&signature.0));
|
||||||
assert!(verify_strong(&signature, &message[..], &public));
|
assert!(verify_strong(&signature, &message[..], &public));
|
||||||
|
|||||||
@@ -57,8 +57,10 @@ macro_rules! map {
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod wasm_utils;
|
mod wasm_utils;
|
||||||
mod wasm_executor;
|
mod wasm_executor;
|
||||||
|
#[macro_use]
|
||||||
mod native_executor;
|
mod native_executor;
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub use wasm_executor::WasmExecutor;
|
pub use wasm_executor::WasmExecutor;
|
||||||
pub use native_executor::{with_native_environment, NativeExecutor, NativeExecutionDispatch};
|
pub use native_executor::{with_native_environment, NativeExecutor, NativeExecutionDispatch};
|
||||||
|
pub use state_machine::Externalities;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use error::{Error, ErrorKind, Result};
|
use error::{Error, ErrorKind, Result};
|
||||||
use state_machine::{Externalities, CodeExecutor};
|
use state_machine::{CodeExecutor, Externalities};
|
||||||
use wasm_executor::WasmExecutor;
|
use wasm_executor::WasmExecutor;
|
||||||
|
|
||||||
fn safe_call<F, U>(f: F) -> Result<U>
|
fn safe_call<F, U>(f: F) -> Result<U>
|
||||||
@@ -45,6 +45,7 @@ pub trait NativeExecutionDispatch {
|
|||||||
|
|
||||||
/// A generic `CodeExecutor` implementation that uses a delegate to determine wasm code equivalence
|
/// A generic `CodeExecutor` implementation that uses a delegate to determine wasm code equivalence
|
||||||
/// and dispatch to native code when possible, falling back on `WasmExecutor` when not.
|
/// and dispatch to native code when possible, falling back on `WasmExecutor` when not.
|
||||||
|
#[derive(Default)]
|
||||||
pub struct NativeExecutor<D: NativeExecutionDispatch + Sync + Send> {
|
pub struct NativeExecutor<D: NativeExecutionDispatch + Sync + Send> {
|
||||||
/// Dummy field to avoid the compiler complaining about us not using `D`.
|
/// Dummy field to avoid the compiler complaining about us not using `D`.
|
||||||
pub _dummy: ::std::marker::PhantomData<D>,
|
pub _dummy: ::std::marker::PhantomData<D>,
|
||||||
@@ -69,3 +70,37 @@ impl<D: NativeExecutionDispatch + Sync + Send> CodeExecutor for NativeExecutor<D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! native_executor_instance {
|
||||||
|
(pub $name:ident, $dispatcher:path, $code:expr) => {
|
||||||
|
pub struct $name;
|
||||||
|
native_executor_instance!(IMPL $name, $dispatcher, $code);
|
||||||
|
};
|
||||||
|
($name:ident, $dispatcher:path, $code:expr) => {
|
||||||
|
/// A unit struct which implements `NativeExecutionDispatch` feeding in the hard-coded runtime.
|
||||||
|
struct $name;
|
||||||
|
native_executor_instance!(IMPL $name, $dispatcher, $code);
|
||||||
|
};
|
||||||
|
(IMPL $name:ident, $dispatcher:path, $code:expr) => {
|
||||||
|
impl $crate::NativeExecutionDispatch for $name {
|
||||||
|
fn native_equivalent() -> &'static [u8] {
|
||||||
|
// WARNING!!! This assumes that the runtime was built *before* the main project. Until we
|
||||||
|
// get a proper build script, this must be strictly adhered to or things will go wrong.
|
||||||
|
$code
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dispatch(ext: &mut $crate::Externalities, method: &str, data: &[u8]) -> $crate::error::Result<Vec<u8>> {
|
||||||
|
$crate::with_native_environment(ext, move || $dispatcher(method, data))?
|
||||||
|
.ok_or_else(|| $crate::error::ErrorKind::MethodNotFound(method.to_owned()).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $name {
|
||||||
|
pub fn new() -> $crate::NativeExecutor<$name> {
|
||||||
|
$crate::NativeExecutor { _dummy: Default::default() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "substrate-keyring"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ed25519 = { path = "../ed25519" }
|
||||||
|
hex-literal = { version = "0.1.0" }
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
// Copyright 2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Polkadot.
|
||||||
|
|
||||||
|
// Polkadot is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Polkadot is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Support code for the runtime.
|
||||||
|
|
||||||
|
#[macro_use] extern crate hex_literal;
|
||||||
|
extern crate ed25519;
|
||||||
|
|
||||||
|
use ed25519::{Pair, Public, Signature};
|
||||||
|
|
||||||
|
/// Set of test accounts.
|
||||||
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
pub enum Keyring {
|
||||||
|
Alice,
|
||||||
|
Bob,
|
||||||
|
Charlie,
|
||||||
|
Dave,
|
||||||
|
Eve,
|
||||||
|
Ferdie,
|
||||||
|
One,
|
||||||
|
Two,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Keyring {
|
||||||
|
pub fn from_public(who: Public) -> Option<Keyring> {
|
||||||
|
[
|
||||||
|
Keyring::Alice,
|
||||||
|
Keyring::Bob,
|
||||||
|
Keyring::Charlie,
|
||||||
|
Keyring::Dave,
|
||||||
|
Keyring::Eve,
|
||||||
|
Keyring::Ferdie,
|
||||||
|
Keyring::One,
|
||||||
|
Keyring::Two,
|
||||||
|
].iter()
|
||||||
|
.map(|i| *i)
|
||||||
|
.find(|&k| Public::from(k) == who)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_raw_public(who: [u8; 32]) -> Option<Keyring> {
|
||||||
|
Self::from_public(Public::from_raw(who))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_raw_public(self) -> [u8; 32] {
|
||||||
|
*Public::from(self).as_array_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_raw_public_vec(self) -> Vec<u8> {
|
||||||
|
Public::from(self).to_raw_vec()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sign(self, msg: &[u8]) -> Signature {
|
||||||
|
Pair::from(self).sign(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Keyring> for &'static str {
|
||||||
|
fn from(k: Keyring) -> Self {
|
||||||
|
match k {
|
||||||
|
Keyring::Alice => "Alice",
|
||||||
|
Keyring::Bob => "Bob",
|
||||||
|
Keyring::Charlie => "Charlie",
|
||||||
|
Keyring::Dave => "Dave",
|
||||||
|
Keyring::Eve => "Eve",
|
||||||
|
Keyring::Ferdie => "Ferdie",
|
||||||
|
Keyring::One => "one",
|
||||||
|
Keyring::Two => "two",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Keyring> for Pair {
|
||||||
|
fn from(k: Keyring) -> Self {
|
||||||
|
match k {
|
||||||
|
Keyring::Alice => Pair::from_seed(b"Alice "),
|
||||||
|
Keyring::Bob => Pair::from_seed(b"Bob "),
|
||||||
|
Keyring::Charlie => Pair::from_seed(b"Charlie "),
|
||||||
|
Keyring::Dave => Pair::from_seed(b"Dave "),
|
||||||
|
Keyring::Eve => Pair::from_seed(b"Eve "),
|
||||||
|
Keyring::Ferdie => Pair::from_seed(b"Ferdie "),
|
||||||
|
Keyring::One => Pair::from_seed(b"12345678901234567890123456789012"),
|
||||||
|
Keyring::Two => Pair::from_seed(&hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Keyring> for Public {
|
||||||
|
fn from(k: Keyring) -> Self {
|
||||||
|
let pair: Pair = k.into();
|
||||||
|
pair.public()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Keyring> for [u8; 32] {
|
||||||
|
fn from(k: Keyring) -> Self {
|
||||||
|
let pair: Pair = k.into();
|
||||||
|
*pair.public().as_array_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use ed25519::Verifiable;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_work() {
|
||||||
|
assert!(Keyring::Alice.sign(b"I am Alice!").verify(b"I am Alice!", &Keyring::Alice.into()));
|
||||||
|
assert!(!Keyring::Alice.sign(b"I am Alice!").verify(b"I am Bob!", &Keyring::Alice.into()));
|
||||||
|
assert!(!Keyring::Alice.sign(b"I am Alice!").verify(b"I am Alice!", &Keyring::Bob.into()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ version = "0.1.0"
|
|||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
ed25519 = { path = "../ed25519", optional = true }
|
||||||
hex-literal = { version = "0.1.0", optional = true }
|
hex-literal = { version = "0.1.0", optional = true }
|
||||||
substrate-runtime-std = { path = "../runtime-std", default_features = false }
|
substrate-runtime-std = { path = "../runtime-std", default_features = false }
|
||||||
substrate-runtime-io = { path = "../runtime-io", default_features = false }
|
substrate-runtime-io = { path = "../runtime-io", default_features = false }
|
||||||
@@ -14,6 +15,7 @@ substrate-codec = { path = "../codec", default_features = false }
|
|||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
std = [
|
std = [
|
||||||
|
"ed25519",
|
||||||
"hex-literal",
|
"hex-literal",
|
||||||
"environmental",
|
"environmental",
|
||||||
"substrate-primitives/std",
|
"substrate-primitives/std",
|
||||||
|
|||||||
@@ -22,18 +22,9 @@ extern crate substrate_runtime_std as rstd;
|
|||||||
extern crate substrate_runtime_io as runtime_io;
|
extern crate substrate_runtime_io as runtime_io;
|
||||||
extern crate substrate_codec as codec;
|
extern crate substrate_codec as codec;
|
||||||
extern crate substrate_primitives as primitives;
|
extern crate substrate_primitives as primitives;
|
||||||
#[macro_use]
|
|
||||||
#[cfg(any(feature = "std", test))]
|
|
||||||
extern crate hex_literal;
|
|
||||||
|
|
||||||
pub mod storage;
|
pub mod storage;
|
||||||
mod hashable;
|
mod hashable;
|
||||||
#[macro_use]
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
mod testing;
|
|
||||||
|
|
||||||
pub use self::storage::StorageVec;
|
pub use self::storage::StorageVec;
|
||||||
pub use self::hashable::Hashable;
|
pub use self::hashable::Hashable;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
pub use self::testing::{one, two};
|
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
// Copyright 2017 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Polkadot.
|
|
||||||
|
|
||||||
// Polkadot is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Polkadot is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Testing helpers.
|
|
||||||
|
|
||||||
use primitives::AuthorityId;
|
|
||||||
|
|
||||||
/// One account (to which we know the secret key).
|
|
||||||
pub fn one() -> AuthorityId {
|
|
||||||
hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee")
|
|
||||||
}
|
|
||||||
/// Another account (secret key known).
|
|
||||||
pub fn two() -> AuthorityId {
|
|
||||||
hex!("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a")
|
|
||||||
}
|
|
||||||
@@ -130,11 +130,6 @@ impl fmt::Display for ExternalitiesError {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Externalities Error") }
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Externalities Error") }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_keyed_vec(value: u32, mut prepend: Vec<u8>) -> Vec<u8> {
|
|
||||||
prepend.extend((0..::std::mem::size_of::<u32>()).into_iter().map(|i| (value >> (i * 8)) as u8));
|
|
||||||
prepend
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Externalities: pinned to specific active address.
|
/// Externalities: pinned to specific active address.
|
||||||
pub trait Externalities {
|
pub trait Externalities {
|
||||||
/// Read storage of current contract being called.
|
/// Read storage of current contract being called.
|
||||||
@@ -148,20 +143,6 @@ pub trait Externalities {
|
|||||||
|
|
||||||
/// Get the trie root of the current storage map.
|
/// Get the trie root of the current storage map.
|
||||||
fn storage_root(&self) -> [u8; 32];
|
fn storage_root(&self) -> [u8; 32];
|
||||||
|
|
||||||
/// Get the current set of authorities from storage.
|
|
||||||
fn authorities(&self) -> Result<Vec<&[u8]>, ExternalitiesError> {
|
|
||||||
(0..self.storage(b":auth:len")?.into_iter()
|
|
||||||
.rev()
|
|
||||||
.fold(0, |acc, &i| (acc << 8) + (i as u32)))
|
|
||||||
.map(|i| self.storage(&to_keyed_vec(i, b":auth:".to_vec())))
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the runtime code.
|
|
||||||
fn code(&self) -> Result<&[u8], ExternalitiesError> {
|
|
||||||
self.storage(b":code")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Code execution engine.
|
/// Code execution engine.
|
||||||
@@ -252,26 +233,6 @@ mod tests {
|
|||||||
assert!(overlayed.storage(&key).is_none());
|
assert!(overlayed.storage(&key).is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn authorities_call_works() {
|
|
||||||
let mut ext = TestExternalities::default();
|
|
||||||
|
|
||||||
assert_eq!(ext.authorities(), Ok(vec![]));
|
|
||||||
|
|
||||||
ext.set_storage(b":auth:len".to_vec(), vec![0u8; 4]);
|
|
||||||
assert_eq!(ext.authorities(), Ok(vec![]));
|
|
||||||
|
|
||||||
ext.set_storage(b":auth:len".to_vec(), vec![1u8, 0, 0, 0]);
|
|
||||||
assert_eq!(ext.authorities(), Ok(vec![&[][..]]));
|
|
||||||
|
|
||||||
ext.set_storage(b":auth:\0\0\0\0".to_vec(), b"first".to_vec());
|
|
||||||
assert_eq!(ext.authorities(), Ok(vec![&b"first"[..]]));
|
|
||||||
|
|
||||||
ext.set_storage(b":auth:len".to_vec(), vec![2u8, 0, 0, 0]);
|
|
||||||
ext.set_storage(b":auth:\x01\0\0\0".to_vec(), b"second".to_vec());
|
|
||||||
assert_eq!(ext.authorities(), Ok(vec![&b"first"[..], &b"second"[..]]));
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! map {
|
macro_rules! map {
|
||||||
($( $name:expr => $value:expr ),*) => (
|
($( $name:expr => $value:expr ),*) => (
|
||||||
vec![ $( ( $name, $value ) ),* ].into_iter().collect()
|
vec![ $( ( $name, $value ) ),* ].into_iter().collect()
|
||||||
|
|||||||
@@ -4,21 +4,26 @@ version = "0.1.0"
|
|||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
hex-literal = "0.1.0"
|
|
||||||
log = { version = "0.3", optional = true }
|
log = { version = "0.3", optional = true }
|
||||||
substrate-codec = { path = "../../substrate/codec" }
|
hex-literal = { version = "0.1.0", optional = true }
|
||||||
substrate-runtime-std = { path = "../../substrate/runtime-std" }
|
ed25519 = { path = "../ed25519", optional = true }
|
||||||
substrate-runtime-io = { path = "../../substrate/runtime-io" }
|
substrate-keyring = { path = "../keyring", optional = true }
|
||||||
substrate-runtime-support = { path = "../../substrate/runtime-support" }
|
substrate-codec = { path = "../codec", default-features = false }
|
||||||
substrate-primitives = { path = "../../substrate/primitives" }
|
substrate-runtime-std = { path = "../runtime-std", default-features = false }
|
||||||
|
substrate-runtime-io = { path = "../runtime-io", default-features = false }
|
||||||
|
substrate-runtime-support = { path = "../runtime-support", default-features = false }
|
||||||
|
substrate-primitives = { path = "../primitives", default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
std = [
|
std = [
|
||||||
|
"log",
|
||||||
|
"hex-literal",
|
||||||
|
"ed25519",
|
||||||
|
"substrate-keyring",
|
||||||
"substrate-codec/std",
|
"substrate-codec/std",
|
||||||
"substrate-runtime-std/std",
|
"substrate-runtime-std/std",
|
||||||
"substrate-runtime-io/std",
|
"substrate-runtime-io/std",
|
||||||
"substrate-runtime-support/std",
|
"substrate-runtime-support/std",
|
||||||
"substrate-primitives/std",
|
"substrate-primitives/std",
|
||||||
"log"
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -19,15 +19,15 @@
|
|||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
extern crate substrate_runtime_std as rstd;
|
extern crate substrate_runtime_std as rstd;
|
||||||
#[macro_use]
|
#[macro_use] extern crate substrate_runtime_io as runtime_io;
|
||||||
extern crate substrate_runtime_io as runtime_io;
|
|
||||||
extern crate substrate_runtime_support as runtime_support;
|
extern crate substrate_runtime_support as runtime_support;
|
||||||
extern crate substrate_codec as codec;
|
extern crate substrate_codec as codec;
|
||||||
#[cfg(test)] #[macro_use] extern crate hex_literal;
|
#[cfg(test)] #[macro_use] extern crate hex_literal;
|
||||||
|
#[cfg(test)] extern crate ed25519;
|
||||||
|
#[cfg(test)] extern crate substrate_keyring as keyring;
|
||||||
#[cfg_attr(test, macro_use)] extern crate substrate_primitives as primitives;
|
#[cfg_attr(test, macro_use)] extern crate substrate_primitives as primitives;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")] pub mod genesismap;
|
||||||
pub mod genesismap;
|
|
||||||
pub mod system;
|
pub mod system;
|
||||||
mod transaction;
|
mod transaction;
|
||||||
mod unchecked_transaction;
|
mod unchecked_transaction;
|
||||||
@@ -63,7 +63,7 @@ pub fn run_tests(mut input: &[u8]) -> Vec<u8> {
|
|||||||
[stxs.len() as u8].encode()
|
[stxs.len() as u8].encode()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod apis {
|
pub mod api {
|
||||||
use system;
|
use system;
|
||||||
|
|
||||||
impl_stubs!(
|
impl_stubs!(
|
||||||
|
|||||||
@@ -132,24 +132,25 @@ mod tests {
|
|||||||
|
|
||||||
use runtime_io::{with_externalities, twox_128, TestExternalities};
|
use runtime_io::{with_externalities, twox_128, TestExternalities};
|
||||||
use codec::{Joiner, KeyedVec};
|
use codec::{Joiner, KeyedVec};
|
||||||
use runtime_support::{one, two};
|
use keyring::Keyring;
|
||||||
use ::{Header, Digest};
|
use ::{Header, Digest, Transaction, UncheckedTransaction};
|
||||||
|
|
||||||
fn new_test_ext() -> TestExternalities {
|
fn new_test_ext() -> TestExternalities {
|
||||||
let one = one();
|
|
||||||
let two = two();
|
|
||||||
let three = [3u8; 32];
|
|
||||||
|
|
||||||
TestExternalities { storage: map![
|
TestExternalities { storage: map![
|
||||||
twox_128(b"latest").to_vec() => vec![69u8; 32],
|
twox_128(b"latest").to_vec() => vec![69u8; 32],
|
||||||
twox_128(b":auth:len").to_vec() => vec![].and(&3u32),
|
twox_128(b":auth:len").to_vec() => vec![].and(&3u32),
|
||||||
twox_128(&0u32.to_keyed_vec(b":auth:")).to_vec() => one.to_vec(),
|
twox_128(&0u32.to_keyed_vec(b":auth:")).to_vec() => Keyring::Alice.to_raw_public().to_vec(),
|
||||||
twox_128(&1u32.to_keyed_vec(b":auth:")).to_vec() => two.to_vec(),
|
twox_128(&1u32.to_keyed_vec(b":auth:")).to_vec() => Keyring::Bob.to_raw_public().to_vec(),
|
||||||
twox_128(&2u32.to_keyed_vec(b":auth:")).to_vec() => three.to_vec(),
|
twox_128(&2u32.to_keyed_vec(b":auth:")).to_vec() => Keyring::Charlie.to_raw_public().to_vec(),
|
||||||
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
|
twox_128(&Keyring::Alice.to_raw_public().to_keyed_vec(b"balance:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
|
||||||
], }
|
], }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn construct_signed_tx(tx: Transaction) -> UncheckedTransaction {
|
||||||
|
let signature = Keyring::from_raw_public(tx.from).unwrap().sign(&tx.encode());
|
||||||
|
UncheckedTransaction { tx, signature }
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn block_import_works() {
|
fn block_import_works() {
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
@@ -157,7 +158,7 @@ mod tests {
|
|||||||
let h = Header {
|
let h = Header {
|
||||||
parent_hash: [69u8; 32].into(),
|
parent_hash: [69u8; 32].into(),
|
||||||
number: 1,
|
number: 1,
|
||||||
state_root: hex!("89b5f5775a45310806a77f421d66bffeff190a519c55f2dcb21f251c2b714524").into(),
|
state_root: hex!("97dfcd1f8cbf8845fcb544f89332f1a94c1137f7d1b199ef0b0a6ed217015c3e").into(),
|
||||||
transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(),
|
transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(),
|
||||||
digest: Digest { logs: vec![], },
|
digest: Digest { logs: vec![], },
|
||||||
};
|
};
|
||||||
@@ -171,4 +172,71 @@ mod tests {
|
|||||||
execute_block(b);
|
execute_block(b);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn block_import_with_transaction_works() {
|
||||||
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
|
with_externalities(&mut t, || {
|
||||||
|
assert_eq!(balance_of(Keyring::Alice.to_raw_public()), 111);
|
||||||
|
assert_eq!(balance_of(Keyring::Bob.to_raw_public()), 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
let b = Block {
|
||||||
|
header: Header {
|
||||||
|
parent_hash: [69u8; 32].into(),
|
||||||
|
number: 1,
|
||||||
|
state_root: hex!("0dd8210adaf581464cc68555814a787ed491f8c608d0a0dbbf2208a6d44190b1").into(),
|
||||||
|
transaction_root: hex!("5e44188712452f900acfa1b4bf4084753122ea1856d58187dd33374a2ca653b1").into(),
|
||||||
|
digest: Digest { logs: vec![], },
|
||||||
|
},
|
||||||
|
transactions: vec![
|
||||||
|
construct_signed_tx(Transaction {
|
||||||
|
from: Keyring::Alice.to_raw_public(),
|
||||||
|
to: Keyring::Bob.to_raw_public(),
|
||||||
|
amount: 69,
|
||||||
|
nonce: 0,
|
||||||
|
})
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
with_externalities(&mut t, || {
|
||||||
|
execute_block(b.clone());
|
||||||
|
|
||||||
|
assert_eq!(balance_of(Keyring::Alice.to_raw_public()), 42);
|
||||||
|
assert_eq!(balance_of(Keyring::Bob.to_raw_public()), 69);
|
||||||
|
});
|
||||||
|
|
||||||
|
let b = Block {
|
||||||
|
header: Header {
|
||||||
|
parent_hash: b.header.blake2_256().into(),
|
||||||
|
number: 2,
|
||||||
|
state_root: hex!("aea7c370a9fa4075b703742c22cc4fb12759bdd7d5aa5cdd85895447f838b81b").into(),
|
||||||
|
transaction_root: hex!("9ac45fbcc93fa6a8b5a3c44f04d936d53569c72a53fbc12eb58bf884f6dbfae5").into(),
|
||||||
|
digest: Digest { logs: vec![], },
|
||||||
|
},
|
||||||
|
transactions: vec![
|
||||||
|
construct_signed_tx(Transaction {
|
||||||
|
from: Keyring::Bob.to_raw_public(),
|
||||||
|
to: Keyring::Alice.to_raw_public(),
|
||||||
|
amount: 27,
|
||||||
|
nonce: 0,
|
||||||
|
}),
|
||||||
|
construct_signed_tx(Transaction {
|
||||||
|
from: Keyring::Alice.to_raw_public(),
|
||||||
|
to: Keyring::Charlie.to_raw_public(),
|
||||||
|
amount: 69,
|
||||||
|
nonce: 1,
|
||||||
|
})
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
with_externalities(&mut t, || {
|
||||||
|
execute_block(b);
|
||||||
|
|
||||||
|
assert_eq!(balance_of(Keyring::Alice.to_raw_public()), 0);
|
||||||
|
assert_eq!(balance_of(Keyring::Bob.to_raw_public()), 42);
|
||||||
|
assert_eq!(balance_of(Keyring::Charlie.to_raw_public()), 69);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -92,8 +92,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
name = "ed25519"
|
name = "ed25519"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"substrate-primitives 0.1.0",
|
"substrate-primitives 0.1.0",
|
||||||
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -620,6 +620,7 @@ dependencies = [
|
|||||||
name = "substrate-runtime-support"
|
name = "substrate-runtime-support"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ed25519 0.1.0",
|
||||||
"environmental 0.1.0",
|
"environmental 0.1.0",
|
||||||
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"substrate-codec 0.1.0",
|
"substrate-codec 0.1.0",
|
||||||
@@ -645,7 +646,9 @@ dependencies = [
|
|||||||
name = "substrate-test-runtime"
|
name = "substrate-test-runtime"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ed25519 0.1.0",
|
||||||
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"substrate-codec 0.1.0",
|
"substrate-codec 0.1.0",
|
||||||
"substrate-primitives 0.1.0",
|
"substrate-primitives 0.1.0",
|
||||||
"substrate-runtime-io 0.1.0",
|
"substrate-runtime-io 0.1.0",
|
||||||
|
|||||||
@@ -3,28 +3,32 @@ name = "substrate-test-runtime"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["cdylib"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
log = { version = "0.3", optional = true }
|
||||||
hex-literal = { version = "0.1.0", optional = true }
|
hex-literal = { version = "0.1.0", optional = true }
|
||||||
substrate-codec = { path = "../../../substrate/codec", default-features = false }
|
ed25519 = { path = "../../ed25519", optional = true }
|
||||||
substrate-runtime-std = { path = "../../../substrate/runtime-std", default-features = false }
|
substrate-codec = { path = "../../codec", default-features = false }
|
||||||
substrate-runtime-io = { path = "../../../substrate/runtime-io", default-features = false }
|
substrate-runtime-std = { path = "../../runtime-std", default-features = false }
|
||||||
substrate-runtime-support = { path = "../../../substrate/runtime-support", default-features = false }
|
substrate-runtime-io = { path = "../../runtime-io", default-features = false }
|
||||||
substrate-primitives = { path = "../../../substrate/primitives", default-features = false }
|
substrate-runtime-support = { path = "../../runtime-support", default-features = false }
|
||||||
|
substrate-primitives = { path = "../../primitives", default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
std = [
|
std = [
|
||||||
|
"log",
|
||||||
"hex-literal",
|
"hex-literal",
|
||||||
|
"ed25519",
|
||||||
"substrate-codec/std",
|
"substrate-codec/std",
|
||||||
"substrate-runtime-io/std",
|
|
||||||
"substrate-runtime-std/std",
|
"substrate-runtime-std/std",
|
||||||
|
"substrate-runtime-io/std",
|
||||||
"substrate-runtime-support/std",
|
"substrate-runtime-support/std",
|
||||||
"substrate-primitives/std",
|
"substrate-primitives/std",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
Reference in New Issue
Block a user