Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Integrate transaction pool to the proposal logic #80

Merged
merged 47 commits into from
Mar 2, 2018
Merged
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
482a074
reshuffle consensus libraries
rphmeier Feb 8, 2018
917b092
polkadot-useful type definitions for statement table
rphmeier Feb 8, 2018
8e2fd3c
begin BftService
rphmeier Feb 10, 2018
776cf13
Merge branch 'master' into rh-split-bft-table
rphmeier Feb 10, 2018
6abfed4
primary selection logic
rphmeier Feb 12, 2018
fc18524
bft service implementation without I/O
rphmeier Feb 12, 2018
017fd51
extract out `BlockImport` trait
rphmeier Feb 12, 2018
25990ee
Merge branch 'master' into rh-split-bft-table
rphmeier Feb 12, 2018
c33c3ff
allow bft primitives to compile on wasm
rphmeier Feb 12, 2018
acab9a3
Block builder (substrate)
gavofyork Feb 12, 2018
1830fa7
take polkadot-consensus down to the core.
rphmeier Feb 12, 2018
767a9d9
test for preemption
rphmeier Feb 12, 2018
7fc4b4d
fix test build
rphmeier Feb 12, 2018
9acd3f9
Fix wasm build
gavofyork Feb 12, 2018
ca5900f
Bulid on any block
gavofyork Feb 13, 2018
d11cfe1
Test for block builder.
gavofyork Feb 13, 2018
b973ccc
Block import tests for client.
gavofyork Feb 13, 2018
ec61865
Tidy ups
gavofyork Feb 13, 2018
23638cd
clean up block builder instantiation
rphmeier Feb 15, 2018
dda6d24
Merge branch 'rh-split-bft-table' into rh-justification-verification
rphmeier Feb 15, 2018
340ce39
justification verification logic
rphmeier Feb 15, 2018
170b0d1
JustifiedHeader and import
rphmeier Feb 15, 2018
6a1a851
Propert block generation for tests
arkpar Feb 15, 2018
1352765
network and tablerouter trait
rphmeier Feb 15, 2018
2758503
use statement import to drive creation of further statements
rphmeier Feb 15, 2018
a1247bd
Fixed rpc tests
arkpar Feb 15, 2018
a1a19b6
custom error type for consensus
rphmeier Feb 15, 2018
40a9496
create proposer
rphmeier Feb 15, 2018
9e4f273
asynchronous proposal evaluation
rphmeier Feb 15, 2018
673fc2c
Merge branch 'master' into rh-justification-verification
rphmeier Feb 15, 2018
8636b77
Merge branch 'rh-justification-verification' into rh-polkadot-propose
rphmeier Feb 15, 2018
a5c09c8
inherent transactions in polkadot runtime
rphmeier Feb 16, 2018
7b1a563
fix tests to match real polkadot block constraints
rphmeier Feb 16, 2018
8d08573
implicitly generate inherent functions
rphmeier Feb 16, 2018
2abbe6c
add inherent transaction functionality to block body
rphmeier Feb 20, 2018
5bace3a
Merge branch 'master' into rh-polkadot-propose
rphmeier Feb 20, 2018
a87afa7
block builder logic for polkadot
rphmeier Feb 20, 2018
e891649
some tests for the polkadot API
rphmeier Feb 20, 2018
5b3556c
avoid redundancy in native code compatibility check
rphmeier Feb 21, 2018
ad8a576
helper for extracting nonce
rphmeier Feb 21, 2018
40b5e4c
transaction pool implementation
rphmeier Feb 21, 2018
760aeff
transaction pool
rphmeier Feb 23, 2018
198ff7b
integrate transaction pool with proposer
rphmeier Feb 23, 2018
3d052fb
Merge branch 'master' into rh-transaction-pool
rphmeier Feb 25, 2018
fd8e624
indentation
rphmeier Feb 25, 2018
8458389
kill storage keys module
rphmeier Feb 25, 2018
81ff2ad
accept new transactions to replace old
rphmeier Mar 1, 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
Prev Previous commit
Next Next commit
JustifiedHeader and import
  • Loading branch information
rphmeier committed Feb 15, 2018
commit 170b0d19251c5f803fafe2c4731cbc6fd0b56e52
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion polkadot/api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -28,12 +28,12 @@ extern crate substrate_state_machine as state_machine;
extern crate error_chain;

use client::backend::Backend;
use client::blockchain::BlockId;
use client::Client;
use polkadot_runtime::runtime;
use polkadot_executor::Executor as LocalDispatch;
use substrate_executor::{NativeExecutionDispatch, NativeExecutor};
use primitives::{AccountId, SessionKey};
use primitives::block::Id as BlockId;
use primitives::parachain::DutyRoster;

error_chain! {
2 changes: 2 additions & 0 deletions polkadot/primitives/src/block.rs
Original file line number Diff line number Diff line change
@@ -23,6 +23,8 @@ use rstd::vec::Vec;
use codec::{Input, Slicable};
use transaction::UncheckedTransaction;

pub use primitives::block::Id;

/// Used to refer to a block number.
pub type Number = u64;

2 changes: 0 additions & 2 deletions substrate/bft/Cargo.toml
Original file line number Diff line number Diff line change
@@ -5,10 +5,8 @@ authors = ["Parity Technologies <admin@parity.io>"]

[dependencies]
futures = "0.1.17"
substrate-client = { path = "../client" }
substrate-codec = { path = "../codec" }
substrate-primitives = { path = "../primitives" }
substrate-state-machine = { path = "../state-machine" }
ed25519 = { path = "../ed25519" }
tokio-timer = "0.1.2"
parking_lot = "0.4"
2 changes: 1 addition & 1 deletion substrate/bft/src/error.rs
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@
error_chain! {
errors {
/// Missing state at block with given Id.
StateUnavailable(b: ::client::BlockId) {
StateUnavailable(b: ::primitives::block::Id) {
description("State missing at given block."),
display("State unavailable at block {:?}", b),
}
158 changes: 105 additions & 53 deletions substrate/bft/src/lib.rs
Original file line number Diff line number Diff line change
@@ -20,9 +20,7 @@ pub mod error;
pub mod generic;

extern crate substrate_codec as codec;
extern crate substrate_client as client;
extern crate substrate_primitives as primitives;
extern crate substrate_state_machine as state_machine;
extern crate ed25519;
extern crate tokio_timer;
extern crate parking_lot;
@@ -37,14 +35,11 @@ use std::collections::HashMap;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};

use client::{BlockId, Client};
use client::backend::Backend;
use codec::Slicable;
use ed25519::LocalizedSignature;
use primitives::bft::{Message as PrimitiveMessage, Action as PrimitiveAction};
use primitives::block::{Block, Header, HeaderHash};
use primitives::bft::{Message as PrimitiveMessage, Action as PrimitiveAction, Justification as PrimitiveJustification};
use primitives::block::{Block, Id as BlockId, Header, HeaderHash};
use primitives::AuthorityId;
use state_machine::CodeExecutor;

use futures::{stream, task, Async, Sink, Future, IntoFuture};
use futures::future::Executor;
@@ -76,6 +71,19 @@ pub type PrepareJustification = generic::PrepareJustification<HeaderHash, Locali
/// Unchecked justification.
pub type UncheckedJustification = generic::UncheckedJustification<HeaderHash, LocalizedSignature>;

impl From<PrimitiveJustification> for UncheckedJustification {
fn from(just: PrimitiveJustification) -> Self {
UncheckedJustification {
round_number: just.round_number as usize,
digest: just.hash,
signatures: just.signatures.into_iter().map(|(from, sig)| LocalizedSignature {
signer: ed25519::Public(from),
signature: sig,
}).collect(),
}
}
}

/// Result of a committed round of BFT
pub type Committed = generic::Committed<Block, HeaderHash, LocalizedSignature>;

@@ -112,29 +120,6 @@ pub trait Authorities {
fn authorities(&self, at: &BlockId) -> Result<Vec<AuthorityId>, Error>;
}

impl<B, E> BlockImport for Client<B, E>
where
B: Backend,
E: CodeExecutor,
client::error::Error: From<<B::State as state_machine::backend::Backend>::Error>
{
fn import_block(&self, block: Block, _justification: Justification) {
// TODO: use justification.
let _ = self.import_block(block.header, Some(block.transactions));
}
}

impl<B, E> Authorities for Client<B, E>
where
B: Backend,
E: CodeExecutor,
client::error::Error: From<<B::State as state_machine::backend::Backend>::Error>
{
fn authorities(&self, at: &BlockId) -> Result<Vec<AuthorityId>, Error> {
self.authorities_at(at).map_err(|_| ErrorKind::StateUnavailable(*at).into())
}
}

/// Instance of BFT agreement.
struct BftInstance<P> {
key: Arc<ed25519::Pair>,
@@ -166,29 +151,7 @@ impl<P: Proposer> generic::Context for BftInstance<P> {
}

fn sign_local(&self, message: Message) -> LocalizedMessage {
let action = match message.clone() {
::generic::Message::Propose(r, p) => PrimitiveAction::Propose(r as u32, p),
::generic::Message::Prepare(r, h) => PrimitiveAction::Prepare(r as u32, h),
::generic::Message::Commit(r, h) => PrimitiveAction::Commit(r as u32, h),
::generic::Message::AdvanceRound(r) => PrimitiveAction::AdvanceRound(r as u32),
};

let primitive = PrimitiveMessage {
parent: self.parent_hash,
action,
};

let to_sign = Slicable::encode(&primitive);
let signature = LocalizedSignature {
signer: self.key.public(),
signature: self.key.sign(&to_sign),
};

LocalizedMessage {
message,
signature,
sender: self.key.public().0
}
sign_message(message, &*self.key, self.parent_hash.clone())
}

fn round_proposer(&self, round: usize) -> AuthorityId {
@@ -427,6 +390,33 @@ pub fn check_prepare_justification(authorities: &[AuthorityId], parent: HeaderHa
check_justification_signed_message(authorities, &message[..], just)
}

/// Sign a BFT message with the given key.
pub fn sign_message(message: Message, key: &ed25519::Pair, parent_hash: HeaderHash) -> LocalizedMessage {
let action = match message.clone() {
::generic::Message::Propose(r, p) => PrimitiveAction::Propose(r as u32, p),
::generic::Message::Prepare(r, h) => PrimitiveAction::Prepare(r as u32, h),
::generic::Message::Commit(r, h) => PrimitiveAction::Commit(r as u32, h),
::generic::Message::AdvanceRound(r) => PrimitiveAction::AdvanceRound(r as u32),
};

let primitive = PrimitiveMessage {
parent: parent_hash,
action,
};

let to_sign = Slicable::encode(&primitive);
let signature = LocalizedSignature {
signer: key.public(),
signature: key.sign(&to_sign),
};

LocalizedMessage {
message,
signature,
sender: key.public().0
}
}

#[cfg(test)]
mod tests {
use super::*;
@@ -535,4 +525,66 @@ mod tests {
assert_eq!(max_faulty_of(11), 3);
assert_eq!(max_faulty_of(99), 32);
}

#[test]
fn justification_check_works() {
let parent_hash = Default::default();
let hash = [0xff; 32].into();

let authorities = vec![
Keyring::One.to_raw_public(),
Keyring::Two.to_raw_public(),
Keyring::Alice.to_raw_public(),
Keyring::Eve.to_raw_public(),
];

let authorities_keys = vec![
Keyring::One.into(),
Keyring::Two.into(),
Keyring::Alice.into(),
Keyring::Eve.into(),
];

let unchecked = UncheckedJustification {
digest: hash,
round_number: 1,
signatures: authorities_keys.iter().take(3).map(|key| {
sign_message(generic::Message::Commit(1, hash), key, parent_hash).signature
}).collect(),
};

assert!(check_justification(&authorities, parent_hash, unchecked).is_ok());

let unchecked = UncheckedJustification {
digest: hash,
round_number: 0, // wrong round number (vs. the signatures)
signatures: authorities_keys.iter().take(3).map(|key| {
sign_message(generic::Message::Commit(1, hash), key, parent_hash).signature
}).collect(),
};

assert!(check_justification(&authorities, parent_hash, unchecked).is_err());

// not enough signatures.
let unchecked = UncheckedJustification {
digest: hash,
round_number: 1,
signatures: authorities_keys.iter().take(2).map(|key| {
sign_message(generic::Message::Commit(1, hash), key, parent_hash).signature
}).collect(),
};

assert!(check_justification(&authorities, parent_hash, unchecked).is_err());

// wrong hash.
let unchecked = UncheckedJustification {
digest: [0xfe; 32].into(),
round_number: 1,
signatures: authorities_keys.iter().take(3).map(|key| {
sign_message(generic::Message::Commit(1, hash), key, parent_hash).signature
}).collect(),
};

assert!(check_justification(&authorities, parent_hash, unchecked).is_err());
}
}
1 change: 1 addition & 0 deletions substrate/client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ parking_lot = "0.4"
triehash = "0.1"
hex-literal = "0.1"
ed25519 = { path = "../ed25519" }
substrate-bft = { path = "../bft" }
substrate-codec = { path = "../codec" }
substrate-executor = { path = "../executor" }
substrate-primitives = { path = "../primitives" }
5 changes: 2 additions & 3 deletions substrate/client/src/backend.rs
Original file line number Diff line number Diff line change
@@ -18,8 +18,7 @@

use state_machine;
use error;
use primitives::block;
use blockchain::{self, BlockId};
use primitives::block::{self, Id as BlockId};

/// Block insertion operation. Keeps hold if the inserted block state and data.
pub trait BlockImportOperation {
@@ -41,7 +40,7 @@ pub trait Backend {
/// Associated block insertion operation type.
type BlockImportOperation: BlockImportOperation;
/// Associated blockchain backend type.
type Blockchain: blockchain::Backend;
type Blockchain: ::blockchain::Backend;
/// Associated state backend type.
type State: state_machine::backend::Backend;

4 changes: 2 additions & 2 deletions substrate/client/src/block_builder.rs
Original file line number Diff line number Diff line change
@@ -20,8 +20,8 @@ use std::vec::Vec;
use codec::{Joiner, Slicable};
use state_machine::{self, CodeExecutor};
use primitives::{Header, Block};
use primitives::block::Transaction;
use {backend, error, BlockId, Client};
use primitives::block::{Id as BlockId, Transaction};
use {backend, error, Client};
use triehash::ordered_trie_root;

/// Utility for building new (valid) blocks from a stream of transactions.
20 changes: 1 addition & 19 deletions substrate/client/src/blockchain.rs
Original file line number Diff line number Diff line change
@@ -16,27 +16,9 @@

//! Polkadot blockchain trait

use std::fmt::{Display, Formatter, Error as FmtError};
use primitives::block;
use primitives::block::{self, Id as BlockId};
use error::Result;

/// Block indentification.
#[derive(Debug, Clone, Copy)]
pub enum BlockId {
/// Identify by block header hash.
Hash(block::HeaderHash),
/// Identify by block number.
Number(block::Number),
}

impl Display for BlockId {
fn fmt(&self, f: &mut Formatter) -> ::std::result::Result<(), FmtError> {
match *self {
BlockId::Hash(h) => h.fmt(f),
BlockId::Number(n) => n.fmt(f),
}
}
}

/// Blockchain database backend. Does not perform any validation.
pub trait Backend: Send + Sync {
9 changes: 7 additions & 2 deletions substrate/client/src/error.rs
Original file line number Diff line number Diff line change
@@ -18,7 +18,6 @@

use std;
use state_machine;
use blockchain;

error_chain! {
errors {
@@ -29,7 +28,7 @@ error_chain! {
}

/// Unknown block.
UnknownBlock(h: blockchain::BlockId) {
UnknownBlock(h: ::primitives::block::Id) {
description("unknown block"),
display("UnknownBlock: {}", h),
}
@@ -46,6 +45,12 @@ error_chain! {
display("Blockchain: {}", e),
}

/// Bad justification for header.
BadJustification(h: ::primitives::block::Id) {
description("bad justification for header"),
display("bad justification for header: {}", h),
}

/// Invalid state data.
AuthLen {
description("authority count state error"),
4 changes: 2 additions & 2 deletions substrate/client/src/in_mem.rs
Original file line number Diff line number Diff line change
@@ -22,8 +22,8 @@ use state_machine;
use error;
use backend;
use runtime_support::Hashable;
use primitives::block::{self, HeaderHash};
use blockchain::{self, BlockId, BlockStatus};
use primitives::block::{self, Id as BlockId, HeaderHash};
use blockchain::{self, BlockStatus};
use state_machine::backend::Backend as StateBackend;

fn header_hash(header: &block::Header) -> block::HeaderHash {
Loading