Interchain message-passing (#117)

* compute ingress and routing in polkadot runtime

* extract parent candidates from block when beginning consensus

* fetch incoming messages when validating

* fix consensus tests

* parachain wasm execution uses messages

* update parachain tests to check if messages are executed

* abstract out network service to make room for network tests

* skeleton for incoming data fetch

* collate ingress from consensus-gossip

* keep track of validated candidates in the shared-table

* add some shared_table tests for new behavior

* broadcast egress messages on gossip

* test compute_ingress

* move network tests to module folder

* dummy network for consensus-network tests

* make consensus network generic over executor

* test egress broadcast and ingress fetch

* fix test compilation

* address some grumbles

* address grumbles and fix parachain shuffle

* remove broadcast parameter from consensus network trait
This commit is contained in:
Robert Habermeier
2019-02-19 13:59:29 -03:00
committed by GitHub
parent da409f6c9e
commit f8af277006
26 changed files with 1733 additions and 368 deletions
@@ -58,7 +58,7 @@ impl ParachainContext for AdderContext {
fn produce_candidate<I: IntoIterator<Item=(ParaId, Message)>>(
&self,
last_head: HeadData,
_ingress: I,
ingress: I,
) -> Result<(BlockData, HeadData), InvalidHead>
{
let adder_head = AdderHead::decode(&mut &last_head.0[..])
@@ -79,7 +79,11 @@ impl ParachainContext for AdderContext {
add: adder_head.number % 100,
};
let next_head = ::adder::execute(adder_head.hash(), adder_head, &next_body)
let from_messages = ::adder::process_messages(
ingress.into_iter().map(|(_, msg)| msg.0)
);
let next_head = ::adder::execute(adder_head.hash(), adder_head, &next_body, from_messages)
.expect("good execution params; qed");
let encoded_head = HeadData(next_head.encode());
+25 -2
View File
@@ -24,7 +24,7 @@ extern crate parity_codec;
extern crate polkadot_parachain as parachain;
extern crate tiny_keccak;
use parity_codec::Encode;
use parity_codec::{Encode, Decode};
/// Head data for this parachain.
#[derive(Default, Clone, Hash, Eq, PartialEq, Encode, Decode)]
@@ -56,13 +56,35 @@ pub fn hash_state(state: u64) -> [u8; 32] {
::tiny_keccak::keccak256(state.encode().as_slice())
}
#[derive(Default, Encode, Decode)]
pub struct AddMessage {
/// The amount to add based on this message.
pub amount: u64,
}
/// Start state mismatched with parent header's state hash.
#[derive(Debug)]
pub struct StateMismatch;
/// Process all incoming messages, yielding the amount of addition from messages.
///
/// Ignores unknown message kinds.
pub fn process_messages<I, T>(iterable: I) -> u64
where I: IntoIterator<Item=T>, T: AsRef<[u8]>
{
iterable.into_iter()
.filter_map(|data| AddMessage::decode(&mut data.as_ref()))
.fold(0u64, |a, c| a.overflowing_add(c.amount).0)
}
/// Execute a block body on top of given parent head, producing new parent head
/// if valid.
pub fn execute(parent_hash: [u8; 32], parent_head: HeadData, block_data: &BlockData) -> Result<HeadData, StateMismatch> {
pub fn execute(
parent_hash: [u8; 32],
parent_head: HeadData,
block_data: &BlockData,
from_messages: u64,
) -> Result<HeadData, StateMismatch> {
debug_assert_eq!(parent_hash, parent_head.hash());
if hash_state(block_data.state) != parent_head.post_state {
@@ -70,6 +92,7 @@ pub fn execute(parent_hash: [u8; 32], parent_head: HeadData, block_data: &BlockD
}
let new_state = block_data.state.overflowing_add(block_data.add).0;
let new_state = new_state.overflowing_add(from_messages).0;
Ok(HeadData {
number: parent_head.number + 1,
@@ -6,9 +6,8 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
adder = { path = ".." }
polkadot-parachain = { path = "../../../parachain", default-features = false, features = ["wasm-api"] }
wee_alloc = { version = "0.4.1" }
pwasm-libc = { version = "0.2" }
tiny-keccak = "1.4"
dlmalloc = { version = "0.1.2", features = ["global"] }
[lib]
crate-type = ["cdylib"]
@@ -23,13 +23,13 @@
)]
extern crate alloc;
extern crate pwasm_libc;
extern crate adder;
extern crate polkadot_parachain as parachain;
extern crate tiny_keccak;
extern crate dlmalloc;
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
static ALLOC: dlmalloc::GlobalDlmalloc = dlmalloc::GlobalDlmalloc;
use core::{intrinsics, panic};
use parachain::ValidationResult;
@@ -63,7 +63,13 @@ pub extern fn validate(offset: usize, len: usize) -> usize {
let parent_hash = ::tiny_keccak::keccak256(&params.parent_head[..]);
match ::adder::execute(parent_hash, parent_head, &block_data) {
// we also add based on incoming data from messages. ignoring unknown message
// kinds.
let from_messages = ::adder::process_messages(
params.ingress.iter().map(|incoming| &incoming.data[..])
);
match ::adder::execute(parent_hash, parent_head, &block_data, from_messages) {
Ok(new_head) => parachain::wasm_api::write_result(
ValidationResult { head_data: new_head.encode() }
),