From 36c171c4064b37ccd61f0f692f94e667aae3315a Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 8 Jan 2018 17:13:44 +0100 Subject: [PATCH 01/76] Introduce basic skeleton for Polkador runtime. --- executor/src/wasm_executor.rs | 28 +++-- runtime/polkadot/src/lib.rs | 222 +++++++++++++++++++++++++++++++--- runtime/support/src/lib.rs | 87 ++++++------- runtime/test/src/lib.rs | 53 +++++++- 4 files changed, 308 insertions(+), 82 deletions(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index f52b2cbf715e1..4c3ed5b7916c6 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -76,7 +76,7 @@ impl WritePrimitive for MemoryInstance { } impl_function_executor!(this: FunctionExecutor<'e, E>, - ext_print(utf8_data: *const u8, utf8_len: i32) => { + ext_print(utf8_data: *const u8, utf8_len: u32) => { if let Ok(utf8) = this.memory.get(utf8_data, utf8_len as usize) { if let Ok(message) = String::from_utf8(utf8) { println!("Runtime: {}", message); @@ -96,7 +96,7 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, println!("memmove {} from {}, {} bytes", dest, src, count); dest }, - ext_memset(dest: *mut u8, val: i32, count: usize) -> *mut u8 => { + ext_memset(dest: *mut u8, val: u32, count: usize) -> *mut u8 => { let _ = this.memory.clear(dest as usize, val as u8, count as usize); println!("memset {} with {}, {} bytes", dest, val, count); dest @@ -110,12 +110,12 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, this.heap.deallocate(addr); println!("free {}", addr) }, - ext_set_storage(key_data: *const u8, key_len: i32, value_data: *const u8, value_len: i32) => { + ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32) => { if let (Ok(key), Ok(value)) = (this.memory.get(key_data, key_len as usize), this.memory.get(value_data, value_len as usize)) { this.ext.set_storage(key, value); } }, - ext_get_allocated_storage(key_data: *const u8, key_len: i32, written_out: *mut i32) -> *mut u8 => { + ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8 => { let (offset, written) = if let Ok(key) = this.memory.get(key_data, key_len as usize) { if let Ok(value) = this.ext.storage(&key) { let offset = this.heap.allocate(value.len() as u32) as u32; @@ -126,6 +126,18 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, this.memory.write_primitive(written_out, written); offset as u32 + }, + ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32) -> u32 => { + if let Ok(key) = this.memory.get(key_data, key_len as usize) { + if let Ok(value) = this.ext.storage(&key) { + let written = ::std::cmp::min(value_len as usize, value.len()); + let _ = this.memory.set(value_data, &value[0..written]); + written as u32 + } else { 0 } + } else { 0 } + }, + ext_deposit_log(_log_data: *const u8, _log_len: u32) { + unimplemented!() } => <'e, E: Externalities + 'e> ); @@ -163,8 +175,8 @@ impl CodeExecutor for WasmExecutor { let returned = program .params_with_external("env", &mut fec) .map(|p| p - .add_argument(I32(offset as i32)) - .add_argument(I32(size as i32))) + .add_argument(I32(offset as u32)) + .add_argument(I32(size as u32))) .and_then(|p| module.execute_export(method, p)) .map_err(|_| -> Error { ErrorKind::Runtime.into() })?; @@ -221,8 +233,8 @@ mod tests { let returned = program .params_with_external("env", &mut fec) .map(|p| p - .add_argument(I32(offset as i32)) - .add_argument(I32(size as i32))) + .add_argument(I32(offset as u32)) + .add_argument(I32(size as u32))) .and_then(|p| module.execute_export("test_data_in", p)) .map_err(|_| -> Error { ErrorKind::Runtime.into() }).expect("function should be callable"); diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index ec3fabb89cd15..da82db8fa2ce2 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -8,29 +8,215 @@ use alloc::vec::Vec; #[macro_use] extern crate runtime_support; -use runtime_support::{set_storage, code, set_code, storage, validators, set_validators, print}; +use runtime_support::{set_storage, storage, storage_into, print, Value20}; -impl_stub!(test_data_in); -fn test_data_in(input: Vec) -> Vec { - print(b"set_storage" as &[u8]); - set_storage(b"input", &input); +/// The hash of an ECDSA pub key which is used to identify an external transactor. +type AccountID = [u8; 32]; +/// The ECDSA pub key of an authority. This is what the external environment/consensus algorithm +/// refers to as a "authority". +type SessionKey = [u8; 65]; +type Balance = u64; +type ChainID = u64; +type Hash = [u8; 32]; +type BlockNumber = u64; +/// A proportion (rational number). +struct Proportion { nom: u64, denom: u64, }; +type Timestamp = u64; +type TxOrder = u64; +/// Statistics concerning consensus. +// TODO. +struct Statistics; +/// A report of bad behaviour. +// TODO. +struct Complaint; - print(b"code" as &[u8]); - set_storage(b"code", &code()); +/// The state of a parachain. +/*struct ParachainState { + head_data: Vec, + balance: Balance, + user_balances: HashMap, + balance_downloads: HashMap ), + egress_roots: Vec +}*/ +//struct CandidateReceipt; - print(b"set_code" as &[u8]); - set_code(&input); +// TODO: include RLP implementation +// TODO: add keccak256 (or some better hashing scheme) & ECDSA-recover (or some better sig scheme) - print(b"storage" as &[u8]); - let copy = storage(b"input"); +impl_stub!(execute_block); +fn execute_block(_input: Vec) -> Vec { + // TODO: decode block and ensure valid + // TODO: iterate through transactions amd decode/dispatch them + // TODO: progress to next session if it's time + // TODO: progress to next era if it's time + Vec::new() +} + +impl_stub!(execute_transaction); +fn execute_transaction(tx: Vec) -> Vec { + environment::execute_transaction(&tx) +} + +/// The current relay chain identifier. +fn chain_id() -> ChainID { unimplemented!() } // TODO: retrieve from external + +mod environment { + /// The current block number being processed. Set by `execute_block`. + pub fn block_number() -> BlockNumber { unimplemented!() } + + /// Get the block hash of a given block. + pub fn block_hash(_number: BlockNumber) -> Hash { unimplemented!() } + + /// ? + fn set_digest(_preserialised_rlp_digest: &[u8]) { unimplemented!() } + + /// Get the current user's ID + pub fn current_user() -> AccountID { unimplemented!() } + + /// Execute a given transaction. + pub fn execute_transaction(_tx: &[u8]) -> Vec { + // TODO: decode data and ensure valid + // TODO: ensure signature valid and recover id + // TODO: ensure target_function valid + // TODO: decode parameters + // TODO: make call + // TODO: encode any return + Vec::new() + } + + /// Set the new code. + pub fn set_code(new: &[u8]) { + set_storage(b"\0code", new) + } + + /// ? + fn set_active_parachains(_data: &[u8]) { unimplemented!() } +} + +mod consensus { + fn value_vec(mut value: usize, initial: Vec) -> Vec { + let mut acc = initial; + while value > 0 { + acc.push(value as u8); + value /= 256; + } + acc + } + + fn set_authority(index: usize, authority: AccountID) { + set_storage(&value_vec(index, b"\0authority".to_vec()), &authority[..]); + } + + fn authority(index: usize) -> AccountID { + storage_into::(&value_vec(index, b"\0authority".to_vec())) + } + + fn set_authority_count(count: usize) { + (count..authority_count()).for_each(|i| set_authority(i, &[])); + set_storage(b"\0authority_count", &value_vec(count, Vec::new())); + } + + fn authority_count() -> usize { + storage(b"\0authority_count").into_iter().rev().fold(0, |acc, i| (acc << 8) + (i as usize)) + } + + /// Get the current set of authorities. These are the session keys. + pub fn authorities() -> Vec { + (0..authority_count()).into_iter().map(authority).map.collect() + } - print(b"validators" as &[u8]); - let mut v = validators(); - v.push(copy); + /// Set the current set of authorities' session keys. + /// + /// Called by `next_session` only. + fn set_authorities(authorities: &[AccountID]) { + set_authority_count(authorities.len()); + authorities.iter().enumerate().for_each(|(v, i)| set_authority(v, i)); + } - print(b"set_validators" as &[u8]); - set_validators(&v.iter().map(Vec::as_slice).collect::>()); + /// Get the current set of validators. These are the long-term identifiers for the validators + /// and will be mapped to a session key with the most recent `set_next_session_key`. + pub fn validators() -> Vec { + unimplemented!() + } - print(b"finished!" as &[u8]); - b"all ok!".to_vec() + /// Set the current set of validators. + /// + /// Called by staking::next_era() only. + pub fn set_validators(_new: &[AccountID]) { + unimplemented!() + } + + /// Flush out any statistics. + pub fn flush_statistics() -> Statistics { unimplemented!() } + + /// Sets the session key of `_validator` to `_session`. This doesn't take effect until the next + /// session. + pub fn set_session_key(_validator: AccountID, _session: AccountID) { + unimplemented!() + } + + /// Move onto next session: register the new authority set. + pub fn next_session() { + // TODO: Call set_authorities(). + unimplemented!() + } +} + +mod staking { + /// The length of a staking era in blocks. + fn era_length() -> BlockNumber { unimplemented!() } + + /// The era has changed - enact new staking set. + /// + /// NOTE: This is always a session change. + fn next_era() { unimplemented!() } + + /// The balance of a given account. + fn balance(_who: AccountID) -> Balance { unimplemented!() } + + /// User-level function to move funds onto a parachain. Calls `parachains::credit_parachain`. + fn move_to_parachain(chain_id: ChainID, value: Balance) { unimplemented!() } + + /// System-level function to be called only by Parachains object when funds have left that + /// object and are to be credited here. + fn credit_staker(value: Balance) { unimplemented!() } + + /// Declare the desire to stake under the requirement that under flawless operation, each era + /// should return `minimum_era_return` on the amount staked. + /// + /// Effects will be felt at the beginning of the next era. + fn stake(minimum_era_return: Proportion) { unimplemented!() } + + /// Retract the desire to stake. + /// + /// Effects will be felt at the beginning of the next era. + fn unstake() { unimplemented!() } + + /// Report invalid behaviour by a staking participant. + fn complain(complaint: Complaint) { unimplemented!() } +} + +/* +mod parachains { + fn chain_ids(self) -> [ ChainID ]; + fn validation_function(self, chain_id: ChainID) -> Fn(consolidated_ingress: [ ( ChainID, bytes ) ], balance_downloads: [ ( AccountID, Balance ) ], block_data: bytes, previous_head_data: bytes) -> (head_data: bytes, egress_queues: [ [ bytes ] ], balance_uploads: [ ( AccountID, Balance ) ]); + fn validate_and_calculate_fees_function(self, chain_id: ChainID) -> Fn(egress_queues: [ [ bytes ] ], balance_uploads: [ ( AccountID, Balance ) ]) -> Balance; + fn balance(self, chain_id: ChainID, id: AccountID) -> Balance; + fn verify_and_consolidate_queues(self, unprocessed_ingress: [ [ [ bytes ] ] ]) -> [ (chain_id: ChainID, message: bytes) ]; + fn chain_state(self, chain_id: ChainID) -> ParachainState; + fn move_to_staking(mut self, chain_id: ChainID, value: Balance); + fn credit_parachain(mut self, chain_id: ChainID, value: Balance); + fn download(mut self, chain_id: ChainID, value: Balance, instruction: bytes); + fn update_heads(mut self, candidate_receipts: &[ ( ChainID, CandidateReceipt ) ]); +} + +mod authentication { + fn validate_signature(self, tx: Transaction) -> ( AccountID, TxOrder ); + fn nonce(self, id: AccountID) -> TxOrder; + fn authenticate(mut self, tx: Transaction) -> AccountID; +} +*/ +mod timestamp { + fn timestamp() -> Timestamp { unimplemented!() } + fn set_timestamp(Timestamp) { unimplemented!() } } diff --git a/runtime/support/src/lib.rs b/runtime/support/src/lib.rs index 472497d284548..4430f7249faa6 100644 --- a/runtime/support/src/lib.rs +++ b/runtime/support/src/lib.rs @@ -17,70 +17,57 @@ pub fn panic_fmt() -> ! { } extern "C" { - fn ext_print(utf8_data: *const u8, utf8_len: i32); + fn ext_print(utf8_data: *const u8, utf8_len: u32); fn ext_print_num(value: u64); - fn ext_set_storage(key_data: *const u8, key_len: i32, value_data: *const u8, value_len: i32); - fn ext_get_allocated_storage(key_data: *const u8, key_len: i32, written_out: *mut i32) -> *mut u8; + fn ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32); + fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8; + fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32) -> u32; + fn ext_deposit_log(log_data: *const u8, log_len: u32); } pub fn storage(key: &[u8]) -> Vec { - let mut length: i32 = 0; + let mut length: u32 = 0; unsafe { - let ptr = ext_get_allocated_storage(&key[0], key.len() as i32, &mut length); + let ptr = ext_get_allocated_storage(&key[0], key.len() as u32, &mut length); Vec::from_raw_parts(ptr, length as usize, length as usize) } } -pub fn set_storage(key: &[u8], value: &[u8]) { - unsafe { - ext_set_storage( - &key[0] as *const u8, key.len() as i32, - &value[0] as *const u8, value.len() as i32 - ); - } -} - -pub fn code() -> Vec { - storage(b"\0code") +pub trait IsValue { + const value: usize; } -pub fn set_code(new: &[u8]) { - set_storage(b"\0code", new) -} +pub struct Value20; impl IsValue for Value20 { const value = 20usize; } +pub struct Value32; impl IsValue for Value32 { const value = 32usize; } +pub struct Value64; impl IsValue for Value64 { const value = 64usize; } +pub struct Value65; impl IsValue for Value65 { const value = 65usize; } -fn value_vec(mut value: usize, initial: Vec) -> Vec { - let mut acc = initial; - while value > 0 { - acc.push(value as u8); - value /= 256; +pub fn storage_into(key: &[u8]) -> Option<[u8; T::value]> { + let mut result = [0u8; T::value]; + let written = unsafe { + ext_get_storage_into(&key[0], key.len() as u32, &result[0], result.len()) + }; + match written { + T::value => Some(result), + _ => None, } - acc -} - -pub fn set_validator(index: usize, validator: &[u8]) { - set_storage(&value_vec(index, b"\0validator".to_vec()), validator); -} - -pub fn validator(index: usize) -> Vec { - storage(&value_vec(index, b"\0validator".to_vec())) } -pub fn set_validator_count(count: usize) { - (count..validator_count()).for_each(|i| set_validator(i, &[])); - set_storage(b"\0validator_count", &value_vec(count, Vec::new())); -} - -pub fn validator_count() -> usize { - storage(b"\0validator_count").into_iter().rev().fold(0, |acc, i| (acc << 8) + (i as usize)) -} - -pub fn validators() -> Vec> { - (0..validator_count()).into_iter().map(validator).collect() +pub fn set_storage(key: &[u8], value: &[u8]) { + unsafe { + ext_set_storage( + &key[0] as *const u8, key.len() as u32, + &value[0] as *const u8, value.len() as u32 + ); + } } -pub fn set_validators(validators: &[&[u8]]) { - set_validator_count(validators.len()); - validators.iter().enumerate().for_each(|(v, i)| set_validator(v, i)); +pub fn deposit_log(log: &[u8]) { + unsafe { + ext_deposit_log( + &log[0] as *const u8, log.len() as u32, + ) + } } pub trait Printable { @@ -90,7 +77,7 @@ pub trait Printable { impl<'a> Printable for &'a [u8] { fn print(self) { unsafe { - ext_print(&self[0] as *const u8, self.len() as i32); + ext_print(&self[0] as *const u8, self.len() as u32); } } } @@ -109,12 +96,10 @@ pub fn print(value: T) { macro_rules! impl_stub { ($name:ident) => { pub mod _internal { - extern crate alloc; - #[no_mangle] pub fn $name(input_data: *mut u8, input_len: usize) -> u64 { let input = unsafe { - ::alloc::vec::Vec::from_raw_parts(input_data, input_len, input_len) + super::alloc::vec::Vec::from_raw_parts(input_data, input_len, input_len) }; let output = super::$name(input); diff --git a/runtime/test/src/lib.rs b/runtime/test/src/lib.rs index ec3fabb89cd15..550e06c05dd84 100644 --- a/runtime/test/src/lib.rs +++ b/runtime/test/src/lib.rs @@ -8,7 +8,50 @@ use alloc::vec::Vec; #[macro_use] extern crate runtime_support; -use runtime_support::{set_storage, code, set_code, storage, validators, set_validators, print}; +use runtime_support::{set_storage, storage, print}; + +pub fn code() -> Vec { + storage(b"\0code") +} + +pub fn set_code(new: &[u8]) { + set_storage(b"\0code", new) +} + +fn value_vec(mut value: usize, initial: Vec) -> Vec { + let mut acc = initial; + while value > 0 { + acc.push(value as u8); + value /= 256; + } + acc +} + +pub fn set_authority(index: usize, authority: &[u8]) { + set_storage(&value_vec(index, b"\0authority".to_vec()), authority); +} + +pub fn authority(index: usize) -> Vec { + storage(&value_vec(index, b"\0authority".to_vec())) +} + +pub fn set_authority_count(count: usize) { + (count..authority_count()).for_each(|i| set_authority(i, &[])); + set_storage(b"\0authority_count", &value_vec(count, Vec::new())); +} + +pub fn authority_count() -> usize { + storage(b"\0authority_count").into_iter().rev().fold(0, |acc, i| (acc << 8) + (i as usize)) +} + +pub fn authorities() -> Vec> { + (0..authority_count()).into_iter().map(authority).collect() +} + +pub fn set_authorities(authorities: &[&[u8]]) { + set_authority_count(authorities.len()); + authorities.iter().enumerate().for_each(|(v, i)| set_authority(v, i)); +} impl_stub!(test_data_in); fn test_data_in(input: Vec) -> Vec { @@ -24,12 +67,12 @@ fn test_data_in(input: Vec) -> Vec { print(b"storage" as &[u8]); let copy = storage(b"input"); - print(b"validators" as &[u8]); - let mut v = validators(); + print(b"authorities" as &[u8]); + let mut v = authorities(); v.push(copy); - print(b"set_validators" as &[u8]); - set_validators(&v.iter().map(Vec::as_slice).collect::>()); + print(b"set_authorities" as &[u8]); + set_authorities(&v.iter().map(Vec::as_slice).collect::>()); print(b"finished!" as &[u8]); b"all ok!".to_vec() From f79b7bb18dabad416a34b2e015b87a61105f6b37 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 8 Jan 2018 17:56:16 +0100 Subject: [PATCH 02/76] Clean up the runtime skeleton. --- runtime/polkadot/src/lib.rs | 174 +++++++++++++++++++++++++----------- 1 file changed, 120 insertions(+), 54 deletions(-) diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index da82db8fa2ce2..d2143f28cdfd1 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -10,6 +10,37 @@ use alloc::vec::Vec; extern crate runtime_support; use runtime_support::{set_storage, storage, storage_into, print, Value20}; +/* +use std::sync::{rc, RefCell, Once, ONCE_INIT}; +use std::mem; + +#[derive(Clone)] +struct SingletonReader { + inner: Rc>, +} + +fn singleton() -> SingletonReader { + // Initialize it to a null value + static mut SINGLETON: *const SingletonReader = 0 as *const SingletonReader; + static ONCE: Once = ONCE_INIT; + + unsafe { + ONCE.call_once(|| { + // Make it + let singleton = SingletonReader { + inner: Rc::new(RefCell::new(Default::default())), + }; + + // Put it in the heap so it can outlive this call + SINGLETON = mem::transmute(Box::new(singleton)); + }); + + // Now we give out a copy of the data that is safe to use concurrently. + (*SINGLETON).clone() + } +} +*/ + /// The hash of an ECDSA pub key which is used to identify an external transactor. type AccountID = [u8; 32]; /// The ECDSA pub key of an authority. This is what the external environment/consensus algorithm @@ -23,42 +54,69 @@ type BlockNumber = u64; struct Proportion { nom: u64, denom: u64, }; type Timestamp = u64; type TxOrder = u64; -/// Statistics concerning consensus. -// TODO. -struct Statistics; -/// A report of bad behaviour. -// TODO. -struct Complaint; - -/// The state of a parachain. -/*struct ParachainState { - head_data: Vec, - balance: Balance, - user_balances: HashMap, - balance_downloads: HashMap ), - egress_roots: Vec -}*/ -//struct CandidateReceipt; + +struct Digest { + logs: Vec>, +} + +struct Header { + parent_hash: Hash, + number: BlockNumber, + state_root: Hash, + transaction_root: Hash, + digest: Digest, +} + +struct Transaction { + senders: Vec, + function_name: String, + input_data: Vec, + nonce: TxOrder, +} + +struct Block { + header: Header, + transactions: Vec, +} + +impl Header { + pub fn from_rlp(_rlp: &[u8]) -> Self { + unimplemented!() + } +} + +impl Transaction { + pub fn from_rlp(_rlp: &[u8]) -> Self { + unimplemented!() + } +} + +impl Block { + pub fn from_rlp(_rlp: &[u8]) -> Self { + unimplemented!() + } +} // TODO: include RLP implementation // TODO: add keccak256 (or some better hashing scheme) & ECDSA-recover (or some better sig scheme) impl_stub!(execute_block); fn execute_block(_input: Vec) -> Vec { - // TODO: decode block and ensure valid - // TODO: iterate through transactions amd decode/dispatch them - // TODO: progress to next session if it's time - // TODO: progress to next era if it's time - Vec::new() + let block = Block::from_rlp(&_input); + environment::execute_block(&block) } impl_stub!(execute_transaction); -fn execute_transaction(tx: Vec) -> Vec { +fn execute_transaction(_input: Vec) -> Vec { + let tx = Transaction::from_rlp(&_input); environment::execute_transaction(&tx) } /// The current relay chain identifier. -fn chain_id() -> ChainID { unimplemented!() } // TODO: retrieve from external +fn chain_id() -> ChainID { + // TODO: retrieve from external + unimplemented!() +} mod environment { /// The current block number being processed. Set by `execute_block`. @@ -67,19 +125,27 @@ mod environment { /// Get the block hash of a given block. pub fn block_hash(_number: BlockNumber) -> Hash { unimplemented!() } - /// ? - fn set_digest(_preserialised_rlp_digest: &[u8]) { unimplemented!() } - /// Get the current user's ID pub fn current_user() -> AccountID { unimplemented!() } + pub fn execute_block(_block: &Block) -> Vec { + // TODO: populate environment from header. + staking::pre_transactions(); + // TODO: go through each transaction and use execute_transaction to execute. + staking::post_transactions(); + // TODO: ensure digest in header is what we expect from transactions. + Vec::new() + } + /// Execute a given transaction. - pub fn execute_transaction(_tx: &[u8]) -> Vec { + pub fn execute_transaction(_tx: &Transaction) -> Vec { // TODO: decode data and ensure valid - // TODO: ensure signature valid and recover id + // TODO: ensure signature valid and recover id (use authentication::authenticate) // TODO: ensure target_function valid // TODO: decode parameters + // TODO: set `current_user` to the id // TODO: make call + // TODO: reset `current_user` // TODO: encode any return Vec::new() } @@ -89,8 +155,11 @@ mod environment { set_storage(b"\0code", new) } - /// ? - fn set_active_parachains(_data: &[u8]) { unimplemented!() } + /// Set the light-client digest for the header. + pub fn set_digest(_preserialised_rlp_digest: &[u8]) { + // TODO: Mention this to the external environment? + unimplemented!() + } } mod consensus { @@ -160,6 +229,14 @@ mod consensus { // TODO: Call set_authorities(). unimplemented!() } + + /// Hook to be called prior to transaction processing. + pub fn pre_transactions() {} + + /// Hook to be called after to transaction processing. + pub fn post_transactions() { + // TODO: check block number and call next_session if necessary. + } } mod staking { @@ -174,15 +251,10 @@ mod staking { /// The balance of a given account. fn balance(_who: AccountID) -> Balance { unimplemented!() } - /// User-level function to move funds onto a parachain. Calls `parachains::credit_parachain`. - fn move_to_parachain(chain_id: ChainID, value: Balance) { unimplemented!() } - - /// System-level function to be called only by Parachains object when funds have left that - /// object and are to be credited here. - fn credit_staker(value: Balance) { unimplemented!() } + /// Transfer some unlocked staking balance to another staker. + fn transfer_stake(_who: AccountID, dest: AccountID, value: Balance) { unimplemented!() } - /// Declare the desire to stake under the requirement that under flawless operation, each era - /// should return `minimum_era_return` on the amount staked. + /// Declare the desire to stake. /// /// Effects will be felt at the beginning of the next era. fn stake(minimum_era_return: Proportion) { unimplemented!() } @@ -192,22 +264,16 @@ mod staking { /// Effects will be felt at the beginning of the next era. fn unstake() { unimplemented!() } - /// Report invalid behaviour by a staking participant. - fn complain(complaint: Complaint) { unimplemented!() } -} + /// Hook to be called prior to transaction processing. + pub fn pre_transactions() { + conensus::pre_transactions(); + } -/* -mod parachains { - fn chain_ids(self) -> [ ChainID ]; - fn validation_function(self, chain_id: ChainID) -> Fn(consolidated_ingress: [ ( ChainID, bytes ) ], balance_downloads: [ ( AccountID, Balance ) ], block_data: bytes, previous_head_data: bytes) -> (head_data: bytes, egress_queues: [ [ bytes ] ], balance_uploads: [ ( AccountID, Balance ) ]); - fn validate_and_calculate_fees_function(self, chain_id: ChainID) -> Fn(egress_queues: [ [ bytes ] ], balance_uploads: [ ( AccountID, Balance ) ]) -> Balance; - fn balance(self, chain_id: ChainID, id: AccountID) -> Balance; - fn verify_and_consolidate_queues(self, unprocessed_ingress: [ [ [ bytes ] ] ]) -> [ (chain_id: ChainID, message: bytes) ]; - fn chain_state(self, chain_id: ChainID) -> ParachainState; - fn move_to_staking(mut self, chain_id: ChainID, value: Balance); - fn credit_parachain(mut self, chain_id: ChainID, value: Balance); - fn download(mut self, chain_id: ChainID, value: Balance, instruction: bytes); - fn update_heads(mut self, candidate_receipts: &[ ( ChainID, CandidateReceipt ) ]); + /// Hook to be called after to transaction processing. + pub fn post_transactions() { + // TODO: check block number and call next_era if necessary. + conensus::post_transactions(); + } } mod authentication { @@ -215,7 +281,7 @@ mod authentication { fn nonce(self, id: AccountID) -> TxOrder; fn authenticate(mut self, tx: Transaction) -> AccountID; } -*/ + mod timestamp { fn timestamp() -> Timestamp { unimplemented!() } fn set_timestamp(Timestamp) { unimplemented!() } From b48e05330b0ef2d6fe2713ba3ef98d62ad350b13 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 8 Jan 2018 19:32:46 +0100 Subject: [PATCH 03/76] Make initial runtime skeleton compile. --- runtime/polkadot/src/lib.rs | 173 ++++++++++-------- runtime/support/src/lib.rs | 52 +++--- .../release/runtime_polkadot.compact.wasm | Bin 3042 -> 218 bytes .../release/runtime_polkadot.wasm | Bin 3130 -> 341 bytes .../release/runtime_test.compact.wasm | Bin 3042 -> 3392 bytes .../release/runtime_test.wasm | Bin 3130 -> 3480 bytes runtime/test/src/lib.rs | 2 +- 7 files changed, 124 insertions(+), 103 deletions(-) diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index d2143f28cdfd1..4993b009b4486 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -8,75 +8,54 @@ use alloc::vec::Vec; #[macro_use] extern crate runtime_support; -use runtime_support::{set_storage, storage, storage_into, print, Value20}; +use runtime_support::{set_storage, storage, storage_into}; -/* -use std::sync::{rc, RefCell, Once, ONCE_INIT}; -use std::mem; - -#[derive(Clone)] -struct SingletonReader { - inner: Rc>, +/// The hash of an ECDSA pub key which is used to identify an external transactor. +pub type AccountID = [u8; 32]; +/// The ECDSA pub key of an authority. This is what the external environment/consensus algorithm +/// refers to as a "authority". +pub type SessionKey = AccountID; +pub type Balance = u64; +pub type ChainID = u64; +pub type Hash = [u8; 32]; +pub type BlockNumber = u64; +pub type Timestamp = u64; +pub type TxOrder = u64; + +/// The functions that a transaction can call (and be dispatched to). +pub enum Function { + StakingStake(), + StakingUnstake(), + ConsensusSetSessionKey(SessionKey), } -fn singleton() -> SingletonReader { - // Initialize it to a null value - static mut SINGLETON: *const SingletonReader = 0 as *const SingletonReader; - static ONCE: Once = ONCE_INIT; - - unsafe { - ONCE.call_once(|| { - // Make it - let singleton = SingletonReader { - inner: Rc::new(RefCell::new(Default::default())), - }; - - // Put it in the heap so it can outlive this call - SINGLETON = mem::transmute(Box::new(singleton)); - }); - - // Now we give out a copy of the data that is safe to use concurrently. - (*SINGLETON).clone() - } +impl Function { + /// Dispatch the function. + pub fn dispatch(self) -> Vec { unimplemented!() } } -*/ -/// The hash of an ECDSA pub key which is used to identify an external transactor. -type AccountID = [u8; 32]; -/// The ECDSA pub key of an authority. This is what the external environment/consensus algorithm -/// refers to as a "authority". -type SessionKey = [u8; 65]; -type Balance = u64; -type ChainID = u64; -type Hash = [u8; 32]; -type BlockNumber = u64; -/// A proportion (rational number). -struct Proportion { nom: u64, denom: u64, }; -type Timestamp = u64; -type TxOrder = u64; - -struct Digest { - logs: Vec>, +pub struct Digest { + pub logs: Vec>, } -struct Header { - parent_hash: Hash, - number: BlockNumber, - state_root: Hash, - transaction_root: Hash, - digest: Digest, +pub struct Header { + pub parent_hash: Hash, + pub number: BlockNumber, + pub state_root: Hash, + pub transaction_root: Hash, + pub digest: Digest, } -struct Transaction { - senders: Vec, - function_name: String, - input_data: Vec, - nonce: TxOrder, +pub struct Transaction { + pub senders: Vec, + pub function: Function, + pub input_data: Vec, + pub nonce: TxOrder, } -struct Block { - header: Header, - transactions: Vec, +pub struct Block { + pub header: Header, + pub transactions: Vec, } impl Header { @@ -97,21 +76,58 @@ impl Block { } } +/* +use std::sync::{rc, RefCell, Once, ONCE_INIT}; +use std::mem; + +#[derive(Default)] +struct Environment { + header: Option
, + current_user: Option, +} + +#[derive(Clone)] +struct EnvironmentHolder { + inner: Rc>, +} + +fn get_environment() -> EnvironmentHolder { + // Initialize it to a null value + static mut SINGLETON: *const EnvironmentHolder = 0 as *const EnvironmentHolder; + static ONCE: Once = ONCE_INIT; + + unsafe { + ONCE.call_once(|| { + // Make it + let singleton = EnvironmentHolder { + inner: Rc::new(RefCell::new(Default::default())), + }; + + // Put it in the heap so it can outlive this call + SINGLETON = mem::transmute(Box::new(singleton)); + }); + + // Now we give out a copy of the data that is safe to use concurrently. + (*SINGLETON).clone() + } +} +*/ + // TODO: include RLP implementation // TODO: add keccak256 (or some better hashing scheme) & ECDSA-recover (or some better sig scheme) -impl_stub!(execute_block); fn execute_block(_input: Vec) -> Vec { let block = Block::from_rlp(&_input); environment::execute_block(&block) } -impl_stub!(execute_transaction); fn execute_transaction(_input: Vec) -> Vec { let tx = Transaction::from_rlp(&_input); environment::execute_transaction(&tx) } +impl_stubs!(execute_block, execute_transaction); + /// The current relay chain identifier. fn chain_id() -> ChainID { // TODO: retrieve from external @@ -119,6 +135,8 @@ fn chain_id() -> ChainID { } mod environment { + use super::*; + /// The current block number being processed. Set by `execute_block`. pub fn block_number() -> BlockNumber { unimplemented!() } @@ -163,6 +181,8 @@ mod environment { } mod consensus { + use super::*; + fn value_vec(mut value: usize, initial: Vec) -> Vec { let mut acc = initial; while value > 0 { @@ -177,11 +197,11 @@ mod consensus { } fn authority(index: usize) -> AccountID { - storage_into::(&value_vec(index, b"\0authority".to_vec())) + storage_into(&value_vec(index, b"\0authority".to_vec())).unwrap() } fn set_authority_count(count: usize) { - (count..authority_count()).for_each(|i| set_authority(i, &[])); + (count..authority_count()).for_each(|i| set_authority(i, SessionKey::default())); set_storage(b"\0authority_count", &value_vec(count, Vec::new())); } @@ -191,7 +211,7 @@ mod consensus { /// Get the current set of authorities. These are the session keys. pub fn authorities() -> Vec { - (0..authority_count()).into_iter().map(authority).map.collect() + (0..authority_count()).into_iter().map(authority).collect() } /// Set the current set of authorities' session keys. @@ -199,7 +219,7 @@ mod consensus { /// Called by `next_session` only. fn set_authorities(authorities: &[AccountID]) { set_authority_count(authorities.len()); - authorities.iter().enumerate().for_each(|(v, i)| set_authority(v, i)); + authorities.iter().enumerate().for_each(|(v, &i)| set_authority(v, i)); } /// Get the current set of validators. These are the long-term identifiers for the validators @@ -215,9 +235,6 @@ mod consensus { unimplemented!() } - /// Flush out any statistics. - pub fn flush_statistics() -> Statistics { unimplemented!() } - /// Sets the session key of `_validator` to `_session`. This doesn't take effect until the next /// session. pub fn set_session_key(_validator: AccountID, _session: AccountID) { @@ -240,6 +257,8 @@ mod consensus { } mod staking { + use super::*; + /// The length of a staking era in blocks. fn era_length() -> BlockNumber { unimplemented!() } @@ -252,12 +271,12 @@ mod staking { fn balance(_who: AccountID) -> Balance { unimplemented!() } /// Transfer some unlocked staking balance to another staker. - fn transfer_stake(_who: AccountID, dest: AccountID, value: Balance) { unimplemented!() } + fn transfer_stake(_who: AccountID, _dest: AccountID, _value: Balance) { unimplemented!() } /// Declare the desire to stake. /// /// Effects will be felt at the beginning of the next era. - fn stake(minimum_era_return: Proportion) { unimplemented!() } + fn stake() { unimplemented!() } /// Retract the desire to stake. /// @@ -266,23 +285,27 @@ mod staking { /// Hook to be called prior to transaction processing. pub fn pre_transactions() { - conensus::pre_transactions(); + consensus::pre_transactions(); } /// Hook to be called after to transaction processing. pub fn post_transactions() { // TODO: check block number and call next_era if necessary. - conensus::post_transactions(); + consensus::post_transactions(); } } mod authentication { - fn validate_signature(self, tx: Transaction) -> ( AccountID, TxOrder ); - fn nonce(self, id: AccountID) -> TxOrder; - fn authenticate(mut self, tx: Transaction) -> AccountID; + use super::*; + + fn validate_signature(_tx: Transaction) -> ( AccountID, TxOrder ) { unimplemented!() } + fn nonce(_id: AccountID) -> TxOrder { unimplemented!() } + fn authenticate(_tx: Transaction) -> AccountID { unimplemented!() } } mod timestamp { + use super::*; + fn timestamp() -> Timestamp { unimplemented!() } - fn set_timestamp(Timestamp) { unimplemented!() } + fn set_timestamp(_now: Timestamp) { unimplemented!() } } diff --git a/runtime/support/src/lib.rs b/runtime/support/src/lib.rs index 4430f7249faa6..3114446880012 100644 --- a/runtime/support/src/lib.rs +++ b/runtime/support/src/lib.rs @@ -3,9 +3,9 @@ #![cfg_attr(feature = "strict", deny(warnings))] #![feature(alloc)] - extern crate alloc; use alloc::vec::Vec; +use core::mem; extern crate pwasm_libc; extern crate pwasm_alloc; @@ -33,22 +33,18 @@ pub fn storage(key: &[u8]) -> Vec { } } -pub trait IsValue { - const value: usize; -} - -pub struct Value20; impl IsValue for Value20 { const value = 20usize; } -pub struct Value32; impl IsValue for Value32 { const value = 32usize; } -pub struct Value64; impl IsValue for Value64 { const value = 64usize; } -pub struct Value65; impl IsValue for Value65 { const value = 65usize; } - -pub fn storage_into(key: &[u8]) -> Option<[u8; T::value]> { - let mut result = [0u8; T::value]; - let written = unsafe { - ext_get_storage_into(&key[0], key.len() as u32, &result[0], result.len()) - }; +pub fn storage_into(key: &[u8]) -> Option { + let mut result: T; + let size = mem::size_of::(); + let mut written; + unsafe { + result = mem::uninitialized(); + let result_as_byte_blob = mem::transmute::<*mut T, *mut u8>(&mut result); + written = ext_get_storage_into(&key[0], key.len() as u32, result_as_byte_blob, size as u32) as usize; + } + // Only return a fully written value. match written { - T::value => Some(result), + size => Some(result), _ => None, } } @@ -93,18 +89,20 @@ pub fn print(value: T) { } #[macro_export] -macro_rules! impl_stub { - ($name:ident) => { +macro_rules! impl_stubs { + ( $( $name:ident ),* ) => { pub mod _internal { - #[no_mangle] - pub fn $name(input_data: *mut u8, input_len: usize) -> u64 { - let input = unsafe { - super::alloc::vec::Vec::from_raw_parts(input_data, input_len, input_len) - }; - - let output = super::$name(input); - &output[0] as *const u8 as u64 + ((output.len() as u64) << 32) - } + $( + #[no_mangle] + pub fn $name(input_data: *mut u8, input_len: usize) -> u64 { + let input = unsafe { + super::alloc::vec::Vec::from_raw_parts(input_data, input_len, input_len) + }; + + let output = super::$name(input); + &output[0] as *const u8 as u64 + ((output.len() as u64) << 32) + } + )* } } } diff --git a/runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm index 6ce8afb77ce2136b71e41d74bf115b4c8f918264..be2ae9b30e8d7d68992f083914c317bed5487e55 100644 GIT binary patch literal 218 zcmXwyTMmLS6h!B?r6Sb?!Uk|Bx(EMxc{M~R28!a3Y+dm2F_}5ZBnNrl5CDo*Mib`H zl!yc=P$F*As%-1!iCL#+%!_yZg_!$Gx4+ z!}0!T`$bPkp3ixHFH8z`D(LM!J9yo!Xz_}JQGYlV5ie*ne+Y|HJ37iz5hp?_p|v~^ zB95f!q+i9!UT<%I^jZl!?j4RdcecmdoBg3kJEJ48PkS%=!_A}NH~ry`$ddOy7#)1K zEh+M!=F%Uej3=b4SglRJUXUKFC{fFGC%nL@ioGPeTSp+>-CAup>ElXUW#~?+YVDK| z#w#BB*hgOR@A2g_uau8V;nliR2D)-w#l{P-R}~Cn7awEPHqid7Bg+X1!giYc%euV^ zYRQzEx)ei4mN9wK;6;`DHi=bLvVh(R%(tl=l(Kfdy`su8_O2APOc_>(=|=q)rKO&# zveiZlr(>-uqq~%!F8EVWIbGqV*v!(P6+nvCyz_EElfi8vd`{VT1Ro{%S~?&DZyH6P zGo;NQ00m$SjnAvZO2cx6(HQvHdWwD+k4r6JfDk}^)Y|^`Rmr{(4Gvf;cKEV)*$T%bsNbn+XnKxty z6^#1)k%IxR0%G2-stjDh3T?cVp>UYDgIf7w1G&vWa702m&X!DptvEi@0^uxpUm$5H5Z-KBAcz{` z>K=27HpwpkIoW5j8ykb`at0`jLm5;kgGx3jt`VZfxh}#W??ojqMY^3Vm7&UTG@uAP zHe8J0asW{ZB?nl5AixO-0<5djL~l+D;r|`^vZzpYS9KI8Y1Yb(EnK@icYf}|#rf{S zrOQ_qmwcx)Taed-|M&l;AZv?~II|#YRMbgzFZ1#37bnKhUj$d#z^7c@2?fGz+{H0K{$uato>`HDnLFGlXIkeq3t&#$-Zd()=%W*0 z&Tf0l_S%`i6m|*n08CRc+~aU5FfJ}A6_hsuI){BeY`WZe3~!#aN8_^%H&1gAt{5M) z;}ALeY5Ak&zgc3k=TRd%|r~^)0e8-?BR@9SKj6#Dd zd<2X+BA&X?UFJ*O?xH0iFKGc1oRC`xR`HrkkN_wN7EW9Shd_ju#l2*V*5(%J3dG1F z9dwpx5$x6Ggi9C#8t8_k;1=o!+zQj5AAE<;AL4tw9r*P?DVAO`xCBbOz@56ZUGCJS zoo_1mVpGo-LIvBork>B6kZ9*jfURRfK9z>9La%MegA^u&))^|n*@i>YV=gz;0cja( zgJgy{BB=>6N=(2U*99BHb-|}ZH(`v>O&AJv6FwkXXeOeyaBX}m_2jgpgcs6#yhZa4 zQ)tNijH)$1!BiEoF^zCW{B+QGl1U)RJn}_)+z(!dcNi7}MFb9ajPMZ`Zg_w3ODw#< z0Adaq6jT|R1jAA_1P=a!R}5*Re?%w*;Vztgol@7t{o%pUSdcgR+5S!sPcM`4l7_iu z(&i+0Z;1)9lFPxRV6{hvPKkOfV-P@@I{U%I`*R$V$3Fe(Jv1qLR T&JLgG3A7Ybp7PlGXgK~GM3S9O diff --git a/runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm b/runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm index 9fe583e7e40eeab56bf09d407ddd10c4e9070248..228d1aaf0c24cc037dfc52fcf4da91896ab05f32 100644 GIT binary patch literal 341 zcmYLE%Wi})3>+unnXSaCx1RWv?nmqySn5`&n}8tf<5GUT3AEy1duC*NY&4T00Q45s zw7>@~wOp1^gwH=UAkL9wdrSG@s?U)b2s97WG}mk2f_8yTJ3JwRpw|vIroZu~Y%^>o zc3#L*DU}d{pcD;2Bnii4$YR5$AD;p*{NQ$WTwT1$H=@^n?#9MWP3yYeB0i4u9pWC!?+9uuinwAu`P@trUUNV)^sE2+4B%~y5++sI&BIhO0 z12qT4nLD3>D;F+&gnj^yJ#yfPIPsf(wH>4XS?99&W&i>}luGl>qN+E>2k?hEc z*a;?+iJV}FKQ)0Mga8C%`D#Z9^@B`<-smLleN}Hi8~1ubFuTO;^IpBZyT5<%bhqy9 zZ6DPKyA$dOI`JtZ_YA)yvpB}z!G_=>~4TlFOf3xWgk9u{Z(qfgvaeq{cfY)d< zkJ;H)VUV>%6bmV(5@9G0g@^(vI>~2gJnRh*#xIpHb?>O&-rKErxBDZ}>Wq)UKIuL0 zkG79TU-n0PB4b_l%On_he=LjGk34>Rh<4}?U$msieqLyOCuKCDu#D8k^y>tLgEb{8 zxoL$H7?qKeWcI57q`P0KEh}AAhDK?+Q>ZGmN(k)~4_)K}r}+2ya$!p4qCz;eX_bbp ztjkC{;lg!=g|Ul^FluX9|Jjkngal!`klc%^y$)(f7cq4yf{iQ^auk9WW#-x>)>Xj* zdLuC3reaXY%DVQNDvHF}LeMIu(Du`f`7KI{cxuY4HdZ(tTa_u@rEIS7hoEArVW-%f zrryef6l^%_{05@k5&#ttr5=ktPWedWcNW00!I`KH$bX3+=xMyLTDOJ_zpx9F|kdVzR&tM0|dn zjtPPu_~Wuq3L}&pK(sDpx2!J~5O68|A}B|$qAUl9V2GpEO=WWi7yb|Y+4|Q8scgnbBZ>}F8?{%Ph~eY2G`{bP#F6% zC{YHbY*IW#h#Kd*2!p&A6s(GLo2g1)WjGp81Rh&9LU1{ND20LpEI<(87z6uY3RR|4Ttu1|@N3 zK~|`!S#_`S@y#c*#n4{_SJ}WNT-^xkNtM`TbLGs%wBLlQTT+uKoE-@&7MZYVD@w8W z$8a7M+`{lK`X(}$^QS~a3-gh7NccgSB4s%)xE&z<5QUCA1N{~RH8f42k_=`)z%1u3 zjsfx?dnfnIk}Q_F!;SJ(>%3+F%)ISgqZ~@_&44+(?X8+?X9AO(705j>O~r7J!==Eu zSZ|b5)(Gev_IbDIa_2F;IctyFrCWB979d>HE@Hu3?;>o^F-fabP%(nK-zIPLHqgPK@VpRZ%&8&vKBV9XJ5)P?OTU+QKbEdhB+OOW7% z+(MwmI+q{;P!cShxC{<~@GXmbNsZQKm+1<`$fD5Otk5#ptIY{lFa$KP^+~}k)D5^5 zCOw|G17>wyxeUedS(3bVwWx-ebt)P-4WD)?ek&lh|Jn}w#H&ugD(=d_2d zqkTRVny$jGt;vDp+K1L^D!`eBL(^j})6@ZJX=;O{nm8hf_A!dJ#~jxMFNW)aPl;~A z7@?am6zC>=K(x?Q1RMU^_*#aOc}MXtq_=pB<{hTckog%^h5Q6lWx$Jt2xq`ghY(LP z2_%_EzDO7H&%eW<3=|PK+%duhT)6)I#V;}c{sM>@WH3-gFdv5VVWeXy6sjR``zO3@ zDAeKi2#_G$kf&d?)YVacba-3~ayoo^u-C(bOsA~UFt>CveQ48Not^CN_wlwp7#|7T zZ8~Sg)3Vn>x1RM!{i82>d!?XXg--A&cLy)Pyb(GQ&8olgF=loGjYb!99$O!e>c0R6 CpR&{d diff --git a/runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 6ce8afb77ce2136b71e41d74bf115b4c8f918264..bac77de7ffc344d73e46f9c32657563efb790174 100644 GIT binary patch literal 3392 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 T&JLgG3A7Ybp7PlGXgK~GM3S9O diff --git a/runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm b/runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm index 9fe583e7e40eeab56bf09d407ddd10c4e9070248..9f8b8bc2e8ffe194480b62236bf55efa0870ed80 100644 GIT binary patch literal 3480 zcmcgv&2k&Z5$>6t{hisxQldmrq{!K|6U$CyBPoS)B|e~CrsN!4KIcTyA}j+ENEHdv z(IJK^0>pc$I)yyQ!{k&rDvEhm_UQR`sOi_{+r68;qgT_{NwcC%hTbINQRp-d^(&S96o=3 z^5k$jJUTd=o}3;&9g>puLe?i?k@V|{;pEASmz{(S62r;lDz!^zoj+KJ>M^5S%K zJf%o<^kj_HR0on;sk;P7e=8$7I(| z&oTUB_;hr9aDM#t==g}7$ckZQicT=7k|{Bym(0DWP4Ip#S5*9Uqxh3DGd)=Rd15oZ ztEpA{C3!-x(O!AQYTBAdrSiIooVILg-A4PRX44p_tPf)^qDDTSZPjH1;hH=YY3s>H zdm0L%-5d0JmPr18r&K(Hl6YZ&9$aBU3lV*nu&U@)AGnLbe4zat#Z^sZiifL_7{PVq@+PZ(uzAJ)oR zHf|y=8pQ<{kIDdg(Zql%bw-e5jUEsnG|F$0|7rAOz>PLNL+$?7BK2DBzl%3OvRQJ8q>KRErAeZ z0E8$-YS}-p=@K`85z|Y0)|ODheYSPNA90KWRhz{$^WEr zt=im|clDr7eGbEafRT`w^-jqptgVy9W>G%hhub6j5V(Jl9J~_{%$9+KxCi`XN^X|%0lM7^# z^`+1EwChX}kNp^5*|;vC2iE%T;LIoC;F9}etO^2#gfHqItX9=zZ>g zYL>$Bok4JzpgS~5%Bj1Av<$?-6{k%owS?f=Ivv2n%T71bFJRJ^djX@Y#KM zg8T3Y$O}ldAoQWIr{ocQZE#~`Ca4z!67;}h22qn_7pjy@57ePE{x@+CDPqKmqSK&| zpAn*#?W<|Xo@g{iIpS)h}sw9HhUO|C-+ff;GEDG^cmq^K?FlN z)OgSj8qDDK=7NBvloR7J_+%wp3>*j-Vl`psc`|4-NxCd#Nddl?rzbQbJ>lF+dIrft z(i2C02J?g0; z3!j5MF50}@1({avH*ow)offy&7fYR9U~#`*>I|uaHxIA5=tRgb@DASwXIJi5&P$x=(UCtoU@AyAQ_X7|Xl341E9mKP8?}vA2+~6S((Q<4td(V1{$Er!C zAyD=_e|Fem^_N(cG=|0hE1Ty0gq)G2e>1zBoLxfCFRY}Lcerlh)!pS9v+rGvP~q;Z zqQ1iwWbZB!x*GKzUW3#-3xq=aK$=noq=Hbn>vqJ8qMP7rkp3Aa@aSAe_igK)TvQ28 z{HR>#bxgj6+GoGq<{RiE5hBRmL>K7&NSx!HO1olYi#IThorV)!xqI}T>SAZY1^iac z%agnMl|m&Ww)KUFI!==aZSgH=*hSnyV_*w_#haLc$sj5r7LmD)89*bn15>sz+73H} zT63P_B`I(5Hm0`%4EOiTO}>NS?at2~bT?5Ipm38SL4tKjV_{44_m5xU-+$=aP(GrR zsN7Ad1}b->yT0pE4OH%WxW(?8R0EY;vn-ib+kh6T2uY~Q@-CXvvPa`=h#n|Uf>_uP zcRZIpj4~UbMTIm}3s4|-Hl`;hM?>Ou>^VH2esyv>n!Y6VwthW4cye-%9~j)X zcJ-$Pe`Mp)@r!e;d{5SNdVV0AiBLDXB%3aN^q@|$c5%dLct&`YY)@q0nEa7!{^jU+ UboSNos3Cr(Y>MAV{^VKnUuVwX;Q#;t literal 3130 zcmcguPj6dA5Z~SR*Kc>9pWC!?+9uuinwAu`P@trUUNV)^sE2+4B%~y5++sI&BIhO0 z12qT4nLD3>D;F+&gnj^yJ#yfPIPsf(wH>4XS?99&W&i>}luGl>qN+E>2k?hEc z*a;?+iJV}FKQ)0Mga8C%`D#Z9^@B`<-smLleN}Hi8~1ubFuTO;^IpBZyT5<%bhqy9 zZ6DPKyA$dOI`JtZ_YA)yvpB}z!G_=>~4TlFOf3xWgk9u{Z(qfgvaeq{cfY)d< zkJ;H)VUV>%6bmV(5@9G0g@^(vI>~2gJnRh*#xIpHb?>O&-rKErxBDZ}>Wq)UKIuL0 zkG79TU-n0PB4b_l%On_he=LjGk34>Rh<4}?U$msieqLyOCuKCDu#D8k^y>tLgEb{8 zxoL$H7?qKeWcI57q`P0KEh}AAhDK?+Q>ZGmN(k)~4_)K}r}+2ya$!p4qCz;eX_bbp ztjkC{;lg!=g|Ul^FluX9|Jjkngal!`klc%^y$)(f7cq4yf{iQ^auk9WW#-x>)>Xj* zdLuC3reaXY%DVQNDvHF}LeMIu(Du`f`7KI{cxuY4HdZ(tTa_u@rEIS7hoEArVW-%f zrryef6l^%_{05@k5&#ttr5=ktPWedWcNW00!I`KH$bX3+=xMyLTDOJ_zpx9F|kdVzR&tM0|dn zjtPPu_~Wuq3L}&pK(sDpx2!J~5O68|A}B|$qAUl9V2GpEO=WWi7yb|Y+4|Q8scgnbBZ>}F8?{%Ph~eY2G`{bP#F6% zC{YHbY*IW#h#Kd*2!p&A6s(GLo2g1)WjGp81Rh&9LU1{ND20LpEI<(87z6uY3RR|4Ttu1|@N3 zK~|`!S#_`S@y#c*#n4{_SJ}WNT-^xkNtM`TbLGs%wBLlQTT+uKoE-@&7MZYVD@w8W z$8a7M+`{lK`X(}$^QS~a3-gh7NccgSB4s%)xE&z<5QUCA1N{~RH8f42k_=`)z%1u3 zjsfx?dnfnIk}Q_F!;SJ(>%3+F%)ISgqZ~@_&44+(?X8+?X9AO(705j>O~r7J!==Eu zSZ|b5)(Gev_IbDIa_2F;IctyFrCWB979d>HE@Hu3?;>o^F-fabP%(nK-zIPLHqgPK@VpRZ%&8&vKBV9XJ5)P?OTU+QKbEdhB+OOW7% z+(MwmI+q{;P!cShxC{<~@GXmbNsZQKm+1<`$fD5Otk5#ptIY{lFa$KP^+~}k)D5^5 zCOw|G17>wyxeUedS(3bVwWx-ebt)P-4WD)?ek&lh|Jn}w#H&ugD(=d_2d zqkTRVny$jGt;vDp+K1L^D!`eBL(^j})6@ZJX=;O{nm8hf_A!dJ#~jxMFNW)aPl;~A z7@?am6zC>=K(x?Q1RMU^_*#aOc}MXtq_=pB<{hTckog%^h5Q6lWx$Jt2xq`ghY(LP z2_%_EzDO7H&%eW<3=|PK+%duhT)6)I#V;}c{sM>@WH3-gFdv5VVWeXy6sjR``zO3@ zDAeKi2#_G$kf&d?)YVacba-3~ayoo^u-C(bOsA~UFt>CveQ48Not^CN_wlwp7#|7T zZ8~Sg)3Vn>x1RM!{i82>d!?XXg--A&cLy)Pyb(GQ&8olgF=loGjYb!99$O!e>c0R6 CpR&{d diff --git a/runtime/test/src/lib.rs b/runtime/test/src/lib.rs index 550e06c05dd84..e95844fdb038b 100644 --- a/runtime/test/src/lib.rs +++ b/runtime/test/src/lib.rs @@ -53,7 +53,7 @@ pub fn set_authorities(authorities: &[&[u8]]) { authorities.iter().enumerate().for_each(|(v, i)| set_authority(v, i)); } -impl_stub!(test_data_in); +impl_stubs!(test_data_in); fn test_data_in(input: Vec) -> Vec { print(b"set_storage" as &[u8]); set_storage(b"input", &input); From 4e25b242e208da5c07e7f16ae76805d21edae713 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 9 Jan 2018 13:47:28 +0100 Subject: [PATCH 04/76] Compile polkadot-runtime both for Wasm ad native, allowing for testing and direct usage. --- Cargo.lock | 11 ++++++++ Cargo.toml | 3 ++- executor/src/wasm_executor.rs | 10 +++---- native-runtime/Cargo.toml | 12 +++++++++ native-runtime/src | 1 + native-runtime/support/Cargo.toml | 7 +++++ native-runtime/support/src/lib.rs | 10 +++++++ {runtime => wasm-runtime}/Cargo.lock | 0 {runtime => wasm-runtime}/Cargo.toml | 0 {runtime => wasm-runtime}/build.sh | 0 {runtime => wasm-runtime}/init.sh | 0 {runtime => wasm-runtime}/polkadot/Cargo.toml | 5 ++++ {runtime => wasm-runtime}/polkadot/src/lib.rs | 25 ++++++++++-------- .../pwasm-alloc/Cargo.toml | 0 .../pwasm-alloc/README.md | 0 .../pwasm-alloc/src/lib.rs | 0 .../pwasm-libc/Cargo.toml | 0 .../pwasm-libc/README.md | 0 .../pwasm-libc/src/lib.rs | 0 {runtime => wasm-runtime}/support/Cargo.toml | 0 {runtime => wasm-runtime}/support/src/lib.rs | 15 ++++++----- wasm-runtime/target/debug/.cargo-lock | 0 .../dep-lib-pwasm_libc-e72991cbfafd2b71 | Bin 0 -> 409 bytes .../lib-pwasm_libc-e72991cbfafd2b71 | 1 + .../lib-pwasm_libc-e72991cbfafd2b71.json | 1 + .../deps/libpwasm_libc-e72991cbfafd2b71.rlib | Bin 0 -> 10670 bytes ...023388293df7da5.crate.allocator.rust-cgu.o | Bin 0 -> 1636 bytes ...b023388293df7da5.crate.metadata.rust-cgu.o | Bin 0 -> 184 bytes .../debug/deps/pwasm_libc-b023388293df7da5.d | 5 ++++ ...bc-b023388293df7da5.pwasm_libc0.rust-cgu.o | Bin 0 -> 2568 bytes ...bc-b023388293df7da5.pwasm_libc1.rust-cgu.o | Bin 0 -> 4208 bytes wasm-runtime/target/debug/libpwasm_libc.rlib | Bin 0 -> 10670 bytes wasm-runtime/target/release/.cargo-lock | 0 .../release/.cargo-lock | 0 .../dep-lib-pwasm_alloc-e37006629c0ab425 | Bin 0 -> 342 bytes .../lib-pwasm_alloc-e37006629c0ab425 | 1 + .../lib-pwasm_alloc-e37006629c0ab425.json | 1 + .../dep-lib-pwasm_libc-9375d1aea6d3c98f | Bin 0 -> 337 bytes .../lib-pwasm_libc-9375d1aea6d3c98f | 1 + .../lib-pwasm_libc-9375d1aea6d3c98f.json | 1 + .../dep-lib-runtime_polkadot | Bin 0 -> 306 bytes .../lib-runtime_polkadot | 1 + .../lib-runtime_polkadot.json | 1 + .../dep-lib-runtime_support-5482fb51bf4d410e | Bin 0 -> 338 bytes .../lib-runtime_support-5482fb51bf4d410e | 1 + .../lib-runtime_support-5482fb51bf4d410e.json | 1 + .../dep-lib-runtime_test | Bin 0 -> 286 bytes .../lib-runtime_test | 1 + .../lib-runtime_test.json | 1 + .../deps/libpwasm_alloc-e37006629c0ab425.rlib | Bin 0 -> 13718 bytes .../deps/libpwasm_libc-9375d1aea6d3c98f.rlib | Bin 0 -> 6310 bytes .../libruntime_support-5482fb51bf4d410e.rlib | Bin 0 -> 12778 bytes .../release/deps}/runtime_polkadot.wasm | Bin .../release/deps}/runtime_test.wasm | Bin .../release/libpwasm_alloc.d | 1 + .../release/libpwasm_alloc.rlib | Bin 0 -> 13718 bytes .../release/libpwasm_libc.d | 1 + .../release/libpwasm_libc.rlib | Bin 0 -> 6310 bytes .../release/libruntime_support.d | 1 + .../release/libruntime_support.rlib | Bin 0 -> 12778 bytes .../release/runtime_polkadot.compact.wasm | Bin .../release/runtime_polkadot.d | 1 + .../release/runtime_polkadot.wasm | Bin 0 -> 341 bytes .../release/runtime_test.compact.wasm | Bin .../release/runtime_test.d | 1 + .../release/runtime_test.wasm | Bin 0 -> 3480 bytes {runtime => wasm-runtime}/test/Cargo.toml | 0 {runtime => wasm-runtime}/test/src/lib.rs | 0 68 files changed, 98 insertions(+), 23 deletions(-) create mode 100644 native-runtime/Cargo.toml create mode 120000 native-runtime/src create mode 100644 native-runtime/support/Cargo.toml create mode 100644 native-runtime/support/src/lib.rs rename {runtime => wasm-runtime}/Cargo.lock (100%) rename {runtime => wasm-runtime}/Cargo.toml (100%) rename {runtime => wasm-runtime}/build.sh (100%) rename {runtime => wasm-runtime}/init.sh (100%) rename {runtime => wasm-runtime}/polkadot/Cargo.toml (75%) rename {runtime => wasm-runtime}/polkadot/src/lib.rs (93%) rename {runtime => wasm-runtime}/pwasm-alloc/Cargo.toml (100%) rename {runtime => wasm-runtime}/pwasm-alloc/README.md (100%) rename {runtime => wasm-runtime}/pwasm-alloc/src/lib.rs (100%) rename {runtime => wasm-runtime}/pwasm-libc/Cargo.toml (100%) rename {runtime => wasm-runtime}/pwasm-libc/README.md (100%) rename {runtime => wasm-runtime}/pwasm-libc/src/lib.rs (100%) rename {runtime => wasm-runtime}/support/Cargo.toml (100%) rename {runtime => wasm-runtime}/support/src/lib.rs (92%) create mode 100644 wasm-runtime/target/debug/.cargo-lock create mode 100644 wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/dep-lib-pwasm_libc-e72991cbfafd2b71 create mode 100644 wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71 create mode 100644 wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71.json create mode 100644 wasm-runtime/target/debug/deps/libpwasm_libc-e72991cbfafd2b71.rlib create mode 100644 wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.crate.allocator.rust-cgu.o create mode 100644 wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.crate.metadata.rust-cgu.o create mode 100644 wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.d create mode 100644 wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.pwasm_libc0.rust-cgu.o create mode 100644 wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.pwasm_libc1.rust-cgu.o create mode 100644 wasm-runtime/target/debug/libpwasm_libc.rlib create mode 100644 wasm-runtime/target/release/.cargo-lock create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.cargo-lock create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/dep-lib-pwasm_alloc-e37006629c0ab425 create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425 create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425.json create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-libc-9375d1aea6d3c98f/dep-lib-pwasm_libc-9375d1aea6d3c98f create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-libc-9375d1aea6d3c98f/lib-pwasm_libc-9375d1aea6d3c98f create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-libc-9375d1aea6d3c98f/lib-pwasm_libc-9375d1aea6d3c98f.json create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/dep-lib-runtime_polkadot create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot.json create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/dep-lib-runtime_support-5482fb51bf4d410e create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e.json create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/dep-lib-runtime_test create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/lib-runtime_test create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/lib-runtime_test.json create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/deps/libpwasm_alloc-e37006629c0ab425.rlib create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/deps/libpwasm_libc-9375d1aea6d3c98f.rlib create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/deps/libruntime_support-5482fb51bf4d410e.rlib rename {runtime/target/wasm32-unknown-unknown/release => wasm-runtime/target/wasm32-unknown-unknown/release/deps}/runtime_polkadot.wasm (100%) rename {runtime/target/wasm32-unknown-unknown/release => wasm-runtime/target/wasm32-unknown-unknown/release/deps}/runtime_test.wasm (100%) create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_alloc.d create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_alloc.rlib create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_libc.d create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_libc.rlib create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.d create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.rlib rename {runtime => wasm-runtime}/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm (100%) create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.d create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm rename {runtime => wasm-runtime}/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm (100%) create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.d create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm rename {runtime => wasm-runtime}/test/Cargo.toml (100%) rename {runtime => wasm-runtime}/test/src/lib.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 15f526edd955d..61afee3c0abe2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -499,6 +499,13 @@ dependencies = [ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "native-runtime" +version = "0.1.0" +dependencies = [ + "runtime-support 0.1.0", +] + [[package]] name = "net2" version = "0.2.31" @@ -808,6 +815,10 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "runtime-support" +version = "0.1.0" + [[package]] name = "rustc-demangle" version = "0.1.5" diff --git a/Cargo.toml b/Cargo.toml index a0f6303a6782f..bfbff5696930c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,10 +16,11 @@ members = [ "primitives", "rpc", "rpc_servers", + "native-runtime", "serializer", "state_machine", "validator", ] exclude = [ - "runtime" + "wasm-runtime" ] diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index 4c3ed5b7916c6..ff4b1a31a269c 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -136,7 +136,7 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, } else { 0 } } else { 0 } }, - ext_deposit_log(_log_data: *const u8, _log_len: u32) { + ext_deposit_log(_log_data: *const u8, _log_len: u32) => { unimplemented!() } => <'e, E: Externalities + 'e> @@ -175,8 +175,8 @@ impl CodeExecutor for WasmExecutor { let returned = program .params_with_external("env", &mut fec) .map(|p| p - .add_argument(I32(offset as u32)) - .add_argument(I32(size as u32))) + .add_argument(I32(offset as i32)) + .add_argument(I32(size as i32))) .and_then(|p| module.execute_export(method, p)) .map_err(|_| -> Error { ErrorKind::Runtime.into() })?; @@ -233,8 +233,8 @@ mod tests { let returned = program .params_with_external("env", &mut fec) .map(|p| p - .add_argument(I32(offset as u32)) - .add_argument(I32(size as u32))) + .add_argument(I32(offset as i32)) + .add_argument(I32(size as i32))) .and_then(|p| module.execute_export("test_data_in", p)) .map_err(|_| -> Error { ErrorKind::Runtime.into() }).expect("function should be callable"); diff --git a/native-runtime/Cargo.toml b/native-runtime/Cargo.toml new file mode 100644 index 0000000000000..c971a6d694855 --- /dev/null +++ b/native-runtime/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "native-runtime" +version = "0.1.0" +authors = ["Parity Technologies "] + +[features] +default = ["with-std"] +with-std = [] +without-std = [] + +[dependencies] +runtime-support = { path = "./support", version = "0.1" } diff --git a/native-runtime/src b/native-runtime/src new file mode 120000 index 0000000000000..12e3333860cd6 --- /dev/null +++ b/native-runtime/src @@ -0,0 +1 @@ +../wasm-runtime/polkadot/src \ No newline at end of file diff --git a/native-runtime/support/Cargo.toml b/native-runtime/support/Cargo.toml new file mode 100644 index 0000000000000..b9c56adf24acd --- /dev/null +++ b/native-runtime/support/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "runtime-support" +version = "0.1.0" +authors = ["Parity Technologies "] + +[features] +strict = [] diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs new file mode 100644 index 0000000000000..b1c41f4821df1 --- /dev/null +++ b/native-runtime/support/src/lib.rs @@ -0,0 +1,10 @@ +pub use std::vec::Vec; + +pub fn storage(_key: &[u8]) -> Vec { vec![] } +pub fn storage_into(_key: &[u8]) -> Option { None } +pub fn set_storage(_key: &[u8], _value: &[u8]) {} + +#[macro_export] +macro_rules! impl_stubs { + ($( $name:ident ),*) => {} +} diff --git a/runtime/Cargo.lock b/wasm-runtime/Cargo.lock similarity index 100% rename from runtime/Cargo.lock rename to wasm-runtime/Cargo.lock diff --git a/runtime/Cargo.toml b/wasm-runtime/Cargo.toml similarity index 100% rename from runtime/Cargo.toml rename to wasm-runtime/Cargo.toml diff --git a/runtime/build.sh b/wasm-runtime/build.sh similarity index 100% rename from runtime/build.sh rename to wasm-runtime/build.sh diff --git a/runtime/init.sh b/wasm-runtime/init.sh similarity index 100% rename from runtime/init.sh rename to wasm-runtime/init.sh diff --git a/runtime/polkadot/Cargo.toml b/wasm-runtime/polkadot/Cargo.toml similarity index 75% rename from runtime/polkadot/Cargo.toml rename to wasm-runtime/polkadot/Cargo.toml index a313da2a1ef88..ce2d9909a7cde 100644 --- a/runtime/polkadot/Cargo.toml +++ b/wasm-runtime/polkadot/Cargo.toml @@ -8,3 +8,8 @@ crate-type = ["cdylib"] [dependencies] runtime-support = { path = "../support", version = "0.1" } + +[features] +default = ["without-std"] +with-std = [] +without-std = [] diff --git a/runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs similarity index 93% rename from runtime/polkadot/src/lib.rs rename to wasm-runtime/polkadot/src/lib.rs index 4993b009b4486..24529d4380afc 100644 --- a/runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -1,14 +1,9 @@ -#![no_std] -#![feature(lang_items)] +#![cfg_attr(feature = "without-std", no_std)] #![cfg_attr(feature = "strict", deny(warnings))] -#![feature(alloc)] -extern crate alloc; -use alloc::vec::Vec; - #[macro_use] extern crate runtime_support; -use runtime_support::{set_storage, storage, storage_into}; +use runtime_support::{set_storage, storage, storage_into, Vec}; /// The hash of an ECDSA pub key which is used to identify an external transactor. pub type AccountID = [u8; 32]; @@ -116,12 +111,12 @@ fn get_environment() -> EnvironmentHolder { // TODO: include RLP implementation // TODO: add keccak256 (or some better hashing scheme) & ECDSA-recover (or some better sig scheme) -fn execute_block(_input: Vec) -> Vec { +pub fn execute_block(_input: Vec) -> Vec { let block = Block::from_rlp(&_input); environment::execute_block(&block) } -fn execute_transaction(_input: Vec) -> Vec { +pub fn execute_transaction(_input: Vec) -> Vec { let tx = Transaction::from_rlp(&_input); environment::execute_transaction(&tx) } @@ -235,6 +230,11 @@ mod consensus { unimplemented!() } + /// The number of blocks in each session. + pub fn session_length() -> BlockNumber { + 10 + } + /// Sets the session key of `_validator` to `_session`. This doesn't take effect until the next /// session. pub fn set_session_key(_validator: AccountID, _session: AccountID) { @@ -260,11 +260,14 @@ mod staking { use super::*; /// The length of a staking era in blocks. - fn era_length() -> BlockNumber { unimplemented!() } + pub fn era_length() -> BlockNumber { sessions_per_era() * consensus::session_length() } + + /// The length of a staking era in sessions. + pub fn sessions_per_era() -> BlockNumber { 10 } /// The era has changed - enact new staking set. /// - /// NOTE: This is always a session change. + /// NOTE: This always happens on a session change. fn next_era() { unimplemented!() } /// The balance of a given account. diff --git a/runtime/pwasm-alloc/Cargo.toml b/wasm-runtime/pwasm-alloc/Cargo.toml similarity index 100% rename from runtime/pwasm-alloc/Cargo.toml rename to wasm-runtime/pwasm-alloc/Cargo.toml diff --git a/runtime/pwasm-alloc/README.md b/wasm-runtime/pwasm-alloc/README.md similarity index 100% rename from runtime/pwasm-alloc/README.md rename to wasm-runtime/pwasm-alloc/README.md diff --git a/runtime/pwasm-alloc/src/lib.rs b/wasm-runtime/pwasm-alloc/src/lib.rs similarity index 100% rename from runtime/pwasm-alloc/src/lib.rs rename to wasm-runtime/pwasm-alloc/src/lib.rs diff --git a/runtime/pwasm-libc/Cargo.toml b/wasm-runtime/pwasm-libc/Cargo.toml similarity index 100% rename from runtime/pwasm-libc/Cargo.toml rename to wasm-runtime/pwasm-libc/Cargo.toml diff --git a/runtime/pwasm-libc/README.md b/wasm-runtime/pwasm-libc/README.md similarity index 100% rename from runtime/pwasm-libc/README.md rename to wasm-runtime/pwasm-libc/README.md diff --git a/runtime/pwasm-libc/src/lib.rs b/wasm-runtime/pwasm-libc/src/lib.rs similarity index 100% rename from runtime/pwasm-libc/src/lib.rs rename to wasm-runtime/pwasm-libc/src/lib.rs diff --git a/runtime/support/Cargo.toml b/wasm-runtime/support/Cargo.toml similarity index 100% rename from runtime/support/Cargo.toml rename to wasm-runtime/support/Cargo.toml diff --git a/runtime/support/src/lib.rs b/wasm-runtime/support/src/lib.rs similarity index 92% rename from runtime/support/src/lib.rs rename to wasm-runtime/support/src/lib.rs index 3114446880012..aaab93e96034c 100644 --- a/runtime/support/src/lib.rs +++ b/wasm-runtime/support/src/lib.rs @@ -1,10 +1,12 @@ #![no_std] #![feature(lang_items)] +#![feature(alloc)] #![cfg_attr(feature = "strict", deny(warnings))] #![feature(alloc)] +//#[macro_use] extern crate alloc; -use alloc::vec::Vec; +pub use alloc::vec::Vec; use core::mem; extern crate pwasm_libc; @@ -36,16 +38,17 @@ pub fn storage(key: &[u8]) -> Vec { pub fn storage_into(key: &[u8]) -> Option { let mut result: T; let size = mem::size_of::(); - let mut written; + let written; unsafe { result = mem::uninitialized(); let result_as_byte_blob = mem::transmute::<*mut T, *mut u8>(&mut result); written = ext_get_storage_into(&key[0], key.len() as u32, result_as_byte_blob, size as u32) as usize; } // Only return a fully written value. - match written { - size => Some(result), - _ => None, + if written == size { + Some(result) + } else { + None } } @@ -96,7 +99,7 @@ macro_rules! impl_stubs { #[no_mangle] pub fn $name(input_data: *mut u8, input_len: usize) -> u64 { let input = unsafe { - super::alloc::vec::Vec::from_raw_parts(input_data, input_len, input_len) + $crate::Vec::from_raw_parts(input_data, input_len, input_len) }; let output = super::$name(input); diff --git a/wasm-runtime/target/debug/.cargo-lock b/wasm-runtime/target/debug/.cargo-lock new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/dep-lib-pwasm_libc-e72991cbfafd2b71 b/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/dep-lib-pwasm_libc-e72991cbfafd2b71 new file mode 100644 index 0000000000000000000000000000000000000000..92c61885d84f13585667714e922ac63d3e89ddd5 GIT binary patch literal 409 zcmchSJr2S!3`UuA3NDaZ?NYTXXJAJ8aifZsSawpbPr?d9nOLk(pX{e+xC*jBFb7;B zBT(G##>WItBfIAONb8OunJ98PLDP0J958`Ln?so-u&tIV@K%D;I1ba)JG+?04|eQ3 hF7t@n+wrH_FD?HUr>_sq>IKdJl!pKS literal 0 HcmV?d00001 diff --git a/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71 b/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71 new file mode 100644 index 0000000000000..cb6d43a3ff91e --- /dev/null +++ b/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71 @@ -0,0 +1 @@ +ba1707f874223553 \ No newline at end of file diff --git a/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71.json b/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71.json new file mode 100644 index 0000000000000..e73f9ca5d12bf --- /dev/null +++ b/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71.json @@ -0,0 +1 @@ +{"rustc":8291033049748019918,"features":"[]","target":14441046832906989149,"profile":731176819336294830,"deps":[],"local":[{"MtimeBased":[[1515500307,607755819],"/Users/gav/Core/polkadot/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/dep-lib-pwasm_libc-e72991cbfafd2b71"]}],"rustflags":[]} \ No newline at end of file diff --git a/wasm-runtime/target/debug/deps/libpwasm_libc-e72991cbfafd2b71.rlib b/wasm-runtime/target/debug/deps/libpwasm_libc-e72991cbfafd2b71.rlib new file mode 100644 index 0000000000000000000000000000000000000000..284e12e552798df2d3d6e5de9fd96601c0918b28 GIT binary patch literal 10670 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 Xk5~A7R5dzuyPJPu&DrP0@2>nGWWk?; literal 0 HcmV?d00001 diff --git a/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.crate.allocator.rust-cgu.o b/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.crate.allocator.rust-cgu.o new file mode 100644 index 0000000000000000000000000000000000000000..095c41adea2bd940449bc284431f91b9a03e463a GIT binary patch literal 1636 zcmcIku}&L75ZwbuSiy-6q%e{th(tkS6e=hvf*`^rL>6%oX*uk5Y{mGjJEK@m3KFG3 zG^RkJ;16ghDN<0<(YnY7KoNx!MG@i6-7FmE%ZY}O#&6!dx4UzzJD>gebv+=2(J%0W zBwVIq9Eli3p1W1}&n0;g4Mxqer=aX35g}z$wVGb-@%)=Y{*LQvj|?QdMNxHaC>lk@Eh2`)n-mTyYFS&!%Hgh>ETWY0fnA2&NanOB~+BTKL2=(jPRB zPJjO)^#z&A<*DS@ch~;dJh!tr5zlQePF%Ssbwba>B=pP_M*FQWS}7xy7>IZ9{2BBp zbN{?}LMC63Hiw*z(BDI!jL^S8Peh+0yAX|Al|v` zDvBf#jwvAVHRivW>vwjB{o}0D_eK6K=I@x}Y&X*Ef6W}!^*5NGFz+z0Gk?Xrgax!l z#{vpJj|KFl06z@)ivd0v@Y6Tz-@hB+-vS(eMAF`Ln$lKgt!5RaY892^xb2b(>ykOl z+S4PWWo_uKbV=<^$6T)|=~UZF%fS}eKG@bLS*^=P%`Dy;dz)l+Dt5L0vBw=?QvzWaMkn9zP|y+L^w1_nlE1|R{&Gk`RM0*GK>kOX2dAI!r|>_C$On#lmdATvQAKE5Qiq6ET* U@Izc9LJ)j(7P@&r`37V)06RttumAu6 literal 0 HcmV?d00001 diff --git a/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.d b/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.d new file mode 100644 index 0000000000000..4116414cae7b2 --- /dev/null +++ b/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.d @@ -0,0 +1,5 @@ +/Users/gav/Core/polkadot/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5: /Users/gav/Core/polkadot/wasm-runtime/pwasm-libc/src/lib.rs + +/Users/gav/Core/polkadot/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.d: /Users/gav/Core/polkadot/wasm-runtime/pwasm-libc/src/lib.rs + +/Users/gav/Core/polkadot/wasm-runtime/pwasm-libc/src/lib.rs: diff --git a/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.pwasm_libc0.rust-cgu.o b/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.pwasm_libc0.rust-cgu.o new file mode 100644 index 0000000000000000000000000000000000000000..43bde99ac7b005f8b8998304557aa557a927c94e GIT binary patch literal 2568 zcmbVO&2Jk;6rZ)zG;LaU3l%CNg*`yk3SxUUjz2&}F>%ly3Ti`B0#dcC*X!89U)|k= zf{*|e0T!ynffK5bxN+phflEXY>7k+*{)8fNDB^-d1cLB;vondkO-bNMZ{B+|@BQYz znR#p9{^OUw_cNv?83r&(eIEt`40;&+<%m#s9KN6cP?lmq$_6GQPSGUDwnOhq80nFH zVQ%rlwym`DQXxFr_Q$bE!gyEtkhE>L+X=P-ZF?ARQ94siL>~c9rW#GeM%%7=)s-bX z2z{|)+m)Bg^UrU2y&|%A`Vo{~A;+7-`h*mWPL7X`%o?WV+QNW2Z;4ffkOV`@owZ1qR8 zBM{^DW@YeYiT4`b9nrA^(RT{!(D{*Z96W(_YRwkpbx7>X&Vh-@hnTLK;D-QU?}Zku z{!iAmGvvzG`rrRd%B36i^pVHjCzXlyt9Nzln)pCi?rp2TZuM6-to{$y#|s-Gpxj@p z^w+Gb-|3fbh$swh3!P(}J$vy5{nmp+3mG_w3ef_Ii?-eo=82oFPYLuA4wh69>7H; zN?H=X5y>G5aAmk-ftf}>j+6a6{CO7gtklaj`6f#Izd`&1o!Z{!P&GJDiqd1SHu+1WPf>R=8pl z%*SyFQ~CVc-V}fGxv!s{?O(pD_NMY^J`EQ|1)SaJ8BX1NRB#&=V=s^ z_}}4#O_vuMwOXNAEKJqhlI!O4W^E4bb^o41K%GzXdeO{Hd4)VL<#JKLR1nroKjc~Z ftPnc%LZeXPrD}0H&ui1QVztWQ>wEQdma%^TH_UR6 literal 0 HcmV?d00001 diff --git a/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.pwasm_libc1.rust-cgu.o b/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.pwasm_libc1.rust-cgu.o new file mode 100644 index 0000000000000000000000000000000000000000..97cda093e5671de857e2df2707019da063a4a503 GIT binary patch literal 4208 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 Xk5~A7R5dzuyPJPu&DrP0@2>nGWWk?; literal 0 HcmV?d00001 diff --git a/wasm-runtime/target/release/.cargo-lock b/wasm-runtime/target/release/.cargo-lock new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.cargo-lock b/wasm-runtime/target/wasm32-unknown-unknown/release/.cargo-lock new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/dep-lib-pwasm_alloc-e37006629c0ab425 b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/dep-lib-pwasm_alloc-e37006629c0ab425 new file mode 100644 index 0000000000000000000000000000000000000000..a4da1cb1a4785e0602bfc1a4030bfe35b9ce362d GIT binary patch literal 342 zcmb`BK@Ng25Jg@06kecAQxqdx&fwY%?Sv3YOJ<5(U%|LjmlR)U(X??h22+3(GPsUW0 kJv)Q#!5#~K0QG)D^oD@2TdjgcslVrZZSkK&-Urs|4sPChY5)KL literal 0 HcmV?d00001 diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425 b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425 new file mode 100644 index 0000000000000..96fca0ffc7f22 --- /dev/null +++ b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425 @@ -0,0 +1 @@ +ee4d5b5400bf9619 \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425.json b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425.json new file mode 100644 index 0000000000000..c1764b5654c53 --- /dev/null +++ b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425.json @@ -0,0 +1 @@ +{"rustc":8294656847287967537,"features":"[]","target":1127969377865045195,"profile":42358739494345872,"deps":[["pwasm-libc v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/pwasm-libc)",6197225601014249845]],"local":[{"MtimeBased":[[1515500743,816953612],"/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/dep-lib-pwasm_alloc-e37006629c0ab425"]}],"rustflags":[]} \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-libc-9375d1aea6d3c98f/dep-lib-pwasm_libc-9375d1aea6d3c98f b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-libc-9375d1aea6d3c98f/dep-lib-pwasm_libc-9375d1aea6d3c98f new file mode 100644 index 0000000000000000000000000000000000000000..75ac0990e3be0ca9842cb7435c423e19f0ebb7d8 GIT binary patch literal 337 zcmb`BOAf*?3`AMy6kH&+AmY<*dj{6XB&MpGCXt=e>(hYP0b;?*BkPUk!AXb(I=n#} znIJ_!poEcl2zUt)9XV;v8NVm^`5nI7$M(zofEoUV_!NIqcj9 k3HQ#}`gpB)c{l3^p$h@Rwsa~MrT#AS&BT4wcx%_FJAK4?eEe)=y6?(|67Q literal 0 HcmV?d00001 diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot new file mode 100644 index 0000000000000..3e7282f285d57 --- /dev/null +++ b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot @@ -0,0 +1 @@ +d4940d6f62cf958e \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot.json b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot.json new file mode 100644 index 0000000000000..ae6a4a3c0f0f3 --- /dev/null +++ b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot.json @@ -0,0 +1 @@ +{"rustc":8294656847287967537,"features":"[\"default\", \"without-std\"]","target":15371597068611496627,"profile":42358739494345872,"deps":[["runtime-support v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/support)",2223771509741189442]],"local":[{"MtimeBased":[[1515501953,507863132],"/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/dep-lib-runtime_polkadot"]}],"rustflags":[]} \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/dep-lib-runtime_support-5482fb51bf4d410e b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/dep-lib-runtime_support-5482fb51bf4d410e new file mode 100644 index 0000000000000000000000000000000000000000..e910e84870e0c19cd1c4960302fa60875852926d GIT binary patch literal 338 zcmb`BF%H5o5Cp0H3O?W*366x)@&;;T<4Y99@mY5^`92^*1riigTkOti;3UWbgT2C$ z7$H%Ztfvf%m05F%d7N>}GF8;H~yIiMkqBDC% literal 0 HcmV?d00001 diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e new file mode 100644 index 0000000000000..c062c609744d2 --- /dev/null +++ b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e @@ -0,0 +1 @@ +42f9c1f3676cdc1e \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e.json b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e.json new file mode 100644 index 0000000000000..497c7e5b562ae --- /dev/null +++ b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e.json @@ -0,0 +1 @@ +{"rustc":8294656847287967537,"features":"[]","target":14982045766639954252,"profile":42358739494345872,"deps":[["pwasm-alloc v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/pwasm-alloc)",1843871105590971886],["pwasm-libc v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/pwasm-libc)",6197225601014249845]],"local":[{"MtimeBased":[[1515500954,752149165],"/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/dep-lib-runtime_support-5482fb51bf4d410e"]}],"rustflags":[]} \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/dep-lib-runtime_test b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/dep-lib-runtime_test new file mode 100644 index 0000000000000000000000000000000000000000..9aade611431b40cb99925f0fc1275d234f5704d1 GIT binary patch literal 286 zcmcJJF%E)26hy7}6kY%((T>(LP?L{4A%ta@{QrUL8=^MG!p3T*n3*?djcOQV!>uT> zlr%{!j$Lf7bj?1_JmHrVTy)^GdA(F?o^sjqTcJ!8BO({WYq)co*9WRO9~P!}q_MBn OLijH`~bx%98fF%rK-ZlO;==WwOiIrLwdrl~7Wt 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 literal 0 HcmV?d00001 diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/deps/libruntime_support-5482fb51bf4d410e.rlib b/wasm-runtime/target/wasm32-unknown-unknown/release/deps/libruntime_support-5482fb51bf4d410e.rlib new file mode 100644 index 0000000000000000000000000000000000000000..2e0626d0708f1edb9ac3677db1439b816a1e3eb1 GIT binary patch literal 12778 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 literal 0 HcmV?d00001 diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.d b/wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.d new file mode 100644 index 0000000000000..43fe058cb3888 --- /dev/null +++ b/wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.d @@ -0,0 +1 @@ +/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.rlib: /Users/gav/Core/polkadot/wasm-runtime/pwasm-libc/src/lib.rs /Users/gav/Core/polkadot/wasm-runtime/support/src/lib.rs /Users/gav/Core/polkadot/wasm-runtime/pwasm-alloc/src/lib.rs diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.rlib b/wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.rlib new file mode 100644 index 0000000000000000000000000000000000000000..2e0626d0708f1edb9ac3677db1439b816a1e3eb1 GIT binary patch literal 12778 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 UboSNos3Cr(Y>MAV{^VKnUuVwX;Q#;t literal 0 HcmV?d00001 diff --git a/runtime/test/Cargo.toml b/wasm-runtime/test/Cargo.toml similarity index 100% rename from runtime/test/Cargo.toml rename to wasm-runtime/test/Cargo.toml diff --git a/runtime/test/src/lib.rs b/wasm-runtime/test/src/lib.rs similarity index 100% rename from runtime/test/src/lib.rs rename to wasm-runtime/test/src/lib.rs From b28402c9a8875cf3b7f25664c1382a22760f17df Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 9 Jan 2018 15:05:41 +0100 Subject: [PATCH 05/76] More fleshing out on runtime. --- wasm-runtime/polkadot/src/lib.rs | 93 ++++++++++-------- wasm-runtime/support/src/lib.rs | 11 ++- .../lib-runtime_polkadot | 2 +- .../lib-runtime_polkadot.json | 2 +- .../lib-runtime_support-5482fb51bf4d410e | 2 +- .../lib-runtime_support-5482fb51bf4d410e.json | 2 +- .../lib-runtime_test | 2 +- .../lib-runtime_test.json | 2 +- .../libruntime_support-5482fb51bf4d410e.rlib | Bin 12778 -> 13160 bytes .../release/libpwasm_alloc.d | 2 +- .../release/libruntime_support.d | 2 +- .../release/libruntime_support.rlib | Bin 12778 -> 13160 bytes .../release/runtime_polkadot.d | 2 +- .../release/runtime_test.d | 2 +- 14 files changed, 68 insertions(+), 56 deletions(-) diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 24529d4380afc..fb8e5b86f882b 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -3,7 +3,8 @@ #[macro_use] extern crate runtime_support; -use runtime_support::{set_storage, storage, storage_into, Vec}; +use runtime_support::{set_storage, storage, storage_into, Vec, size_of}; +use runtime_support::{Rc, RefCell, transmute, Box}; /// The hash of an ECDSA pub key which is used to identify an external transactor. pub type AccountID = [u8; 32]; @@ -19,20 +20,36 @@ pub type TxOrder = u64; /// The functions that a transaction can call (and be dispatched to). pub enum Function { - StakingStake(), - StakingUnstake(), - ConsensusSetSessionKey(SessionKey), + StakingStake, + StakingUnstake, + ConsensusSetSessionKey, } impl Function { /// Dispatch the function. - pub fn dispatch(self) -> Vec { unimplemented!() } + pub fn dispatch(&self, transactor: &AccountID, params: &[u8]) { + match *self { + Function::StakingStake => { + staking::stake(transactor); + } + Function::StakingUnstake => { + staking::unstake(transactor); + } + Function::ConsensusSetSessionKey => { + let mut session = AccountID::default(); + session.copy_from_slice(¶ms[0..size_of::()]); + consensus::set_session_key(transactor, session); + } + } + } } +#[derive(Clone)] pub struct Digest { pub logs: Vec>, } +#[derive(Clone)] pub struct Header { pub parent_hash: Hash, pub number: BlockNumber, @@ -42,7 +59,7 @@ pub struct Header { } pub struct Transaction { - pub senders: Vec, + pub signed: AccountID, pub function: Function, pub input_data: Vec, pub nonce: TxOrder, @@ -71,42 +88,28 @@ impl Block { } } -/* -use std::sync::{rc, RefCell, Once, ONCE_INIT}; -use std::mem; - #[derive(Default)] struct Environment { - header: Option
, - current_user: Option, + block_number: BlockNumber, } -#[derive(Clone)] -struct EnvironmentHolder { - inner: Rc>, -} - -fn get_environment() -> EnvironmentHolder { +fn env() -> Rc> { // Initialize it to a null value - static mut SINGLETON: *const EnvironmentHolder = 0 as *const EnvironmentHolder; - static ONCE: Once = ONCE_INIT; + static mut SINGLETON: *const Rc> = 0 as *const Rc>; unsafe { - ONCE.call_once(|| { + if SINGLETON == 0 as *const Rc> { // Make it - let singleton = EnvironmentHolder { - inner: Rc::new(RefCell::new(Default::default())), - }; + let singleton: Rc> = Rc::new(RefCell::new(Default::default())); // Put it in the heap so it can outlive this call - SINGLETON = mem::transmute(Box::new(singleton)); - }); + SINGLETON = transmute(Box::new(singleton)); + } // Now we give out a copy of the data that is safe to use concurrently. (*SINGLETON).clone() } } -*/ // TODO: include RLP implementation // TODO: add keccak256 (or some better hashing scheme) & ECDSA-recover (or some better sig scheme) @@ -133,20 +136,26 @@ mod environment { use super::*; /// The current block number being processed. Set by `execute_block`. - pub fn block_number() -> BlockNumber { unimplemented!() } + pub fn block_number() -> BlockNumber { let e = env(); let eb = e.borrow(); eb.block_number } /// Get the block hash of a given block. pub fn block_hash(_number: BlockNumber) -> Hash { unimplemented!() } - /// Get the current user's ID - pub fn current_user() -> AccountID { unimplemented!() } - pub fn execute_block(_block: &Block) -> Vec { - // TODO: populate environment from header. + // populate environment from header. + { + let e = env(); + e.borrow_mut().block_number = _block.header.number; + } + staking::pre_transactions(); + // TODO: go through each transaction and use execute_transaction to execute. + staking::post_transactions(); + // TODO: ensure digest in header is what we expect from transactions. + Vec::new() } @@ -156,9 +165,9 @@ mod environment { // TODO: ensure signature valid and recover id (use authentication::authenticate) // TODO: ensure target_function valid // TODO: decode parameters - // TODO: set `current_user` to the id - // TODO: make call - // TODO: reset `current_user` + + _tx.function.dispatch(&_tx.signed, &_tx.input_data); + // TODO: encode any return Vec::new() } @@ -235,9 +244,9 @@ mod consensus { 10 } - /// Sets the session key of `_validator` to `_session`. This doesn't take effect until the next + /// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next /// session. - pub fn set_session_key(_validator: AccountID, _session: AccountID) { + pub fn set_session_key(_transactor: &AccountID, _session: AccountID) { unimplemented!() } @@ -274,17 +283,17 @@ mod staking { fn balance(_who: AccountID) -> Balance { unimplemented!() } /// Transfer some unlocked staking balance to another staker. - fn transfer_stake(_who: AccountID, _dest: AccountID, _value: Balance) { unimplemented!() } + pub fn transfer_stake(_transactor: AccountID, _dest: AccountID, _value: Balance) { unimplemented!() } - /// Declare the desire to stake. + /// Declare the desire to stake for the transactor. /// /// Effects will be felt at the beginning of the next era. - fn stake() { unimplemented!() } + pub fn stake(_transactor: &AccountID) { unimplemented!() } - /// Retract the desire to stake. + /// Retract the desire to stake for the transactor. /// /// Effects will be felt at the beginning of the next era. - fn unstake() { unimplemented!() } + pub fn unstake(_transactor: &AccountID) { unimplemented!() } /// Hook to be called prior to transaction processing. pub fn pre_transactions() { diff --git a/wasm-runtime/support/src/lib.rs b/wasm-runtime/support/src/lib.rs index aaab93e96034c..3acad5237e35b 100644 --- a/wasm-runtime/support/src/lib.rs +++ b/wasm-runtime/support/src/lib.rs @@ -7,7 +7,10 @@ //#[macro_use] extern crate alloc; pub use alloc::vec::Vec; -use core::mem; +pub use alloc::boxed::Box; +pub use alloc::rc::Rc; +pub use core::mem::{transmute, size_of, uninitialized}; +pub use core::cell::{RefCell, Ref, RefMut}; extern crate pwasm_libc; extern crate pwasm_alloc; @@ -37,11 +40,11 @@ pub fn storage(key: &[u8]) -> Vec { pub fn storage_into(key: &[u8]) -> Option { let mut result: T; - let size = mem::size_of::(); + let size = size_of::(); let written; unsafe { - result = mem::uninitialized(); - let result_as_byte_blob = mem::transmute::<*mut T, *mut u8>(&mut result); + result = uninitialized(); + let result_as_byte_blob = transmute::<*mut T, *mut u8>(&mut result); written = ext_get_storage_into(&key[0], key.len() as u32, result_as_byte_blob, size as u32) as usize; } // Only return a fully written value. diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot index 3e7282f285d57..77c1ca366703a 100644 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot +++ b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot @@ -1 +1 @@ -d4940d6f62cf958e \ No newline at end of file +6eee55b59b574864 \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot.json b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot.json index ae6a4a3c0f0f3..39174c4da4e33 100644 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot.json +++ b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot.json @@ -1 +1 @@ -{"rustc":8294656847287967537,"features":"[\"default\", \"without-std\"]","target":15371597068611496627,"profile":42358739494345872,"deps":[["runtime-support v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/support)",2223771509741189442]],"local":[{"MtimeBased":[[1515501953,507863132],"/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/dep-lib-runtime_polkadot"]}],"rustflags":[]} \ No newline at end of file +{"rustc":8294656847287967537,"features":"[\"default\", \"without-std\"]","target":15371597068611496627,"profile":42358739494345872,"deps":[["runtime-support v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/support)",18014962227880213226]],"local":[{"MtimeBased":[[1515506687,785085370],"/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/dep-lib-runtime_polkadot"]}],"rustflags":[]} \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e index c062c609744d2..7d69f929721a2 100644 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e +++ b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e @@ -1 +1 @@ -42f9c1f3676cdc1e \ No newline at end of file +ea3ae1eab20002fa \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e.json b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e.json index 497c7e5b562ae..1e4859a996d00 100644 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e.json +++ b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e.json @@ -1 +1 @@ -{"rustc":8294656847287967537,"features":"[]","target":14982045766639954252,"profile":42358739494345872,"deps":[["pwasm-alloc v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/pwasm-alloc)",1843871105590971886],["pwasm-libc v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/pwasm-libc)",6197225601014249845]],"local":[{"MtimeBased":[[1515500954,752149165],"/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/dep-lib-runtime_support-5482fb51bf4d410e"]}],"rustflags":[]} \ No newline at end of file +{"rustc":8294656847287967537,"features":"[]","target":14982045766639954252,"profile":42358739494345872,"deps":[["pwasm-alloc v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/pwasm-alloc)",1843871105590971886],["pwasm-libc v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/pwasm-libc)",6197225601014249845]],"local":[{"MtimeBased":[[1515504344,57881737],"/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/dep-lib-runtime_support-5482fb51bf4d410e"]}],"rustflags":[]} \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/lib-runtime_test b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/lib-runtime_test index dc062b33e3c34..fb66643a9214f 100644 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/lib-runtime_test +++ b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/lib-runtime_test @@ -1 +1 @@ -9cf830998a9aef5e \ No newline at end of file +0caae204cc6f3f45 \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/lib-runtime_test.json b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/lib-runtime_test.json index 6040d1fe18564..1003d6c5db697 100644 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/lib-runtime_test.json +++ b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/lib-runtime_test.json @@ -1 +1 @@ -{"rustc":8294656847287967537,"features":"[]","target":11385551307513482501,"profile":42358739494345872,"deps":[["runtime-support v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/support)",2223771509741189442]],"local":[{"MtimeBased":[[1515500955,389693545],"/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/dep-lib-runtime_test"]}],"rustflags":[]} \ No newline at end of file +{"rustc":8294656847287967537,"features":"[]","target":11385551307513482501,"profile":42358739494345872,"deps":[["runtime-support v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/support)",18014962227880213226]],"local":[{"MtimeBased":[[1515504344,719487568],"/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/dep-lib-runtime_test"]}],"rustflags":[]} \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/deps/libruntime_support-5482fb51bf4d410e.rlib b/wasm-runtime/target/wasm32-unknown-unknown/release/deps/libruntime_support-5482fb51bf4d410e.rlib index 2e0626d0708f1edb9ac3677db1439b816a1e3eb1..c74a5505236b2abd831d543c288f99ad02138b74 100644 GIT binary patch delta 6273 zcmZu!2|Sct)W7$6X3T0Ch8YG$g-8k|)tgGIH}#fQ(S-0S`w}7}rBap{R8*E|vn5+u zQI^!d+6PqQp1RrkTmft%Ts19`Oz)K-=7_gMjhc?*PTn7-@_+Jb4n$F~FDq(@dTu{kz3?_j3bKo+L|Xd>j$^dU)G8 zJ0hJhSV3*6Jc&*8IRDqfM?-o1cG=_T>EYwz%Xjr~29QmKo6!ttn6@2&YD8m-utULH zFec2u&~qWCJPf|AJl}fs#rWxX*fE&-A-;d4Qd4y3&Cxr#)omVQt=AH6SJi!c3*)aG z6LtvW4rv@M9(voIQupc*6!zR37^rLPx&adh8=6jLylz`QI&?>rQ9XpPCQ@T>e*P!r zVibJcl~5lskyLjJhCQrnm`ts&obs+;FYVgLs=Ovz``h-?i(#pwhVQRLJk6_(JhQSk zer!A}ujh?t=1BbA6NAGa4i{LkBQOC^8E`P5prWLz$fCQrdAg!)@w4|)0_xy2E1fOv z=kDU};_G7P>T(=0XT^#;!{X8Pdj%P2fmXVisvx=G%f{_@QXO4 zxqI;4kcX=y(L|_c@C=*@SdsyRG_Dz`3y&fR*Kzd~I@ka(A(Tdu3t~vwBqlf^{J=F7 zR&tfNEo>2+Ac+lWjwZ6nC7mP-2e`}Chz`1l4d|^10YTupDyTb({DI5_k-s2#gjK7O z2z?0~3B*ToyA%^dAsbEMV`UcSzacPXS%lFkb&A3S(ZUT}4U|XV0Uk#YPE}c;-O7e! zbZQWw5z!VwE)L=;!&D|vkSq)Uc!hF>A{3}7njEDaqft?Y|M$c9IR;|GTr#|W3__p? zhy*|&Y#fYG)0s@bhM-wl*r=i^NT4Oqhy<-incS>=QiX|MrxQrz(Bi5eiqpE+Kfkd1#z!+zcG423k6ftEn13(!~ ziS$L>qatPis1UOh8v`KV5&+5&sEiXf_)n$``x&WBGTI+5x@Q1Jkpkp!=1C?QlL!WJ91Z zh-9K*S@ioT=fq_k1Ftnes}h(%)#jH%KxokZpnRZUX!-xoY9u-`S}humC?O!5hBo8p z_ckFz$+w%3amkkm4@i!sqc27BMY9EJh#Hl}g$NA>07F3i#D$P3S*K`1VnM_)Kq+rW zA3s-LN$EkeYvDl>aY>1b5J{q-_Z$i_4>c2 zX!?ILDn~?NlDP21rARD;-=Y8@SR(0v*$|~dEGJAu`oj_#9U77QVm-1aGW?f4k@;d7 z03xM+sfq0SB@<~UmeJCF<_xj-;-f~10K~^3{62N6-7ptj6abEAKOzL4?SKphFu&wT-Yugd`!< zRMh04A_c&yQ1oB{=(&d$A%>DiRv%@CWmQUagbOrh+mz`1hQ!fgLA>mcEEA{@;%{H% zh)R<9ha|w!Bct3vW8nazdm9pQibhL7cPmm74~h}lyK<@tio!dZ(_9i1|L*{ia@BH7 zqF?}?7?GGW4{+3fV-g!kKsL*@$o=1|oV?%8)z1-YR{n`7O$N1c;VdRlBho~;eww=A zB&w!pF2wbXVV~r_$pH)(Gjt+oAP7Ing|Sd>6HL5!Cq%?%}LTE3;ncankIfP>wOt<{#YYS?CVH6n(}X}L2XC=)1)uL zW_z?SbOVkV0BB3(4XA}MTv`e@{HAVTVnX~&Mlv*6Fh@w$-XMsSQ~{8)HE6rlHu;of zQN>cGiB^uu{0Ng!rG%%aLP@dn4d&{$A0JQ>QE1dKMV|V|jjq0x@^05yE{-`xsjcsd z%QD;YWJQUmR%A5jD(MY9wf@_x!TM9d)1gw^tf1L9%f1))Onwgb*YfFWYVzo7>K%!i{$|9+hkhv-P5d7&#ZW0FYF&b}slXWwwl z&C2eEwGUqEUj+Z?^x-*o{h!=fwp$y!zU18PCpR_~S}hdh-#v50+~M-e7dD1r%%OW- zF}sa+D5#Wj;=<&|&U`U-G4L~WH+thqx~ONVzx&1`!~90uajkgh%01#c7U0-Z?aO&yQ-3;kD zJg}Ko$vxm^v^rkU-oI*q;lFz6VpGwF7@yVN^||UZpBgIPoI5AghFY$=aI2;M79G+Uw>b&%Q0+)CaBuD5*OHzNSm|BGdp)5 zkKY(+X+A6N%(2p!_t!Xm+vpxCT01p_?WyKj*uKJgcYBu9R>7hX4Y>|Q=bMwJN!RLZ zzi|eWzExLenYz_y`LSH*u6@De`qZ8$b2jMhCX z_OI2bNIeyvJ!1GeG20@mf;#Ifa zI`9pCv}uXCQ`Z84Nw&ac-rvCk*-wX6Ne8;l`b7u68q?M-FJA6Z^kB=*Xp`;bMe!xY zJ$j}Ui+`xpJfFizht-_UF_yI_dCM~G#@V0i%ol!LP48cMY@+wN@j}hA$oj@Bj!Coc zmj98P9pckmv3%CEZ&KxHZaan^ES>QCM~`n{=8_OSbI<7mdp0nwB}!*4@iLr?}?GbL-yJx7+?~ zdzYTk9X9>_QRxkdizhs7XWCcI(zn}8Udv#_aV;$MvO;d$xYB9O-&3$vBzT(P6wldb z7(e6Mt^OH~76}V0T!+FY`5A$QMF)B=H8e*R6?zv33G8$S4_Y0n#P_}oi+!`a`-dBQ zrQCX3WsgJNhZ7gT38u>BZ(EM!HfFVukL0dccR8b7clkiKb*7=7eQ4UNir%|A zM;{GbrEj)?WZY!I%)G|mX`)}yCXbs$p4JT)UV3+0vX-N zR{uanqY|glgImp38Z6KJGdOy`Ony|{>{ZG411q*TR9=uVv206B%G@Q(OFna-IU1aE zlAEHGc&Pks{f53snabP4X?PoXS;cT{LkHv5%-&dyZddu(K!$$g!G&|?r5f+fTzzt{ zXIlL-TKciGtChcf7oE#LwK&#<_HylPftK?hfwf5k`K!Xh55x&N)j4{WZG~~Fr$Zn4 z$g~eVD9|=@?4nwbKBh$sL>IIK7YjBRAAVHhG|Z|Q8?DN(HH&fk8t5vOXV~Ge&Lzb4 z_119D`nt!5UzHep;d6G4Ke99W&ha`Bys*jADl5d!`Doa!X)({(^;M#vrCE5}@m&JH z_D5cW)!hg8EYDx0dnrnN)0s2>&d}LxdTB{k}+sDS1hdNu` zrkywGbLFWg**#i?k2YQZ8uPELhML!nov(sN6vp(DhPq_TOW!-G=B}w6H}$%_iOWwA zxit;0Z)987ol803#*g@3^S(c7qPm1W(PM0~rFzN^P0i7VLRo#&5WU$c?C`qP4@dly zIfCSmWgE_W7+;#UvSe;hnU06m=L${lXDLSy4zIme=%aCSET%kdUcs7;&SM|*V$Oe` z>T+-NUgFi03uAWGNAv{lSm`!1z@ahSve|r}ynoXCwG+J+k={>YCP}J))E@lNw!ve6 zQO*U8MXjcOZO=-p<01>+G{^|7&sU~<{@CZ-ShiI#JGti0m#@|`i!DYMO@>_AR<)BO zFk7;CV&rUKmuzDH)kpqn6W8|gYjc%lZ;Xx4c9T7y*WIl+dMwW-%j{&}x&Y~_3I5Sz zA!Ze0WW4VU~MogOupZY(oEQ5|!j<1Mve*VqE*fGY#)w(SDZqD$Bkb4gmp3(LX zJU#e)Ky#-cSv@ED%lg`JtG(N7Zs`ebp0|_kWXBc$ya3VPn;ah9d-#2z g%l1xrS+n-_Z9GOzKnw5wyc_5IPh8k8Gf4vf0~2h($ delta 5976 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 delta 5976 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 Date: Tue, 9 Jan 2018 15:07:55 +0100 Subject: [PATCH 06/76] Update native support. --- native-runtime/support/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index b1c41f4821df1..93d3aad9cde3e 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -1,4 +1,8 @@ pub use std::vec::Vec; +pub use std::rc::Rc; +pub use std::cell::RefCell; +pub use std::boxed::Box; +pub use std::mem::{size_of, transmute}; pub fn storage(_key: &[u8]) -> Vec { vec![] } pub fn storage_into(_key: &[u8]) -> Option { None } From 9a4360ff02d62e63101f7bbd508b1e209efc5b70 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 9 Jan 2018 15:50:48 +0100 Subject: [PATCH 07/76] Fix warning. --- executor/src/wasm_executor.rs | 2 +- executor/src/wasm_utils.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index ff4b1a31a269c..5de36f7d23453 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -137,7 +137,7 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, } else { 0 } }, ext_deposit_log(_log_data: *const u8, _log_len: u32) => { - unimplemented!() + // TODO } => <'e, E: Externalities + 'e> ); diff --git a/executor/src/wasm_utils.rs b/executor/src/wasm_utils.rs index 577e6ab0b23d6..6d4fedfedbc94 100644 --- a/executor/src/wasm_utils.rs +++ b/executor/src/wasm_utils.rs @@ -75,13 +75,13 @@ macro_rules! reverse_params { #[macro_export] macro_rules! marshall { - ( $context:ident, $self:ident, ( $( $names:ident : $params:ty ),* ) -> $returns:ty => $body:tt ) => ({ - let r : <$returns as $crate::wasm_utils::ConvertibleToWasm>::NativeType = reverse_params!($body, $self, $context, $( $names : $params ),*); - Ok(Some({ use $crate::wasm_utils::ConvertibleToWasm; r.to_runtime_value() })) - }); ( $context:ident, $self:ident, ( $( $names:ident : $params:ty ),* ) => $body:tt ) => ({ reverse_params!($body, $self, $context, $( $names : $params ),*); Ok(None) + }); + ( $context:ident, $self:ident, ( $( $names:ident : $params:ty ),* ) -> $returns:ty => $body:tt ) => ({ + let r : <$returns as $crate::wasm_utils::ConvertibleToWasm>::NativeType = reverse_params!($body, $self, $context, $( $names : $params ),*); + Ok(Some({ use $crate::wasm_utils::ConvertibleToWasm; r.to_runtime_value() })) }) } From 0890e729587aff5ade2946b399d7080e7ca11259 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 9 Jan 2018 15:58:17 +0100 Subject: [PATCH 08/76] Update gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index cd789637f93b0..c7a3830779c4f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ /target/ **/*.rs.bk *.swp -runtime/**/target/ +wasm-runtime/**/target/ **/._* From 4cf5fd1f51ef453909b80015798e07a40ce409d7 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 9 Jan 2018 15:58:45 +0100 Subject: [PATCH 09/76] Update path. --- executor/src/wasm_executor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index 5de36f7d23453..f7b9c1e9e33d2 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -217,7 +217,7 @@ mod tests { let program = ProgramInstance::new().unwrap(); - let test_module = include_bytes!("../../runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); + let test_module = include_bytes!("../../runtime-wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); let module = deserialize_buffer(test_module.to_vec()).expect("Failed to load module"); let module = program.add_module_by_sigs("test", module, map!["env" => FunctionExecutor::::SIGNATURES]).expect("Failed to initialize module"); From 12b15fd14dcab9715b4bd5d0c2cd6dff59390d8b Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 9 Jan 2018 15:59:05 +0100 Subject: [PATCH 10/76] Fix path. --- executor/src/wasm_executor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index f7b9c1e9e33d2..e0d47de267af4 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -217,7 +217,7 @@ mod tests { let program = ProgramInstance::new().unwrap(); - let test_module = include_bytes!("../../runtime-wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); + let test_module = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); let module = deserialize_buffer(test_module.to_vec()).expect("Failed to load module"); let module = program.add_module_by_sigs("test", module, map!["env" => FunctionExecutor::::SIGNATURES]).expect("Failed to initialize module"); From 47260c232070240167acb4d3ab17a1f97027c854 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 9 Jan 2018 16:00:39 +0100 Subject: [PATCH 11/76] Remove accidentally committed files. --- wasm-runtime/target/debug/.cargo-lock | 0 .../dep-lib-pwasm_libc-e72991cbfafd2b71 | Bin 409 -> 0 bytes .../lib-pwasm_libc-e72991cbfafd2b71 | 1 - .../lib-pwasm_libc-e72991cbfafd2b71.json | 1 - .../deps/libpwasm_libc-e72991cbfafd2b71.rlib | Bin 10670 -> 0 bytes ...-b023388293df7da5.crate.allocator.rust-cgu.o | Bin 1636 -> 0 bytes ...c-b023388293df7da5.crate.metadata.rust-cgu.o | Bin 184 -> 0 bytes .../debug/deps/pwasm_libc-b023388293df7da5.d | 5 ----- ...libc-b023388293df7da5.pwasm_libc0.rust-cgu.o | Bin 2568 -> 0 bytes ...libc-b023388293df7da5.pwasm_libc1.rust-cgu.o | Bin 4208 -> 0 bytes wasm-runtime/target/debug/libpwasm_libc.rlib | Bin 10670 -> 0 bytes wasm-runtime/target/release/.cargo-lock | 0 .../wasm32-unknown-unknown/release/.cargo-lock | 0 .../dep-lib-pwasm_alloc-e37006629c0ab425 | Bin 342 -> 0 bytes .../lib-pwasm_alloc-e37006629c0ab425 | 1 - .../lib-pwasm_alloc-e37006629c0ab425.json | 1 - .../dep-lib-pwasm_libc-9375d1aea6d3c98f | Bin 337 -> 0 bytes .../lib-pwasm_libc-9375d1aea6d3c98f | 1 - .../lib-pwasm_libc-9375d1aea6d3c98f.json | 1 - .../dep-lib-runtime_polkadot | Bin 306 -> 0 bytes .../lib-runtime_polkadot | 1 - .../lib-runtime_polkadot.json | 1 - .../dep-lib-runtime_support-5482fb51bf4d410e | Bin 338 -> 0 bytes .../lib-runtime_support-5482fb51bf4d410e | 1 - .../lib-runtime_support-5482fb51bf4d410e.json | 1 - .../dep-lib-runtime_test | Bin 286 -> 0 bytes .../lib-runtime_test | 1 - .../lib-runtime_test.json | 1 - .../deps/libpwasm_alloc-e37006629c0ab425.rlib | Bin 13718 -> 0 bytes .../deps/libpwasm_libc-9375d1aea6d3c98f.rlib | Bin 6310 -> 0 bytes .../libruntime_support-5482fb51bf4d410e.rlib | Bin 13160 -> 0 bytes .../release/deps/runtime_polkadot.wasm | Bin 341 -> 0 bytes .../release/deps/runtime_test.wasm | Bin 3480 -> 0 bytes .../release/libpwasm_alloc.d | 1 - .../release/libpwasm_alloc.rlib | Bin 13718 -> 0 bytes .../release/libpwasm_libc.d | 1 - .../release/libpwasm_libc.rlib | Bin 6310 -> 0 bytes .../release/libruntime_support.d | 1 - .../release/libruntime_support.rlib | Bin 13160 -> 0 bytes .../release/runtime_polkadot.compact.wasm | Bin 218 -> 0 bytes .../release/runtime_polkadot.d | 1 - .../release/runtime_polkadot.wasm | Bin 341 -> 0 bytes .../release/runtime_test.compact.wasm | Bin 3392 -> 0 bytes .../release/runtime_test.d | 1 - .../release/runtime_test.wasm | Bin 3480 -> 0 bytes 45 files changed, 22 deletions(-) delete mode 100644 wasm-runtime/target/debug/.cargo-lock delete mode 100644 wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/dep-lib-pwasm_libc-e72991cbfafd2b71 delete mode 100644 wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71 delete mode 100644 wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71.json delete mode 100644 wasm-runtime/target/debug/deps/libpwasm_libc-e72991cbfafd2b71.rlib delete mode 100644 wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.crate.allocator.rust-cgu.o delete mode 100644 wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.crate.metadata.rust-cgu.o delete mode 100644 wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.d delete mode 100644 wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.pwasm_libc0.rust-cgu.o delete mode 100644 wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.pwasm_libc1.rust-cgu.o delete mode 100644 wasm-runtime/target/debug/libpwasm_libc.rlib delete mode 100644 wasm-runtime/target/release/.cargo-lock delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.cargo-lock delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/dep-lib-pwasm_alloc-e37006629c0ab425 delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425 delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425.json delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-libc-9375d1aea6d3c98f/dep-lib-pwasm_libc-9375d1aea6d3c98f delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-libc-9375d1aea6d3c98f/lib-pwasm_libc-9375d1aea6d3c98f delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-libc-9375d1aea6d3c98f/lib-pwasm_libc-9375d1aea6d3c98f.json delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/dep-lib-runtime_polkadot delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot.json delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/dep-lib-runtime_support-5482fb51bf4d410e delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e.json delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/dep-lib-runtime_test delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/lib-runtime_test delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/lib-runtime_test.json delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/deps/libpwasm_alloc-e37006629c0ab425.rlib delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/deps/libpwasm_libc-9375d1aea6d3c98f.rlib delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/deps/libruntime_support-5482fb51bf4d410e.rlib delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/deps/runtime_polkadot.wasm delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/deps/runtime_test.wasm delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_alloc.d delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_alloc.rlib delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_libc.d delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_libc.rlib delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.d delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.rlib delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.d delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.d delete mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm diff --git a/wasm-runtime/target/debug/.cargo-lock b/wasm-runtime/target/debug/.cargo-lock deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/dep-lib-pwasm_libc-e72991cbfafd2b71 b/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/dep-lib-pwasm_libc-e72991cbfafd2b71 deleted file mode 100644 index 92c61885d84f13585667714e922ac63d3e89ddd5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 409 zcmchSJr2S!3`UuA3NDaZ?NYTXXJAJ8aifZsSawpbPr?d9nOLk(pX{e+xC*jBFb7;B zBT(G##>WItBfIAONb8OunJ98PLDP0J958`Ln?so-u&tIV@K%D;I1ba)JG+?04|eQ3 hF7t@n+wrH_FD?HUr>_sq>IKdJl!pKS diff --git a/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71 b/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71 deleted file mode 100644 index cb6d43a3ff91e..0000000000000 --- a/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71 +++ /dev/null @@ -1 +0,0 @@ -ba1707f874223553 \ No newline at end of file diff --git a/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71.json b/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71.json deleted file mode 100644 index e73f9ca5d12bf..0000000000000 --- a/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/lib-pwasm_libc-e72991cbfafd2b71.json +++ /dev/null @@ -1 +0,0 @@ -{"rustc":8291033049748019918,"features":"[]","target":14441046832906989149,"profile":731176819336294830,"deps":[],"local":[{"MtimeBased":[[1515500307,607755819],"/Users/gav/Core/polkadot/wasm-runtime/target/debug/.fingerprint/pwasm-libc-e72991cbfafd2b71/dep-lib-pwasm_libc-e72991cbfafd2b71"]}],"rustflags":[]} \ No newline at end of file diff --git a/wasm-runtime/target/debug/deps/libpwasm_libc-e72991cbfafd2b71.rlib b/wasm-runtime/target/debug/deps/libpwasm_libc-e72991cbfafd2b71.rlib deleted file mode 100644 index 284e12e552798df2d3d6e5de9fd96601c0918b28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10670 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 Xk5~A7R5dzuyPJPu&DrP0@2>nGWWk?; diff --git a/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.crate.allocator.rust-cgu.o b/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.crate.allocator.rust-cgu.o deleted file mode 100644 index 095c41adea2bd940449bc284431f91b9a03e463a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1636 zcmcIku}&L75ZwbuSiy-6q%e{th(tkS6e=hvf*`^rL>6%oX*uk5Y{mGjJEK@m3KFG3 zG^RkJ;16ghDN<0<(YnY7KoNx!MG@i6-7FmE%ZY}O#&6!dx4UzzJD>gebv+=2(J%0W zBwVIq9Eli3p1W1}&n0;g4Mxqer=aX35g}z$wVGb-@%)=Y{*LQvj|?QdMNxHaC>lk@Eh2`)n-mTyYFS&!%Hgh>ETWY0fnA2&NanOB~+BTKL2=(jPRB zPJjO)^#z&A<*DS@ch~;dJh!tr5zlQePF%Ssbwba>B=pP_M*FQWS}7xy7>IZ9{2BBp zbN{?}LMC63Hiw*z(BDI!jL^S8Peh+0yAX|Al|v` zDvBf#jwvAVHRivW>vwjB{o}0D_eK6K=I@x}Y&X*Ef6W}!^*5NGFz+z0Gk?Xrgax!l z#{vpJj|KFl06z@)ivd0v@Y6Tz-@hB+-vS(eMAF`Ln$lKgt!5RaY892^xb2b(>ykOl z+S4PWWo_uKbV=<^$6T)|=~UZF%fS}eKG@bLS*^=P%`Dy;dz)l+Dt5L0vBw=?QvzWaMkn9zP|y+L^w1_nlE1|R{&Gk`RM0*GK>kOX2dAI!r|>_C$On#lmdATvQAKE5Qiq6ET* U@Izc9LJ)j(7P@&r`37V)06RttumAu6 diff --git a/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.d b/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.d deleted file mode 100644 index 4116414cae7b2..0000000000000 --- a/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.d +++ /dev/null @@ -1,5 +0,0 @@ -/Users/gav/Core/polkadot/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5: /Users/gav/Core/polkadot/wasm-runtime/pwasm-libc/src/lib.rs - -/Users/gav/Core/polkadot/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.d: /Users/gav/Core/polkadot/wasm-runtime/pwasm-libc/src/lib.rs - -/Users/gav/Core/polkadot/wasm-runtime/pwasm-libc/src/lib.rs: diff --git a/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.pwasm_libc0.rust-cgu.o b/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.pwasm_libc0.rust-cgu.o deleted file mode 100644 index 43bde99ac7b005f8b8998304557aa557a927c94e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2568 zcmbVO&2Jk;6rZ)zG;LaU3l%CNg*`yk3SxUUjz2&}F>%ly3Ti`B0#dcC*X!89U)|k= zf{*|e0T!ynffK5bxN+phflEXY>7k+*{)8fNDB^-d1cLB;vondkO-bNMZ{B+|@BQYz znR#p9{^OUw_cNv?83r&(eIEt`40;&+<%m#s9KN6cP?lmq$_6GQPSGUDwnOhq80nFH zVQ%rlwym`DQXxFr_Q$bE!gyEtkhE>L+X=P-ZF?ARQ94siL>~c9rW#GeM%%7=)s-bX z2z{|)+m)Bg^UrU2y&|%A`Vo{~A;+7-`h*mWPL7X`%o?WV+QNW2Z;4ffkOV`@owZ1qR8 zBM{^DW@YeYiT4`b9nrA^(RT{!(D{*Z96W(_YRwkpbx7>X&Vh-@hnTLK;D-QU?}Zku z{!iAmGvvzG`rrRd%B36i^pVHjCzXlyt9Nzln)pCi?rp2TZuM6-to{$y#|s-Gpxj@p z^w+Gb-|3fbh$swh3!P(}J$vy5{nmp+3mG_w3ef_Ii?-eo=82oFPYLuA4wh69>7H; zN?H=X5y>G5aAmk-ftf}>j+6a6{CO7gtklaj`6f#Izd`&1o!Z{!P&GJDiqd1SHu+1WPf>R=8pl z%*SyFQ~CVc-V}fGxv!s{?O(pD_NMY^J`EQ|1)SaJ8BX1NRB#&=V=s^ z_}}4#O_vuMwOXNAEKJqhlI!O4W^E4bb^o41K%GzXdeO{Hd4)VL<#JKLR1nroKjc~Z ftPnc%LZeXPrD}0H&ui1QVztWQ>wEQdma%^TH_UR6 diff --git a/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.pwasm_libc1.rust-cgu.o b/wasm-runtime/target/debug/deps/pwasm_libc-b023388293df7da5.pwasm_libc1.rust-cgu.o deleted file mode 100644 index 97cda093e5671de857e2df2707019da063a4a503..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4208 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 Xk5~A7R5dzuyPJPu&DrP0@2>nGWWk?; diff --git a/wasm-runtime/target/release/.cargo-lock b/wasm-runtime/target/release/.cargo-lock deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.cargo-lock b/wasm-runtime/target/wasm32-unknown-unknown/release/.cargo-lock deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/dep-lib-pwasm_alloc-e37006629c0ab425 b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/dep-lib-pwasm_alloc-e37006629c0ab425 deleted file mode 100644 index a4da1cb1a4785e0602bfc1a4030bfe35b9ce362d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 342 zcmb`BK@Ng25Jg@06kecAQxqdx&fwY%?Sv3YOJ<5(U%|LjmlR)U(X??h22+3(GPsUW0 kJv)Q#!5#~K0QG)D^oD@2TdjgcslVrZZSkK&-Urs|4sPChY5)KL diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425 b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425 deleted file mode 100644 index 96fca0ffc7f22..0000000000000 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425 +++ /dev/null @@ -1 +0,0 @@ -ee4d5b5400bf9619 \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425.json b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425.json deleted file mode 100644 index c1764b5654c53..0000000000000 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/lib-pwasm_alloc-e37006629c0ab425.json +++ /dev/null @@ -1 +0,0 @@ -{"rustc":8294656847287967537,"features":"[]","target":1127969377865045195,"profile":42358739494345872,"deps":[["pwasm-libc v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/pwasm-libc)",6197225601014249845]],"local":[{"MtimeBased":[[1515500743,816953612],"/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-alloc-e37006629c0ab425/dep-lib-pwasm_alloc-e37006629c0ab425"]}],"rustflags":[]} \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-libc-9375d1aea6d3c98f/dep-lib-pwasm_libc-9375d1aea6d3c98f b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/pwasm-libc-9375d1aea6d3c98f/dep-lib-pwasm_libc-9375d1aea6d3c98f deleted file mode 100644 index 75ac0990e3be0ca9842cb7435c423e19f0ebb7d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 337 zcmb`BOAf*?3`AMy6kH&+AmY<*dj{6XB&MpGCXt=e>(hYP0b;?*BkPUk!AXb(I=n#} znIJ_!poEcl2zUt)9XV;v8NVm^`5nI7$M(zofEoUV_!NIqcj9 k3HQ#}`gpB)c{l3^p$h@Rwsa~MrT#AS&BT4wcx%_FJAK4?eEe)=y6?(|67Q diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot deleted file mode 100644 index 77c1ca366703a..0000000000000 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot +++ /dev/null @@ -1 +0,0 @@ -6eee55b59b574864 \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot.json b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot.json deleted file mode 100644 index 39174c4da4e33..0000000000000 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/lib-runtime_polkadot.json +++ /dev/null @@ -1 +0,0 @@ -{"rustc":8294656847287967537,"features":"[\"default\", \"without-std\"]","target":15371597068611496627,"profile":42358739494345872,"deps":[["runtime-support v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/support)",18014962227880213226]],"local":[{"MtimeBased":[[1515506687,785085370],"/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-polkadot-1e4c8740d04ba868/dep-lib-runtime_polkadot"]}],"rustflags":[]} \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/dep-lib-runtime_support-5482fb51bf4d410e b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/dep-lib-runtime_support-5482fb51bf4d410e deleted file mode 100644 index e910e84870e0c19cd1c4960302fa60875852926d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 338 zcmb`BF%H5o5Cp0H3O?W*366x)@&;;T<4Y99@mY5^`92^*1riigTkOti;3UWbgT2C$ z7$H%Ztfvf%m05F%d7N>}GF8;H~yIiMkqBDC% diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e deleted file mode 100644 index 7d69f929721a2..0000000000000 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e +++ /dev/null @@ -1 +0,0 @@ -ea3ae1eab20002fa \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e.json b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e.json deleted file mode 100644 index 1e4859a996d00..0000000000000 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/lib-runtime_support-5482fb51bf4d410e.json +++ /dev/null @@ -1 +0,0 @@ -{"rustc":8294656847287967537,"features":"[]","target":14982045766639954252,"profile":42358739494345872,"deps":[["pwasm-alloc v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/pwasm-alloc)",1843871105590971886],["pwasm-libc v0.1.0 (file:///Users/gav/Core/polkadot/wasm-runtime/pwasm-libc)",6197225601014249845]],"local":[{"MtimeBased":[[1515504344,57881737],"/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-support-5482fb51bf4d410e/dep-lib-runtime_support-5482fb51bf4d410e"]}],"rustflags":[]} \ No newline at end of file diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/dep-lib-runtime_test b/wasm-runtime/target/wasm32-unknown-unknown/release/.fingerprint/runtime-test-0ee9f37942e84b82/dep-lib-runtime_test deleted file mode 100644 index 9aade611431b40cb99925f0fc1275d234f5704d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 286 zcmcJJF%E)26hy7}6kY%((T>(LP?L{4A%ta@{QrUL8=^MG!p3T*n3*?djcOQV!>uT> zlr%{!j$Lf7bj?1_JmHrVTy)^GdA(F?o^sjqTcJ!8BO({WYq)co*9WRO9~P!}q_MBn OLijH`~bx%98fF%rK-ZlO;==WwOiIrLwdrl~7Wt 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 diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/deps/libruntime_support-5482fb51bf4d410e.rlib b/wasm-runtime/target/wasm32-unknown-unknown/release/deps/libruntime_support-5482fb51bf4d410e.rlib deleted file mode 100644 index c74a5505236b2abd831d543c288f99ad02138b74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13160 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
    HR$IqRQ-~NdMd_~>}hj^GH`OEk}jvxFLe4Nh1 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 diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/deps/runtime_polkadot.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/deps/runtime_polkadot.wasm deleted file mode 100644 index 228d1aaf0c24cc037dfc52fcf4da91896ab05f32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 341 zcmYLE%Wi})3>+unnXSaCx1RWv?nmqySn5`&n}8tf<5GUT3AEy1duC*NY&4T00Q45s zw7>@~wOp1^gwH=UAkL9wdrSG@s?U)b2s97WG}mk2f_8yTJ3JwRpw|vIroZu~Y%^>o zc3#L*DU}d{pcD;2Bnii4$YR5$AD;p*{NQ$WTwT1$H=@^n?#9MWP3yYeB0i4u6t{hisxQldmrq{!K|6U$CyBPoS)B|e~CrsN!4KIcTyA}j+ENEHdv z(IJK^0>pc$I)yyQ!{k&rDvEhm_UQR`sOi_{+r68;qgT_{NwcC%hTbINQRp-d^(&S96o=3 z^5k$jJUTd=o}3;&9g>puLe?i?k@V|{;pEASmz{(S62r;lDz!^zoj+KJ>M^5S%K zJf%o<^kj_HR0on;sk;P7e=8$7I(| z&oTUB_;hr9aDM#t==g}7$ckZQicT=7k|{Bym(0DWP4Ip#S5*9Uqxh3DGd)=Rd15oZ ztEpA{C3!-x(O!AQYTBAdrSiIooVILg-A4PRX44p_tPf)^qDDTSZPjH1;hH=YY3s>H zdm0L%-5d0JmPr18r&K(Hl6YZ&9$aBU3lV*nu&U@)AGnLbe4zat#Z^sZiifL_7{PVq@+PZ(uzAJ)oR zHf|y=8pQ<{kIDdg(Zql%bw-e5jUEsnG|F$0|7rAOz>PLNL+$?7BK2DBzl%3OvRQJ8q>KRErAeZ z0E8$-YS}-p=@K`85z|Y0)|ODheYSPNA90KWRhz{$^WEr zt=im|clDr7eGbEafRT`w^-jqptgVy9W>G%hhub6j5V(Jl9J~_{%$9+KxCi`XN^X|%0lM7^# z^`+1EwChX}kNp^5*|;vC2iE%T;LIoC;F9}etO^2#gfHqItX9=zZ>g zYL>$Bok4JzpgS~5%Bj1Av<$?-6{k%owS?f=Ivv2n%T71bFJRJ^djX@Y#KM zg8T3Y$O}ldAoQWIr{ocQZE#~`Ca4z!67;}h22qn_7pjy@57ePE{x@+CDPqKmqSK&| zpAn*#?W<|Xo@g{iIpS)h}sw9HhUO|C-+ff;GEDG^cmq^K?FlN z)OgSj8qDDK=7NBvloR7J_+%wp3>*j-Vl`psc`|4-NxCd#Nddl?rzbQbJ>lF+dIrft z(i2C02J?g0; z3!j5MF50}@1({avH*ow)offy&7fYR9U~#`*>I|uaHxIA5=tRgb@DASwXIJi5&P$x=(UCtoU@AyAQ_X7|Xl341E9mKP8?}vA2+~6S((Q<4td(V1{$Er!C zAyD=_e|Fem^_N(cG=|0hE1Ty0gq)G2e>1zBoLxfCFRY}Lcerlh)!pS9v+rGvP~q;Z zqQ1iwWbZB!x*GKzUW3#-3xq=aK$=noq=Hbn>vqJ8qMP7rkp3Aa@aSAe_igK)TvQ28 z{HR>#bxgj6+GoGq<{RiE5hBRmL>K7&NSx!HO1olYi#IThorV)!xqI}T>SAZY1^iac z%agnMl|m&Ww)KUFI!==aZSgH=*hSnyV_*w_#haLc$sj5r7LmD)89*bn15>sz+73H} zT63P_B`I(5Hm0`%4EOiTO}>NS?at2~bT?5Ipm38SL4tKjV_{44_m5xU-+$=aP(GrR zsN7Ad1}b->yT0pE4OH%WxW(?8R0EY;vn-ib+kh6T2uY~Q@-CXvvPa`=h#n|Uf>_uP zcRZIpj4~UbMTIm}3s4|-Hl`;hM?>Ou>^VH2esyv>n!Y6VwthW4cye-%9~j)X zcJ-$Pe`Mp)@r!e;d{5SNdVV0AiBLDXB%3aN^q@|$c5%dLct&`YY)@q0nEa7!{^jU+ UboSNos3Cr(Y>MAV{^VKnUuVwX;Q#;t diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_alloc.d b/wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_alloc.d deleted file mode 100644 index 4bcb36f4252a8..0000000000000 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_alloc.d +++ /dev/null @@ -1 +0,0 @@ -/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_alloc.rlib: /Users/gav/Core/polkadot/wasm-runtime/pwasm-libc/src/lib.rs /Users/gav/Core/polkadot/wasm-runtime/pwasm-alloc/src/lib.rs diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_alloc.rlib b/wasm-runtime/target/wasm32-unknown-unknown/release/libpwasm_alloc.rlib deleted file mode 100644 index e3eb1a92d763dab9d4914d81a7146b0aafa6be2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13718 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 diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.d b/wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.d deleted file mode 100644 index 6ea9ca2b932a9..0000000000000 --- a/wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.d +++ /dev/null @@ -1 +0,0 @@ -/Users/gav/Core/polkadot/wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.rlib: /Users/gav/Core/polkadot/wasm-runtime/pwasm-alloc/src/lib.rs /Users/gav/Core/polkadot/wasm-runtime/pwasm-libc/src/lib.rs /Users/gav/Core/polkadot/wasm-runtime/support/src/lib.rs diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.rlib b/wasm-runtime/target/wasm32-unknown-unknown/release/libruntime_support.rlib deleted file mode 100644 index c74a5505236b2abd831d543c288f99ad02138b74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13160 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
      HR$IqRQ-~NdMd_~>}hj^GH`OEk}jvxFLe4Nh1 z_q!-PzL&3mkc3EFk=${7bgttESs=kuJj!DcItUMiNRj>&Ci+t(B-mRlkrMDH^MiZ? zMIK^8n;U+k$DcTnj}Df2_17OXQ3rle_N#_p;j#P;d@Di$O8b#%NCUe66$jw*hWkG( z2N`6=AI%>oTgDfl-iZQHAKd(W1BqUs7H;o&rXJEgOlQEy`=rN5+{2&8@+VE=8w(L) z11jUtdjlj+%`~uCE<+BoeMD{ne$HazvJS_fVT+f`l#|QA-bfc6K9Kl>-vpbW<%0h$ z&i~7E49RFmVPFJ`Z@bV^eu9b?`s*VXRB}*xiHbQ&|5l@N1eG&rDLSLn?0=$j2+6iY zJH&2O22ojt^x&c14C%u8E08?dzx{cZGJYLzEYuJ3UE}K);`_bM{8I9;d-I<72AJ7% zH#=_MyB5RRyQl7C|GE8^E1J$IOB*xkw12=X>FL!)tR3BAg#GzL9N zNnLB;^!=V`@;*o9yu`=P=Cr&hE;(@fq-<+us(pU_IOXwucb2Z2U%&Ky(Vf1FD+v0e{$ygKA&m5s|7QsI={6*o`M zJ2QXcsp_m4JGVpKUCV`0?7qwQQ(TOfD5zajNsE#n%=**P%P`2&*Z8SFdH;AveV5ZW zgr^!-d>)++y?HT`Q5&WnTQ)`V?ZYHU?7e)p4*t5-Dc9v5B9vfF60@44q3 zt1FogsyxE#)530_vg%O}>e;#d&zq<8$6&f4OJojp^d|R)CzU@rf5Cg1?Af!?W z4i6W%u`AFS38c@ZfdRMP%3C`U;1=VJYV6P@5qZW2E{kdcBiHhwes!lsVG&qm-C*o& zOCs6pfbzN1uuaR!#lhp#T;Igjnf#54{+j-0+U%FQ zv=vbQuo}?j-c|BE|IIS{Xx)lWDzCCXRaO?5zi17u-nZ~Z_=b!3mK7B{p6;tnF)uC3 zEBE#coOVxiO|kNWg5RdMeXAOFJ`ZH9P3GmK#8z(5%bC?VeP+xBxT!HQwoIe?Sgq#4 zHoI3_ADlmHdbXox%7uLj;muFHHOnSVT0eGTv4_dMlAfv=+ZNuO>)g7b>Ci$ARo08- zu?M!b+FcAR%HQ@NR&q0}e>BA@*|mUCVj|ShS8%&KCHk`FhnKHH-LRF-f7FhM9W2Q2 zI=CXI=jD@Jt-H@TUOUsQe0$dA?Az1fS@)r+=(GCJS+n)Vk>=T@X6l{pZmp)FK4%u) zGE`j7pifVKqn`1`dAZ7Rb5@JHeeg`}vYgb|V*|n`naA8t9D{Z}avz4=PJHwY{^MKF z+C7v9%ac9R!wcljh5Nvh*P>cSJqkK^UeCL%W0`$ufu3K`u5+iZZ3}pHvFl!8S4mFS zmb4Y^t=dV!4xg`loL2BI-&SpH-S11oo?>y0Q|vtMTWm5v=4HBSeebb5{Tk$T_jd** zhdmk`Gp@AQ*6-}Kh0Bu77nhz*KUdr_-m+}cSGAf40#+WZRJk`Ox744q&}K}7!G}7# zi63V$pHGV)dRS;OQKuyFYQtf1wn2622Hq;OozVG-TAJ&#r0<&bP|)M?&W2OH zGLpx-?^x$P$8A7w)?)1v-zQ2YB_?0Gj~UpRT}-{7`*E&armWB1ri9Cj5hY#;F#$+*0tu`DrcS0{~!XpJEK)QV5-o;b-rH3z_aa|GSBV(;|b9cAN z)B`HhThlQ?&4YX2A$jz(*K?(u7>Nhk6fQZ2c`$+N<(MkhVb`XgnWyMkquQn#_4 z{==AglKN5kyON+fIH+fN(b+CgEjTkeSm1k3Yo<=JcC3AQVsVA+@wP1IQ@fQMVje7gnDcDWZ?|9M<+n%azKoNZlR0U~f5lkW@(KE)1(caARvK@X zQQ%es|gY-FK%(eMY*tb9D0Lp|z+J1HFZkj*QuY1T z<$q3Cs||gswy%o}$@1fWRCVQyOKb@VQ!+m1@pi)>Q>Pi)9{6p2axmvqQkuc^U01@& z7P?*9%Q1Jnotb@LrL6j{tSjud>yK~c?NiQ-EPZx$PER7|Qbm6*cAH{T*1xU(F6+YB zhugHrn7AC6v30e7?o}H`Ui{7(s-M2J?mm?|X`4Btd#1r?&&gr6 z*}bQxN5!s7+jLJ$WxV6nAok z&M(*~@{EhRFfyf6@oIT%xOD+`J7Hx|+l{raD%&@>+n%x-cQ8q7URKt-QF;q34^AoG zsDBEx3l^R?%-DZB^%(yZXLU#K^N2%fqa7o}BV{K0ez2?1xwe2ip3Tgaxk<5Kkiuok z*(eS8*@b>22}Q??=Fd|9oOf{cal@wWrx!OruxA%gM~pf*W*oJ|RIB5j!zbC&mJv~Y zUW;dmLVxd^$9dAT^daq8lZj*Gy%wL5d(3;h)wQxkH>P868w)?Cypz?|Tzh)iqxAy{ zgX6RN?sM!ezVy&I;c)4*<=R8@c+MHEK8>$_Z%|xXw|n0@ALq?qYF<818mc_U9O^JJ zUsyR}iH^?O>)U1ZEjNxg*rymPNwYn!uPuT_HyQttrJsLUftXgwq%;m*ig5IJjYvh zYve<+&1McgEK3ZynevUSF}Zfb*V}Xag3lh`t8LX{8FahzVr5$5nWy!fO-uJ&%Jcua z#16Wbl6gngyTB diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm deleted file mode 100644 index be2ae9b30e8d7d68992f083914c317bed5487e55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 218 zcmXwyTMmLS6h!B?r6Sb?!Uk|Bx(EMxc{M~R28!a3Y+dm2F_}5ZBnNrl5CDo*Mib`H zl!+unnXSaCx1RWv?nmqySn5`&n}8tf<5GUT3AEy1duC*NY&4T00Q45s zw7>@~wOp1^gwH=UAkL9wdrSG@s?U)b2s97WG}mk2f_8yTJ3JwRpw|vIroZu~Y%^>o zc3#L*DU}d{pcD;2Bnii4$YR5$AD;p*{NQ$WTwT1$H=@^n?#9MWP3yYeB0i4u>Cp8$HA67`@+k?4+{$Vn7WQVQitoGMuGk9Ozd+xyjhW1Yn6%nbQ=1dPlY`im@?9K9+gU(EJCJDE&~q`4-|XOr39{)-pKPxoh& zgT2$)@yY(P2`L$`Wc)A=lK#G9a`^P+>tRMIGhUudk7ks}gpssQVR324BxQlk(oAVG zM!h6T6GbceAJXh_a(I05T9cbiPG@@u`?LMM=@FGHCueAWI(ard+B-Y?)AZRrBo&urP>Y##RHS5e{uYzt9r!AXCcge2TY+B=# z4Y3_$s*%sf>y2$OxuF0<+6D^AwuV7i4+gc7C6fPNE0xY+Bwae7cdl?Dg#+$Im!P=) zqSN9>ihbe77=9S9VF{a|8q$!!4Sb>tI;3zxM;9c9HWgRIfx(q@>B@PcvN;nYV#Cez zF5A{-=~7Sv2x7z7CqPBB>bo@PPdoz064($3;L|qIu!t*h1`sj<2E#?q^sd_YJz;aE zcl7E*)H1HHOUMR)Vyi&-@K(l(zD>Al6<1t6_7U`|O#xNzj3CDvH6TDJl;yn5ZL+g; z`KmJHb)i5(lV*8tL)xj3A)-gViZ;9jYQPAg2|P$+AN23wrsm>Rr+w}+8?q(~iI5_$ zCFB5>UA@t+|2tfuwh*40>{$)jboZDqi&*^#RVT8wQ8^iB&iVamGfM)y+ zc!^GGi{Qoeo!G+;lRW=}`bKqS@b~milZFzGe+wruU&aR`=kT^M%f(`Ru@0w4)**5K zB-wa5C2(^w<$`F-ti>f=HPELFAVIPd6T5uM%tv$g`p|7$1;Rnr2e4GxAljpqgX|OktS5ZT^KNz z7B-g_u6Ax%h~lkbVF+dTv0Dn;4-O$x$x4*_lg-Xr-?nI6=>gh<2# z2n%S?1VkE&ZT%h!=-C5AQiS9&kQb1e9L0O0p28!<+Tz4WPc$zMWT-*M46-I<7pWAc zN9oW7|BHA8ihx*sTMZTz_?aMUB|aM48NSu?tv_PNirrzSIhi5NP+}z{fKZ33?}|rJ zc*>Bp2EmDZ!JZNA6-3aKO-+FOpg<2!Zz%`}rJOidASNqpxstGzWDu&u^dgQz4iwl;S|16uah?`jYl}ZXg9|iw`lC;L7aB043B_^DX7Kfb)vI@DVMNjdEky-@Aw6#sXT%N`MR~hQM z)ryiVHF;51*7;^suUucfar4&gwL9w@cQ?1fwQCZf=n;q{Nd;9!Tq@TASELQC4Y^rd*23&%c{+#AV~ItKb!0@`b&%ojp6bCV$(vOz!@R^5835pZx1`autKTeaNOdp zyTuK9e||MWmAiWx^-ZoZ_ud6USEIhkE131OB|^h7!r6p0KgamVMq6+lBBQ9}I<-=oSoo}HVD-CBj za`)+LHRR631NfC%JWuZFHwrHq@og+RG-#S+Xq|7v!WQxl8G~8?EM7woT!v7Iu*jS{ z=m9h$J8)$kt&O-sq_yN3ZW4c+H_*KvVR*3X*Z3})cZN7OQC-8U01r2LBuKK(sTZ|0 zfBWDK{{5T2iqA(pC2Dt5UIVqeF&y7jc@5O=dOXGMn!E;Tw_;hC*4T&^UJ*j5+VU0( zZ#kfFHf9f!CrPYq%sZ~j5n6?f(BmZ{$;fO37mpBGjz@?Df=7tJfY+Er3k{JNAfN>$ zJMl46Q4p2aO=2@t8$A@5@^{?dY^?b!;w5%ArKiUS6XI1{(f--&^W&50>@{()&G*f{ zr^jdbvA|<%FaJ#7_iZ{odU=MCZ^)X#&bMR>nKZP{$>z&n6?l6t{hisxQldmrq{!K|6U$CyBPoS)B|e~CrsN!4KIcTyA}j+ENEHdv z(IJK^0>pc$I)yyQ!{k&rDvEhm_UQR`sOi_{+r68;qgT_{NwcC%hTbINQRp-d^(&S96o=3 z^5k$jJUTd=o}3;&9g>puLe?i?k@V|{;pEASmz{(S62r;lDz!^zoj+KJ>M^5S%K zJf%o<^kj_HR0on;sk;P7e=8$7I(| z&oTUB_;hr9aDM#t==g}7$ckZQicT=7k|{Bym(0DWP4Ip#S5*9Uqxh3DGd)=Rd15oZ ztEpA{C3!-x(O!AQYTBAdrSiIooVILg-A4PRX44p_tPf)^qDDTSZPjH1;hH=YY3s>H zdm0L%-5d0JmPr18r&K(Hl6YZ&9$aBU3lV*nu&U@)AGnLbe4zat#Z^sZiifL_7{PVq@+PZ(uzAJ)oR zHf|y=8pQ<{kIDdg(Zql%bw-e5jUEsnG|F$0|7rAOz>PLNL+$?7BK2DBzl%3OvRQJ8q>KRErAeZ z0E8$-YS}-p=@K`85z|Y0)|ODheYSPNA90KWRhz{$^WEr zt=im|clDr7eGbEafRT`w^-jqptgVy9W>G%hhub6j5V(Jl9J~_{%$9+KxCi`XN^X|%0lM7^# z^`+1EwChX}kNp^5*|;vC2iE%T;LIoC;F9}etO^2#gfHqItX9=zZ>g zYL>$Bok4JzpgS~5%Bj1Av<$?-6{k%owS?f=Ivv2n%T71bFJRJ^djX@Y#KM zg8T3Y$O}ldAoQWIr{ocQZE#~`Ca4z!67;}h22qn_7pjy@57ePE{x@+CDPqKmqSK&| zpAn*#?W<|Xo@g{iIpS)h}sw9HhUO|C-+ff;GEDG^cmq^K?FlN z)OgSj8qDDK=7NBvloR7J_+%wp3>*j-Vl`psc`|4-NxCd#Nddl?rzbQbJ>lF+dIrft z(i2C02J?g0; z3!j5MF50}@1({avH*ow)offy&7fYR9U~#`*>I|uaHxIA5=tRgb@DASwXIJi5&P$x=(UCtoU@AyAQ_X7|Xl341E9mKP8?}vA2+~6S((Q<4td(V1{$Er!C zAyD=_e|Fem^_N(cG=|0hE1Ty0gq)G2e>1zBoLxfCFRY}Lcerlh)!pS9v+rGvP~q;Z zqQ1iwWbZB!x*GKzUW3#-3xq=aK$=noq=Hbn>vqJ8qMP7rkp3Aa@aSAe_igK)TvQ28 z{HR>#bxgj6+GoGq<{RiE5hBRmL>K7&NSx!HO1olYi#IThorV)!xqI}T>SAZY1^iac z%agnMl|m&Ww)KUFI!==aZSgH=*hSnyV_*w_#haLc$sj5r7LmD)89*bn15>sz+73H} zT63P_B`I(5Hm0`%4EOiTO}>NS?at2~bT?5Ipm38SL4tKjV_{44_m5xU-+$=aP(GrR zsN7Ad1}b->yT0pE4OH%WxW(?8R0EY;vn-ib+kh6T2uY~Q@-CXvvPa`=h#n|Uf>_uP zcRZIpj4~UbMTIm}3s4|-Hl`;hM?>Ou>^VH2esyv>n!Y6VwthW4cye-%9~j)X zcJ-$Pe`Mp)@r!e;d{5SNdVV0AiBLDXB%3aN^q@|$c5%dLct&`YY)@q0nEa7!{^jU+ UboSNos3Cr(Y>MAV{^VKnUuVwX;Q#;t From 800eb20403b7ac7de41dfcb3c91b1556a1239899 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 9 Jan 2018 16:01:46 +0100 Subject: [PATCH 12/76] Add wasm binaries. --- .../release/runtime_polkadot.compact.wasm | Bin 0 -> 218 bytes .../release/runtime_polkadot.wasm | Bin 0 -> 341 bytes .../release/runtime_test.compact.wasm | Bin 0 -> 3392 bytes .../release/runtime_test.wasm | Bin 0 -> 3480 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm create mode 100644 wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm new file mode 100644 index 0000000000000000000000000000000000000000..be2ae9b30e8d7d68992f083914c317bed5487e55 GIT binary patch literal 218 zcmXwyTMmLS6h!B?r6Sb?!Uk|Bx(EMxc{M~R28!a3Y+dm2F_}5ZBnNrl5CDo*Mib`H zl!+unnXSaCx1RWv?nmqySn5`&n}8tf<5GUT3AEy1duC*NY&4T00Q45s zw7>@~wOp1^gwH=UAkL9wdrSG@s?U)b2s97WG}mk2f_8yTJ3JwRpw|vIroZu~Y%^>o zc3#L*DU}d{pcD;2Bnii4$YR5$AD;p*{NQ$WTwT1$H=@^n?#9MWP3yYeB0i4u>Cp8$HA67`@+k?4+{$Vn7WQVQitoGMuGk9Ozd+xyjhW1Yn6%nbQ=1dPlY`im@?9K9+gU(EJCJDE&~q`4-|XOr39{)-pKPxoh& zgT2$)@yY(P2`L$`Wc)A=lK#G9a`^P+>tRMIGhUudk7ks}gpssQVR324BxQlk(oAVG zM!h6T6GbceAJXh_a(I05T9cbiPG@@u`?LMM=@FGHCueAWI(ard+B-Y?)AZRrBo&urP>Y##RHS5e{uYzt9r!AXCcge2TY+B=# z4Y3_$s*%sf>y2$OxuF0<+6D^AwuV7i4+gc7C6fPNE0xY+Bwae7cdl?Dg#+$Im!P=) zqSN9>ihbe77=9S9VF{a|8q$!!4Sb>tI;3zxM;9c9HWgRIfx(q@>B@PcvN;nYV#Cez zF5A{-=~7Sv2x7z7CqPBB>bo@PPdoz064($3;L|qIu!t*h1`sj<2E#?q^sd_YJz;aE zcl7E*)H1HHOUMR)Vyi&-@K(l(zD>Al6<1t6_7U`|O#xNzj3CDvH6TDJl;yn5ZL+g; z`KmJHb)i5(lV*8tL)xj3A)-gViZ;9jYQPAg2|P$+AN23wrsm>Rr+w}+8?q(~iI5_$ zCFB5>UA@t+|2tfuwh*40>{$)jboZDqi&*^#RVT8wQ8^iB&iVamGfM)y+ zc!^GGi{Qoeo!G+;lRW=}`bKqS@b~milZFzGe+wruU&aR`=kT^M%f(`Ru@0w4)**5K zB-wa5C2(^w<$`F-ti>f=HPELFAVIPd6T5uM%tv$g`p|7$1;Rnr2e4GxAljpqgX|OktS5ZT^KNz z7B-g_u6Ax%h~lkbVF+dTv0Dn;4-O$x$x4*_lg-Xr-?nI6=>gh<2# z2n%S?1VkE&ZT%h!=-C5AQiS9&kQb1e9L0O0p28!<+Tz4WPc$zMWT-*M46-I<7pWAc zN9oW7|BHA8ihx*sTMZTz_?aMUB|aM48NSu?tv_PNirrzSIhi5NP+}z{fKZ33?}|rJ zc*>Bp2EmDZ!JZNA6-3aKO-+FOpg<2!Zz%`}rJOidASNqpxstGzWDu&u^dgQz4iwl;S|16uah?`jYl}ZXg9|iw`lC;L7aB043B_^DX7Kfb)vI@DVMNjdEky-@Aw6#sXT%N`MR~hQM z)ryiVHF;51*7;^suUucfar4&gwL9w@cQ?1fwQCZf=n;q{Nd;9!Tq@TASELQC4Y^rd*23&%c{+#AV~ItKb!0@`b&%ojp6bCV$(vOz!@R^5835pZx1`autKTeaNOdp zyTuK9e||MWmAiWx^-ZoZ_ud6USEIhkE131OB|^h7!r6p0KgamVMq6+lBBQ9}I<-=oSoo}HVD-CBj za`)+LHRR631NfC%JWuZFHwrHq@og+RG-#S+Xq|7v!WQxl8G~8?EM7woT!v7Iu*jS{ z=m9h$J8)$kt&O-sq_yN3ZW4c+H_*KvVR*3X*Z3})cZN7OQC-8U01r2LBuKK(sTZ|0 zfBWDK{{5T2iqA(pC2Dt5UIVqeF&y7jc@5O=dOXGMn!E;Tw_;hC*4T&^UJ*j5+VU0( zZ#kfFHf9f!CrPYq%sZ~j5n6?f(BmZ{$;fO37mpBGjz@?Df=7tJfY+Er3k{JNAfN>$ zJMl46Q4p2aO=2@t8$A@5@^{?dY^?b!;w5%ArKiUS6XI1{(f--&^W&50>@{()&G*f{ zr^jdbvA|<%FaJ#7_iZ{odU=MCZ^)X#&bMR>nKZP{$>z&n6?l6t{hisxQldmrq{!K|6U$CyBPoS)B|e~CrsN!4KIcTyA}j+ENEHdv z(IJK^0>pc$I)yyQ!{k&rDvEhm_UQR`sOi_{+r68;qgT_{NwcC%hTbINQRp-d^(&S96o=3 z^5k$jJUTd=o}3;&9g>puLe?i?k@V|{;pEASmz{(S62r;lDz!^zoj+KJ>M^5S%K zJf%o<^kj_HR0on;sk;P7e=8$7I(| z&oTUB_;hr9aDM#t==g}7$ckZQicT=7k|{Bym(0DWP4Ip#S5*9Uqxh3DGd)=Rd15oZ ztEpA{C3!-x(O!AQYTBAdrSiIooVILg-A4PRX44p_tPf)^qDDTSZPjH1;hH=YY3s>H zdm0L%-5d0JmPr18r&K(Hl6YZ&9$aBU3lV*nu&U@)AGnLbe4zat#Z^sZiifL_7{PVq@+PZ(uzAJ)oR zHf|y=8pQ<{kIDdg(Zql%bw-e5jUEsnG|F$0|7rAOz>PLNL+$?7BK2DBzl%3OvRQJ8q>KRErAeZ z0E8$-YS}-p=@K`85z|Y0)|ODheYSPNA90KWRhz{$^WEr zt=im|clDr7eGbEafRT`w^-jqptgVy9W>G%hhub6j5V(Jl9J~_{%$9+KxCi`XN^X|%0lM7^# z^`+1EwChX}kNp^5*|;vC2iE%T;LIoC;F9}etO^2#gfHqItX9=zZ>g zYL>$Bok4JzpgS~5%Bj1Av<$?-6{k%owS?f=Ivv2n%T71bFJRJ^djX@Y#KM zg8T3Y$O}ldAoQWIr{ocQZE#~`Ca4z!67;}h22qn_7pjy@57ePE{x@+CDPqKmqSK&| zpAn*#?W<|Xo@g{iIpS)h}sw9HhUO|C-+ff;GEDG^cmq^K?FlN z)OgSj8qDDK=7NBvloR7J_+%wp3>*j-Vl`psc`|4-NxCd#Nddl?rzbQbJ>lF+dIrft z(i2C02J?g0; z3!j5MF50}@1({avH*ow)offy&7fYR9U~#`*>I|uaHxIA5=tRgb@DASwXIJi5&P$x=(UCtoU@AyAQ_X7|Xl341E9mKP8?}vA2+~6S((Q<4td(V1{$Er!C zAyD=_e|Fem^_N(cG=|0hE1Ty0gq)G2e>1zBoLxfCFRY}Lcerlh)!pS9v+rGvP~q;Z zqQ1iwWbZB!x*GKzUW3#-3xq=aK$=noq=Hbn>vqJ8qMP7rkp3Aa@aSAe_igK)TvQ28 z{HR>#bxgj6+GoGq<{RiE5hBRmL>K7&NSx!HO1olYi#IThorV)!xqI}T>SAZY1^iac z%agnMl|m&Ww)KUFI!==aZSgH=*hSnyV_*w_#haLc$sj5r7LmD)89*bn15>sz+73H} zT63P_B`I(5Hm0`%4EOiTO}>NS?at2~bT?5Ipm38SL4tKjV_{44_m5xU-+$=aP(GrR zsN7Ad1}b->yT0pE4OH%WxW(?8R0EY;vn-ib+kh6T2uY~Q@-CXvvPa`=h#n|Uf>_uP zcRZIpj4~UbMTIm}3s4|-Hl`;hM?>Ou>^VH2esyv>n!Y6VwthW4cye-%9~j)X zcJ-$Pe`Mp)@r!e;d{5SNdVV0AiBLDXB%3aN^q@|$c5%dLct&`YY)@q0nEa7!{^jU+ UboSNos3Cr(Y>MAV{^VKnUuVwX;Q#;t literal 0 HcmV?d00001 From 10eaefed1a3c94b81cf150ca2a2ff56c2b0fb721 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 9 Jan 2018 17:50:35 +0100 Subject: [PATCH 13/76] Fix test. --- executor/src/wasm_executor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index e0d47de267af4..cb2df774d93d9 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -252,8 +252,8 @@ mod tests { b"\0code".to_vec() => b"Hello world".to_vec(), b"input".to_vec() => b"Hello world".to_vec(), b"code".to_vec() => b"The code".to_vec(), - b"\0validator_count".to_vec() => vec![1], - b"\0validator".to_vec() => b"Hello world".to_vec() + b"\0authority_count".to_vec() => vec![1], + b"\0authority".to_vec() => b"Hello world".to_vec() ]; assert_eq!(expected, ext.storage); } From 24ba809f7c71fe61e207beb5b00f7b35d8593e11 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 9 Jan 2018 19:28:22 +0100 Subject: [PATCH 14/76] Native storage support API. --- Cargo.lock | 20 ++++++++++ native-runtime/support/Cargo.toml | 4 ++ native-runtime/support/src/lib.rs | 65 +++++++++++++++++++++++++++++-- 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61afee3c0abe2..2d02a1799c7cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -425,6 +425,11 @@ name = "lazy_static" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lazy_static" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "lazycell" version = "0.5.1" @@ -568,6 +573,15 @@ dependencies = [ "parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot_core" version = "0.2.6" @@ -818,6 +832,10 @@ dependencies = [ [[package]] name = "runtime-support" version = "0.1.0" +dependencies = [ + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "rustc-demangle" @@ -1189,6 +1207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9e5e58fa1a4c3b915a561a78a22ee0cac6ab97dca2504428bc1cb074375f8d5" +"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" "checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2" "checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" @@ -1205,6 +1224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parity-wasm 0.15.4 (registry+https://github.com/rust-lang/crates.io-index)" = "235801e9531998c4bb307f4ea6833c9f40a4cf132895219ac8c2cd25a9b310f7" "checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e" +"checksum parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e7f7c9857874e54afeb950eebeae662b1e51a2493666d2ea4c0a5d91dcf0412" "checksum parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f610cb9664da38e417ea3225f23051f589851999535290e077939838ab7a595" "checksum patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e2f638d79aba5c4a71a4f373df6e3cd702250a53b7f0ed4da1e2a7be9737ae" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" diff --git a/native-runtime/support/Cargo.toml b/native-runtime/support/Cargo.toml index b9c56adf24acd..4f4e0202b58a6 100644 --- a/native-runtime/support/Cargo.toml +++ b/native-runtime/support/Cargo.toml @@ -5,3 +5,7 @@ authors = ["Parity Technologies "] [features] strict = [] + +[dependencies] +lazy_static = "1.0.0" +parking_lot = "0.5" diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index 93d3aad9cde3e..0e12d5e67892e 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -1,14 +1,73 @@ +#[macro_use] +extern crate lazy_static; +extern crate parking_lot; + pub use std::vec::Vec; pub use std::rc::Rc; pub use std::cell::RefCell; pub use std::boxed::Box; pub use std::mem::{size_of, transmute}; -pub fn storage(_key: &[u8]) -> Vec { vec![] } -pub fn storage_into(_key: &[u8]) -> Option { None } -pub fn set_storage(_key: &[u8], _value: &[u8]) {} +use std::collections::HashMap; +use parking_lot::Mutex; + +lazy_static! { + static ref HASHMAP: Mutex, Vec>> = Mutex::new(HashMap::new()); +} + +pub fn storage(_key: &[u8]) -> Vec { + HASHMAP.lock().get(_key).cloned().unwrap_or_else(Vec::new) +} + +pub fn storage_into(_key: &[u8]) -> Option { + let size = size_of::(); + if let Some(value) = HASHMAP.lock().get(_key) { + if value.len() == size { + unsafe { + let mut result: T = std::mem::uninitialized(); + std::slice::from_raw_parts_mut(transmute::<*mut T, *mut u8>(&mut result), size) + .copy_from_slice(&value); + return Some(result); + } + } + } + None +} + +pub fn set_storage(_key: &[u8], _value: &[u8]) { + HASHMAP.lock().insert(_key.to_vec(), _value.to_vec()); +} + +pub fn init_storage(new: HashMap, Vec>) { + *HASHMAP.lock() = new; +} #[macro_export] macro_rules! impl_stubs { ($( $name:ident ),*) => {} } + +#[cfg(test)] +mod tests { + use super::*; + + macro_rules! map { + ($( $name:expr => $value:expr ),*) => ( + vec![ $( ( $name, $value ) ),* ].into_iter().collect() + ) + } + + #[test] + fn storage_works() { + assert_eq!(storage(b"hello"), vec![]); + set_storage(b"hello", b"world"); + assert_eq!(storage(b"hello"), b"world".to_vec()); + assert_eq!(storage(b"foo"), vec![]); + set_storage(b"foo", &[1, 2, 3][..]); + assert_eq!(storage_into::<[u8; 3]>(b"foo"), Some([1, 2, 3])); + assert_eq!(storage_into::<[u8; 3]>(b"hello"), None); + init_storage(map![b"foo".to_vec() => b"bar".to_vec()]); + assert_eq!(storage(b"hello"), vec![]); + assert_eq!(storage(b"foo"), b"bar".to_vec()); + } +} From 36a49ffd58d6fbca37a06f8f26cb6023f3c4da42 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 10 Jan 2018 14:12:14 +0100 Subject: [PATCH 15/76] Add environmental module --- environmental/Cargo.toml | 4 ++ environmental/src/lib.rs | 107 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 environmental/Cargo.toml create mode 100644 environmental/src/lib.rs diff --git a/environmental/Cargo.toml b/environmental/Cargo.toml new file mode 100644 index 0000000000000..52c3337f8a130 --- /dev/null +++ b/environmental/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "environmental" +version = "0.1.0" +authors = ["Parity Technologies "] diff --git a/environmental/src/lib.rs b/environmental/src/lib.rs new file mode 100644 index 0000000000000..db46b13158a64 --- /dev/null +++ b/environmental/src/lib.rs @@ -0,0 +1,107 @@ +// 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 . + +use std::cell::RefCell; +use std::thread::LocalKey; + +pub fn using_environment<'a, T: 'a, S, F: FnOnce()>( + global: &'static LocalKey>, + protected: &'a mut T, + f: F +) { + global.with(|r| *r.borrow_mut() = protected as *mut T as *mut S); + f(); + global.with(|r| *r.borrow_mut() = 0 as *mut S); +} + +pub fn with_environment<'r, S, T: 'r, F: FnOnce(&'r mut T)>( + global: &'static LocalKey>, + mutator: F, +) { + global.with(|r| { + let br = r.borrow_mut(); + if *br != 0 as *mut S { + // safe because it's only non-zero when it in with_environment, which + // is holding on to the underlying reference safely + unsafe { + mutator(&mut *(*br as *mut S as *mut T)); + } + } + }); +} + +#[macro_export] +macro_rules! decl_environment { + ($name:ident : $t:ty) => { + thread_local! { + static $name: std::cell::RefCell<*mut $t> = std::cell::RefCell::new(0 as *mut $t); + } + } +} + +#[macro_export] +macro_rules! declare_generic_environment { + ($name:ident : $t:tt) => { + mod $name { + use super::*; + + decl_environment!(GLOBAL: $t<'static> ); + + pub fn using<'a: 'b, 'b, F: FnOnce(), T: 'a>(protected: &'b mut T, f: F) { + $crate::using_environment(&GLOBAL, protected, f); + } + + pub fn with FnOnce(&'r mut $t<'t>)>(f: F) { + let dummy = (); + with_closed(f, &dummy); + } + + fn with_closed<'d: 't, 't: 'r, 'r, F: FnOnce(&'r mut $t<'t>)>( + f: F, + _dummy: &'d (), + ) { + $crate::with_environment(&GLOBAL, f); + } + } + } +} + +#[macro_export] +macro_rules! declare_simple_environment { + ($name:ident : $t:tt) => { + mod $name { + use super::*; + + decl_environment!(GLOBAL: $t ); + + pub fn using<'a: 'b, 'b, F: FnOnce(), T: 'a>(protected: &'b mut T, f: F) { + $crate::using_environment(&GLOBAL, protected, f); + } + + pub fn with FnOnce(&'r mut $t)>(f: F) { + let dummy = (); + with_closed(f, &dummy); + } + + fn with_closed<'d: 'r, 'r, F: FnOnce(&'r mut $t)>( + f: F, + _dummy: &'d (), + ) { + $crate::with_environment(&GLOBAL, f); + } + } + } +} From 50e7222acf3371fa60440fcb658372f447c4d1f3 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 10 Jan 2018 14:39:56 +0100 Subject: [PATCH 16/76] Add native environment to make native source-code compatible with wasm. Also tests. --- Cargo.lock | 6 ++ Cargo.toml | 1 + environmental/src/lib.rs | 35 ++++++---- executor/src/wasm_utils.rs | 6 +- native-runtime/support/Cargo.toml | 2 + native-runtime/support/src/lib.rs | 106 +++++++++++++++++++++--------- 6 files changed, 108 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d02a1799c7cf..d0eee3e39a138 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -170,6 +170,10 @@ dependencies = [ "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "environmental" +version = "0.1.0" + [[package]] name = "error-chain" version = "0.11.0" @@ -833,8 +837,10 @@ dependencies = [ name = "runtime-support" version = "0.1.0" dependencies = [ + "environmental 0.1.0", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "polkadot-state-machine 0.1.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index bfbff5696930c..21232d39ef32b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ members = [ "candidate-agreement", "client", "collator", + "environmental", "executor", "primitives", "rpc", diff --git a/environmental/src/lib.rs b/environmental/src/lib.rs index db46b13158a64..420c22f44fa89 100644 --- a/environmental/src/lib.rs +++ b/environmental/src/lib.rs @@ -27,20 +27,23 @@ pub fn using_environment<'a, T: 'a, S, F: FnOnce()>( global.with(|r| *r.borrow_mut() = 0 as *mut S); } -pub fn with_environment<'r, S, T: 'r, F: FnOnce(&'r mut T)>( +pub fn with_environment<'r, R, S, T: 'r, F: FnOnce(&'r mut T) -> R>( global: &'static LocalKey>, mutator: F, -) { +) -> Option { + global.with(|r| { let br = r.borrow_mut(); if *br != 0 as *mut S { // safe because it's only non-zero when it in with_environment, which // is holding on to the underlying reference safely unsafe { - mutator(&mut *(*br as *mut S as *mut T)); + Some(mutator(&mut *(*br as *mut S as *mut T))) } + } else { + None } - }); + }) } #[macro_export] @@ -64,16 +67,18 @@ macro_rules! declare_generic_environment { $crate::using_environment(&GLOBAL, protected, f); } - pub fn with FnOnce(&'r mut $t<'t>)>(f: F) { + pub fn with FnOnce(&'r mut $t<'t>) -> R>( + f: F + ) -> Option { let dummy = (); - with_closed(f, &dummy); + with_closed(f, &dummy) } - fn with_closed<'d: 't, 't: 'r, 'r, F: FnOnce(&'r mut $t<'t>)>( + fn with_closed<'d: 't, 't: 'r, 'r, R, F: FnOnce(&'r mut $t<'t>) -> R>( f: F, _dummy: &'d (), - ) { - $crate::with_environment(&GLOBAL, f); + ) -> Option { + $crate::with_environment(&GLOBAL, f) } } } @@ -91,16 +96,18 @@ macro_rules! declare_simple_environment { $crate::using_environment(&GLOBAL, protected, f); } - pub fn with FnOnce(&'r mut $t)>(f: F) { + pub fn with FnOnce(&'r mut $t -> R)>( + f: F + ) -> Option { let dummy = (); - with_closed(f, &dummy); + with_closed(f, &dummy) } - fn with_closed<'d: 'r, 'r, F: FnOnce(&'r mut $t)>( + fn with_closed<'d: 'r, 'r, R, F: FnOnce(&'r mut $t -> R)>( f: F, _dummy: &'d (), - ) { - $crate::with_environment(&GLOBAL, f); + ) -> Option { + $crate::with_environment(&GLOBAL, f) } } } diff --git a/executor/src/wasm_utils.rs b/executor/src/wasm_utils.rs index 6d4fedfedbc94..f6440628b986e 100644 --- a/executor/src/wasm_utils.rs +++ b/executor/src/wasm_utils.rs @@ -119,13 +119,13 @@ pub trait IntoUserDefinedElements { #[macro_export] macro_rules! impl_function_executor { ( $objectname:ident : $structname:ty, $( $name:ident ( $( $names:ident : $params:ty ),* ) $( -> $returns:ty )* => $body:tt ),* => $($pre:tt)+ ) => ( - impl $( $pre ) + $crate::wasm_utils::UserFunctionExecutor<$crate::wasm_utils::DummyUserError> for $structname { + impl $($pre)+ $crate::wasm_utils::UserFunctionExecutor<$crate::wasm_utils::DummyUserError> for $structname { dispatch!($objectname, $( $name( $( $names : $params ),* ) $( -> $returns )* => $body ),*); } - impl $( $pre ) + $structname { + impl $($pre)+ $structname { signatures!($( $name( $( $params ),* ) $( -> $returns )* ),*); } - impl $( $pre ) + $crate::wasm_utils::IntoUserDefinedElements for $structname { + impl $($pre)+ $crate::wasm_utils::IntoUserDefinedElements for $structname { fn into_user_defined_elements(&mut self) -> UserDefinedElements<$crate::wasm_utils::DummyUserError> { $crate::wasm_utils::UserDefinedElements { executor: Some(self), diff --git a/native-runtime/support/Cargo.toml b/native-runtime/support/Cargo.toml index 4f4e0202b58a6..3f979bd4ff443 100644 --- a/native-runtime/support/Cargo.toml +++ b/native-runtime/support/Cargo.toml @@ -9,3 +9,5 @@ strict = [] [dependencies] lazy_static = "1.0.0" parking_lot = "0.5" +polkadot-state-machine = { path = "../../state_machine" , version = "0.1" } +environmental = { path = "../../environmental", version = "0.1.0" } diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index 0e12d5e67892e..091e07fbceb93 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -1,6 +1,6 @@ #[macro_use] -extern crate lazy_static; -extern crate parking_lot; +extern crate environmental; +extern crate polkadot_state_machine; pub use std::vec::Vec; pub use std::rc::Rc; @@ -8,38 +8,51 @@ pub use std::cell::RefCell; pub use std::boxed::Box; pub use std::mem::{size_of, transmute}; -use std::collections::HashMap; -use parking_lot::Mutex; +use polkadot_state_machine::Externalities; +use std::fmt; -lazy_static! { - static ref HASHMAP: Mutex, Vec>> = Mutex::new(HashMap::new()); +// TODO: use the real error, not NoError. + +#[derive(Debug)] +struct NoError; +impl fmt::Display for NoError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "") } +} + +pub struct ExternalitiesHolder<'a> { + ext: &'a mut Externalities, } +declare_generic_environment!(ext : ExternalitiesHolder); + pub fn storage(_key: &[u8]) -> Vec { - HASHMAP.lock().get(_key).cloned().unwrap_or_else(Vec::new) + ext::with(|holder| holder.ext.storage(_key).ok().map(|s| s.to_vec())) + .unwrap_or(None) + .unwrap_or_else(|| vec![]) } pub fn storage_into(_key: &[u8]) -> Option { let size = size_of::(); - if let Some(value) = HASHMAP.lock().get(_key) { - if value.len() == size { - unsafe { - let mut result: T = std::mem::uninitialized(); - std::slice::from_raw_parts_mut(transmute::<*mut T, *mut u8>(&mut result), size) - .copy_from_slice(&value); - return Some(result); + + ext::with(|holder| { + if let Ok(value) = holder.ext.storage(_key) { + if value.len() == size { + unsafe { + let mut result: T = std::mem::uninitialized(); + std::slice::from_raw_parts_mut(transmute::<*mut T, *mut u8>(&mut result), size) + .copy_from_slice(&value); + return Some(result); + } } } - } - None + None + }).unwrap_or(None) } pub fn set_storage(_key: &[u8], _value: &[u8]) { - HASHMAP.lock().insert(_key.to_vec(), _value.to_vec()); -} - -pub fn init_storage(new: HashMap, Vec>) { - *HASHMAP.lock() = new; + ext::with(|holder| + holder.ext.set_storage(_key.to_vec(), _value.to_vec()) + ); } #[macro_export] @@ -50,6 +63,23 @@ macro_rules! impl_stubs { #[cfg(test)] mod tests { use super::*; + use std::collections::HashMap; + + #[derive(Debug, Default)] + struct TestExternalities { + storage: HashMap, Vec>, + } + impl Externalities for TestExternalities { + type Error = NoError; + + fn storage(&self, key: &[u8]) -> Result<&[u8], NoError> { + Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) + } + + fn set_storage(&mut self, key: Vec, value: Vec) { + self.storage.insert(key, value); + } + } macro_rules! map { ($( $name:expr => $value:expr ),*) => ( @@ -59,15 +89,29 @@ mod tests { #[test] fn storage_works() { - assert_eq!(storage(b"hello"), vec![]); - set_storage(b"hello", b"world"); - assert_eq!(storage(b"hello"), b"world".to_vec()); - assert_eq!(storage(b"foo"), vec![]); - set_storage(b"foo", &[1, 2, 3][..]); - assert_eq!(storage_into::<[u8; 3]>(b"foo"), Some([1, 2, 3])); - assert_eq!(storage_into::<[u8; 3]>(b"hello"), None); - init_storage(map![b"foo".to_vec() => b"bar".to_vec()]); - assert_eq!(storage(b"hello"), vec![]); - assert_eq!(storage(b"foo"), b"bar".to_vec()); + let mut t = TestExternalities { storage: map![], }; + + { + let mut h = ExternalitiesHolder { ext: &mut t, }; + ext::using(&mut h, || { + assert_eq!(storage(b"hello"), b"".to_vec()); + set_storage(b"hello", b"world"); + assert_eq!(storage(b"hello"), b"world".to_vec()); + assert_eq!(storage(b"foo"), b"".to_vec()); + set_storage(b"foo", &[1, 2, 3][..]); + assert_eq!(storage_into::<[u8; 3]>(b"foo"), Some([1, 2, 3])); + assert_eq!(storage_into::<[u8; 3]>(b"hello"), None); + }); + } + + t.storage = map![b"foo".to_vec() => b"bar".to_vec()]; + + { + let mut h = ExternalitiesHolder { ext: &mut t, }; + ext::using(&mut h, || { + assert_eq!(storage(b"hello"), b"".to_vec()); + assert_eq!(storage(b"foo"), b"bar".to_vec()); + }); + } } } From 3e17caa6b9039f0b0a89629250b152a5ab7d33f6 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 10 Jan 2018 14:53:03 +0100 Subject: [PATCH 17/76] Finish up & polish environment stuff. --- environmental/src/lib.rs | 28 +++++++++++++------- native-runtime/support/src/lib.rs | 44 ++++++++++++++++--------------- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/environmental/src/lib.rs b/environmental/src/lib.rs index 420c22f44fa89..b7fc47ea5067d 100644 --- a/environmental/src/lib.rs +++ b/environmental/src/lib.rs @@ -17,21 +17,21 @@ use std::cell::RefCell; use std::thread::LocalKey; -pub fn using_environment<'a, T: 'a, S, F: FnOnce()>( +pub fn using_environment<'a, T: 'a, R, S, F: FnOnce() -> R>( global: &'static LocalKey>, protected: &'a mut T, f: F -) { +) -> R { global.with(|r| *r.borrow_mut() = protected as *mut T as *mut S); - f(); + let r = f(); global.with(|r| *r.borrow_mut() = 0 as *mut S); + r } pub fn with_environment<'r, R, S, T: 'r, F: FnOnce(&'r mut T) -> R>( global: &'static LocalKey>, mutator: F, ) -> Option { - global.with(|r| { let br = r.borrow_mut(); if *br != 0 as *mut S { @@ -63,8 +63,11 @@ macro_rules! declare_generic_environment { decl_environment!(GLOBAL: $t<'static> ); - pub fn using<'a: 'b, 'b, F: FnOnce(), T: 'a>(protected: &'b mut T, f: F) { - $crate::using_environment(&GLOBAL, protected, f); + pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>( + protected: &'b mut T, + f: F + ) -> R { + $crate::using_environment(&GLOBAL, protected, f) } pub fn with FnOnce(&'r mut $t<'t>) -> R>( @@ -90,10 +93,13 @@ macro_rules! declare_simple_environment { mod $name { use super::*; - decl_environment!(GLOBAL: $t ); + decl_environment!(GLOBAL: $t); - pub fn using<'a: 'b, 'b, F: FnOnce(), T: 'a>(protected: &'b mut T, f: F) { - $crate::using_environment(&GLOBAL, protected, f); + pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>( + protected: &'b mut T, + f: F + ) -> R { + $crate::using_environment(&GLOBAL, protected, f) } pub fn with FnOnce(&'r mut $t -> R)>( @@ -112,3 +118,7 @@ macro_rules! declare_simple_environment { } } } + +// TODO: Docs +// TODO: Example +// TODO: Tests diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index 091e07fbceb93..2926a20891656 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -14,7 +14,7 @@ use std::fmt; // TODO: use the real error, not NoError. #[derive(Debug)] -struct NoError; +pub struct NoError; impl fmt::Display for NoError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "") } } @@ -55,6 +55,13 @@ pub fn set_storage(_key: &[u8], _value: &[u8]) { ); } +/// Execute the given closure with global function available whose functionality routes into the +/// externalities `ext`. Forwards the value that the closure returns. +pub fn with_externalities R>(ext: &mut Externalities, f: F) -> R { + let mut h = ExternalitiesHolder { ext }; + ext::using(&mut h, f) +} + #[macro_export] macro_rules! impl_stubs { ($( $name:ident ),*) => {} @@ -90,28 +97,23 @@ mod tests { #[test] fn storage_works() { let mut t = TestExternalities { storage: map![], }; - - { - let mut h = ExternalitiesHolder { ext: &mut t, }; - ext::using(&mut h, || { - assert_eq!(storage(b"hello"), b"".to_vec()); - set_storage(b"hello", b"world"); - assert_eq!(storage(b"hello"), b"world".to_vec()); - assert_eq!(storage(b"foo"), b"".to_vec()); - set_storage(b"foo", &[1, 2, 3][..]); - assert_eq!(storage_into::<[u8; 3]>(b"foo"), Some([1, 2, 3])); - assert_eq!(storage_into::<[u8; 3]>(b"hello"), None); - }); - } + assert!(with_externalities(&mut t, || { + assert_eq!(storage(b"hello"), b"".to_vec()); + set_storage(b"hello", b"world"); + assert_eq!(storage(b"hello"), b"world".to_vec()); + assert_eq!(storage(b"foo"), b"".to_vec()); + set_storage(b"foo", &[1, 2, 3][..]); + assert_eq!(storage_into::<[u8; 3]>(b"foo"), Some([1, 2, 3])); + assert_eq!(storage_into::<[u8; 3]>(b"hello"), None); + true + })); t.storage = map![b"foo".to_vec() => b"bar".to_vec()]; - { - let mut h = ExternalitiesHolder { ext: &mut t, }; - ext::using(&mut h, || { - assert_eq!(storage(b"hello"), b"".to_vec()); - assert_eq!(storage(b"foo"), b"bar".to_vec()); - }); - } + assert!(!with_externalities(&mut t, || { + assert_eq!(storage(b"hello"), b"".to_vec()); + assert_eq!(storage(b"foo"), b"bar".to_vec()); + false + })); } } From e807c9a2545563ae53e3a6054817d64eb045acd0 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 10 Jan 2018 15:08:41 +0100 Subject: [PATCH 18/76] Avoid using reentrancy issues. --- environmental/src/lib.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/environmental/src/lib.rs b/environmental/src/lib.rs index b7fc47ea5067d..cd278f812335c 100644 --- a/environmental/src/lib.rs +++ b/environmental/src/lib.rs @@ -22,9 +22,21 @@ pub fn using_environment<'a, T: 'a, R, S, F: FnOnce() -> R>( protected: &'a mut T, f: F ) -> R { - global.with(|r| *r.borrow_mut() = protected as *mut T as *mut S); + // store the `protected` reference as a pointer so we can provide it to logic running within + // `f`. + // while re record this pointer (while it's non-zero) we guarantee: + // - it will only be used once at any time (no reentrancy); + // - that no other thread will use it; and + // - that we do not use the original mutating reference while the pointer. + // exists. + let original = global.with(|r| { + let mut b = r.borrow_mut(); + let o = *b; + *b = protected as *mut T as *mut S; + o + }); let r = f(); - global.with(|r| *r.borrow_mut() = 0 as *mut S); + global.with(|r| *r.borrow_mut() = original); r } @@ -35,8 +47,8 @@ pub fn with_environment<'r, R, S, T: 'r, F: FnOnce(&'r mut T) -> R>( global.with(|r| { let br = r.borrow_mut(); if *br != 0 as *mut S { - // safe because it's only non-zero when it in with_environment, which - // is holding on to the underlying reference safely + // safe because it's only non-zero when it's being called from using_environment, which + // is holding on to the underlying reference (and not using it itself) safely. unsafe { Some(mutator(&mut *(*br as *mut S as *mut T))) } From 402ae290739adf427f6965fdfe7e33f53dd69d9a Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 10 Jan 2018 18:58:49 +0100 Subject: [PATCH 19/76] Add some docs and a test. --- environmental/src/lib.rs | 61 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/environmental/src/lib.rs b/environmental/src/lib.rs index cd278f812335c..0dcd55bdcb269 100644 --- a/environmental/src/lib.rs +++ b/environmental/src/lib.rs @@ -14,9 +14,38 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use std::cell::RefCell; +//! Safe global references to stack variables. +//! +//! Set up a global reference with declare_simple_environment! macro giving it a name and type. +//! Use the `using` function scoped under its name to name a reference and call a function that +//! takes no parameters yet can access said reference through the similarly place `with` function. +//! +//! # Examples +//! +//! ``` +//! #[macro_use] extern crate environmental; +//! // create a place for the global reference to exist. +//! declare_simple_environment!(counter: u32); +//! fn stuff() { +//! // do some stuff, accessing the named reference as desired. +//! counter::with(|value| *value += 1); +//! } +//! fn main() { +//! // declare a stack variable of the same type as our global declaration. +//! let mut local = 41u32; +//! // call stuff, setting up our `counter` environment as a refrence to our local counter var. +//! counter::using(&mut local, stuff); +//! println!("The answer is {:?}", local); // will print 42! +//! stuff(); // safe! doesn't do anything. +//! } +//! ``` + + +pub use std::cell::RefCell; use std::thread::LocalKey; +pub fn test_me() { panic!("Hello") } + pub fn using_environment<'a, T: 'a, R, S, F: FnOnce() -> R>( global: &'static LocalKey>, protected: &'a mut T, @@ -24,7 +53,7 @@ pub fn using_environment<'a, T: 'a, R, S, F: FnOnce() -> R>( ) -> R { // store the `protected` reference as a pointer so we can provide it to logic running within // `f`. - // while re record this pointer (while it's non-zero) we guarantee: + // while we record this pointer (while it's non-zero) we guarantee: // - it will only be used once at any time (no reentrancy); // - that no other thread will use it; and // - that we do not use the original mutating reference while the pointer. @@ -62,7 +91,7 @@ pub fn with_environment<'r, R, S, T: 'r, F: FnOnce(&'r mut T) -> R>( macro_rules! decl_environment { ($name:ident : $t:ty) => { thread_local! { - static $name: std::cell::RefCell<*mut $t> = std::cell::RefCell::new(0 as *mut $t); + static $name: $crate::RefCell<*mut $t> = $crate::RefCell::new(0 as *mut $t); } } } @@ -71,6 +100,7 @@ macro_rules! decl_environment { macro_rules! declare_generic_environment { ($name:ident : $t:tt) => { mod $name { + #[allow(unused_imports)] use super::*; decl_environment!(GLOBAL: $t<'static> ); @@ -103,6 +133,7 @@ macro_rules! declare_generic_environment { macro_rules! declare_simple_environment { ($name:ident : $t:tt) => { mod $name { + #[allow(unused_imports)] use super::*; decl_environment!(GLOBAL: $t); @@ -114,14 +145,14 @@ macro_rules! declare_simple_environment { $crate::using_environment(&GLOBAL, protected, f) } - pub fn with FnOnce(&'r mut $t -> R)>( + pub fn with FnOnce(&'r mut $t) -> R>( f: F ) -> Option { let dummy = (); with_closed(f, &dummy) } - fn with_closed<'d: 'r, 'r, R, F: FnOnce(&'r mut $t -> R)>( + fn with_closed<'d: 'r, 'r, R, F: FnOnce(&'r mut $t) -> R>( f: F, _dummy: &'d (), ) -> Option { @@ -134,3 +165,23 @@ macro_rules! declare_simple_environment { // TODO: Docs // TODO: Example // TODO: Tests + +#[cfg(test)] +mod tests { + declare_simple_environment!(counter: u32); + + fn stuff() { + // do some stuff, accessing the named reference as desired. + counter::with(|value| *value += 1); + } + + #[test] + fn simple_environment_works() { + // declare a stack variable of the same type as our global declaration. + let mut local = 41u32; + // call stuff, setting up our `counter` environment as a refrence to our local counter var. + counter::using(&mut local, stuff); + println!("The answer is {:?}", local); // will print 42! + stuff(); // safe! doesn't do anything. + } +} From 762826b37aad1d7db5a076ee051869fee6ef308f Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 10 Jan 2018 18:59:49 +0100 Subject: [PATCH 20/76] Remove unneeded function. --- environmental/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/environmental/src/lib.rs b/environmental/src/lib.rs index 0dcd55bdcb269..2556b437ae934 100644 --- a/environmental/src/lib.rs +++ b/environmental/src/lib.rs @@ -44,8 +44,6 @@ pub use std::cell::RefCell; use std::thread::LocalKey; -pub fn test_me() { panic!("Hello") } - pub fn using_environment<'a, T: 'a, R, S, F: FnOnce() -> R>( global: &'static LocalKey>, protected: &'a mut T, From 7e969c8eb310e5fbd4cdd78ec3f3fe55e47883e3 Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 11 Jan 2018 18:23:06 +0100 Subject: [PATCH 21/76] Documentation --- environmental/src/lib.rs | 121 +++++++++++++++++++++++------- native-runtime/support/src/lib.rs | 2 +- 2 files changed, 95 insertions(+), 28 deletions(-) diff --git a/environmental/src/lib.rs b/environmental/src/lib.rs index 2556b437ae934..0c389e13dc592 100644 --- a/environmental/src/lib.rs +++ b/environmental/src/lib.rs @@ -16,35 +16,36 @@ //! Safe global references to stack variables. //! -//! Set up a global reference with declare_simple_environment! macro giving it a name and type. +//! Set up a global reference with declare_simple! macro giving it a name and type. //! Use the `using` function scoped under its name to name a reference and call a function that -//! takes no parameters yet can access said reference through the similarly place `with` function. +//! takes no parameters yet can access said reference through the similarly placed `with` function. //! //! # Examples //! //! ``` //! #[macro_use] extern crate environmental; //! // create a place for the global reference to exist. -//! declare_simple_environment!(counter: u32); +//! declare_simple!(counter: u32); //! fn stuff() { //! // do some stuff, accessing the named reference as desired. -//! counter::with(|value| *value += 1); +//! counter::with(|i| *i += 1); //! } //! fn main() { //! // declare a stack variable of the same type as our global declaration. -//! let mut local = 41u32; -//! // call stuff, setting up our `counter` environment as a refrence to our local counter var. -//! counter::using(&mut local, stuff); -//! println!("The answer is {:?}", local); // will print 42! +//! let mut counter_value = 41u32; +//! // call stuff, setting up our `counter` environment as a refrence to our counter_value var. +//! counter::using(&mut counter_value, stuff); +//! println!("The answer is {:?}", counter_value); // will print 42! //! stuff(); // safe! doesn't do anything. //! } //! ``` - +#[doc(hidden)] pub use std::cell::RefCell; use std::thread::LocalKey; -pub fn using_environment<'a, T: 'a, R, S, F: FnOnce() -> R>( +#[doc(hidden)] +pub fn using<'a, T: 'a, R, S, F: FnOnce() -> R>( global: &'static LocalKey>, protected: &'a mut T, f: F @@ -67,14 +68,15 @@ pub fn using_environment<'a, T: 'a, R, S, F: FnOnce() -> R>( r } -pub fn with_environment<'r, R, S, T: 'r, F: FnOnce(&'r mut T) -> R>( +#[doc(hidden)] +pub fn with<'r, R, S, T: 'r, F: FnOnce(&'r mut T) -> R>( global: &'static LocalKey>, mutator: F, ) -> Option { global.with(|r| { let br = r.borrow_mut(); if *br != 0 as *mut S { - // safe because it's only non-zero when it's being called from using_environment, which + // safe because it's only non-zero when it's being called from using, which // is holding on to the underlying reference (and not using it itself) safely. unsafe { Some(mutator(&mut *(*br as *mut S as *mut T))) @@ -85,8 +87,9 @@ pub fn with_environment<'r, R, S, T: 'r, F: FnOnce(&'r mut T) -> R>( }) } +#[doc(hidden)] #[macro_export] -macro_rules! decl_environment { +macro_rules! decl { ($name:ident : $t:ty) => { thread_local! { static $name: $crate::RefCell<*mut $t> = $crate::RefCell::new(0 as *mut $t); @@ -94,67 +97,131 @@ macro_rules! decl_environment { } } +/// Declare a new global reference module whose underlying value does not contain references. +/// +/// Will create a module of a given name that contains two functions: +/// - `pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>(protected: &'b mut T, f: F) -> R` +/// This executes `f`, returning its value. During the call, the module's reference is set to +/// be equal to `protected`. +/// - `pub fn with FnOnce(&'r mut $t<'t>) -> R>(f: F) -> Option` +/// This executes `f`, returning its value if called from code that is being executed as part of +/// a `using` call. The function takes one argument: the same reference as provided to the most +/// recent `using` call. +/// +/// # Examples +/// +/// ``` +/// #[macro_use] extern crate environmental; +/// declare_simple!(counter: u32); +/// fn main() { +/// let mut counter_value = 41u32; +/// counter::using(&mut counter_value, || { +/// let odd = counter::with(|value| +/// if *value % 2 == 1 { +/// *value += 1; true +/// } else { +/// *value -= 3; false +/// }).unwrap(); // safe because we're inside a counter::using +/// println!("counter was {}", match odd { true => "odd", _ => "even" }); +/// }); +/// +/// println!("The answer is {:?}", counter_value); // 42 +/// } +/// ``` #[macro_export] -macro_rules! declare_generic_environment { +macro_rules! declare_simple { ($name:ident : $t:tt) => { mod $name { #[allow(unused_imports)] use super::*; - decl_environment!(GLOBAL: $t<'static> ); + decl!(GLOBAL: $t); pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>( protected: &'b mut T, f: F ) -> R { - $crate::using_environment(&GLOBAL, protected, f) + $crate::using(&GLOBAL, protected, f) } - pub fn with FnOnce(&'r mut $t<'t>) -> R>( + pub fn with FnOnce(&'r mut $t) -> R>( f: F ) -> Option { let dummy = (); with_closed(f, &dummy) } - fn with_closed<'d: 't, 't: 'r, 'r, R, F: FnOnce(&'r mut $t<'t>) -> R>( + fn with_closed<'d: 'r, 'r, R, F: FnOnce(&'r mut $t) -> R>( f: F, _dummy: &'d (), ) -> Option { - $crate::with_environment(&GLOBAL, f) + $crate::with(&GLOBAL, f) } } } } +/// Declare a new global reference module whose underlying value is generic over a reference. +/// +/// Will create a module of a given name that contains two functions: +/// - `pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>(protected: &'b mut T, f: F) -> R` +/// This executes `f`, returning its value. During the call, the module's reference is set to +/// be equal to `protected`. +/// - `pub fn with FnOnce(&'r mut $t<'t>) -> R>(f: F) -> Option` +/// This executes `f`, returning its value if called from code that is being executed as part of +/// a `using` call. The function takes one argument: the same reference as provided to the most +/// recent `using` call. +/// +/// # Examples +/// +/// ``` +/// #[macro_use] extern crate environmental; +/// // a type that we want to reference from a temp global; it has a reference in it. +/// struct WithReference<'a> { answer_ref: &'a mut u32, } +/// // create a place for the global reference to exist. +/// declare_generic!(counter: WithReference); +/// fn stuff() { +/// // do some stuff, accessing the named reference as desired. +/// counter::with(|i| *i.answer_ref += 1); +/// } +/// fn main() { +/// // declare a stack variable of the same type as our global declaration. +/// let mut answer = 41u32; +/// { +/// let mut ref_struct = WithReference { answer_ref: &mut answer, }; +/// counter::using(&mut ref_struct, stuff); +/// } +/// println!("The answer is {:?}", answer); // will print 42! +/// } +/// ``` #[macro_export] -macro_rules! declare_simple_environment { +macro_rules! declare_generic { ($name:ident : $t:tt) => { mod $name { #[allow(unused_imports)] use super::*; - decl_environment!(GLOBAL: $t); + decl!(GLOBAL: $t<'static> ); pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>( protected: &'b mut T, f: F ) -> R { - $crate::using_environment(&GLOBAL, protected, f) + $crate::using(&GLOBAL, protected, f) } - pub fn with FnOnce(&'r mut $t) -> R>( + pub fn with FnOnce(&'r mut $t<'t>) -> R>( f: F ) -> Option { let dummy = (); with_closed(f, &dummy) } - fn with_closed<'d: 'r, 'r, R, F: FnOnce(&'r mut $t) -> R>( + fn with_closed<'d: 't, 't: 'r, 'r, R, F: FnOnce(&'r mut $t<'t>) -> R>( f: F, _dummy: &'d (), ) -> Option { - $crate::with_environment(&GLOBAL, f) + $crate::with(&GLOBAL, f) } } } @@ -166,7 +233,7 @@ macro_rules! declare_simple_environment { #[cfg(test)] mod tests { - declare_simple_environment!(counter: u32); + declare_simple!(counter: u32); fn stuff() { // do some stuff, accessing the named reference as desired. @@ -174,7 +241,7 @@ mod tests { } #[test] - fn simple_environment_works() { + fn simple_works() { // declare a stack variable of the same type as our global declaration. let mut local = 41u32; // call stuff, setting up our `counter` environment as a refrence to our local counter var. diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index 2926a20891656..93947dde681f8 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -23,7 +23,7 @@ pub struct ExternalitiesHolder<'a> { ext: &'a mut Externalities, } -declare_generic_environment!(ext : ExternalitiesHolder); +declare_generic!(ext : ExternalitiesHolder); pub fn storage(_key: &[u8]) -> Vec { ext::with(|holder| holder.ext.storage(_key).ok().map(|s| s.to_vec())) From 64b067073b1a39a8a16d5b6c02fd267388c98482 Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 11 Jan 2018 18:28:29 +0100 Subject: [PATCH 22/76] Tweak docs --- environmental/src/lib.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/environmental/src/lib.rs b/environmental/src/lib.rs index 0c389e13dc592..e921833301ea8 100644 --- a/environmental/src/lib.rs +++ b/environmental/src/lib.rs @@ -100,13 +100,13 @@ macro_rules! decl { /// Declare a new global reference module whose underlying value does not contain references. /// /// Will create a module of a given name that contains two functions: -/// - `pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>(protected: &'b mut T, f: F) -> R` +/// * `pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>(protected: &'b mut T, f: F) -> R` /// This executes `f`, returning its value. During the call, the module's reference is set to /// be equal to `protected`. -/// - `pub fn with FnOnce(&'r mut $t<'t>) -> R>(f: F) -> Option` -/// This executes `f`, returning its value if called from code that is being executed as part of -/// a `using` call. The function takes one argument: the same reference as provided to the most -/// recent `using` call. +/// * `pub fn with FnOnce(&'r mut $t<'t>) -> R>(f: F) -> Option` +/// This executes `f`, returning `Some` of its value if called from code that is being executed +/// as part of a `using` call. If not, it returns `None`. `f` is provided with one argument: the +/// same reference as provided to the most recent `using` call. /// /// # Examples /// @@ -164,13 +164,14 @@ macro_rules! declare_simple { /// Declare a new global reference module whose underlying value is generic over a reference. /// /// Will create a module of a given name that contains two functions: -/// - `pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>(protected: &'b mut T, f: F) -> R` +/// +/// * `pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>(protected: &'b mut T, f: F) -> R` /// This executes `f`, returning its value. During the call, the module's reference is set to /// be equal to `protected`. -/// - `pub fn with FnOnce(&'r mut $t<'t>) -> R>(f: F) -> Option` -/// This executes `f`, returning its value if called from code that is being executed as part of -/// a `using` call. The function takes one argument: the same reference as provided to the most -/// recent `using` call. +/// * `pub fn with FnOnce(&'r mut $t<'t>) -> R>(f: F) -> Option` +/// This executes `f`, returning `Some` of its value if called from code that is being executed +/// as part of a `using` call. If not, it returns `None`. `f` is provided with one argument: the +/// same reference as provided to the most recent `using` call. /// /// # Examples /// From d34f62a453d8379d1760f251d53f29a5b95b75cc Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 11 Jan 2018 18:29:08 +0100 Subject: [PATCH 23/76] Remove TODOs. --- environmental/src/lib.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/environmental/src/lib.rs b/environmental/src/lib.rs index e921833301ea8..239a2fb90f07b 100644 --- a/environmental/src/lib.rs +++ b/environmental/src/lib.rs @@ -228,10 +228,6 @@ macro_rules! declare_generic { } } -// TODO: Docs -// TODO: Example -// TODO: Tests - #[cfg(test)] mod tests { declare_simple!(counter: u32); From 89f35e3649c726b1e5ec4582b4ad01838411e6fb Mon Sep 17 00:00:00 2001 From: Gav Date: Sun, 14 Jan 2018 20:51:46 +0100 Subject: [PATCH 24/76] Balance transfers + util methods. --- native-runtime/support/src/lib.rs | 2 +- wasm-runtime/polkadot/src/lib.rs | 257 ++++++++++++++++++++++++------ 2 files changed, 212 insertions(+), 47 deletions(-) diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index 93947dde681f8..7bbd6d235e4db 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -8,7 +8,7 @@ pub use std::cell::RefCell; pub use std::boxed::Box; pub use std::mem::{size_of, transmute}; -use polkadot_state_machine::Externalities; +pub use polkadot_state_machine::Externalities; use std::fmt; // TODO: use the real error, not NoError. diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index fb8e5b86f882b..205d2e31a7d46 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -3,7 +3,7 @@ #[macro_use] extern crate runtime_support; -use runtime_support::{set_storage, storage, storage_into, Vec, size_of}; +use runtime_support::{Vec, size_of}; use runtime_support::{Rc, RefCell, transmute, Box}; /// The hash of an ECDSA pub key which is used to identify an external transactor. @@ -93,6 +93,12 @@ struct Environment { block_number: BlockNumber, } +fn with_env T>(f: F) -> T { + let e = env(); + let mut eb = e.borrow_mut(); + f(&mut *eb) +} + fn env() -> Rc> { // Initialize it to a null value static mut SINGLETON: *const Rc> = 0 as *const Rc>; @@ -111,6 +117,77 @@ fn env() -> Rc> { } } +fn value_vec(mut value: u32, initial: Vec) -> Vec { + let mut acc = initial; + while value > 0 { + acc.push(value as u8); + value /= 256; + } + acc +} + +trait EndianSensitive: Sized { + fn to_le(self) -> Self { self } + fn to_be(self) -> Self { self } + fn from_le(self) -> Self { self } + fn from_be(self) -> Self { self } +} + +macro_rules! impl_endians { + ( $( $t:ty ),* ) => { $( + impl EndianSensitive for $t { + fn to_le(self) -> Self { <$t>::to_le(self) } + fn to_be(self) -> Self { <$t>::to_be(self) } + fn from_le(self) -> Self { <$t>::from_le(self) } + fn from_be(self) -> Self { <$t>::from_be(self) } + } + )* } +} +macro_rules! impl_non_endians { + ( $( $t:ty ),* ) => { $( + impl EndianSensitive for $t {} + )* } +} + +impl_endians!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize); +impl_non_endians!([u8; 20], [u8; 32]); + +trait Storage { + fn storage_into(key: &[u8]) -> Self; + fn store(self, key: &[u8]); +} + +impl Storage for T { + fn storage_into(key: &[u8]) -> Self { + runtime_support::storage_into(key).map(EndianSensitive::from_le).unwrap_or_else(Default::default) + } + + fn store(self, key: &[u8]) { + let size = size_of::(); + let value_bytes = self.to_le(); + let value_slice = unsafe { + std::slice::from_raw_parts(transmute::<*const Self, *const u8>(&value_bytes), size) + }; + runtime_support::set_storage(key, value_slice); + } +} + +fn storage_into(key: &[u8]) -> T { + T::storage_into(key) +} + + +trait KeyedVec { + fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec; +} +impl KeyedVec for AccountID { + fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec { + let mut r = prepend_key.to_vec(); + r.extend_from_slice(self); + r + } +} + // TODO: include RLP implementation // TODO: add keccak256 (or some better hashing scheme) & ECDSA-recover (or some better sig scheme) @@ -127,26 +204,27 @@ pub fn execute_transaction(_input: Vec) -> Vec { impl_stubs!(execute_block, execute_transaction); /// The current relay chain identifier. -fn chain_id() -> ChainID { +pub fn chain_id() -> ChainID { // TODO: retrieve from external unimplemented!() } -mod environment { +pub mod environment { use super::*; /// The current block number being processed. Set by `execute_block`. - pub fn block_number() -> BlockNumber { let e = env(); let eb = e.borrow(); eb.block_number } + pub fn block_number() -> BlockNumber { + with_env(|e| e.block_number) + } /// Get the block hash of a given block. - pub fn block_hash(_number: BlockNumber) -> Hash { unimplemented!() } + pub fn block_hash(_number: BlockNumber) -> Hash { + unimplemented!() + } pub fn execute_block(_block: &Block) -> Vec { // populate environment from header. - { - let e = env(); - e.borrow_mut().block_number = _block.header.number; - } + with_env(|e| e.block_number = _block.header.number); staking::pre_transactions(); @@ -174,7 +252,7 @@ mod environment { /// Set the new code. pub fn set_code(new: &[u8]) { - set_storage(b"\0code", new) + runtime_support::set_storage(b"\0code", new) } /// Set the light-client digest for the header. @@ -184,33 +262,24 @@ mod environment { } } -mod consensus { +pub mod consensus { use super::*; - fn value_vec(mut value: usize, initial: Vec) -> Vec { - let mut acc = initial; - while value > 0 { - acc.push(value as u8); - value /= 256; - } - acc - } - - fn set_authority(index: usize, authority: AccountID) { - set_storage(&value_vec(index, b"\0authority".to_vec()), &authority[..]); + pub fn set_authority(index: u32, authority: AccountID) { + runtime_support::set_storage(&value_vec(index, b"\0authority".to_vec()), &authority[..]); } - fn authority(index: usize) -> AccountID { - storage_into(&value_vec(index, b"\0authority".to_vec())).unwrap() + fn authority(index: u32) -> AccountID { + runtime_support::storage_into(&value_vec(index, b"\0authority".to_vec())).unwrap() } - fn set_authority_count(count: usize) { + pub fn set_authority_count(count: u32) { (count..authority_count()).for_each(|i| set_authority(i, SessionKey::default())); - set_storage(b"\0authority_count", &value_vec(count, Vec::new())); + runtime_support::set_storage(b"\0authority_count", &value_vec(count, Vec::new())); } - fn authority_count() -> usize { - storage(b"\0authority_count").into_iter().rev().fold(0, |acc, i| (acc << 8) + (i as usize)) + fn authority_count() -> u32 { + runtime_support::storage(b"\0authority_count").into_iter().rev().fold(0, |acc, i| (acc << 8) + (i as u32)) } /// Get the current set of authorities. These are the session keys. @@ -221,9 +290,9 @@ mod consensus { /// Set the current set of authorities' session keys. /// /// Called by `next_session` only. - fn set_authorities(authorities: &[AccountID]) { - set_authority_count(authorities.len()); - authorities.iter().enumerate().for_each(|(v, &i)| set_authority(v, i)); + pub fn set_authorities(authorities: &[AccountID]) { + set_authority_count(authorities.len() as u32); + authorities.iter().enumerate().for_each(|(v, &i)| set_authority(v as u32, i)); } /// Get the current set of validators. These are the long-term identifiers for the validators @@ -265,35 +334,56 @@ mod consensus { } } -mod staking { +pub mod staking { use super::*; /// The length of a staking era in blocks. - pub fn era_length() -> BlockNumber { sessions_per_era() * consensus::session_length() } + pub fn era_length() -> BlockNumber { + sessions_per_era() * consensus::session_length() + } /// The length of a staking era in sessions. - pub fn sessions_per_era() -> BlockNumber { 10 } + pub fn sessions_per_era() -> BlockNumber { + 10 + } /// The era has changed - enact new staking set. /// /// NOTE: This always happens on a session change. - fn next_era() { unimplemented!() } + pub fn next_era() { + unimplemented!() + } /// The balance of a given account. - fn balance(_who: AccountID) -> Balance { unimplemented!() } + pub fn balance(who: &AccountID) -> Balance { + storage_into(&who.to_keyed_vec(b"sta\0bal\0")) + } /// Transfer some unlocked staking balance to another staker. - pub fn transfer_stake(_transactor: AccountID, _dest: AccountID, _value: Balance) { unimplemented!() } + pub fn transfer_stake(transactor: &AccountID, dest: &AccountID, value: Balance) { + let from_key = transactor.to_keyed_vec(b"sta\0bal\0"); + let from_balance: Balance = storage_into(&from_key); + assert!(from_balance >= value); + let to_key = dest.to_keyed_vec(b"sta\0bal\0"); + let to_balance: Balance = storage_into(&to_key); + assert!(to_balance + value > to_balance); // no overflow + (from_balance - value).store(&from_key); + (to_balance + value).store(&to_key); + } /// Declare the desire to stake for the transactor. /// /// Effects will be felt at the beginning of the next era. - pub fn stake(_transactor: &AccountID) { unimplemented!() } + pub fn stake(_transactor: &AccountID) { + unimplemented!() + } /// Retract the desire to stake for the transactor. /// /// Effects will be felt at the beginning of the next era. - pub fn unstake(_transactor: &AccountID) { unimplemented!() } + pub fn unstake(_transactor: &AccountID) { + unimplemented!() + } /// Hook to be called prior to transaction processing. pub fn pre_transactions() { @@ -307,17 +397,92 @@ mod staking { } } -mod authentication { +pub mod authentication { use super::*; - fn validate_signature(_tx: Transaction) -> ( AccountID, TxOrder ) { unimplemented!() } - fn nonce(_id: AccountID) -> TxOrder { unimplemented!() } - fn authenticate(_tx: Transaction) -> AccountID { unimplemented!() } + pub fn validate_signature(_tx: Transaction) -> ( AccountID, TxOrder ) { + unimplemented!() + } + + pub fn nonce(_id: AccountID) -> TxOrder { + unimplemented!() + } + + pub fn authenticate(_tx: Transaction) -> AccountID { + unimplemented!() + } } -mod timestamp { +pub mod timestamp { use super::*; - fn timestamp() -> Timestamp { unimplemented!() } - fn set_timestamp(_now: Timestamp) { unimplemented!() } + pub fn timestamp() -> Timestamp { + unimplemented!() + } + + pub fn set_timestamp(_now: Timestamp) { + unimplemented!() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + + use std::collections::HashMap; + use runtime_support::{NoError, with_externalities, Externalities}; + + #[derive(Debug, Default)] + struct TestExternalities { + storage: HashMap, Vec>, + } + impl Externalities for TestExternalities { + type Error = NoError; + + fn storage(&self, key: &[u8]) -> Result<&[u8], NoError> { + Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) + } + + fn set_storage(&mut self, key: Vec, value: Vec) { + self.storage.insert(key, value); + } + } + + macro_rules! map { + ($( $name:expr => $value:expr ),*) => ( + vec![ $( ( $name, $value ) ),* ].into_iter().collect() + ) + } + + #[test] + fn staking_balance_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + + let mut t = TestExternalities { storage: map![ + { let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![42u8, 0, 0, 0, 0, 0, 0, 0] + ], }; + + with_externalities(&mut t, || { + assert_eq!(staking::balance(&one), 42); + assert_eq!(staking::balance(&two), 0); + }); + } + + #[test] + fn staking_balance_transfer_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + + let mut t = TestExternalities { storage: map![ + { let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + ], }; + + with_externalities(&mut t, || { + staking::transfer_stake(&one, &two, 69); + assert_eq!(staking::balance(&one), 42); + assert_eq!(staking::balance(&two), 69); + }); + } } From 5e422404ec17ffe3770711e2caeaf07f7fd5287a Mon Sep 17 00:00:00 2001 From: Gav Date: Sun, 14 Jan 2018 23:41:32 +0100 Subject: [PATCH 25/76] Rejig tests and ensure authorities are addressed consistently. --- state_machine/src/lib.rs | 42 +++++++++++++++----------------- wasm-runtime/polkadot/src/lib.rs | 38 ++++++++++++++++++----------- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/state_machine/src/lib.rs b/state_machine/src/lib.rs index 58ba558322ac8..38c481113f21f 100644 --- a/state_machine/src/lib.rs +++ b/state_machine/src/lib.rs @@ -114,13 +114,9 @@ impl OverlayedChanges { pub trait Error: 'static + fmt::Debug + fmt::Display + Send {} impl Error for E where E: 'static + fmt::Debug + fmt::Display + Send {} -fn value_vec(mut value: usize, initial: Vec) -> Vec { - let mut acc = initial; - while value > 0 { - acc.push(value as u8); - value /= 256; - } - acc +fn to_keyed_vec(value: u32, mut prepend: Vec) -> Vec { + prepend.extend((0..::std::mem::size_of::()).into_iter().map(|i| (value >> (i * 8)) as u8)); + prepend } /// Externalities: pinned to specific active address. @@ -134,12 +130,12 @@ pub trait Externalities { /// Set storage of current contract being called (effective immediately). fn set_storage(&mut self, key: Vec, value: Vec); - /// Get the current set of validators. - fn validators(&self) -> Result, Self::Error> { - (0..self.storage(b"\0validator_count")?.into_iter() + /// Get the current set of authorities. + fn authorities(&self) -> Result, Self::Error> { + (0..self.storage(b"con\0aut\0len")?.into_iter() .rev() - .fold(0, |acc, &i| (acc << 8) + (i as usize))) - .map(|i| self.storage(&value_vec(i, b"\0validator".to_vec()))) + .fold(0, |acc, &i| (acc << 8) + (i as u32))) + .map(|i| self.storage(&to_keyed_vec(i, b"con\0aut\0".to_vec()))) .collect() } } @@ -248,22 +244,22 @@ mod tests { } #[test] - fn validators_call_works() { + fn authorities_call_works() { let mut ext = TestExternalities::default(); - assert_eq!(ext.validators(), Ok(vec![])); + assert_eq!(ext.authorities(), Ok(vec![])); - ext.set_storage(b"\0validator_count".to_vec(), vec![]); - assert_eq!(ext.validators(), Ok(vec![])); + ext.set_storage(b"con\0aut\0len".to_vec(), vec![0u8; 4]); + assert_eq!(ext.authorities(), Ok(vec![])); - ext.set_storage(b"\0validator_count".to_vec(), vec![1]); - assert_eq!(ext.validators(), Ok(vec![&[][..]])); + ext.set_storage(b"con\0aut\0len".to_vec(), vec![1u8, 0, 0, 0]); + assert_eq!(ext.authorities(), Ok(vec![&[][..]])); - ext.set_storage(b"\0validator".to_vec(), b"first".to_vec()); - assert_eq!(ext.validators(), Ok(vec![&b"first"[..]])); + ext.set_storage(b"con\0aut\0\0\0\0\0".to_vec(), b"first".to_vec()); + assert_eq!(ext.authorities(), Ok(vec![&b"first"[..]])); - ext.set_storage(b"\0validator_count".to_vec(), vec![2]); - ext.set_storage(b"\0validator\x01".to_vec(), b"second".to_vec()); - assert_eq!(ext.validators(), Ok(vec![&b"first"[..], &b"second"[..]])); + ext.set_storage(b"con\0aut\0len".to_vec(), vec![2u8, 0, 0, 0]); + ext.set_storage(b"con\0aut\0\x01\0\0\0".to_vec(), b"second".to_vec()); + assert_eq!(ext.authorities(), Ok(vec![&b"first"[..], &b"second"[..]])); } } diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 205d2e31a7d46..b54eac0cdf059 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -117,15 +117,6 @@ fn env() -> Rc> { } } -fn value_vec(mut value: u32, initial: Vec) -> Vec { - let mut acc = initial; - while value > 0 { - acc.push(value as u8); - value /= 256; - } - acc -} - trait EndianSensitive: Sized { fn to_le(self) -> Self { self } fn to_be(self) -> Self { self } @@ -176,10 +167,10 @@ fn storage_into(key: &[u8]) -> T { T::storage_into(key) } - trait KeyedVec { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec; } + impl KeyedVec for AccountID { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec { let mut r = prepend_key.to_vec(); @@ -188,6 +179,25 @@ impl KeyedVec for AccountID { } } +macro_rules! impl_endians { + ( $( $t:ty ),* ) => { $( + impl KeyedVec for $t { + fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec { + let size = size_of::(); + let value_bytes = self.to_le(); + let value_slice = unsafe { + std::slice::from_raw_parts(transmute::<*const Self, *const u8>(&value_bytes), size) + }; + let mut r = prepend_key.to_vec(); + r.extend_from_slice(value_slice); + r + } + } + )* } +} + +impl_endians!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize); + // TODO: include RLP implementation // TODO: add keccak256 (or some better hashing scheme) & ECDSA-recover (or some better sig scheme) @@ -266,20 +276,20 @@ pub mod consensus { use super::*; pub fn set_authority(index: u32, authority: AccountID) { - runtime_support::set_storage(&value_vec(index, b"\0authority".to_vec()), &authority[..]); + authority.store(&index.to_keyed_vec(b"con\0aut\0")); } fn authority(index: u32) -> AccountID { - runtime_support::storage_into(&value_vec(index, b"\0authority".to_vec())).unwrap() + storage_into(&index.to_keyed_vec(b"con\0aut\0")) } pub fn set_authority_count(count: u32) { (count..authority_count()).for_each(|i| set_authority(i, SessionKey::default())); - runtime_support::set_storage(b"\0authority_count", &value_vec(count, Vec::new())); + count.store(b"con\0aut\0len"); } fn authority_count() -> u32 { - runtime_support::storage(b"\0authority_count").into_iter().rev().fold(0, |acc, i| (acc << 8) + (i as u32)) + storage_into(b"con\0aut\0len") } /// Get the current set of authorities. These are the session keys. From d97e2d6e21ce602211b8a197d89e4908e572d21f Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 15 Jan 2018 00:01:25 +0100 Subject: [PATCH 26/76] Add marshaller for xfer function --- wasm-runtime/polkadot/src/lib.rs | 36 ++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index b54eac0cdf059..639cdcdbc48ce 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -22,6 +22,7 @@ pub type TxOrder = u64; pub enum Function { StakingStake, StakingUnstake, + StakingTransferStake, ConsensusSetSessionKey, } @@ -35,6 +36,11 @@ impl Function { Function::StakingUnstake => { staking::unstake(transactor); } + Function::StakingTransferStake => { + let dest = FromSlice::from_slice(¶ms[0..size_of::()]).unwrap(); + let value = FromSlice::from_slice(¶ms[size_of::()..size_of::() + 4]).unwrap(); + staking::transfer_stake(transactor, &dest, value); + } Function::ConsensusSetSessionKey => { let mut session = AccountID::default(); session.copy_from_slice(¶ms[0..size_of::()]); @@ -140,8 +146,8 @@ macro_rules! impl_non_endians { )* } } -impl_endians!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize); -impl_non_endians!([u8; 20], [u8; 32]); +impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize); +impl_non_endians!(u8, i8, [u8; 20], [u8; 32]); trait Storage { fn storage_into(key: &[u8]) -> Self; @@ -150,7 +156,9 @@ trait Storage { impl Storage for T { fn storage_into(key: &[u8]) -> Self { - runtime_support::storage_into(key).map(EndianSensitive::from_le).unwrap_or_else(Default::default) + runtime_support::storage_into(key) + .map(EndianSensitive::from_le) + .unwrap_or_else(Default::default) } fn store(self, key: &[u8]) { @@ -167,6 +175,26 @@ fn storage_into(key: &[u8]) -> T { T::storage_into(key) } +trait FromSlice: Sized { + fn from_slice(value: &[u8]) -> Option; +} + +impl FromSlice for T { + fn from_slice(value: &[u8]) -> Option { + let size = size_of::(); + if value.len() == size { + unsafe { + let mut result: T = std::mem::uninitialized(); + std::slice::from_raw_parts_mut(transmute::<*mut T, *mut u8>(&mut result), size) + .copy_from_slice(&value); + Some(result.from_le()) + } + } else { + None + } + } +} + trait KeyedVec { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec; } @@ -196,7 +224,7 @@ macro_rules! impl_endians { )* } } -impl_endians!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize); +impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize); // TODO: include RLP implementation // TODO: add keccak256 (or some better hashing scheme) & ECDSA-recover (or some better sig scheme) From 26ccc1448cb82e1080feda10c83e5c165fdaaafb Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 15 Jan 2018 11:59:54 +0100 Subject: [PATCH 27/76] Transaction dispatch test. --- native-runtime/support/src/lib.rs | 16 ++- wasm-runtime/polkadot/src/lib.rs | 187 ++++++++++++++++++++++++------ 2 files changed, 163 insertions(+), 40 deletions(-) diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index 7bbd6d235e4db..38de2f29b6e90 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -25,12 +25,24 @@ pub struct ExternalitiesHolder<'a> { declare_generic!(ext : ExternalitiesHolder); -pub fn storage(_key: &[u8]) -> Vec { - ext::with(|holder| holder.ext.storage(_key).ok().map(|s| s.to_vec())) +pub fn storage(key: &[u8]) -> Vec { + ext::with(|holder| holder.ext.storage(key).ok().map(|s| s.to_vec())) .unwrap_or(None) .unwrap_or_else(|| vec![]) } +pub fn read_storage(key: &[u8], value_out: &mut [u8]) -> usize { + ext::with(|holder| { + if let Ok(value) = holder.ext.storage(key) { + let written = ::std::cmp::min(value.len(), value_out.len()); + value_out[0..written].copy_from_slice(&value[0..written]); + value.len() + } else { + 0 + } + }).unwrap_or(0) +} + pub fn storage_into(_key: &[u8]) -> Option { let size = size_of::(); diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 639cdcdbc48ce..fa22929a79c84 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -26,9 +26,81 @@ pub enum Function { ConsensusSetSessionKey, } +impl Function { + fn from_u8(value: u8) -> Option { + match value { + x if x == Function::StakingStake as u8 => Some(Function::StakingStake), + x if x == Function::StakingUnstake as u8 => Some(Function::StakingUnstake), + x if x == Function::StakingTransferStake as u8 => Some(Function::StakingTransferStake), + x if x == Function::ConsensusSetSessionKey as u8 => Some(Function::ConsensusSetSessionKey), + _ => None, + } + } +} + +struct StreamReader<'a> { + data: &'a[u8], + offset: usize, +} + +impl<'a> StreamReader<'a> { + fn new(data: &'a[u8]) -> Self { + StreamReader { + data: data, + offset: 0, + } + } + fn read(&mut self) -> Option { + let size = size_of::(); + let new_offset = self.offset + size; + let slice = &self.data[self.offset..new_offset]; + self.offset = new_offset; + Slicable::from_slice(slice) + } +} + +struct StreamWriter<'a> { + data: &'a mut[u8], + offset: usize, +} + +impl<'a> StreamWriter<'a> { + fn new(data: &'a mut[u8]) -> Self { + StreamWriter { + data: data, + offset: 0, + } + } + fn write(&mut self, value: &T) -> bool { + value.as_slice_then(|s| { + let new_offset = self.offset + s.len(); + if self.data.len() <= new_offset { + let slice = &self.data[self.offset..new_offset]; + self.offset = new_offset; + slice.copy_from_slice(s); + true + } else { + false + } + }) + } +} + +trait Joiner { + fn join(self, value: &T) -> Self; +} + +impl Joiner for Vec { + fn join(mut self, value: &T) -> Vec { + value.as_slice_then(|s| self.extend_from_slice(s)); + self + } +} + impl Function { /// Dispatch the function. - pub fn dispatch(&self, transactor: &AccountID, params: &[u8]) { + pub fn dispatch(&self, transactor: &AccountID, data: &[u8]) { + let mut params = StreamReader::new(data); match *self { Function::StakingStake => { staking::stake(transactor); @@ -37,14 +109,13 @@ impl Function { staking::unstake(transactor); } Function::StakingTransferStake => { - let dest = FromSlice::from_slice(¶ms[0..size_of::()]).unwrap(); - let value = FromSlice::from_slice(¶ms[size_of::()..size_of::() + 4]).unwrap(); + let dest = params.read().unwrap(); + let value = params.read().unwrap(); staking::transfer_stake(transactor, &dest, value); } Function::ConsensusSetSessionKey => { - let mut session = AccountID::default(); - session.copy_from_slice(¶ms[0..size_of::()]); - consensus::set_session_key(transactor, session); + let session = params.read().unwrap(); + consensus::set_session_key(transactor, &session); } } } @@ -128,6 +199,8 @@ trait EndianSensitive: Sized { fn to_be(self) -> Self { self } fn from_le(self) -> Self { self } fn from_be(self) -> Self { self } + fn as_be_then T>(&self, f: F) -> T { f(&self) } + fn as_le_then T>(&self, f: F) -> T { f(&self) } } macro_rules! impl_endians { @@ -137,6 +210,8 @@ macro_rules! impl_endians { fn to_be(self) -> Self { <$t>::to_be(self) } fn from_le(self) -> Self { <$t>::from_le(self) } fn from_be(self) -> Self { <$t>::from_be(self) } + fn as_be_then T>(&self, f: F) -> T { let d = self.to_be(); f(&d) } + fn as_le_then T>(&self, f: F) -> T { let d = self.to_le(); f(&d) } } )* } } @@ -151,23 +226,17 @@ impl_non_endians!(u8, i8, [u8; 20], [u8; 32]); trait Storage { fn storage_into(key: &[u8]) -> Self; - fn store(self, key: &[u8]); + fn store(&self, key: &[u8]); } -impl Storage for T { +impl Storage for T { fn storage_into(key: &[u8]) -> Self { - runtime_support::storage_into(key) - .map(EndianSensitive::from_le) + Slicable::set_as_slice(|out| runtime_support::read_storage(key, out) == out.len()) .unwrap_or_else(Default::default) } - fn store(self, key: &[u8]) { - let size = size_of::(); - let value_bytes = self.to_le(); - let value_slice = unsafe { - std::slice::from_raw_parts(transmute::<*const Self, *const u8>(&value_bytes), size) - }; - runtime_support::set_storage(key, value_slice); + fn store(&self, key: &[u8]) { + self.as_slice_then(|slice| runtime_support::set_storage(key, slice)); } } @@ -175,24 +244,47 @@ fn storage_into(key: &[u8]) -> T { T::storage_into(key) } -trait FromSlice: Sized { - fn from_slice(value: &[u8]) -> Option; +/// Trait that allows zero-copy read/write of value-references to/from slices in LE format. +trait Slicable: Sized { + fn from_slice(value: &[u8]) -> Option { + Self::set_as_slice(|out| if value.len() == out.len() { + out.copy_from_slice(&value); + true + } else { + false + }) + } + fn to_vec(&self) -> Vec { + self.as_slice_then(|s| s.to_vec()) + } + fn set_as_slice bool>(set_slice: F) -> Option; + fn as_slice_then R>(&self, f: F) -> R { + f(&self.to_vec()) + } } -impl FromSlice for T { - fn from_slice(value: &[u8]) -> Option { +impl Slicable for T { + fn set_as_slice bool>(fill_slice: F) -> Option { let size = size_of::(); - if value.len() == size { - unsafe { - let mut result: T = std::mem::uninitialized(); - std::slice::from_raw_parts_mut(transmute::<*mut T, *mut u8>(&mut result), size) - .copy_from_slice(&value); - Some(result.from_le()) - } + let mut result: T = unsafe { std::mem::uninitialized() }; + let result_slice = unsafe { + std::slice::from_raw_parts_mut(transmute::<*mut T, *mut u8>(&mut result), size) + }; + if fill_slice(result_slice) { + Some(result.from_le()) } else { None } } + fn as_slice_then R>(&self, f: F) -> R { + let size = size_of::(); + self.as_le_then(|le| { + let value_slice = unsafe { + std::slice::from_raw_parts(transmute::<*const Self, *const u8>(le), size) + }; + f(value_slice) + }) + } } trait KeyedVec { @@ -211,14 +303,11 @@ macro_rules! impl_endians { ( $( $t:ty ),* ) => { $( impl KeyedVec for $t { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec { - let size = size_of::(); - let value_bytes = self.to_le(); - let value_slice = unsafe { - std::slice::from_raw_parts(transmute::<*const Self, *const u8>(&value_bytes), size) - }; - let mut r = prepend_key.to_vec(); - r.extend_from_slice(value_slice); - r + self.as_slice_then(|slice| { + let mut r = prepend_key.to_vec(); + r.extend_from_slice(slice); + r + }) } } )* } @@ -226,7 +315,6 @@ macro_rules! impl_endians { impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize); -// TODO: include RLP implementation // TODO: add keccak256 (or some better hashing scheme) & ECDSA-recover (or some better sig scheme) pub fn execute_block(_input: Vec) -> Vec { @@ -353,7 +441,7 @@ pub mod consensus { /// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next /// session. - pub fn set_session_key(_transactor: &AccountID, _session: AccountID) { + pub fn set_session_key(_transactor: &AccountID, _session: &AccountID) { unimplemented!() } @@ -523,4 +611,27 @@ mod tests { assert_eq!(staking::balance(&two), 69); }); } + + #[test] + fn staking_balance_transfer_dispatch_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + + let mut t = TestExternalities { storage: map![ + { let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + ], }; + + let tx = Transaction { + signed: one.clone(), + function: Function::StakingTransferStake, + input_data: vec![].join(&two).join(&69u64), + nonce: 0, + }; + + with_externalities(&mut t, || { + environment::execute_transaction(&tx); + assert_eq!(staking::balance(&one), 42); + assert_eq!(staking::balance(&two), 69); + }); + } } From 7258e1f58e780b25885288db914ee27b1f49cffd Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 15 Jan 2018 12:01:05 +0100 Subject: [PATCH 28/76] Minor fix. --- wasm-runtime/polkadot/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index fa22929a79c84..02c35675e3cb1 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -75,7 +75,7 @@ impl<'a> StreamWriter<'a> { value.as_slice_then(|s| { let new_offset = self.offset + s.len(); if self.data.len() <= new_offset { - let slice = &self.data[self.offset..new_offset]; + let slice = &mut self.data[self.offset..new_offset]; self.offset = new_offset; slice.copy_from_slice(s); true From c02e335212fafa45aa85a58954330123dbc8aedc Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 15 Jan 2018 18:30:04 +0100 Subject: [PATCH 29/76] Add test for ser/de transaction. --- wasm-runtime/polkadot/src/lib.rs | 93 ++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 5 deletions(-) diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 02c35675e3cb1..39cab5def1cd1 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -19,6 +19,8 @@ pub type Timestamp = u64; pub type TxOrder = u64; /// The functions that a transaction can call (and be dispatched to). +#[cfg_attr(test, derive(PartialEq, Debug))] +#[derive(Clone, Copy)] pub enum Function { StakingStake, StakingUnstake, @@ -50,8 +52,8 @@ impl<'a> StreamReader<'a> { offset: 0, } } - fn read(&mut self) -> Option { - let size = size_of::(); + fn read(&mut self) -> Option { + let size = T::size_of(&self.data[self.offset..])?; let new_offset = self.offset + size; let slice = &self.data[self.offset..new_offset]; self.offset = new_offset; @@ -71,7 +73,7 @@ impl<'a> StreamWriter<'a> { offset: 0, } } - fn write(&mut self, value: &T) -> bool { + fn write(&mut self, value: &T) -> bool { value.as_slice_then(|s| { let new_offset = self.offset + s.len(); if self.data.len() <= new_offset { @@ -135,6 +137,7 @@ pub struct Header { pub digest: Digest, } +#[cfg_attr(test, derive(PartialEq, Debug))] pub struct Transaction { pub signed: AccountID, pub function: Function, @@ -261,6 +264,7 @@ trait Slicable: Sized { fn as_slice_then R>(&self, f: F) -> R { f(&self.to_vec()) } + fn size_of(_value: &[u8]) -> Option; } impl Slicable for T { @@ -285,6 +289,56 @@ impl Slicable for T { f(value_slice) }) } + fn size_of(_value: &[u8]) -> Option { + Some(size_of::()) + } +} + +impl Slicable for Vec { + fn from_slice(value: &[u8]) -> Option { + Some(value[4..].to_vec()) + } + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + fn to_vec(&self) -> Vec { + let mut r = vec![].join(&(self.len() as u32)); + r.extend_from_slice(&self); + r + } + fn size_of(data: &[u8]) -> Option { + u32::from_slice(&data[0..4]).map(|i| (i + 4) as usize) + } +} + +impl Slicable for Transaction { + fn from_slice(value: &[u8]) -> Option { + let mut reader = StreamReader::new(value); + Some(Transaction { + signed: reader.read()?, + function: Function::from_u8(reader.read()?)?, + nonce: reader.read()?, + input_data: reader.read()?, + }) + } + + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + + fn to_vec(&self) -> Vec { + vec![] + .join(&self.signed) + .join(&(self.function as u8)) + .join(&self.nonce) + .join(&self.input_data) + } + + fn size_of(data: &[u8]) -> Option { + let first_part = size_of::() + size_of::() + size_of::(); + let second_part = >::size_of(&data[first_part..])?; + Some(first_part + second_part) + } } trait KeyedVec { @@ -436,7 +490,7 @@ pub mod consensus { /// The number of blocks in each session. pub fn session_length() -> BlockNumber { - 10 + storage_into(b"con\0sel") } /// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next @@ -470,7 +524,7 @@ pub mod staking { /// The length of a staking era in sessions. pub fn sessions_per_era() -> BlockNumber { - 10 + storage_into(b"sta\0spe") } /// The era has changed - enact new staking set. @@ -634,4 +688,33 @@ mod tests { assert_eq!(staking::balance(&two), 69); }); } + + #[test] + fn serialise_transaction_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + let tx = Transaction { + signed: one.clone(), + function: Function::StakingTransferStake, + input_data: vec![].join(&two).join(&69u64), + nonce: 0, + }; + let serialised = tx.to_vec(); + assert_eq!(serialised, vec![1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 0, 0, 0, 0, 0, 0, 0]); + } + + #[test] + fn deserialise_transaction_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + let tx = Transaction { + signed: one.clone(), + function: Function::StakingTransferStake, + input_data: vec![].join(&two).join(&69u64), + nonce: 0, + }; + let data = [1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 0, 0, 0, 0, 0, 0, 0]; + let deserialised: Transaction = Slicable::from_slice(&data).unwrap(); + assert_eq!(deserialised, tx); + } } From 28fa76182435bd52494a67253d5aa36bfe3d41c4 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 15 Jan 2018 23:03:38 +0100 Subject: [PATCH 30/76] Add ser/de for header. --- wasm-runtime/polkadot/src/lib.rs | 73 ++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 39cab5def1cd1..120c5562cde10 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -124,11 +124,13 @@ impl Function { } #[derive(Clone)] +#[cfg_attr(test, derive(PartialEq, Debug))] pub struct Digest { pub logs: Vec>, } #[derive(Clone)] +#[cfg_attr(test, derive(PartialEq, Debug))] pub struct Header { pub parent_hash: Hash, pub number: BlockNumber, @@ -145,6 +147,7 @@ pub struct Transaction { pub nonce: TxOrder, } +#[cfg_attr(test, derive(PartialEq, Debug))] pub struct Block { pub header: Header, pub transactions: Vec, @@ -267,6 +270,8 @@ trait Slicable: Sized { fn size_of(_value: &[u8]) -> Option; } +trait NonTrivialSlicable: Slicable {} + impl Slicable for T { fn set_as_slice bool>(fill_slice: F) -> Option { let size = size_of::(); @@ -341,6 +346,72 @@ impl Slicable for Transaction { } } +impl NonTrivialSlicable for Transaction {} + +impl NonTrivialSlicable for Vec where Vec: Slicable {} + +impl Slicable for Vec { + fn from_slice(value: &[u8]) -> Option { + let len = Self::size_of(&value[0..4])?; + let mut off = 4; + let mut r = vec![]; + while off < len { + let element_len = T::size_of(&value[off..])?; + r.push(T::from_slice(&value[off..off + element_len])?); + off += element_len; + } + Some(r) + } + + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + + fn to_vec(&self) -> Vec { + let vecs = self.iter().map(Slicable::to_vec).collect::>(); + let len = vecs.iter().fold(0, |mut a, v| {a += v.len(); a}); + let mut r = vec![].join(&(len as u32)); + vecs.iter().for_each(|v| r.extend_from_slice(v)); + r + } + + fn size_of(data: &[u8]) -> Option { + u32::from_slice(&data[0..4]).map(|i| (i + 4) as usize) + } +} + +impl Slicable for Header { + fn from_slice(value: &[u8]) -> Option { + let mut reader = StreamReader::new(value); + Some(Header { + parent_hash: reader.read()?, + number: reader.read()?, + state_root: reader.read()?, + transaction_root: reader.read()?, + digest: Digest { logs: reader.read()?, }, + }) + } + + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + + fn to_vec(&self) -> Vec { + vec![] + .join(&self.parent_hash) + .join(&self.number) + .join(&self.state_root) + .join(&self.transaction_root) + .join(&self.digest.logs) + } + + fn size_of(data: &[u8]) -> Option { + let first_part = size_of::() + size_of::() + size_of::() + size_of::(); + let second_part = >>::size_of(&data[first_part..])?; + Some(first_part + second_part) + } +} + trait KeyedVec { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec; } @@ -717,4 +788,6 @@ mod tests { let deserialised: Transaction = Slicable::from_slice(&data).unwrap(); assert_eq!(deserialised, tx); } + + // TODO: Ser/de Header. } From cd93a37b41b219fd38d3616470be80b78067c50d Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 16 Jan 2018 15:56:05 +0100 Subject: [PATCH 31/76] Add tests for header ser/de --- wasm-runtime/polkadot/src/lib.rs | 77 ++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 8 deletions(-) diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 120c5562cde10..ea6030f1cbcf9 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -60,7 +60,9 @@ impl<'a> StreamReader<'a> { Slicable::from_slice(slice) } } - +/* +// Not in use yet +// TODO: introduce fn size_will_be(&self) -> usize; to Slicable trait and implement struct StreamWriter<'a> { data: &'a mut[u8], offset: usize, @@ -87,7 +89,7 @@ impl<'a> StreamWriter<'a> { }) } } - +*/ trait Joiner { fn join(self, value: &T) -> Self; } @@ -768,10 +770,17 @@ mod tests { signed: one.clone(), function: Function::StakingTransferStake, input_data: vec![].join(&two).join(&69u64), - nonce: 0, + nonce: 69, }; let serialised = tx.to_vec(); - assert_eq!(serialised, vec![1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 0, 0, 0, 0, 0, 0, 0]); + assert_eq!(serialised, vec![ + 1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, + 69, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 69, 0, 0, 0, 0, 0, 0, 0 + ]); } #[test] @@ -782,12 +791,64 @@ mod tests { signed: one.clone(), function: Function::StakingTransferStake, input_data: vec![].join(&two).join(&69u64), - nonce: 0, + nonce: 69, }; - let data = [1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 0, 0, 0, 0, 0, 0, 0]; - let deserialised: Transaction = Slicable::from_slice(&data).unwrap(); + let data = [ + 1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, + 69, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 69, 0, 0, 0, 0, 0, 0, 0 + ]; + let deserialised = Transaction::from_slice(&data).unwrap(); assert_eq!(deserialised, tx); } - // TODO: Ser/de Header. + #[test] + fn serialise_header_works() { + let h = Header { + parent_hash: [4u8; 32], + number: 42, + state_root: [5u8; 32], + transaction_root: [6u8; 32], + digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, + }; + let serialised = h.to_vec(); + assert_eq!(serialised, vec![ + 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 42, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 26, 0, 0, 0, + 7, 0, 0, 0, + 111, 110, 101, 32, 108, 111, 103, + 11, 0, 0, 0, + 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103 + ]); + } + + #[test] + fn deserialise_header_works() { + let h = Header { + parent_hash: [4u8; 32], + number: 42, + state_root: [5u8; 32], + transaction_root: [6u8; 32], + digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, + }; + let data = [ + 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 42, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 26, 0, 0, 0, + 7, 0, 0, 0, + 111, 110, 101, 32, 108, 111, 103, + 11, 0, 0, 0, + 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103 + ]; + let deserialised = Header::from_slice(&data).unwrap(); + assert_eq!(deserialised, h); + } } From b55095adfe5f8fd27e79ffe2400060cd903cc9b6 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 16 Jan 2018 16:32:22 +0100 Subject: [PATCH 32/76] Introduce basic block decoding/execution framework. --- native-runtime/support/src/lib.rs | 2 +- wasm-runtime/polkadot/src/lib.rs | 189 +++++++++++++++++++++++++++--- wasm-runtime/support/src/lib.rs | 2 +- 3 files changed, 177 insertions(+), 16 deletions(-) diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index 38de2f29b6e90..c1805d2d2268c 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -6,7 +6,7 @@ pub use std::vec::Vec; pub use std::rc::Rc; pub use std::cell::RefCell; pub use std::boxed::Box; -pub use std::mem::{size_of, transmute}; +pub use std::mem::{size_of, transmute, swap}; pub use polkadot_state_machine::Externalities; use std::fmt; diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index ea6030f1cbcf9..3b3530fcaae4e 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -3,8 +3,7 @@ #[macro_use] extern crate runtime_support; -use runtime_support::{Vec, size_of}; -use runtime_support::{Rc, RefCell, transmute, Box}; +use runtime_support::{Vec, size_of, Rc, RefCell, transmute, swap, Box}; /// The hash of an ECDSA pub key which is used to identify an external transactor. pub type AccountID = [u8; 32]; @@ -125,7 +124,7 @@ impl Function { } } -#[derive(Clone)] +#[derive(Clone, Default)] #[cfg_attr(test, derive(PartialEq, Debug))] pub struct Digest { pub logs: Vec>, @@ -176,6 +175,8 @@ impl Block { #[derive(Default)] struct Environment { block_number: BlockNumber, + digest: Digest, + next_log_index: usize, } fn with_env T>(f: F) -> T { @@ -414,6 +415,32 @@ impl Slicable for Header { } } +impl Slicable for Block { + fn from_slice(value: &[u8]) -> Option { + let mut reader = StreamReader::new(value); + Some(Block { + header: reader.read()?, + transactions: reader.read()?, + }) + } + + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + + fn to_vec(&self) -> Vec { + vec![] + .join(&self.header) + .join(&self.transactions) + } + + fn size_of(data: &[u8]) -> Option { + let first_part = Header::size_of(data)?; + let second_part = >::size_of(&data[first_part..])?; + Some(first_part + second_part) + } +} + trait KeyedVec { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec; } @@ -444,14 +471,12 @@ impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize); // TODO: add keccak256 (or some better hashing scheme) & ECDSA-recover (or some better sig scheme) -pub fn execute_block(_input: Vec) -> Vec { - let block = Block::from_rlp(&_input); - environment::execute_block(&block) +pub fn execute_block(input: Vec) -> Vec { + environment::execute_block(Block::from_slice(&input).unwrap()) } -pub fn execute_transaction(_input: Vec) -> Vec { - let tx = Transaction::from_rlp(&_input); - environment::execute_transaction(&tx) +pub fn execute_transaction(input: Vec) -> Vec { + environment::execute_transaction(&Transaction::from_slice(&input).unwrap()) } impl_stubs!(execute_block, execute_transaction); @@ -470,26 +495,49 @@ pub mod environment { with_env(|e| e.block_number) } - /// Get the block hash of a given block. + /// Get the block hash of a given block (uses storage). pub fn block_hash(_number: BlockNumber) -> Hash { unimplemented!() } - pub fn execute_block(_block: &Block) -> Vec { + /// Deposits a log and ensures it matches the blocks log data. + pub fn deposit_log(log: &[u8]) { + with_env(|e| { + assert_eq!(log, &e.digest.logs[e.next_log_index][..]); + e.next_log_index += 1; + }); + } + + pub fn execute_block(mut block: Block) -> Vec { // populate environment from header. - with_env(|e| e.block_number = _block.header.number); + with_env(|e| { + e.block_number = block.header.number; + swap(&mut e.digest, &mut block.header.digest); + e.next_log_index = 0; + }); + + // TODO: check transaction trie root represents the transactions. + // TODO: store the header in state. staking::pre_transactions(); - // TODO: go through each transaction and use execute_transaction to execute. + block.transactions.iter().for_each(|tx| { execute_transaction(tx); }); staking::post_transactions(); - // TODO: ensure digest in header is what we expect from transactions. + final_checks(&block); + + // TODO: check state root somehow Vec::new() } + fn final_checks(_block: &Block) { + with_env(|e| { + assert_eq!(e.next_log_index, e.digest.logs.len()); + }); + } + /// Execute a given transaction. pub fn execute_transaction(_tx: &Transaction) -> Vec { // TODO: decode data and ensure valid @@ -851,4 +899,117 @@ mod tests { let deserialised = Header::from_slice(&data).unwrap(); assert_eq!(deserialised, h); } + + #[test] + fn serialise_block_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + let tx1 = Transaction { + signed: one.clone(), + function: Function::StakingTransferStake, + input_data: vec![].join(&two).join(&69u64), + nonce: 69, + }; + let tx2 = Transaction { + signed: two.clone(), + function: Function::StakingStake, + input_data: vec![], + nonce: 42, + }; + let h = Header { + parent_hash: [4u8; 32], + number: 42, + state_root: [5u8; 32], + transaction_root: [6u8; 32], + digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, + }; + let b = Block { + header: h, + transactions: vec![tx1, tx2], + }; + let serialised = b.to_vec(); + assert_eq!(serialised, vec![ + // header + 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 42, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 26, 0, 0, 0, + 7, 0, 0, 0, + 111, 110, 101, 32, 108, 111, 103, + 11, 0, 0, 0, + 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103, + // transactions + 130, 0, 0, 0, + // tx1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, + 69, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 69, 0, 0, 0, 0, 0, 0, 0, + // tx2 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, + 42, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 + ]); + } + + #[test] + fn deserialise_block_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + let tx1 = Transaction { + signed: one.clone(), + function: Function::StakingTransferStake, + input_data: vec![].join(&two).join(&69u64), + nonce: 69, + }; + let tx2 = Transaction { + signed: two.clone(), + function: Function::StakingStake, + input_data: vec![], + nonce: 42, + }; + let h = Header { + parent_hash: [4u8; 32], + number: 42, + state_root: [5u8; 32], + transaction_root: [6u8; 32], + digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, + }; + let b = Block { + header: h, + transactions: vec![tx1, tx2], + }; + let data = [ + // header + 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 42, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 26, 0, 0, 0, + 7, 0, 0, 0, + 111, 110, 101, 32, 108, 111, 103, + 11, 0, 0, 0, + 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103, + // transactions + 130, 0, 0, 0, + // tx1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, + 69, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 69, 0, 0, 0, 0, 0, 0, 0, + // tx2 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, + 42, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 + ]; + let deserialised = Block::from_slice(&data).unwrap(); + assert_eq!(deserialised, b); + } } diff --git a/wasm-runtime/support/src/lib.rs b/wasm-runtime/support/src/lib.rs index 3acad5237e35b..9c64f1a72bbc5 100644 --- a/wasm-runtime/support/src/lib.rs +++ b/wasm-runtime/support/src/lib.rs @@ -9,7 +9,7 @@ extern crate alloc; pub use alloc::vec::Vec; pub use alloc::boxed::Box; pub use alloc::rc::Rc; -pub use core::mem::{transmute, size_of, uninitialized}; +pub use core::mem::{transmute, size_of, uninitialized, swap}; pub use core::cell::{RefCell, Ref, RefMut}; extern crate pwasm_libc; From 288f65351b9c728687f414f1c1d1325b64d7e0be Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 16 Jan 2018 16:33:05 +0100 Subject: [PATCH 33/76] Introduce block decoding/execution framework (p2) --- wasm-runtime/polkadot/src/lib.rs | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 3b3530fcaae4e..533a6ad927d30 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -517,7 +517,7 @@ pub mod environment { }); // TODO: check transaction trie root represents the transactions. - // TODO: store the header in state. + // TODO: store the header hash in storage. staking::pre_transactions(); @@ -542,6 +542,8 @@ pub mod environment { pub fn execute_transaction(_tx: &Transaction) -> Vec { // TODO: decode data and ensure valid // TODO: ensure signature valid and recover id (use authentication::authenticate) + // TODO: check nonce + // TODO: increment nonce in storage // TODO: ensure target_function valid // TODO: decode parameters @@ -555,12 +557,6 @@ pub mod environment { pub fn set_code(new: &[u8]) { runtime_support::set_storage(b"\0code", new) } - - /// Set the light-client digest for the header. - pub fn set_digest(_preserialised_rlp_digest: &[u8]) { - // TODO: Mention this to the external environment? - unimplemented!() - } } pub mod consensus { @@ -611,7 +607,7 @@ pub mod consensus { /// The number of blocks in each session. pub fn session_length() -> BlockNumber { - storage_into(b"con\0sel") + storage_into(b"con\0bps") } /// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next @@ -698,22 +694,6 @@ pub mod staking { } } -pub mod authentication { - use super::*; - - pub fn validate_signature(_tx: Transaction) -> ( AccountID, TxOrder ) { - unimplemented!() - } - - pub fn nonce(_id: AccountID) -> TxOrder { - unimplemented!() - } - - pub fn authenticate(_tx: Transaction) -> AccountID { - unimplemented!() - } -} - pub mod timestamp { use super::*; From c64976b22db3e08f3ccf45fb8259fb2c2f9d69ca Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 16 Jan 2018 17:55:07 +0100 Subject: [PATCH 34/76] Big refactor. --- native-runtime/support/src/lib.rs | 3 +- wasm-runtime/polkadot/src/consensus.rs | 72 ++ wasm-runtime/polkadot/src/endiansensitive.rs | 29 + wasm-runtime/polkadot/src/environment.rs | 33 + wasm-runtime/polkadot/src/function.rs | 50 + wasm-runtime/polkadot/src/keyedvec.rs | 30 + wasm-runtime/polkadot/src/lib.rs | 996 +------------------ wasm-runtime/polkadot/src/primitives.rs | 378 +++++++ wasm-runtime/polkadot/src/slicable.rs | 69 ++ wasm-runtime/polkadot/src/staking.rs | 109 ++ wasm-runtime/polkadot/src/storage.rs | 23 + wasm-runtime/polkadot/src/streamreader.rs | 63 ++ wasm-runtime/polkadot/src/system.rs | 129 +++ wasm-runtime/polkadot/src/testing.rs | 19 + wasm-runtime/polkadot/src/timestamp.rs | 9 + 15 files changed, 1038 insertions(+), 974 deletions(-) create mode 100644 wasm-runtime/polkadot/src/consensus.rs create mode 100644 wasm-runtime/polkadot/src/endiansensitive.rs create mode 100644 wasm-runtime/polkadot/src/environment.rs create mode 100644 wasm-runtime/polkadot/src/function.rs create mode 100644 wasm-runtime/polkadot/src/keyedvec.rs create mode 100644 wasm-runtime/polkadot/src/primitives.rs create mode 100644 wasm-runtime/polkadot/src/slicable.rs create mode 100644 wasm-runtime/polkadot/src/staking.rs create mode 100644 wasm-runtime/polkadot/src/storage.rs create mode 100644 wasm-runtime/polkadot/src/streamreader.rs create mode 100644 wasm-runtime/polkadot/src/system.rs create mode 100644 wasm-runtime/polkadot/src/testing.rs create mode 100644 wasm-runtime/polkadot/src/timestamp.rs diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index c1805d2d2268c..795cae2ffd9b4 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -6,7 +6,8 @@ pub use std::vec::Vec; pub use std::rc::Rc; pub use std::cell::RefCell; pub use std::boxed::Box; -pub use std::mem::{size_of, transmute, swap}; +pub use std::slice; +pub use std::mem::{size_of, transmute, swap, uninitialized}; pub use polkadot_state_machine::Externalities; use std::fmt; diff --git a/wasm-runtime/polkadot/src/consensus.rs b/wasm-runtime/polkadot/src/consensus.rs new file mode 100644 index 0000000000000..ef4d5a985692a --- /dev/null +++ b/wasm-runtime/polkadot/src/consensus.rs @@ -0,0 +1,72 @@ +use keyedvec::KeyedVec; +use storage::Storage; +use primitives::{AccountID, SessionKey, BlockNumber}; +use storage::storage_into; + +pub fn set_authority(index: u32, authority: AccountID) { + authority.store(&index.to_keyed_vec(b"con\0aut\0")); +} + +fn authority(index: u32) -> AccountID { + storage_into(&index.to_keyed_vec(b"con\0aut\0")) +} + +pub fn set_authority_count(count: u32) { + (count..authority_count()).for_each(|i| set_authority(i, SessionKey::default())); + count.store(b"con\0aut\0len"); +} + +fn authority_count() -> u32 { + storage_into(b"con\0aut\0len") +} + +/// Get the current set of authorities. These are the session keys. +pub fn authorities() -> Vec { + (0..authority_count()).into_iter().map(authority).collect() +} + +/// Set the current set of authorities' session keys. +/// +/// Called by `next_session` only. +pub fn set_authorities(authorities: &[AccountID]) { + set_authority_count(authorities.len() as u32); + authorities.iter().enumerate().for_each(|(v, &i)| set_authority(v as u32, i)); +} + +/// Get the current set of validators. These are the long-term identifiers for the validators +/// and will be mapped to a session key with the most recent `set_next_session_key`. +pub fn validators() -> Vec { + unimplemented!() +} + +/// Set the current set of validators. +/// +/// Called by staking::next_era() only. +pub fn set_validators(_new: &[AccountID]) { + unimplemented!() +} + +/// The number of blocks in each session. +pub fn session_length() -> BlockNumber { + storage_into(b"con\0bps") +} + +/// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next +/// session. +pub fn set_session_key(_transactor: &AccountID, _session: &AccountID) { + unimplemented!() +} + +/// Move onto next session: register the new authority set. +pub fn next_session() { + // TODO: Call set_authorities(). + unimplemented!() +} + +/// Hook to be called prior to transaction processing. +pub fn pre_transactions() {} + +/// Hook to be called after to transaction processing. +pub fn post_transactions() { + // TODO: check block number and call next_session if necessary. +} diff --git a/wasm-runtime/polkadot/src/endiansensitive.rs b/wasm-runtime/polkadot/src/endiansensitive.rs new file mode 100644 index 0000000000000..c13a96f23d341 --- /dev/null +++ b/wasm-runtime/polkadot/src/endiansensitive.rs @@ -0,0 +1,29 @@ +pub trait EndianSensitive: Sized { + fn to_le(self) -> Self { self } + fn to_be(self) -> Self { self } + fn from_le(self) -> Self { self } + fn from_be(self) -> Self { self } + fn as_be_then T>(&self, f: F) -> T { f(&self) } + fn as_le_then T>(&self, f: F) -> T { f(&self) } +} + +macro_rules! impl_endians { + ( $( $t:ty ),* ) => { $( + impl EndianSensitive for $t { + fn to_le(self) -> Self { <$t>::to_le(self) } + fn to_be(self) -> Self { <$t>::to_be(self) } + fn from_le(self) -> Self { <$t>::from_le(self) } + fn from_be(self) -> Self { <$t>::from_be(self) } + fn as_be_then T>(&self, f: F) -> T { let d = self.to_be(); f(&d) } + fn as_le_then T>(&self, f: F) -> T { let d = self.to_le(); f(&d) } + } + )* } +} +macro_rules! impl_non_endians { + ( $( $t:ty ),* ) => { $( + impl EndianSensitive for $t {} + )* } +} + +impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize); +impl_non_endians!(u8, i8, [u8; 20], [u8; 32]); diff --git a/wasm-runtime/polkadot/src/environment.rs b/wasm-runtime/polkadot/src/environment.rs new file mode 100644 index 0000000000000..4d8ac354a835e --- /dev/null +++ b/wasm-runtime/polkadot/src/environment.rs @@ -0,0 +1,33 @@ +use runtime_support::{Rc, RefCell, transmute, Box}; +use primitives::{BlockNumber, Digest}; + +#[derive(Default)] +pub struct Environment { + pub block_number: BlockNumber, + pub digest: Digest, + pub next_log_index: usize, +} + +pub fn with_env T>(f: F) -> T { + let e = env(); + let mut eb = e.borrow_mut(); + f(&mut *eb) +} + +pub fn env() -> Rc> { + // Initialize it to a null value + static mut SINGLETON: *const Rc> = 0 as *const Rc>; + + unsafe { + if SINGLETON == 0 as *const Rc> { + // Make it + let singleton: Rc> = Rc::new(RefCell::new(Default::default())); + + // Put it in the heap so it can outlive this call + SINGLETON = transmute(Box::new(singleton)); + } + + // Now we give out a copy of the data that is safe to use concurrently. + (*SINGLETON).clone() + } +} diff --git a/wasm-runtime/polkadot/src/function.rs b/wasm-runtime/polkadot/src/function.rs new file mode 100644 index 0000000000000..3f6845bfe6cfb --- /dev/null +++ b/wasm-runtime/polkadot/src/function.rs @@ -0,0 +1,50 @@ +use staking; +use consensus; +use primitives::AccountID; +use streamreader::StreamReader; + +/// The functions that a transaction can call (and be dispatched to). +#[cfg_attr(test, derive(PartialEq, Debug))] +#[derive(Clone, Copy)] +pub enum Function { + StakingStake, + StakingUnstake, + StakingTransferStake, + ConsensusSetSessionKey, +} + +impl Function { + pub fn from_u8(value: u8) -> Option { + match value { + x if x == Function::StakingStake as u8 => Some(Function::StakingStake), + x if x == Function::StakingUnstake as u8 => Some(Function::StakingUnstake), + x if x == Function::StakingTransferStake as u8 => Some(Function::StakingTransferStake), + x if x == Function::ConsensusSetSessionKey as u8 => Some(Function::ConsensusSetSessionKey), + _ => None, + } + } +} + +impl Function { + /// Dispatch the function. + pub fn dispatch(&self, transactor: &AccountID, data: &[u8]) { + let mut params = StreamReader::new(data); + match *self { + Function::StakingStake => { + staking::stake(transactor); + } + Function::StakingUnstake => { + staking::unstake(transactor); + } + Function::StakingTransferStake => { + let dest = params.read().unwrap(); + let value = params.read().unwrap(); + staking::transfer_stake(transactor, &dest, value); + } + Function::ConsensusSetSessionKey => { + let session = params.read().unwrap(); + consensus::set_session_key(transactor, &session); + } + } + } +} diff --git a/wasm-runtime/polkadot/src/keyedvec.rs b/wasm-runtime/polkadot/src/keyedvec.rs new file mode 100644 index 0000000000000..3b0e595628dba --- /dev/null +++ b/wasm-runtime/polkadot/src/keyedvec.rs @@ -0,0 +1,30 @@ +use primitives::AccountID; +use slicable::Slicable; + +pub trait KeyedVec { + fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec; +} + +impl KeyedVec for AccountID { + fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec { + let mut r = prepend_key.to_vec(); + r.extend_from_slice(self); + r + } +} + +macro_rules! impl_endians { + ( $( $t:ty ),* ) => { $( + impl KeyedVec for $t { + fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec { + self.as_slice_then(|slice| { + let mut r = prepend_key.to_vec(); + r.extend_from_slice(slice); + r + }) + } + } + )* } +} + +impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize); diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 533a6ad927d30..e64a3c2a6b28e 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -3,480 +3,37 @@ #[macro_use] extern crate runtime_support; -use runtime_support::{Vec, size_of, Rc, RefCell, transmute, swap, Box}; -/// The hash of an ECDSA pub key which is used to identify an external transactor. -pub type AccountID = [u8; 32]; -/// The ECDSA pub key of an authority. This is what the external environment/consensus algorithm -/// refers to as a "authority". -pub type SessionKey = AccountID; -pub type Balance = u64; -pub type ChainID = u64; -pub type Hash = [u8; 32]; -pub type BlockNumber = u64; -pub type Timestamp = u64; -pub type TxOrder = u64; - -/// The functions that a transaction can call (and be dispatched to). -#[cfg_attr(test, derive(PartialEq, Debug))] -#[derive(Clone, Copy)] -pub enum Function { - StakingStake, - StakingUnstake, - StakingTransferStake, - ConsensusSetSessionKey, -} - -impl Function { - fn from_u8(value: u8) -> Option { - match value { - x if x == Function::StakingStake as u8 => Some(Function::StakingStake), - x if x == Function::StakingUnstake as u8 => Some(Function::StakingUnstake), - x if x == Function::StakingTransferStake as u8 => Some(Function::StakingTransferStake), - x if x == Function::ConsensusSetSessionKey as u8 => Some(Function::ConsensusSetSessionKey), - _ => None, - } - } -} - -struct StreamReader<'a> { - data: &'a[u8], - offset: usize, -} - -impl<'a> StreamReader<'a> { - fn new(data: &'a[u8]) -> Self { - StreamReader { - data: data, - offset: 0, - } - } - fn read(&mut self) -> Option { - let size = T::size_of(&self.data[self.offset..])?; - let new_offset = self.offset + size; - let slice = &self.data[self.offset..new_offset]; - self.offset = new_offset; - Slicable::from_slice(slice) - } -} -/* -// Not in use yet -// TODO: introduce fn size_will_be(&self) -> usize; to Slicable trait and implement -struct StreamWriter<'a> { - data: &'a mut[u8], - offset: usize, -} - -impl<'a> StreamWriter<'a> { - fn new(data: &'a mut[u8]) -> Self { - StreamWriter { - data: data, - offset: 0, - } - } - fn write(&mut self, value: &T) -> bool { - value.as_slice_then(|s| { - let new_offset = self.offset + s.len(); - if self.data.len() <= new_offset { - let slice = &mut self.data[self.offset..new_offset]; - self.offset = new_offset; - slice.copy_from_slice(s); - true - } else { - false - } - }) - } -} -*/ -trait Joiner { - fn join(self, value: &T) -> Self; -} - -impl Joiner for Vec { - fn join(mut self, value: &T) -> Vec { - value.as_slice_then(|s| self.extend_from_slice(s)); - self - } -} - -impl Function { - /// Dispatch the function. - pub fn dispatch(&self, transactor: &AccountID, data: &[u8]) { - let mut params = StreamReader::new(data); - match *self { - Function::StakingStake => { - staking::stake(transactor); - } - Function::StakingUnstake => { - staking::unstake(transactor); - } - Function::StakingTransferStake => { - let dest = params.read().unwrap(); - let value = params.read().unwrap(); - staking::transfer_stake(transactor, &dest, value); - } - Function::ConsensusSetSessionKey => { - let session = params.read().unwrap(); - consensus::set_session_key(transactor, &session); - } - } - } -} - -#[derive(Clone, Default)] -#[cfg_attr(test, derive(PartialEq, Debug))] -pub struct Digest { - pub logs: Vec>, -} - -#[derive(Clone)] -#[cfg_attr(test, derive(PartialEq, Debug))] -pub struct Header { - pub parent_hash: Hash, - pub number: BlockNumber, - pub state_root: Hash, - pub transaction_root: Hash, - pub digest: Digest, -} - -#[cfg_attr(test, derive(PartialEq, Debug))] -pub struct Transaction { - pub signed: AccountID, - pub function: Function, - pub input_data: Vec, - pub nonce: TxOrder, -} - -#[cfg_attr(test, derive(PartialEq, Debug))] -pub struct Block { - pub header: Header, - pub transactions: Vec, -} - -impl Header { - pub fn from_rlp(_rlp: &[u8]) -> Self { - unimplemented!() - } -} - -impl Transaction { - pub fn from_rlp(_rlp: &[u8]) -> Self { - unimplemented!() - } -} - -impl Block { - pub fn from_rlp(_rlp: &[u8]) -> Self { - unimplemented!() - } -} - -#[derive(Default)] -struct Environment { - block_number: BlockNumber, - digest: Digest, - next_log_index: usize, -} - -fn with_env T>(f: F) -> T { - let e = env(); - let mut eb = e.borrow_mut(); - f(&mut *eb) -} - -fn env() -> Rc> { - // Initialize it to a null value - static mut SINGLETON: *const Rc> = 0 as *const Rc>; - - unsafe { - if SINGLETON == 0 as *const Rc> { - // Make it - let singleton: Rc> = Rc::new(RefCell::new(Default::default())); - - // Put it in the heap so it can outlive this call - SINGLETON = transmute(Box::new(singleton)); - } - - // Now we give out a copy of the data that is safe to use concurrently. - (*SINGLETON).clone() - } -} - -trait EndianSensitive: Sized { - fn to_le(self) -> Self { self } - fn to_be(self) -> Self { self } - fn from_le(self) -> Self { self } - fn from_be(self) -> Self { self } - fn as_be_then T>(&self, f: F) -> T { f(&self) } - fn as_le_then T>(&self, f: F) -> T { f(&self) } -} - -macro_rules! impl_endians { - ( $( $t:ty ),* ) => { $( - impl EndianSensitive for $t { - fn to_le(self) -> Self { <$t>::to_le(self) } - fn to_be(self) -> Self { <$t>::to_be(self) } - fn from_le(self) -> Self { <$t>::from_le(self) } - fn from_be(self) -> Self { <$t>::from_be(self) } - fn as_be_then T>(&self, f: F) -> T { let d = self.to_be(); f(&d) } - fn as_le_then T>(&self, f: F) -> T { let d = self.to_le(); f(&d) } - } - )* } -} -macro_rules! impl_non_endians { - ( $( $t:ty ),* ) => { $( - impl EndianSensitive for $t {} - )* } -} - -impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize); -impl_non_endians!(u8, i8, [u8; 20], [u8; 32]); - -trait Storage { - fn storage_into(key: &[u8]) -> Self; - fn store(&self, key: &[u8]); -} - -impl Storage for T { - fn storage_into(key: &[u8]) -> Self { - Slicable::set_as_slice(|out| runtime_support::read_storage(key, out) == out.len()) - .unwrap_or_else(Default::default) - } - - fn store(&self, key: &[u8]) { - self.as_slice_then(|slice| runtime_support::set_storage(key, slice)); - } -} - -fn storage_into(key: &[u8]) -> T { - T::storage_into(key) -} - -/// Trait that allows zero-copy read/write of value-references to/from slices in LE format. -trait Slicable: Sized { - fn from_slice(value: &[u8]) -> Option { - Self::set_as_slice(|out| if value.len() == out.len() { - out.copy_from_slice(&value); - true - } else { - false - }) - } - fn to_vec(&self) -> Vec { - self.as_slice_then(|s| s.to_vec()) - } - fn set_as_slice bool>(set_slice: F) -> Option; - fn as_slice_then R>(&self, f: F) -> R { - f(&self.to_vec()) - } - fn size_of(_value: &[u8]) -> Option; -} - -trait NonTrivialSlicable: Slicable {} - -impl Slicable for T { - fn set_as_slice bool>(fill_slice: F) -> Option { - let size = size_of::(); - let mut result: T = unsafe { std::mem::uninitialized() }; - let result_slice = unsafe { - std::slice::from_raw_parts_mut(transmute::<*mut T, *mut u8>(&mut result), size) - }; - if fill_slice(result_slice) { - Some(result.from_le()) - } else { - None - } - } - fn as_slice_then R>(&self, f: F) -> R { - let size = size_of::(); - self.as_le_then(|le| { - let value_slice = unsafe { - std::slice::from_raw_parts(transmute::<*const Self, *const u8>(le), size) - }; - f(value_slice) - }) - } - fn size_of(_value: &[u8]) -> Option { - Some(size_of::()) - } -} - -impl Slicable for Vec { - fn from_slice(value: &[u8]) -> Option { - Some(value[4..].to_vec()) - } - fn set_as_slice bool>(_fill_slice: F) -> Option { - unimplemented!(); - } - fn to_vec(&self) -> Vec { - let mut r = vec![].join(&(self.len() as u32)); - r.extend_from_slice(&self); - r - } - fn size_of(data: &[u8]) -> Option { - u32::from_slice(&data[0..4]).map(|i| (i + 4) as usize) - } -} - -impl Slicable for Transaction { - fn from_slice(value: &[u8]) -> Option { - let mut reader = StreamReader::new(value); - Some(Transaction { - signed: reader.read()?, - function: Function::from_u8(reader.read()?)?, - nonce: reader.read()?, - input_data: reader.read()?, - }) - } - - fn set_as_slice bool>(_fill_slice: F) -> Option { - unimplemented!(); - } - - fn to_vec(&self) -> Vec { - vec![] - .join(&self.signed) - .join(&(self.function as u8)) - .join(&self.nonce) - .join(&self.input_data) - } - - fn size_of(data: &[u8]) -> Option { - let first_part = size_of::() + size_of::() + size_of::(); - let second_part = >::size_of(&data[first_part..])?; - Some(first_part + second_part) - } -} - -impl NonTrivialSlicable for Transaction {} - -impl NonTrivialSlicable for Vec where Vec: Slicable {} - -impl Slicable for Vec { - fn from_slice(value: &[u8]) -> Option { - let len = Self::size_of(&value[0..4])?; - let mut off = 4; - let mut r = vec![]; - while off < len { - let element_len = T::size_of(&value[off..])?; - r.push(T::from_slice(&value[off..off + element_len])?); - off += element_len; - } - Some(r) - } - - fn set_as_slice bool>(_fill_slice: F) -> Option { - unimplemented!(); - } - - fn to_vec(&self) -> Vec { - let vecs = self.iter().map(Slicable::to_vec).collect::>(); - let len = vecs.iter().fold(0, |mut a, v| {a += v.len(); a}); - let mut r = vec![].join(&(len as u32)); - vecs.iter().for_each(|v| r.extend_from_slice(v)); - r - } - - fn size_of(data: &[u8]) -> Option { - u32::from_slice(&data[0..4]).map(|i| (i + 4) as usize) - } -} - -impl Slicable for Header { - fn from_slice(value: &[u8]) -> Option { - let mut reader = StreamReader::new(value); - Some(Header { - parent_hash: reader.read()?, - number: reader.read()?, - state_root: reader.read()?, - transaction_root: reader.read()?, - digest: Digest { logs: reader.read()?, }, - }) - } - - fn set_as_slice bool>(_fill_slice: F) -> Option { - unimplemented!(); - } - - fn to_vec(&self) -> Vec { - vec![] - .join(&self.parent_hash) - .join(&self.number) - .join(&self.state_root) - .join(&self.transaction_root) - .join(&self.digest.logs) - } - - fn size_of(data: &[u8]) -> Option { - let first_part = size_of::() + size_of::() + size_of::() + size_of::(); - let second_part = >>::size_of(&data[first_part..])?; - Some(first_part + second_part) - } -} - -impl Slicable for Block { - fn from_slice(value: &[u8]) -> Option { - let mut reader = StreamReader::new(value); - Some(Block { - header: reader.read()?, - transactions: reader.read()?, - }) - } - - fn set_as_slice bool>(_fill_slice: F) -> Option { - unimplemented!(); - } - - fn to_vec(&self) -> Vec { - vec![] - .join(&self.header) - .join(&self.transactions) - } - - fn size_of(data: &[u8]) -> Option { - let first_part = Header::size_of(data)?; - let second_part = >::size_of(&data[first_part..])?; - Some(first_part + second_part) - } -} - -trait KeyedVec { - fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec; -} - -impl KeyedVec for AccountID { - fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec { - let mut r = prepend_key.to_vec(); - r.extend_from_slice(self); - r - } -} - -macro_rules! impl_endians { - ( $( $t:ty ),* ) => { $( - impl KeyedVec for $t { - fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec { - self.as_slice_then(|slice| { - let mut r = prepend_key.to_vec(); - r.extend_from_slice(slice); - r - }) - } - } - )* } -} - -impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize); +mod endiansensitive; +mod streamreader; +mod slicable; +mod primitives; +mod keyedvec; +mod function; +mod environment; +mod storage; +mod testing; +#[allow(unused)] +mod system; +#[allow(unused)] +mod consensus; +#[allow(unused)] +mod staking; +#[allow(unused)] +mod timestamp; + +use runtime_support::Vec; +use slicable::Slicable; +use primitives::{ChainID, Block, Transaction}; // TODO: add keccak256 (or some better hashing scheme) & ECDSA-recover (or some better sig scheme) pub fn execute_block(input: Vec) -> Vec { - environment::execute_block(Block::from_slice(&input).unwrap()) + system::execute_block(Block::from_slice(&input).unwrap()) } pub fn execute_transaction(input: Vec) -> Vec { - environment::execute_transaction(&Transaction::from_slice(&input).unwrap()) + system::execute_transaction(&Transaction::from_slice(&input).unwrap()) } impl_stubs!(execute_block, execute_transaction); @@ -486,510 +43,3 @@ pub fn chain_id() -> ChainID { // TODO: retrieve from external unimplemented!() } - -pub mod environment { - use super::*; - - /// The current block number being processed. Set by `execute_block`. - pub fn block_number() -> BlockNumber { - with_env(|e| e.block_number) - } - - /// Get the block hash of a given block (uses storage). - pub fn block_hash(_number: BlockNumber) -> Hash { - unimplemented!() - } - - /// Deposits a log and ensures it matches the blocks log data. - pub fn deposit_log(log: &[u8]) { - with_env(|e| { - assert_eq!(log, &e.digest.logs[e.next_log_index][..]); - e.next_log_index += 1; - }); - } - - pub fn execute_block(mut block: Block) -> Vec { - // populate environment from header. - with_env(|e| { - e.block_number = block.header.number; - swap(&mut e.digest, &mut block.header.digest); - e.next_log_index = 0; - }); - - // TODO: check transaction trie root represents the transactions. - // TODO: store the header hash in storage. - - staking::pre_transactions(); - - block.transactions.iter().for_each(|tx| { execute_transaction(tx); }); - - staking::post_transactions(); - - final_checks(&block); - - // TODO: check state root somehow - - Vec::new() - } - - fn final_checks(_block: &Block) { - with_env(|e| { - assert_eq!(e.next_log_index, e.digest.logs.len()); - }); - } - - /// Execute a given transaction. - pub fn execute_transaction(_tx: &Transaction) -> Vec { - // TODO: decode data and ensure valid - // TODO: ensure signature valid and recover id (use authentication::authenticate) - // TODO: check nonce - // TODO: increment nonce in storage - // TODO: ensure target_function valid - // TODO: decode parameters - - _tx.function.dispatch(&_tx.signed, &_tx.input_data); - - // TODO: encode any return - Vec::new() - } - - /// Set the new code. - pub fn set_code(new: &[u8]) { - runtime_support::set_storage(b"\0code", new) - } -} - -pub mod consensus { - use super::*; - - pub fn set_authority(index: u32, authority: AccountID) { - authority.store(&index.to_keyed_vec(b"con\0aut\0")); - } - - fn authority(index: u32) -> AccountID { - storage_into(&index.to_keyed_vec(b"con\0aut\0")) - } - - pub fn set_authority_count(count: u32) { - (count..authority_count()).for_each(|i| set_authority(i, SessionKey::default())); - count.store(b"con\0aut\0len"); - } - - fn authority_count() -> u32 { - storage_into(b"con\0aut\0len") - } - - /// Get the current set of authorities. These are the session keys. - pub fn authorities() -> Vec { - (0..authority_count()).into_iter().map(authority).collect() - } - - /// Set the current set of authorities' session keys. - /// - /// Called by `next_session` only. - pub fn set_authorities(authorities: &[AccountID]) { - set_authority_count(authorities.len() as u32); - authorities.iter().enumerate().for_each(|(v, &i)| set_authority(v as u32, i)); - } - - /// Get the current set of validators. These are the long-term identifiers for the validators - /// and will be mapped to a session key with the most recent `set_next_session_key`. - pub fn validators() -> Vec { - unimplemented!() - } - - /// Set the current set of validators. - /// - /// Called by staking::next_era() only. - pub fn set_validators(_new: &[AccountID]) { - unimplemented!() - } - - /// The number of blocks in each session. - pub fn session_length() -> BlockNumber { - storage_into(b"con\0bps") - } - - /// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next - /// session. - pub fn set_session_key(_transactor: &AccountID, _session: &AccountID) { - unimplemented!() - } - - /// Move onto next session: register the new authority set. - pub fn next_session() { - // TODO: Call set_authorities(). - unimplemented!() - } - - /// Hook to be called prior to transaction processing. - pub fn pre_transactions() {} - - /// Hook to be called after to transaction processing. - pub fn post_transactions() { - // TODO: check block number and call next_session if necessary. - } -} - -pub mod staking { - use super::*; - - /// The length of a staking era in blocks. - pub fn era_length() -> BlockNumber { - sessions_per_era() * consensus::session_length() - } - - /// The length of a staking era in sessions. - pub fn sessions_per_era() -> BlockNumber { - storage_into(b"sta\0spe") - } - - /// The era has changed - enact new staking set. - /// - /// NOTE: This always happens on a session change. - pub fn next_era() { - unimplemented!() - } - - /// The balance of a given account. - pub fn balance(who: &AccountID) -> Balance { - storage_into(&who.to_keyed_vec(b"sta\0bal\0")) - } - - /// Transfer some unlocked staking balance to another staker. - pub fn transfer_stake(transactor: &AccountID, dest: &AccountID, value: Balance) { - let from_key = transactor.to_keyed_vec(b"sta\0bal\0"); - let from_balance: Balance = storage_into(&from_key); - assert!(from_balance >= value); - let to_key = dest.to_keyed_vec(b"sta\0bal\0"); - let to_balance: Balance = storage_into(&to_key); - assert!(to_balance + value > to_balance); // no overflow - (from_balance - value).store(&from_key); - (to_balance + value).store(&to_key); - } - - /// Declare the desire to stake for the transactor. - /// - /// Effects will be felt at the beginning of the next era. - pub fn stake(_transactor: &AccountID) { - unimplemented!() - } - - /// Retract the desire to stake for the transactor. - /// - /// Effects will be felt at the beginning of the next era. - pub fn unstake(_transactor: &AccountID) { - unimplemented!() - } - - /// Hook to be called prior to transaction processing. - pub fn pre_transactions() { - consensus::pre_transactions(); - } - - /// Hook to be called after to transaction processing. - pub fn post_transactions() { - // TODO: check block number and call next_era if necessary. - consensus::post_transactions(); - } -} - -pub mod timestamp { - use super::*; - - pub fn timestamp() -> Timestamp { - unimplemented!() - } - - pub fn set_timestamp(_now: Timestamp) { - unimplemented!() - } -} - -#[cfg(test)] -mod tests { - - use super::*; - - use std::collections::HashMap; - use runtime_support::{NoError, with_externalities, Externalities}; - - #[derive(Debug, Default)] - struct TestExternalities { - storage: HashMap, Vec>, - } - impl Externalities for TestExternalities { - type Error = NoError; - - fn storage(&self, key: &[u8]) -> Result<&[u8], NoError> { - Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) - } - - fn set_storage(&mut self, key: Vec, value: Vec) { - self.storage.insert(key, value); - } - } - - macro_rules! map { - ($( $name:expr => $value:expr ),*) => ( - vec![ $( ( $name, $value ) ),* ].into_iter().collect() - ) - } - - #[test] - fn staking_balance_works() { - let one: AccountID = [1u8; 32]; - let two: AccountID = [2u8; 32]; - - let mut t = TestExternalities { storage: map![ - { let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![42u8, 0, 0, 0, 0, 0, 0, 0] - ], }; - - with_externalities(&mut t, || { - assert_eq!(staking::balance(&one), 42); - assert_eq!(staking::balance(&two), 0); - }); - } - - #[test] - fn staking_balance_transfer_works() { - let one: AccountID = [1u8; 32]; - let two: AccountID = [2u8; 32]; - - let mut t = TestExternalities { storage: map![ - { let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![111u8, 0, 0, 0, 0, 0, 0, 0] - ], }; - - with_externalities(&mut t, || { - staking::transfer_stake(&one, &two, 69); - assert_eq!(staking::balance(&one), 42); - assert_eq!(staking::balance(&two), 69); - }); - } - - #[test] - fn staking_balance_transfer_dispatch_works() { - let one: AccountID = [1u8; 32]; - let two: AccountID = [2u8; 32]; - - let mut t = TestExternalities { storage: map![ - { let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![111u8, 0, 0, 0, 0, 0, 0, 0] - ], }; - - let tx = Transaction { - signed: one.clone(), - function: Function::StakingTransferStake, - input_data: vec![].join(&two).join(&69u64), - nonce: 0, - }; - - with_externalities(&mut t, || { - environment::execute_transaction(&tx); - assert_eq!(staking::balance(&one), 42); - assert_eq!(staking::balance(&two), 69); - }); - } - - #[test] - fn serialise_transaction_works() { - let one: AccountID = [1u8; 32]; - let two: AccountID = [2u8; 32]; - let tx = Transaction { - signed: one.clone(), - function: Function::StakingTransferStake, - input_data: vec![].join(&two).join(&69u64), - nonce: 69, - }; - let serialised = tx.to_vec(); - assert_eq!(serialised, vec![ - 1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, - 69, 0, 0, 0, 0, 0, 0, 0, - 40, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 69, 0, 0, 0, 0, 0, 0, 0 - ]); - } - - #[test] - fn deserialise_transaction_works() { - let one: AccountID = [1u8; 32]; - let two: AccountID = [2u8; 32]; - let tx = Transaction { - signed: one.clone(), - function: Function::StakingTransferStake, - input_data: vec![].join(&two).join(&69u64), - nonce: 69, - }; - let data = [ - 1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, - 69, 0, 0, 0, 0, 0, 0, 0, - 40, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 69, 0, 0, 0, 0, 0, 0, 0 - ]; - let deserialised = Transaction::from_slice(&data).unwrap(); - assert_eq!(deserialised, tx); - } - - #[test] - fn serialise_header_works() { - let h = Header { - parent_hash: [4u8; 32], - number: 42, - state_root: [5u8; 32], - transaction_root: [6u8; 32], - digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, - }; - let serialised = h.to_vec(); - assert_eq!(serialised, vec![ - 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 42, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 26, 0, 0, 0, - 7, 0, 0, 0, - 111, 110, 101, 32, 108, 111, 103, - 11, 0, 0, 0, - 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103 - ]); - } - - #[test] - fn deserialise_header_works() { - let h = Header { - parent_hash: [4u8; 32], - number: 42, - state_root: [5u8; 32], - transaction_root: [6u8; 32], - digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, - }; - let data = [ - 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 42, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 26, 0, 0, 0, - 7, 0, 0, 0, - 111, 110, 101, 32, 108, 111, 103, - 11, 0, 0, 0, - 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103 - ]; - let deserialised = Header::from_slice(&data).unwrap(); - assert_eq!(deserialised, h); - } - - #[test] - fn serialise_block_works() { - let one: AccountID = [1u8; 32]; - let two: AccountID = [2u8; 32]; - let tx1 = Transaction { - signed: one.clone(), - function: Function::StakingTransferStake, - input_data: vec![].join(&two).join(&69u64), - nonce: 69, - }; - let tx2 = Transaction { - signed: two.clone(), - function: Function::StakingStake, - input_data: vec![], - nonce: 42, - }; - let h = Header { - parent_hash: [4u8; 32], - number: 42, - state_root: [5u8; 32], - transaction_root: [6u8; 32], - digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, - }; - let b = Block { - header: h, - transactions: vec![tx1, tx2], - }; - let serialised = b.to_vec(); - assert_eq!(serialised, vec![ - // header - 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 42, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 26, 0, 0, 0, - 7, 0, 0, 0, - 111, 110, 101, 32, 108, 111, 103, - 11, 0, 0, 0, - 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103, - // transactions - 130, 0, 0, 0, - // tx1 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, - 69, 0, 0, 0, 0, 0, 0, 0, - 40, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 69, 0, 0, 0, 0, 0, 0, 0, - // tx2 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 0, - 42, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 - ]); - } - - #[test] - fn deserialise_block_works() { - let one: AccountID = [1u8; 32]; - let two: AccountID = [2u8; 32]; - let tx1 = Transaction { - signed: one.clone(), - function: Function::StakingTransferStake, - input_data: vec![].join(&two).join(&69u64), - nonce: 69, - }; - let tx2 = Transaction { - signed: two.clone(), - function: Function::StakingStake, - input_data: vec![], - nonce: 42, - }; - let h = Header { - parent_hash: [4u8; 32], - number: 42, - state_root: [5u8; 32], - transaction_root: [6u8; 32], - digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, - }; - let b = Block { - header: h, - transactions: vec![tx1, tx2], - }; - let data = [ - // header - 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 42, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 26, 0, 0, 0, - 7, 0, 0, 0, - 111, 110, 101, 32, 108, 111, 103, - 11, 0, 0, 0, - 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103, - // transactions - 130, 0, 0, 0, - // tx1 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, - 69, 0, 0, 0, 0, 0, 0, 0, - 40, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 69, 0, 0, 0, 0, 0, 0, 0, - // tx2 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 0, - 42, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 - ]; - let deserialised = Block::from_slice(&data).unwrap(); - assert_eq!(deserialised, b); - } -} diff --git a/wasm-runtime/polkadot/src/primitives.rs b/wasm-runtime/polkadot/src/primitives.rs new file mode 100644 index 0000000000000..a689eb7dce783 --- /dev/null +++ b/wasm-runtime/polkadot/src/primitives.rs @@ -0,0 +1,378 @@ +use streamreader::{StreamReader, Joiner}; +use slicable::{Slicable, NonTrivialSlicable}; +use function::Function; +use runtime_support::size_of; + +/// The hash of an ECDSA pub key which is used to identify an external transactor. +pub type AccountID = [u8; 32]; +/// The ECDSA pub key of an authority. This is what the external environment/consensus algorithm +/// refers to as a "authority". +pub type SessionKey = AccountID; +pub type Balance = u64; +pub type ChainID = u64; +pub type Hash = [u8; 32]; +pub type BlockNumber = u64; +pub type Timestamp = u64; +pub type TxOrder = u64; + +#[derive(Clone, Default)] +#[cfg_attr(test, derive(PartialEq, Debug))] +pub struct Digest { + pub logs: Vec>, +} + +#[derive(Clone)] +#[cfg_attr(test, derive(PartialEq, Debug))] +pub struct Header { + pub parent_hash: Hash, + pub number: BlockNumber, + pub state_root: Hash, + pub transaction_root: Hash, + pub digest: Digest, +} + +#[cfg_attr(test, derive(PartialEq, Debug))] +pub struct Transaction { + pub signed: AccountID, + pub function: Function, + pub input_data: Vec, + pub nonce: TxOrder, +} + +#[cfg_attr(test, derive(PartialEq, Debug))] +pub struct Block { + pub header: Header, + pub transactions: Vec, +} + +impl Slicable for Transaction { + fn from_slice(value: &[u8]) -> Option { + let mut reader = StreamReader::new(value); + Some(Transaction { + signed: reader.read()?, + function: Function::from_u8(reader.read()?)?, + nonce: reader.read()?, + input_data: reader.read()?, + }) + } + + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + + fn to_vec(&self) -> Vec { + vec![] + .join(&self.signed) + .join(&(self.function as u8)) + .join(&self.nonce) + .join(&self.input_data) + } + + fn size_of(data: &[u8]) -> Option { + let first_part = size_of::() + size_of::() + size_of::(); + let second_part = >::size_of(&data[first_part..])?; + Some(first_part + second_part) + } +} + +impl NonTrivialSlicable for Transaction {} + +impl NonTrivialSlicable for Vec where Vec: Slicable {} + +impl Slicable for Vec { + fn from_slice(value: &[u8]) -> Option { + let len = Self::size_of(&value[0..4])?; + let mut off = 4; + let mut r = vec![]; + while off < len { + let element_len = T::size_of(&value[off..])?; + r.push(T::from_slice(&value[off..off + element_len])?); + off += element_len; + } + Some(r) + } + + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + + fn to_vec(&self) -> Vec { + let vecs = self.iter().map(Slicable::to_vec).collect::>(); + let len = vecs.iter().fold(0, |mut a, v| {a += v.len(); a}); + let mut r = vec![].join(&(len as u32)); + vecs.iter().for_each(|v| r.extend_from_slice(v)); + r + } + + fn size_of(data: &[u8]) -> Option { + u32::from_slice(&data[0..4]).map(|i| (i + 4) as usize) + } +} + +impl Slicable for Header { + fn from_slice(value: &[u8]) -> Option { + let mut reader = StreamReader::new(value); + Some(Header { + parent_hash: reader.read()?, + number: reader.read()?, + state_root: reader.read()?, + transaction_root: reader.read()?, + digest: Digest { logs: reader.read()?, }, + }) + } + + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + + fn to_vec(&self) -> Vec { + vec![] + .join(&self.parent_hash) + .join(&self.number) + .join(&self.state_root) + .join(&self.transaction_root) + .join(&self.digest.logs) + } + + fn size_of(data: &[u8]) -> Option { + let first_part = size_of::() + size_of::() + size_of::() + size_of::(); + let second_part = >>::size_of(&data[first_part..])?; + Some(first_part + second_part) + } +} + +impl Slicable for Block { + fn from_slice(value: &[u8]) -> Option { + let mut reader = StreamReader::new(value); + Some(Block { + header: reader.read()?, + transactions: reader.read()?, + }) + } + + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + + fn to_vec(&self) -> Vec { + vec![] + .join(&self.header) + .join(&self.transactions) + } + + fn size_of(data: &[u8]) -> Option { + let first_part = Header::size_of(data)?; + let second_part = >::size_of(&data[first_part..])?; + Some(first_part + second_part) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use streamreader::Joiner; + use function::Function; + + #[test] + fn serialise_transaction_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + let tx = Transaction { + signed: one.clone(), + function: Function::StakingTransferStake, + input_data: vec![].join(&two).join(&69u64), + nonce: 69, + }; + let serialised = tx.to_vec(); + assert_eq!(serialised, vec![ + 1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, + 69, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 69, 0, 0, 0, 0, 0, 0, 0 + ]); + } + + #[test] + fn deserialise_transaction_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + let tx = Transaction { + signed: one.clone(), + function: Function::StakingTransferStake, + input_data: vec![].join(&two).join(&69u64), + nonce: 69, + }; + let data = [ + 1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, + 69, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 69, 0, 0, 0, 0, 0, 0, 0 + ]; + let deserialised = Transaction::from_slice(&data).unwrap(); + assert_eq!(deserialised, tx); + } + + #[test] + fn serialise_header_works() { + let h = Header { + parent_hash: [4u8; 32], + number: 42, + state_root: [5u8; 32], + transaction_root: [6u8; 32], + digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, + }; + let serialised = h.to_vec(); + assert_eq!(serialised, vec![ + 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 42, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 26, 0, 0, 0, + 7, 0, 0, 0, + 111, 110, 101, 32, 108, 111, 103, + 11, 0, 0, 0, + 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103 + ]); + } + + #[test] + fn deserialise_header_works() { + let h = Header { + parent_hash: [4u8; 32], + number: 42, + state_root: [5u8; 32], + transaction_root: [6u8; 32], + digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, + }; + let data = [ + 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 42, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 26, 0, 0, 0, + 7, 0, 0, 0, + 111, 110, 101, 32, 108, 111, 103, + 11, 0, 0, 0, + 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103 + ]; + let deserialised = Header::from_slice(&data).unwrap(); + assert_eq!(deserialised, h); + } + + #[test] + fn serialise_block_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + let tx1 = Transaction { + signed: one.clone(), + function: Function::StakingTransferStake, + input_data: vec![].join(&two).join(&69u64), + nonce: 69, + }; + let tx2 = Transaction { + signed: two.clone(), + function: Function::StakingStake, + input_data: vec![], + nonce: 42, + }; + let h = Header { + parent_hash: [4u8; 32], + number: 42, + state_root: [5u8; 32], + transaction_root: [6u8; 32], + digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, + }; + let b = Block { + header: h, + transactions: vec![tx1, tx2], + }; + let serialised = b.to_vec(); + assert_eq!(serialised, vec![ + // header + 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 42, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 26, 0, 0, 0, + 7, 0, 0, 0, + 111, 110, 101, 32, 108, 111, 103, + 11, 0, 0, 0, + 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103, + // transactions + 130, 0, 0, 0, + // tx1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, + 69, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 69, 0, 0, 0, 0, 0, 0, 0, + // tx2 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, + 42, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 + ]); + } + + #[test] + fn deserialise_block_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + let tx1 = Transaction { + signed: one.clone(), + function: Function::StakingTransferStake, + input_data: vec![].join(&two).join(&69u64), + nonce: 69, + }; + let tx2 = Transaction { + signed: two.clone(), + function: Function::StakingStake, + input_data: vec![], + nonce: 42, + }; + let h = Header { + parent_hash: [4u8; 32], + number: 42, + state_root: [5u8; 32], + transaction_root: [6u8; 32], + digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, + }; + let b = Block { + header: h, + transactions: vec![tx1, tx2], + }; + let data = [ + // header + 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 42, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 26, 0, 0, 0, + 7, 0, 0, 0, + 111, 110, 101, 32, 108, 111, 103, + 11, 0, 0, 0, + 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103, + // transactions + 130, 0, 0, 0, + // tx1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, + 69, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 69, 0, 0, 0, 0, 0, 0, 0, + // tx2 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, + 42, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 + ]; + let deserialised = Block::from_slice(&data).unwrap(); + assert_eq!(deserialised, b); + } +} diff --git a/wasm-runtime/polkadot/src/slicable.rs b/wasm-runtime/polkadot/src/slicable.rs new file mode 100644 index 0000000000000..0459881f0ed97 --- /dev/null +++ b/wasm-runtime/polkadot/src/slicable.rs @@ -0,0 +1,69 @@ +use runtime_support::{Vec, size_of, transmute, uninitialized, slice}; +use streamreader::Joiner; +use endiansensitive::EndianSensitive; + +/// Trait that allows zero-copy read/write of value-references to/from slices in LE format. +pub trait Slicable: Sized { + fn from_slice(value: &[u8]) -> Option { + Self::set_as_slice(|out| if value.len() == out.len() { + out.copy_from_slice(&value); + true + } else { + false + }) + } + fn to_vec(&self) -> Vec { + self.as_slice_then(|s| s.to_vec()) + } + fn set_as_slice bool>(set_slice: F) -> Option; + fn as_slice_then R>(&self, f: F) -> R { + f(&self.to_vec()) + } + fn size_of(_value: &[u8]) -> Option; +} + +pub trait NonTrivialSlicable: Slicable {} + +impl Slicable for T { + fn set_as_slice bool>(fill_slice: F) -> Option { + let size = size_of::(); + let mut result: T = unsafe { uninitialized() }; + let result_slice = unsafe { + slice::from_raw_parts_mut(transmute::<*mut T, *mut u8>(&mut result), size) + }; + if fill_slice(result_slice) { + Some(result.from_le()) + } else { + None + } + } + fn as_slice_then R>(&self, f: F) -> R { + let size = size_of::(); + self.as_le_then(|le| { + let value_slice = unsafe { + slice::from_raw_parts(transmute::<*const Self, *const u8>(le), size) + }; + f(value_slice) + }) + } + fn size_of(_value: &[u8]) -> Option { + Some(size_of::()) + } +} + +impl Slicable for Vec { + fn from_slice(value: &[u8]) -> Option { + Some(value[4..].to_vec()) + } + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + fn to_vec(&self) -> Vec { + let mut r: Vec = vec![].join(&(self.len() as u32)); + r.extend_from_slice(&self); + r + } + fn size_of(data: &[u8]) -> Option { + u32::from_slice(&data[0..4]).map(|i| (i + 4) as usize) + } +} diff --git a/wasm-runtime/polkadot/src/staking.rs b/wasm-runtime/polkadot/src/staking.rs new file mode 100644 index 0000000000000..d8903504d2d53 --- /dev/null +++ b/wasm-runtime/polkadot/src/staking.rs @@ -0,0 +1,109 @@ +use keyedvec::KeyedVec; +use storage::{Storage, storage_into}; +use primitives::{BlockNumber, Balance, AccountID}; +use consensus; + +/// The length of a staking era in blocks. +pub fn era_length() -> BlockNumber { + sessions_per_era() * consensus::session_length() +} + +/// The length of a staking era in sessions. +pub fn sessions_per_era() -> BlockNumber { + storage_into(b"sta\0spe") +} + +/// The era has changed - enact new staking set. +/// +/// NOTE: This always happens on a session change. +pub fn next_era() { + unimplemented!() +} + +/// The balance of a given account. +pub fn balance(who: &AccountID) -> Balance { + storage_into(&who.to_keyed_vec(b"sta\0bal\0")) +} + +/// Transfer some unlocked staking balance to another staker. +pub fn transfer_stake(transactor: &AccountID, dest: &AccountID, value: Balance) { + let from_key = transactor.to_keyed_vec(b"sta\0bal\0"); + let from_balance: Balance = storage_into(&from_key); + assert!(from_balance >= value); + let to_key = dest.to_keyed_vec(b"sta\0bal\0"); + let to_balance: Balance = storage_into(&to_key); + assert!(to_balance + value > to_balance); // no overflow + (from_balance - value).store(&from_key); + (to_balance + value).store(&to_key); +} + +/// Declare the desire to stake for the transactor. +/// +/// Effects will be felt at the beginning of the next era. +pub fn stake(_transactor: &AccountID) { + unimplemented!() +} + +/// Retract the desire to stake for the transactor. +/// +/// Effects will be felt at the beginning of the next era. +pub fn unstake(_transactor: &AccountID) { + unimplemented!() +} + +/// Hook to be called prior to transaction processing. +pub fn pre_transactions() { + consensus::pre_transactions(); +} + +/// Hook to be called after to transaction processing. +pub fn post_transactions() { + // TODO: check block number and call next_era if necessary. + consensus::post_transactions(); +} + + +#[cfg(test)] +mod tests { + use runtime_support::with_externalities; + use testing::TestExternalities; + use primitives::{AccountID}; + use staking; + + macro_rules! map { + ($( $name:expr => $value:expr ),*) => ( + vec![ $( ( $name, $value ) ),* ].into_iter().collect() + ) + } + + #[test] + fn staking_balance_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + + let mut t = TestExternalities { storage: map![ + { let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![42u8, 0, 0, 0, 0, 0, 0, 0] + ], }; + + with_externalities(&mut t, || { + assert_eq!(staking::balance(&one), 42); + assert_eq!(staking::balance(&two), 0); + }); + } + + #[test] + fn staking_balance_transfer_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + + let mut t = TestExternalities { storage: map![ + { let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + ], }; + + with_externalities(&mut t, || { + staking::transfer_stake(&one, &two, 69); + assert_eq!(staking::balance(&one), 42); + assert_eq!(staking::balance(&two), 69); + }); + } +} diff --git a/wasm-runtime/polkadot/src/storage.rs b/wasm-runtime/polkadot/src/storage.rs new file mode 100644 index 0000000000000..13a9074d950c9 --- /dev/null +++ b/wasm-runtime/polkadot/src/storage.rs @@ -0,0 +1,23 @@ +use slicable::Slicable; +use endiansensitive::EndianSensitive; +use runtime_support; + +pub trait Storage { + fn storage_into(key: &[u8]) -> Self; + fn store(&self, key: &[u8]); +} + +impl Storage for T { + fn storage_into(key: &[u8]) -> Self { + Slicable::set_as_slice(|out| runtime_support::read_storage(key, out) == out.len()) + .unwrap_or_else(Default::default) + } + + fn store(&self, key: &[u8]) { + self.as_slice_then(|slice| runtime_support::set_storage(key, slice)); + } +} + +pub fn storage_into(key: &[u8]) -> T { + T::storage_into(key) +} diff --git a/wasm-runtime/polkadot/src/streamreader.rs b/wasm-runtime/polkadot/src/streamreader.rs new file mode 100644 index 0000000000000..3bb427a1ef001 --- /dev/null +++ b/wasm-runtime/polkadot/src/streamreader.rs @@ -0,0 +1,63 @@ +use slicable::Slicable; + +pub struct StreamReader<'a> { + data: &'a[u8], + offset: usize, +} + +impl<'a> StreamReader<'a> { + pub fn new(data: &'a[u8]) -> Self { + StreamReader { + data: data, + offset: 0, + } + } + pub fn read(&mut self) -> Option { + let size = T::size_of(&self.data[self.offset..])?; + let new_offset = self.offset + size; + let slice = &self.data[self.offset..new_offset]; + self.offset = new_offset; + Slicable::from_slice(slice) + } +} + +pub trait Joiner { + fn join(self, value: &T) -> Self; +} + +impl Joiner for Vec { + fn join(mut self, value: &T) -> Vec { + value.as_slice_then(|s| self.extend_from_slice(s)); + self + } +} +/* +// Not in use yet +// TODO: introduce fn size_will_be(&self) -> usize; to Slicable trait and implement +struct StreamWriter<'a> { + data: &'a mut[u8], + offset: usize, +} + +impl<'a> StreamWriter<'a> { + pub fn new(data: &'a mut[u8]) -> Self { + StreamWriter { + data: data, + offset: 0, + } + } + pub fn write(&mut self, value: &T) -> bool { + value.as_slice_then(|s| { + let new_offset = self.offset + s.len(); + if self.data.len() <= new_offset { + let slice = &mut self.data[self.offset..new_offset]; + self.offset = new_offset; + slice.copy_from_slice(s); + true + } else { + false + } + }) + } +} +*/ diff --git a/wasm-runtime/polkadot/src/system.rs b/wasm-runtime/polkadot/src/system.rs new file mode 100644 index 0000000000000..96169d09cc646 --- /dev/null +++ b/wasm-runtime/polkadot/src/system.rs @@ -0,0 +1,129 @@ +use primitives::{Block, BlockNumber, Hash, Transaction}; +use runtime_support::{Vec, swap}; +use environment::with_env; +use staking; +use runtime_support; + +/// The current block number being processed. Set by `execute_block`. +pub fn block_number() -> BlockNumber { + with_env(|e| e.block_number) +} + +/// Get the block hash of a given block (uses storage). +pub fn block_hash(_number: BlockNumber) -> Hash { + unimplemented!() +} + +/// Deposits a log and ensures it matches the blocks log data. +pub fn deposit_log(log: &[u8]) { + with_env(|e| { + assert_eq!(log, &e.digest.logs[e.next_log_index][..]); + e.next_log_index += 1; + }); +} + +pub fn execute_block(mut block: Block) -> Vec { + // populate environment from header. + with_env(|e| { + e.block_number = block.header.number; + swap(&mut e.digest, &mut block.header.digest); + e.next_log_index = 0; + }); + + // TODO: check transaction trie root represents the transactions. + // TODO: store the header hash in storage. + + staking::pre_transactions(); + + block.transactions.iter().for_each(|tx| { execute_transaction(tx); }); + + staking::post_transactions(); + + final_checks(&block); + + // TODO: check state root somehow + + Vec::new() +} + +fn final_checks(_block: &Block) { + with_env(|e| { + assert_eq!(e.next_log_index, e.digest.logs.len()); + }); +} + +/// Execute a given transaction. +pub fn execute_transaction(_tx: &Transaction) -> Vec { + // TODO: decode data and ensure valid + // TODO: ensure signature valid and recover id (use authentication::authenticate) + // TODO: check nonce + // TODO: increment nonce in storage + // TODO: ensure target_function valid + // TODO: decode parameters + + _tx.function.dispatch(&_tx.signed, &_tx.input_data); + + // TODO: encode any return + Vec::new() +} + +/// Set the new code. +pub fn set_code(new: &[u8]) { + runtime_support::set_storage(b"\0code", new) +} + +#[cfg(test)] +mod tests { + use streamreader::Joiner; + use function::Function; + use std::collections::HashMap; + use runtime_support::{NoError, with_externalities, Externalities}; + use primitives::{AccountID, Transaction}; + use system; + use staking; + + #[derive(Debug, Default)] + struct TestExternalities { + storage: HashMap, Vec>, + } + impl Externalities for TestExternalities { + type Error = NoError; + + fn storage(&self, key: &[u8]) -> Result<&[u8], NoError> { + Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) + } + + fn set_storage(&mut self, key: Vec, value: Vec) { + self.storage.insert(key, value); + } + } + + macro_rules! map { + ($( $name:expr => $value:expr ),*) => ( + vec![ $( ( $name, $value ) ),* ].into_iter().collect() + ) + } + + #[test] + fn staking_balance_transfer_dispatch_works() { + let one: AccountID = [1u8; 32]; + let two: AccountID = [2u8; 32]; + + let mut t = TestExternalities { storage: map![ + { let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + ], }; + + let tx = Transaction { + signed: one.clone(), + function: Function::StakingTransferStake, + input_data: vec![].join(&two).join(&69u64), + nonce: 0, + }; + + with_externalities(&mut t, || { + system::execute_transaction(&tx); + assert_eq!(staking::balance(&one), 42); + assert_eq!(staking::balance(&two), 69); + }); + } +} diff --git a/wasm-runtime/polkadot/src/testing.rs b/wasm-runtime/polkadot/src/testing.rs new file mode 100644 index 0000000000000..d73917eb16f6d --- /dev/null +++ b/wasm-runtime/polkadot/src/testing.rs @@ -0,0 +1,19 @@ +use runtime_support::{NoError, Externalities}; +use std::collections::HashMap; + +#[derive(Debug, Default)] +pub struct TestExternalities { + pub storage: HashMap, Vec>, +} + +impl Externalities for TestExternalities { + type Error = NoError; + + fn storage(&self, key: &[u8]) -> Result<&[u8], NoError> { + Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) + } + + fn set_storage(&mut self, key: Vec, value: Vec) { + self.storage.insert(key, value); + } +} diff --git a/wasm-runtime/polkadot/src/timestamp.rs b/wasm-runtime/polkadot/src/timestamp.rs new file mode 100644 index 0000000000000..6a4043651d87a --- /dev/null +++ b/wasm-runtime/polkadot/src/timestamp.rs @@ -0,0 +1,9 @@ +use primitives::Timestamp; + +pub fn timestamp() -> Timestamp { + unimplemented!() +} + +pub fn set_timestamp(_now: Timestamp) { + unimplemented!() +} From 40e28fc30b49e2f35421577fe5236a49db59fd1a Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 16 Jan 2018 17:57:42 +0100 Subject: [PATCH 35/76] Split out joiner. --- wasm-runtime/polkadot/src/joiner.rs | 12 ++++++++++++ wasm-runtime/polkadot/src/lib.rs | 1 + wasm-runtime/polkadot/src/primitives.rs | 5 +++-- wasm-runtime/polkadot/src/slicable.rs | 2 +- wasm-runtime/polkadot/src/streamreader.rs | 11 ----------- wasm-runtime/polkadot/src/system.rs | 2 +- 6 files changed, 18 insertions(+), 15 deletions(-) create mode 100644 wasm-runtime/polkadot/src/joiner.rs diff --git a/wasm-runtime/polkadot/src/joiner.rs b/wasm-runtime/polkadot/src/joiner.rs new file mode 100644 index 0000000000000..99b38dec57915 --- /dev/null +++ b/wasm-runtime/polkadot/src/joiner.rs @@ -0,0 +1,12 @@ +use slicable::Slicable; + +pub trait Joiner { + fn join(self, value: &T) -> Self; +} + +impl Joiner for Vec { + fn join(mut self, value: &T) -> Vec { + value.as_slice_then(|s| self.extend_from_slice(s)); + self + } +} diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index e64a3c2a6b28e..5646c7c3229df 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -6,6 +6,7 @@ extern crate runtime_support; mod endiansensitive; mod streamreader; +mod joiner; mod slicable; mod primitives; mod keyedvec; diff --git a/wasm-runtime/polkadot/src/primitives.rs b/wasm-runtime/polkadot/src/primitives.rs index a689eb7dce783..44d3bc47399f7 100644 --- a/wasm-runtime/polkadot/src/primitives.rs +++ b/wasm-runtime/polkadot/src/primitives.rs @@ -1,4 +1,5 @@ -use streamreader::{StreamReader, Joiner}; +use streamreader::StreamReader; +use joiner::Joiner; use slicable::{Slicable, NonTrivialSlicable}; use function::Function; use runtime_support::size_of; @@ -170,7 +171,7 @@ impl Slicable for Block { #[cfg(test)] mod tests { use super::*; - use streamreader::Joiner; + use joiner::Joiner; use function::Function; #[test] diff --git a/wasm-runtime/polkadot/src/slicable.rs b/wasm-runtime/polkadot/src/slicable.rs index 0459881f0ed97..e220eb0f7d6c9 100644 --- a/wasm-runtime/polkadot/src/slicable.rs +++ b/wasm-runtime/polkadot/src/slicable.rs @@ -1,5 +1,5 @@ use runtime_support::{Vec, size_of, transmute, uninitialized, slice}; -use streamreader::Joiner; +use joiner::Joiner; use endiansensitive::EndianSensitive; /// Trait that allows zero-copy read/write of value-references to/from slices in LE format. diff --git a/wasm-runtime/polkadot/src/streamreader.rs b/wasm-runtime/polkadot/src/streamreader.rs index 3bb427a1ef001..33d6fd8bfdf35 100644 --- a/wasm-runtime/polkadot/src/streamreader.rs +++ b/wasm-runtime/polkadot/src/streamreader.rs @@ -20,17 +20,6 @@ impl<'a> StreamReader<'a> { Slicable::from_slice(slice) } } - -pub trait Joiner { - fn join(self, value: &T) -> Self; -} - -impl Joiner for Vec { - fn join(mut self, value: &T) -> Vec { - value.as_slice_then(|s| self.extend_from_slice(s)); - self - } -} /* // Not in use yet // TODO: introduce fn size_will_be(&self) -> usize; to Slicable trait and implement diff --git a/wasm-runtime/polkadot/src/system.rs b/wasm-runtime/polkadot/src/system.rs index 96169d09cc646..88414fa9a16d4 100644 --- a/wasm-runtime/polkadot/src/system.rs +++ b/wasm-runtime/polkadot/src/system.rs @@ -74,7 +74,7 @@ pub fn set_code(new: &[u8]) { #[cfg(test)] mod tests { - use streamreader::Joiner; + use joiner::Joiner; use function::Function; use std::collections::HashMap; use runtime_support::{NoError, with_externalities, Externalities}; From ab37f64bcc5a1307440d8e5803774d203df83145 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 16 Jan 2018 18:03:13 +0100 Subject: [PATCH 36/76] Hide away support modules. --- wasm-runtime/polkadot/src/lib.rs | 14 ++++---------- .../polkadot/src/{ => support}/endiansensitive.rs | 0 .../polkadot/src/{ => support}/environment.rs | 0 .../polkadot/src/{ => support}/function.rs | 0 wasm-runtime/polkadot/src/{ => support}/joiner.rs | 0 .../polkadot/src/{ => support}/keyedvec.rs | 0 wasm-runtime/polkadot/src/support/mod.rs | 10 ++++++++++ .../polkadot/src/{ => support}/primitives.rs | 0 .../polkadot/src/{ => support}/slicable.rs | 0 wasm-runtime/polkadot/src/{ => support}/storage.rs | 0 .../polkadot/src/{ => support}/streamreader.rs | 0 wasm-runtime/polkadot/src/{ => support}/testing.rs | 0 12 files changed, 14 insertions(+), 10 deletions(-) rename wasm-runtime/polkadot/src/{ => support}/endiansensitive.rs (100%) rename wasm-runtime/polkadot/src/{ => support}/environment.rs (100%) rename wasm-runtime/polkadot/src/{ => support}/function.rs (100%) rename wasm-runtime/polkadot/src/{ => support}/joiner.rs (100%) rename wasm-runtime/polkadot/src/{ => support}/keyedvec.rs (100%) create mode 100644 wasm-runtime/polkadot/src/support/mod.rs rename wasm-runtime/polkadot/src/{ => support}/primitives.rs (100%) rename wasm-runtime/polkadot/src/{ => support}/slicable.rs (100%) rename wasm-runtime/polkadot/src/{ => support}/storage.rs (100%) rename wasm-runtime/polkadot/src/{ => support}/streamreader.rs (100%) rename wasm-runtime/polkadot/src/{ => support}/testing.rs (100%) diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 5646c7c3229df..cc48d8caa6b73 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -4,16 +4,10 @@ #[macro_use] extern crate runtime_support; -mod endiansensitive; -mod streamreader; -mod joiner; -mod slicable; -mod primitives; -mod keyedvec; -mod function; -mod environment; -mod storage; -mod testing; +mod support; +pub use support::{endiansensitive, streamreader, joiner, slicable, primitives, keyedvec, function, + environment, storage, testing}; + #[allow(unused)] mod system; #[allow(unused)] diff --git a/wasm-runtime/polkadot/src/endiansensitive.rs b/wasm-runtime/polkadot/src/support/endiansensitive.rs similarity index 100% rename from wasm-runtime/polkadot/src/endiansensitive.rs rename to wasm-runtime/polkadot/src/support/endiansensitive.rs diff --git a/wasm-runtime/polkadot/src/environment.rs b/wasm-runtime/polkadot/src/support/environment.rs similarity index 100% rename from wasm-runtime/polkadot/src/environment.rs rename to wasm-runtime/polkadot/src/support/environment.rs diff --git a/wasm-runtime/polkadot/src/function.rs b/wasm-runtime/polkadot/src/support/function.rs similarity index 100% rename from wasm-runtime/polkadot/src/function.rs rename to wasm-runtime/polkadot/src/support/function.rs diff --git a/wasm-runtime/polkadot/src/joiner.rs b/wasm-runtime/polkadot/src/support/joiner.rs similarity index 100% rename from wasm-runtime/polkadot/src/joiner.rs rename to wasm-runtime/polkadot/src/support/joiner.rs diff --git a/wasm-runtime/polkadot/src/keyedvec.rs b/wasm-runtime/polkadot/src/support/keyedvec.rs similarity index 100% rename from wasm-runtime/polkadot/src/keyedvec.rs rename to wasm-runtime/polkadot/src/support/keyedvec.rs diff --git a/wasm-runtime/polkadot/src/support/mod.rs b/wasm-runtime/polkadot/src/support/mod.rs new file mode 100644 index 0000000000000..dd381b1ad2e13 --- /dev/null +++ b/wasm-runtime/polkadot/src/support/mod.rs @@ -0,0 +1,10 @@ +pub mod endiansensitive; +pub mod streamreader; +pub mod joiner; +pub mod slicable; +pub mod primitives; +pub mod keyedvec; +pub mod function; +pub mod environment; +pub mod storage; +pub mod testing; diff --git a/wasm-runtime/polkadot/src/primitives.rs b/wasm-runtime/polkadot/src/support/primitives.rs similarity index 100% rename from wasm-runtime/polkadot/src/primitives.rs rename to wasm-runtime/polkadot/src/support/primitives.rs diff --git a/wasm-runtime/polkadot/src/slicable.rs b/wasm-runtime/polkadot/src/support/slicable.rs similarity index 100% rename from wasm-runtime/polkadot/src/slicable.rs rename to wasm-runtime/polkadot/src/support/slicable.rs diff --git a/wasm-runtime/polkadot/src/storage.rs b/wasm-runtime/polkadot/src/support/storage.rs similarity index 100% rename from wasm-runtime/polkadot/src/storage.rs rename to wasm-runtime/polkadot/src/support/storage.rs diff --git a/wasm-runtime/polkadot/src/streamreader.rs b/wasm-runtime/polkadot/src/support/streamreader.rs similarity index 100% rename from wasm-runtime/polkadot/src/streamreader.rs rename to wasm-runtime/polkadot/src/support/streamreader.rs diff --git a/wasm-runtime/polkadot/src/testing.rs b/wasm-runtime/polkadot/src/support/testing.rs similarity index 100% rename from wasm-runtime/polkadot/src/testing.rs rename to wasm-runtime/polkadot/src/support/testing.rs From 48440863a22f8fdb918a11bb8d4a0d7d29206cbb Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 16 Jan 2018 18:56:57 +0100 Subject: [PATCH 37/76] Fix up wasm runtime. --- executor/src/wasm_executor.rs | 4 +-- native-runtime/support/src/lib.rs | 6 +++++ wasm-runtime/polkadot/src/consensus.rs | 1 + wasm-runtime/polkadot/src/lib.rs | 17 ++++++------- wasm-runtime/polkadot/src/support/joiner.rs | 1 + wasm-runtime/polkadot/src/support/keyedvec.rs | 1 + wasm-runtime/polkadot/src/support/mod.rs | 2 ++ .../polkadot/src/support/primitives.rs | 23 +++++++++--------- wasm-runtime/polkadot/src/support/slicable.rs | 2 +- wasm-runtime/support/src/lib.rs | 16 ++++++++---- .../release/runtime_polkadot.compact.wasm | Bin 218 -> 5276 bytes .../release/runtime_polkadot.wasm | Bin 341 -> 5364 bytes 12 files changed, 45 insertions(+), 28 deletions(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index cb2df774d93d9..41029424fa221 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -136,8 +136,8 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, } else { 0 } } else { 0 } }, - ext_deposit_log(_log_data: *const u8, _log_len: u32) => { - // TODO + ext_chain_id() -> u64 => { + 42u64 } => <'e, E: Externalities + 'e> ); diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index 795cae2ffd9b4..9ec5f77bdd648 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -68,6 +68,12 @@ pub fn set_storage(_key: &[u8], _value: &[u8]) { ); } +/// The current relay chain identifier. +pub fn chain_id() -> u64 { + // TODO: fetch from Externalities. + 42u64 +} + /// Execute the given closure with global function available whose functionality routes into the /// externalities `ext`. Forwards the value that the closure returns. pub fn with_externalities R>(ext: &mut Externalities, f: F) -> R { diff --git a/wasm-runtime/polkadot/src/consensus.rs b/wasm-runtime/polkadot/src/consensus.rs index ef4d5a985692a..add87a180831e 100644 --- a/wasm-runtime/polkadot/src/consensus.rs +++ b/wasm-runtime/polkadot/src/consensus.rs @@ -1,3 +1,4 @@ +use runtime_support::Vec; use keyedvec::KeyedVec; use storage::Storage; use primitives::{AccountID, SessionKey, BlockNumber}; diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index cc48d8caa6b73..680116b3d9d76 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -6,7 +6,9 @@ extern crate runtime_support; mod support; pub use support::{endiansensitive, streamreader, joiner, slicable, primitives, keyedvec, function, - environment, storage, testing}; + environment, storage}; +#[cfg(test)] +pub use support::testing; #[allow(unused)] mod system; @@ -19,9 +21,12 @@ mod timestamp; use runtime_support::Vec; use slicable::Slicable; -use primitives::{ChainID, Block, Transaction}; +use primitives::{Block, Transaction}; -// TODO: add keccak256 (or some better hashing scheme) & ECDSA-recover (or some better sig scheme) +// TODO: add externals for: +// - keccak256 (or some better hashing scheme) +// - trie rooting +// - ECDSA-recover (or some better sig scheme) pub fn execute_block(input: Vec) -> Vec { system::execute_block(Block::from_slice(&input).unwrap()) @@ -32,9 +37,3 @@ pub fn execute_transaction(input: Vec) -> Vec { } impl_stubs!(execute_block, execute_transaction); - -/// The current relay chain identifier. -pub fn chain_id() -> ChainID { - // TODO: retrieve from external - unimplemented!() -} diff --git a/wasm-runtime/polkadot/src/support/joiner.rs b/wasm-runtime/polkadot/src/support/joiner.rs index 99b38dec57915..817df8e4cb6cf 100644 --- a/wasm-runtime/polkadot/src/support/joiner.rs +++ b/wasm-runtime/polkadot/src/support/joiner.rs @@ -1,3 +1,4 @@ +use runtime_support::Vec; use slicable::Slicable; pub trait Joiner { diff --git a/wasm-runtime/polkadot/src/support/keyedvec.rs b/wasm-runtime/polkadot/src/support/keyedvec.rs index 3b0e595628dba..fcc410e58234f 100644 --- a/wasm-runtime/polkadot/src/support/keyedvec.rs +++ b/wasm-runtime/polkadot/src/support/keyedvec.rs @@ -1,3 +1,4 @@ +use runtime_support::Vec; use primitives::AccountID; use slicable::Slicable; diff --git a/wasm-runtime/polkadot/src/support/mod.rs b/wasm-runtime/polkadot/src/support/mod.rs index dd381b1ad2e13..47b29194dccdf 100644 --- a/wasm-runtime/polkadot/src/support/mod.rs +++ b/wasm-runtime/polkadot/src/support/mod.rs @@ -7,4 +7,6 @@ pub mod keyedvec; pub mod function; pub mod environment; pub mod storage; + +#[cfg(test)] pub mod testing; diff --git a/wasm-runtime/polkadot/src/support/primitives.rs b/wasm-runtime/polkadot/src/support/primitives.rs index 44d3bc47399f7..f1bd31cc66097 100644 --- a/wasm-runtime/polkadot/src/support/primitives.rs +++ b/wasm-runtime/polkadot/src/support/primitives.rs @@ -1,3 +1,4 @@ +use runtime_support::Vec; use streamreader::StreamReader; use joiner::Joiner; use slicable::{Slicable, NonTrivialSlicable}; @@ -62,7 +63,7 @@ impl Slicable for Transaction { } fn to_vec(&self) -> Vec { - vec![] + Vec::new() .join(&self.signed) .join(&(self.function as u8)) .join(&self.nonce) @@ -84,7 +85,7 @@ impl Slicable for Vec { fn from_slice(value: &[u8]) -> Option { let len = Self::size_of(&value[0..4])?; let mut off = 4; - let mut r = vec![]; + let mut r = Vec::new(); while off < len { let element_len = T::size_of(&value[off..])?; r.push(T::from_slice(&value[off..off + element_len])?); @@ -100,7 +101,7 @@ impl Slicable for Vec { fn to_vec(&self) -> Vec { let vecs = self.iter().map(Slicable::to_vec).collect::>(); let len = vecs.iter().fold(0, |mut a, v| {a += v.len(); a}); - let mut r = vec![].join(&(len as u32)); + let mut r = Vec::new().join(&(len as u32)); vecs.iter().for_each(|v| r.extend_from_slice(v)); r } @@ -127,7 +128,7 @@ impl Slicable for Header { } fn to_vec(&self) -> Vec { - vec![] + Vec::new() .join(&self.parent_hash) .join(&self.number) .join(&self.state_root) @@ -156,7 +157,7 @@ impl Slicable for Block { } fn to_vec(&self) -> Vec { - vec![] + Vec::new() .join(&self.header) .join(&self.transactions) } @@ -181,7 +182,7 @@ mod tests { let tx = Transaction { signed: one.clone(), function: Function::StakingTransferStake, - input_data: vec![].join(&two).join(&69u64), + input_data: Vec::new().join(&two).join(&69u64), nonce: 69, }; let serialised = tx.to_vec(); @@ -202,7 +203,7 @@ mod tests { let tx = Transaction { signed: one.clone(), function: Function::StakingTransferStake, - input_data: vec![].join(&two).join(&69u64), + input_data: Vec::new().join(&two).join(&69u64), nonce: 69, }; let data = [ @@ -271,13 +272,13 @@ mod tests { let tx1 = Transaction { signed: one.clone(), function: Function::StakingTransferStake, - input_data: vec![].join(&two).join(&69u64), + input_data: Vec::new().join(&two).join(&69u64), nonce: 69, }; let tx2 = Transaction { signed: two.clone(), function: Function::StakingStake, - input_data: vec![], + input_data: Vec::new(), nonce: 42, }; let h = Header { @@ -327,13 +328,13 @@ mod tests { let tx1 = Transaction { signed: one.clone(), function: Function::StakingTransferStake, - input_data: vec![].join(&two).join(&69u64), + input_data: Vec::new().join(&two).join(&69u64), nonce: 69, }; let tx2 = Transaction { signed: two.clone(), function: Function::StakingStake, - input_data: vec![], + input_data: Vec::new(), nonce: 42, }; let h = Header { diff --git a/wasm-runtime/polkadot/src/support/slicable.rs b/wasm-runtime/polkadot/src/support/slicable.rs index e220eb0f7d6c9..939d1591caecd 100644 --- a/wasm-runtime/polkadot/src/support/slicable.rs +++ b/wasm-runtime/polkadot/src/support/slicable.rs @@ -59,7 +59,7 @@ impl Slicable for Vec { unimplemented!(); } fn to_vec(&self) -> Vec { - let mut r: Vec = vec![].join(&(self.len() as u32)); + let mut r: Vec = Vec::new().join(&(self.len() as u32)); r.extend_from_slice(&self); r } diff --git a/wasm-runtime/support/src/lib.rs b/wasm-runtime/support/src/lib.rs index 9c64f1a72bbc5..308ab6dd9e93e 100644 --- a/wasm-runtime/support/src/lib.rs +++ b/wasm-runtime/support/src/lib.rs @@ -10,6 +10,7 @@ pub use alloc::vec::Vec; pub use alloc::boxed::Box; pub use alloc::rc::Rc; pub use core::mem::{transmute, size_of, uninitialized, swap}; +pub use core::slice; pub use core::cell::{RefCell, Ref, RefMut}; extern crate pwasm_libc; @@ -27,7 +28,7 @@ extern "C" { fn ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32); fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8; fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32) -> u32; - fn ext_deposit_log(log_data: *const u8, log_len: u32); + fn ext_chain_id() -> u64; } pub fn storage(key: &[u8]) -> Vec { @@ -64,11 +65,16 @@ pub fn set_storage(key: &[u8], value: &[u8]) { } } -pub fn deposit_log(log: &[u8]) { +pub fn read_storage(key: &[u8], value_out: &mut [u8]) -> usize { unsafe { - ext_deposit_log( - &log[0] as *const u8, log.len() as u32, - ) + ext_get_storage_into(&key[0], key.len() as u32, &mut value_out[0], value_out.len() as u32) as usize + } +} + +/// The current relay chain identifier. +pub fn chain_id() -> u64 { + unsafe { + ext_chain_id() } } diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm index be2ae9b30e8d7d68992f083914c317bed5487e55..658efc37386ac47900dea844825f63fd7c92c24f 100644 GIT binary patch literal 5276 zcmb_gy>A@H6`z^iy$|l~-QL}vMaL@ME{Na=M34*nc(4S6LqJhn7;e(@DC#0S#V!ieD3cy)$3z9xo1$_U_Dg?;R`-mFB56o_e_V;KAX(GPPj-aR2i!l*fV|YaG{$ zmG5=JK&hb7Y_>e3d|!W#H&3g6^Oudr!}-I*qc4n#=8xz5j~4UYTQGfJtqsff#nIlu z@!tO8-r<1?`$vzC7rVFSckUhRK05f#y@T7T(&DV-*MCV_ zKOY;F`FLu{lXsuYXOSY0OrEvKw|bE^sYT7t-b(}WZ$z3DR-_H`DYzLKYNXAM7m9w` za&saGVv{u^&2#cdvVvEA`d%ERJ~d*+_Do2MniHc03i-jx?^`BXnlG)gIJ$3N>ib!5Vtne^mnygG zInD?#wJ}+(MSp(8mB_%DZW>|Hq#g<3@rYQ`u2!`Oob0Sy?s8Ncj zw`pcu=2XMRGiRegUO6iw*l4bpWi8lf)n?hosopZr*vN@9(yq4<5sa)+v$D%tFcMO$ z6tR(KFmfVDoM$@JE~o7?h+rh5wR0jE=~7sV*vJWtY*U*$g>a3c;whx=s^Ye6=2d(6 zmFeJ3i*Qiwm)ada`veMM2`Tklh@T(=JV8r!ZEVna73gpP#?ux9!^31k4=Y%9s1^D6XRI#=f#GXnPMH6{0!)-moY2+P1my{&hQjyo|4Ah18N{}!wKLFZSL`baUt-c@y~uc;5&*Usyq6>88q zm?Qj4)AW{J#VDs>l$aSMwq@Gsv1w(dW)+!%;~HexagJ(42)}__*>8oAj64ynRs2*Y zqZ3I0N&;~r@qWn~F~yq(={bXmf(`0|aUz(gE60goqAnLPF_Zd?rSd_OHGMb{Y}EAO zM6gj)hS+dq5Hroz%n@@A)vOV78TKl^kagS4#eT&cLB$+MvLeGo4;ePY9axfXeW(l1 zQXip4ej#AQfYQF%wk;GDZad_z#dUj|VloqPEYkFD5h6^*0SGT1o4XmNr8(dM2*+l| zq7&_2ZfEU@`HEjKZa8ZkX{4~WNp1;-ux2CmrMU4(87^NWGit7gQ;ZwvCL`MPPINjz zj_#;*5DL`xIjGoUhE;DsEd%ZlLkq?@btQ}3t3!_G8aa9pL5`7;W3E8%VqZaT*3c0I zhTgas`p`iihOjoE{_nPM9<&UP9+t2o;4pfgf;(~w4N;(JY_9e>MvuF*?*e4_F% zh3E;hru7{q|3l^A%aNV3`_h=TtxAU&jkgUVjsUOEy<&H)RF*K%1UVJmhyq3~(NQ#_ zWMZykh$dz#)~JhZpc>Fhb*B4w<|8nEQwpR#$JqMx^QV1aJ^~zE@b~vxWerQx^TSwTjdtZLuz6u zE|n2AuPSv-FR%+os{?t~w*Jp0Tu4%9q%`pa7cEQ-D6H0xuIj}#{RD~0(Zx?JD%Ekn zv3j2dtLjhmHGRhVXf|9}3xFNgrv9q#8FV}JZhDEjX-pAvx(!kR(1F9qxyOlD>>a

      45kB57@SlpcDVEVlarH} z@Al!2+VVi}7T=ERZvL_x$PF9T$7%pFa6Z!z*c>F;32DgK4YL!H5^f_$gb`BV9kB^L zg&oFf9fdwb8?1PT%Xwy)L%_zg{uCXX)1h<#9e<*D-;JDsVl4*Mf;_QHYy(wfS`zV3 zxohy5#|+9GPo6LwX1tpH_{J9YOA!M~kez@H1nk*Zc;B(-I!jn_$fxp)%|OY_t&qcN zgfwI)DikJI7MX)YP2x7D5asJUfpIFkVM@5R%me1ZDzI=LZ$Co#B`_n7bw#CBU`8%5 zBNrH%zwFe=4OL)}DTMp84h(RpOs)+?>=OiTWS8tlzTFgHI;Z084X2LKe#qkDIO}o@ zzFXevUU4248|XL-*N&tb&bfBvTsvURfy?gZTVyv}-{+-Gb~Hd94p*U-M6b& zjwG+{vN>b}?!@xnAGN`6<*JT_e|Ldy(#Hn_k^tXTxR#84g}a9ZcFNa}vESl$5NRQB zB7Q;D$fRVCLEgeeytBdQigStk6%hk5ADZv<4t>p&-|9^N`77>&`0Y=kq@je8H1?%5 zSmcE*W{{k&I B=@I|{ literal 218 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 literal 341 zcmYLE%Wi})3>+unnXSaCx1RWv?nmqySn5`&n}8tf<5GUT3AEy1duC*NY&4T00Q45s zw7>@~wOp1^gwH=UAkL9wdrSG@s?U)b2s97WG}mk2f_8yTJ3JwRpw|vIroZu~Y%^>o zc3#L*DU}d{pcD;2Bnii4$YR5$AD;p*{NQ$WTwT1$H=@^n?#9MWP3yYeB0i4u Date: Tue, 16 Jan 2018 19:04:13 +0100 Subject: [PATCH 38/76] use externalities for chain_id --- executor/src/wasm_executor.rs | 2 +- native-runtime/support/src/lib.rs | 7 +++++-- state_machine/src/ext.rs | 4 ++++ state_machine/src/lib.rs | 5 ++++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index 41029424fa221..580da807722cb 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -137,7 +137,7 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, } else { 0 } }, ext_chain_id() -> u64 => { - 42u64 + this.ext.chain_id() } => <'e, E: Externalities + 'e> ); diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index 9ec5f77bdd648..498081cd333f2 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -70,8 +70,9 @@ pub fn set_storage(_key: &[u8], _value: &[u8]) { /// The current relay chain identifier. pub fn chain_id() -> u64 { - // TODO: fetch from Externalities. - 42u64 + ext::with(|holder| + holder.ext.chain_id() + ).unwrap_or(0) } /// Execute the given closure with global function available whose functionality routes into the @@ -105,6 +106,8 @@ mod tests { fn set_storage(&mut self, key: Vec, value: Vec) { self.storage.insert(key, value); } + + fn chain_id(&self) -> u64 { 42 } } macro_rules! map { diff --git a/state_machine/src/ext.rs b/state_machine/src/ext.rs index ce7b9a02680dd..1452558ccd957 100644 --- a/state_machine/src/ext.rs +++ b/state_machine/src/ext.rs @@ -73,4 +73,8 @@ impl<'a, B: 'a> Externalities for Ext<'a, B> fn set_storage(&mut self, key: Vec, value: Vec) { self.overlay.set_storage(key, value); } + + fn chain_id(&self) -> u64 { + 42 + } } diff --git a/state_machine/src/lib.rs b/state_machine/src/lib.rs index 38c481113f21f..3ff3b6946999b 100644 --- a/state_machine/src/lib.rs +++ b/state_machine/src/lib.rs @@ -130,7 +130,10 @@ pub trait Externalities { /// Set storage of current contract being called (effective immediately). fn set_storage(&mut self, key: Vec, value: Vec); - /// Get the current set of authorities. + /// Get the identity of the chain. + fn chain_id(&self) -> u64 { 42 } // TODO: remove implementation and fix resulting errors. + + /// Get the current set of authorities from storage. fn authorities(&self) -> Result, Self::Error> { (0..self.storage(b"con\0aut\0len")?.into_iter() .rev() From 75cedd9503870fccc3fe3c66b241f0503f5aacb3 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 16 Jan 2018 19:07:10 +0100 Subject: [PATCH 39/76] Clean up (Test)Externalities. --- executor/src/wasm_executor.rs | 2 ++ state_machine/src/lib.rs | 4 +++- wasm-runtime/polkadot/src/support/testing.rs | 2 ++ wasm-runtime/polkadot/src/system.rs | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index 580da807722cb..b12986e975cf4 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -208,6 +208,8 @@ mod tests { fn set_storage(&mut self, key: Vec, value: Vec) { self.storage.insert(key, value); } + + fn chain_id(&self) -> u64 { 42 } } #[test] diff --git a/state_machine/src/lib.rs b/state_machine/src/lib.rs index 3ff3b6946999b..e94b2b6078c4f 100644 --- a/state_machine/src/lib.rs +++ b/state_machine/src/lib.rs @@ -131,7 +131,7 @@ pub trait Externalities { fn set_storage(&mut self, key: Vec, value: Vec); /// Get the identity of the chain. - fn chain_id(&self) -> u64 { 42 } // TODO: remove implementation and fix resulting errors. + fn chain_id(&self) -> u64; /// Get the current set of authorities from storage. fn authorities(&self) -> Result, Self::Error> { @@ -244,6 +244,8 @@ mod tests { fn set_storage(&mut self, key: Vec, value: Vec) { self.storage.insert(key, value); } + + fn chain_id(&self) -> u64 { 42 } } #[test] diff --git a/wasm-runtime/polkadot/src/support/testing.rs b/wasm-runtime/polkadot/src/support/testing.rs index d73917eb16f6d..ec7fac6d6ddb6 100644 --- a/wasm-runtime/polkadot/src/support/testing.rs +++ b/wasm-runtime/polkadot/src/support/testing.rs @@ -16,4 +16,6 @@ impl Externalities for TestExternalities { fn set_storage(&mut self, key: Vec, value: Vec) { self.storage.insert(key, value); } + + fn chain_id(&self) -> u64 { 42 } } diff --git a/wasm-runtime/polkadot/src/system.rs b/wasm-runtime/polkadot/src/system.rs index 88414fa9a16d4..de8b814bcfea2 100644 --- a/wasm-runtime/polkadot/src/system.rs +++ b/wasm-runtime/polkadot/src/system.rs @@ -96,6 +96,8 @@ mod tests { fn set_storage(&mut self, key: Vec, value: Vec) { self.storage.insert(key, value); } + + fn chain_id(&self) -> u64 { 42 } } macro_rules! map { From 0feadc6b84c7880c5927431e94c24165bd96b600 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 17 Jan 2018 11:45:36 +0100 Subject: [PATCH 40/76] Repot and introduce keccak-256 external. --- Cargo.lock | 3 + executor/Cargo.toml | 2 + executor/src/lib.rs | 2 + executor/src/wasm_executor.rs | 69 ++++++++---------- native-runtime/support/Cargo.toml | 1 + native-runtime/support/src/lib.rs | 4 + .../src/{support => codec}/endiansensitive.rs | 0 .../polkadot/src/{support => codec}/joiner.rs | 0 .../src/{support => codec}/keyedvec.rs | 0 wasm-runtime/polkadot/src/codec/mod.rs | 5 ++ .../src/{support => codec}/slicable.rs | 0 .../src/{support => codec}/streamreader.rs | 0 wasm-runtime/polkadot/src/lib.rs | 20 ++--- .../polkadot/src/{ => runtime}/consensus.rs | 0 wasm-runtime/polkadot/src/runtime/mod.rs | 8 ++ .../polkadot/src/{ => runtime}/staking.rs | 4 +- .../polkadot/src/{ => runtime}/system.rs | 5 +- .../polkadot/src/{ => runtime}/timestamp.rs | 0 wasm-runtime/polkadot/src/support/function.rs | 3 +- wasm-runtime/polkadot/src/support/mod.rs | 5 -- wasm-runtime/support/src/lib.rs | 11 +++ .../release/runtime_test.compact.wasm | Bin 3392 -> 843 bytes .../release/runtime_test.wasm | Bin 3480 -> 960 bytes wasm-runtime/test/src/lib.rs | 65 +++-------------- 24 files changed, 89 insertions(+), 118 deletions(-) rename wasm-runtime/polkadot/src/{support => codec}/endiansensitive.rs (100%) rename wasm-runtime/polkadot/src/{support => codec}/joiner.rs (100%) rename wasm-runtime/polkadot/src/{support => codec}/keyedvec.rs (100%) create mode 100644 wasm-runtime/polkadot/src/codec/mod.rs rename wasm-runtime/polkadot/src/{support => codec}/slicable.rs (100%) rename wasm-runtime/polkadot/src/{support => codec}/streamreader.rs (100%) rename wasm-runtime/polkadot/src/{ => runtime}/consensus.rs (100%) create mode 100644 wasm-runtime/polkadot/src/runtime/mod.rs rename wasm-runtime/polkadot/src/{ => runtime}/staking.rs (98%) rename wasm-runtime/polkadot/src/{ => runtime}/system.rs (98%) rename wasm-runtime/polkadot/src/{ => runtime}/timestamp.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index d0eee3e39a138..2ac1c11912de4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -687,8 +687,10 @@ dependencies = [ "polkadot-primitives 0.1.0", "polkadot-serializer 0.1.0", "polkadot-state-machine 0.1.0", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -841,6 +843,7 @@ dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-state-machine 0.1.0", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/executor/Cargo.toml b/executor/Cargo.toml index 8aa72f4327b81..2d124f60ac323 100644 --- a/executor/Cargo.toml +++ b/executor/Cargo.toml @@ -12,6 +12,8 @@ serde = "1.0" serde_derive = "1.0" parity-wasm = "0.15.0" byteorder = "1.1" +tiny-keccak = "1.3" +rustc-hex = "1.0.0" [dev-dependencies] assert_matches = "1.1" diff --git a/executor/src/lib.rs b/executor/src/lib.rs index 8bf7f42b623fe..3c54d25efb216 100644 --- a/executor/src/lib.rs +++ b/executor/src/lib.rs @@ -33,6 +33,8 @@ extern crate polkadot_state_machine as state_machine; extern crate serde; extern crate parity_wasm; extern crate byteorder; +extern crate tiny_keccak; +extern crate rustc_hex; #[macro_use] extern crate error_chain; diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index b12986e975cf4..8597656c51cd3 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -26,6 +26,7 @@ use state_machine::{Externalities, CodeExecutor}; use error::{Error, ErrorKind, Result}; use wasm_utils::{MemoryInstance, UserDefinedElements, AddModuleWithoutFullDependentInstance}; +use tiny_keccak; struct Heap { end: u32, @@ -138,6 +139,15 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, }, ext_chain_id() -> u64 => { this.ext.chain_id() + }, + ext_keccak256(data: *const u8, len: u32, out: *mut u8) => { + let result = + if let Ok(value) = this.memory.get(data, len as usize) { + tiny_keccak::keccak256(&value) + } else { + [0; 32] + }; + let _ = this.memory.set(out, &result); } => <'e, E: Externalities + 'e> ); @@ -193,6 +203,7 @@ impl CodeExecutor for WasmExecutor { mod tests { use super::*; + use rustc_hex::FromHex; #[derive(Debug, Default)] struct TestExternalities { @@ -213,50 +224,34 @@ mod tests { } #[test] - fn should_pass_externalities_at_call() { + fn storage_should_work() { let mut ext = TestExternalities::default(); - ext.set_storage(b"\0code".to_vec(), b"The code".to_vec()); - - let program = ProgramInstance::new().unwrap(); - - let test_module = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); - let module = deserialize_buffer(test_module.to_vec()).expect("Failed to load module"); - let module = program.add_module_by_sigs("test", module, map!["env" => FunctionExecutor::::SIGNATURES]).expect("Failed to initialize module"); - - let output = { - let memory = module.memory(ItemIndex::Internal(0)).unwrap(); - let mut fec = FunctionExecutor::new(&memory, &mut ext); - - let data = b"Hello world"; - let size = data.len() as u32; - let offset = fec.heap.allocate(size); - memory.set(offset, data).unwrap(); - - let returned = program - .params_with_external("env", &mut fec) - .map(|p| p - .add_argument(I32(offset as i32)) - .add_argument(I32(size as i32))) - .and_then(|p| module.execute_export("test_data_in", p)) - .map_err(|_| -> Error { ErrorKind::Runtime.into() }).expect("function should be callable"); - - if let Some(I64(r)) = returned { - println!("returned {:?} ({:?}, {:?})", r, r as u32, (r >> 32) as u32 as usize); - memory.get(r as u32, (r >> 32) as u32 as usize).expect("memory address should be reasonable.") - } else { - panic!("bad return value, not u64"); - } - }; + ext.set_storage(b"foo".to_vec(), b"bar".to_vec()); + let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); + + let output = WasmExecutor.call(&mut ext, &test_code[..], "test_data_in", &CallData(b"Hello world".to_vec())).unwrap(); assert_eq!(output, b"all ok!".to_vec()); let expected: HashMap<_, _> = map![ - b"\0code".to_vec() => b"Hello world".to_vec(), b"input".to_vec() => b"Hello world".to_vec(), - b"code".to_vec() => b"The code".to_vec(), - b"\0authority_count".to_vec() => vec![1], - b"\0authority".to_vec() => b"Hello world".to_vec() + b"foo".to_vec() => b"bar".to_vec(), + b"baz".to_vec() => b"bar".to_vec() ]; assert_eq!(expected, ext.storage); } + + #[test] + fn keccak256_should_work() { + let mut ext = TestExternalities::default(); + let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); + assert_eq!( + WasmExecutor.call(&mut ext, &test_code[..], "test_keccak256", &CallData(b"".to_vec())).unwrap(), + FromHex::from_hex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap() + ); + assert_eq!( + WasmExecutor.call(&mut ext, &test_code[..], "test_keccak256", &CallData(b"Hello world!".to_vec())).unwrap(), + FromHex::from_hex("ecd0e108a98e192af1d2c25055f4e3bed784b5c877204e73219a5203251feaab").unwrap() + ); + } } diff --git a/native-runtime/support/Cargo.toml b/native-runtime/support/Cargo.toml index 3f979bd4ff443..185dea5f925a0 100644 --- a/native-runtime/support/Cargo.toml +++ b/native-runtime/support/Cargo.toml @@ -11,3 +11,4 @@ lazy_static = "1.0.0" parking_lot = "0.5" polkadot-state-machine = { path = "../../state_machine" , version = "0.1" } environmental = { path = "../../environmental", version = "0.1.0" } +tiny-keccak = "1.3" diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index 498081cd333f2..a2fe13eb104a2 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -1,6 +1,7 @@ #[macro_use] extern crate environmental; extern crate polkadot_state_machine; +extern crate tiny_keccak; pub use std::vec::Vec; pub use std::rc::Rc; @@ -75,6 +76,9 @@ pub fn chain_id() -> u64 { ).unwrap_or(0) } +/// Conduct a Keccak-256 hash of the given data. +pub use tiny_keccak::keccak256; + /// Execute the given closure with global function available whose functionality routes into the /// externalities `ext`. Forwards the value that the closure returns. pub fn with_externalities R>(ext: &mut Externalities, f: F) -> R { diff --git a/wasm-runtime/polkadot/src/support/endiansensitive.rs b/wasm-runtime/polkadot/src/codec/endiansensitive.rs similarity index 100% rename from wasm-runtime/polkadot/src/support/endiansensitive.rs rename to wasm-runtime/polkadot/src/codec/endiansensitive.rs diff --git a/wasm-runtime/polkadot/src/support/joiner.rs b/wasm-runtime/polkadot/src/codec/joiner.rs similarity index 100% rename from wasm-runtime/polkadot/src/support/joiner.rs rename to wasm-runtime/polkadot/src/codec/joiner.rs diff --git a/wasm-runtime/polkadot/src/support/keyedvec.rs b/wasm-runtime/polkadot/src/codec/keyedvec.rs similarity index 100% rename from wasm-runtime/polkadot/src/support/keyedvec.rs rename to wasm-runtime/polkadot/src/codec/keyedvec.rs diff --git a/wasm-runtime/polkadot/src/codec/mod.rs b/wasm-runtime/polkadot/src/codec/mod.rs new file mode 100644 index 0000000000000..5350dc05c180f --- /dev/null +++ b/wasm-runtime/polkadot/src/codec/mod.rs @@ -0,0 +1,5 @@ +pub mod endiansensitive; +pub mod streamreader; +pub mod joiner; +pub mod slicable; +pub mod keyedvec; diff --git a/wasm-runtime/polkadot/src/support/slicable.rs b/wasm-runtime/polkadot/src/codec/slicable.rs similarity index 100% rename from wasm-runtime/polkadot/src/support/slicable.rs rename to wasm-runtime/polkadot/src/codec/slicable.rs diff --git a/wasm-runtime/polkadot/src/support/streamreader.rs b/wasm-runtime/polkadot/src/codec/streamreader.rs similarity index 100% rename from wasm-runtime/polkadot/src/support/streamreader.rs rename to wasm-runtime/polkadot/src/codec/streamreader.rs diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 680116b3d9d76..52b29b05cf75d 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -4,20 +4,14 @@ #[macro_use] extern crate runtime_support; +mod codec; mod support; -pub use support::{endiansensitive, streamreader, joiner, slicable, primitives, keyedvec, function, - environment, storage}; +mod runtime; +pub use codec::{endiansensitive, streamreader, joiner, slicable, keyedvec}; +pub use support::{primitives, function, environment, storage}; #[cfg(test)] pub use support::testing; - -#[allow(unused)] -mod system; -#[allow(unused)] -mod consensus; -#[allow(unused)] -mod staking; -#[allow(unused)] -mod timestamp; +#[allow(unused_imports)] // TODO: remove in due course use runtime_support::Vec; use slicable::Slicable; @@ -29,11 +23,11 @@ use primitives::{Block, Transaction}; // - ECDSA-recover (or some better sig scheme) pub fn execute_block(input: Vec) -> Vec { - system::execute_block(Block::from_slice(&input).unwrap()) + runtime::system::execute_block(Block::from_slice(&input).unwrap()) } pub fn execute_transaction(input: Vec) -> Vec { - system::execute_transaction(&Transaction::from_slice(&input).unwrap()) + runtime::system::execute_transaction(&Transaction::from_slice(&input).unwrap()) } impl_stubs!(execute_block, execute_transaction); diff --git a/wasm-runtime/polkadot/src/consensus.rs b/wasm-runtime/polkadot/src/runtime/consensus.rs similarity index 100% rename from wasm-runtime/polkadot/src/consensus.rs rename to wasm-runtime/polkadot/src/runtime/consensus.rs diff --git a/wasm-runtime/polkadot/src/runtime/mod.rs b/wasm-runtime/polkadot/src/runtime/mod.rs new file mode 100644 index 0000000000000..c73e338a91b2c --- /dev/null +++ b/wasm-runtime/polkadot/src/runtime/mod.rs @@ -0,0 +1,8 @@ +#[allow(unused)] +pub mod system; +#[allow(unused)] +pub mod consensus; +#[allow(unused)] +pub mod staking; +#[allow(unused)] +pub mod timestamp; diff --git a/wasm-runtime/polkadot/src/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs similarity index 98% rename from wasm-runtime/polkadot/src/staking.rs rename to wasm-runtime/polkadot/src/runtime/staking.rs index d8903504d2d53..ca37e7f6fea7f 100644 --- a/wasm-runtime/polkadot/src/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -1,7 +1,7 @@ use keyedvec::KeyedVec; use storage::{Storage, storage_into}; use primitives::{BlockNumber, Balance, AccountID}; -use consensus; +use runtime::consensus; /// The length of a staking era in blocks. pub fn era_length() -> BlockNumber { @@ -68,7 +68,7 @@ mod tests { use runtime_support::with_externalities; use testing::TestExternalities; use primitives::{AccountID}; - use staking; + use runtime::staking; macro_rules! map { ($( $name:expr => $value:expr ),*) => ( diff --git a/wasm-runtime/polkadot/src/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs similarity index 98% rename from wasm-runtime/polkadot/src/system.rs rename to wasm-runtime/polkadot/src/runtime/system.rs index de8b814bcfea2..27c5eb4fd9bcb 100644 --- a/wasm-runtime/polkadot/src/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -1,8 +1,8 @@ use primitives::{Block, BlockNumber, Hash, Transaction}; use runtime_support::{Vec, swap}; use environment::with_env; -use staking; use runtime_support; +use runtime::staking; /// The current block number being processed. Set by `execute_block`. pub fn block_number() -> BlockNumber { @@ -79,8 +79,7 @@ mod tests { use std::collections::HashMap; use runtime_support::{NoError, with_externalities, Externalities}; use primitives::{AccountID, Transaction}; - use system; - use staking; + use runtime::{system, staking}; #[derive(Debug, Default)] struct TestExternalities { diff --git a/wasm-runtime/polkadot/src/timestamp.rs b/wasm-runtime/polkadot/src/runtime/timestamp.rs similarity index 100% rename from wasm-runtime/polkadot/src/timestamp.rs rename to wasm-runtime/polkadot/src/runtime/timestamp.rs diff --git a/wasm-runtime/polkadot/src/support/function.rs b/wasm-runtime/polkadot/src/support/function.rs index 3f6845bfe6cfb..ff54938d47aa8 100644 --- a/wasm-runtime/polkadot/src/support/function.rs +++ b/wasm-runtime/polkadot/src/support/function.rs @@ -1,5 +1,4 @@ -use staking; -use consensus; +use runtime::{staking, consensus}; use primitives::AccountID; use streamreader::StreamReader; diff --git a/wasm-runtime/polkadot/src/support/mod.rs b/wasm-runtime/polkadot/src/support/mod.rs index 47b29194dccdf..aa14ad2f5dba9 100644 --- a/wasm-runtime/polkadot/src/support/mod.rs +++ b/wasm-runtime/polkadot/src/support/mod.rs @@ -1,9 +1,4 @@ -pub mod endiansensitive; -pub mod streamreader; -pub mod joiner; -pub mod slicable; pub mod primitives; -pub mod keyedvec; pub mod function; pub mod environment; pub mod storage; diff --git a/wasm-runtime/support/src/lib.rs b/wasm-runtime/support/src/lib.rs index 308ab6dd9e93e..ae3feb14c931c 100644 --- a/wasm-runtime/support/src/lib.rs +++ b/wasm-runtime/support/src/lib.rs @@ -29,6 +29,7 @@ extern "C" { fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8; fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32) -> u32; fn ext_chain_id() -> u64; + fn ext_keccak256(data: *const u8, len: u32, out: *mut u8); } pub fn storage(key: &[u8]) -> Vec { @@ -78,6 +79,16 @@ pub fn chain_id() -> u64 { } } +/// Conduct a keccak256 hash. +pub fn keccak256(data: &[u8]) -> [u8; 32] { + unsafe { + let mut result: [u8; 32] = uninitialized(); + // guaranteed to write into result. + ext_keccak256(&data[0], data.len() as u32, &mut result[0]); + result + } +} + pub trait Printable { fn print(self); } diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index bac77de7ffc344d73e46f9c32657563efb790174..f4c438ec106e2dad2e662f47d1abbb293e62178c 100644 GIT binary patch literal 843 zcmY*XOKuZE5Pkib_SiiklbzYMy>cWYA|xCMvT#LWi&(RW^M3pN}E z&cGeGK#sr>s2+b3MjBPU_o`l3mm0}>ApnSeI2IMgs;Vkc)d5U!Dl4Wn(;PS#-^PIa zYE)X>hUuqrbh%1Xz{95=&eC#}TwN_ENtsSZ>vFkDW+{Z%54=84CzE9U;^hF+b1ly; z>INuJG(B;>%8C-&<3o?vY`U`wlnIP!C}=INfj|iyHQpMtNEgf1XNjmx*X3xMl*uS7 zV4l?Q;nc>_>W1};be0vPo8n_uOc9#x1WjGvrqvW^{ZYX$A!J1$^rWVE-c7nu;Tg_f z!2`|Uxfs5#0Uv!f;7rDF;9tZ%4j&QcJc|=Q&+qvAi|>aPus@^-_VeCj-Zj36o17t+ z$CATuR&l|$y)kY_oTTPwB+oZLfh z=3VR{x5*(N$qR7%1$Yvt^@ZEH(|Zu-F4%)G-g0$7|*Z~w-`}k#1+Xh*2eN%#*ZS39~^{l#FEx6WhGZifsKMopwNH Lw!yF0E$5woQ|P6l literal 3392 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 IqnC@pKX_xoTmS$7 literal 3480 zcmcgv&2k&Z5$>6t{hisxQldmrq{!K|6U$CyBPoS)B|e~CrsN!4KIcTyA}j+ENEHdv z(IJK^0>pc$I)yyQ!{k&rDvEhm_UQR`sOi_{+r68;qgT_{NwcC%hTbINQRp-d^(&S96o=3 z^5k$jJUTd=o}3;&9g>puLe?i?k@V|{;pEASmz{(S62r;lDz!^zoj+KJ>M^5S%K zJf%o<^kj_HR0on;sk;P7e=8$7I(| z&oTUB_;hr9aDM#t==g}7$ckZQicT=7k|{Bym(0DWP4Ip#S5*9Uqxh3DGd)=Rd15oZ ztEpA{C3!-x(O!AQYTBAdrSiIooVILg-A4PRX44p_tPf)^qDDTSZPjH1;hH=YY3s>H zdm0L%-5d0JmPr18r&K(Hl6YZ&9$aBU3lV*nu&U@)AGnLbe4zat#Z^sZiifL_7{PVq@+PZ(uzAJ)oR zHf|y=8pQ<{kIDdg(Zql%bw-e5jUEsnG|F$0|7rAOz>PLNL+$?7BK2DBzl%3OvRQJ8q>KRErAeZ z0E8$-YS}-p=@K`85z|Y0)|ODheYSPNA90KWRhz{$^WEr zt=im|clDr7eGbEafRT`w^-jqptgVy9W>G%hhub6j5V(Jl9J~_{%$9+KxCi`XN^X|%0lM7^# z^`+1EwChX}kNp^5*|;vC2iE%T;LIoC;F9}etO^2#gfHqItX9=zZ>g zYL>$Bok4JzpgS~5%Bj1Av<$?-6{k%owS?f=Ivv2n%T71bFJRJ^djX@Y#KM zg8T3Y$O}ldAoQWIr{ocQZE#~`Ca4z!67;}h22qn_7pjy@57ePE{x@+CDPqKmqSK&| zpAn*#?W<|Xo@g{iIpS)h}sw9HhUO|C-+ff;GEDG^cmq^K?FlN z)OgSj8qDDK=7NBvloR7J_+%wp3>*j-Vl`psc`|4-NxCd#Nddl?rzbQbJ>lF+dIrft z(i2C02J?g0; z3!j5MF50}@1({avH*ow)offy&7fYR9U~#`*>I|uaHxIA5=tRgb@DASwXIJi5&P$x=(UCtoU@AyAQ_X7|Xl341E9mKP8?}vA2+~6S((Q<4td(V1{$Er!C zAyD=_e|Fem^_N(cG=|0hE1Ty0gq)G2e>1zBoLxfCFRY}Lcerlh)!pS9v+rGvP~q;Z zqQ1iwWbZB!x*GKzUW3#-3xq=aK$=noq=Hbn>vqJ8qMP7rkp3Aa@aSAe_igK)TvQ28 z{HR>#bxgj6+GoGq<{RiE5hBRmL>K7&NSx!HO1olYi#IThorV)!xqI}T>SAZY1^iac z%agnMl|m&Ww)KUFI!==aZSgH=*hSnyV_*w_#haLc$sj5r7LmD)89*bn15>sz+73H} zT63P_B`I(5Hm0`%4EOiTO}>NS?at2~bT?5Ipm38SL4tKjV_{44_m5xU-+$=aP(GrR zsN7Ad1}b->yT0pE4OH%WxW(?8R0EY;vn-ib+kh6T2uY~Q@-CXvvPa`=h#n|Uf>_uP zcRZIpj4~UbMTIm}3s4|-Hl`;hM?>Ou>^VH2esyv>n!Y6VwthW4cye-%9~j)X zcJ-$Pe`Mp)@r!e;d{5SNdVV0AiBLDXB%3aN^q@|$c5%dLct&`YY)@q0nEa7!{^jU+ UboSNos3Cr(Y>MAV{^VKnUuVwX;Q#;t diff --git a/wasm-runtime/test/src/lib.rs b/wasm-runtime/test/src/lib.rs index e95844fdb038b..a24de0219d114 100644 --- a/wasm-runtime/test/src/lib.rs +++ b/wasm-runtime/test/src/lib.rs @@ -8,72 +8,25 @@ use alloc::vec::Vec; #[macro_use] extern crate runtime_support; -use runtime_support::{set_storage, storage, print}; +use runtime_support::{set_storage, storage, print, keccak256}; -pub fn code() -> Vec { - storage(b"\0code") +fn test_keccak256(input: Vec) -> Vec { + keccak256(&input).to_vec() } -pub fn set_code(new: &[u8]) { - set_storage(b"\0code", new) -} - -fn value_vec(mut value: usize, initial: Vec) -> Vec { - let mut acc = initial; - while value > 0 { - acc.push(value as u8); - value /= 256; - } - acc -} - -pub fn set_authority(index: usize, authority: &[u8]) { - set_storage(&value_vec(index, b"\0authority".to_vec()), authority); -} - -pub fn authority(index: usize) -> Vec { - storage(&value_vec(index, b"\0authority".to_vec())) -} - -pub fn set_authority_count(count: usize) { - (count..authority_count()).for_each(|i| set_authority(i, &[])); - set_storage(b"\0authority_count", &value_vec(count, Vec::new())); -} - -pub fn authority_count() -> usize { - storage(b"\0authority_count").into_iter().rev().fold(0, |acc, i| (acc << 8) + (i as usize)) -} - -pub fn authorities() -> Vec> { - (0..authority_count()).into_iter().map(authority).collect() -} - -pub fn set_authorities(authorities: &[&[u8]]) { - set_authority_count(authorities.len()); - authorities.iter().enumerate().for_each(|(v, i)| set_authority(v, i)); -} - -impl_stubs!(test_data_in); fn test_data_in(input: Vec) -> Vec { print(b"set_storage" as &[u8]); set_storage(b"input", &input); - print(b"code" as &[u8]); - set_storage(b"code", &code()); - - print(b"set_code" as &[u8]); - set_code(&input); - print(b"storage" as &[u8]); - let copy = storage(b"input"); - - print(b"authorities" as &[u8]); - let mut v = authorities(); - v.push(copy); + let foo = storage(b"foo"); - print(b"set_authorities" as &[u8]); - set_authorities(&v.iter().map(Vec::as_slice).collect::>()); + print(b"set_storage" as &[u8]); + set_storage(b"baz", &foo); print(b"finished!" as &[u8]); b"all ok!".to_vec() } + + +impl_stubs!(test_data_in, test_keccak256); From 15ae7754d0a220c92a59c7fd9e63dc7622f972f3 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 17 Jan 2018 15:23:22 +0100 Subject: [PATCH 41/76] Signing with crypto. --- Cargo.lock | 26 ++++++++++++ primitives/Cargo.toml | 2 + primitives/src/lib.rs | 92 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 2ac1c11912de4..524ec96570c1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -261,6 +261,11 @@ dependencies = [ "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "gcc" +version = "0.3.54" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "globset" version = "0.1.4" @@ -701,6 +706,7 @@ dependencies = [ "fixed-hash 0.1.0 (git+https://github.com/paritytech/primitives.git)", "polkadot-serializer 0.1.0", "pretty_assertions 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -846,6 +852,18 @@ dependencies = [ "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rust-crypto" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc-demangle" version = "0.1.5" @@ -856,6 +874,11 @@ name = "rustc-hex" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc_version" version = "0.1.7" @@ -1199,6 +1222,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" "checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" "checksum futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e86f49cc0d92fe1b97a5980ec32d56208272cbb00f15044ea9e2799dde766fdf" +"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" "checksum globset 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90d069fe6beb9be359ef505650b3f73228c5591a3c4b1f32be2f4f44459ffa3a" "checksum hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d97be07c358c5b461268b4ce60304024c5fa5acfd4bd8cd743639f0252003cf5" "checksum heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "54fab2624374e5137ae4df13bf32b0b269cb804df42d13a51221bbd431d1a237" @@ -1247,8 +1271,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" "checksum rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "babe6fce20c0ca9b1582998734c4569082d0ad08e43772a1c6c40aef4f106ef9" +"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" +"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" "checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index f31afccf5b266..3e2877e073326 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -11,6 +11,8 @@ serde = "1.0" serde_derive = "1.0" tiny-keccak = "1.3" uint = { git = "https://github.com/paritytech/primitives.git" } +rust-crypto = "0.2.36" +ring = "0.12" [dev-dependencies] polkadot-serializer = { path = "../serializer", version = "0.1" } diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index ca32f302f3e8f..ad4c6efd5822a 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -21,6 +21,7 @@ extern crate rustc_hex; extern crate serde; extern crate tiny_keccak; +extern crate crypto; #[macro_use] extern crate crunchy; @@ -59,3 +60,94 @@ pub use self::uint::{U256, U512}; pub fn hash(data: &[u8]) -> hash::H256 { tiny_keccak::keccak256(data).into() } + +/// Cool module. +pub mod ed25519 { + use crypto; + use rustc_hex::FromHex; + + #[derive(PartialEq, Clone)] + struct Public ([u8; 32]); + #[derive(Clone)] + struct Pair ([u8; 64]); + #[derive(Clone)] + struct Signature ([u8; 64]); + impl Pair { + pub fn from_seed(seed: &[u8]) -> Pair { + let (secret_public, public) = crypto::ed25519::keypair(seed); + assert_eq!(&secret_public[32..64], &public[0..32]); + Pair(secret_public) + } + pub fn sign(&self, message: &[u8]) -> Signature { + Signature(crypto::ed25519::signature(message, &self.0)) + } + pub fn public(&self) -> Public { + let mut r = [0u8; 32]; + r.copy_from_slice(&self.0[32..64]); + Public(r) + } + } + impl From<&'static str> for Public { + fn from(hex: &'static str) -> Self { + let mut r = [0u8; 32]; + r.copy_from_slice(&FromHex::from_hex(hex).unwrap()[0..32]); + Public(r) + } + } + impl From<&'static str> for Pair { + fn from(hex: &'static str) -> Self { + let mut r = [0u8; 64]; + r.copy_from_slice(&FromHex::from_hex(hex).unwrap()[0..64]); + Pair(r) + } + } + impl From<&'static str> for Signature { + fn from(hex: &'static str) -> Self { + let mut r = [0u8; 64]; + r.copy_from_slice(&FromHex::from_hex(hex).unwrap()[0..64]); + Signature(r) + } + } + + impl PartialEq for Signature { + fn eq(&self, other: &Signature) -> bool { + self.0.iter().eq(other.0.iter()) + } + } + + impl PartialEq for Pair { + fn eq(&self, other: &Pair) -> bool { + self.0.iter().eq(other.0.iter()) + } + } + + impl Signature { + fn verify(&self, message: &[u8], public: &Public) -> bool { + crypto::ed25519::verify(message, &public.0, &self.0) + } + } + + #[cfg(test)] + mod test { + use super::*; + + #[test] + fn test_vector_should_work() { + let pair: Pair = "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".into(); + let public = pair.public(); + let message = b""; + let signature: Signature = "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b".into(); + assert!(&pair.sign(&message[..]) == &signature); + assert!(signature.verify(&message[..], &public)); + } + + #[test] + fn generated_pair_should_work() { + let pair = Pair::from_seed(b"test"); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(signature.verify(&message[..], &public)); + } + } +} From 565099707960de9891f27756327e2cdd34eefc5e Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Wed, 17 Jan 2018 18:12:06 +0100 Subject: [PATCH 42/76] fix unsafety hole in environmental using function --- environmental/src/lib.rs | 80 ++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/environmental/src/lib.rs b/environmental/src/lib.rs index 239a2fb90f07b..18dc10d10f77f 100644 --- a/environmental/src/lib.rs +++ b/environmental/src/lib.rs @@ -44,10 +44,12 @@ pub use std::cell::RefCell; use std::thread::LocalKey; +// invoking this function asserts that T and S are both instantiations +// of the same lifetime-parametric type. #[doc(hidden)] -pub fn using<'a, T: 'a, R, S, F: FnOnce() -> R>( +pub unsafe fn using R>( global: &'static LocalKey>, - protected: &'a mut T, + protected: &mut T, f: F ) -> R { // store the `protected` reference as a pointer so we can provide it to logic running within @@ -57,19 +59,22 @@ pub fn using<'a, T: 'a, R, S, F: FnOnce() -> R>( // - that no other thread will use it; and // - that we do not use the original mutating reference while the pointer. // exists. - let original = global.with(|r| { - let mut b = r.borrow_mut(); - let o = *b; - *b = protected as *mut T as *mut S; - o - }); - let r = f(); - global.with(|r| *r.borrow_mut() = original); - r + global.with(|r| { + let original = { + let mut global = r.borrow_mut(); + ::std::mem::replace(&mut *global, protected as *mut _ as *mut S) + }; + + let res = f(); + *r.borrow_mut() = original; + res + }) } +// invoking this function asserts that T and S are both instantiations +// of the same lifetime-parametric type. #[doc(hidden)] -pub fn with<'r, R, S, T: 'r, F: FnOnce(&'r mut T) -> R>( +pub unsafe fn with R>( global: &'static LocalKey>, mutator: F, ) -> Option { @@ -78,9 +83,7 @@ pub fn with<'r, R, S, T: 'r, F: FnOnce(&'r mut T) -> R>( if *br != 0 as *mut S { // safe because it's only non-zero when it's being called from using, which // is holding on to the underlying reference (and not using it itself) safely. - unsafe { - Some(mutator(&mut *(*br as *mut S as *mut T))) - } + Some(mutator(&mut *(*br as *mut S as *mut T))) } else { None } @@ -130,32 +133,24 @@ macro_rules! decl { /// ``` #[macro_export] macro_rules! declare_simple { - ($name:ident : $t:tt) => { + ($name:ident : $t:ty) => { mod $name { #[allow(unused_imports)] use super::*; decl!(GLOBAL: $t); - pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>( - protected: &'b mut T, + pub fn using R>( + protected: &mut $t, f: F ) -> R { - $crate::using(&GLOBAL, protected, f) + unsafe { $crate::using(&GLOBAL, protected, f) } } - pub fn with FnOnce(&'r mut $t) -> R>( + pub fn with R>( f: F ) -> Option { - let dummy = (); - with_closed(f, &dummy) - } - - fn with_closed<'d: 'r, 'r, R, F: FnOnce(&'r mut $t) -> R>( - f: F, - _dummy: &'d (), - ) -> Option { - $crate::with(&GLOBAL, f) + unsafe { $crate::with(&GLOBAL, f) } } } } @@ -230,20 +225,33 @@ macro_rules! declare_generic { #[cfg(test)] mod tests { - declare_simple!(counter: u32); - - fn stuff() { - // do some stuff, accessing the named reference as desired. - counter::with(|value| *value += 1); - } #[test] fn simple_works() { + declare_simple!(counter: u32); + + let stuff = || counter::with(|value| *value += 1); + // declare a stack variable of the same type as our global declaration. let mut local = 41u32; + // call stuff, setting up our `counter` environment as a refrence to our local counter var. counter::using(&mut local, stuff); - println!("The answer is {:?}", local); // will print 42! + assert_eq!(local, 42); + stuff(); // safe! doesn't do anything. } + + #[test] + fn overwrite_with_lesser_lifetime() { + declare_simple!(items: Vec); + + let mut local_items = vec![1, 2, 3]; + items::using(&mut local_items, || { + let dies_at_end = vec![4, 5, 6]; + items::with(|items| *items = dies_at_end); + }); + + assert_eq!(local_items, vec![4, 5, 6]); + } } From 7820149eaf2cec8ce57198ad86df960d4de85801 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 17 Jan 2018 18:33:20 +0100 Subject: [PATCH 43/76] Introduce Ed25519 crypto. --- Cargo.lock | 85 +++++++++++++++++++++------- ed25519.pk8 | Bin 0 -> 85 bytes pkcs8.key | 28 ++++++++++ primitives/Cargo.toml | 2 +- primitives/src/lib.rs | 127 ++++++++++++++++++++++++++++++++---------- 5 files changed, 191 insertions(+), 51 deletions(-) create mode 100644 ed25519.pk8 create mode 100644 pkcs8.key diff --git a/Cargo.lock b/Cargo.lock index 524ec96570c1e..ce227ffe4bdff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -129,6 +129,15 @@ dependencies = [ "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "coco" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crunchy" version = "0.1.6" @@ -153,6 +162,11 @@ name = "dtoa" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "either" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "elastic-array" version = "0.9.0" @@ -706,12 +720,13 @@ dependencies = [ "fixed-hash 0.1.0 (git+https://github.com/paritytech/primitives.git)", "polkadot-serializer 0.1.0", "pretty_assertions 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-crypto 0.2.36 (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)", "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.1.0 (git+https://github.com/paritytech/primitives.git)", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -791,6 +806,26 @@ dependencies = [ "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rayon" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon-core" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "redox_syscall" version = "0.1.31" @@ -829,6 +864,18 @@ dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ring" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rlp" version = "0.2.1" @@ -852,18 +899,6 @@ dependencies = [ "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rust-crypto" -version = "0.2.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rustc-demangle" version = "0.1.5" @@ -874,11 +909,6 @@ name = "rustc-hex" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "rustc-serialize" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "rustc_version" version = "0.1.7" @@ -905,6 +935,11 @@ name = "scoped-tls" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "scopeguard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "semver" version = "0.1.20" @@ -1150,6 +1185,11 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "untrusted" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "utf8-ranges" version = "1.0.0" @@ -1206,10 +1246,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b8c532887f1a292d17de05ae858a8fe50a301e196f9ef0ddb7ccd0d1d00f180" +"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd" "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" +"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" "checksum elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "258ff6a9a94f648d0379dbd79110e057edbb53eb85cc237e33eadf8e5a30df85" "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" @@ -1265,20 +1307,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pretty_assertions 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94b6bbc8a323d89a019c4cdde21850522fb8405e97add70827177fc2f86c1495" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" +"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8" +"checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53" "checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" +"checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c" "checksum rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "babe6fce20c0ca9b1582998734c4569082d0ad08e43772a1c6c40aef4f106ef9" -"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" "checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" +"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" @@ -1310,6 +1354,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" diff --git a/ed25519.pk8 b/ed25519.pk8 new file mode 100644 index 0000000000000000000000000000000000000000..57a8e9f84df1dc3175d02132f88bf7d03563ed8a GIT binary patch literal 85 zcmV-b0IL5mQvv}2Fa-t!D`jv5A_O2jp9~yh%qqhDL7XlV#y11mAEmT)YK|2S8mY`X rKcB~;BLg7-wIOt@fg3EC6j=CGA>0MTxofFio@CXjjO!~zYbh_!erz9j literal 0 HcmV?d00001 diff --git a/pkcs8.key b/pkcs8.key new file mode 100644 index 0000000000000..250fbac646b9f --- /dev/null +++ b/pkcs8.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDMpfNjaigc9FKC +8owWoKvAua3O1es2CB7Gq6pFI4Ctv34Wt5XSk83XkSXLOsf2ib1zCpzLUQSVLtH1 +c05uTH6rXLmjbH3lFOUCqD41dIveqo72sekHnYjS23ME2v5JCkg9YFmn32FffHGt +2Uaho+MQZWbpT3SD5tKRdaUUx1f/i16oB4Fnk8zCdQ7NPFru+WUV0cvQnK3rOpOo +KbK59Jo04bHmf/EPeVmxonwt/nmAJRUemuQXPl1cH8sk+t6Bxxp9FLzX6rtmpGDk +mBwrYBNC5auT3L1V2xabI2TKobd/qa+9/Sz41PeHsYLX/cu9Iplvj+LU85gYwv5d +kjvMEI7pAgMBAAECggEBAID7z21HSUUGkMLL0JOqbNYpsWx906PYdl1NcSHmgIIC +AZyb1ShF1CUb7LAsuj+fDPLnK2/R/otwWRDUvggy2ltzM+XWyXqLMtP76kmSzV1o +Lnc6Jt+P4N7VRac3x7GNc36LrbZqylp+er/SA/x46PI6lyRR2eQQpYLcnVF9Wu9K +bbTQ9nH+hxJiRG85GXKjeFkIj7PXBYAiYYcgiPF1RfB3o2R0cXZI24Y5/Ufc3OKg +Jws/VsTIzoxoLd3u6rDKX/N40/VBrGqv76HFqVwgnbxeG+i6HZNIAvZn+6m3a6l5 +APIZp7FfLJ1vZaHP7S7GeNmcz+eJ9Y/FanItohJGfqECgYEA5d17o9Ol3H+6wkQk +a3LU03NfvcdU5TqTOGvzx6yGGASjlByZWb7rMsRMyQ/wP60j+2Hd/G4rXbkF6vee +5uen7geJ6bzhUev1nd1NDcVdZay8x0r3huePUV96k+wU1IrOZrZddlqPyUJMctDy +VbwbDPM0saGx0xIlx/JOC1kEEr0CgYEA4+p/TSEq9DWH5QaMlVxBp48HY4Yrv/gQ +UmNUbCyd7J21Re+7cY3ZGF5IoC2l4K4yPM6ovNipkX9WDZrw8T68sD8yTQzL/tDE +CuXxG+X0b81k5UiZBFIGXiBb8JpoHRKNNGjZTZyBNhOKc902oKoNyTKILX3qI/aL +M2v/SELm5Z0CgYEAx+XZnPn09pF5t3GM/ogpPw3Jh/+t+376AooWwWFuZ7q5Cpfo +YFygq1B8uimLM8T9UqKkat7gBaxe0hyvanyw1FZoAAXLKPP7cGLAnKYzd7VFoka2 +hfIf95MBxVv8LW3c2wPiuYc+HbbzRrIg3KAuIg/qlkNYoobYpk44wrOR0D0CgYB0 +RNeGaGo6ROi7nHixZWwU57FUQ0kkWI8zCHsz6Br0b4vfTqooBr3+YXLZTBA4K4Vz +YdXQ6RKwJ+6laCqMV334x3SIvAOBTc0E5kL3AXuOYZCcK0nsW0/mSsm8V3jPg/xH +BUn9/t4n0RYrf2lz0uzPfBjeZELC7+4ZYHnNyltyPQKBgQCvT40UwZ5yHAt3leWG +stGRTkbupenh2z23hXY0Cio8Zqa7KE5jBWdF4uu27ScK4rhFdS1sgQJFghj6SxRO +VT5PQuRP9ETJIVwNgNQbAxbfeg8DADKGAWX9W5r//WlW1xH0/tSAxX6Pp/IiT9or +cRljrhP8zW6qhj3BKjdivPDgPw== +-----END PRIVATE KEY----- diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 3e2877e073326..045afba827c76 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -11,8 +11,8 @@ serde = "1.0" serde_derive = "1.0" tiny-keccak = "1.3" uint = { git = "https://github.com/paritytech/primitives.git" } -rust-crypto = "0.2.36" ring = "0.12" +untrusted = "0.5" [dev-dependencies] polkadot-serializer = { path = "../serializer", version = "0.1" } diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index ad4c6efd5822a..cd166f0a54359 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -21,7 +21,8 @@ extern crate rustc_hex; extern crate serde; extern crate tiny_keccak; -extern crate crypto; +extern crate ring; +extern crate untrusted; #[macro_use] extern crate crunchy; @@ -63,30 +64,85 @@ pub fn hash(data: &[u8]) -> hash::H256 { /// Cool module. pub mod ed25519 { - use crypto; + use untrusted; + use ring::{rand, signature}; use rustc_hex::FromHex; - #[derive(PartialEq, Clone)] - struct Public ([u8; 32]); - #[derive(Clone)] - struct Pair ([u8; 64]); + struct HexDisplay<'a>(&'a [u8]); + + impl<'a> ::std::fmt::Display for HexDisplay<'a> { + fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + for byte in self.0 { + try!( fmtr.write_fmt(format_args!("{:02x}", byte))); + } + Ok(()) + } + } + + /// A public key. + #[derive(PartialEq, Clone, Debug)] + pub struct Public ([u8; 32]); + + /// A key pair. + pub struct Pair(signature::Ed25519KeyPair); + + /// A signature. #[derive(Clone)] - struct Signature ([u8; 64]); + pub struct Signature ([u8; 64]); + impl Pair { - pub fn from_seed(seed: &[u8]) -> Pair { - let (secret_public, public) = crypto::ed25519::keypair(seed); - assert_eq!(&secret_public[32..64], &public[0..32]); - Pair(secret_public) + /// Generate new secure (random) key pair. + pub fn new() -> Pair { + let rng = rand::SystemRandom::new(); + let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng).unwrap(); + Pair(signature::Ed25519KeyPair::from_pkcs8(untrusted::Input::from(&pkcs8_bytes)).unwrap()) + } + /// Make a new key pair from a seed phrase. + pub fn from_seed(seed: &[u8; 32]) -> Pair { + 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 = 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 + /// they correspond to each other). + pub fn from_both(secret_public: &[u8; 64]) -> Option { + let mut pkcs8_bytes = FromHex::from_hex("3053020101300506032b657004220420").unwrap(); + pkcs8_bytes.extend_from_slice(&secret_public[0..32]); + pkcs8_bytes.extend_from_slice(&[0xa1u8, 0x23, 0x03, 0x21, 0x00]); + pkcs8_bytes.extend_from_slice(&secret_public[32..64]); + signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(untrusted::Input::from(&pkcs8_bytes)).ok().map(Pair) + } + /// Sign a message. pub fn sign(&self, message: &[u8]) -> Signature { - Signature(crypto::ed25519::signature(message, &self.0)) + let mut r = [0u8; 64]; + r.copy_from_slice(self.0.sign(message).as_ref()); + Signature(r) } + /// Get the public key. pub fn public(&self) -> Public { let mut r = [0u8; 32]; - r.copy_from_slice(&self.0[32..64]); + let pk = self.0.public_key_bytes(); + r.copy_from_slice(pk); Public(r) } } + impl Signature { + /// Verify a message. + pub fn verify(&self, message: &[u8], public: &Public) -> bool { + let peer_public_key = untrusted::Input::from(&public.0[..]); + let msg = untrusted::Input::from(message); + let sig = untrusted::Input::from(&self.0[..]); + + match signature::verify(&signature::ED25519, peer_public_key, msg, sig) { + Ok(_) => true, + _ => false, + } + } + } impl From<&'static str> for Public { fn from(hex: &'static str) -> Self { let mut r = [0u8; 32]; @@ -96,9 +152,22 @@ pub mod ed25519 { } impl From<&'static str> for Pair { fn from(hex: &'static str) -> Self { - let mut r = [0u8; 64]; - r.copy_from_slice(&FromHex::from_hex(hex).unwrap()[0..64]); - Pair(r) + let data = FromHex::from_hex(hex).expect("Key pair given is static so hex should be good."); + match data.len() { + 32 => { + 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."); + } + } } } impl From<&'static str> for Signature { @@ -115,26 +184,15 @@ pub mod ed25519 { } } - impl PartialEq for Pair { - fn eq(&self, other: &Pair) -> bool { - self.0.iter().eq(other.0.iter()) - } - } - - impl Signature { - fn verify(&self, message: &[u8], public: &Public) -> bool { - crypto::ed25519::verify(message, &public.0, &self.0) - } - } - #[cfg(test)] mod test { use super::*; #[test] fn test_vector_should_work() { - let pair: Pair = "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".into(); + let pair: Pair = "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into(); let public = pair.public(); + assert_eq!(public, "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".into()); let message = b""; let signature: Signature = "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b".into(); assert!(&pair.sign(&message[..]) == &signature); @@ -143,7 +201,16 @@ pub mod ed25519 { #[test] fn generated_pair_should_work() { - let pair = Pair::from_seed(b"test"); + let pair = Pair::new(); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(signature.verify(&message[..], &public)); + } + + #[test] + fn seeded_pair_should_work() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); let public = pair.public(); let message = b"Something important"; let signature = pair.sign(&message[..]); From 4ef4239194ab6624b04e522c8671a0a681e31fad Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 17 Jan 2018 18:34:40 +0100 Subject: [PATCH 44/76] Repotting. --- primitives/src/ed25519.rs | 155 +++++++++++++++++++++++++++++++++++++ primitives/src/lib.rs | 158 +------------------------------------- 2 files changed, 156 insertions(+), 157 deletions(-) create mode 100644 primitives/src/ed25519.rs diff --git a/primitives/src/ed25519.rs b/primitives/src/ed25519.rs new file mode 100644 index 0000000000000..676f8ef2668c9 --- /dev/null +++ b/primitives/src/ed25519.rs @@ -0,0 +1,155 @@ +//! Simple Ed25519 API. + +use untrusted; +use ring::{rand, signature}; +use rustc_hex::FromHex; + +struct HexDisplay<'a>(&'a [u8]); + +impl<'a> ::std::fmt::Display for HexDisplay<'a> { + fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + for byte in self.0 { + try!( fmtr.write_fmt(format_args!("{:02x}", byte))); + } + Ok(()) + } +} + +/// A public key. +#[derive(PartialEq, Clone, Debug)] +pub struct Public ([u8; 32]); + +/// A key pair. +pub struct Pair(signature::Ed25519KeyPair); + +/// A signature. +#[derive(Clone)] +pub struct Signature ([u8; 64]); + +impl Pair { + /// Generate new secure (random) key pair. + pub fn new() -> Pair { + let rng = rand::SystemRandom::new(); + let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng).unwrap(); + Pair(signature::Ed25519KeyPair::from_pkcs8(untrusted::Input::from(&pkcs8_bytes)).unwrap()) + } + /// Make a new key pair from a seed phrase. + pub fn from_seed(seed: &[u8; 32]) -> Pair { + 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 = 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 + /// they correspond to each other). + pub fn from_both(secret_public: &[u8; 64]) -> Option { + let mut pkcs8_bytes = FromHex::from_hex("3053020101300506032b657004220420").unwrap(); + pkcs8_bytes.extend_from_slice(&secret_public[0..32]); + pkcs8_bytes.extend_from_slice(&[0xa1u8, 0x23, 0x03, 0x21, 0x00]); + pkcs8_bytes.extend_from_slice(&secret_public[32..64]); + signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(untrusted::Input::from(&pkcs8_bytes)).ok().map(Pair) + } + /// Sign a message. + pub fn sign(&self, message: &[u8]) -> Signature { + let mut r = [0u8; 64]; + r.copy_from_slice(self.0.sign(message).as_ref()); + Signature(r) + } + /// Get the public key. + pub fn public(&self) -> Public { + let mut r = [0u8; 32]; + let pk = self.0.public_key_bytes(); + r.copy_from_slice(pk); + Public(r) + } +} +impl Signature { + /// Verify a message. + pub fn verify(&self, message: &[u8], public: &Public) -> bool { + let peer_public_key = untrusted::Input::from(&public.0[..]); + let msg = untrusted::Input::from(message); + let sig = untrusted::Input::from(&self.0[..]); + + match signature::verify(&signature::ED25519, peer_public_key, msg, sig) { + Ok(_) => true, + _ => false, + } + } +} +impl From<&'static str> for Public { + fn from(hex: &'static str) -> Self { + let mut r = [0u8; 32]; + r.copy_from_slice(&FromHex::from_hex(hex).unwrap()[0..32]); + Public(r) + } +} +impl From<&'static str> for Pair { + fn from(hex: &'static str) -> Self { + let data = FromHex::from_hex(hex).expect("Key pair given is static so hex should be good."); + match data.len() { + 32 => { + 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."); + } + } + } +} +impl From<&'static str> for Signature { + fn from(hex: &'static str) -> Self { + let mut r = [0u8; 64]; + r.copy_from_slice(&FromHex::from_hex(hex).unwrap()[0..64]); + Signature(r) + } +} + +impl PartialEq for Signature { + fn eq(&self, other: &Signature) -> bool { + self.0.iter().eq(other.0.iter()) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_vector_should_work() { + let pair: Pair = "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into(); + let public = pair.public(); + assert_eq!(public, "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".into()); + let message = b""; + let signature: Signature = "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b".into(); + assert!(&pair.sign(&message[..]) == &signature); + assert!(signature.verify(&message[..], &public)); + } + + #[test] + fn generated_pair_should_work() { + let pair = Pair::new(); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(signature.verify(&message[..], &public)); + } + + #[test] + fn seeded_pair_should_work() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(signature.verify(&message[..], &public)); + } +} diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index cd166f0a54359..fc266582004f6 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -48,6 +48,7 @@ pub mod hash; pub mod parachain; pub mod uint; pub mod validator; +pub mod ed25519; /// Alias to 160-bit hash when used in the context of an account address. pub type Address = hash::H160; @@ -61,160 +62,3 @@ pub use self::uint::{U256, U512}; pub fn hash(data: &[u8]) -> hash::H256 { tiny_keccak::keccak256(data).into() } - -/// Cool module. -pub mod ed25519 { - use untrusted; - use ring::{rand, signature}; - use rustc_hex::FromHex; - - struct HexDisplay<'a>(&'a [u8]); - - impl<'a> ::std::fmt::Display for HexDisplay<'a> { - fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - for byte in self.0 { - try!( fmtr.write_fmt(format_args!("{:02x}", byte))); - } - Ok(()) - } - } - - /// A public key. - #[derive(PartialEq, Clone, Debug)] - pub struct Public ([u8; 32]); - - /// A key pair. - pub struct Pair(signature::Ed25519KeyPair); - - /// A signature. - #[derive(Clone)] - pub struct Signature ([u8; 64]); - - impl Pair { - /// Generate new secure (random) key pair. - pub fn new() -> Pair { - let rng = rand::SystemRandom::new(); - let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng).unwrap(); - Pair(signature::Ed25519KeyPair::from_pkcs8(untrusted::Input::from(&pkcs8_bytes)).unwrap()) - } - /// Make a new key pair from a seed phrase. - pub fn from_seed(seed: &[u8; 32]) -> Pair { - 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 = 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 - /// they correspond to each other). - pub fn from_both(secret_public: &[u8; 64]) -> Option { - let mut pkcs8_bytes = FromHex::from_hex("3053020101300506032b657004220420").unwrap(); - pkcs8_bytes.extend_from_slice(&secret_public[0..32]); - pkcs8_bytes.extend_from_slice(&[0xa1u8, 0x23, 0x03, 0x21, 0x00]); - pkcs8_bytes.extend_from_slice(&secret_public[32..64]); - signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(untrusted::Input::from(&pkcs8_bytes)).ok().map(Pair) - } - /// Sign a message. - pub fn sign(&self, message: &[u8]) -> Signature { - let mut r = [0u8; 64]; - r.copy_from_slice(self.0.sign(message).as_ref()); - Signature(r) - } - /// Get the public key. - pub fn public(&self) -> Public { - let mut r = [0u8; 32]; - let pk = self.0.public_key_bytes(); - r.copy_from_slice(pk); - Public(r) - } - } - impl Signature { - /// Verify a message. - pub fn verify(&self, message: &[u8], public: &Public) -> bool { - let peer_public_key = untrusted::Input::from(&public.0[..]); - let msg = untrusted::Input::from(message); - let sig = untrusted::Input::from(&self.0[..]); - - match signature::verify(&signature::ED25519, peer_public_key, msg, sig) { - Ok(_) => true, - _ => false, - } - } - } - impl From<&'static str> for Public { - fn from(hex: &'static str) -> Self { - let mut r = [0u8; 32]; - r.copy_from_slice(&FromHex::from_hex(hex).unwrap()[0..32]); - Public(r) - } - } - impl From<&'static str> for Pair { - fn from(hex: &'static str) -> Self { - let data = FromHex::from_hex(hex).expect("Key pair given is static so hex should be good."); - match data.len() { - 32 => { - 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."); - } - } - } - } - impl From<&'static str> for Signature { - fn from(hex: &'static str) -> Self { - let mut r = [0u8; 64]; - r.copy_from_slice(&FromHex::from_hex(hex).unwrap()[0..64]); - Signature(r) - } - } - - impl PartialEq for Signature { - fn eq(&self, other: &Signature) -> bool { - self.0.iter().eq(other.0.iter()) - } - } - - #[cfg(test)] - mod test { - use super::*; - - #[test] - fn test_vector_should_work() { - let pair: Pair = "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into(); - let public = pair.public(); - assert_eq!(public, "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".into()); - let message = b""; - let signature: Signature = "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b".into(); - assert!(&pair.sign(&message[..]) == &signature); - assert!(signature.verify(&message[..], &public)); - } - - #[test] - fn generated_pair_should_work() { - let pair = Pair::new(); - let public = pair.public(); - let message = b"Something important"; - let signature = pair.sign(&message[..]); - assert!(signature.verify(&message[..], &public)); - } - - #[test] - fn seeded_pair_should_work() { - let pair = Pair::from_seed(b"12345678901234567890123456789012"); - let public = pair.public(); - let message = b"Something important"; - let signature = pair.sign(&message[..]); - assert!(signature.verify(&message[..], &public)); - } - } -} From 78a22d435c2e1e0ea7ea5b7885ea9b7d085e1078 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 17 Jan 2018 19:05:31 +0100 Subject: [PATCH 45/76] Add ed25519_verify external. --- executor/src/wasm_executor.rs | 19 +++++++++++++++++++ primitives/src/ed25519.rs | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index 8597656c51cd3..719343f8fa0f6 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -27,6 +27,7 @@ use error::{Error, ErrorKind, Result}; use wasm_utils::{MemoryInstance, UserDefinedElements, AddModuleWithoutFullDependentInstance}; use tiny_keccak; +use primitives::ed25519; struct Heap { end: u32, @@ -148,6 +149,24 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, [0; 32] }; let _ = this.memory.set(out, &result); + }, + ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32 => { + (||{ + let mut sig = [0u8; 64]; + if let Err(_) = this.memory.get_into(sig_data, &mut sig[..]) { + return 0; + }; + let mut pubkey = [0u8; 32]; + if let Err(_) = this.memory.get_into(pubkey_data, &mut pubkey[..]) { + return 0; + }; + + if let Ok(msg) = this.memory.get(msg_data, msg_len as usize) { + if ed25519::Signature::from(sig).verify(&msg, &ed25519::Public::from(pubkey)) { 1 } else { 0 } + } else { + 0 + } + })() } => <'e, E: Externalities + 'e> ); diff --git a/primitives/src/ed25519.rs b/primitives/src/ed25519.rs index 676f8ef2668c9..576d1a409ae6c 100644 --- a/primitives/src/ed25519.rs +++ b/primitives/src/ed25519.rs @@ -26,6 +26,28 @@ pub struct Pair(signature::Ed25519KeyPair); #[derive(Clone)] pub struct Signature ([u8; 64]); +impl Signature { + pub fn from(data: [u8; 64]) -> Self { + Signature(data) + } + pub fn from_slice(data: &[u8]) -> Self { + let mut r = [0u8; 64]; + r.copy_from_slice(data); + Signature(r) + } +} + +impl Public { + pub fn from(data: [u8; 32]) -> Self { + Public(data) + } + pub fn from_slice(data: &[u8]) -> Self { + let mut r = [0u8; 32]; + r.copy_from_slice(data); + Public(r) + } +} + impl Pair { /// Generate new secure (random) key pair. pub fn new() -> Pair { From 93f7aedc87fbcb6244de9849781d48f798513fc6 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 17 Jan 2018 19:17:34 +0100 Subject: [PATCH 46/76] Introduce Ed25519 verify as an external. --- native-runtime/support/src/lib.rs | 13 ++++++++++--- primitives/src/ed25519.rs | 11 +++++++++++ wasm-runtime/support/src/lib.rs | 11 +++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index a2fe13eb104a2..7f2de2d10342f 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -3,6 +3,9 @@ extern crate environmental; extern crate polkadot_state_machine; extern crate tiny_keccak; +use std::fmt; +use primitives::ed25519; + pub use std::vec::Vec; pub use std::rc::Rc; pub use std::cell::RefCell; @@ -11,7 +14,6 @@ pub use std::slice; pub use std::mem::{size_of, transmute, swap, uninitialized}; pub use polkadot_state_machine::Externalities; -use std::fmt; // TODO: use the real error, not NoError. @@ -63,9 +65,9 @@ pub fn storage_into(_key: &[u8]) -> Option { }).unwrap_or(None) } -pub fn set_storage(_key: &[u8], _value: &[u8]) { +pub fn set_storage(key: &[u8], value: &[u8]) { ext::with(|holder| - holder.ext.set_storage(_key.to_vec(), _value.to_vec()) + holder.ext.set_storage(key.to_vec(), value.to_vec()) ); } @@ -79,6 +81,11 @@ pub fn chain_id() -> u64 { /// Conduct a Keccak-256 hash of the given data. pub use tiny_keccak::keccak256; +/// Verify a ed25519 signature. +pub fn ed25519_verify(sig: &[u8; 64], msg: &[u8], pubkey: &[u8; 32]) -> bool { + ed25519::verify(&sig[..], msg, &pubkey[..]) +} + /// Execute the given closure with global function available whose functionality routes into the /// externalities `ext`. Forwards the value that the closure returns. pub fn with_externalities R>(ext: &mut Externalities, f: F) -> R { diff --git a/primitives/src/ed25519.rs b/primitives/src/ed25519.rs index 576d1a409ae6c..58556b666940c 100644 --- a/primitives/src/ed25519.rs +++ b/primitives/src/ed25519.rs @@ -15,6 +15,17 @@ impl<'a> ::std::fmt::Display for HexDisplay<'a> { } } +pub fn verify(sig: &[u8], message: &[u8], public: &[u8]) -> bool { + let public_key = untrusted::Input::from(public); + let msg = untrusted::Input::from(message); + let sig = untrusted::Input::from(sig); + + match signature::verify(&signature::ED25519, public_key, msg, sig) { + Ok(_) => true, + _ => false, + } +} + /// A public key. #[derive(PartialEq, Clone, Debug)] pub struct Public ([u8; 32]); diff --git a/wasm-runtime/support/src/lib.rs b/wasm-runtime/support/src/lib.rs index ae3feb14c931c..9f75504513594 100644 --- a/wasm-runtime/support/src/lib.rs +++ b/wasm-runtime/support/src/lib.rs @@ -30,6 +30,7 @@ extern "C" { fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32) -> u32; fn ext_chain_id() -> u64; fn ext_keccak256(data: *const u8, len: u32, out: *mut u8); + fn ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32; } pub fn storage(key: &[u8]) -> Vec { @@ -89,6 +90,16 @@ pub fn keccak256(data: &[u8]) -> [u8; 32] { } } +/// Verify a ed25519 signature. +pub fn ed25519_verify(sig: &[u8; 64], msg: &[u8], pubkey: &[u8; 32]) -> bool { + unsafe { + match ext_ed25519_verify(&msg[0], msg.len() as u32, &sig[0], &pubkey[0]) { + 0 => false, + _ => true, + } + } +} + pub trait Printable { fn print(self); } From cdc1387e666a2bed9d83f596705921994e9d6e18 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Wed, 17 Jan 2018 19:20:38 +0100 Subject: [PATCH 47/76] fix unsafety hole around unwinding --- environmental/src/lib.rs | 239 +++++++++++++++++++++------------------ 1 file changed, 127 insertions(+), 112 deletions(-) diff --git a/environmental/src/lib.rs b/environmental/src/lib.rs index 18dc10d10f77f..ef5b5967bea9f 100644 --- a/environmental/src/lib.rs +++ b/environmental/src/lib.rs @@ -16,7 +16,7 @@ //! Safe global references to stack variables. //! -//! Set up a global reference with declare_simple! macro giving it a name and type. +//! Set up a global reference with environmental! macro giving it a name and type. //! Use the `using` function scoped under its name to name a reference and call a function that //! takes no parameters yet can access said reference through the similarly placed `with` function. //! @@ -25,7 +25,7 @@ //! ``` //! #[macro_use] extern crate environmental; //! // create a place for the global reference to exist. -//! declare_simple!(counter: u32); +//! environmental!(counter: u32); //! fn stuff() { //! // do some stuff, accessing the named reference as desired. //! counter::with(|i| *i += 1); @@ -40,15 +40,12 @@ //! } //! ``` -#[doc(hidden)] -pub use std::cell::RefCell; +use std::cell::RefCell; use std::thread::LocalKey; -// invoking this function asserts that T and S are both instantiations -// of the same lifetime-parametric type. #[doc(hidden)] -pub unsafe fn using R>( - global: &'static LocalKey>, +pub fn using R>( + global: &'static LocalKey>>, protected: &mut T, f: F ) -> R { @@ -62,60 +59,66 @@ pub unsafe fn using R>( global.with(|r| { let original = { let mut global = r.borrow_mut(); - ::std::mem::replace(&mut *global, protected as *mut _ as *mut S) + ::std::mem::replace(&mut *global, Some(protected as _)) }; - let res = f(); - *r.borrow_mut() = original; - res + // even if `f` panics the original will be replaced. + struct ReplaceOriginal<'a, T: 'a + ?Sized> { + original: Option<*mut T>, + global: &'a RefCell>, + } + + impl<'a, T: 'a + ?Sized> Drop for ReplaceOriginal<'a, T> { + fn drop(&mut self) { + *self.global.borrow_mut() = self.original.take(); + } + } + + let _guard = ReplaceOriginal { + original, + global: r, + }; + + f() }) } -// invoking this function asserts that T and S are both instantiations -// of the same lifetime-parametric type. #[doc(hidden)] -pub unsafe fn with R>( - global: &'static LocalKey>, +pub fn with R>( + global: &'static LocalKey>>, mutator: F, ) -> Option { - global.with(|r| { - let br = r.borrow_mut(); - if *br != 0 as *mut S { - // safe because it's only non-zero when it's being called from using, which - // is holding on to the underlying reference (and not using it itself) safely. - Some(mutator(&mut *(*br as *mut S as *mut T))) - } else { - None + global.with(|r| unsafe { + let ptr = r.borrow_mut(); + match *ptr { + Some(ptr) => { + // safe because it's only non-zero when it's being called from using, which + // is holding on to the underlying reference (and not using it itself) safely. + Some(mutator(&mut *ptr)) + } + None => None, } }) } -#[doc(hidden)] -#[macro_export] -macro_rules! decl { - ($name:ident : $t:ty) => { - thread_local! { - static $name: $crate::RefCell<*mut $t> = $crate::RefCell::new(0 as *mut $t); - } - } -} - /// Declare a new global reference module whose underlying value does not contain references. /// /// Will create a module of a given name that contains two functions: -/// * `pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>(protected: &'b mut T, f: F) -> R` +/// * `pub fn using R>(protected: &mut $t, f: F) -> R` /// This executes `f`, returning its value. During the call, the module's reference is set to /// be equal to `protected`. -/// * `pub fn with FnOnce(&'r mut $t<'t>) -> R>(f: F) -> Option` +/// * `pub fn with R>(f: F) -> Option` /// This executes `f`, returning `Some` of its value if called from code that is being executed /// as part of a `using` call. If not, it returns `None`. `f` is provided with one argument: the /// same reference as provided to the most recent `using` call. /// /// # Examples /// -/// ``` +/// Initializing the global context with a given value. +/// +/// ```rust /// #[macro_use] extern crate environmental; -/// declare_simple!(counter: u32); +/// environmental!(counter: u32); /// fn main() { /// let mut counter_value = 41u32; /// counter::using(&mut counter_value, || { @@ -131,96 +134,55 @@ macro_rules! decl { /// println!("The answer is {:?}", counter_value); // 42 /// } /// ``` -#[macro_export] -macro_rules! declare_simple { - ($name:ident : $t:ty) => { - mod $name { - #[allow(unused_imports)] - use super::*; - - decl!(GLOBAL: $t); - - pub fn using R>( - protected: &mut $t, - f: F - ) -> R { - unsafe { $crate::using(&GLOBAL, protected, f) } - } - - pub fn with R>( - f: F - ) -> Option { - unsafe { $crate::with(&GLOBAL, f) } - } - } - } -} - -/// Declare a new global reference module whose underlying value is generic over a reference. /// -/// Will create a module of a given name that contains two functions: +/// Roughly the same, but with a trait object: /// -/// * `pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>(protected: &'b mut T, f: F) -> R` -/// This executes `f`, returning its value. During the call, the module's reference is set to -/// be equal to `protected`. -/// * `pub fn with FnOnce(&'r mut $t<'t>) -> R>(f: F) -> Option` -/// This executes `f`, returning `Some` of its value if called from code that is being executed -/// as part of a `using` call. If not, it returns `None`. `f` is provided with one argument: the -/// same reference as provided to the most recent `using` call. +/// ```rust +/// #[macro_use] extern crate environmental; /// -/// # Examples +/// trait Increment { fn increment(&mut self); } /// -/// ``` -/// #[macro_use] extern crate environmental; -/// // a type that we want to reference from a temp global; it has a reference in it. -/// struct WithReference<'a> { answer_ref: &'a mut u32, } -/// // create a place for the global reference to exist. -/// declare_generic!(counter: WithReference); -/// fn stuff() { -/// // do some stuff, accessing the named reference as desired. -/// counter::with(|i| *i.answer_ref += 1); +/// impl Increment for i32 { +/// fn increment(&mut self) { *self += 1 } /// } +/// +/// environmental!(val: Increment + 'static); +/// /// fn main() { -/// // declare a stack variable of the same type as our global declaration. -/// let mut answer = 41u32; -/// { -/// let mut ref_struct = WithReference { answer_ref: &mut answer, }; -/// counter::using(&mut ref_struct, stuff); -/// } -/// println!("The answer is {:?}", answer); // will print 42! +/// let mut local = 0i32; +/// val::using(&mut local, || { +/// val::with(|v| for _ in 0..5 { v.increment() }); +/// }); +/// +/// assert_eq!(local, 5); /// } /// ``` #[macro_export] -macro_rules! declare_generic { - ($name:ident : $t:tt) => { - mod $name { - #[allow(unused_imports)] - use super::*; +macro_rules! environmental { + ($name:ident : $t:ty) => { + #[allow(non_camel_case_types)] + struct $name { __private_field: () } - decl!(GLOBAL: $t<'static> ); + thread_local!(static GLOBAL: ::std::cell::RefCell> + = ::std::cell::RefCell::new(None)); - pub fn using<'a: 'b, 'b, R, F: FnOnce() -> R, T: 'a>( - protected: &'b mut T, + impl $name { + #[allow(unused_imports)] + + pub fn using R>( + protected: &mut $t, f: F ) -> R { $crate::using(&GLOBAL, protected, f) } - pub fn with FnOnce(&'r mut $t<'t>) -> R>( + pub fn with R>( f: F ) -> Option { - let dummy = (); - with_closed(f, &dummy) - } - - fn with_closed<'d: 't, 't: 'r, 'r, R, F: FnOnce(&'r mut $t<'t>) -> R>( - f: F, - _dummy: &'d (), - ) -> Option { - $crate::with(&GLOBAL, f) + $crate::with(&GLOBAL, |x| f(x)) } } - } + }; } #[cfg(test)] @@ -228,9 +190,9 @@ mod tests { #[test] fn simple_works() { - declare_simple!(counter: u32); + environmental!(counter: u32); - let stuff = || counter::with(|value| *value += 1); + fn stuff() { counter::with(|value| *value += 1); }; // declare a stack variable of the same type as our global declaration. let mut local = 41u32; @@ -238,13 +200,12 @@ mod tests { // call stuff, setting up our `counter` environment as a refrence to our local counter var. counter::using(&mut local, stuff); assert_eq!(local, 42); - stuff(); // safe! doesn't do anything. } #[test] fn overwrite_with_lesser_lifetime() { - declare_simple!(items: Vec); + environmental!(items: Vec); let mut local_items = vec![1, 2, 3]; items::using(&mut local_items, || { @@ -254,4 +215,58 @@ mod tests { assert_eq!(local_items, vec![4, 5, 6]); } + + #[test] + fn declare_with_trait_object() { + trait Foo { + fn get(&self) -> i32; + fn set(&mut self, x: i32); + } + + impl Foo for i32 { + fn get(&self) -> i32 { *self } + fn set(&mut self, x: i32) { *self = x } + } + + environmental!(foo: Foo + 'static); + + fn stuff() { + foo::with(|value| { + let new_val = value.get() + 1; + value.set(new_val); + }); + } + + let mut local = 41i32; + foo::using(&mut local, stuff); + + assert_eq!(local, 42); + + stuff(); // doesn't do anything. + } + + #[test] + fn unwind_recursive() { + use std::panic; + + environmental!(items: Vec); + + let panicked = panic::catch_unwind(|| { + let mut local_outer = vec![1, 2, 3]; + + items::using(&mut local_outer, || { + let mut local_inner = vec![4, 5, 6]; + items::using(&mut local_inner, || { + panic!("are you unsafe?"); + }) + }); + }).is_err(); + + assert!(panicked); + + let mut was_cleared = true; + items::with(|_items| was_cleared = false); + + assert!(was_cleared); + } } From 0477b7e018450d79f175d59767cbe82996c593bc Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 17 Jan 2018 19:20:48 +0100 Subject: [PATCH 48/76] Compile fixes. --- Cargo.lock | 1 + native-runtime/support/Cargo.toml | 1 + native-runtime/support/src/lib.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index ce227ffe4bdff..f886c60be544f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -895,6 +895,7 @@ dependencies = [ "environmental 0.1.0", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "polkadot-primitives 0.1.0", "polkadot-state-machine 0.1.0", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/native-runtime/support/Cargo.toml b/native-runtime/support/Cargo.toml index 185dea5f925a0..f576037bd2c7d 100644 --- a/native-runtime/support/Cargo.toml +++ b/native-runtime/support/Cargo.toml @@ -12,3 +12,4 @@ parking_lot = "0.5" polkadot-state-machine = { path = "../../state_machine" , version = "0.1" } environmental = { path = "../../environmental", version = "0.1.0" } tiny-keccak = "1.3" +polkadot-primitives = { path = "../../primitives", version = "0.1.0" } diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index 7f2de2d10342f..02a4b8b2edb84 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -2,6 +2,7 @@ extern crate environmental; extern crate polkadot_state_machine; extern crate tiny_keccak; +extern crate polkadot_primitives as primitives; use std::fmt; use primitives::ed25519; From 66c93843ba3f59da6ad0b28473adae75ad8dc8e5 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Wed, 17 Jan 2018 19:27:38 +0100 Subject: [PATCH 49/76] use new environmental API --- native-runtime/support/src/lib.rs | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index a2fe13eb104a2..d929b699de6b0 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -21,21 +21,17 @@ impl fmt::Display for NoError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "") } } -pub struct ExternalitiesHolder<'a> { - ext: &'a mut Externalities, -} - -declare_generic!(ext : ExternalitiesHolder); +environmental!(ext : Externalities + 'static); pub fn storage(key: &[u8]) -> Vec { - ext::with(|holder| holder.ext.storage(key).ok().map(|s| s.to_vec())) + ext::with(|ext| ext.storage(key).ok().map(|s| s.to_vec())) .unwrap_or(None) .unwrap_or_else(|| vec![]) } pub fn read_storage(key: &[u8], value_out: &mut [u8]) -> usize { - ext::with(|holder| { - if let Ok(value) = holder.ext.storage(key) { + ext::with(|ext| { + if let Ok(value) = ext.storage(key) { let written = ::std::cmp::min(value.len(), value_out.len()); value_out[0..written].copy_from_slice(&value[0..written]); value.len() @@ -48,8 +44,8 @@ pub fn read_storage(key: &[u8], value_out: &mut [u8]) -> usize { pub fn storage_into(_key: &[u8]) -> Option { let size = size_of::(); - ext::with(|holder| { - if let Ok(value) = holder.ext.storage(_key) { + ext::with(|ext| { + if let Ok(value) = ext.storage(_key) { if value.len() == size { unsafe { let mut result: T = std::mem::uninitialized(); @@ -64,15 +60,15 @@ pub fn storage_into(_key: &[u8]) -> Option { } pub fn set_storage(_key: &[u8], _value: &[u8]) { - ext::with(|holder| - holder.ext.set_storage(_key.to_vec(), _value.to_vec()) + ext::with(|ext| + ext.set_storage(_key.to_vec(), _value.to_vec()) ); } /// The current relay chain identifier. pub fn chain_id() -> u64 { - ext::with(|holder| - holder.ext.chain_id() + ext::with(|ext| + ext.chain_id() ).unwrap_or(0) } @@ -81,9 +77,8 @@ pub use tiny_keccak::keccak256; /// Execute the given closure with global function available whose functionality routes into the /// externalities `ext`. Forwards the value that the closure returns. -pub fn with_externalities R>(ext: &mut Externalities, f: F) -> R { - let mut h = ExternalitiesHolder { ext }; - ext::using(&mut h, f) +pub fn with_externalities R>(ext: &mut (Externalities + 'static), f: F) -> R { + ext::using(ext, f) } #[macro_export] From eebc07188a824b4303646ef34900cb4ede4196b3 Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 18 Jan 2018 12:31:34 +0100 Subject: [PATCH 50/76] Tests for ed25519 verify. --- executor/src/wasm_executor.rs | 15 +++++++++++ primitives/src/ed25519.rs | 24 ++++++++++++++++++ wasm-runtime/support/src/lib.rs | 11 +++----- .../release/runtime_test.compact.wasm | Bin 843 -> 1193 bytes .../release/runtime_test.wasm | Bin 960 -> 1281 bytes wasm-runtime/test/src/lib.rs | 13 ++++++++-- 6 files changed, 54 insertions(+), 9 deletions(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index 719343f8fa0f6..07056b1df7016 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -273,4 +273,19 @@ mod tests { FromHex::from_hex("ecd0e108a98e192af1d2c25055f4e3bed784b5c877204e73219a5203251feaab").unwrap() ); } + + #[test] + fn ed25519_verify_should_work() { + let mut ext = TestExternalities::default(); + let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); + let key = ed25519::Pair::from_seed(&tiny_keccak::keccak256(b"test")); + let sig = key.sign(b"all ok!"); + let mut calldata = vec![]; + calldata.extend_from_slice(key.public().as_ref()); + calldata.extend_from_slice(sig.as_ref()); + assert_eq!( + WasmExecutor.call(&mut ext, &test_code[..], "test_ed25519_verify", &CallData(calldata)).unwrap(), + vec![1] + ); + } } diff --git a/primitives/src/ed25519.rs b/primitives/src/ed25519.rs index 58556b666940c..f6a02a735bd65 100644 --- a/primitives/src/ed25519.rs +++ b/primitives/src/ed25519.rs @@ -48,6 +48,18 @@ impl Signature { } } +impl AsRef<[u8; 64]> for Signature { + fn as_ref(&self) -> &[u8; 64] { + &self.0 + } +} + +impl AsRef<[u8]> for Signature { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + impl Public { pub fn from(data: [u8; 32]) -> Self { Public(data) @@ -59,6 +71,18 @@ impl Public { } } +impl AsRef<[u8; 32]> for Public { + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } +} + +impl AsRef<[u8]> for Public { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + impl Pair { /// Generate new secure (random) key pair. pub fn new() -> Pair { diff --git a/wasm-runtime/support/src/lib.rs b/wasm-runtime/support/src/lib.rs index 9f75504513594..57606a3f1bf6c 100644 --- a/wasm-runtime/support/src/lib.rs +++ b/wasm-runtime/support/src/lib.rs @@ -91,13 +91,10 @@ pub fn keccak256(data: &[u8]) -> [u8; 32] { } /// Verify a ed25519 signature. -pub fn ed25519_verify(sig: &[u8; 64], msg: &[u8], pubkey: &[u8; 32]) -> bool { - unsafe { - match ext_ed25519_verify(&msg[0], msg.len() as u32, &sig[0], &pubkey[0]) { - 0 => false, - _ => true, - } - } +pub fn ed25519_verify(sig: &[u8], msg: &[u8], pubkey: &[u8]) -> bool { + sig.len() != 64 || pubkey.len() != 32 || unsafe { + ext_ed25519_verify(&msg[0], msg.len() as u32, &sig[0], &pubkey[0]) + } == 0 } pub trait Printable { diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index f4c438ec106e2dad2e662f47d1abbb293e62178c..e4431c2606a6e09c8aabfc4baf815ebe5c296a54 100644 GIT binary patch literal 1193 zcmZ8g%Tg0T6uteJN755$kOh{To>_&3B~p-}ZgQ!jTv_GXO)?|{&V)=-$$(;&h6SbN zhq%OV@Ke~h_Y=H5lLR!6>iask&wVt+vk?OTwqNVXIepl?$L7!zm1qwj16jG1$`G(J z`_cp8KbS9){Bkq-Sag%Y-oe517v0Nbnx0+(Sch*Nr_&?>X4S`5Jxhvie11Oe$3-&e z&WiCgK1+aGf5ZBRNxvTt_YPVhtgUWsqY?n}-jIy?ldB3vF2KC>L|Cz}-?<~ItP-aaI5j$>x0g^&)m|@6@NWN|` z!$T2pg;L8%95*=1PzFqyQa3hK+W(s;x)D;aCMZQI14gtsC8X>|lC-V>?C&RIe2##0 zlSDm?C`#fMD(#{{hhR*5*hEjeMj*6!fV(J23^L7$nP~DLWDCGPd58f44zZ?P-XWN* z3SsDG2v1@2B~VHtf$)s!SEWK%2Q88;S+ImPL!yg1BQA#B9$nMt58RZLzjNlS_};-V za%~XhG(O5XqN?V(+F0I&Wy8C{H#h!VfUSI@eUrg;#yX% z_{O-T*Y;p|j_rkG$K)I5h_wY^fF5-RY*RFZ!Z?~-cE7ki{D{^;9NVEdMk1pglvrAZ zkh)64;I~HH9+|HuB|{;2UF^uPn)OY zThKt9lt-`DjE5oMmQoKNBpT(U`Q)MiY$|X0OmSC<)A1N^Ux}0W6X2n$ou+v@d!G!# Ezbf6@Qvd(} delta 503 zcmYk3&2G~`6ot?Hcx-1}a0IB`G3hFcASxs*6}rf+#G;$3i>}y2ZaOJWT04pzKp+$r zynvObU;$emf(;Tcz?;ySw5mGN=-%^<&be2b@9}S?k=IuY02@T@qe1tx61IFF*^kX= zval9tr%yBH*_LNBJ09n=7cVn#&pMu6<(HS$7{Y_tgZZK;8_4$0lkGsLK&enbN;U@q z!O#tlRr`N?r5-f4zMmL&7fT1u>_t(ImgR?{JV&H%(_^_=rxP=D{)*ryV|+y*^tq&T zwktAM6Vj=q9SRH#O9L_#rqT#P#uMt3aBVV8S&tjh=ch@J-8u&DiEkWx6sM98oloqt zH(M@-)RgcHhp*s;bmBQ1zTOBo`yg{2PhsFLOR@gK_ZeUR;w=;FBeB2QP=ZnP4^y|J zVLuMP`Xj$R)PRm4h6yyZ@)_c$K=NNRcFazTmKwQWXqQ!Vlf3);~^QO=hQ$msBn j_O+N)6=Thi8FuB?aAF5s$Jm24c_Of>sX2Y{<07;~hIGcq4DDDs9o`X)s|t z4^>mrl9G$ra8f}eJvPMW>}va1+cqXik}9PP8iN34YuQP7*A){3bHE9tKOhr z^?Sn!*hjUy=9_KTf&U57*_>T6>TNh5PI{M<_ru8m9!X0%z(&GGP25RH2ye#A({7ns zx$PE0``@Vj3C%)v@4p_%lsgIvJnn!8wsPgsBVkpTHy!jU*O{_poGJ8iN0G@*hSt}< zmr^7DUw(8OITt&Ia+USq^?~As+}#_tHY|Yrz9Omx0r5_T+^FCxLyyV2lsrWYL)W4m zN?htS!GX%?DQPyd(kW)9cT|?+60pY^X25_K)N-lnGR!mwL5fR)pJ3}1a7!jZ@H4vC zwZmIy2W$yh5W)_L>5?m%i^sd88~*$Qw>9NI6-Fz*-(Xb4Qp7!dOulrQm%pH-CuPw@ z*xCg+L0SrH@ulS~g9&Y^_90-{7GXH>Q!|4^)Pq*9XIkM2kqql=|oh z4>eFm39ADlii2GH$hCbW_e;r=7JMD_u?!{hhLAO=v3wbFR+WdL?!3M`@?UQASarRT zOUZMxJfLVfpxCCMyBXgm+vc5k63RtuGhUmCjpbaXSfgc5PiGr&#X(gw{Y9!luAWZNTd?Gndp&w#82EM2TA{2iyY}ehlyz z_$mDf9QXmu+No0_Su^jwc{AftjC4~l0PH9_XEn}6UDvE`0*IiL*F<|nQ=puEJqP$N z77JV6M)q?xy+9t#t?Ycdsg~>X%7Qt4&*=+0o283augBny>p8Ay z3=liQ7PHk|>yk}{EsEvswomJ^#l}``N$g5i>#VHcxgPrtliH2wz z&rxo#XTkQR_PypnDrV^Y712+|cx_-X;+|29p%_z4j8viN8(%{+6&Y4EH=7|{@ zL1~gJHsD%}crsvH!x1UGF&vv%g?vIbF=X%dsEY}5gBLh^0|z_;FWKa618DT=m@=-Q zK@U^34vkPb?V{O_vwQme!MA-0$nTu_-M$Z432tq^sB4i2GD_=I?BNV^>JZ7XWyYu-UJ(=8q$+4zJ;(gAdL07v4a zdEtJpy$+~c`yGh#wkehEE)kdqJUzv|*PbGRm?V&pJ*uVyaOLe%f0qU_aP34JAmxV$ z#*^NA8Ud3?`ShP@`qIzJ)lCJXW%&5Hn2{8h%O%W_6c_0im}41VW@WbdXy*f%QyJ11 IqnC@pKX_xoTmS$7 diff --git a/wasm-runtime/test/src/lib.rs b/wasm-runtime/test/src/lib.rs index a24de0219d114..8bbba9e7a81b5 100644 --- a/wasm-runtime/test/src/lib.rs +++ b/wasm-runtime/test/src/lib.rs @@ -8,12 +8,21 @@ use alloc::vec::Vec; #[macro_use] extern crate runtime_support; -use runtime_support::{set_storage, storage, print, keccak256}; +use runtime_support::{set_storage, storage, print, keccak256, ed25519_verify}; fn test_keccak256(input: Vec) -> Vec { keccak256(&input).to_vec() } +fn test_ed25519_verify(input: Vec) -> Vec { + let sig = &input[0..64]; + let pubkey = &input[64..96]; + let msg = b"all ok!"; + let mut r = Vec::new(); + r.push(ed25519_verify(sig, &msg[..], pubkey) as u8); + r +} + fn test_data_in(input: Vec) -> Vec { print(b"set_storage" as &[u8]); set_storage(b"input", &input); @@ -29,4 +38,4 @@ fn test_data_in(input: Vec) -> Vec { } -impl_stubs!(test_data_in, test_keccak256); +impl_stubs!(test_data_in, test_keccak256, test_ed25519_verify); From 5685173032f4ad3a8131e9c59064d4be02ccddd5 Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 18 Jan 2018 12:34:14 +0100 Subject: [PATCH 51/76] Polish --- .../release/runtime_test.compact.wasm | Bin 1193 -> 962 bytes .../release/runtime_test.wasm | Bin 1281 -> 1079 bytes wasm-runtime/test/src/lib.rs | 4 +--- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index e4431c2606a6e09c8aabfc4baf815ebe5c296a54..69e547cd117a8e644a910fd360ae972b4a6efa6b 100644 GIT binary patch delta 256 zcmW+uO-{l<82#qIWvULrwHa|CTZtuVqVhGtYg8%2^7R4@HQK4 gfc2BX3HZ92cp(BHUIzs delta 487 zcmYjNyKYlK5S`h_eR%IpHXH$>2Q9N5>c7Hs)sndlg=fW`ncY z`_b$Oie!3ta`I*fYvyfTsTl*eFjycp#mLmu&@#R(wJ0;K zl7UCCs1&FyDK$MaFTOOdJTotaftM{eH8;7Sl7WvM$jHqvOJ(2(2^FW7FbJ^aCg$Yi zCo>4Lq!p#6G6-=pGH`8T;atba$W-sh;K-oC#NsHBt+d&aX*Hv*El7~ZkzIj7fx+Bb5S`iGJK#R#kkV%EDmxn3&zozMXmV-rLXez4Pv%bRFDyc$B+)nOS7rvFZ1F<3=+Euf8joL8I9` zKJBi|d^B8xUz;zPc4@9g)9!M5Gnx)y&rVI+zg|PN#2}rm3T%_^oQs2?8ZtTHQD(UWBxAvXtWJti)deW_8=}ZHXm(OM7)SEs3tusRLZNcJ``55y zp~%t@i!xblJdvP1U1D9(-;e|lO0ointRlN8u5!dyvU3JN7AcKM#0hwojY37h$;6iA cwoQ)@p)FdZiVt&OR|8cn9VCUJy?K$(zffRE) -> Vec { let sig = &input[0..64]; let pubkey = &input[64..96]; let msg = b"all ok!"; - let mut r = Vec::new(); - r.push(ed25519_verify(sig, &msg[..], pubkey) as u8); - r + [ed25519_verify(sig, &msg[..], pubkey) as u8].to_vec() } fn test_data_in(input: Vec) -> Vec { From f3d415ca8ad7ca841eae34dc1042267b4855f93a Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 18 Jan 2018 15:14:01 +0100 Subject: [PATCH 52/76] Introduce UncheckedTransaction & test. --- .../polkadot/src/codec/endiansensitive.rs | 4 +- wasm-runtime/polkadot/src/lib.rs | 7 +- .../polkadot/src/runtime/consensus.rs | 7 +- wasm-runtime/polkadot/src/runtime/staking.rs | 10 +- wasm-runtime/polkadot/src/runtime/system.rs | 21 +-- .../polkadot/src/runtime/timestamp.rs | 7 +- .../polkadot/src/support/primitives.rs | 152 +++++++++++++----- wasm-runtime/polkadot/src/support/storage.rs | 6 +- 8 files changed, 143 insertions(+), 71 deletions(-) diff --git a/wasm-runtime/polkadot/src/codec/endiansensitive.rs b/wasm-runtime/polkadot/src/codec/endiansensitive.rs index c13a96f23d341..f1e042d886734 100644 --- a/wasm-runtime/polkadot/src/codec/endiansensitive.rs +++ b/wasm-runtime/polkadot/src/codec/endiansensitive.rs @@ -26,4 +26,6 @@ macro_rules! impl_non_endians { } impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize); -impl_non_endians!(u8, i8, [u8; 20], [u8; 32]); +impl_non_endians!(u8, i8, [u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], + [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], + [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 52b29b05cf75d..18ce4059a8b33 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -11,11 +11,12 @@ pub use codec::{endiansensitive, streamreader, joiner, slicable, keyedvec}; pub use support::{primitives, function, environment, storage}; #[cfg(test)] pub use support::testing; -#[allow(unused_imports)] // TODO: remove in due course + +#[allow(unused_imports)] // TODO: remove in due course use runtime_support::Vec; use slicable::Slicable; -use primitives::{Block, Transaction}; +use primitives::{Block, UncheckedTransaction}; // TODO: add externals for: // - keccak256 (or some better hashing scheme) @@ -27,7 +28,7 @@ pub fn execute_block(input: Vec) -> Vec { } pub fn execute_transaction(input: Vec) -> Vec { - runtime::system::execute_transaction(&Transaction::from_slice(&input).unwrap()) + runtime::system::execute_transaction(&UncheckedTransaction::from_slice(&input).unwrap()) } impl_stubs!(execute_block, execute_transaction); diff --git a/wasm-runtime/polkadot/src/runtime/consensus.rs b/wasm-runtime/polkadot/src/runtime/consensus.rs index add87a180831e..0d2531cea4023 100644 --- a/wasm-runtime/polkadot/src/runtime/consensus.rs +++ b/wasm-runtime/polkadot/src/runtime/consensus.rs @@ -2,14 +2,13 @@ use runtime_support::Vec; use keyedvec::KeyedVec; use storage::Storage; use primitives::{AccountID, SessionKey, BlockNumber}; -use storage::storage_into; pub fn set_authority(index: u32, authority: AccountID) { authority.store(&index.to_keyed_vec(b"con\0aut\0")); } fn authority(index: u32) -> AccountID { - storage_into(&index.to_keyed_vec(b"con\0aut\0")) + Storage::into(&index.to_keyed_vec(b"con\0aut\0")) } pub fn set_authority_count(count: u32) { @@ -18,7 +17,7 @@ pub fn set_authority_count(count: u32) { } fn authority_count() -> u32 { - storage_into(b"con\0aut\0len") + Storage::into(b"con\0aut\0len") } /// Get the current set of authorities. These are the session keys. @@ -49,7 +48,7 @@ pub fn set_validators(_new: &[AccountID]) { /// The number of blocks in each session. pub fn session_length() -> BlockNumber { - storage_into(b"con\0bps") + Storage::into(b"con\0bps") } /// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index ca37e7f6fea7f..6e22cfcd5facf 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -1,5 +1,5 @@ use keyedvec::KeyedVec; -use storage::{Storage, storage_into}; +use storage::Storage; use primitives::{BlockNumber, Balance, AccountID}; use runtime::consensus; @@ -10,7 +10,7 @@ pub fn era_length() -> BlockNumber { /// The length of a staking era in sessions. pub fn sessions_per_era() -> BlockNumber { - storage_into(b"sta\0spe") + Storage::into(b"sta\0spe") } /// The era has changed - enact new staking set. @@ -22,16 +22,16 @@ pub fn next_era() { /// The balance of a given account. pub fn balance(who: &AccountID) -> Balance { - storage_into(&who.to_keyed_vec(b"sta\0bal\0")) + Storage::into(&who.to_keyed_vec(b"sta\0bal\0")) } /// Transfer some unlocked staking balance to another staker. pub fn transfer_stake(transactor: &AccountID, dest: &AccountID, value: Balance) { let from_key = transactor.to_keyed_vec(b"sta\0bal\0"); - let from_balance: Balance = storage_into(&from_key); + let from_balance: Balance = Storage::into(&from_key); assert!(from_balance >= value); let to_key = dest.to_keyed_vec(b"sta\0bal\0"); - let to_balance: Balance = storage_into(&to_key); + let to_balance: Balance = Storage::into(&to_key); assert!(to_balance + value > to_balance); // no overflow (from_balance - value).store(&from_key); (to_balance + value).store(&to_key); diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index 27c5eb4fd9bcb..3c4d020dee601 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -1,4 +1,4 @@ -use primitives::{Block, BlockNumber, Hash, Transaction}; +use primitives::{Block, BlockNumber, Hash, UncheckedTransaction}; use runtime_support::{Vec, swap}; use environment::with_env; use runtime_support; @@ -53,7 +53,7 @@ fn final_checks(_block: &Block) { } /// Execute a given transaction. -pub fn execute_transaction(_tx: &Transaction) -> Vec { +pub fn execute_transaction(_tx: &UncheckedTransaction) -> Vec { // TODO: decode data and ensure valid // TODO: ensure signature valid and recover id (use authentication::authenticate) // TODO: check nonce @@ -61,7 +61,7 @@ pub fn execute_transaction(_tx: &Transaction) -> Vec { // TODO: ensure target_function valid // TODO: decode parameters - _tx.function.dispatch(&_tx.signed, &_tx.input_data); + _tx.transaction.function.dispatch(&_tx.transaction.signed, &_tx.transaction.input_data); // TODO: encode any return Vec::new() @@ -78,7 +78,7 @@ mod tests { use function::Function; use std::collections::HashMap; use runtime_support::{NoError, with_externalities, Externalities}; - use primitives::{AccountID, Transaction}; + use primitives::{AccountID, UncheckedTransaction, Transaction}; use runtime::{system, staking}; #[derive(Debug, Default)] @@ -114,11 +114,14 @@ mod tests { { let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let tx = Transaction { - signed: one.clone(), - function: Function::StakingTransferStake, - input_data: vec![].join(&two).join(&69u64), - nonce: 0, + let tx = UncheckedTransaction { + transaction: Transaction { + signed: one.clone(), + nonce: 0, + function: Function::StakingTransferStake, + input_data: vec![].join(&two).join(&69u64), + }, + signature: [1u8; 64], }; with_externalities(&mut t, || { diff --git a/wasm-runtime/polkadot/src/runtime/timestamp.rs b/wasm-runtime/polkadot/src/runtime/timestamp.rs index 6a4043651d87a..6d694c88aefaf 100644 --- a/wasm-runtime/polkadot/src/runtime/timestamp.rs +++ b/wasm-runtime/polkadot/src/runtime/timestamp.rs @@ -1,9 +1,10 @@ use primitives::Timestamp; +use storage::Storage; pub fn timestamp() -> Timestamp { - unimplemented!() + Storage::into(b"tim\0val") } -pub fn set_timestamp(_now: Timestamp) { - unimplemented!() +pub fn set_timestamp(now: Timestamp) { + now.store(b"tim\0val") } diff --git a/wasm-runtime/polkadot/src/support/primitives.rs b/wasm-runtime/polkadot/src/support/primitives.rs index f1bd31cc66097..bb82da8f3bf1e 100644 --- a/wasm-runtime/polkadot/src/support/primitives.rs +++ b/wasm-runtime/polkadot/src/support/primitives.rs @@ -5,10 +5,13 @@ use slicable::{Slicable, NonTrivialSlicable}; use function::Function; use runtime_support::size_of; -/// The hash of an ECDSA pub key which is used to identify an external transactor. +#[cfg(test)] +use std::fmt; + +/// The Ed25519 pubkey that identifies an account. pub type AccountID = [u8; 32]; -/// The ECDSA pub key of an authority. This is what the external environment/consensus algorithm -/// refers to as a "authority". +/// The Ed25519 pub key of an session that belongs to an authority. This is used as what the +/// external environment/consensus algorithm calls an "authority". pub type SessionKey = AccountID; pub type Balance = u64; pub type ChainID = u64; @@ -36,15 +39,9 @@ pub struct Header { #[cfg_attr(test, derive(PartialEq, Debug))] pub struct Transaction { pub signed: AccountID, + pub nonce: TxOrder, pub function: Function, pub input_data: Vec, - pub nonce: TxOrder, -} - -#[cfg_attr(test, derive(PartialEq, Debug))] -pub struct Block { - pub header: Header, - pub transactions: Vec, } impl Slicable for Transaction { @@ -52,8 +49,8 @@ impl Slicable for Transaction { let mut reader = StreamReader::new(value); Some(Transaction { signed: reader.read()?, - function: Function::from_u8(reader.read()?)?, nonce: reader.read()?, + function: Function::from_u8(reader.read()?)?, input_data: reader.read()?, }) } @@ -65,13 +62,13 @@ impl Slicable for Transaction { fn to_vec(&self) -> Vec { Vec::new() .join(&self.signed) - .join(&(self.function as u8)) .join(&self.nonce) + .join(&(self.function as u8)) .join(&self.input_data) } fn size_of(data: &[u8]) -> Option { - let first_part = size_of::() + size_of::() + size_of::(); + let first_part = size_of::() + size_of::() + size_of::(); let second_part = >::size_of(&data[first_part..])?; Some(first_part + second_part) } @@ -79,6 +76,59 @@ impl Slicable for Transaction { impl NonTrivialSlicable for Transaction {} +pub struct UncheckedTransaction { + pub transaction: Transaction, + pub signature: [u8; 64], +} + +#[cfg(test)] +impl PartialEq for UncheckedTransaction { + fn eq(&self, other: &Self) -> bool { + self.signature.iter().eq(other.signature.iter()) && self.transaction == other.transaction + } +} + +#[cfg(test)] +impl fmt::Debug for UncheckedTransaction { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "UncheckedTransaction({:?})", self.transaction) + } +} + +impl Slicable for UncheckedTransaction { + fn from_slice(value: &[u8]) -> Option { + let mut reader = StreamReader::new(value); + Some(UncheckedTransaction { + signature: reader.read()?, + transaction: reader.read()?, + }) + } + + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + + fn to_vec(&self) -> Vec { + Vec::new() + .join(&self.signature) + .join(&self.transaction) + } + + fn size_of(data: &[u8]) -> Option { + let first_part = size_of::<[u8; 64]>(); + let second_part = ::size_of(&data[first_part..])?; + Some(first_part + second_part) + } +} + +impl NonTrivialSlicable for UncheckedTransaction {} + +#[cfg_attr(test, derive(PartialEq, Debug))] +pub struct Block { + pub header: Header, + pub transactions: Vec, +} + impl NonTrivialSlicable for Vec where Vec: Slicable {} impl Slicable for Vec { @@ -181,15 +231,15 @@ mod tests { let two: AccountID = [2u8; 32]; let tx = Transaction { signed: one.clone(), + nonce: 69, function: Function::StakingTransferStake, input_data: Vec::new().join(&two).join(&69u64), - nonce: 69, }; let serialised = tx.to_vec(); assert_eq!(serialised, vec![ 1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 69, 0, 0, 0, 0, 0, 0, 0, + 2, 40, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 0, 0, 0, 0, 0, 0, 0 @@ -202,14 +252,14 @@ mod tests { let two: AccountID = [2u8; 32]; let tx = Transaction { signed: one.clone(), + nonce: 69, function: Function::StakingTransferStake, input_data: Vec::new().join(&two).join(&69u64), - nonce: 69, }; let data = [ 1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 69, 0, 0, 0, 0, 0, 0, 0, + 2, 40, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 0, 0, 0, 0, 0, 0, 0 @@ -269,17 +319,23 @@ mod tests { fn serialise_block_works() { let one: AccountID = [1u8; 32]; let two: AccountID = [2u8; 32]; - let tx1 = Transaction { - signed: one.clone(), - function: Function::StakingTransferStake, - input_data: Vec::new().join(&two).join(&69u64), - nonce: 69, + let tx1 = UncheckedTransaction { + transaction: Transaction { + signed: one.clone(), + nonce: 69, + function: Function::StakingTransferStake, + input_data: Vec::new().join(&two).join(&69u64), + }, + signature: [1u8; 64], }; - let tx2 = Transaction { - signed: two.clone(), - function: Function::StakingStake, - input_data: Vec::new(), - nonce: 42, + let tx2 = UncheckedTransaction { + transaction: Transaction { + signed: two.clone(), + nonce: 42, + function: Function::StakingStake, + input_data: Vec::new(), + }, + signature: [2u8; 64], }; let h = Header { parent_hash: [4u8; 32], @@ -305,18 +361,20 @@ mod tests { 11, 0, 0, 0, 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103, // transactions - 130, 0, 0, 0, + 2, 1, 0, 0, // tx1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 69, 0, 0, 0, 0, 0, 0, 0, + 2, 40, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 0, 0, 0, 0, 0, 0, 0, // tx2 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 0, 42, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 ]); } @@ -325,17 +383,23 @@ mod tests { fn deserialise_block_works() { let one: AccountID = [1u8; 32]; let two: AccountID = [2u8; 32]; - let tx1 = Transaction { - signed: one.clone(), - function: Function::StakingTransferStake, - input_data: Vec::new().join(&two).join(&69u64), - nonce: 69, + let tx1 = UncheckedTransaction { + transaction: Transaction { + signed: one.clone(), + nonce: 69, + function: Function::StakingTransferStake, + input_data: Vec::new().join(&two).join(&69u64), + }, + signature: [1u8; 64], }; - let tx2 = Transaction { - signed: two.clone(), - function: Function::StakingStake, - input_data: Vec::new(), - nonce: 42, + let tx2 = UncheckedTransaction { + transaction: Transaction { + signed: two.clone(), + nonce: 42, + function: Function::StakingStake, + input_data: Vec::new(), + }, + signature: [2u8; 64], }; let h = Header { parent_hash: [4u8; 32], @@ -360,18 +424,20 @@ mod tests { 11, 0, 0, 0, 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103, // transactions - 130, 0, 0, 0, + 2, 1, 0, 0, // tx1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 69, 0, 0, 0, 0, 0, 0, 0, + 2, 40, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 0, 0, 0, 0, 0, 0, 0, // tx2 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 0, 42, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 ]; let deserialised = Block::from_slice(&data).unwrap(); diff --git a/wasm-runtime/polkadot/src/support/storage.rs b/wasm-runtime/polkadot/src/support/storage.rs index 13a9074d950c9..99c8bab88033f 100644 --- a/wasm-runtime/polkadot/src/support/storage.rs +++ b/wasm-runtime/polkadot/src/support/storage.rs @@ -3,12 +3,12 @@ use endiansensitive::EndianSensitive; use runtime_support; pub trait Storage { - fn storage_into(key: &[u8]) -> Self; + fn into(key: &[u8]) -> Self; fn store(&self, key: &[u8]); } impl Storage for T { - fn storage_into(key: &[u8]) -> Self { + fn into(key: &[u8]) -> Self { Slicable::set_as_slice(|out| runtime_support::read_storage(key, out) == out.len()) .unwrap_or_else(Default::default) } @@ -19,5 +19,5 @@ impl Storage for T { } pub fn storage_into(key: &[u8]) -> T { - T::storage_into(key) + T::into(key) } From 2c9cb7baa1ec4750c7d3053f21de17bfea9df361 Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 18 Jan 2018 16:24:53 +0100 Subject: [PATCH 53/76] Implement basic block and tx processing --- wasm-runtime/polkadot/src/codec/keyedvec.rs | 22 ++- wasm-runtime/polkadot/src/lib.rs | 8 +- wasm-runtime/polkadot/src/runtime/system.rs | 67 +++++---- .../polkadot/src/support/primitives.rs | 139 ++++++++++-------- wasm-runtime/polkadot/src/support/storage.rs | 9 +- 5 files changed, 144 insertions(+), 101 deletions(-) diff --git a/wasm-runtime/polkadot/src/codec/keyedvec.rs b/wasm-runtime/polkadot/src/codec/keyedvec.rs index fcc410e58234f..fad6b1956f7d5 100644 --- a/wasm-runtime/polkadot/src/codec/keyedvec.rs +++ b/wasm-runtime/polkadot/src/codec/keyedvec.rs @@ -1,17 +1,20 @@ use runtime_support::Vec; -use primitives::AccountID; use slicable::Slicable; pub trait KeyedVec { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec; } -impl KeyedVec for AccountID { - fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec { - let mut r = prepend_key.to_vec(); - r.extend_from_slice(self); - r - } +macro_rules! impl_non_endians { + ( $( $t:ty ),* ) => { $( + impl KeyedVec for $t { + fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec { + let mut r = prepend_key.to_vec(); + r.extend_from_slice(&self[..]); + r + } + } + )* } } macro_rules! impl_endians { @@ -28,4 +31,7 @@ macro_rules! impl_endians { )* } } -impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize); +impl_endians!(u8, i8, u16, u32, u64, usize, i16, i32, i64, isize); +impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], + [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], + [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 18ce4059a8b33..7653aaff9be1f 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -19,16 +19,16 @@ use slicable::Slicable; use primitives::{Block, UncheckedTransaction}; // TODO: add externals for: -// - keccak256 (or some better hashing scheme) // - trie rooting -// - ECDSA-recover (or some better sig scheme) pub fn execute_block(input: Vec) -> Vec { - runtime::system::execute_block(Block::from_slice(&input).unwrap()) + runtime::system::execute_block(Block::from_slice(&input).unwrap()); + Vec::new() } pub fn execute_transaction(input: Vec) -> Vec { - runtime::system::execute_transaction(&UncheckedTransaction::from_slice(&input).unwrap()) + runtime::system::execute_transaction(&UncheckedTransaction::from_slice(&input).unwrap()); + Vec::new() } impl_stubs!(execute_block, execute_transaction); diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index 3c4d020dee601..2ddc83bdb2476 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -1,7 +1,8 @@ -use primitives::{Block, BlockNumber, Hash, UncheckedTransaction}; +use primitives::{Block, BlockNumber, Hash, UncheckedTransaction, TxOrder, Hashable}; use runtime_support::{Vec, swap}; +use storage::Storage; +use keyedvec::KeyedVec; use environment::with_env; -use runtime_support; use runtime::staking; /// The current block number being processed. Set by `execute_block`. @@ -10,8 +11,8 @@ pub fn block_number() -> BlockNumber { } /// Get the block hash of a given block (uses storage). -pub fn block_hash(_number: BlockNumber) -> Hash { - unimplemented!() +pub fn block_hash(number: BlockNumber) -> Hash { + Storage::into(&number.to_keyed_vec(b"sys\0old\0")) } /// Deposits a log and ensures it matches the blocks log data. @@ -22,7 +23,7 @@ pub fn deposit_log(log: &[u8]) { }); } -pub fn execute_block(mut block: Block) -> Vec { +pub fn execute_block(mut block: Block) { // populate environment from header. with_env(|e| { e.block_number = block.header.number; @@ -30,20 +31,29 @@ pub fn execute_block(mut block: Block) -> Vec { e.next_log_index = 0; }); - // TODO: check transaction trie root represents the transactions. - // TODO: store the header hash in storage. + let ref header = block.header; - staking::pre_transactions(); + // check parent_hash is correct. + assert!( + header.number > 0 && block_hash(header.number - 1) == header.parent_hash, + "Parent hash should be valid." + ); - block.transactions.iter().for_each(|tx| { execute_transaction(tx); }); + // TODO: check transaction trie root represents the transactions. + // store the header hash in storage. + let header_hash_key = header.number.to_keyed_vec(b"sys\0old\0"); + header.keccak256().store(&header_hash_key); + + // execute transactions + staking::pre_transactions(); + block.transactions.iter().for_each(execute_transaction); staking::post_transactions(); + // any final checks final_checks(&block); - // TODO: check state root somehow - - Vec::new() + // TODO: check storage root somehow } fn final_checks(_block: &Block) { @@ -53,29 +63,34 @@ fn final_checks(_block: &Block) { } /// Execute a given transaction. -pub fn execute_transaction(_tx: &UncheckedTransaction) -> Vec { - // TODO: decode data and ensure valid - // TODO: ensure signature valid and recover id (use authentication::authenticate) - // TODO: check nonce - // TODO: increment nonce in storage - // TODO: ensure target_function valid - // TODO: decode parameters - - _tx.transaction.function.dispatch(&_tx.transaction.signed, &_tx.transaction.input_data); - - // TODO: encode any return - Vec::new() +pub fn execute_transaction(utx: &UncheckedTransaction) { + // Verify the signature is good. + assert!(utx.ed25519_verify(), "All transactions should be properly signed"); + + let ref tx = utx.transaction; + + // check nonce + let nonce_key = tx.signed.to_keyed_vec(b"sys\0non\0"); + let expected_nonce: TxOrder = Storage::into(&nonce_key); + assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce"); + + // increment nonce in storage + (expected_nonce + 1).store(&nonce_key); + + // decode parameters and dispatch + tx.function.dispatch(&tx.signed, &tx.input_data); } /// Set the new code. pub fn set_code(new: &[u8]) { - runtime_support::set_storage(b"\0code", new) + new.store(b"\0code"); } #[cfg(test)] mod tests { use joiner::Joiner; use function::Function; + use codec::keyedvec::KeyedVec; use std::collections::HashMap; use runtime_support::{NoError, with_externalities, Externalities}; use primitives::{AccountID, UncheckedTransaction, Transaction}; @@ -111,7 +126,7 @@ mod tests { let two: AccountID = [2u8; 32]; let mut t = TestExternalities { storage: map![ - { let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + one.to_keyed_vec(b"sta\0bal\0") => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ], }; let tx = UncheckedTransaction { diff --git a/wasm-runtime/polkadot/src/support/primitives.rs b/wasm-runtime/polkadot/src/support/primitives.rs index bb82da8f3bf1e..4cf9dd9d32e72 100644 --- a/wasm-runtime/polkadot/src/support/primitives.rs +++ b/wasm-runtime/polkadot/src/support/primitives.rs @@ -3,7 +3,7 @@ use streamreader::StreamReader; use joiner::Joiner; use slicable::{Slicable, NonTrivialSlicable}; use function::Function; -use runtime_support::size_of; +use runtime_support::{size_of, keccak256, ed25519_verify}; #[cfg(test)] use std::fmt; @@ -36,6 +36,40 @@ pub struct Header { pub digest: Digest, } +impl Slicable for Header { + fn from_slice(value: &[u8]) -> Option { + let mut reader = StreamReader::new(value); + Some(Header { + parent_hash: reader.read()?, + number: reader.read()?, + state_root: reader.read()?, + transaction_root: reader.read()?, + digest: Digest { logs: reader.read()?, }, + }) + } + + fn set_as_slice bool>(_fill_slice: F) -> Option { + unimplemented!(); + } + + fn to_vec(&self) -> Vec { + Vec::new() + .join(&self.parent_hash) + .join(&self.number) + .join(&self.state_root) + .join(&self.transaction_root) + .join(&self.digest.logs) + } + + fn size_of(data: &[u8]) -> Option { + let first_part = size_of::() + size_of::() + size_of::() + size_of::(); + let second_part = >>::size_of(&data[first_part..])?; + Some(first_part + second_part) + } +} + +impl NonTrivialSlicable for Header {} + #[cfg_attr(test, derive(PartialEq, Debug))] pub struct Transaction { pub signed: AccountID, @@ -74,6 +108,16 @@ impl Slicable for Transaction { } } +pub trait Hashable: Sized { + fn keccak256(&self) -> [u8; 32]; +} + +impl Hashable for T { + fn keccak256(&self) -> [u8; 32] { + keccak256(&self.to_vec()) + } +} + impl NonTrivialSlicable for Transaction {} pub struct UncheckedTransaction { @@ -81,6 +125,13 @@ pub struct UncheckedTransaction { pub signature: [u8; 64], } +impl UncheckedTransaction { + pub fn ed25519_verify(&self) -> bool { + let msg = self.transaction.to_vec(); + ed25519_verify(&self.signature, &msg, &self.transaction.signed) + } +} + #[cfg(test)] impl PartialEq for UncheckedTransaction { fn eq(&self, other: &Self) -> bool { @@ -129,47 +180,12 @@ pub struct Block { pub transactions: Vec, } -impl NonTrivialSlicable for Vec where Vec: Slicable {} - -impl Slicable for Vec { - fn from_slice(value: &[u8]) -> Option { - let len = Self::size_of(&value[0..4])?; - let mut off = 4; - let mut r = Vec::new(); - while off < len { - let element_len = T::size_of(&value[off..])?; - r.push(T::from_slice(&value[off..off + element_len])?); - off += element_len; - } - Some(r) - } - - fn set_as_slice bool>(_fill_slice: F) -> Option { - unimplemented!(); - } - - fn to_vec(&self) -> Vec { - let vecs = self.iter().map(Slicable::to_vec).collect::>(); - let len = vecs.iter().fold(0, |mut a, v| {a += v.len(); a}); - let mut r = Vec::new().join(&(len as u32)); - vecs.iter().for_each(|v| r.extend_from_slice(v)); - r - } - - fn size_of(data: &[u8]) -> Option { - u32::from_slice(&data[0..4]).map(|i| (i + 4) as usize) - } -} - -impl Slicable for Header { +impl Slicable for Block { fn from_slice(value: &[u8]) -> Option { let mut reader = StreamReader::new(value); - Some(Header { - parent_hash: reader.read()?, - number: reader.read()?, - state_root: reader.read()?, - transaction_root: reader.read()?, - digest: Digest { logs: reader.read()?, }, + Some(Block { + header: reader.read()?, + transactions: reader.read()?, }) } @@ -179,27 +195,32 @@ impl Slicable for Header { fn to_vec(&self) -> Vec { Vec::new() - .join(&self.parent_hash) - .join(&self.number) - .join(&self.state_root) - .join(&self.transaction_root) - .join(&self.digest.logs) + .join(&self.header) + .join(&self.transactions) } fn size_of(data: &[u8]) -> Option { - let first_part = size_of::() + size_of::() + size_of::() + size_of::(); - let second_part = >>::size_of(&data[first_part..])?; + let first_part = Header::size_of(data)?; + let second_part = >::size_of(&data[first_part..])?; Some(first_part + second_part) } } -impl Slicable for Block { +impl NonTrivialSlicable for Block {} + +impl NonTrivialSlicable for Vec where Vec: Slicable {} + +impl Slicable for Vec { fn from_slice(value: &[u8]) -> Option { - let mut reader = StreamReader::new(value); - Some(Block { - header: reader.read()?, - transactions: reader.read()?, - }) + let len = Self::size_of(&value[0..4])?; + let mut off = 4; + let mut r = Vec::new(); + while off < len { + let element_len = T::size_of(&value[off..])?; + r.push(T::from_slice(&value[off..off + element_len])?); + off += element_len; + } + Some(r) } fn set_as_slice bool>(_fill_slice: F) -> Option { @@ -207,15 +228,15 @@ impl Slicable for Block { } fn to_vec(&self) -> Vec { - Vec::new() - .join(&self.header) - .join(&self.transactions) + let vecs = self.iter().map(Slicable::to_vec).collect::>(); + let len = vecs.iter().fold(0, |mut a, v| {a += v.len(); a}); + let mut r = Vec::new().join(&(len as u32)); + vecs.iter().for_each(|v| r.extend_from_slice(v)); + r } fn size_of(data: &[u8]) -> Option { - let first_part = Header::size_of(data)?; - let second_part = >::size_of(&data[first_part..])?; - Some(first_part + second_part) + u32::from_slice(&data[0..4]).map(|i| (i + 4) as usize) } } diff --git a/wasm-runtime/polkadot/src/support/storage.rs b/wasm-runtime/polkadot/src/support/storage.rs index 99c8bab88033f..becb4f7fb28a4 100644 --- a/wasm-runtime/polkadot/src/support/storage.rs +++ b/wasm-runtime/polkadot/src/support/storage.rs @@ -3,7 +3,7 @@ use endiansensitive::EndianSensitive; use runtime_support; pub trait Storage { - fn into(key: &[u8]) -> Self; + fn into(_key: &[u8]) -> Self where Self: Sized { unimplemented!() } fn store(&self, key: &[u8]); } @@ -12,12 +12,13 @@ impl Storage for T { Slicable::set_as_slice(|out| runtime_support::read_storage(key, out) == out.len()) .unwrap_or_else(Default::default) } - fn store(&self, key: &[u8]) { self.as_slice_then(|slice| runtime_support::set_storage(key, slice)); } } -pub fn storage_into(key: &[u8]) -> T { - T::into(key) +impl Storage for [u8] { + fn store(&self, key: &[u8]) { + runtime_support::set_storage(key, self) + } } From eda7d714bc29d5ce2d6b42839debff509c642b5f Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 18 Jan 2018 17:35:18 +0100 Subject: [PATCH 54/76] Introduce static hex and valid signature for block test. --- Cargo.lock | 1 + native-runtime/Cargo.toml | 1 + primitives/src/ed25519.rs | 60 +++++++++++++++---- wasm-runtime/polkadot/src/lib.rs | 5 +- wasm-runtime/polkadot/src/runtime/system.rs | 20 +++++-- wasm-runtime/polkadot/src/support/mod.rs | 2 + .../polkadot/src/support/statichex.rs | 29 +++++++++ wasm-runtime/polkadot/src/support/testing.rs | 43 +++++++++++++ 8 files changed, 144 insertions(+), 17 deletions(-) create mode 100644 wasm-runtime/polkadot/src/support/statichex.rs diff --git a/Cargo.lock b/Cargo.lock index f886c60be544f..7d5f50ddc46ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -532,6 +532,7 @@ name = "native-runtime" version = "0.1.0" dependencies = [ "runtime-support 0.1.0", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/native-runtime/Cargo.toml b/native-runtime/Cargo.toml index c971a6d694855..eb5eb82408f18 100644 --- a/native-runtime/Cargo.toml +++ b/native-runtime/Cargo.toml @@ -10,3 +10,4 @@ without-std = [] [dependencies] runtime-support = { path = "./support", version = "0.1" } +rustc-hex = "1.0" diff --git a/primitives/src/ed25519.rs b/primitives/src/ed25519.rs index f6a02a735bd65..2630f858d22ef 100644 --- a/primitives/src/ed25519.rs +++ b/primitives/src/ed25519.rs @@ -4,17 +4,6 @@ use untrusted; use ring::{rand, signature}; use rustc_hex::FromHex; -struct HexDisplay<'a>(&'a [u8]); - -impl<'a> ::std::fmt::Display for HexDisplay<'a> { - fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - for byte in self.0 { - try!( fmtr.write_fmt(format_args!("{:02x}", byte))); - } - Ok(()) - } -} - pub fn verify(sig: &[u8], message: &[u8], public: &[u8]) -> bool { let public_key = untrusted::Input::from(public); let msg = untrusted::Input::from(message); @@ -181,6 +170,41 @@ impl PartialEq for Signature { mod test { use super::*; +pub struct HexDisplay<'a>(&'a [u8]); + +impl<'a> HexDisplay<'a> { + pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) } +} + +impl<'a> ::std::fmt::Display for HexDisplay<'a> { + fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + for byte in self.0 { + try!( fmtr.write_fmt(format_args!("{:02x}", byte))); + } + Ok(()) + } +} + +pub trait AsBytesRef { + fn as_bytes_ref(&self) -> &[u8]; +} + +impl AsBytesRef for [u8] { + fn as_bytes_ref(&self) -> &[u8] { &self } +} + +macro_rules! impl_non_endians { + ( $( $t:ty ),* ) => { $( + impl AsBytesRef for $t { + fn as_bytes_ref(&self) -> &[u8] { &self[..] } + } + )* } +} + +impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], + [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], + [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); + #[test] fn test_vector_should_work() { let pair: Pair = "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into(); @@ -205,8 +229,22 @@ mod test { fn seeded_pair_should_work() { let pair = Pair::from_seed(b"12345678901234567890123456789012"); let public = pair.public(); + println!("{}", HexDisplay::from(&public.0)); + assert_eq!(public, "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".into()); let message = b"Something important"; let signature = pair.sign(&message[..]); assert!(signature.verify(&message[..], &public)); } + + #[test] + fn can_sign_transaction() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let public = pair.public(); + assert_eq!(public, "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".into()); + let message = FromHex::from_hex("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000").unwrap(); + let signature = pair.sign(&message[..]); + println!("pub: {}", HexDisplay::from(&public.0)); + println!("sig: {}", HexDisplay::from(&signature.0)); + assert!(signature.verify(&message[..], &public)); + } } diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 7653aaff9be1f..6a6201945dccc 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -4,13 +4,16 @@ #[macro_use] extern crate runtime_support; +#[cfg(test)] +extern crate rustc_hex; + mod codec; mod support; mod runtime; pub use codec::{endiansensitive, streamreader, joiner, slicable, keyedvec}; pub use support::{primitives, function, environment, storage}; #[cfg(test)] -pub use support::testing; +pub use support::{testing, statichex}; #[allow(unused_imports)] // TODO: remove in due course diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index 2ddc83bdb2476..fe0e83560880b 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -90,11 +90,14 @@ pub fn set_code(new: &[u8]) { mod tests { use joiner::Joiner; use function::Function; - use codec::keyedvec::KeyedVec; + use keyedvec::KeyedVec; + use slicable::Slicable; use std::collections::HashMap; use runtime_support::{NoError, with_externalities, Externalities}; - use primitives::{AccountID, UncheckedTransaction, Transaction}; + use primitives::{AccountID, UncheckedTransaction, Transaction, Hashable}; + use statichex::StaticHexInto; use runtime::{system, staking}; + use testing::HexDisplay; #[derive(Debug, Default)] struct TestExternalities { @@ -120,10 +123,13 @@ mod tests { ) } + fn one() -> AccountID { "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".convert() } + fn two() -> AccountID { "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".convert() } + #[test] fn staking_balance_transfer_dispatch_works() { - let one: AccountID = [1u8; 32]; - let two: AccountID = [2u8; 32]; + let one = one(); + let two = two(); let mut t = TestExternalities { storage: map![ one.to_keyed_vec(b"sta\0bal\0") => vec![111u8, 0, 0, 0, 0, 0, 0, 0] @@ -136,8 +142,12 @@ mod tests { function: Function::StakingTransferStake, input_data: vec![].join(&two).join(&69u64), }, - signature: [1u8; 64], + signature: "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a".convert(), }; + // tx: 2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000 + // sig: 679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a + + println!("tx is {}", HexDisplay::from(&tx.transaction.to_vec())); with_externalities(&mut t, || { system::execute_transaction(&tx); diff --git a/wasm-runtime/polkadot/src/support/mod.rs b/wasm-runtime/polkadot/src/support/mod.rs index aa14ad2f5dba9..732552effd735 100644 --- a/wasm-runtime/polkadot/src/support/mod.rs +++ b/wasm-runtime/polkadot/src/support/mod.rs @@ -3,5 +3,7 @@ pub mod function; pub mod environment; pub mod storage; +#[cfg(test)] +pub mod statichex; #[cfg(test)] pub mod testing; diff --git a/wasm-runtime/polkadot/src/support/statichex.rs b/wasm-runtime/polkadot/src/support/statichex.rs new file mode 100644 index 0000000000000..774cb82538ba4 --- /dev/null +++ b/wasm-runtime/polkadot/src/support/statichex.rs @@ -0,0 +1,29 @@ +use rustc_hex::FromHex; + +pub trait StaticHexConversion: Sized { + fn from_static_hex(hex: &'static str) -> Self; +} + +macro_rules! impl_sizes { + ( $( $t:expr ),* ) => { $( + impl StaticHexConversion for [u8; $t] { + fn from_static_hex(hex: &'static str) -> Self { + let mut r = [0u8; $t]; + r.copy_from_slice(&FromHex::from_hex(hex).unwrap()); + r + } + } + )* } +} + +impl_sizes!(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128); + +pub trait StaticHexInto { + fn convert(self) -> T; +} + +impl StaticHexInto for &'static str { + fn convert(self) -> T { + T::from_static_hex(self) + } +} diff --git a/wasm-runtime/polkadot/src/support/testing.rs b/wasm-runtime/polkadot/src/support/testing.rs index ec7fac6d6ddb6..5338add6350c9 100644 --- a/wasm-runtime/polkadot/src/support/testing.rs +++ b/wasm-runtime/polkadot/src/support/testing.rs @@ -19,3 +19,46 @@ impl Externalities for TestExternalities { fn chain_id(&self) -> u64 { 42 } } + +pub struct HexDisplay<'a>(&'a [u8]); + +impl<'a> HexDisplay<'a> { + pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) } +} + +impl<'a> ::std::fmt::Display for HexDisplay<'a> { + fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + for byte in self.0 { + try!( fmtr.write_fmt(format_args!("{:02x}", byte))); + } + Ok(()) + } +} + +pub trait AsBytesRef { + fn as_bytes_ref(&self) -> &[u8]; +} + +impl AsBytesRef for [u8] { + fn as_bytes_ref(&self) -> &[u8] { &self } +} + +impl<'a> AsBytesRef for &'a[u8] { + fn as_bytes_ref(&self) -> &[u8] { self } +} + +impl AsBytesRef for Vec { + fn as_bytes_ref(&self) -> &[u8] { &self[..] } +} + +macro_rules! impl_non_endians { + ( $( $t:ty ),* ) => { $( + impl AsBytesRef for $t { + fn as_bytes_ref(&self) -> &[u8] { &self[..] } + } + )* } +} + +impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], + [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], + [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); From e8cd918cb15e506b8ed4b5480235e0f6430c22a9 Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 18 Jan 2018 18:42:33 +0100 Subject: [PATCH 55/76] Repot session. --- wasm-runtime/polkadot/src/lib.rs | 5 -- .../polkadot/src/runtime/consensus.rs | 39 +------------- wasm-runtime/polkadot/src/runtime/mod.rs | 2 + wasm-runtime/polkadot/src/runtime/session.rs | 51 +++++++++++++++++++ wasm-runtime/polkadot/src/runtime/staking.rs | 14 ++--- wasm-runtime/polkadot/src/runtime/system.rs | 12 +++-- wasm-runtime/polkadot/src/support/function.rs | 10 ++-- 7 files changed, 75 insertions(+), 58 deletions(-) create mode 100644 wasm-runtime/polkadot/src/runtime/session.rs diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 6a6201945dccc..500594e31ad4e 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -15,15 +15,10 @@ pub use support::{primitives, function, environment, storage}; #[cfg(test)] pub use support::{testing, statichex}; - -#[allow(unused_imports)] // TODO: remove in due course use runtime_support::Vec; use slicable::Slicable; use primitives::{Block, UncheckedTransaction}; -// TODO: add externals for: -// - trie rooting - pub fn execute_block(input: Vec) -> Vec { runtime::system::execute_block(Block::from_slice(&input).unwrap()); Vec::new() diff --git a/wasm-runtime/polkadot/src/runtime/consensus.rs b/wasm-runtime/polkadot/src/runtime/consensus.rs index 0d2531cea4023..f8991e88715e6 100644 --- a/wasm-runtime/polkadot/src/runtime/consensus.rs +++ b/wasm-runtime/polkadot/src/runtime/consensus.rs @@ -2,6 +2,7 @@ use runtime_support::Vec; use keyedvec::KeyedVec; use storage::Storage; use primitives::{AccountID, SessionKey, BlockNumber}; +use runtime::{system, staking}; pub fn set_authority(index: u32, authority: AccountID) { authority.store(&index.to_keyed_vec(b"con\0aut\0")); @@ -32,41 +33,3 @@ pub fn set_authorities(authorities: &[AccountID]) { set_authority_count(authorities.len() as u32); authorities.iter().enumerate().for_each(|(v, &i)| set_authority(v as u32, i)); } - -/// Get the current set of validators. These are the long-term identifiers for the validators -/// and will be mapped to a session key with the most recent `set_next_session_key`. -pub fn validators() -> Vec { - unimplemented!() -} - -/// Set the current set of validators. -/// -/// Called by staking::next_era() only. -pub fn set_validators(_new: &[AccountID]) { - unimplemented!() -} - -/// The number of blocks in each session. -pub fn session_length() -> BlockNumber { - Storage::into(b"con\0bps") -} - -/// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next -/// session. -pub fn set_session_key(_transactor: &AccountID, _session: &AccountID) { - unimplemented!() -} - -/// Move onto next session: register the new authority set. -pub fn next_session() { - // TODO: Call set_authorities(). - unimplemented!() -} - -/// Hook to be called prior to transaction processing. -pub fn pre_transactions() {} - -/// Hook to be called after to transaction processing. -pub fn post_transactions() { - // TODO: check block number and call next_session if necessary. -} diff --git a/wasm-runtime/polkadot/src/runtime/mod.rs b/wasm-runtime/polkadot/src/runtime/mod.rs index c73e338a91b2c..8e60ec431c37a 100644 --- a/wasm-runtime/polkadot/src/runtime/mod.rs +++ b/wasm-runtime/polkadot/src/runtime/mod.rs @@ -6,3 +6,5 @@ pub mod consensus; pub mod staking; #[allow(unused)] pub mod timestamp; +#[allow(unused)] +pub mod session; diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs new file mode 100644 index 0000000000000..f72ef0b5c653c --- /dev/null +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -0,0 +1,51 @@ +use runtime_support::Vec; +use keyedvec::KeyedVec; +use storage::Storage; +use primitives::{AccountID, SessionKey, BlockNumber}; +use runtime::{system, staking, consensus}; + +/// Get the current set of validators. These are the long-term identifiers for the validators +/// and will be mapped to a session key with the most recent `set_next_session_key`. +pub fn validators() -> Vec { + consensus::authorities() +} + +/// Set the current set of validators. +/// +/// Called by staking::next_era() only. +pub fn set_validators(new: &[AccountID]) { + consensus::set_authorities(new); +} + +/// The number of blocks in each session. +pub fn length() -> BlockNumber { + Storage::into(b"con\0bps") +} + +/// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next +/// session. +pub fn set_key(_transactor: &AccountID, _session: &AccountID) { + // TODO: record the new session key for `_transactor`, ready for the next session. +} + +/// Move onto next session: register the new authority set. +pub fn next_session() { + // TODO: Call set_authorities() with any new authorities. +} + +/// Hook to be called prior to transaction processing. +pub fn pre_transactions() { + staking::pre_transactions(); +} + +/// Hook to be called after to transaction processing. +pub fn post_transactions() { + staking::post_transactions(); + + // do this last, after the staking system has had chance to switch out the authorities for the + // new set. + // check block number and call next_session if necessary. + if system::block_number() % length() == 0 { + next_session(); + } +} diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index 6e22cfcd5facf..366ad0668bcbe 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -1,11 +1,11 @@ use keyedvec::KeyedVec; use storage::Storage; use primitives::{BlockNumber, Balance, AccountID}; -use runtime::consensus; +use runtime::{system, session}; /// The length of a staking era in blocks. pub fn era_length() -> BlockNumber { - sessions_per_era() * consensus::session_length() + sessions_per_era() * session::length() } /// The length of a staking era in sessions. @@ -17,7 +17,8 @@ pub fn sessions_per_era() -> BlockNumber { /// /// NOTE: This always happens on a session change. pub fn next_era() { - unimplemented!() + // TODO: evaluate desired staking amounts and nominations and optimise to find the best + // combination of validators, then use session::set_validators(). } /// The balance of a given account. @@ -53,13 +54,14 @@ pub fn unstake(_transactor: &AccountID) { /// Hook to be called prior to transaction processing. pub fn pre_transactions() { - consensus::pre_transactions(); } /// Hook to be called after to transaction processing. pub fn post_transactions() { - // TODO: check block number and call next_era if necessary. - consensus::post_transactions(); + // check block number and call next_era if necessary. + if system::block_number() % era_length() == 0 { + next_era(); + } } diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index fe0e83560880b..690e1db527e41 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -3,7 +3,7 @@ use runtime_support::{Vec, swap}; use storage::Storage; use keyedvec::KeyedVec; use environment::with_env; -use runtime::staking; +use runtime::session; /// The current block number being processed. Set by `execute_block`. pub fn block_number() -> BlockNumber { @@ -40,20 +40,24 @@ pub fn execute_block(mut block: Block) { ); // TODO: check transaction trie root represents the transactions. + // this requires non-trivial changes to the externals API or compiling trie rooting into wasm + // so will wait until a little later. // store the header hash in storage. let header_hash_key = header.number.to_keyed_vec(b"sys\0old\0"); header.keccak256().store(&header_hash_key); // execute transactions - staking::pre_transactions(); + session::pre_transactions(); block.transactions.iter().for_each(execute_transaction); - staking::post_transactions(); + session::post_transactions(); // any final checks final_checks(&block); - // TODO: check storage root somehow + // TODO: check storage root. + // this requires non-trivial changes to the externals API or compiling trie rooting into wasm + // so will wait until a little later. } fn final_checks(_block: &Block) { diff --git a/wasm-runtime/polkadot/src/support/function.rs b/wasm-runtime/polkadot/src/support/function.rs index ff54938d47aa8..995ec3c459105 100644 --- a/wasm-runtime/polkadot/src/support/function.rs +++ b/wasm-runtime/polkadot/src/support/function.rs @@ -1,4 +1,4 @@ -use runtime::{staking, consensus}; +use runtime::{staking, session}; use primitives::AccountID; use streamreader::StreamReader; @@ -9,7 +9,7 @@ pub enum Function { StakingStake, StakingUnstake, StakingTransferStake, - ConsensusSetSessionKey, + SessionSetKey, } impl Function { @@ -18,7 +18,7 @@ impl Function { x if x == Function::StakingStake as u8 => Some(Function::StakingStake), x if x == Function::StakingUnstake as u8 => Some(Function::StakingUnstake), x if x == Function::StakingTransferStake as u8 => Some(Function::StakingTransferStake), - x if x == Function::ConsensusSetSessionKey as u8 => Some(Function::ConsensusSetSessionKey), + x if x == Function::SessionSetKey as u8 => Some(Function::SessionSetKey), _ => None, } } @@ -40,9 +40,9 @@ impl Function { let value = params.read().unwrap(); staking::transfer_stake(transactor, &dest, value); } - Function::ConsensusSetSessionKey => { + Function::SessionSetKey => { let session = params.read().unwrap(); - consensus::set_session_key(transactor, &session); + session::set_key(transactor, &session); } } } From 3d1ff94e852066b1d83b1c9944c3652ee653b021 Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 18 Jan 2018 18:45:29 +0100 Subject: [PATCH 56/76] comments. --- wasm-runtime/polkadot/src/runtime/session.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs index f72ef0b5c653c..1112d45249d7c 100644 --- a/wasm-runtime/polkadot/src/runtime/session.rs +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -7,6 +7,7 @@ use runtime::{system, staking, consensus}; /// Get the current set of validators. These are the long-term identifiers for the validators /// and will be mapped to a session key with the most recent `set_next_session_key`. pub fn validators() -> Vec { + // TODO: derive from the actual validator set consensus::authorities() } @@ -14,6 +15,7 @@ pub fn validators() -> Vec { /// /// Called by staking::next_era() only. pub fn set_validators(new: &[AccountID]) { + // TODO: set the actual validators consensus::set_authorities(new); } From 92a12f0182391a0b6d40eb77eaca51adebc2a2f8 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 08:49:38 +0100 Subject: [PATCH 57/76] Refactor and timestamp test --- wasm-runtime/polkadot/src/lib.rs | 1 + wasm-runtime/polkadot/src/runtime/session.rs | 28 ++++++---- wasm-runtime/polkadot/src/runtime/staking.rs | 30 +++++++---- wasm-runtime/polkadot/src/runtime/system.rs | 52 +++++-------------- .../polkadot/src/runtime/timestamp.rs | 30 ++++++++++- wasm-runtime/polkadot/src/support/function.rs | 16 ++++-- wasm-runtime/polkadot/src/support/mod.rs | 1 + .../polkadot/src/support/primitives.rs | 8 +-- wasm-runtime/polkadot/src/support/testing.rs | 16 ++++++ 9 files changed, 110 insertions(+), 72 deletions(-) diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 500594e31ad4e..b791fefdb7d6b 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -8,6 +8,7 @@ extern crate runtime_support; extern crate rustc_hex; mod codec; +#[macro_use] mod support; mod runtime; pub use codec::{endiansensitive, streamreader, joiner, slicable, keyedvec}; diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs index 1112d45249d7c..0a736b3b47a02 100644 --- a/wasm-runtime/polkadot/src/runtime/session.rs +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -4,6 +4,16 @@ use storage::Storage; use primitives::{AccountID, SessionKey, BlockNumber}; use runtime::{system, staking, consensus}; +// TRANSACTION API (available to all transactors) + +/// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next +/// session. +pub fn set_key(_transactor: &AccountID, _session: &AccountID) { + // TODO: record the new session key for `_transactor`, ready for the next session. +} + +// PUBLIC API (available to other runtime modules) + /// Get the current set of validators. These are the long-term identifiers for the validators /// and will be mapped to a session key with the most recent `set_next_session_key`. pub fn validators() -> Vec { @@ -24,17 +34,6 @@ pub fn length() -> BlockNumber { Storage::into(b"con\0bps") } -/// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next -/// session. -pub fn set_key(_transactor: &AccountID, _session: &AccountID) { - // TODO: record the new session key for `_transactor`, ready for the next session. -} - -/// Move onto next session: register the new authority set. -pub fn next_session() { - // TODO: Call set_authorities() with any new authorities. -} - /// Hook to be called prior to transaction processing. pub fn pre_transactions() { staking::pre_transactions(); @@ -51,3 +50,10 @@ pub fn post_transactions() { next_session(); } } + +// PRIVATE (not available) + +/// Move onto next session: register the new authority set. +fn next_session() { + // TODO: Call set_authorities() with any new authorities. +} diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index 366ad0668bcbe..9b06602c84a8a 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -3,6 +3,11 @@ use storage::Storage; use primitives::{BlockNumber, Balance, AccountID}; use runtime::{system, session}; +// Each validator's stake has one amount in each of three states: +// - inactive: free to be transferred +// - active: currently representing a validator +// - deactivating: recently representing a validator and not yet ready for transfer + /// The length of a staking era in blocks. pub fn era_length() -> BlockNumber { sessions_per_era() * session::length() @@ -13,21 +18,26 @@ pub fn sessions_per_era() -> BlockNumber { Storage::into(b"sta\0spe") } +/// The length of a staking era in sessions. +pub fn lockup_eras() -> BlockNumber { + Storage::into(b"sta\0lpe") +} + /// The era has changed - enact new staking set. /// /// NOTE: This always happens on a session change. -pub fn next_era() { +fn next_era() { // TODO: evaluate desired staking amounts and nominations and optimise to find the best // combination of validators, then use session::set_validators(). } /// The balance of a given account. -pub fn balance(who: &AccountID) -> Balance { +pub fn balance_inactive(who: &AccountID) -> Balance { Storage::into(&who.to_keyed_vec(b"sta\0bal\0")) } /// Transfer some unlocked staking balance to another staker. -pub fn transfer_stake(transactor: &AccountID, dest: &AccountID, value: Balance) { +pub fn transfer_inactive(transactor: &AccountID, dest: &AccountID, value: Balance) { let from_key = transactor.to_keyed_vec(b"sta\0bal\0"); let from_balance: Balance = Storage::into(&from_key); assert!(from_balance >= value); @@ -42,14 +52,14 @@ pub fn transfer_stake(transactor: &AccountID, dest: &AccountID, value: Balance) /// /// Effects will be felt at the beginning of the next era. pub fn stake(_transactor: &AccountID) { - unimplemented!() + // TODO: record the desire for `_transactor` to activate their stake. } /// Retract the desire to stake for the transactor. /// /// Effects will be felt at the beginning of the next era. pub fn unstake(_transactor: &AccountID) { - unimplemented!() + // TODO: record the desire for `_transactor` to deactivate their stake. } /// Hook to be called prior to transaction processing. @@ -88,8 +98,8 @@ mod tests { ], }; with_externalities(&mut t, || { - assert_eq!(staking::balance(&one), 42); - assert_eq!(staking::balance(&two), 0); + assert_eq!(staking::balance_inactive(&one), 42); + assert_eq!(staking::balance_inactive(&two), 0); }); } @@ -103,9 +113,9 @@ mod tests { ], }; with_externalities(&mut t, || { - staking::transfer_stake(&one, &two, 69); - assert_eq!(staking::balance(&one), 42); - assert_eq!(staking::balance(&two), 69); + staking::transfer_inactive(&one, &two, 69); + assert_eq!(staking::balance_inactive(&one), 42); + assert_eq!(staking::balance_inactive(&two), 69); }); } } diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index 690e1db527e41..d7abd1835ad1d 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -60,12 +60,6 @@ pub fn execute_block(mut block: Block) { // so will wait until a little later. } -fn final_checks(_block: &Block) { - with_env(|e| { - assert_eq!(e.next_log_index, e.digest.logs.len()); - }); -} - /// Execute a given transaction. pub fn execute_transaction(utx: &UncheckedTransaction) { // Verify the signature is good. @@ -90,45 +84,23 @@ pub fn set_code(new: &[u8]) { new.store(b"\0code"); } +fn final_checks(_block: &Block) { + with_env(|e| { + assert_eq!(e.next_log_index, e.digest.logs.len()); + }); +} + #[cfg(test)] mod tests { use joiner::Joiner; use function::Function; use keyedvec::KeyedVec; use slicable::Slicable; - use std::collections::HashMap; - use runtime_support::{NoError, with_externalities, Externalities}; - use primitives::{AccountID, UncheckedTransaction, Transaction, Hashable}; + use runtime_support::with_externalities; + use primitives::{UncheckedTransaction, Transaction}; use statichex::StaticHexInto; use runtime::{system, staking}; - use testing::HexDisplay; - - #[derive(Debug, Default)] - struct TestExternalities { - storage: HashMap, Vec>, - } - impl Externalities for TestExternalities { - type Error = NoError; - - fn storage(&self, key: &[u8]) -> Result<&[u8], NoError> { - Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) - } - - fn set_storage(&mut self, key: Vec, value: Vec) { - self.storage.insert(key, value); - } - - fn chain_id(&self) -> u64 { 42 } - } - - macro_rules! map { - ($( $name:expr => $value:expr ),*) => ( - vec![ $( ( $name, $value ) ),* ].into_iter().collect() - ) - } - - fn one() -> AccountID { "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".convert() } - fn two() -> AccountID { "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".convert() } + use testing::{TestExternalities, HexDisplay, one, two}; #[test] fn staking_balance_transfer_dispatch_works() { @@ -143,7 +115,7 @@ mod tests { transaction: Transaction { signed: one.clone(), nonce: 0, - function: Function::StakingTransferStake, + function: Function::StakingTransferInactive, input_data: vec![].join(&two).join(&69u64), }, signature: "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a".convert(), @@ -155,8 +127,8 @@ mod tests { with_externalities(&mut t, || { system::execute_transaction(&tx); - assert_eq!(staking::balance(&one), 42); - assert_eq!(staking::balance(&two), 69); + assert_eq!(staking::balance_inactive(&one), 42); + assert_eq!(staking::balance_inactive(&two), 69); }); } } diff --git a/wasm-runtime/polkadot/src/runtime/timestamp.rs b/wasm-runtime/polkadot/src/runtime/timestamp.rs index 6d694c88aefaf..09c1d5bcbe6ca 100644 --- a/wasm-runtime/polkadot/src/runtime/timestamp.rs +++ b/wasm-runtime/polkadot/src/runtime/timestamp.rs @@ -1,10 +1,36 @@ use primitives::Timestamp; use storage::Storage; -pub fn timestamp() -> Timestamp { +pub fn get() -> Timestamp { Storage::into(b"tim\0val") } -pub fn set_timestamp(now: Timestamp) { +pub fn set(now: Timestamp) { now.store(b"tim\0val") } + +#[cfg(test)] +mod tests { + use joiner::Joiner; + use function::Function; + use keyedvec::KeyedVec; + use slicable::Slicable; + use runtime_support::with_externalities; + use primitives::{UncheckedTransaction, Transaction}; + use statichex::StaticHexInto; + use runtime::{system, timestamp}; + use testing::{TestExternalities, HexDisplay, one, two}; + + #[test] + fn timestamp_works() { + let mut t = TestExternalities { storage: map![ + b"tim\0val".to_vec() => vec![].join(&42u64) + ], }; + + with_externalities(&mut t, || { + assert_eq!(timestamp::get(), 42); + timestamp::set(69); + assert_eq!(timestamp::get(), 69); + }); + } +} diff --git a/wasm-runtime/polkadot/src/support/function.rs b/wasm-runtime/polkadot/src/support/function.rs index 995ec3c459105..45dcea876b4e6 100644 --- a/wasm-runtime/polkadot/src/support/function.rs +++ b/wasm-runtime/polkadot/src/support/function.rs @@ -1,6 +1,6 @@ -use runtime::{staking, session}; use primitives::AccountID; use streamreader::StreamReader; +use runtime::{staking, session, timestamp}; /// The functions that a transaction can call (and be dispatched to). #[cfg_attr(test, derive(PartialEq, Debug))] @@ -8,8 +8,9 @@ use streamreader::StreamReader; pub enum Function { StakingStake, StakingUnstake, - StakingTransferStake, + StakingTransferInactive, SessionSetKey, + TimestampSet, } impl Function { @@ -17,8 +18,9 @@ impl Function { match value { x if x == Function::StakingStake as u8 => Some(Function::StakingStake), x if x == Function::StakingUnstake as u8 => Some(Function::StakingUnstake), - x if x == Function::StakingTransferStake as u8 => Some(Function::StakingTransferStake), + x if x == Function::StakingTransferInactive as u8 => Some(Function::StakingTransferInactive), x if x == Function::SessionSetKey as u8 => Some(Function::SessionSetKey), + x if x == Function::TimestampSet as u8 => Some(Function::TimestampSet), _ => None, } } @@ -35,15 +37,19 @@ impl Function { Function::StakingUnstake => { staking::unstake(transactor); } - Function::StakingTransferStake => { + Function::StakingTransferInactive => { let dest = params.read().unwrap(); let value = params.read().unwrap(); - staking::transfer_stake(transactor, &dest, value); + staking::transfer_inactive(transactor, &dest, value); } Function::SessionSetKey => { let session = params.read().unwrap(); session::set_key(transactor, &session); } + Function::TimestampSet => { + let t = params.read().unwrap(); + timestamp::set(t); + } } } } diff --git a/wasm-runtime/polkadot/src/support/mod.rs b/wasm-runtime/polkadot/src/support/mod.rs index 732552effd735..11cb23e997a06 100644 --- a/wasm-runtime/polkadot/src/support/mod.rs +++ b/wasm-runtime/polkadot/src/support/mod.rs @@ -6,4 +6,5 @@ pub mod storage; #[cfg(test)] pub mod statichex; #[cfg(test)] +#[macro_use] pub mod testing; diff --git a/wasm-runtime/polkadot/src/support/primitives.rs b/wasm-runtime/polkadot/src/support/primitives.rs index 4cf9dd9d32e72..ecac3fbbd48e8 100644 --- a/wasm-runtime/polkadot/src/support/primitives.rs +++ b/wasm-runtime/polkadot/src/support/primitives.rs @@ -253,7 +253,7 @@ mod tests { let tx = Transaction { signed: one.clone(), nonce: 69, - function: Function::StakingTransferStake, + function: Function::StakingTransferInactive, input_data: Vec::new().join(&two).join(&69u64), }; let serialised = tx.to_vec(); @@ -274,7 +274,7 @@ mod tests { let tx = Transaction { signed: one.clone(), nonce: 69, - function: Function::StakingTransferStake, + function: Function::StakingTransferInactive, input_data: Vec::new().join(&two).join(&69u64), }; let data = [ @@ -344,7 +344,7 @@ mod tests { transaction: Transaction { signed: one.clone(), nonce: 69, - function: Function::StakingTransferStake, + function: Function::StakingTransferInactive, input_data: Vec::new().join(&two).join(&69u64), }, signature: [1u8; 64], @@ -408,7 +408,7 @@ mod tests { transaction: Transaction { signed: one.clone(), nonce: 69, - function: Function::StakingTransferStake, + function: Function::StakingTransferInactive, input_data: Vec::new().join(&two).join(&69u64), }, signature: [1u8; 64], diff --git a/wasm-runtime/polkadot/src/support/testing.rs b/wasm-runtime/polkadot/src/support/testing.rs index 5338add6350c9..a617405e793e6 100644 --- a/wasm-runtime/polkadot/src/support/testing.rs +++ b/wasm-runtime/polkadot/src/support/testing.rs @@ -1,5 +1,7 @@ use runtime_support::{NoError, Externalities}; use std::collections::HashMap; +use primitives::AccountID; +use statichex::StaticHexInto; #[derive(Debug, Default)] pub struct TestExternalities { @@ -20,6 +22,20 @@ impl Externalities for TestExternalities { fn chain_id(&self) -> u64 { 42 } } +#[macro_export] +macro_rules! map { + ($( $name:expr => $value:expr ),*) => ( + vec![ $( ( $name, $value ) ),* ].into_iter().collect() + ) +} + +pub fn one() -> AccountID { + "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".convert() +} +pub fn two() -> AccountID { + "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".convert() +} + pub struct HexDisplay<'a>(&'a [u8]); impl<'a> HexDisplay<'a> { From 55232778850691329776a53290da2e909f70eda9 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 08:50:33 +0100 Subject: [PATCH 58/76] Remove fluff --- wasm-runtime/polkadot/src/runtime/timestamp.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/wasm-runtime/polkadot/src/runtime/timestamp.rs b/wasm-runtime/polkadot/src/runtime/timestamp.rs index 09c1d5bcbe6ca..e0f3d2c04e7ec 100644 --- a/wasm-runtime/polkadot/src/runtime/timestamp.rs +++ b/wasm-runtime/polkadot/src/runtime/timestamp.rs @@ -12,14 +12,10 @@ pub fn set(now: Timestamp) { #[cfg(test)] mod tests { use joiner::Joiner; - use function::Function; use keyedvec::KeyedVec; - use slicable::Slicable; use runtime_support::with_externalities; - use primitives::{UncheckedTransaction, Transaction}; - use statichex::StaticHexInto; - use runtime::{system, timestamp}; - use testing::{TestExternalities, HexDisplay, one, two}; + use runtime::timestamp; + use testing::TestExternalities; #[test] fn timestamp_works() { From 9a8f61d9ebb9b377944a7e70efcfe5f135607f2c Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 08:51:38 +0100 Subject: [PATCH 59/76] Remove fluff. --- wasm-runtime/polkadot/src/runtime/staking.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index 9b06602c84a8a..ecc2532872c45 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -74,7 +74,6 @@ pub fn post_transactions() { } } - #[cfg(test)] mod tests { use runtime_support::with_externalities; @@ -82,12 +81,6 @@ mod tests { use primitives::{AccountID}; use runtime::staking; - macro_rules! map { - ($( $name:expr => $value:expr ),*) => ( - vec![ $( ( $name, $value ) ),* ].into_iter().collect() - ) - } - #[test] fn staking_balance_works() { let one: AccountID = [1u8; 32]; From 90f965a83dc9cf99375bee1c8cbdc2c76675b75d Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 09:37:00 +0100 Subject: [PATCH 60/76] Staking eras and tests. --- wasm-runtime/polkadot/src/runtime/session.rs | 2 +- wasm-runtime/polkadot/src/runtime/staking.rs | 127 ++++++++++++++++--- 2 files changed, 113 insertions(+), 16 deletions(-) diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs index 0a736b3b47a02..2ed6c7a0a2009 100644 --- a/wasm-runtime/polkadot/src/runtime/session.rs +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -31,7 +31,7 @@ pub fn set_validators(new: &[AccountID]) { /// The number of blocks in each session. pub fn length() -> BlockNumber { - Storage::into(b"con\0bps") + Storage::into(b"ses\0bps") } /// Hook to be called prior to transaction processing. diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index ecc2532872c45..ea2116b0352ec 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -4,9 +4,14 @@ use primitives::{BlockNumber, Balance, AccountID}; use runtime::{system, session}; // Each validator's stake has one amount in each of three states: -// - inactive: free to be transferred -// - active: currently representing a validator -// - deactivating: recently representing a validator and not yet ready for transfer +// - inactive: free to be transferred. +// - active: currently representing a validator. +// - deactivating: recently representing a validator and not yet ready for transfer. + +/// The length of a staking era in sessions. +pub fn lockup_eras() -> BlockNumber { + Storage::into(b"sta\0lpe") +} /// The length of a staking era in blocks. pub fn era_length() -> BlockNumber { @@ -18,15 +23,40 @@ pub fn sessions_per_era() -> BlockNumber { Storage::into(b"sta\0spe") } -/// The length of a staking era in sessions. -pub fn lockup_eras() -> BlockNumber { - Storage::into(b"sta\0lpe") +/// The current era index. +pub fn current_era() -> BlockNumber { + Storage::into(b"sta\0era") +} + +/// The current era index. +pub fn set_current_era(new: BlockNumber) { + new.store(b"sta\0era"); +} + +/// The block number at which the era length last changed. +pub fn last_era_length_change() -> BlockNumber { + Storage::into(b"sta\0lec") +} + +/// Set a new era length. Won't kick in until the next era change (at current length). +pub fn set_sessions_per_era(new: BlockNumber) { + new.store(b"sta\0nse"); } /// The era has changed - enact new staking set. /// /// NOTE: This always happens on a session change. fn next_era() { + // Increment current era. + set_current_era(current_era() + 1); + + // Enact era length change. + let next_spe: u64 = Storage::into(b"sta\0nse"); + if next_spe > 0 && next_spe != sessions_per_era() { + next_spe.store(b"sta\0spe"); + system::block_number().store(b"sta\0lec"); + } + // TODO: evaluate desired staking amounts and nominations and optimise to find the best // combination of validators, then use session::set_validators(). } @@ -69,7 +99,7 @@ pub fn pre_transactions() { /// Hook to be called after to transaction processing. pub fn post_transactions() { // check block number and call next_era if necessary. - if system::block_number() % era_length() == 0 { + if (system::block_number() - last_era_length_change()) % era_length() == 0 { next_era(); } } @@ -77,17 +107,84 @@ pub fn post_transactions() { #[cfg(test)] mod tests { use runtime_support::with_externalities; - use testing::TestExternalities; - use primitives::{AccountID}; + use keyedvec::KeyedVec; + use joiner::Joiner; + use testing::{one, two, TestExternalities}; + use primitives::AccountID; use runtime::staking; + use environment::with_env; + + #[test] + fn staking_eras_work() { + let mut t = TestExternalities { storage: map![ + b"ses\0bps".to_vec() => vec![].join(&1u64), + b"sta\0spe".to_vec() => vec![].join(&2u64) + ], }; + with_externalities(&mut t, || { + assert_eq!(staking::era_length(), 2u64); + assert_eq!(staking::sessions_per_era(), 2u64); + assert_eq!(staking::last_era_length_change(), 0u64); + assert_eq!(staking::current_era(), 0u64); + + // Block 1: No change. + with_env(|e| e.block_number = 1); + staking::post_transactions(); + assert_eq!(staking::sessions_per_era(), 2u64); + assert_eq!(staking::last_era_length_change(), 0u64); + assert_eq!(staking::current_era(), 0u64); + + // Block 2: Simple era change. + with_env(|e| e.block_number = 2); + staking::post_transactions(); + assert_eq!(staking::sessions_per_era(), 2u64); + assert_eq!(staking::last_era_length_change(), 0u64); + assert_eq!(staking::current_era(), 1u64); + + // Block 3: Schedule an era length change; no visible changes. + with_env(|e| e.block_number = 3); + staking::set_sessions_per_era(3); + staking::post_transactions(); + assert_eq!(staking::sessions_per_era(), 2u64); + assert_eq!(staking::last_era_length_change(), 0u64); + assert_eq!(staking::current_era(), 1u64); + + // Block 4: Era change kicks in. + with_env(|e| e.block_number = 4); + staking::post_transactions(); + assert_eq!(staking::sessions_per_era(), 3u64); + assert_eq!(staking::last_era_length_change(), 4u64); + assert_eq!(staking::current_era(), 2u64); + + // Block 5: No change. + with_env(|e| e.block_number = 5); + staking::post_transactions(); + assert_eq!(staking::sessions_per_era(), 3u64); + assert_eq!(staking::last_era_length_change(), 4u64); + assert_eq!(staking::current_era(), 2u64); + + // Block 6: No change. + with_env(|e| e.block_number = 6); + staking::post_transactions(); + assert_eq!(staking::sessions_per_era(), 3u64); + assert_eq!(staking::last_era_length_change(), 4u64); + assert_eq!(staking::current_era(), 2u64); + + // Block 7: Era increment. + with_env(|e| e.block_number = 7); + staking::post_transactions(); + assert_eq!(staking::sessions_per_era(), 3u64); + assert_eq!(staking::last_era_length_change(), 4u64); + assert_eq!(staking::current_era(), 3u64); + }); + } #[test] fn staking_balance_works() { - let one: AccountID = [1u8; 32]; - let two: AccountID = [2u8; 32]; + let one = one(); + let two = two(); let mut t = TestExternalities { storage: map![ - { let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![42u8, 0, 0, 0, 0, 0, 0, 0] + one.to_keyed_vec(b"sta\0bal\0") => vec![].join(&42u64) ], }; with_externalities(&mut t, || { @@ -98,11 +195,11 @@ mod tests { #[test] fn staking_balance_transfer_works() { - let one: AccountID = [1u8; 32]; - let two: AccountID = [2u8; 32]; + let one = one(); + let two = two(); let mut t = TestExternalities { storage: map![ - { let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + one.to_keyed_vec(b"sta\0bal\0") => vec![].join(&111u64) ], }; with_externalities(&mut t, || { From 58670fc62f83e47d45589f11f628ef377612babe Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 10:34:55 +0100 Subject: [PATCH 61/76] Implement sessions. --- wasm-runtime/polkadot/src/lib.rs | 2 +- .../polkadot/src/runtime/consensus.rs | 39 +++++++------------ wasm-runtime/polkadot/src/runtime/mod.rs | 2 + wasm-runtime/polkadot/src/runtime/session.rs | 33 +++++++++++----- wasm-runtime/polkadot/src/support/mod.rs | 1 + wasm-runtime/polkadot/src/support/storage.rs | 6 +-- .../polkadot/src/support/storagevec.rs | 38 ++++++++++++++++++ 7 files changed, 83 insertions(+), 38 deletions(-) create mode 100644 wasm-runtime/polkadot/src/support/storagevec.rs diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index b791fefdb7d6b..4a1302a756797 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -12,7 +12,7 @@ mod codec; mod support; mod runtime; pub use codec::{endiansensitive, streamreader, joiner, slicable, keyedvec}; -pub use support::{primitives, function, environment, storage}; +pub use support::{primitives, function, environment, storage, storagevec}; #[cfg(test)] pub use support::{testing, statichex}; diff --git a/wasm-runtime/polkadot/src/runtime/consensus.rs b/wasm-runtime/polkadot/src/runtime/consensus.rs index f8991e88715e6..b773e7e1e6d8f 100644 --- a/wasm-runtime/polkadot/src/runtime/consensus.rs +++ b/wasm-runtime/polkadot/src/runtime/consensus.rs @@ -1,35 +1,26 @@ use runtime_support::Vec; -use keyedvec::KeyedVec; -use storage::Storage; -use primitives::{AccountID, SessionKey, BlockNumber}; -use runtime::{system, staking}; +use storagevec::StorageVec; +use primitives::SessionKey; -pub fn set_authority(index: u32, authority: AccountID) { - authority.store(&index.to_keyed_vec(b"con\0aut\0")); -} - -fn authority(index: u32) -> AccountID { - Storage::into(&index.to_keyed_vec(b"con\0aut\0")) -} - -pub fn set_authority_count(count: u32) { - (count..authority_count()).for_each(|i| set_authority(i, SessionKey::default())); - count.store(b"con\0aut\0len"); -} - -fn authority_count() -> u32 { - Storage::into(b"con\0aut\0len") +struct AuthorityStorageVec {} +impl StorageVec for AuthorityStorageVec { + type Item = SessionKey; + const PREFIX: &'static[u8] = b"con\0aut\0"; } /// Get the current set of authorities. These are the session keys. -pub fn authorities() -> Vec { - (0..authority_count()).into_iter().map(authority).collect() +pub fn authorities() -> Vec { + AuthorityStorageVec::items() } /// Set the current set of authorities' session keys. /// /// Called by `next_session` only. -pub fn set_authorities(authorities: &[AccountID]) { - set_authority_count(authorities.len() as u32); - authorities.iter().enumerate().for_each(|(v, &i)| set_authority(v as u32, i)); +pub fn set_authorities(authorities: &[SessionKey]) { + AuthorityStorageVec::set_items(authorities); +} + +/// Set a single authority by index. +pub fn set_authority(index: u32, key: &SessionKey) { + AuthorityStorageVec::set_item(index, key); } diff --git a/wasm-runtime/polkadot/src/runtime/mod.rs b/wasm-runtime/polkadot/src/runtime/mod.rs index 8e60ec431c37a..55a4801a5b979 100644 --- a/wasm-runtime/polkadot/src/runtime/mod.rs +++ b/wasm-runtime/polkadot/src/runtime/mod.rs @@ -8,3 +8,5 @@ pub mod staking; pub mod timestamp; #[allow(unused)] pub mod session; + +// TODO: governance, polkadao diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs index 2ed6c7a0a2009..8e133ad5633c9 100644 --- a/wasm-runtime/polkadot/src/runtime/session.rs +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -1,31 +1,38 @@ use runtime_support::Vec; use keyedvec::KeyedVec; use storage::Storage; +use storagevec::StorageVec; use primitives::{AccountID, SessionKey, BlockNumber}; use runtime::{system, staking, consensus}; +struct ValidatorStorageVec {} +impl StorageVec for ValidatorStorageVec { + type Item = AccountID; + const PREFIX: &'static[u8] = b"ses\0key\0"; +} + // TRANSACTION API (available to all transactors) -/// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next +/// Sets the session key of `_validator` to `_key`. This doesn't take effect until the next /// session. -pub fn set_key(_transactor: &AccountID, _session: &AccountID) { - // TODO: record the new session key for `_transactor`, ready for the next session. +pub fn set_key(validator: &AccountID, key: &SessionKey) { + // set new value for next session + key.store(&validator.to_keyed_vec(b"ses\0nxt\0")); } // PUBLIC API (available to other runtime modules) -/// Get the current set of validators. These are the long-term identifiers for the validators -/// and will be mapped to a session key with the most recent `set_next_session_key`. -pub fn validators() -> Vec { - // TODO: derive from the actual validator set - consensus::authorities() +/// Get the current set of authorities. These are the session keys. +fn validators() -> Vec { + ValidatorStorageVec::items() } /// Set the current set of validators. /// -/// Called by staking::next_era() only. +/// Called by staking::next_era() only. `next_session` should be called after this in order to +/// update the session keys to the next validator set. pub fn set_validators(new: &[AccountID]) { - // TODO: set the actual validators + ValidatorStorageVec::set_items(new); consensus::set_authorities(new); } @@ -56,4 +63,10 @@ pub fn post_transactions() { /// Move onto next session: register the new authority set. fn next_session() { // TODO: Call set_authorities() with any new authorities. + validators().iter().enumerate().for_each(|(i, v)| { + let k = v.to_keyed_vec(b"ses\0nxt\0"); + if let Some(n) = Storage::try_into(&k) { + consensus::set_authority(i as u32, &n); + } + }) } diff --git a/wasm-runtime/polkadot/src/support/mod.rs b/wasm-runtime/polkadot/src/support/mod.rs index 11cb23e997a06..e4dae46c40636 100644 --- a/wasm-runtime/polkadot/src/support/mod.rs +++ b/wasm-runtime/polkadot/src/support/mod.rs @@ -2,6 +2,7 @@ pub mod primitives; pub mod function; pub mod environment; pub mod storage; +pub mod storagevec; #[cfg(test)] pub mod statichex; diff --git a/wasm-runtime/polkadot/src/support/storage.rs b/wasm-runtime/polkadot/src/support/storage.rs index becb4f7fb28a4..7c9696bc11faa 100644 --- a/wasm-runtime/polkadot/src/support/storage.rs +++ b/wasm-runtime/polkadot/src/support/storage.rs @@ -3,14 +3,14 @@ use endiansensitive::EndianSensitive; use runtime_support; pub trait Storage { - fn into(_key: &[u8]) -> Self where Self: Sized { unimplemented!() } + fn into(key: &[u8]) -> Self where Self: Sized + Default { Self::try_into(key).unwrap_or_else(Default::default) } + fn try_into(_key: &[u8]) -> Option where Self: Sized { unimplemented!() } fn store(&self, key: &[u8]); } impl Storage for T { - fn into(key: &[u8]) -> Self { + fn try_into(key: &[u8]) -> Option { Slicable::set_as_slice(|out| runtime_support::read_storage(key, out) == out.len()) - .unwrap_or_else(Default::default) } fn store(&self, key: &[u8]) { self.as_slice_then(|slice| runtime_support::set_storage(key, slice)); diff --git a/wasm-runtime/polkadot/src/support/storagevec.rs b/wasm-runtime/polkadot/src/support/storagevec.rs new file mode 100644 index 0000000000000..ac0ded3a563d2 --- /dev/null +++ b/wasm-runtime/polkadot/src/support/storagevec.rs @@ -0,0 +1,38 @@ +use runtime_support::Vec; +use keyedvec::KeyedVec; +use storage::Storage; + +/// A trait to conveniently store a vector of storable data. +// TODO: add iterator support +pub trait StorageVec { + type Item: Default + Sized + Storage; + const PREFIX: &'static [u8]; + + /// Get the current set of items. + fn items() -> Vec { + (0..Self::count()).into_iter().map(Self::item).collect() + } + + /// Set the current set of items. + fn set_items(items: &[Self::Item]) { + Self::set_count(items.len() as u32); + items.iter().enumerate().for_each(|(v, ref i)| Self::set_item(v as u32, i)); + } + + fn set_item(index: u32, item: &Self::Item) { + item.store(&index.to_keyed_vec(Self::PREFIX)); + } + + fn item(index: u32) -> Self::Item { + Storage::into(&index.to_keyed_vec(Self::PREFIX)) + } + + fn set_count(count: u32) { + (count..Self::count()).for_each(|i| Self::set_item(i, &Self::Item::default())); + count.store(&b"len".to_keyed_vec(Self::PREFIX)); + } + + fn count() -> u32 { + Storage::into(&b"len".to_keyed_vec(Self::PREFIX)) + } +} From 999025fd036a4fe9a2912a259604cafcb4920f02 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 10:49:23 +0100 Subject: [PATCH 62/76] Polish --- state_machine/src/lib.rs | 2 +- wasm-runtime/polkadot/src/lib.rs | 2 +- .../polkadot/src/runtime/consensus.rs | 2 +- wasm-runtime/polkadot/src/runtime/session.rs | 13 ++-- wasm-runtime/polkadot/src/runtime/staking.rs | 18 +++--- wasm-runtime/polkadot/src/runtime/system.rs | 6 +- .../polkadot/src/runtime/timestamp.rs | 4 +- wasm-runtime/polkadot/src/support/mod.rs | 3 +- wasm-runtime/polkadot/src/support/storable.rs | 62 +++++++++++++++++++ wasm-runtime/polkadot/src/support/storage.rs | 24 ------- .../polkadot/src/support/storagevec.rs | 38 ------------ 11 files changed, 87 insertions(+), 87 deletions(-) create mode 100644 wasm-runtime/polkadot/src/support/storable.rs delete mode 100644 wasm-runtime/polkadot/src/support/storage.rs delete mode 100644 wasm-runtime/polkadot/src/support/storagevec.rs diff --git a/state_machine/src/lib.rs b/state_machine/src/lib.rs index e94b2b6078c4f..91622c9bc42d6 100644 --- a/state_machine/src/lib.rs +++ b/state_machine/src/lib.rs @@ -244,7 +244,7 @@ mod tests { fn set_storage(&mut self, key: Vec, value: Vec) { self.storage.insert(key, value); } - + fn chain_id(&self) -> u64 { 42 } } diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 4a1302a756797..7e8cc2233e4cf 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -12,7 +12,7 @@ mod codec; mod support; mod runtime; pub use codec::{endiansensitive, streamreader, joiner, slicable, keyedvec}; -pub use support::{primitives, function, environment, storage, storagevec}; +pub use support::{primitives, function, environment, storable}; #[cfg(test)] pub use support::{testing, statichex}; diff --git a/wasm-runtime/polkadot/src/runtime/consensus.rs b/wasm-runtime/polkadot/src/runtime/consensus.rs index b773e7e1e6d8f..02bf288493b7f 100644 --- a/wasm-runtime/polkadot/src/runtime/consensus.rs +++ b/wasm-runtime/polkadot/src/runtime/consensus.rs @@ -1,5 +1,5 @@ use runtime_support::Vec; -use storagevec::StorageVec; +use storable::StorageVec; use primitives::SessionKey; struct AuthorityStorageVec {} diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs index 8e133ad5633c9..66309becafcf7 100644 --- a/wasm-runtime/polkadot/src/runtime/session.rs +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -1,7 +1,6 @@ use runtime_support::Vec; use keyedvec::KeyedVec; -use storage::Storage; -use storagevec::StorageVec; +use storable::{kill, Storable, StorageVec}; use primitives::{AccountID, SessionKey, BlockNumber}; use runtime::{system, staking, consensus}; @@ -38,7 +37,7 @@ pub fn set_validators(new: &[AccountID]) { /// The number of blocks in each session. pub fn length() -> BlockNumber { - Storage::into(b"ses\0bps") + Storable::lookup_default(b"ses\0bps") } /// Hook to be called prior to transaction processing. @@ -62,11 +61,13 @@ pub fn post_transactions() { /// Move onto next session: register the new authority set. fn next_session() { - // TODO: Call set_authorities() with any new authorities. validators().iter().enumerate().for_each(|(i, v)| { let k = v.to_keyed_vec(b"ses\0nxt\0"); - if let Some(n) = Storage::try_into(&k) { + if let Some(n) = Storable::lookup(&k) { consensus::set_authority(i as u32, &n); + kill(&k); } - }) + }); } + +// TODO: tests diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index ea2116b0352ec..29d6ac0272b9d 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -1,5 +1,5 @@ use keyedvec::KeyedVec; -use storage::Storage; +use storable::Storable; use primitives::{BlockNumber, Balance, AccountID}; use runtime::{system, session}; @@ -10,7 +10,7 @@ use runtime::{system, session}; /// The length of a staking era in sessions. pub fn lockup_eras() -> BlockNumber { - Storage::into(b"sta\0lpe") + Storable::lookup_default(b"sta\0lpe") } /// The length of a staking era in blocks. @@ -20,12 +20,12 @@ pub fn era_length() -> BlockNumber { /// The length of a staking era in sessions. pub fn sessions_per_era() -> BlockNumber { - Storage::into(b"sta\0spe") + Storable::lookup_default(b"sta\0spe") } /// The current era index. pub fn current_era() -> BlockNumber { - Storage::into(b"sta\0era") + Storable::lookup_default(b"sta\0era") } /// The current era index. @@ -35,7 +35,7 @@ pub fn set_current_era(new: BlockNumber) { /// The block number at which the era length last changed. pub fn last_era_length_change() -> BlockNumber { - Storage::into(b"sta\0lec") + Storable::lookup_default(b"sta\0lec") } /// Set a new era length. Won't kick in until the next era change (at current length). @@ -51,7 +51,7 @@ fn next_era() { set_current_era(current_era() + 1); // Enact era length change. - let next_spe: u64 = Storage::into(b"sta\0nse"); + let next_spe: u64 = Storable::lookup_default(b"sta\0nse"); if next_spe > 0 && next_spe != sessions_per_era() { next_spe.store(b"sta\0spe"); system::block_number().store(b"sta\0lec"); @@ -63,16 +63,16 @@ fn next_era() { /// The balance of a given account. pub fn balance_inactive(who: &AccountID) -> Balance { - Storage::into(&who.to_keyed_vec(b"sta\0bal\0")) + Storable::lookup_default(&who.to_keyed_vec(b"sta\0bal\0")) } /// Transfer some unlocked staking balance to another staker. pub fn transfer_inactive(transactor: &AccountID, dest: &AccountID, value: Balance) { let from_key = transactor.to_keyed_vec(b"sta\0bal\0"); - let from_balance: Balance = Storage::into(&from_key); + let from_balance: Balance = Storable::lookup_default(&from_key); assert!(from_balance >= value); let to_key = dest.to_keyed_vec(b"sta\0bal\0"); - let to_balance: Balance = Storage::into(&to_key); + let to_balance: Balance = Storable::lookup_default(&to_key); assert!(to_balance + value > to_balance); // no overflow (from_balance - value).store(&from_key); (to_balance + value).store(&to_key); diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index d7abd1835ad1d..f6be199625d5c 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -1,6 +1,6 @@ use primitives::{Block, BlockNumber, Hash, UncheckedTransaction, TxOrder, Hashable}; use runtime_support::{Vec, swap}; -use storage::Storage; +use storable::Storable; use keyedvec::KeyedVec; use environment::with_env; use runtime::session; @@ -12,7 +12,7 @@ pub fn block_number() -> BlockNumber { /// Get the block hash of a given block (uses storage). pub fn block_hash(number: BlockNumber) -> Hash { - Storage::into(&number.to_keyed_vec(b"sys\0old\0")) + Storable::lookup_default(&number.to_keyed_vec(b"sys\0old\0")) } /// Deposits a log and ensures it matches the blocks log data. @@ -69,7 +69,7 @@ pub fn execute_transaction(utx: &UncheckedTransaction) { // check nonce let nonce_key = tx.signed.to_keyed_vec(b"sys\0non\0"); - let expected_nonce: TxOrder = Storage::into(&nonce_key); + let expected_nonce: TxOrder = Storable::lookup_default(&nonce_key); assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce"); // increment nonce in storage diff --git a/wasm-runtime/polkadot/src/runtime/timestamp.rs b/wasm-runtime/polkadot/src/runtime/timestamp.rs index e0f3d2c04e7ec..2232843b07da5 100644 --- a/wasm-runtime/polkadot/src/runtime/timestamp.rs +++ b/wasm-runtime/polkadot/src/runtime/timestamp.rs @@ -1,8 +1,8 @@ use primitives::Timestamp; -use storage::Storage; +use storable::Storable; pub fn get() -> Timestamp { - Storage::into(b"tim\0val") + Storable::lookup_default(b"tim\0val") } pub fn set(now: Timestamp) { diff --git a/wasm-runtime/polkadot/src/support/mod.rs b/wasm-runtime/polkadot/src/support/mod.rs index e4dae46c40636..802476cc1b1e2 100644 --- a/wasm-runtime/polkadot/src/support/mod.rs +++ b/wasm-runtime/polkadot/src/support/mod.rs @@ -1,8 +1,7 @@ pub mod primitives; pub mod function; pub mod environment; -pub mod storage; -pub mod storagevec; +pub mod storable; #[cfg(test)] pub mod statichex; diff --git a/wasm-runtime/polkadot/src/support/storable.rs b/wasm-runtime/polkadot/src/support/storable.rs new file mode 100644 index 0000000000000..7d45587338f33 --- /dev/null +++ b/wasm-runtime/polkadot/src/support/storable.rs @@ -0,0 +1,62 @@ +use slicable::Slicable; +use endiansensitive::EndianSensitive; +use keyedvec::KeyedVec; +use runtime_support; + +pub trait Storable { + fn lookup_default(key: &[u8]) -> Self where Self: Sized + Default { Self::lookup(key).unwrap_or_else(Default::default) } + fn lookup(_key: &[u8]) -> Option where Self: Sized { unimplemented!() } + fn store(&self, key: &[u8]); +} + +pub fn kill(key: &[u8]) { runtime_support::set_storage(key, b""); } + +impl Storable for T { + fn lookup(key: &[u8]) -> Option { + Slicable::set_as_slice(|out| runtime_support::read_storage(key, out) == out.len()) + } + fn store(&self, key: &[u8]) { + self.as_slice_then(|slice| runtime_support::set_storage(key, slice)); + } +} + +impl Storable for [u8] { + fn store(&self, key: &[u8]) { + runtime_support::set_storage(key, self) + } +} + +/// A trait to conveniently store a vector of storable data. +// TODO: add iterator support +pub trait StorageVec { + type Item: Default + Sized + Storable; + const PREFIX: &'static [u8]; + + /// Get the current set of items. + fn items() -> Vec { + (0..Self::count()).into_iter().map(Self::item).collect() + } + + /// Set the current set of items. + fn set_items(items: &[Self::Item]) { + Self::set_count(items.len() as u32); + items.iter().enumerate().for_each(|(v, ref i)| Self::set_item(v as u32, i)); + } + + fn set_item(index: u32, item: &Self::Item) { + item.store(&index.to_keyed_vec(Self::PREFIX)); + } + + fn item(index: u32) -> Self::Item { + Storable::lookup_default(&index.to_keyed_vec(Self::PREFIX)) + } + + fn set_count(count: u32) { + (count..Self::count()).for_each(|i| Self::set_item(i, &Self::Item::default())); + count.store(&b"len".to_keyed_vec(Self::PREFIX)); + } + + fn count() -> u32 { + Storable::lookup_default(&b"len".to_keyed_vec(Self::PREFIX)) + } +} diff --git a/wasm-runtime/polkadot/src/support/storage.rs b/wasm-runtime/polkadot/src/support/storage.rs deleted file mode 100644 index 7c9696bc11faa..0000000000000 --- a/wasm-runtime/polkadot/src/support/storage.rs +++ /dev/null @@ -1,24 +0,0 @@ -use slicable::Slicable; -use endiansensitive::EndianSensitive; -use runtime_support; - -pub trait Storage { - fn into(key: &[u8]) -> Self where Self: Sized + Default { Self::try_into(key).unwrap_or_else(Default::default) } - fn try_into(_key: &[u8]) -> Option where Self: Sized { unimplemented!() } - fn store(&self, key: &[u8]); -} - -impl Storage for T { - fn try_into(key: &[u8]) -> Option { - Slicable::set_as_slice(|out| runtime_support::read_storage(key, out) == out.len()) - } - fn store(&self, key: &[u8]) { - self.as_slice_then(|slice| runtime_support::set_storage(key, slice)); - } -} - -impl Storage for [u8] { - fn store(&self, key: &[u8]) { - runtime_support::set_storage(key, self) - } -} diff --git a/wasm-runtime/polkadot/src/support/storagevec.rs b/wasm-runtime/polkadot/src/support/storagevec.rs deleted file mode 100644 index ac0ded3a563d2..0000000000000 --- a/wasm-runtime/polkadot/src/support/storagevec.rs +++ /dev/null @@ -1,38 +0,0 @@ -use runtime_support::Vec; -use keyedvec::KeyedVec; -use storage::Storage; - -/// A trait to conveniently store a vector of storable data. -// TODO: add iterator support -pub trait StorageVec { - type Item: Default + Sized + Storage; - const PREFIX: &'static [u8]; - - /// Get the current set of items. - fn items() -> Vec { - (0..Self::count()).into_iter().map(Self::item).collect() - } - - /// Set the current set of items. - fn set_items(items: &[Self::Item]) { - Self::set_count(items.len() as u32); - items.iter().enumerate().for_each(|(v, ref i)| Self::set_item(v as u32, i)); - } - - fn set_item(index: u32, item: &Self::Item) { - item.store(&index.to_keyed_vec(Self::PREFIX)); - } - - fn item(index: u32) -> Self::Item { - Storage::into(&index.to_keyed_vec(Self::PREFIX)) - } - - fn set_count(count: u32) { - (count..Self::count()).for_each(|i| Self::set_item(i, &Self::Item::default())); - count.store(&b"len".to_keyed_vec(Self::PREFIX)); - } - - fn count() -> u32 { - Storage::into(&b"len".to_keyed_vec(Self::PREFIX)) - } -} From 4fde6f0c1bfbf093d87ce63287344f9fc77d6463 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 12:34:51 +0100 Subject: [PATCH 63/76] Test sessions. --- wasm-runtime/polkadot/src/runtime/session.rs | 71 ++++++++++++++++---- wasm-runtime/polkadot/src/runtime/staking.rs | 26 +++---- wasm-runtime/polkadot/src/runtime/system.rs | 7 +- 3 files changed, 73 insertions(+), 31 deletions(-) diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs index 66309becafcf7..ee88937ead62e 100644 --- a/wasm-runtime/polkadot/src/runtime/session.rs +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -40,27 +40,20 @@ pub fn length() -> BlockNumber { Storable::lookup_default(b"ses\0bps") } -/// Hook to be called prior to transaction processing. -pub fn pre_transactions() { - staking::pre_transactions(); -} - -/// Hook to be called after to transaction processing. -pub fn post_transactions() { - staking::post_transactions(); - +/// Hook to be called after transaction processing. +pub fn check_rotate_session() { // do this last, after the staking system has had chance to switch out the authorities for the // new set. // check block number and call next_session if necessary. if system::block_number() % length() == 0 { - next_session(); + rotate_session(); } } -// PRIVATE (not available) +// PRIVATE (not available for use externally) /// Move onto next session: register the new authority set. -fn next_session() { +fn rotate_session() { validators().iter().enumerate().for_each(|(i, v)| { let k = v.to_keyed_vec(b"ses\0nxt\0"); if let Some(n) = Storable::lookup(&k) { @@ -70,4 +63,56 @@ fn next_session() { }); } -// TODO: tests +#[cfg(test)] +mod tests { + use runtime_support::with_externalities; + use keyedvec::KeyedVec; + use joiner::Joiner; + use testing::{one, two, TestExternalities}; + use primitives::AccountID; + use runtime::{consensus, session}; + use environment::with_env; + + #[test] + fn session_change_should_work() { + let mut t = TestExternalities { storage: map![ + b"ses\0bps".to_vec() => vec![].join(&2u64), + // the validators (10, 20, ...) + b"ses\0key\0len".to_vec() => vec![].join(&2u32), + 0u32.to_keyed_vec(b"ses\0key\0") => vec![10; 32], + 1u32.to_keyed_vec(b"ses\0key\0") => vec![20; 32], + // initial session keys (11, 21, ...) + b"con\0aut\0len".to_vec() => vec![].join(&2u32), + 0u32.to_keyed_vec(b"con\0aut\0") => vec![11; 32], + 1u32.to_keyed_vec(b"con\0aut\0") => vec![21; 32] + ], }; + with_externalities(&mut t, || { + assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); + assert_eq!(session::length(), 2u64); + assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]); + + // Block 1: No change + with_env(|e| e.block_number = 1); + session::check_rotate_session(); + assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); + + // Block 2: Session rollover, but no change. + with_env(|e| e.block_number = 2); + session::check_rotate_session(); + assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); + + // Block 3: Set new key for validator 2; no visible change. + with_env(|e| e.block_number = 3); + session::set_key(&[20; 32], &[22; 32]); + assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); + + session::check_rotate_session(); + assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); + + // Block 4: Session rollover, authority 2 changes. + with_env(|e| e.block_number = 4); + session::check_rotate_session(); + assert_eq!(consensus::authorities(), vec![[11u8; 32], [22u8; 32]]); + }); + } +} diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index 29d6ac0272b9d..127b7041ad1aa 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -46,7 +46,7 @@ pub fn set_sessions_per_era(new: BlockNumber) { /// The era has changed - enact new staking set. /// /// NOTE: This always happens on a session change. -fn next_era() { +fn new_era() { // Increment current era. set_current_era(current_era() + 1); @@ -92,15 +92,11 @@ pub fn unstake(_transactor: &AccountID) { // TODO: record the desire for `_transactor` to deactivate their stake. } -/// Hook to be called prior to transaction processing. -pub fn pre_transactions() { -} - /// Hook to be called after to transaction processing. -pub fn post_transactions() { - // check block number and call next_era if necessary. +pub fn check_new_era() { + // check block number and call new_era if necessary. if (system::block_number() - last_era_length_change()) % era_length() == 0 { - next_era(); + new_era(); } } @@ -128,14 +124,14 @@ mod tests { // Block 1: No change. with_env(|e| e.block_number = 1); - staking::post_transactions(); + staking::check_new_era(); assert_eq!(staking::sessions_per_era(), 2u64); assert_eq!(staking::last_era_length_change(), 0u64); assert_eq!(staking::current_era(), 0u64); // Block 2: Simple era change. with_env(|e| e.block_number = 2); - staking::post_transactions(); + staking::check_new_era(); assert_eq!(staking::sessions_per_era(), 2u64); assert_eq!(staking::last_era_length_change(), 0u64); assert_eq!(staking::current_era(), 1u64); @@ -143,35 +139,35 @@ mod tests { // Block 3: Schedule an era length change; no visible changes. with_env(|e| e.block_number = 3); staking::set_sessions_per_era(3); - staking::post_transactions(); + staking::check_new_era(); assert_eq!(staking::sessions_per_era(), 2u64); assert_eq!(staking::last_era_length_change(), 0u64); assert_eq!(staking::current_era(), 1u64); // Block 4: Era change kicks in. with_env(|e| e.block_number = 4); - staking::post_transactions(); + staking::check_new_era(); assert_eq!(staking::sessions_per_era(), 3u64); assert_eq!(staking::last_era_length_change(), 4u64); assert_eq!(staking::current_era(), 2u64); // Block 5: No change. with_env(|e| e.block_number = 5); - staking::post_transactions(); + staking::check_new_era(); assert_eq!(staking::sessions_per_era(), 3u64); assert_eq!(staking::last_era_length_change(), 4u64); assert_eq!(staking::current_era(), 2u64); // Block 6: No change. with_env(|e| e.block_number = 6); - staking::post_transactions(); + staking::check_new_era(); assert_eq!(staking::sessions_per_era(), 3u64); assert_eq!(staking::last_era_length_change(), 4u64); assert_eq!(staking::current_era(), 2u64); // Block 7: Era increment. with_env(|e| e.block_number = 7); - staking::post_transactions(); + staking::check_new_era(); assert_eq!(staking::sessions_per_era(), 3u64); assert_eq!(staking::last_era_length_change(), 4u64); assert_eq!(staking::current_era(), 3u64); diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index f6be199625d5c..0b3b8a590ba3b 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -3,7 +3,7 @@ use runtime_support::{Vec, swap}; use storable::Storable; use keyedvec::KeyedVec; use environment::with_env; -use runtime::session; +use runtime::{staking, session}; /// The current block number being processed. Set by `execute_block`. pub fn block_number() -> BlockNumber { @@ -48,9 +48,10 @@ pub fn execute_block(mut block: Block) { header.keccak256().store(&header_hash_key); // execute transactions - session::pre_transactions(); block.transactions.iter().for_each(execute_transaction); - session::post_transactions(); + + staking::check_new_era(); + session::check_rotate_session(); // any final checks final_checks(&block); From 9c8cafd397fbb0f79ec12e66d41cbec091ae0c6b Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 14:17:56 +0100 Subject: [PATCH 64/76] Introduce better hashing. - Blake2 for secure hashing - XX for fast hashing --- Cargo.lock | 41 +++++++- executor/Cargo.toml | 1 - executor/src/lib.rs | 1 - executor/src/wasm_executor.rs | 66 ++++++++++-- native-runtime/support/Cargo.toml | 1 - native-runtime/support/src/lib.rs | 3 +- primitives/Cargo.toml | 4 +- primitives/src/ed25519.rs | 65 ++++++------ primitives/src/hash.rs | 4 +- primitives/src/lib.rs | 94 +++++++++++++++++- state_machine/Cargo.toml | 1 - state_machine/src/lib.rs | 1 - wasm-runtime/polkadot/src/runtime/session.rs | 16 +-- wasm-runtime/polkadot/src/runtime/staking.rs | 10 +- wasm-runtime/polkadot/src/runtime/system.rs | 6 +- .../polkadot/src/runtime/timestamp.rs | 4 +- .../polkadot/src/support/primitives.rs | 16 ++- wasm-runtime/polkadot/src/support/storable.rs | 10 +- wasm-runtime/support/src/lib.rs | 30 +++++- .../release/runtime_polkadot.compact.wasm | Bin 5276 -> 18522 bytes .../release/runtime_polkadot.wasm | Bin 5364 -> 18609 bytes .../release/runtime_test.compact.wasm | Bin 962 -> 1460 bytes .../release/runtime_test.wasm | Bin 1079 -> 1576 bytes wasm-runtime/test/src/lib.rs | 17 +++- 24 files changed, 300 insertions(+), 91 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7d5f50ddc46ae..72a5687799783 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,14 @@ dependencies = [ "odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "arrayvec" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "assert_matches" version = "1.1.0" @@ -90,6 +98,15 @@ name = "bitflags" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "byteorder" version = "1.1.0" @@ -138,6 +155,11 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "constant_time_eq" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "crunchy" version = "0.1.6" @@ -710,13 +732,14 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "polkadot-primitives" version = "0.1.0" dependencies = [ + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "fixed-hash 0.1.0 (git+https://github.com/paritytech/primitives.git)", "polkadot-serializer 0.1.0", @@ -725,7 +748,7 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.1.0 (git+https://github.com/paritytech/primitives.git)", "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -767,7 +790,6 @@ version = "0.1.0" dependencies = [ "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", @@ -898,7 +920,6 @@ dependencies = [ "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", "polkadot-state-machine 0.1.0", - "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1151,6 +1172,14 @@ dependencies = [ "rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "twox-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "uint" version = "0.1.0" @@ -1235,6 +1264,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" "checksum arrayvec 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e003cbf6e0e1c43a0fc8df2ea8ea24174514d35cbcf60c35ca6112e0139f65e2" +"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum assert_matches 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e772942dccdf11b368c31e044e4fca9189f80a773d2f0808379de65894cbf57" "checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860" "checksum backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99f2ce94e22b8e664d95c57fff45b98a966c2252b60691d0b7aeeccd88d70983" @@ -1243,12 +1273,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5442186ef6560f30f1ee4b9c1e4c87a35a6879d3644550cc248ec2b955eb5fcd" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" +"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" "checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" "checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6" "checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b8c532887f1a292d17de05ae858a8fe50a301e196f9ef0ddb7ccd0d1d00f180" "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd" +"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8" @@ -1351,6 +1383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" "checksum triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9291c7f0fae44858b5e087dd462afb382354120003778f1695b44aab98c7abd7" +"checksum twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "475352206e7a290c5fccc27624a163e8d0d115f7bb60ca18a64fc9ce056d7435" "checksum uint 0.1.0 (git+https://github.com/paritytech/primitives.git)" = "" "checksum unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e01da42520092d0cd2d6ac3ae69eb21a22ad43ff195676b86f8c37f487d6b80" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" diff --git a/executor/Cargo.toml b/executor/Cargo.toml index 2d124f60ac323..0401bd4c771f8 100644 --- a/executor/Cargo.toml +++ b/executor/Cargo.toml @@ -12,7 +12,6 @@ serde = "1.0" serde_derive = "1.0" parity-wasm = "0.15.0" byteorder = "1.1" -tiny-keccak = "1.3" rustc-hex = "1.0.0" [dev-dependencies] diff --git a/executor/src/lib.rs b/executor/src/lib.rs index 3c54d25efb216..f1da582538744 100644 --- a/executor/src/lib.rs +++ b/executor/src/lib.rs @@ -33,7 +33,6 @@ extern crate polkadot_state_machine as state_machine; extern crate serde; extern crate parity_wasm; extern crate byteorder; -extern crate tiny_keccak; extern crate rustc_hex; #[macro_use] diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index 07056b1df7016..c0c638fa3d6d2 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -26,8 +26,7 @@ use state_machine::{Externalities, CodeExecutor}; use error::{Error, ErrorKind, Result}; use wasm_utils::{MemoryInstance, UserDefinedElements, AddModuleWithoutFullDependentInstance}; -use tiny_keccak; -use primitives::ed25519; +use primitives::{ed25519, blake2_256, twox_128, twox_256}; struct Heap { end: u32, @@ -141,10 +140,28 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, ext_chain_id() -> u64 => { this.ext.chain_id() }, - ext_keccak256(data: *const u8, len: u32, out: *mut u8) => { + ext_twox_128(data: *const u8, len: u32, out: *mut u8) => { let result = if let Ok(value) = this.memory.get(data, len as usize) { - tiny_keccak::keccak256(&value) + twox_128(&value) + } else { + [0; 16] + }; + let _ = this.memory.set(out, &result); + }, + ext_twox_256(data: *const u8, len: u32, out: *mut u8) => { + let result = + if let Ok(value) = this.memory.get(data, len as usize) { + twox_256(&value) + } else { + [0; 32] + }; + let _ = this.memory.set(out, &result); + }, + ext_blake2_256(data: *const u8, len: u32, out: *mut u8) => { + let result = + if let Ok(value) = this.memory.get(data, len as usize) { + blake2_256(&value) } else { [0; 32] }; @@ -223,6 +240,7 @@ mod tests { use super::*; use rustc_hex::FromHex; + use primitives::ed25519::hexdisplay::HexDisplay; #[derive(Debug, Default)] struct TestExternalities { @@ -261,16 +279,44 @@ mod tests { } #[test] - fn keccak256_should_work() { + fn blake2_256_should_work() { + let mut ext = TestExternalities::default(); + let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); + assert_eq!( + WasmExecutor.call(&mut ext, &test_code[..], "test_blake2_256", &CallData(b"".to_vec())).unwrap(), + FromHex::from_hex("0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8").unwrap() + ); + assert_eq!( + WasmExecutor.call(&mut ext, &test_code[..], "test_blake2_256", &CallData(b"Hello world!".to_vec())).unwrap(), + FromHex::from_hex("3fbc092db9350757e2ab4f7ee9792bfcd2f5220ada5a4bc684487f60c6034369").unwrap() + ); + } + + #[test] + fn twox_256_should_work() { + let mut ext = TestExternalities::default(); + let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); + assert_eq!( + WasmExecutor.call(&mut ext, &test_code[..], "test_twox_256", &CallData(b"".to_vec())).unwrap(), + FromHex::from_hex("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a").unwrap() + ); + assert_eq!( + WasmExecutor.call(&mut ext, &test_code[..], "test_twox_256", &CallData(b"Hello world!".to_vec())).unwrap(), + FromHex::from_hex("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74").unwrap() + ); + } + + #[test] + fn twox_128_should_work() { let mut ext = TestExternalities::default(); let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); assert_eq!( - WasmExecutor.call(&mut ext, &test_code[..], "test_keccak256", &CallData(b"".to_vec())).unwrap(), - FromHex::from_hex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap() + WasmExecutor.call(&mut ext, &test_code[..], "test_twox_128", &CallData(b"".to_vec())).unwrap(), + FromHex::from_hex("99e9d85137db46ef4bbea33613baafd5").unwrap() ); assert_eq!( - WasmExecutor.call(&mut ext, &test_code[..], "test_keccak256", &CallData(b"Hello world!".to_vec())).unwrap(), - FromHex::from_hex("ecd0e108a98e192af1d2c25055f4e3bed784b5c877204e73219a5203251feaab").unwrap() + WasmExecutor.call(&mut ext, &test_code[..], "test_twox_128", &CallData(b"Hello world!".to_vec())).unwrap(), + FromHex::from_hex("b27dfd7f223f177f2a13647b533599af").unwrap() ); } @@ -278,7 +324,7 @@ mod tests { fn ed25519_verify_should_work() { let mut ext = TestExternalities::default(); let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); - let key = ed25519::Pair::from_seed(&tiny_keccak::keccak256(b"test")); + let key = ed25519::Pair::from_seed(&blake2_256(b"test")); let sig = key.sign(b"all ok!"); let mut calldata = vec![]; calldata.extend_from_slice(key.public().as_ref()); diff --git a/native-runtime/support/Cargo.toml b/native-runtime/support/Cargo.toml index f576037bd2c7d..1c24c014e64f5 100644 --- a/native-runtime/support/Cargo.toml +++ b/native-runtime/support/Cargo.toml @@ -11,5 +11,4 @@ lazy_static = "1.0.0" parking_lot = "0.5" polkadot-state-machine = { path = "../../state_machine" , version = "0.1" } environmental = { path = "../../environmental", version = "0.1.0" } -tiny-keccak = "1.3" polkadot-primitives = { path = "../../primitives", version = "0.1.0" } diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index aaa323f98ddd9..caa7f3b272fcf 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -1,7 +1,6 @@ #[macro_use] extern crate environmental; extern crate polkadot_state_machine; -extern crate tiny_keccak; extern crate polkadot_primitives as primitives; use std::fmt; @@ -76,7 +75,7 @@ pub fn chain_id() -> u64 { } /// Conduct a Keccak-256 hash of the given data. -pub use tiny_keccak::keccak256; +pub use primitives::{blake2_256, twox_128, twox_256}; /// Verify a ed25519 signature. pub fn ed25519_verify(sig: &[u8; 64], msg: &[u8], pubkey: &[u8; 32]) -> bool { diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 045afba827c76..77eccdea883e8 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -9,10 +9,12 @@ fixed-hash = { git = "https://github.com/paritytech/primitives.git" } rustc-hex = "1.0" serde = "1.0" serde_derive = "1.0" -tiny-keccak = "1.3" uint = { git = "https://github.com/paritytech/primitives.git" } ring = "0.12" untrusted = "0.5" +twox-hash = "1.1.0" +byteorder = "1.1" +blake2-rfc = "0.2.18" [dev-dependencies] polkadot-serializer = { path = "../serializer", version = "0.1" } diff --git a/primitives/src/ed25519.rs b/primitives/src/ed25519.rs index 2630f858d22ef..e9ac7e473c4f9 100644 --- a/primitives/src/ed25519.rs +++ b/primitives/src/ed25519.rs @@ -166,44 +166,53 @@ impl PartialEq for Signature { } } -#[cfg(test)] -mod test { - use super::*; +pub mod hexdisplay { -pub struct HexDisplay<'a>(&'a [u8]); + pub struct HexDisplay<'a>(&'a [u8]); -impl<'a> HexDisplay<'a> { - pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) } -} + impl<'a> HexDisplay<'a> { + pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) } + } -impl<'a> ::std::fmt::Display for HexDisplay<'a> { - fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - for byte in self.0 { - try!( fmtr.write_fmt(format_args!("{:02x}", byte))); + impl<'a> ::std::fmt::Display for HexDisplay<'a> { + fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + for byte in self.0 { + try!( fmtr.write_fmt(format_args!("{:02x}", byte))); + } + Ok(()) } - Ok(()) } -} -pub trait AsBytesRef { - fn as_bytes_ref(&self) -> &[u8]; -} + pub trait AsBytesRef { + fn as_bytes_ref(&self) -> &[u8]; + } -impl AsBytesRef for [u8] { - fn as_bytes_ref(&self) -> &[u8] { &self } -} + impl AsBytesRef for [u8] { + fn as_bytes_ref(&self) -> &[u8] { &self } + } + + impl AsBytesRef for Vec { + fn as_bytes_ref(&self) -> &[u8] { &self } + } + + macro_rules! impl_non_endians { + ( $( $t:ty ),* ) => { $( + impl AsBytesRef for $t { + fn as_bytes_ref(&self) -> &[u8] { &self[..] } + } + )* } + } + + impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], + [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], + [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); -macro_rules! impl_non_endians { - ( $( $t:ty ),* ) => { $( - impl AsBytesRef for $t { - fn as_bytes_ref(&self) -> &[u8] { &self[..] } - } - )* } } -impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], - [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], - [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); +#[cfg(test)] +mod test { + use super::*; + use super::hexdisplay::HexDisplay; #[test] fn test_vector_should_work() { diff --git a/primitives/src/hash.rs b/primitives/src/hash.rs index cef573f6f29b1..0b56d5757fafb 100644 --- a/primitives/src/hash.rs +++ b/primitives/src/hash.rs @@ -41,8 +41,8 @@ impl_hash!(H160, 20); impl_serde!(H160, 20); impl_hash!(H256, 32); impl_serde!(H256, 32); -impl_hash!(H520, 65); -impl_serde!(H520, 65); +impl_hash!(H512, 64); +impl_serde!(H512, 64); #[cfg(test)] mod tests { diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index fc266582004f6..cb7606add2f4d 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -20,9 +20,11 @@ extern crate rustc_hex; extern crate serde; -extern crate tiny_keccak; extern crate ring; extern crate untrusted; +extern crate twox_hash; +extern crate byteorder; +extern crate blake2_rfc; #[macro_use] extern crate crunchy; @@ -53,12 +55,98 @@ pub mod ed25519; /// Alias to 160-bit hash when used in the context of an account address. pub type Address = hash::H160; /// Alias to 520-bit hash when used in the context of a signature. -pub type Signature = hash::H520; +pub type Signature = hash::H512; pub use self::hash::{H160, H256}; pub use self::uint::{U256, U512}; /// A hash function. pub fn hash(data: &[u8]) -> hash::H256 { - tiny_keccak::keccak256(data).into() + blake2_256(data).into() +} + +/// Do a Blake2 512-bit hash and place result in `dest`. +pub fn blake2_512_into(data: &[u8], dest: &mut[u8; 64]) { + dest.copy_from_slice(blake2_rfc::blake2b::blake2b(64, &[], data).as_bytes()); +} + +/// Do a Blake2 512-bit hash and return result. +pub fn blake2_512(data: &[u8]) -> [u8; 64] { + let mut r: [u8; 64] = unsafe { std::mem::uninitialized() }; + blake2_512_into(data, &mut r); + r +} + +/// Do a Blake2 256-bit hash and place result in `dest`. +pub fn blake2_256_into(data: &[u8], dest: &mut[u8; 32]) { + dest.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes()); +} + +/// Do a Blake2 256-bit hash and return result. +pub fn blake2_256(data: &[u8]) -> [u8; 32] { + let mut r: [u8; 32] = unsafe { std::mem::uninitialized() }; + blake2_256_into(data, &mut r); + r +} + +/// Do a Blake2 128-bit hash and place result in `dest`. +pub fn blake2_128_into(data: &[u8], dest: &mut[u8; 16]) { + dest.copy_from_slice(blake2_rfc::blake2b::blake2b(16, &[], data).as_bytes()); +} + +/// Do a Blake2 128-bit hash and return result. +pub fn blake2_128(data: &[u8]) -> [u8; 16] { + let mut r: [u8; 16] = unsafe { std::mem::uninitialized() }; + blake2_128_into(data, &mut r); + r +} + +/// Do a XX 128-bit hash and place result in `dest`. +pub fn twox_128_into(data: &[u8], dest: &mut [u8; 16]) { + use ::std::hash::Hasher; + let mut h0 = twox_hash::XxHash::with_seed(0); + let mut h1 = twox_hash::XxHash::with_seed(1); + h0.write(data); + h1.write(data); + let r0 = h0.finish(); + let r1 = h1.finish(); + use byteorder::{ByteOrder, LittleEndian}; + LittleEndian::write_u64(&mut dest[0..8], r0); + LittleEndian::write_u64(&mut dest[8..16], r1); +} + +/// Do a XX 128-bit hash and return result. +pub fn twox_128(data: &[u8]) -> [u8; 16] { + let mut r: [u8; 16] = unsafe { std::mem::uninitialized() }; + twox_128_into(data, &mut r); + r +} + +/// Do a XX 256-bit hash and place result in `dest`. +pub fn twox_256_into(data: &[u8], dest: &mut [u8; 32]) { + use ::std::hash::Hasher; + use byteorder::{ByteOrder, LittleEndian}; + let mut h0 = twox_hash::XxHash::with_seed(0); + let mut h1 = twox_hash::XxHash::with_seed(1); + let mut h2 = twox_hash::XxHash::with_seed(2); + let mut h3 = twox_hash::XxHash::with_seed(3); + h0.write(data); + h1.write(data); + h2.write(data); + h3.write(data); + let r0 = h0.finish(); + let r1 = h1.finish(); + let r2 = h2.finish(); + let r3 = h3.finish(); + LittleEndian::write_u64(&mut dest[0..8], r0); + LittleEndian::write_u64(&mut dest[8..16], r1); + LittleEndian::write_u64(&mut dest[16..24], r2); + LittleEndian::write_u64(&mut dest[24..32], r3); +} + +/// Do a XX 256-bit hash and return result. +pub fn twox_256(data: &[u8]) -> [u8; 32] { + let mut r: [u8; 32] = unsafe { std::mem::uninitialized() }; + twox_256_into(data, &mut r); + r } diff --git a/state_machine/Cargo.toml b/state_machine/Cargo.toml index a0d25c821cb4b..458bae8e1efe4 100644 --- a/state_machine/Cargo.toml +++ b/state_machine/Cargo.toml @@ -7,7 +7,6 @@ description = "Polkadot State Machine" [dependencies] polkadot-primitives = { path = "../primitives", version = "0.1.0" } hashdb = "0.1.1" -keccak-hash = "0.1.0" patricia-trie = "0.1.0" memorydb = "0.1.1" triehash = "0.1" diff --git a/state_machine/src/lib.rs b/state_machine/src/lib.rs index 91622c9bc42d6..cee96a36ad3ff 100644 --- a/state_machine/src/lib.rs +++ b/state_machine/src/lib.rs @@ -22,7 +22,6 @@ extern crate polkadot_primitives as primitives; extern crate hashdb; extern crate memorydb; -extern crate keccak_hash; extern crate patricia_trie; extern crate triehash; diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs index ee88937ead62e..412809d6b8921 100644 --- a/wasm-runtime/polkadot/src/runtime/session.rs +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -65,7 +65,7 @@ fn rotate_session() { #[cfg(test)] mod tests { - use runtime_support::with_externalities; + use runtime_support::{with_externalities, twox_128}; use keyedvec::KeyedVec; use joiner::Joiner; use testing::{one, two, TestExternalities}; @@ -76,15 +76,15 @@ mod tests { #[test] fn session_change_should_work() { let mut t = TestExternalities { storage: map![ - b"ses\0bps".to_vec() => vec![].join(&2u64), + twox_128(b"ses\0bps").to_vec() => vec![].join(&2u64), // the validators (10, 20, ...) - b"ses\0key\0len".to_vec() => vec![].join(&2u32), - 0u32.to_keyed_vec(b"ses\0key\0") => vec![10; 32], - 1u32.to_keyed_vec(b"ses\0key\0") => vec![20; 32], + twox_128(b"ses\0key\0len").to_vec() => vec![].join(&2u32), + twox_128(&0u32.to_keyed_vec(b"ses\0key\0")).to_vec() => vec![10; 32], + twox_128(&1u32.to_keyed_vec(b"ses\0key\0")).to_vec() => vec![20; 32], // initial session keys (11, 21, ...) - b"con\0aut\0len".to_vec() => vec![].join(&2u32), - 0u32.to_keyed_vec(b"con\0aut\0") => vec![11; 32], - 1u32.to_keyed_vec(b"con\0aut\0") => vec![21; 32] + twox_128(b"con\0aut\0len").to_vec() => vec![].join(&2u32), + twox_128(&0u32.to_keyed_vec(b"con\0aut\0")).to_vec() => vec![11; 32], + twox_128(&1u32.to_keyed_vec(b"con\0aut\0")).to_vec() => vec![21; 32] ], }; with_externalities(&mut t, || { assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index 127b7041ad1aa..f3bae420600ee 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -102,7 +102,7 @@ pub fn check_new_era() { #[cfg(test)] mod tests { - use runtime_support::with_externalities; + use runtime_support::{with_externalities, twox_128}; use keyedvec::KeyedVec; use joiner::Joiner; use testing::{one, two, TestExternalities}; @@ -113,8 +113,8 @@ mod tests { #[test] fn staking_eras_work() { let mut t = TestExternalities { storage: map![ - b"ses\0bps".to_vec() => vec![].join(&1u64), - b"sta\0spe".to_vec() => vec![].join(&2u64) + twox_128(b"ses\0bps").to_vec() => vec![].join(&1u64), + twox_128(b"sta\0spe").to_vec() => vec![].join(&2u64) ], }; with_externalities(&mut t, || { assert_eq!(staking::era_length(), 2u64); @@ -180,7 +180,7 @@ mod tests { let two = two(); let mut t = TestExternalities { storage: map![ - one.to_keyed_vec(b"sta\0bal\0") => vec![].join(&42u64) + twox_128(&one.to_keyed_vec(b"sta\0bal\0")).to_vec() => vec![].join(&42u64) ], }; with_externalities(&mut t, || { @@ -195,7 +195,7 @@ mod tests { let two = two(); let mut t = TestExternalities { storage: map![ - one.to_keyed_vec(b"sta\0bal\0") => vec![].join(&111u64) + twox_128(&one.to_keyed_vec(b"sta\0bal\0")).to_vec() => vec![].join(&111u64) ], }; with_externalities(&mut t, || { diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index 0b3b8a590ba3b..0bf300d2b3b16 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -45,7 +45,7 @@ pub fn execute_block(mut block: Block) { // store the header hash in storage. let header_hash_key = header.number.to_keyed_vec(b"sys\0old\0"); - header.keccak256().store(&header_hash_key); + header.blake2_256().store(&header_hash_key); // execute transactions block.transactions.iter().for_each(execute_transaction); @@ -97,7 +97,7 @@ mod tests { use function::Function; use keyedvec::KeyedVec; use slicable::Slicable; - use runtime_support::with_externalities; + use runtime_support::{with_externalities, twox_128}; use primitives::{UncheckedTransaction, Transaction}; use statichex::StaticHexInto; use runtime::{system, staking}; @@ -109,7 +109,7 @@ mod tests { let two = two(); let mut t = TestExternalities { storage: map![ - one.to_keyed_vec(b"sta\0bal\0") => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + twox_128(&one.to_keyed_vec(b"sta\0bal\0")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ], }; let tx = UncheckedTransaction { diff --git a/wasm-runtime/polkadot/src/runtime/timestamp.rs b/wasm-runtime/polkadot/src/runtime/timestamp.rs index 2232843b07da5..10708a5a3cb69 100644 --- a/wasm-runtime/polkadot/src/runtime/timestamp.rs +++ b/wasm-runtime/polkadot/src/runtime/timestamp.rs @@ -13,14 +13,14 @@ pub fn set(now: Timestamp) { mod tests { use joiner::Joiner; use keyedvec::KeyedVec; - use runtime_support::with_externalities; + use runtime_support::{with_externalities, twox_128}; use runtime::timestamp; use testing::TestExternalities; #[test] fn timestamp_works() { let mut t = TestExternalities { storage: map![ - b"tim\0val".to_vec() => vec![].join(&42u64) + twox_128(b"tim\0val").to_vec() => vec![].join(&42u64) ], }; with_externalities(&mut t, || { diff --git a/wasm-runtime/polkadot/src/support/primitives.rs b/wasm-runtime/polkadot/src/support/primitives.rs index ecac3fbbd48e8..fb983bf84ea7b 100644 --- a/wasm-runtime/polkadot/src/support/primitives.rs +++ b/wasm-runtime/polkadot/src/support/primitives.rs @@ -3,7 +3,7 @@ use streamreader::StreamReader; use joiner::Joiner; use slicable::{Slicable, NonTrivialSlicable}; use function::Function; -use runtime_support::{size_of, keccak256, ed25519_verify}; +use runtime_support::{size_of, blake2_256, twox_128, twox_256, ed25519_verify}; #[cfg(test)] use std::fmt; @@ -109,12 +109,20 @@ impl Slicable for Transaction { } pub trait Hashable: Sized { - fn keccak256(&self) -> [u8; 32]; + fn blake2_256(&self) -> [u8; 32]; + fn twox_128(&self) -> [u8; 16]; + fn twox_256(&self) -> [u8; 32]; } impl Hashable for T { - fn keccak256(&self) -> [u8; 32] { - keccak256(&self.to_vec()) + fn blake2_256(&self) -> [u8; 32] { + blake2_256(&self.to_vec()) + } + fn twox_128(&self) -> [u8; 16] { + twox_128(&self.to_vec()) + } + fn twox_256(&self) -> [u8; 32] { + twox_256(&self.to_vec()) } } diff --git a/wasm-runtime/polkadot/src/support/storable.rs b/wasm-runtime/polkadot/src/support/storable.rs index 7d45587338f33..177475b2d7395 100644 --- a/wasm-runtime/polkadot/src/support/storable.rs +++ b/wasm-runtime/polkadot/src/support/storable.rs @@ -1,7 +1,7 @@ use slicable::Slicable; use endiansensitive::EndianSensitive; use keyedvec::KeyedVec; -use runtime_support; +use runtime_support::{self, twox_128, Vec}; pub trait Storable { fn lookup_default(key: &[u8]) -> Self where Self: Sized + Default { Self::lookup(key).unwrap_or_else(Default::default) } @@ -9,20 +9,20 @@ pub trait Storable { fn store(&self, key: &[u8]); } -pub fn kill(key: &[u8]) { runtime_support::set_storage(key, b""); } +pub fn kill(key: &[u8]) { runtime_support::set_storage(&twox_128(key)[..], b""); } impl Storable for T { fn lookup(key: &[u8]) -> Option { - Slicable::set_as_slice(|out| runtime_support::read_storage(key, out) == out.len()) + Slicable::set_as_slice(|out| runtime_support::read_storage(&twox_128(key)[..], out) == out.len()) } fn store(&self, key: &[u8]) { - self.as_slice_then(|slice| runtime_support::set_storage(key, slice)); + self.as_slice_then(|slice| runtime_support::set_storage(&twox_128(key)[..], slice)); } } impl Storable for [u8] { fn store(&self, key: &[u8]) { - runtime_support::set_storage(key, self) + runtime_support::set_storage(&twox_128(key)[..], self) } } diff --git a/wasm-runtime/support/src/lib.rs b/wasm-runtime/support/src/lib.rs index 57606a3f1bf6c..bc987ff3964f3 100644 --- a/wasm-runtime/support/src/lib.rs +++ b/wasm-runtime/support/src/lib.rs @@ -29,7 +29,9 @@ extern "C" { fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8; fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32) -> u32; fn ext_chain_id() -> u64; - fn ext_keccak256(data: *const u8, len: u32, out: *mut u8); + fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8); + fn ext_twox_128(data: *const u8, len: u32, out: *mut u8); + fn ext_twox_256(data: *const u8, len: u32, out: *mut u8); fn ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32; } @@ -80,12 +82,32 @@ pub fn chain_id() -> u64 { } } -/// Conduct a keccak256 hash. -pub fn keccak256(data: &[u8]) -> [u8; 32] { +/// Conduct a 256-bit Blake2 hash. +pub fn blake2_256(data: &[u8]) -> [u8; 32] { unsafe { let mut result: [u8; 32] = uninitialized(); // guaranteed to write into result. - ext_keccak256(&data[0], data.len() as u32, &mut result[0]); + ext_blake2_256(&data[0], data.len() as u32, &mut result[0]); + result + } +} + +/// Conduct four XX hashes to give a 256-bit result. +pub fn twox_256(data: &[u8]) -> [u8; 32] { + unsafe { + let mut result: [u8; 32] = uninitialized(); + // guaranteed to write into result. + ext_twox_256(&data[0], data.len() as u32, &mut result[0]); + result + } +} + +/// Conduct two XX hashes to give a 256-bit result. +pub fn twox_128(data: &[u8]) -> [u8; 16] { + unsafe { + let mut result: [u8; 16] = uninitialized(); + // guaranteed to write into result. + ext_twox_128(&data[0], data.len() as u32, &mut result[0]); result } } diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm index 658efc37386ac47900dea844825f63fd7c92c24f..dbc3273e1b506a06521aae4b775386774d7353a8 100644 GIT binary patch literal 18522 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 literal 5276 zcmb_gy>A@H6`z^iy$|l~-QL}vMaL@ME{Na=M34*nc(4S6LqJhn7;e(@DC#0S#V!ieD3cy)$3z9xo1$_U_Dg?;R`-mFB56o_e_V;KAX(GPPj-aR2i!l*fV|YaG{$ zmG5=JK&hb7Y_>e3d|!W#H&3g6^Oudr!}-I*qc4n#=8xz5j~4UYTQGfJtqsff#nIlu z@!tO8-r<1?`$vzC7rVFSckUhRK05f#y@T7T(&DV-*MCV_ zKOY;F`FLu{lXsuYXOSY0OrEvKw|bE^sYT7t-b(}WZ$z3DR-_H`DYzLKYNXAM7m9w` za&saGVv{u^&2#cdvVvEA`d%ERJ~d*+_Do2MniHc03i-jx?^`BXnlG)gIJ$3N>ib!5Vtne^mnygG zInD?#wJ}+(MSp(8mB_%DZW>|Hq#g<3@rYQ`u2!`Oob0Sy?s8Ncj zw`pcu=2XMRGiRegUO6iw*l4bpWi8lf)n?hosopZr*vN@9(yq4<5sa)+v$D%tFcMO$ z6tR(KFmfVDoM$@JE~o7?h+rh5wR0jE=~7sV*vJWtY*U*$g>a3c;whx=s^Ye6=2d(6 zmFeJ3i*Qiwm)ada`veMM2`Tklh@T(=JV8r!ZEVna73gpP#?ux9!^31k4=Y%9s1^D6XRI#=f#GXnPMH6{0!)-moY2+P1my{&hQjyo|4Ah18N{}!wKLFZSL`baUt-c@y~uc;5&*Usyq6>88q zm?Qj4)AW{J#VDs>l$aSMwq@Gsv1w(dW)+!%;~HexagJ(42)}__*>8oAj64ynRs2*Y zqZ3I0N&;~r@qWn~F~yq(={bXmf(`0|aUz(gE60goqAnLPF_Zd?rSd_OHGMb{Y}EAO zM6gj)hS+dq5Hroz%n@@A)vOV78TKl^kagS4#eT&cLB$+MvLeGo4;ePY9axfXeW(l1 zQXip4ej#AQfYQF%wk;GDZad_z#dUj|VloqPEYkFD5h6^*0SGT1o4XmNr8(dM2*+l| zq7&_2ZfEU@`HEjKZa8ZkX{4~WNp1;-ux2CmrMU4(87^NWGit7gQ;ZwvCL`MPPINjz zj_#;*5DL`xIjGoUhE;DsEd%ZlLkq?@btQ}3t3!_G8aa9pL5`7;W3E8%VqZaT*3c0I zhTgas`p`iihOjoE{_nPM9<&UP9+t2o;4pfgf;(~w4N;(JY_9e>MvuF*?*e4_F% zh3E;hru7{q|3l^A%aNV3`_h=TtxAU&jkgUVjsUOEy<&H)RF*K%1UVJmhyq3~(NQ#_ zWMZykh$dz#)~JhZpc>Fhb*B4w<|8nEQwpR#$JqMx^QV1aJ^~zE@b~vxWerQx^TSwTjdtZLuz6u zE|n2AuPSv-FR%+os{?t~w*Jp0Tu4%9q%`pa7cEQ-D6H0xuIj}#{RD~0(Zx?JD%Ekn zv3j2dtLjhmHGRhVXf|9}3xFNgrv9q#8FV}JZhDEjX-pAvx(!kR(1F9qxyOlD>>a

      45kB57@SlpcDVEVlarH} z@Al!2+VVi}7T=ERZvL_x$PF9T$7%pFa6Z!z*c>F;32DgK4YL!H5^f_$gb`BV9kB^L zg&oFf9fdwb8?1PT%Xwy)L%_zg{uCXX)1h<#9e<*D-;JDsVl4*Mf;_QHYy(wfS`zV3 zxohy5#|+9GPo6LwX1tpH_{J9YOA!M~kez@H1nk*Zc;B(-I!jn_$fxp)%|OY_t&qcN zgfwI)DikJI7MX)YP2x7D5asJUfpIFkVM@5R%me1ZDzI=LZ$Co#B`_n7bw#CBU`8%5 zBNrH%zwFe=4OL)}DTMp84h(RpOs)+?>=OiTWS8tlzTFgHI;Z084X2LKe#qkDIO}o@ zzFXevUU4248|XL-*N&tb&bfBvTsvURfy?gZTVyv}-{+-Gb~Hd94p*U-M6b& zjwG+{vN>b}?!@xnAGN`6<*JT_e|Ldy(#Hn_k^tXTxR#84g}a9ZcFNa}vESl$5NRQB zB7Q;D$fRVCLEgeeytBdQigStk6%hk5ADZv<4t>p&-|9^N`77>&`0Y=kq@je8H1?%5 zSmcE*W{{k&I B=@I|{ diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm index 1d1c937b7001c2f142ec7f610157e0af3eb9b778..d04664b607955d53f806292a0250899ca082b507 100644 GIT binary patch literal 18609 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 F{{emLQm6m` literal 5364 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 diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 69e547cd117a8e644a910fd360ae972b4a6efa6b..5c717847a5a2dfb1d4b0e0db128b5a2cb9c57aaf 100644 GIT binary patch delta 655 zcmZ{gzityj5XQfmU3_=39bZC6!(su#U1H$`Cql|1rJ|ytL+1z_(mKaHUmsF0( z#?JAfz4$r_7t@;&z+Wg5CO=*_r$w?iO%F^z=?^vlXRbQajQfMZ`Y<^*i^={O$R$FT z*k2d}zQ}H0d>EG2Y&o+ynV%->{YN$6w^cKvFmNZ7EG4}LZV19ka86NUW@hun8KYI0 z!y*}{MVd@({xm}{x+9pA<=o3(y=-M4kq7yL7Idu4HCxqIf-Bu|d=lSw|ta$}ZG zr}LNSNWV%P5tcp&VfCE0NmQ5gEMkS26~$crq#>cY&);u(t)UwF2eJ*8iatJh>yEtS zdlb5w^8YpOI!&PYo|x_bYiK-Rsn-s=!jYgz2_0u~U>}v~F!R#BJ)kQ$8CHi`msK4r z(L?NfrG&S5N5`@3PHDI8Sv|%kY~)CMC9XEI8wkDj*8*G*_n5fUEgjf#puZxE=?+^k ZS+HU)z)|YG{Si}T?POZY;zUFzJ!>62bpH)hfT#i!Hs}Ha@l3XRL zP4$v_Ds+3jlfJi7X*5{_RnVw{Nvag6$oIEc<#j4=s>b7B>h{ix_raw!rIZapLeL{% zaDpvEX~rs^r)!3GrWTnO23g=m3FJnN{|C^}KJ6S^cDgLL?$tw-c+2EDN1=*A)kU2>>P`keKN>nHYY{PB?QYHrwjIAH8*NL_KrM;$oa TVWR<1*LYcTjUys`Yux<;(KbtX diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm index cbf1c77bdcb8bee40d72f5b5c37e3f2723db12a3..64fb6a48bfd6f1cd23a2e17c4cc720efd7e8ae65 100644 GIT binary patch delta 673 zcmZ9J&2G~`5Xa}kZJfkuofe7^5?!nc=!rHWg>tGZ<-(0C5^~&TTg8o?Dsj_>1IsH! z=2WQ%Zd~BXkq6)j;EKexufXn_mXAH`%>3r#zhi%PKX?k_af$$dkE>l)NtU zaWIk+XqK$bE`l{SxNdMN({wnIU`g#a8Ot1a_Tz!lRi0t_>F_MtY&|W7{-9FZt5?i% znb{%7!DE0qMrc;vqc^VwhNCHgm&BVJR z@ZW-db9ADs_T*tdi%zoBe%6Dg5#2wY!cygGy=8;US~up?crY05!%fG2k(DY!?OUb( z36WF?Av`1}^p67G(zf`5_mPXA_@YVzd=ltWu|wMk#cTRHSH{ozPVtgfvHmYRJVzq^ z*RE!6lrseg6dd}AU(-e;p_|xH+jW4zc|xFLHwj3TzTkE64HtqfqMgw9od7!xJF0lZ xE4S@SLesgC=!XmZxck-|Dk8ph7w?g7Lfyosi3N3@0oa9DFZ7N(NX2)4^$Uk8py&Vq delta 405 zcmZ9HJxjw-6o$_^_oivm50h396f{<$f{PX_)X5B;#KFZ)+M3=>~i+ff3rvCrnBSO_V5`q%t1sIK(;L zHUa1zO(ud_LEKClqFt$0_iK%r7AGfv> zoKe^pzCV}=NQn7E#$o~#ewJ5FL)Y~*5pm=khX5Kwu=P7Mqf=awW_}{Ze^x`Ln1FxA zvi4{iw_S>>ZqS$p*WI8Exm0}F8_prG|5{j5NS(G)eyiUfcwqD7lY)U@zH;LQk)#VQ z>=1XYUMb?VixlnAnSl;i=%9ts1J#g4A8et0>nFYzoon_wY!V&2Xz>!O=fGhO)sFy@ PF&2;AYjwnEp) -> Vec { - keccak256(&input).to_vec() +fn test_blake2_256(input: Vec) -> Vec { + blake2_256(&input).to_vec() +} + +fn test_twox_256(input: Vec) -> Vec { + twox_256(&input).to_vec() +} + +fn test_twox_128(input: Vec) -> Vec { + twox_128(&input).to_vec() } fn test_ed25519_verify(input: Vec) -> Vec { @@ -35,5 +43,4 @@ fn test_data_in(input: Vec) -> Vec { b"all ok!".to_vec() } - -impl_stubs!(test_data_in, test_keccak256, test_ed25519_verify); +impl_stubs!(test_data_in, test_blake2_256, test_twox_256, test_twox_128, test_ed25519_verify); From ae5a9c9dd48e25815707e8fbb921cabbd5a5be6a Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 16:34:28 +0100 Subject: [PATCH 65/76] Fix tests. --- wasm-runtime/polkadot/src/runtime/session.rs | 106 ++++++++++++++++-- wasm-runtime/polkadot/src/runtime/staking.rs | 4 +- wasm-runtime/polkadot/src/support/storable.rs | 2 + 3 files changed, 103 insertions(+), 9 deletions(-) diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs index 412809d6b8921..687dedfc5bbaf 100644 --- a/wasm-runtime/polkadot/src/runtime/session.rs +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -37,7 +37,27 @@ pub fn set_validators(new: &[AccountID]) { /// The number of blocks in each session. pub fn length() -> BlockNumber { - Storable::lookup_default(b"ses\0bps") + Storable::lookup_default(b"ses\0len") +} + +/// The current era index. +pub fn current_index() -> BlockNumber { + Storable::lookup_default(b"ses\0ind") +} + +/// Set the current era index. +pub fn set_current_index(new: BlockNumber) { + new.store(b"ses\0ind"); +} + +/// The block number at which the era length last changed. +pub fn last_length_change() -> BlockNumber { + Storable::lookup_default(b"ses\0llc") +} + +/// Set a new era length. Won't kick in until the next era change (at current length). +pub fn set_length(new: BlockNumber) { + new.store(b"ses\0nln"); } /// Hook to be called after transaction processing. @@ -45,7 +65,7 @@ pub fn check_rotate_session() { // do this last, after the staking system has had chance to switch out the authorities for the // new set. // check block number and call next_session if necessary. - if system::block_number() % length() == 0 { + if (system::block_number() - last_length_change()) % length() == 0 { rotate_session(); } } @@ -54,6 +74,17 @@ pub fn check_rotate_session() { /// Move onto next session: register the new authority set. fn rotate_session() { + // Increment current session index. + set_current_index(current_index() + 1); + + // Enact era length change. + if let Some(next_len) = u64::lookup(b"ses\0nln") { + next_len.store(b"ses\0len"); + system::block_number().store(b"ses\0llc"); + kill(b"ses\0nln"); + } + + // Update any changes in session keys. validators().iter().enumerate().for_each(|(i, v)| { let k = v.to_keyed_vec(b"ses\0nxt\0"); if let Some(n) = Storable::lookup(&k) { @@ -73,10 +104,9 @@ mod tests { use runtime::{consensus, session}; use environment::with_env; - #[test] - fn session_change_should_work() { - let mut t = TestExternalities { storage: map![ - twox_128(b"ses\0bps").to_vec() => vec![].join(&2u64), + fn simple_setup() -> TestExternalities { + TestExternalities { storage: map![ + twox_128(b"ses\0len").to_vec() => vec![].join(&2u64), // the validators (10, 20, ...) twox_128(b"ses\0key\0len").to_vec() => vec![].join(&2u32), twox_128(&0u32.to_keyed_vec(b"ses\0key\0")).to_vec() => vec![10; 32], @@ -85,12 +115,74 @@ mod tests { twox_128(b"con\0aut\0len").to_vec() => vec![].join(&2u32), twox_128(&0u32.to_keyed_vec(b"con\0aut\0")).to_vec() => vec![11; 32], twox_128(&1u32.to_keyed_vec(b"con\0aut\0")).to_vec() => vec![21; 32] - ], }; + ], } + } + + #[test] + fn simple_setup_should_work() { + let mut t = simple_setup(); with_externalities(&mut t, || { assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); assert_eq!(session::length(), 2u64); assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]); + }); + } + + #[test] + fn session_length_change_should_work() { + let mut t = simple_setup(); + with_externalities(&mut t, || { + // Block 1: Change to length 3; no visible change. + with_env(|e| e.block_number = 1); + session::set_length(3); + session::check_rotate_session(); + assert_eq!(session::length(), 2); + assert_eq!(session::current_index(), 0); + + // Block 2: Length now changed to 3. Index incremented. + with_env(|e| e.block_number = 2); + session::set_length(3); + session::check_rotate_session(); + assert_eq!(session::length(), 3); + assert_eq!(session::current_index(), 1); + // Block 3: Length now changed to 3. Index incremented. + with_env(|e| e.block_number = 3); + session::check_rotate_session(); + assert_eq!(session::length(), 3); + assert_eq!(session::current_index(), 1); + + // Block 4: Change to length 2; no visible change. + with_env(|e| e.block_number = 4); + session::set_length(2); + session::check_rotate_session(); + assert_eq!(session::length(), 3); + assert_eq!(session::current_index(), 1); + + // Block 5: Length now changed to 2. Index incremented. + with_env(|e| e.block_number = 5); + session::check_rotate_session(); + assert_eq!(session::length(), 2); + assert_eq!(session::current_index(), 2); + + // Block 6: No change. + with_env(|e| e.block_number = 6); + session::check_rotate_session(); + assert_eq!(session::length(), 2); + assert_eq!(session::current_index(), 2); + + // Block 7: Next index. + with_env(|e| e.block_number = 7); + session::check_rotate_session(); + assert_eq!(session::length(), 2); + assert_eq!(session::current_index(), 3); + }); + } + + #[test] + fn session_change_should_work() { + let mut t = simple_setup(); + with_externalities(&mut t, || { // Block 1: No change with_env(|e| e.block_number = 1); session::check_rotate_session(); diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index f3bae420600ee..64b64521bd896 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -28,7 +28,7 @@ pub fn current_era() -> BlockNumber { Storable::lookup_default(b"sta\0era") } -/// The current era index. +/// Set the current era index. pub fn set_current_era(new: BlockNumber) { new.store(b"sta\0era"); } @@ -113,7 +113,7 @@ mod tests { #[test] fn staking_eras_work() { let mut t = TestExternalities { storage: map![ - twox_128(b"ses\0bps").to_vec() => vec![].join(&1u64), + twox_128(b"ses\0len").to_vec() => vec![].join(&1u64), twox_128(b"sta\0spe").to_vec() => vec![].join(&2u64) ], }; with_externalities(&mut t, || { diff --git a/wasm-runtime/polkadot/src/support/storable.rs b/wasm-runtime/polkadot/src/support/storable.rs index 177475b2d7395..80c7af2136d2b 100644 --- a/wasm-runtime/polkadot/src/support/storable.rs +++ b/wasm-runtime/polkadot/src/support/storable.rs @@ -9,6 +9,8 @@ pub trait Storable { fn store(&self, key: &[u8]); } +// TODO: consider using blake256 to avoid possible eclipse attack. + pub fn kill(key: &[u8]) { runtime_support::set_storage(&twox_128(key)[..], b""); } impl Storable for T { From 639554ce933286929fcb2ef26dc3664c5c3cc5ca Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 17:39:06 +0100 Subject: [PATCH 66/76] Introduce staking. --- state_machine/src/lib.rs | 16 +-- .../polkadot/src/runtime/consensus.rs | 2 +- wasm-runtime/polkadot/src/runtime/session.rs | 38 +++--- wasm-runtime/polkadot/src/runtime/staking.rs | 109 ++++++++++++------ wasm-runtime/polkadot/src/runtime/system.rs | 16 +-- .../polkadot/src/runtime/timestamp.rs | 6 +- wasm-runtime/polkadot/src/support/function.rs | 8 +- .../polkadot/src/support/primitives.rs | 8 +- 8 files changed, 122 insertions(+), 81 deletions(-) diff --git a/state_machine/src/lib.rs b/state_machine/src/lib.rs index cee96a36ad3ff..d1357592d4ec7 100644 --- a/state_machine/src/lib.rs +++ b/state_machine/src/lib.rs @@ -134,10 +134,10 @@ pub trait Externalities { /// Get the current set of authorities from storage. fn authorities(&self) -> Result, Self::Error> { - (0..self.storage(b"con\0aut\0len")?.into_iter() + (0..self.storage(b"con:aut:len")?.into_iter() .rev() .fold(0, |acc, &i| (acc << 8) + (i as u32))) - .map(|i| self.storage(&to_keyed_vec(i, b"con\0aut\0".to_vec()))) + .map(|i| self.storage(&to_keyed_vec(i, b"con:aut:".to_vec()))) .collect() } } @@ -177,7 +177,7 @@ pub fn execute( overlay: &mut *overlay }; // make a copy. - let code = externalities.storage(b"\0code").unwrap_or(&[]).to_vec(); + let code = externalities.storage(b":code").unwrap_or(&[]).to_vec(); exec.call( &mut externalities, @@ -253,17 +253,17 @@ mod tests { assert_eq!(ext.authorities(), Ok(vec![])); - ext.set_storage(b"con\0aut\0len".to_vec(), vec![0u8; 4]); + ext.set_storage(b"con:aut:len".to_vec(), vec![0u8; 4]); assert_eq!(ext.authorities(), Ok(vec![])); - ext.set_storage(b"con\0aut\0len".to_vec(), vec![1u8, 0, 0, 0]); + ext.set_storage(b"con:aut:len".to_vec(), vec![1u8, 0, 0, 0]); assert_eq!(ext.authorities(), Ok(vec![&[][..]])); - ext.set_storage(b"con\0aut\0\0\0\0\0".to_vec(), b"first".to_vec()); + ext.set_storage(b"con:aut:::::".to_vec(), b"first".to_vec()); assert_eq!(ext.authorities(), Ok(vec![&b"first"[..]])); - ext.set_storage(b"con\0aut\0len".to_vec(), vec![2u8, 0, 0, 0]); - ext.set_storage(b"con\0aut\0\x01\0\0\0".to_vec(), b"second".to_vec()); + ext.set_storage(b"con:aut:len".to_vec(), vec![2u8, 0, 0, 0]); + ext.set_storage(b"con:aut:\x01:::".to_vec(), b"second".to_vec()); assert_eq!(ext.authorities(), Ok(vec![&b"first"[..], &b"second"[..]])); } } diff --git a/wasm-runtime/polkadot/src/runtime/consensus.rs b/wasm-runtime/polkadot/src/runtime/consensus.rs index 02bf288493b7f..757c032f03fa1 100644 --- a/wasm-runtime/polkadot/src/runtime/consensus.rs +++ b/wasm-runtime/polkadot/src/runtime/consensus.rs @@ -5,7 +5,7 @@ use primitives::SessionKey; struct AuthorityStorageVec {} impl StorageVec for AuthorityStorageVec { type Item = SessionKey; - const PREFIX: &'static[u8] = b"con\0aut\0"; + const PREFIX: &'static[u8] = b"con:aut:"; } /// Get the current set of authorities. These are the session keys. diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs index 687dedfc5bbaf..cc572ea842083 100644 --- a/wasm-runtime/polkadot/src/runtime/session.rs +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -7,7 +7,7 @@ use runtime::{system, staking, consensus}; struct ValidatorStorageVec {} impl StorageVec for ValidatorStorageVec { type Item = AccountID; - const PREFIX: &'static[u8] = b"ses\0key\0"; + const PREFIX: &'static[u8] = b"ses:key:"; } // TRANSACTION API (available to all transactors) @@ -16,7 +16,7 @@ impl StorageVec for ValidatorStorageVec { /// session. pub fn set_key(validator: &AccountID, key: &SessionKey) { // set new value for next session - key.store(&validator.to_keyed_vec(b"ses\0nxt\0")); + key.store(&validator.to_keyed_vec(b"ses:nxt:")); } // PUBLIC API (available to other runtime modules) @@ -37,27 +37,27 @@ pub fn set_validators(new: &[AccountID]) { /// The number of blocks in each session. pub fn length() -> BlockNumber { - Storable::lookup_default(b"ses\0len") + Storable::lookup_default(b"ses:len") } /// The current era index. pub fn current_index() -> BlockNumber { - Storable::lookup_default(b"ses\0ind") + Storable::lookup_default(b"ses:ind") } /// Set the current era index. pub fn set_current_index(new: BlockNumber) { - new.store(b"ses\0ind"); + new.store(b"ses:ind"); } /// The block number at which the era length last changed. pub fn last_length_change() -> BlockNumber { - Storable::lookup_default(b"ses\0llc") + Storable::lookup_default(b"ses:llc") } /// Set a new era length. Won't kick in until the next era change (at current length). pub fn set_length(new: BlockNumber) { - new.store(b"ses\0nln"); + new.store(b"ses:nln"); } /// Hook to be called after transaction processing. @@ -78,15 +78,15 @@ fn rotate_session() { set_current_index(current_index() + 1); // Enact era length change. - if let Some(next_len) = u64::lookup(b"ses\0nln") { - next_len.store(b"ses\0len"); - system::block_number().store(b"ses\0llc"); - kill(b"ses\0nln"); + if let Some(next_len) = u64::lookup(b"ses:nln") { + next_len.store(b"ses:len"); + system::block_number().store(b"ses:llc"); + kill(b"ses:nln"); } // Update any changes in session keys. validators().iter().enumerate().for_each(|(i, v)| { - let k = v.to_keyed_vec(b"ses\0nxt\0"); + let k = v.to_keyed_vec(b"ses:nxt:"); if let Some(n) = Storable::lookup(&k) { consensus::set_authority(i as u32, &n); kill(&k); @@ -106,15 +106,15 @@ mod tests { fn simple_setup() -> TestExternalities { TestExternalities { storage: map![ - twox_128(b"ses\0len").to_vec() => vec![].join(&2u64), + twox_128(b"ses:len").to_vec() => vec![].join(&2u64), // the validators (10, 20, ...) - twox_128(b"ses\0key\0len").to_vec() => vec![].join(&2u32), - twox_128(&0u32.to_keyed_vec(b"ses\0key\0")).to_vec() => vec![10; 32], - twox_128(&1u32.to_keyed_vec(b"ses\0key\0")).to_vec() => vec![20; 32], + twox_128(b"ses:key:len").to_vec() => vec![].join(&2u32), + twox_128(&0u32.to_keyed_vec(b"ses:key:")).to_vec() => vec![10; 32], + twox_128(&1u32.to_keyed_vec(b"ses:key:")).to_vec() => vec![20; 32], // initial session keys (11, 21, ...) - twox_128(b"con\0aut\0len").to_vec() => vec![].join(&2u32), - twox_128(&0u32.to_keyed_vec(b"con\0aut\0")).to_vec() => vec![11; 32], - twox_128(&1u32.to_keyed_vec(b"con\0aut\0")).to_vec() => vec![21; 32] + twox_128(b"con:aut:len").to_vec() => vec![].join(&2u32), + twox_128(&0u32.to_keyed_vec(b"con:aut:")).to_vec() => vec![11; 32], + twox_128(&1u32.to_keyed_vec(b"con:aut:")).to_vec() => vec![21; 32] ], } } diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index 64b64521bd896..1406cd96cedd8 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -1,16 +1,30 @@ use keyedvec::KeyedVec; -use storable::Storable; +use storable::{Storable, StorageVec}; use primitives::{BlockNumber, Balance, AccountID}; use runtime::{system, session}; -// Each validator's stake has one amount in each of three states: -// - inactive: free to be transferred. -// - active: currently representing a validator. -// - deactivating: recently representing a validator and not yet ready for transfer. +type Liquidity = u64; + +struct IntentionStorageVec {} +impl StorageVec for IntentionStorageVec { + type Item = AccountID; + const PREFIX: &'static[u8] = b"ses:wil:"; +} + +// Each identity's stake may be in one of three bondage states, given by an integer: +// - n | n <= system::block_number(): inactive: free to be transferred. +// - ~0: active: currently representing a validator. +// - n | n > system::block_number(): deactivating: recently representing a validator and not yet +// ready for transfer. /// The length of a staking era in sessions. -pub fn lockup_eras() -> BlockNumber { - Storable::lookup_default(b"sta\0lpe") +pub fn eras_per_lockup() -> BlockNumber { + Storable::lookup_default(b"sta:epl") +} + +/// The length of a staking era in sessions. +pub fn validator_count() -> usize { + Storable::lookup_default(b"sta:vac") } /// The length of a staking era in blocks. @@ -20,27 +34,27 @@ pub fn era_length() -> BlockNumber { /// The length of a staking era in sessions. pub fn sessions_per_era() -> BlockNumber { - Storable::lookup_default(b"sta\0spe") + Storable::lookup_default(b"sta:spe") } /// The current era index. pub fn current_era() -> BlockNumber { - Storable::lookup_default(b"sta\0era") + Storable::lookup_default(b"sta:era") } /// Set the current era index. pub fn set_current_era(new: BlockNumber) { - new.store(b"sta\0era"); + new.store(b"sta:era"); } /// The block number at which the era length last changed. pub fn last_era_length_change() -> BlockNumber { - Storable::lookup_default(b"sta\0lec") + Storable::lookup_default(b"sta:lec") } /// Set a new era length. Won't kick in until the next era change (at current length). pub fn set_sessions_per_era(new: BlockNumber) { - new.store(b"sta\0nse"); + new.store(b"sta:nse"); } /// The era has changed - enact new staking set. @@ -51,28 +65,48 @@ fn new_era() { set_current_era(current_era() + 1); // Enact era length change. - let next_spe: u64 = Storable::lookup_default(b"sta\0nse"); + let next_spe: u64 = Storable::lookup_default(b"sta:nse"); if next_spe > 0 && next_spe != sessions_per_era() { - next_spe.store(b"sta\0spe"); - system::block_number().store(b"sta\0lec"); + next_spe.store(b"sta:spe"); + system::block_number().store(b"sta:lec"); } // TODO: evaluate desired staking amounts and nominations and optimise to find the best // combination of validators, then use session::set_validators(). + + // for now, this just orders would-be stakers by their balances and chooses the top-most + // validator_count() of them. + let mut intentions = IntentionStorageVec::items() + .into_iter() + .map(|v| (balance(&v), v)) + .collect::>(); + intentions.sort_unstable_by(|&(b1, _), &(b2, _)| b2.cmp(&b1)); + session::set_validators( + &intentions.into_iter() + .map(|(_, v)| v) + .take(validator_count()) + .collect::>() + ); } /// The balance of a given account. -pub fn balance_inactive(who: &AccountID) -> Balance { - Storable::lookup_default(&who.to_keyed_vec(b"sta\0bal\0")) +pub fn balance(who: &AccountID) -> Balance { + Storable::lookup_default(&who.to_keyed_vec(b"sta:bal:")) +} + +/// The liquidity-state of a given account. +pub fn bondage(who: &AccountID) -> Liquidity { + Storable::lookup_default(&who.to_keyed_vec(b"sta:bon:")) } /// Transfer some unlocked staking balance to another staker. -pub fn transfer_inactive(transactor: &AccountID, dest: &AccountID, value: Balance) { - let from_key = transactor.to_keyed_vec(b"sta\0bal\0"); - let from_balance: Balance = Storable::lookup_default(&from_key); +pub fn transfer(transactor: &AccountID, dest: &AccountID, value: Balance) { + let from_key = transactor.to_keyed_vec(b"sta:bal:"); + let from_balance = Balance::lookup_default(&from_key); assert!(from_balance >= value); - let to_key = dest.to_keyed_vec(b"sta\0bal\0"); + let to_key = dest.to_keyed_vec(b"sta:bal:"); let to_balance: Balance = Storable::lookup_default(&to_key); + assert!(bondage(transactor) <= bondage(dest)); assert!(to_balance + value > to_balance); // no overflow (from_balance - value).store(&from_key); (to_balance + value).store(&to_key); @@ -81,15 +115,22 @@ pub fn transfer_inactive(transactor: &AccountID, dest: &AccountID, value: Balanc /// Declare the desire to stake for the transactor. /// /// Effects will be felt at the beginning of the next era. -pub fn stake(_transactor: &AccountID) { - // TODO: record the desire for `_transactor` to activate their stake. +pub fn stake(transactor: &AccountID) { + let mut intentions = IntentionStorageVec::items(); + // can't be in the list twice. + assert!(intentions.iter().find(|t| *t == transactor).is_none()); + intentions.push(transactor.clone()); + IntentionStorageVec::set_items(&intentions); } /// Retract the desire to stake for the transactor. /// /// Effects will be felt at the beginning of the next era. -pub fn unstake(_transactor: &AccountID) { - // TODO: record the desire for `_transactor` to deactivate their stake. +pub fn unstake(transactor: &AccountID) { + let mut intentions = IntentionStorageVec::items(); + // TODO: use swap remove. + let intentions = intentions.into_iter().filter(|t| t != transactor).collect::>(); + IntentionStorageVec::set_items(&intentions); } /// Hook to be called after to transaction processing. @@ -113,8 +154,8 @@ mod tests { #[test] fn staking_eras_work() { let mut t = TestExternalities { storage: map![ - twox_128(b"ses\0len").to_vec() => vec![].join(&1u64), - twox_128(b"sta\0spe").to_vec() => vec![].join(&2u64) + twox_128(b"ses:len").to_vec() => vec![].join(&1u64), + twox_128(b"sta:spe").to_vec() => vec![].join(&2u64) ], }; with_externalities(&mut t, || { assert_eq!(staking::era_length(), 2u64); @@ -180,12 +221,12 @@ mod tests { let two = two(); let mut t = TestExternalities { storage: map![ - twox_128(&one.to_keyed_vec(b"sta\0bal\0")).to_vec() => vec![].join(&42u64) + twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![].join(&42u64) ], }; with_externalities(&mut t, || { - assert_eq!(staking::balance_inactive(&one), 42); - assert_eq!(staking::balance_inactive(&two), 0); + assert_eq!(staking::balance(&one), 42); + assert_eq!(staking::balance(&two), 0); }); } @@ -195,13 +236,13 @@ mod tests { let two = two(); let mut t = TestExternalities { storage: map![ - twox_128(&one.to_keyed_vec(b"sta\0bal\0")).to_vec() => vec![].join(&111u64) + twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![].join(&111u64) ], }; with_externalities(&mut t, || { - staking::transfer_inactive(&one, &two, 69); - assert_eq!(staking::balance_inactive(&one), 42); - assert_eq!(staking::balance_inactive(&two), 69); + staking::transfer(&one, &two, 69); + assert_eq!(staking::balance(&one), 42); + assert_eq!(staking::balance(&two), 69); }); } } diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index 0bf300d2b3b16..f96bc40c93ff3 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -12,7 +12,7 @@ pub fn block_number() -> BlockNumber { /// Get the block hash of a given block (uses storage). pub fn block_hash(number: BlockNumber) -> Hash { - Storable::lookup_default(&number.to_keyed_vec(b"sys\0old\0")) + Storable::lookup_default(&number.to_keyed_vec(b"sys:old:")) } /// Deposits a log and ensures it matches the blocks log data. @@ -44,7 +44,7 @@ pub fn execute_block(mut block: Block) { // so will wait until a little later. // store the header hash in storage. - let header_hash_key = header.number.to_keyed_vec(b"sys\0old\0"); + let header_hash_key = header.number.to_keyed_vec(b"sys:old:"); header.blake2_256().store(&header_hash_key); // execute transactions @@ -69,7 +69,7 @@ pub fn execute_transaction(utx: &UncheckedTransaction) { let ref tx = utx.transaction; // check nonce - let nonce_key = tx.signed.to_keyed_vec(b"sys\0non\0"); + let nonce_key = tx.signed.to_keyed_vec(b"sys:non:"); let expected_nonce: TxOrder = Storable::lookup_default(&nonce_key); assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce"); @@ -82,7 +82,7 @@ pub fn execute_transaction(utx: &UncheckedTransaction) { /// Set the new code. pub fn set_code(new: &[u8]) { - new.store(b"\0code"); + new.store(b":code"); } fn final_checks(_block: &Block) { @@ -109,14 +109,14 @@ mod tests { let two = two(); let mut t = TestExternalities { storage: map![ - twox_128(&one.to_keyed_vec(b"sta\0bal\0")).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 tx = UncheckedTransaction { transaction: Transaction { signed: one.clone(), nonce: 0, - function: Function::StakingTransferInactive, + function: Function::StakingTransfer, input_data: vec![].join(&two).join(&69u64), }, signature: "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a".convert(), @@ -128,8 +128,8 @@ mod tests { with_externalities(&mut t, || { system::execute_transaction(&tx); - assert_eq!(staking::balance_inactive(&one), 42); - assert_eq!(staking::balance_inactive(&two), 69); + assert_eq!(staking::balance(&one), 42); + assert_eq!(staking::balance(&two), 69); }); } } diff --git a/wasm-runtime/polkadot/src/runtime/timestamp.rs b/wasm-runtime/polkadot/src/runtime/timestamp.rs index 10708a5a3cb69..c6a3ac2a9609b 100644 --- a/wasm-runtime/polkadot/src/runtime/timestamp.rs +++ b/wasm-runtime/polkadot/src/runtime/timestamp.rs @@ -2,11 +2,11 @@ use primitives::Timestamp; use storable::Storable; pub fn get() -> Timestamp { - Storable::lookup_default(b"tim\0val") + Storable::lookup_default(b"tim:val") } pub fn set(now: Timestamp) { - now.store(b"tim\0val") + now.store(b"tim:val") } #[cfg(test)] @@ -20,7 +20,7 @@ mod tests { #[test] fn timestamp_works() { let mut t = TestExternalities { storage: map![ - twox_128(b"tim\0val").to_vec() => vec![].join(&42u64) + twox_128(b"tim:val").to_vec() => vec![].join(&42u64) ], }; with_externalities(&mut t, || { diff --git a/wasm-runtime/polkadot/src/support/function.rs b/wasm-runtime/polkadot/src/support/function.rs index 45dcea876b4e6..f0be93c4af3b8 100644 --- a/wasm-runtime/polkadot/src/support/function.rs +++ b/wasm-runtime/polkadot/src/support/function.rs @@ -8,7 +8,7 @@ use runtime::{staking, session, timestamp}; pub enum Function { StakingStake, StakingUnstake, - StakingTransferInactive, + StakingTransfer, SessionSetKey, TimestampSet, } @@ -18,7 +18,7 @@ impl Function { match value { x if x == Function::StakingStake as u8 => Some(Function::StakingStake), x if x == Function::StakingUnstake as u8 => Some(Function::StakingUnstake), - x if x == Function::StakingTransferInactive as u8 => Some(Function::StakingTransferInactive), + x if x == Function::StakingTransfer as u8 => Some(Function::StakingTransfer), x if x == Function::SessionSetKey as u8 => Some(Function::SessionSetKey), x if x == Function::TimestampSet as u8 => Some(Function::TimestampSet), _ => None, @@ -37,10 +37,10 @@ impl Function { Function::StakingUnstake => { staking::unstake(transactor); } - Function::StakingTransferInactive => { + Function::StakingTransfer => { let dest = params.read().unwrap(); let value = params.read().unwrap(); - staking::transfer_inactive(transactor, &dest, value); + staking::transfer(transactor, &dest, value); } Function::SessionSetKey => { let session = params.read().unwrap(); diff --git a/wasm-runtime/polkadot/src/support/primitives.rs b/wasm-runtime/polkadot/src/support/primitives.rs index fb983bf84ea7b..dbe75aad1181f 100644 --- a/wasm-runtime/polkadot/src/support/primitives.rs +++ b/wasm-runtime/polkadot/src/support/primitives.rs @@ -261,7 +261,7 @@ mod tests { let tx = Transaction { signed: one.clone(), nonce: 69, - function: Function::StakingTransferInactive, + function: Function::StakingTransfer, input_data: Vec::new().join(&two).join(&69u64), }; let serialised = tx.to_vec(); @@ -282,7 +282,7 @@ mod tests { let tx = Transaction { signed: one.clone(), nonce: 69, - function: Function::StakingTransferInactive, + function: Function::StakingTransfer, input_data: Vec::new().join(&two).join(&69u64), }; let data = [ @@ -352,7 +352,7 @@ mod tests { transaction: Transaction { signed: one.clone(), nonce: 69, - function: Function::StakingTransferInactive, + function: Function::StakingTransfer, input_data: Vec::new().join(&two).join(&69u64), }, signature: [1u8; 64], @@ -416,7 +416,7 @@ mod tests { transaction: Transaction { signed: one.clone(), nonce: 69, - function: Function::StakingTransferInactive, + function: Function::StakingTransfer, input_data: Vec::new().join(&two).join(&69u64), }, signature: [1u8; 64], From 0e88dad9307334e558e42c48debe49e188333ff2 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 20:29:42 +0100 Subject: [PATCH 67/76] Tests for simple staking system. --- wasm-runtime/polkadot/src/runtime/session.rs | 10 +- wasm-runtime/polkadot/src/runtime/staking.rs | 123 ++++++++++++++++--- 2 files changed, 110 insertions(+), 23 deletions(-) diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs index cc572ea842083..b7ed1361eccd9 100644 --- a/wasm-runtime/polkadot/src/runtime/session.rs +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -7,7 +7,7 @@ use runtime::{system, staking, consensus}; struct ValidatorStorageVec {} impl StorageVec for ValidatorStorageVec { type Item = AccountID; - const PREFIX: &'static[u8] = b"ses:key:"; + const PREFIX: &'static[u8] = b"ses:val:"; } // TRANSACTION API (available to all transactors) @@ -22,7 +22,7 @@ pub fn set_key(validator: &AccountID, key: &SessionKey) { // PUBLIC API (available to other runtime modules) /// Get the current set of authorities. These are the session keys. -fn validators() -> Vec { +pub fn validators() -> Vec { ValidatorStorageVec::items() } @@ -108,9 +108,9 @@ mod tests { TestExternalities { storage: map![ twox_128(b"ses:len").to_vec() => vec![].join(&2u64), // the validators (10, 20, ...) - twox_128(b"ses:key:len").to_vec() => vec![].join(&2u32), - twox_128(&0u32.to_keyed_vec(b"ses:key:")).to_vec() => vec![10; 32], - twox_128(&1u32.to_keyed_vec(b"ses:key:")).to_vec() => vec![20; 32], + twox_128(b"ses:val:len").to_vec() => vec![].join(&2u32), + twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => vec![10; 32], + twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => vec![20; 32], // initial session keys (11, 21, ...) twox_128(b"con:aut:len").to_vec() => vec![].join(&2u32), twox_128(&0u32.to_keyed_vec(b"con:aut:")).to_vec() => vec![11; 32], diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index 1406cd96cedd8..fe26a7c928d98 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -12,19 +12,19 @@ impl StorageVec for IntentionStorageVec { } // Each identity's stake may be in one of three bondage states, given by an integer: -// - n | n <= system::block_number(): inactive: free to be transferred. +// - n | n <= current_era(): inactive: free to be transferred. // - ~0: active: currently representing a validator. -// - n | n > system::block_number(): deactivating: recently representing a validator and not yet +// - n | n > current_era(): deactivating: recently representing a validator and not yet // ready for transfer. -/// The length of a staking era in sessions. -pub fn eras_per_lockup() -> BlockNumber { - Storable::lookup_default(b"sta:epl") +/// The length of the bonding duration in eras. +pub fn bonding_duration() -> BlockNumber { + Storable::lookup_default(b"sta:loc") } /// The length of a staking era in sessions. pub fn validator_count() -> usize { - Storable::lookup_default(b"sta:vac") + u32::lookup_default(b"sta:vac") as usize } /// The length of a staking era in blocks. @@ -42,27 +42,17 @@ pub fn current_era() -> BlockNumber { Storable::lookup_default(b"sta:era") } -/// Set the current era index. -pub fn set_current_era(new: BlockNumber) { - new.store(b"sta:era"); -} - /// The block number at which the era length last changed. pub fn last_era_length_change() -> BlockNumber { Storable::lookup_default(b"sta:lec") } -/// Set a new era length. Won't kick in until the next era change (at current length). -pub fn set_sessions_per_era(new: BlockNumber) { - new.store(b"sta:nse"); -} - /// The era has changed - enact new staking set. /// /// NOTE: This always happens on a session change. fn new_era() { // Increment current era. - set_current_era(current_era() + 1); + (current_era() + 1).store(b"sta:era"); // Enact era length change. let next_spe: u64 = Storable::lookup_default(b"sta:nse"); @@ -121,6 +111,7 @@ pub fn stake(transactor: &AccountID) { assert!(intentions.iter().find(|t| *t == transactor).is_none()); intentions.push(transactor.clone()); IntentionStorageVec::set_items(&intentions); + u64::max_value().store(&transactor.to_keyed_vec(b"sta:bon:")); } /// Retract the desire to stake for the transactor. @@ -131,6 +122,7 @@ pub fn unstake(transactor: &AccountID) { // TODO: use swap remove. let intentions = intentions.into_iter().filter(|t| t != transactor).collect::>(); IntentionStorageVec::set_items(&intentions); + (current_era() + bonding_duration()).store(&transactor.to_keyed_vec(b"sta:bon:")); } /// Hook to be called after to transaction processing. @@ -141,6 +133,11 @@ pub fn check_new_era() { } } +/// Set a new era length. Won't kick in until the next era change (at current length). +fn set_sessions_per_era(new: BlockNumber) { + new.store(b"sta:nse"); +} + #[cfg(test)] mod tests { use runtime_support::{with_externalities, twox_128}; @@ -148,9 +145,83 @@ mod tests { use joiner::Joiner; use testing::{one, two, TestExternalities}; use primitives::AccountID; - use runtime::staking; + use runtime::{staking, session}; use environment::with_env; + #[test] + fn staking_should_work() { + let one = one(); + let two = two(); + let three = [3u8; 32]; + let four = [4u8; 32]; + + let mut t = TestExternalities { storage: map![ + twox_128(b"ses:len").to_vec() => vec![].join(&1u64), + twox_128(b"ses:val:len").to_vec() => vec![].join(&2u32), + twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => vec![10; 32], + twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => vec![20; 32], + twox_128(b"sta:spe").to_vec() => vec![].join(&2u64), + twox_128(b"sta:vac").to_vec() => vec![].join(&2u32), + twox_128(b"sta:loc").to_vec() => vec![].join(&3u64), + twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![].join(&10u64), + twox_128(&two.to_keyed_vec(b"sta:bal:")).to_vec() => vec![].join(&20u64), + twox_128(&three.to_keyed_vec(b"sta:bal:")).to_vec() => vec![].join(&30u64), + twox_128(&four.to_keyed_vec(b"sta:bal:")).to_vec() => vec![].join(&40u64) + ], }; + + with_externalities(&mut t, || { + assert_eq!(staking::era_length(), 2u64); + assert_eq!(staking::validator_count(), 2usize); + assert_eq!(staking::bonding_duration(), 3u64); + assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]); + + // Block 1: Add three validators. No obvious change. + with_env(|e| e.block_number = 1); + staking::stake(&one); + staking::stake(&two); + staking::stake(&four); + staking::check_new_era(); + assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]); + + // Block 2: New validator set now. + with_env(|e| e.block_number = 2); + staking::check_new_era(); + assert_eq!(session::validators(), vec![four.clone(), two.clone()]); + + // Block 3: Unstake highest, introduce another staker. No change yet. + with_env(|e| e.block_number = 3); + staking::stake(&three); + staking::unstake(&four); + staking::check_new_era(); + + // Block 4: New era - validators change. + with_env(|e| e.block_number = 4); + staking::check_new_era(); + assert_eq!(session::validators(), vec![three.clone(), two.clone()]); + + // Block 5: Transfer stake from highest to lowest. No change yet. + with_env(|e| e.block_number = 5); + staking::transfer(&four, &one, 40); + staking::check_new_era(); + + // Block 6: Lowest now validator. + with_env(|e| e.block_number = 6); + staking::check_new_era(); + assert_eq!(session::validators(), vec![one.clone(), three.clone()]); + + // Block 7: Unstake three. No change yet. + with_env(|e| e.block_number = 7); + staking::unstake(&three); + staking::check_new_era(); + assert_eq!(session::validators(), vec![one.clone(), three.clone()]); + + // Block 8: Back to one and two. + with_env(|e| e.block_number = 8); + staking::check_new_era(); + assert_eq!(session::validators(), vec![one.clone(), two.clone()]); + }); + } + #[test] fn staking_eras_work() { let mut t = TestExternalities { storage: map![ @@ -245,4 +316,20 @@ mod tests { assert_eq!(staking::balance(&two), 69); }); } + + #[test] + #[should_panic] + fn staking_balance_transfer_when_bonded_doesnt_work() { + let one = one(); + let two = two(); + + let mut t = TestExternalities { storage: map![ + twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![].join(&111u64) + ], }; + + with_externalities(&mut t, || { + staking::stake(&one); + staking::transfer(&one, &two, 69); + }); + } } From 80aa38cf10cb095126b20270ef63632b2f762573 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 20:31:18 +0100 Subject: [PATCH 68/76] Build fix for wasm. --- executor/src/wasm_executor.rs | 1 - wasm-runtime/polkadot/src/runtime/staking.rs | 1 + .../release/runtime_polkadot.compact.wasm | Bin 18522 -> 37802 bytes .../release/runtime_polkadot.wasm | Bin 18609 -> 37859 bytes 4 files changed, 1 insertion(+), 1 deletion(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index c0c638fa3d6d2..7fc9a741f83b5 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -240,7 +240,6 @@ mod tests { use super::*; use rustc_hex::FromHex; - use primitives::ed25519::hexdisplay::HexDisplay; #[derive(Debug, Default)] struct TestExternalities { diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index fe26a7c928d98..6b41ddbd8f850 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -1,3 +1,4 @@ +use runtime_support::Vec; use keyedvec::KeyedVec; use storable::{Storable, StorageVec}; use primitives::{BlockNumber, Balance, AccountID}; diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm index dbc3273e1b506a06521aae4b775386774d7353a8..5f357f211861828f797bbe3bf8388b2839067a07 100644 GIT binary patch literal 37802 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

      GsQHII{LdIbLMM zi4*jCQh0eXlP4zQ^0u8tu^pBF&evgYy=iGX;pL_!dyH;o!!qbk+`Y98#x1?T$M&4; zEbM2u(QdU%=+sp1SkCV4)8cn5<%yt^wqpqx?N~AmC<;iY`~stJ0c@#=ZB;gIy<=%c zqujOBnT}|t_=HhcpVBh|VX3&Z_oxDq;=aFY8=3ygrEKF$v)p*P);T-f)W%b?l|0Q! zn$6-S=h4uK2I!Zbk*{UBrXS=m&xbdytS_X|`HRvs;wy>PezQS`*IEW_qdeQ^tAMm# zo?!Gury@ad}>(!_uh)|~@N=1uXk>Gp&T<3g^1gZl6)fx#@ z#RT+usQPe_;Cm3S45J2o9?rK<$|S1I;Cme0gyQXTlOvw5w?(6m>eu4ix|y1whB>&y3^W_s$_@|{TfZHu0y=It4&sou(w*iV71xjN^Vqz-0&HtNH;s657F258x4+MvkZlf)%jF?%cQ37dc)+GCO3R?WUnn& z6;t3tyb%k1m_&wXuwQPjX=&N@OG~FTmA(ofl@|IcfYjj1pkHHY*=-?wkzng3lyN1@ z>bcAMf$+_jYtL%APbdoomak5w}PBl+7uJfWyzN)4BR{wG0n-|PGMN{7y zP4xK-zMkF88|0YQDLE9-I7#wiCF3|GpBtVIw(u1;

      d?nBkjN_JJ#2vzBkdw}_8t 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 literal 18522 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 diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm index d04664b607955d53f806292a0250899ca082b507..700194bb0a902a08b3704ed1a25f78b67a0e113e 100644 GIT binary patch literal 37859 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 literal 18609 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 F{{emLQm6m` From ef5d78a505c06ff20b4ceab9a14db6aed82db215 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 21:20:44 +0100 Subject: [PATCH 69/76] Fix tests. --- primitives/src/block.rs | 2 +- primitives/src/parachain.rs | 2 +- state_machine/src/lib.rs | 4 ++-- .../polkadot/src/support/environment.rs | 22 +++++++++++++++++++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/primitives/src/block.rs b/primitives/src/block.rs index 740b0c4cdada3..8cd077fd78f13 100644 --- a/primitives/src/block.rs +++ b/primitives/src/block.rs @@ -97,7 +97,7 @@ mod tests { "candidates": [ { "parachainIndex": 10, - "collatorSignature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "collatorSignature": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "unprocessedIngress": [], "block": "0x01030508" } diff --git a/primitives/src/parachain.rs b/primitives/src/parachain.rs index 1d64f3c82429a..ed44134ce27ef 100644 --- a/primitives/src/parachain.rs +++ b/primitives/src/parachain.rs @@ -118,7 +118,7 @@ mod tests { block: BlockData(vec![1, 2, 3]), }), r#"{ "parachainIndex": 5, - "collatorSignature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a", + "collatorSignature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a", "unprocessedIngress": [ [ 1, diff --git a/state_machine/src/lib.rs b/state_machine/src/lib.rs index d1357592d4ec7..cd25cdcb90ee9 100644 --- a/state_machine/src/lib.rs +++ b/state_machine/src/lib.rs @@ -259,11 +259,11 @@ mod tests { ext.set_storage(b"con:aut:len".to_vec(), vec![1u8, 0, 0, 0]); assert_eq!(ext.authorities(), Ok(vec![&[][..]])); - ext.set_storage(b"con:aut:::::".to_vec(), b"first".to_vec()); + ext.set_storage(b"con:aut:\0\0\0\0".to_vec(), b"first".to_vec()); assert_eq!(ext.authorities(), Ok(vec![&b"first"[..]])); ext.set_storage(b"con:aut:len".to_vec(), vec![2u8, 0, 0, 0]); - ext.set_storage(b"con:aut:\x01:::".to_vec(), b"second".to_vec()); + ext.set_storage(b"con:aut:\x01\0\0\0".to_vec(), b"second".to_vec()); assert_eq!(ext.authorities(), Ok(vec![&b"first"[..], &b"second"[..]])); } } diff --git a/wasm-runtime/polkadot/src/support/environment.rs b/wasm-runtime/polkadot/src/support/environment.rs index 4d8ac354a835e..da2e9b18ec19f 100644 --- a/wasm-runtime/polkadot/src/support/environment.rs +++ b/wasm-runtime/polkadot/src/support/environment.rs @@ -14,6 +14,7 @@ pub fn with_env T>(f: F) -> T { f(&mut *eb) } +#[cfg(not(test))] pub fn env() -> Rc> { // Initialize it to a null value static mut SINGLETON: *const Rc> = 0 as *const Rc>; @@ -31,3 +32,24 @@ pub fn env() -> Rc> { (*SINGLETON).clone() } } + +#[cfg(test)] +pub fn env() -> Rc> { + // Initialize it to a null value + thread_local!{ + static SINGLETON: RefCell<*const Rc>> = RefCell::new(0 as *const Rc>); + } + + SINGLETON.with(|s| unsafe { + if *s.borrow() == 0 as *const Rc> { + // Make it + let singleton: Rc> = Rc::new(RefCell::new(Default::default())); + + // Put it in the heap so it can outlive this call + *s.borrow_mut() = transmute(Box::new(singleton)); + } + + // Now we give out a copy of the data that is safe to use concurrently. + (**s.borrow()).clone() + }) +} From e068f44a4cf31bdda6533b378a530d42b230109d Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 21:28:19 +0100 Subject: [PATCH 70/76] Repotting and docs. --- primitives/src/ed25519.rs | 54 +++------------------- primitives/src/hashing.rs | 88 +++++++++++++++++++++++++++++++++++ primitives/src/hexdisplay.rs | 38 +++++++++++++++ primitives/src/lib.rs | 89 ++---------------------------------- 4 files changed, 136 insertions(+), 133 deletions(-) create mode 100644 primitives/src/hashing.rs create mode 100644 primitives/src/hexdisplay.rs diff --git a/primitives/src/ed25519.rs b/primitives/src/ed25519.rs index e9ac7e473c4f9..cdbbc194c791f 100644 --- a/primitives/src/ed25519.rs +++ b/primitives/src/ed25519.rs @@ -4,6 +4,7 @@ use untrusted; use ring::{rand, signature}; use rustc_hex::FromHex; +/// Verify a message without type checking the parameters' types for the right size. pub fn verify(sig: &[u8], message: &[u8], public: &[u8]) -> bool { let public_key = untrusted::Input::from(public); let msg = untrusted::Input::from(message); @@ -27,9 +28,12 @@ pub struct Pair(signature::Ed25519KeyPair); pub struct Signature ([u8; 64]); impl Signature { + /// A new signature from the given 64-byte `data`. pub fn from(data: [u8; 64]) -> Self { Signature(data) } + + /// A new signature from the given slice that should be 64 bytes long. pub fn from_slice(data: &[u8]) -> Self { let mut r = [0u8; 64]; r.copy_from_slice(data); @@ -50,9 +54,12 @@ impl AsRef<[u8]> for Signature { } impl Public { + /// A new instance from the given 32-byte `data`. pub fn from(data: [u8; 32]) -> Self { Public(data) } + + /// A new instance from the given slice that should be 32 bytes long. pub fn from_slice(data: &[u8]) -> Self { let mut r = [0u8; 32]; r.copy_from_slice(data); @@ -166,53 +173,9 @@ impl PartialEq for Signature { } } -pub mod hexdisplay { - - pub struct HexDisplay<'a>(&'a [u8]); - - impl<'a> HexDisplay<'a> { - pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) } - } - - impl<'a> ::std::fmt::Display for HexDisplay<'a> { - fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - for byte in self.0 { - try!( fmtr.write_fmt(format_args!("{:02x}", byte))); - } - Ok(()) - } - } - - pub trait AsBytesRef { - fn as_bytes_ref(&self) -> &[u8]; - } - - impl AsBytesRef for [u8] { - fn as_bytes_ref(&self) -> &[u8] { &self } - } - - impl AsBytesRef for Vec { - fn as_bytes_ref(&self) -> &[u8] { &self } - } - - macro_rules! impl_non_endians { - ( $( $t:ty ),* ) => { $( - impl AsBytesRef for $t { - fn as_bytes_ref(&self) -> &[u8] { &self[..] } - } - )* } - } - - impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], - [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], - [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); - -} - #[cfg(test)] mod test { use super::*; - use super::hexdisplay::HexDisplay; #[test] fn test_vector_should_work() { @@ -238,7 +201,6 @@ mod test { fn seeded_pair_should_work() { let pair = Pair::from_seed(b"12345678901234567890123456789012"); let public = pair.public(); - println!("{}", HexDisplay::from(&public.0)); assert_eq!(public, "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".into()); let message = b"Something important"; let signature = pair.sign(&message[..]); @@ -252,8 +214,6 @@ mod test { assert_eq!(public, "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".into()); let message = FromHex::from_hex("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000").unwrap(); let signature = pair.sign(&message[..]); - println!("pub: {}", HexDisplay::from(&public.0)); - println!("sig: {}", HexDisplay::from(&signature.0)); assert!(signature.verify(&message[..], &public)); } } diff --git a/primitives/src/hashing.rs b/primitives/src/hashing.rs new file mode 100644 index 0000000000000..b21e06391eae0 --- /dev/null +++ b/primitives/src/hashing.rs @@ -0,0 +1,88 @@ +use blake2_rfc; +use twox_hash; + +/// Do a Blake2 512-bit hash and place result in `dest`. +pub fn blake2_512_into(data: &[u8], dest: &mut[u8; 64]) { + dest.copy_from_slice(blake2_rfc::blake2b::blake2b(64, &[], data).as_bytes()); +} + +/// Do a Blake2 512-bit hash and return result. +pub fn blake2_512(data: &[u8]) -> [u8; 64] { + let mut r: [u8; 64] = unsafe { ::std::mem::uninitialized() }; + blake2_512_into(data, &mut r); + r +} + +/// Do a Blake2 256-bit hash and place result in `dest`. +pub fn blake2_256_into(data: &[u8], dest: &mut[u8; 32]) { + dest.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes()); +} + +/// Do a Blake2 256-bit hash and return result. +pub fn blake2_256(data: &[u8]) -> [u8; 32] { + let mut r: [u8; 32] = unsafe { ::std::mem::uninitialized() }; + blake2_256_into(data, &mut r); + r +} + +/// Do a Blake2 128-bit hash and place result in `dest`. +pub fn blake2_128_into(data: &[u8], dest: &mut[u8; 16]) { + dest.copy_from_slice(blake2_rfc::blake2b::blake2b(16, &[], data).as_bytes()); +} + +/// Do a Blake2 128-bit hash and return result. +pub fn blake2_128(data: &[u8]) -> [u8; 16] { + let mut r: [u8; 16] = unsafe { ::std::mem::uninitialized() }; + blake2_128_into(data, &mut r); + r +} + +/// Do a XX 128-bit hash and place result in `dest`. +pub fn twox_128_into(data: &[u8], dest: &mut [u8; 16]) { + use ::std::hash::Hasher; + let mut h0 = twox_hash::XxHash::with_seed(0); + let mut h1 = twox_hash::XxHash::with_seed(1); + h0.write(data); + h1.write(data); + let r0 = h0.finish(); + let r1 = h1.finish(); + use byteorder::{ByteOrder, LittleEndian}; + LittleEndian::write_u64(&mut dest[0..8], r0); + LittleEndian::write_u64(&mut dest[8..16], r1); +} + +/// Do a XX 128-bit hash and return result. +pub fn twox_128(data: &[u8]) -> [u8; 16] { + let mut r: [u8; 16] = unsafe { ::std::mem::uninitialized() }; + twox_128_into(data, &mut r); + r +} + +/// Do a XX 256-bit hash and place result in `dest`. +pub fn twox_256_into(data: &[u8], dest: &mut [u8; 32]) { + use ::std::hash::Hasher; + use byteorder::{ByteOrder, LittleEndian}; + let mut h0 = twox_hash::XxHash::with_seed(0); + let mut h1 = twox_hash::XxHash::with_seed(1); + let mut h2 = twox_hash::XxHash::with_seed(2); + let mut h3 = twox_hash::XxHash::with_seed(3); + h0.write(data); + h1.write(data); + h2.write(data); + h3.write(data); + let r0 = h0.finish(); + let r1 = h1.finish(); + let r2 = h2.finish(); + let r3 = h3.finish(); + LittleEndian::write_u64(&mut dest[0..8], r0); + LittleEndian::write_u64(&mut dest[8..16], r1); + LittleEndian::write_u64(&mut dest[16..24], r2); + LittleEndian::write_u64(&mut dest[24..32], r3); +} + +/// Do a XX 256-bit hash and return result. +pub fn twox_256(data: &[u8]) -> [u8; 32] { + let mut r: [u8; 32] = unsafe { ::std::mem::uninitialized() }; + twox_256_into(data, &mut r); + r +} diff --git a/primitives/src/hexdisplay.rs b/primitives/src/hexdisplay.rs new file mode 100644 index 0000000000000..708d5e0528931 --- /dev/null +++ b/primitives/src/hexdisplay.rs @@ -0,0 +1,38 @@ +pub struct HexDisplay<'a>(&'a [u8]); + +impl<'a> HexDisplay<'a> { + pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) } +} + +impl<'a> ::std::fmt::Display for HexDisplay<'a> { + fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + for byte in self.0 { + try!( fmtr.write_fmt(format_args!("{:02x}", byte))); + } + Ok(()) + } +} + +pub trait AsBytesRef { + fn as_bytes_ref(&self) -> &[u8]; +} + +impl AsBytesRef for [u8] { + fn as_bytes_ref(&self) -> &[u8] { &self } +} + +impl AsBytesRef for Vec { + fn as_bytes_ref(&self) -> &[u8] { &self } +} + +macro_rules! impl_non_endians { + ( $( $t:ty ),* ) => { $( + impl AsBytesRef for $t { + fn as_bytes_ref(&self) -> &[u8] { &self[..] } + } + )* } +} + +impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], + [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], + [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index cb7606add2f4d..c774ec7f42cad 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -51,6 +51,8 @@ pub mod parachain; pub mod uint; pub mod validator; pub mod ed25519; +pub mod hexdisplay; +pub mod hashing; /// Alias to 160-bit hash when used in the context of an account address. pub type Address = hash::H160; @@ -59,94 +61,9 @@ pub type Signature = hash::H512; pub use self::hash::{H160, H256}; pub use self::uint::{U256, U512}; +pub use hashing::{blake2_256, twox_128, twox_256}; /// A hash function. pub fn hash(data: &[u8]) -> hash::H256 { blake2_256(data).into() } - -/// Do a Blake2 512-bit hash and place result in `dest`. -pub fn blake2_512_into(data: &[u8], dest: &mut[u8; 64]) { - dest.copy_from_slice(blake2_rfc::blake2b::blake2b(64, &[], data).as_bytes()); -} - -/// Do a Blake2 512-bit hash and return result. -pub fn blake2_512(data: &[u8]) -> [u8; 64] { - let mut r: [u8; 64] = unsafe { std::mem::uninitialized() }; - blake2_512_into(data, &mut r); - r -} - -/// Do a Blake2 256-bit hash and place result in `dest`. -pub fn blake2_256_into(data: &[u8], dest: &mut[u8; 32]) { - dest.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes()); -} - -/// Do a Blake2 256-bit hash and return result. -pub fn blake2_256(data: &[u8]) -> [u8; 32] { - let mut r: [u8; 32] = unsafe { std::mem::uninitialized() }; - blake2_256_into(data, &mut r); - r -} - -/// Do a Blake2 128-bit hash and place result in `dest`. -pub fn blake2_128_into(data: &[u8], dest: &mut[u8; 16]) { - dest.copy_from_slice(blake2_rfc::blake2b::blake2b(16, &[], data).as_bytes()); -} - -/// Do a Blake2 128-bit hash and return result. -pub fn blake2_128(data: &[u8]) -> [u8; 16] { - let mut r: [u8; 16] = unsafe { std::mem::uninitialized() }; - blake2_128_into(data, &mut r); - r -} - -/// Do a XX 128-bit hash and place result in `dest`. -pub fn twox_128_into(data: &[u8], dest: &mut [u8; 16]) { - use ::std::hash::Hasher; - let mut h0 = twox_hash::XxHash::with_seed(0); - let mut h1 = twox_hash::XxHash::with_seed(1); - h0.write(data); - h1.write(data); - let r0 = h0.finish(); - let r1 = h1.finish(); - use byteorder::{ByteOrder, LittleEndian}; - LittleEndian::write_u64(&mut dest[0..8], r0); - LittleEndian::write_u64(&mut dest[8..16], r1); -} - -/// Do a XX 128-bit hash and return result. -pub fn twox_128(data: &[u8]) -> [u8; 16] { - let mut r: [u8; 16] = unsafe { std::mem::uninitialized() }; - twox_128_into(data, &mut r); - r -} - -/// Do a XX 256-bit hash and place result in `dest`. -pub fn twox_256_into(data: &[u8], dest: &mut [u8; 32]) { - use ::std::hash::Hasher; - use byteorder::{ByteOrder, LittleEndian}; - let mut h0 = twox_hash::XxHash::with_seed(0); - let mut h1 = twox_hash::XxHash::with_seed(1); - let mut h2 = twox_hash::XxHash::with_seed(2); - let mut h3 = twox_hash::XxHash::with_seed(3); - h0.write(data); - h1.write(data); - h2.write(data); - h3.write(data); - let r0 = h0.finish(); - let r1 = h1.finish(); - let r2 = h2.finish(); - let r3 = h3.finish(); - LittleEndian::write_u64(&mut dest[0..8], r0); - LittleEndian::write_u64(&mut dest[8..16], r1); - LittleEndian::write_u64(&mut dest[16..24], r2); - LittleEndian::write_u64(&mut dest[24..32], r3); -} - -/// Do a XX 256-bit hash and return result. -pub fn twox_256(data: &[u8]) -> [u8; 32] { - let mut r: [u8; 32] = unsafe { std::mem::uninitialized() }; - twox_256_into(data, &mut r); - r -} From 24999109460b968f098098b716b9628e02af91d0 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 21:32:11 +0100 Subject: [PATCH 71/76] Docs and licence. --- primitives/src/ed25519.rs | 16 ++++++++++++++++ primitives/src/hashing.rs | 18 ++++++++++++++++++ primitives/src/hexdisplay.rs | 22 ++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/primitives/src/ed25519.rs b/primitives/src/ed25519.rs index cdbbc194c791f..b28e0bde6e2cc 100644 --- a/primitives/src/ed25519.rs +++ b/primitives/src/ed25519.rs @@ -1,3 +1,19 @@ +// 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 . + //! Simple Ed25519 API. use untrusted; diff --git a/primitives/src/hashing.rs b/primitives/src/hashing.rs index b21e06391eae0..f82ec7ef8bf78 100644 --- a/primitives/src/hashing.rs +++ b/primitives/src/hashing.rs @@ -1,3 +1,21 @@ +// 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 . + +//! Hashing functions. + use blake2_rfc; use twox_hash; diff --git a/primitives/src/hexdisplay.rs b/primitives/src/hexdisplay.rs index 708d5e0528931..d6299a2e41d1e 100644 --- a/primitives/src/hexdisplay.rs +++ b/primitives/src/hexdisplay.rs @@ -1,6 +1,26 @@ +// 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 . + +//! Wrapper type for byte collections that outputs hex. + +/// Simple wrapper to display hex representation of bytes. pub struct HexDisplay<'a>(&'a [u8]); impl<'a> HexDisplay<'a> { + /// Create new instance that will display `d` as a hex string when displayed. pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) } } @@ -13,7 +33,9 @@ impl<'a> ::std::fmt::Display for HexDisplay<'a> { } } +/// Simple trait to transferm various types to `&[u8]` pub trait AsBytesRef { + /// Transferm `self` into `&[u8]`. fn as_bytes_ref(&self) -> &[u8]; } From 0c53f71f2988b9acff3e454a0dd66ed412245d9a Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 22:04:18 +0100 Subject: [PATCH 72/76] Documentation. --- native-runtime/support/src/lib.rs | 18 ++++ .../polkadot/src/codec/endiansensitive.rs | 19 ++++ wasm-runtime/polkadot/src/codec/joiner.rs | 19 ++++ wasm-runtime/polkadot/src/codec/keyedvec.rs | 19 ++++ wasm-runtime/polkadot/src/codec/mod.rs | 18 ++++ wasm-runtime/polkadot/src/codec/slicable.rs | 19 ++++ .../polkadot/src/codec/streamreader.rs | 22 +++++ wasm-runtime/polkadot/src/lib.rs | 21 +++++ .../polkadot/src/runtime/consensus.rs | 18 ++++ wasm-runtime/polkadot/src/runtime/mod.rs | 18 ++++ wasm-runtime/polkadot/src/runtime/session.rs | 19 ++++ wasm-runtime/polkadot/src/runtime/staking.rs | 94 ++++++++++++------- wasm-runtime/polkadot/src/runtime/system.rs | 19 ++++ .../polkadot/src/runtime/timestamp.rs | 24 ++++- .../polkadot/src/support/environment.rs | 27 +++++- wasm-runtime/polkadot/src/support/function.rs | 19 ++++ wasm-runtime/polkadot/src/support/mod.rs | 18 ++++ .../polkadot/src/support/primitives.rs | 46 ++++++++- .../polkadot/src/support/statichex.rs | 23 +++++ wasm-runtime/polkadot/src/support/storable.rs | 23 +++++ wasm-runtime/polkadot/src/support/testing.rs | 26 +++++ 21 files changed, 488 insertions(+), 41 deletions(-) diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index caa7f3b272fcf..cd1aa00eef9dc 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -1,3 +1,21 @@ +// 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 . + +//! Support functions. + #[macro_use] extern crate environmental; extern crate polkadot_state_machine; diff --git a/wasm-runtime/polkadot/src/codec/endiansensitive.rs b/wasm-runtime/polkadot/src/codec/endiansensitive.rs index f1e042d886734..a1576284228e9 100644 --- a/wasm-runtime/polkadot/src/codec/endiansensitive.rs +++ b/wasm-runtime/polkadot/src/codec/endiansensitive.rs @@ -1,3 +1,22 @@ +// 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 . + +//! Endian manager. + +/// Trait to allow conversion to a know endian representation when sensitive. pub trait EndianSensitive: Sized { fn to_le(self) -> Self { self } fn to_be(self) -> Self { self } diff --git a/wasm-runtime/polkadot/src/codec/joiner.rs b/wasm-runtime/polkadot/src/codec/joiner.rs index 817df8e4cb6cf..92a5aa87fca97 100644 --- a/wasm-runtime/polkadot/src/codec/joiner.rs +++ b/wasm-runtime/polkadot/src/codec/joiner.rs @@ -1,6 +1,25 @@ +// 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 . + +//! Vec serialiser. + use runtime_support::Vec; use slicable::Slicable; +/// Trait to allow itself to be serialised into a `Vec` pub trait Joiner { fn join(self, value: &T) -> Self; } diff --git a/wasm-runtime/polkadot/src/codec/keyedvec.rs b/wasm-runtime/polkadot/src/codec/keyedvec.rs index fad6b1956f7d5..1f803b7c6206e 100644 --- a/wasm-runtime/polkadot/src/codec/keyedvec.rs +++ b/wasm-runtime/polkadot/src/codec/keyedvec.rs @@ -1,6 +1,25 @@ +// 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 . + +//! Serialiser and prepender. + use runtime_support::Vec; use slicable::Slicable; +/// Trait to allow itselg to be serialised and prepended by a given slice. pub trait KeyedVec { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec; } diff --git a/wasm-runtime/polkadot/src/codec/mod.rs b/wasm-runtime/polkadot/src/codec/mod.rs index 5350dc05c180f..7d9bc90c4fe12 100644 --- a/wasm-runtime/polkadot/src/codec/mod.rs +++ b/wasm-runtime/polkadot/src/codec/mod.rs @@ -1,3 +1,21 @@ +// 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 . + +//! Codec utils. + pub mod endiansensitive; pub mod streamreader; pub mod joiner; diff --git a/wasm-runtime/polkadot/src/codec/slicable.rs b/wasm-runtime/polkadot/src/codec/slicable.rs index 939d1591caecd..5ec042ec9bf5a 100644 --- a/wasm-runtime/polkadot/src/codec/slicable.rs +++ b/wasm-runtime/polkadot/src/codec/slicable.rs @@ -1,3 +1,21 @@ +// 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 . + +//! Serialisation. + use runtime_support::{Vec, size_of, transmute, uninitialized, slice}; use joiner::Joiner; use endiansensitive::EndianSensitive; @@ -22,6 +40,7 @@ pub trait Slicable: Sized { fn size_of(_value: &[u8]) -> Option; } +/// Trait to mark that a type is not trivially (essentially "in place") serialisable. pub trait NonTrivialSlicable: Slicable {} impl Slicable for T { diff --git a/wasm-runtime/polkadot/src/codec/streamreader.rs b/wasm-runtime/polkadot/src/codec/streamreader.rs index 33d6fd8bfdf35..371ceed4eeac4 100644 --- a/wasm-runtime/polkadot/src/codec/streamreader.rs +++ b/wasm-runtime/polkadot/src/codec/streamreader.rs @@ -1,17 +1,39 @@ +// 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 . + +//! Deserialiser. + use slicable::Slicable; +/// Simple deserialiser. pub struct StreamReader<'a> { data: &'a[u8], offset: usize, } impl<'a> StreamReader<'a> { + /// Create a new deserialiser based on the `data`. pub fn new(data: &'a[u8]) -> Self { StreamReader { data: data, offset: 0, } } + + /// Deserialise a single item from the data stream. pub fn read(&mut self) -> Option { let size = T::size_of(&self.data[self.offset..])?; let new_offset = self.offset + size; diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 7e8cc2233e4cf..7a96b6cee4437 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -1,3 +1,21 @@ +// 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 . + +//! The Polkadot runtime. This can be compiled with #[no_std], ready for Wasm. + #![cfg_attr(feature = "without-std", no_std)] #![cfg_attr(feature = "strict", deny(warnings))] @@ -20,11 +38,14 @@ use runtime_support::Vec; use slicable::Slicable; use primitives::{Block, UncheckedTransaction}; +/// Execute a block, with `input` being the canonical serialisation of the block. Returns the +/// empty vector. pub fn execute_block(input: Vec) -> Vec { runtime::system::execute_block(Block::from_slice(&input).unwrap()); Vec::new() } +/// Execute a given, serialised, transaction. Returns the empty vector. pub fn execute_transaction(input: Vec) -> Vec { runtime::system::execute_transaction(&UncheckedTransaction::from_slice(&input).unwrap()); Vec::new() diff --git a/wasm-runtime/polkadot/src/runtime/consensus.rs b/wasm-runtime/polkadot/src/runtime/consensus.rs index 757c032f03fa1..1e12135806f22 100644 --- a/wasm-runtime/polkadot/src/runtime/consensus.rs +++ b/wasm-runtime/polkadot/src/runtime/consensus.rs @@ -1,3 +1,21 @@ +// 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 . + +//! Conensus module for runtime; manages the authority set ready for the native code. + use runtime_support::Vec; use storable::StorageVec; use primitives::SessionKey; diff --git a/wasm-runtime/polkadot/src/runtime/mod.rs b/wasm-runtime/polkadot/src/runtime/mod.rs index 55a4801a5b979..f83922c42fe45 100644 --- a/wasm-runtime/polkadot/src/runtime/mod.rs +++ b/wasm-runtime/polkadot/src/runtime/mod.rs @@ -1,3 +1,21 @@ +// 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 . + +//! The Polkadot runtime. + #[allow(unused)] pub mod system; #[allow(unused)] diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs index b7ed1361eccd9..907b3e16b162e 100644 --- a/wasm-runtime/polkadot/src/runtime/session.rs +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -1,3 +1,22 @@ +// 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 . + +//! Session manager: is told the validators and allows them to manage their session keys for the +//! consensus module. + use runtime_support::Vec; use keyedvec::KeyedVec; use storable::{kill, Storable, StorageVec}; diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index 6b41ddbd8f850..c9fc6e9293c61 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -1,10 +1,32 @@ +// 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 . + +//! Staking manager: Handles balances and periodically determines the best set of validators. + use runtime_support::Vec; use keyedvec::KeyedVec; use storable::{Storable, StorageVec}; -use primitives::{BlockNumber, Balance, AccountID}; +use primitives::{BlockNumber, AccountID}; use runtime::{system, session}; -type Liquidity = u64; +/// The balance of an account. +pub type Balance = u64; + +/// The amount of bonding period left in an account. Measured in eras. +pub type Bondage = u64; struct IntentionStorageVec {} impl StorageVec for IntentionStorageVec { @@ -48,45 +70,13 @@ pub fn last_era_length_change() -> BlockNumber { Storable::lookup_default(b"sta:lec") } -/// The era has changed - enact new staking set. -/// -/// NOTE: This always happens on a session change. -fn new_era() { - // Increment current era. - (current_era() + 1).store(b"sta:era"); - - // Enact era length change. - let next_spe: u64 = Storable::lookup_default(b"sta:nse"); - if next_spe > 0 && next_spe != sessions_per_era() { - next_spe.store(b"sta:spe"); - system::block_number().store(b"sta:lec"); - } - - // TODO: evaluate desired staking amounts and nominations and optimise to find the best - // combination of validators, then use session::set_validators(). - - // for now, this just orders would-be stakers by their balances and chooses the top-most - // validator_count() of them. - let mut intentions = IntentionStorageVec::items() - .into_iter() - .map(|v| (balance(&v), v)) - .collect::>(); - intentions.sort_unstable_by(|&(b1, _), &(b2, _)| b2.cmp(&b1)); - session::set_validators( - &intentions.into_iter() - .map(|(_, v)| v) - .take(validator_count()) - .collect::>() - ); -} - /// The balance of a given account. pub fn balance(who: &AccountID) -> Balance { Storable::lookup_default(&who.to_keyed_vec(b"sta:bal:")) } /// The liquidity-state of a given account. -pub fn bondage(who: &AccountID) -> Liquidity { +pub fn bondage(who: &AccountID) -> Bondage { Storable::lookup_default(&who.to_keyed_vec(b"sta:bon:")) } @@ -134,6 +124,40 @@ pub fn check_new_era() { } } +// PRIVATE + +/// The era has changed - enact new staking set. +/// +/// NOTE: This always happens on a session change. +fn new_era() { + // Increment current era. + (current_era() + 1).store(b"sta:era"); + + // Enact era length change. + let next_spe: u64 = Storable::lookup_default(b"sta:nse"); + if next_spe > 0 && next_spe != sessions_per_era() { + next_spe.store(b"sta:spe"); + system::block_number().store(b"sta:lec"); + } + + // TODO: evaluate desired staking amounts and nominations and optimise to find the best + // combination of validators, then use session::set_validators(). + + // for now, this just orders would-be stakers by their balances and chooses the top-most + // validator_count() of them. + let mut intentions = IntentionStorageVec::items() + .into_iter() + .map(|v| (balance(&v), v)) + .collect::>(); + intentions.sort_unstable_by(|&(b1, _), &(b2, _)| b2.cmp(&b1)); + session::set_validators( + &intentions.into_iter() + .map(|(_, v)| v) + .take(validator_count()) + .collect::>() + ); +} + /// Set a new era length. Won't kick in until the next era change (at current length). fn set_sessions_per_era(new: BlockNumber) { new.store(b"sta:nse"); diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index f96bc40c93ff3..5ffa03ed818a7 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -1,3 +1,22 @@ +// 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 . + +//! System manager: Handles all of the top-level stuff; executing block/transaction, setting code +//! and depositing logs. + use primitives::{Block, BlockNumber, Hash, UncheckedTransaction, TxOrder, Hashable}; use runtime_support::{Vec, swap}; use storable::Storable; diff --git a/wasm-runtime/polkadot/src/runtime/timestamp.rs b/wasm-runtime/polkadot/src/runtime/timestamp.rs index c6a3ac2a9609b..7040473b1a426 100644 --- a/wasm-runtime/polkadot/src/runtime/timestamp.rs +++ b/wasm-runtime/polkadot/src/runtime/timestamp.rs @@ -1,10 +1,32 @@ -use primitives::Timestamp; +// 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 . + +//! Timestamp manager: just handles the current timestamp. + use storable::Storable; +/// Representation of a time. +pub type Timestamp = u64; + +/// Get the current time. pub fn get() -> Timestamp { Storable::lookup_default(b"tim:val") } +/// Set the current time. pub fn set(now: Timestamp) { now.store(b"tim:val") } diff --git a/wasm-runtime/polkadot/src/support/environment.rs b/wasm-runtime/polkadot/src/support/environment.rs index da2e9b18ec19f..c01a1f4e92823 100644 --- a/wasm-runtime/polkadot/src/support/environment.rs +++ b/wasm-runtime/polkadot/src/support/environment.rs @@ -1,13 +1,36 @@ +// 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 . + +//! Environment API: Allows certain information to be accessed throughout the runtime. + use runtime_support::{Rc, RefCell, transmute, Box}; use primitives::{BlockNumber, Digest}; #[derive(Default)] +/// The information that can be accessed globally. pub struct Environment { + /// The current block number. pub block_number: BlockNumber, + /// The current block digest. pub digest: Digest, + /// The number of log items in this block that have been accounted for so far. pub next_log_index: usize, } +/// Do something with the environment and return its value. Keep the function short. pub fn with_env T>(f: F) -> T { let e = env(); let mut eb = e.borrow_mut(); @@ -15,7 +38,7 @@ pub fn with_env T>(f: F) -> T { } #[cfg(not(test))] -pub fn env() -> Rc> { +fn env() -> Rc> { // Initialize it to a null value static mut SINGLETON: *const Rc> = 0 as *const Rc>; @@ -34,7 +57,7 @@ pub fn env() -> Rc> { } #[cfg(test)] -pub fn env() -> Rc> { +fn env() -> Rc> { // Initialize it to a null value thread_local!{ static SINGLETON: RefCell<*const Rc>> = RefCell::new(0 as *const Rc>); diff --git a/wasm-runtime/polkadot/src/support/function.rs b/wasm-runtime/polkadot/src/support/function.rs index f0be93c4af3b8..f4ee9c79e6e4d 100644 --- a/wasm-runtime/polkadot/src/support/function.rs +++ b/wasm-runtime/polkadot/src/support/function.rs @@ -1,3 +1,21 @@ +// 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 . + +//! Function data: This describes a function that can be called from an external transaction. + use primitives::AccountID; use streamreader::StreamReader; use runtime::{staking, session, timestamp}; @@ -14,6 +32,7 @@ pub enum Function { } impl Function { + /// Derive `Some` value from a `u8`, or `None` if it's invalid. pub fn from_u8(value: u8) -> Option { match value { x if x == Function::StakingStake as u8 => Some(Function::StakingStake), diff --git a/wasm-runtime/polkadot/src/support/mod.rs b/wasm-runtime/polkadot/src/support/mod.rs index 802476cc1b1e2..56ad3a355c5b2 100644 --- a/wasm-runtime/polkadot/src/support/mod.rs +++ b/wasm-runtime/polkadot/src/support/mod.rs @@ -1,3 +1,21 @@ +// 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 . + +//! Support code for the runtime. + pub mod primitives; pub mod function; pub mod environment; diff --git a/wasm-runtime/polkadot/src/support/primitives.rs b/wasm-runtime/polkadot/src/support/primitives.rs index dbe75aad1181f..3ab385d488933 100644 --- a/wasm-runtime/polkadot/src/support/primitives.rs +++ b/wasm-runtime/polkadot/src/support/primitives.rs @@ -1,3 +1,21 @@ +// 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 . + +//! Primitive types. + use runtime_support::Vec; use streamreader::StreamReader; use joiner::Joiner; @@ -13,26 +31,36 @@ pub type AccountID = [u8; 32]; /// The Ed25519 pub key of an session that belongs to an authority. This is used as what the /// external environment/consensus algorithm calls an "authority". pub type SessionKey = AccountID; -pub type Balance = u64; +/// Indentifier for a chain. pub type ChainID = u64; -pub type Hash = [u8; 32]; +/// Index of a block in the chain. pub type BlockNumber = u64; -pub type Timestamp = u64; +/// Index of a transaction. pub type TxOrder = u64; +/// A hash of some data. +pub type Hash = [u8; 32]; #[derive(Clone, Default)] #[cfg_attr(test, derive(PartialEq, Debug))] +/// The digest of a block, useful for light-clients. pub struct Digest { + /// All logs that have happened in the block. pub logs: Vec>, } #[derive(Clone)] #[cfg_attr(test, derive(PartialEq, Debug))] +/// The header for a block. pub struct Header { + /// The parent block's "hash" (actually the Blake2-256 hash of its serialised header). pub parent_hash: Hash, + /// The block's number (how many ancestors does it have?). pub number: BlockNumber, + /// The root of the trie that represents this block's final storage map. pub state_root: Hash, + /// The root of the trie that represents this block's transactions, indexed by a 32-bit integer. pub transaction_root: Hash, + /// The digest for this block. pub digest: Digest, } @@ -71,10 +99,15 @@ impl Slicable for Header { impl NonTrivialSlicable for Header {} #[cfg_attr(test, derive(PartialEq, Debug))] +/// A vetted and verified transaction from the external world. pub struct Transaction { + /// Who signed it (note this is not a signature). pub signed: AccountID, + /// The number of transactions have come before from the same signer. pub nonce: TxOrder, + /// The function that should be called. pub function: Function, + /// Serialised input data to the function. pub input_data: Vec, } @@ -128,12 +161,16 @@ impl Hashable for T { impl NonTrivialSlicable for Transaction {} +/// A transactions right from the external world. Unchecked. pub struct UncheckedTransaction { + /// The actual transaction information. pub transaction: Transaction, + /// The signature; should be an Ed25519 signature applied to the serialised `transaction` field. pub signature: [u8; 64], } impl UncheckedTransaction { + /// Verify the signature. pub fn ed25519_verify(&self) -> bool { let msg = self.transaction.to_vec(); ed25519_verify(&self.signature, &msg, &self.transaction.signed) @@ -183,8 +220,11 @@ impl Slicable for UncheckedTransaction { impl NonTrivialSlicable for UncheckedTransaction {} #[cfg_attr(test, derive(PartialEq, Debug))] +/// A Polkadot relay chain block. pub struct Block { + /// The header of the block. pub header: Header, + /// All transactions. pub transactions: Vec, } diff --git a/wasm-runtime/polkadot/src/support/statichex.rs b/wasm-runtime/polkadot/src/support/statichex.rs index 774cb82538ba4..152ceadc0b444 100644 --- a/wasm-runtime/polkadot/src/support/statichex.rs +++ b/wasm-runtime/polkadot/src/support/statichex.rs @@ -1,6 +1,26 @@ +// 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 . + +//! Interpret a static string of hex as a desired type. + use rustc_hex::FromHex; +/// Trait to allow conversion from a static hex string to an instance. pub trait StaticHexConversion: Sized { + /// Convert the static str into Self. Use just like `From::from`. fn from_static_hex(hex: &'static str) -> Self; } @@ -18,7 +38,10 @@ macro_rules! impl_sizes { impl_sizes!(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128); +/// Trait to allow converting from itself (only implemented for a static str) into some useful +/// type (which must implement `StaticHexConversion`). pub trait StaticHexInto { + /// Convert self (i.e. a static str) into the appropriate type. Use just like `Into::into`. fn convert(self) -> T; } diff --git a/wasm-runtime/polkadot/src/support/storable.rs b/wasm-runtime/polkadot/src/support/storable.rs index 80c7af2136d2b..3caf3ed19bfae 100644 --- a/wasm-runtime/polkadot/src/support/storable.rs +++ b/wasm-runtime/polkadot/src/support/storable.rs @@ -1,16 +1,39 @@ +// 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 . + +//! Stuff to do with the runtime's storage. + use slicable::Slicable; use endiansensitive::EndianSensitive; use keyedvec::KeyedVec; use runtime_support::{self, twox_128, Vec}; +/// Trait for a value which may be stored in the storage DB. pub trait Storable { + /// Lookup the value in storage and deserialise, giving a default value if not found. fn lookup_default(key: &[u8]) -> Self where Self: Sized + Default { Self::lookup(key).unwrap_or_else(Default::default) } + /// Lookup `Some` value in storage and deserialise; `None` if it's not there. fn lookup(_key: &[u8]) -> Option where Self: Sized { unimplemented!() } + /// Place the value in storage under `key`. fn store(&self, key: &[u8]); } // TODO: consider using blake256 to avoid possible eclipse attack. +/// Remove `key` from storage. pub fn kill(key: &[u8]) { runtime_support::set_storage(&twox_128(key)[..], b""); } impl Storable for T { diff --git a/wasm-runtime/polkadot/src/support/testing.rs b/wasm-runtime/polkadot/src/support/testing.rs index a617405e793e6..e2e7b40562e51 100644 --- a/wasm-runtime/polkadot/src/support/testing.rs +++ b/wasm-runtime/polkadot/src/support/testing.rs @@ -1,10 +1,30 @@ +// 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 . + +//! Testing helpers. + use runtime_support::{NoError, Externalities}; use std::collections::HashMap; use primitives::AccountID; use statichex::StaticHexInto; #[derive(Debug, Default)] +/// Simple externaties implementation. pub struct TestExternalities { + /// The storage map. pub storage: HashMap, Vec>, } @@ -29,16 +49,20 @@ macro_rules! map { ) } +/// One account (to which we know the secret key). pub fn one() -> AccountID { "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".convert() } +/// Another account (secret key known). pub fn two() -> AccountID { "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".convert() } +/// Hex display, this time for no_std. See main codebase for documentation. pub struct HexDisplay<'a>(&'a [u8]); impl<'a> HexDisplay<'a> { + /// See main codebase for documentation. pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) } } @@ -51,7 +75,9 @@ impl<'a> ::std::fmt::Display for HexDisplay<'a> { } } +/// See main codebase for documentation. pub trait AsBytesRef { + /// See main codebase for documentation. fn as_bytes_ref(&self) -> &[u8]; } From 850f7eea37a05505aba78dab737c6524736b729f Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 22:09:01 +0100 Subject: [PATCH 73/76] Remove superfluous code. --- native-runtime/support/src/lib.rs | 26 ++++-------------- wasm-runtime/support/src/lib.rs | 17 ------------ .../release/runtime_polkadot.compact.wasm | Bin 37802 -> 37802 bytes .../release/runtime_polkadot.wasm | Bin 37859 -> 37859 bytes 4 files changed, 5 insertions(+), 38 deletions(-) diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index cd1aa00eef9dc..348c0b17a9ccb 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Support functions. +//! The with-std support functions for the runtime. #[macro_use] extern crate environmental; @@ -36,6 +36,7 @@ pub use polkadot_state_machine::Externalities; // TODO: use the real error, not NoError. #[derive(Debug)] +/// As it says - an empty type we use for errors. pub struct NoError; impl fmt::Display for NoError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "") } @@ -43,12 +44,15 @@ impl fmt::Display for NoError { environmental!(ext : Externalities + 'static); +/// Get `key` from storage and return a `Vec`, empty if there's a problem. pub fn storage(key: &[u8]) -> Vec { ext::with(|ext| ext.storage(key).ok().map(|s| s.to_vec())) .unwrap_or(None) .unwrap_or_else(|| vec![]) } +/// Get `key` from storage, placing the value into `value_out` (as much as possible) and return +/// the number of bytes that the key in storage was. pub fn read_storage(key: &[u8], value_out: &mut [u8]) -> usize { ext::with(|ext| { if let Ok(value) = ext.storage(key) { @@ -61,24 +65,6 @@ pub fn read_storage(key: &[u8], value_out: &mut [u8]) -> usize { }).unwrap_or(0) } -pub fn storage_into(_key: &[u8]) -> Option { - let size = size_of::(); - - ext::with(|ext| { - if let Ok(value) = ext.storage(_key) { - if value.len() == size { - unsafe { - let mut result: T = std::mem::uninitialized(); - std::slice::from_raw_parts_mut(transmute::<*mut T, *mut u8>(&mut result), size) - .copy_from_slice(&value); - return Some(result); - } - } - } - None - }).unwrap_or(None) -} - pub fn set_storage(key: &[u8], value: &[u8]) { ext::with(|ext| ext.set_storage(key.to_vec(), value.to_vec()) @@ -149,8 +135,6 @@ mod tests { assert_eq!(storage(b"hello"), b"world".to_vec()); assert_eq!(storage(b"foo"), b"".to_vec()); set_storage(b"foo", &[1, 2, 3][..]); - assert_eq!(storage_into::<[u8; 3]>(b"foo"), Some([1, 2, 3])); - assert_eq!(storage_into::<[u8; 3]>(b"hello"), None); true })); diff --git a/wasm-runtime/support/src/lib.rs b/wasm-runtime/support/src/lib.rs index bc987ff3964f3..b65b574351554 100644 --- a/wasm-runtime/support/src/lib.rs +++ b/wasm-runtime/support/src/lib.rs @@ -43,23 +43,6 @@ pub fn storage(key: &[u8]) -> Vec { } } -pub fn storage_into(key: &[u8]) -> Option { - let mut result: T; - let size = size_of::(); - let written; - unsafe { - result = uninitialized(); - let result_as_byte_blob = transmute::<*mut T, *mut u8>(&mut result); - written = ext_get_storage_into(&key[0], key.len() as u32, result_as_byte_blob, size as u32) as usize; - } - // Only return a fully written value. - if written == size { - Some(result) - } else { - None - } -} - pub fn set_storage(key: &[u8], value: &[u8]) { unsafe { ext_set_storage( diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm index 5f357f211861828f797bbe3bf8388b2839067a07..ddd9dc70e64e3b02e101f88ad65bd0a5af897e86 100644 GIT binary patch delta 108 zcmZ3roN3i^rVamO7@utZFC(c1q$J&0S%8$hw-6`O8-~d`4oaItLoP5fzS*o6<_)5X z!b9X4zf2aWFxmXO%tl6qqqro|Dk(9?iox*>12=@1p9kc9Vc=#5$>kNNPL7`J4*;MS BCiVaT delta 108 zcmZ3roN3i^rVamO7~gFEFC(c1q$J&0S%8$hw-6`O7lz3?4oaItLoP5fe%Y)R<_)5X z!b9X4pG+30FxmXO%tl6qy|^UNDz7+|!SM|PHwTE5l$c}1;P?f`%g?i#96i||0Iy9a A761SM diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm index 700194bb0a902a08b3704ed1a25f78b67a0e113e..8d3d3fb1ee5ffba092f881fdbe5e5c3780f7d23b 100644 GIT binary patch delta 107 zcmaF7oaym$rVTo>j88V}%1UYhDR*~P79i#8EyT(AW^+QwXGX?1lM_NjH)n>K0hyZ@ zgons8ewl1nVX|4X++9Y6qqro|Dk(9?iox*>12=@1p9kc9Vc=#5$>kNNPM$K^9{^sN BCWin3 delta 107 zcmaF7oaym$rVTo>jBhsU%1UYhDR*~P79i#8EyT(AWphHvXGX>^lM_NjH)n>K0hyZ@ zgons8KACJ+VX|4X++9Y6y|^UNDz7+|!SM|PHwTE5l$c}1;P?f`%g?i#JY}*!0Bz4E ArvLx| From dde319cc2f35cfd51f7220dc3f9841492e2a8acc Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 22:39:47 +0100 Subject: [PATCH 74/76] Remove dummy key. --- pkcs8.key | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 pkcs8.key diff --git a/pkcs8.key b/pkcs8.key deleted file mode 100644 index 250fbac646b9f..0000000000000 --- a/pkcs8.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDMpfNjaigc9FKC -8owWoKvAua3O1es2CB7Gq6pFI4Ctv34Wt5XSk83XkSXLOsf2ib1zCpzLUQSVLtH1 -c05uTH6rXLmjbH3lFOUCqD41dIveqo72sekHnYjS23ME2v5JCkg9YFmn32FffHGt -2Uaho+MQZWbpT3SD5tKRdaUUx1f/i16oB4Fnk8zCdQ7NPFru+WUV0cvQnK3rOpOo -KbK59Jo04bHmf/EPeVmxonwt/nmAJRUemuQXPl1cH8sk+t6Bxxp9FLzX6rtmpGDk -mBwrYBNC5auT3L1V2xabI2TKobd/qa+9/Sz41PeHsYLX/cu9Iplvj+LU85gYwv5d -kjvMEI7pAgMBAAECggEBAID7z21HSUUGkMLL0JOqbNYpsWx906PYdl1NcSHmgIIC -AZyb1ShF1CUb7LAsuj+fDPLnK2/R/otwWRDUvggy2ltzM+XWyXqLMtP76kmSzV1o -Lnc6Jt+P4N7VRac3x7GNc36LrbZqylp+er/SA/x46PI6lyRR2eQQpYLcnVF9Wu9K -bbTQ9nH+hxJiRG85GXKjeFkIj7PXBYAiYYcgiPF1RfB3o2R0cXZI24Y5/Ufc3OKg -Jws/VsTIzoxoLd3u6rDKX/N40/VBrGqv76HFqVwgnbxeG+i6HZNIAvZn+6m3a6l5 -APIZp7FfLJ1vZaHP7S7GeNmcz+eJ9Y/FanItohJGfqECgYEA5d17o9Ol3H+6wkQk -a3LU03NfvcdU5TqTOGvzx6yGGASjlByZWb7rMsRMyQ/wP60j+2Hd/G4rXbkF6vee -5uen7geJ6bzhUev1nd1NDcVdZay8x0r3huePUV96k+wU1IrOZrZddlqPyUJMctDy -VbwbDPM0saGx0xIlx/JOC1kEEr0CgYEA4+p/TSEq9DWH5QaMlVxBp48HY4Yrv/gQ -UmNUbCyd7J21Re+7cY3ZGF5IoC2l4K4yPM6ovNipkX9WDZrw8T68sD8yTQzL/tDE -CuXxG+X0b81k5UiZBFIGXiBb8JpoHRKNNGjZTZyBNhOKc902oKoNyTKILX3qI/aL -M2v/SELm5Z0CgYEAx+XZnPn09pF5t3GM/ogpPw3Jh/+t+376AooWwWFuZ7q5Cpfo -YFygq1B8uimLM8T9UqKkat7gBaxe0hyvanyw1FZoAAXLKPP7cGLAnKYzd7VFoka2 -hfIf95MBxVv8LW3c2wPiuYc+HbbzRrIg3KAuIg/qlkNYoobYpk44wrOR0D0CgYB0 -RNeGaGo6ROi7nHixZWwU57FUQ0kkWI8zCHsz6Br0b4vfTqooBr3+YXLZTBA4K4Vz -YdXQ6RKwJ+6laCqMV334x3SIvAOBTc0E5kL3AXuOYZCcK0nsW0/mSsm8V3jPg/xH -BUn9/t4n0RYrf2lz0uzPfBjeZELC7+4ZYHnNyltyPQKBgQCvT40UwZ5yHAt3leWG -stGRTkbupenh2z23hXY0Cio8Zqa7KE5jBWdF4uu27ScK4rhFdS1sgQJFghj6SxRO -VT5PQuRP9ETJIVwNgNQbAxbfeg8DADKGAWX9W5r//WlW1xH0/tSAxX6Pp/IiT9or -cRljrhP8zW6qhj3BKjdivPDgPw== ------END PRIVATE KEY----- From 17ef2d0da5bf4cb36da603d215394a0d31957dd5 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 22:40:25 +0100 Subject: [PATCH 75/76] Remove other superfluous file. --- ed25519.pk8 | Bin 85 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 ed25519.pk8 diff --git a/ed25519.pk8 b/ed25519.pk8 deleted file mode 100644 index 57a8e9f84df1dc3175d02132f88bf7d03563ed8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85 zcmV-b0IL5mQvv}2Fa-t!D`jv5A_O2jp9~yh%qqhDL7XlV#y11mAEmT)YK|2S8mY`X rKcB~;BLg7-wIOt@fg3EC6j=CGA>0MTxofFio@CXjjO!~zYbh_!erz9j From 8adb7c67f8c0493ad1c91dbbae1675abd45633e8 Mon Sep 17 00:00:00 2001 From: Gav Date: Sat, 20 Jan 2018 09:48:33 +0100 Subject: [PATCH 76/76] Optimise with swap_remove --- wasm-runtime/polkadot/src/runtime/staking.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index c9fc6e9293c61..fc7c12798e3ed 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -99,7 +99,7 @@ pub fn transfer(transactor: &AccountID, dest: &AccountID, value: Balance) { pub fn stake(transactor: &AccountID) { let mut intentions = IntentionStorageVec::items(); // can't be in the list twice. - assert!(intentions.iter().find(|t| *t == transactor).is_none()); + assert!(intentions.iter().find(|t| *t == transactor).is_none(), "Cannot stake if already staked."); intentions.push(transactor.clone()); IntentionStorageVec::set_items(&intentions); u64::max_value().store(&transactor.to_keyed_vec(b"sta:bon:")); @@ -110,8 +110,11 @@ pub fn stake(transactor: &AccountID) { /// Effects will be felt at the beginning of the next era. pub fn unstake(transactor: &AccountID) { let mut intentions = IntentionStorageVec::items(); - // TODO: use swap remove. - let intentions = intentions.into_iter().filter(|t| t != transactor).collect::>(); + if let Some(position) = intentions.iter().position(|t| t == transactor) { + intentions.swap_remove(position); + } else { + panic!("Cannot unstake if not already staked."); + } IntentionStorageVec::set_items(&intentions); (current_era() + bonding_duration()).store(&transactor.to_keyed_vec(b"sta:bon:")); }