diff --git a/substrate/runtime/polkadot/src/lib.rs b/substrate/runtime/polkadot/src/lib.rs index d2143f28cd..4993b009b4 100644 --- a/substrate/runtime/polkadot/src/lib.rs +++ b/substrate/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 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() - } -} -*/ +use runtime_support::{set_storage, storage, storage_into}; /// The hash of an ECDSA pub key which is used to identify an external transactor. -type AccountID = [u8; 32]; +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". -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; +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; -struct Digest { - logs: Vec>, +/// The functions that a transaction can call (and be dispatched to). +pub enum Function { + StakingStake(), + StakingUnstake(), + ConsensusSetSessionKey(SessionKey), } -struct Header { - parent_hash: Hash, - number: BlockNumber, - state_root: Hash, - transaction_root: Hash, - digest: Digest, +impl Function { + /// Dispatch the function. + pub fn dispatch(self) -> Vec { unimplemented!() } } -struct Transaction { - senders: Vec, - function_name: String, - input_data: Vec, - nonce: TxOrder, +pub struct Digest { + pub logs: Vec>, } -struct Block { - header: Header, - transactions: Vec, +pub struct Header { + pub parent_hash: Hash, + pub number: BlockNumber, + pub state_root: Hash, + pub transaction_root: Hash, + pub digest: Digest, +} + +pub struct Transaction { + pub senders: Vec, + pub function: Function, + pub input_data: Vec, + pub nonce: TxOrder, +} + +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/substrate/runtime/support/src/lib.rs b/substrate/runtime/support/src/lib.rs index 4430f7249f..3114446880 100644 --- a/substrate/runtime/support/src/lib.rs +++ b/substrate/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) - }; + $( + #[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) - } + let output = super::$name(input); + &output[0] as *const u8 as u64 + ((output.len() as u64) << 32) + } + )* } } } diff --git a/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm index 6ce8afb77c..be2ae9b30e 100644 Binary files a/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm and b/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm differ diff --git a/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm b/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm index 9fe583e7e4..228d1aaf0c 100644 Binary files a/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm and b/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm differ diff --git a/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 6ce8afb77c..bac77de7ff 100644 Binary files a/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm and b/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm differ diff --git a/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm b/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm index 9fe583e7e4..9f8b8bc2e8 100644 Binary files a/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm and b/substrate/runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm differ diff --git a/substrate/runtime/test/src/lib.rs b/substrate/runtime/test/src/lib.rs index 550e06c05d..e95844fdb0 100644 --- a/substrate/runtime/test/src/lib.rs +++ b/substrate/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);