Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
36c171c
Introduce basic skeleton for Polkador runtime.
gavofyork Jan 8, 2018
f79b7bb
Clean up the runtime skeleton.
gavofyork Jan 8, 2018
b48e053
Make initial runtime skeleton compile.
gavofyork Jan 8, 2018
4e25b24
Compile polkadot-runtime both for Wasm ad native, allowing for testin…
gavofyork Jan 9, 2018
b28402c
More fleshing out on runtime.
gavofyork Jan 9, 2018
bac50a4
Update native support.
gavofyork Jan 9, 2018
9a4360f
Fix warning.
gavofyork Jan 9, 2018
0890e72
Update gitignore
gavofyork Jan 9, 2018
4cf5fd1
Update path.
gavofyork Jan 9, 2018
12b15fd
Fix path.
gavofyork Jan 9, 2018
47260c2
Remove accidentally committed files.
gavofyork Jan 9, 2018
800eb20
Add wasm binaries.
gavofyork Jan 9, 2018
10eaefe
Fix test.
gavofyork Jan 9, 2018
24ba809
Native storage support API.
gavofyork Jan 9, 2018
36a49ff
Add environmental module
gavofyork Jan 10, 2018
50e7222
Add native environment to make native source-code compatible with wasm.
gavofyork Jan 10, 2018
3e17caa
Finish up & polish environment stuff.
gavofyork Jan 10, 2018
e807c9a
Avoid using reentrancy issues.
gavofyork Jan 10, 2018
402ae29
Add some docs and a test.
gavofyork Jan 10, 2018
762826b
Remove unneeded function.
gavofyork Jan 10, 2018
7e969c8
Documentation
gavofyork Jan 11, 2018
64b0670
Tweak docs
gavofyork Jan 11, 2018
d34f62a
Remove TODOs.
gavofyork Jan 11, 2018
89f35e3
Balance transfers + util methods.
gavofyork Jan 14, 2018
5e42240
Rejig tests and ensure authorities are addressed consistently.
gavofyork Jan 14, 2018
d97e2d6
Add marshaller for xfer function
gavofyork Jan 14, 2018
26ccc14
Transaction dispatch test.
gavofyork Jan 15, 2018
7258e1f
Minor fix.
gavofyork Jan 15, 2018
c02e335
Add test for ser/de transaction.
gavofyork Jan 15, 2018
28fa761
Add ser/de for header.
gavofyork Jan 15, 2018
cd93a37
Add tests for header ser/de
gavofyork Jan 16, 2018
b55095a
Introduce basic block decoding/execution framework.
gavofyork Jan 16, 2018
288f653
Introduce block decoding/execution framework (p2)
gavofyork Jan 16, 2018
c64976b
Big refactor.
gavofyork Jan 16, 2018
40e28fc
Split out joiner.
gavofyork Jan 16, 2018
ab37f64
Hide away support modules.
gavofyork Jan 16, 2018
4844086
Fix up wasm runtime.
gavofyork Jan 16, 2018
28d775d
use externalities for chain_id
gavofyork Jan 16, 2018
75cedd9
Clean up (Test)Externalities.
gavofyork Jan 16, 2018
0feadc6
Repot and introduce keccak-256 external.
gavofyork Jan 17, 2018
15ae775
Signing with crypto.
gavofyork Jan 17, 2018
5650997
fix unsafety hole in environmental using function
rphmeier Jan 17, 2018
7820149
Introduce Ed25519 crypto.
gavofyork Jan 17, 2018
4ef4239
Repotting.
gavofyork Jan 17, 2018
8fa858c
Merge branch 'signing-ring' into polkadot-runtime-skeleton
gavofyork Jan 17, 2018
78a22d4
Add ed25519_verify external.
gavofyork Jan 17, 2018
93f7aed
Introduce Ed25519 verify as an external.
gavofyork Jan 17, 2018
cdc1387
fix unsafety hole around unwinding
rphmeier Jan 17, 2018
0477b7e
Compile fixes.
gavofyork Jan 17, 2018
66c9384
use new environmental API
rphmeier Jan 17, 2018
121aa0b
Merge branch 'polkadot-runtime-skeleton' into environmental-api
rphmeier Jan 17, 2018
eebc071
Tests for ed25519 verify.
gavofyork Jan 18, 2018
5685173
Polish
gavofyork Jan 18, 2018
f3d415c
Introduce UncheckedTransaction & test.
gavofyork Jan 18, 2018
2c9cb7b
Implement basic block and tx processing
gavofyork Jan 18, 2018
eda7d71
Introduce static hex and valid signature for block test.
gavofyork Jan 18, 2018
fd9d8dc
Merge pull request #35 from paritytech/environmental-api
gavofyork Jan 18, 2018
e8cd918
Repot session.
gavofyork Jan 18, 2018
3d1ff94
comments.
gavofyork Jan 18, 2018
92a12f0
Refactor and timestamp test
gavofyork Jan 19, 2018
5523277
Remove fluff
gavofyork Jan 19, 2018
39128b7
Merge branch 'polkadot-runtime-skeleton' of github.com:paritytech/pol…
gavofyork Jan 19, 2018
9a8f61d
Remove fluff.
gavofyork Jan 19, 2018
90f965a
Staking eras and tests.
gavofyork Jan 19, 2018
58670fc
Implement sessions.
gavofyork Jan 19, 2018
999025f
Polish
gavofyork Jan 19, 2018
4fde6f0
Test sessions.
gavofyork Jan 19, 2018
9c8cafd
Introduce better hashing.
gavofyork Jan 19, 2018
ae5a9c9
Fix tests.
gavofyork Jan 19, 2018
639554c
Introduce staking.
gavofyork Jan 19, 2018
0e88dad
Tests for simple staking system.
gavofyork Jan 19, 2018
80aa38c
Build fix for wasm.
gavofyork Jan 19, 2018
ef5d78a
Fix tests.
gavofyork Jan 19, 2018
e068f44
Repotting and docs.
gavofyork Jan 19, 2018
2499910
Docs and licence.
gavofyork Jan 19, 2018
0c53f71
Documentation.
gavofyork Jan 19, 2018
850f7ee
Remove superfluous code.
gavofyork Jan 19, 2018
dde319c
Remove dummy key.
gavofyork Jan 19, 2018
17ef2d0
Remove other superfluous file.
gavofyork Jan 19, 2018
8adb7c6
Optimise with swap_remove
gavofyork Jan 20, 2018
cbd65cb
Merge remote-tracking branch 'origin/master' into polkadot-runtime-sk…
gavofyork Jan 23, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions executor/src/wasm_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl WritePrimitive<u32> 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);
Expand All @@ -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
Expand All @@ -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;
Expand All @@ -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>
);
Expand Down Expand Up @@ -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() })?;

Expand Down Expand Up @@ -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");

Expand Down
311 changes: 293 additions & 18 deletions runtime/polkadot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,304 @@ 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};

impl_stub!(test_data_in);
fn test_data_in(input: Vec<u8>) -> Vec<u8> {
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.
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;

print(b"code" as &[u8]);
set_storage(b"code", &code());
/// The functions that a transaction can call (and be dispatched to).
pub enum Function {
StakingStake(),
StakingUnstake(),
ConsensusSetSessionKey(SessionKey),
}

impl Function {
/// Dispatch the function.
pub fn dispatch(self) -> Vec<u8> { unimplemented!() }
}

pub struct Digest {
pub logs: Vec<Vec<u8>>,
}

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 {
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!()
}
}

/*
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)

fn execute_block(_input: Vec<u8>) -> Vec<u8> {
let block = Block::from_rlp(&_input);
environment::execute_block(&block)
}

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
unimplemented!()
}

print(b"set_code" as &[u8]);
set_code(&input);
mod environment {
use super::*;

print(b"storage" as &[u8]);
let copy = storage(b"input");
/// The current block number being processed. Set by `execute_block`.
pub fn block_number() -> BlockNumber { unimplemented!() }

print(b"validators" as &[u8]);
let mut v = validators();
v.push(copy);
/// 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<u8> {
// 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: &Transaction) -> Vec<u8> {
// TODO: decode data and ensure valid
// 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()
}

/// Set the new code.
pub fn set_code(new: &[u8]) {
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!()
}
}

mod consensus {
use super::*;

fn value_vec(mut value: usize, initial: Vec<u8>) -> Vec<u8> {
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())).unwrap()
}

fn set_authority_count(count: usize) {
(count..authority_count()).for_each(|i| set_authority(i, SessionKey::default()));
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<AccountID> {
(0..authority_count()).into_iter().map(authority).collect()
}

/// 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));
}

/// 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<AccountID> {
unimplemented!()
}

/// Set the current set of validators.
///
/// Called by staking::next_era() only.
pub fn set_validators(_new: &[AccountID]) {
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!()
}

/// 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 {
use super::*;

/// 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!() }

/// Transfer some unlocked staking balance to another staker.
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() { unimplemented!() }

/// Retract the desire to stake.
///
/// Effects will be felt at the beginning of the next era.
fn unstake() { 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();
}
}

mod authentication {
use super::*;

fn validate_signature(_tx: Transaction) -> ( AccountID, TxOrder ) { unimplemented!() }
fn nonce(_id: AccountID) -> TxOrder { unimplemented!() }
fn authenticate(_tx: Transaction) -> AccountID { unimplemented!() }
}

print(b"set_validators" as &[u8]);
set_validators(&v.iter().map(Vec::as_slice).collect::<Vec<_>>());
mod timestamp {
use super::*;

print(b"finished!" as &[u8]);
b"all ok!".to_vec()
fn timestamp() -> Timestamp { unimplemented!() }
fn set_timestamp(_now: Timestamp) { unimplemented!() }
}
Loading