Collator for the "adder" (formerly basic-add) parachain and various small fixes (#438)

* update basic_add wasm

* wasm feature and collator feature

* move test parachains around a little

* fix wasm build for basic_add

* move basic_add to adder, introduce README

* minimal basic_add collator

* ensure collator messages are sent in the right order

* more logging

* route consensus statements to all peers

* minor bugfixes for parachains

* genesis builder accounts for parachain heads

* fix parachains tests

* targets for txpool

* tweak runtime + collator

* fix version in adder-collator

* consistency for overflowing

* adjust comment

* fix stable test run

* remove dummy registration test

* final grumbles
This commit is contained in:
Robert Habermeier
2018-08-01 17:04:04 +02:00
committed by GitHub
parent f5aa4f6f79
commit f4cd995558
27 changed files with 569 additions and 333 deletions
@@ -1,2 +0,0 @@
target/
Cargo.lock
@@ -1,25 +0,0 @@
[package]
name = "basic_add"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
description = "Test parachain which adds to a number as its state transition"
[lib]
crate-type = ["cdylib"]
[dependencies]
polkadot-parachain = { path = "../../", default-features = false }
wee_alloc = "0.4.1"
tiny-keccak = "1.4"
pwasm-libc = "0.2"
[features]
default = ["std"]
std = ["polkadot-parachain/std"]
[profile.release]
panic = "abort"
lto = true
[workspace]
members = []
@@ -1,12 +0,0 @@
#!/usr/bin/env bash
set -e
# Make LLD produce a binary that imports memory from the outside environment.
export RUSTFLAGS="-C link-arg=--import-memory"
cargo +nightly build --target=wasm32-unknown-unknown --release --no-default-features
for i in basic_add
do
wasm-gc target/wasm32-unknown-unknown/release/$i.wasm target/wasm32-unknown-unknown/release/$i.compact.wasm
done
@@ -1,142 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Basic parachain that adds a number as part of its state.
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(
not(feature = "std"),
feature(
alloc, core_intrinsics, lang_items, panic_implementation, core_panic_info,
alloc_error_handler
)
)]
#[cfg(not(feature = "std"))]
extern crate alloc;
extern crate polkadot_parachain as parachain;
extern crate wee_alloc;
extern crate tiny_keccak;
extern crate pwasm_libc;
use parachain::codec::{Decode, Encode, Input, Output};
#[cfg(not(feature = "std"))]
mod wasm;
#[cfg(not(feature = "std"))]
pub use wasm::*;
// Define global allocator.
#[cfg(not(feature = "std"))]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
// Head data for this parachain.
#[derive(Default, Clone)]
struct HeadData {
// Block number
number: u64,
// parent block keccak256
parent_hash: [u8; 32],
// hash of post-execution state.
post_state: [u8; 32],
}
impl Encode for HeadData {
fn encode_to<T: Output>(&self, dest: &mut T) {
dest.push(&self.number);
dest.push(&self.parent_hash);
dest.push(&self.post_state);
}
}
impl Decode for HeadData {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(HeadData {
number: Decode::decode(input)?,
parent_hash: Decode::decode(input)?,
post_state: Decode::decode(input)?,
})
}
}
// Block data for this parachain.
#[derive(Default, Clone)]
struct BlockData {
// State to begin from.
state: u64,
// Amount to add (overflowing)
add: u64,
}
impl Encode for BlockData {
fn encode_to<T: Output>(&self, dest: &mut T) {
dest.push(&self.state);
dest.push(&self.add);
}
}
impl Decode for BlockData {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(BlockData {
state: Decode::decode(input)?,
add: Decode::decode(input)?,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use parachain::ValidationParams;
const TEST_CODE: &[u8] = include_bytes!("../wasm/test.wasm");
fn hash_state(state: u64) -> [u8; 32] {
::tiny_keccak::keccak256(state.encode().as_slice())
}
fn hash_head(head: &HeadData) -> [u8; 32] {
::tiny_keccak::keccak256(head.encode().as_slice())
}
#[test]
fn execute_good_on_parent() {
let parent_head = HeadData {
number: 0,
parent_hash: [0; 32],
post_state: hash_state(0),
};
let block_data = BlockData {
state: 0,
add: 512,
};
let ret = parachain::wasm::validate_candidate(TEST_CODE, ValidationParams {
parent_head: parent_head.encode(),
block_data: block_data.encode(),
}).unwrap();
let new_head = HeadData::decode(&mut &ret.head_data[..]).unwrap();
assert_eq!(new_head.number, 1);
assert_eq!(new_head.parent_hash, hash_head(&parent_head));
assert_eq!(new_head.post_state, hash_state(512));
}
}
@@ -1 +0,0 @@
src
@@ -1,61 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Defines WASM module logic.
use core::{intrinsics, panic, alloc};
use parachain::{self, ValidationResult};
use parachain::codec::{Encode, Decode};
use super::{HeadData, BlockData};
#[panic_implementation]
#[no_mangle]
pub fn panic(_info: &panic::PanicInfo) -> ! {
unsafe {
intrinsics::abort()
}
}
#[alloc_error_handler]
#[no_mangle]
pub fn oom(_: alloc::Layout) -> ! {
unsafe {
intrinsics::abort();
}
}
#[no_mangle]
pub extern fn validate(offset: usize, len: usize) -> usize {
let hash_state = |state: u64| ::tiny_keccak::keccak256(state.encode().as_slice());
let params = unsafe { ::parachain::load_params(offset, len) };
let parent_head = HeadData::decode(&mut &params.parent_head[..])
.expect("invalid parent head format.");
let block_data = BlockData::decode(&mut &params.block_data[..])
.expect("invalid block data format.");
assert_eq!(hash_state(block_data.state), parent_head.post_state, "wrong post-state proof");
let new_state = block_data.state.saturating_add(block_data.add);
let new_head = HeadData {
number: parent_head.number + 1,
parent_hash: ::tiny_keccak::keccak256(&params.parent_head[..]),
post_state: hash_state(new_state),
};
parachain::write_result(ValidationResult { head_data: new_head.encode() })
}
@@ -76,7 +76,7 @@ impl Decode for BlockData {
}
}
const TEST_CODE: &[u8] = include_bytes!("res/basic_add.wasm");
const TEST_CODE: &[u8] = include_bytes!("res/adder.wasm");
fn hash_state(state: u64) -> [u8; 32] {
::tiny_keccak::keccak256(state.encode().as_slice())
Binary file not shown.
Binary file not shown.