Make initial runtime skeleton compile.

This commit is contained in:
Gav
2018-01-08 19:32:46 +01:00
parent a9fe12eb69
commit 5ab59bb171
7 changed files with 123 additions and 102 deletions
+98 -75
View File
@@ -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<RefCell<Environment>>,
}
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<Vec<u8>>,
/// 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<u8> { unimplemented!() }
}
struct Transaction {
senders: Vec<AccountID>,
function_name: String,
input_data: Vec<u8>,
nonce: TxOrder,
pub struct Digest {
pub logs: Vec<Vec<u8>>,
}
struct Block {
header: Header,
transactions: Vec<Transaction>,
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<AccountID>,
pub function: Function,
pub input_data: Vec<u8>,
pub nonce: TxOrder,
}
pub struct Block {
pub header: Header,
pub transactions: Vec<Transaction>,
}
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<Header>,
current_user: Option<AccountID>,
}
#[derive(Clone)]
struct EnvironmentHolder {
inner: Rc<RefCell<Environment>>,
}
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<u8>) -> Vec<u8> {
let block = Block::from_rlp(&_input);
environment::execute_block(&block)
}
impl_stub!(execute_transaction);
fn execute_transaction(_input: Vec<u8>) -> Vec<u8> {
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<u8>) -> Vec<u8> {
let mut acc = initial;
while value > 0 {
@@ -177,11 +197,11 @@ mod consensus {
}
fn authority(index: usize) -> AccountID {
storage_into::<Value20>(&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<AccountID> {
(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!() }
}
+24 -26
View File
@@ -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<u8> {
}
}
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<T: IsValue>(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<T: Sized>(key: &[u8]) -> Option<T> {
let mut result: T;
let size = mem::size_of::<T>();
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<T: Printable + Sized>(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)
}
)*
}
}
}
+1 -1
View File
@@ -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<u8>) -> Vec<u8> {
print(b"set_storage" as &[u8]);
set_storage(b"input", &input);