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 1 commit
Commits
Show all changes
38 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
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
custom error type for consensus
  • Loading branch information
rphmeier committed Feb 15, 2018
commit a1a19b6f4656eb58ea84029a84bd3c553cec57fd
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions polkadot/consensus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ futures = "0.1.17"
parking_lot = "0.4"
tokio-timer = "0.1.2"
ed25519 = { path = "../../substrate/ed25519" }
error-chain = "0.11"
polkadot-api = { path = "../api" }
polkadot-collator = { path = "../collator" }
polkadot-primitives = { path = "../primitives" }
Expand Down
31 changes: 31 additions & 0 deletions polkadot/consensus/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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/>.

//! Errors that can occur during the consensus process.

error_chain! {
links {
PolkadotApi(::polkadot_api::Error, ::polkadot_api::ErrorKind);
Bft(::bft::Error, ::bft::ErrorKind);
}

errors {
InvalidDutyRosterLength(expected: usize, got: usize) {
description("Duty Roster had invalid length"),
display("Invalid duty roster length: expected {}, got {}", expected, got),
}
}
}
73 changes: 68 additions & 5 deletions polkadot/consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ extern crate substrate_bft as bft;
extern crate substrate_codec as codec;
extern crate substrate_primitives as primitives;

#[macro_use]
extern crate error_chain;

use std::collections::{HashMap, HashSet};
use std::sync::Arc;

Expand All @@ -49,14 +52,18 @@ use table::{Table, Context as TableContextTrait};
use table::generic::Statement as GenericStatement;
use polkadot_api::PolkadotApi;
use polkadot_primitives::Hash;
use polkadot_primitives::parachain::{Id as ParaId, BlockData, Extrinsic, CandidateReceipt};
use primitives::block::Block as SubstrateBlock;
use polkadot_primitives::parachain::{Id as ParaId, DutyRoster, BlockData, Extrinsic, CandidateReceipt};
use primitives::block::{Block as SubstrateBlock, Header, HeaderHash, Id as BlockId};
use primitives::AuthorityId;

use futures::prelude::*;
use futures::future;
use parking_lot::Mutex;

pub use self::error::{ErrorKind, Error};

mod error;

/// A handle to a statement table router.
pub trait TableRouter {
/// Errors when fetching data from the network.
Expand All @@ -78,8 +85,9 @@ pub trait TableRouter {

/// A long-lived network which can create statement table routing instances.
pub trait Network {
/// The table router type.
type TableRouter;
/// The table router type. This should handle importing of any statements,
/// routing statements to peers, and driving completion of any `StatementProducers`.
type TableRouter: TableRouter;

/// Instantiate a table router.
fn table_router(&self, groups: HashMap<ParaId, GroupInfo>, table: Arc<SharedTable>) -> Self::TableRouter;
Expand Down Expand Up @@ -166,7 +174,7 @@ struct SharedTableInner {
}

impl SharedTableInner {
// Import a single statement. Provide a handle to a table router
// Import a single statement. Provide a handle to a table router.
fn import_statement<R: TableRouter>(
&mut self,
context: &TableContext,
Expand Down Expand Up @@ -393,3 +401,58 @@ impl SharedTable {
self.inner.lock().proposed_digest.clone()
}
}

/// Polkadot proposer factory.
pub struct ProposerFactory<C, N> {
/// The client instance.
pub client: Arc<C>,
/// The backing network handle.
pub network: N,
}

fn make_group_info(roster: DutyRoster, authorities: &[AuthorityId]) -> Result<HashMap<ParaId, GroupInfo>, Error> {
if duty_roster.validator_duty.len() != authorities.len() {
bail!(ErrorKind::InvalidDutyRosterLength(authorities.len(), duty_roster.validator_duty.len()))
}

if duty_roster.guarantor_duty.len() != authorities.len() {
bail!(ErrorKind::InvalidDutyRosterLength(authorities.len(), duty_roster.guarantor_duty.len()))
}

let mut map = HashMap::new();

unimpleented!()
}

impl<C: PolkadotApi, N: Network> bft::ProposerFactory for ProposerFactory<C, N> {
type Proposer = Proposer<C, N::TableRouter>;
type Error = Error;

fn init(&self, parent_header: &Header, authorities: &[AuthorityId], sign_with: Arc<ed25519::Pair>) -> Result<Self::Proposer, Error> {
let parent_hash = parent_header.hash();
let duty_roster = self.client.duty_roster(&BlockId::Hash(parent_hash))?;

make_group_info(duty_roster, authorities);

unimplemented!()
}
}

/// The Polkadot proposer logic.
pub struct Proposer<C, R> {
parent_hash: HeaderHash,
client: Arc<C>,
router: R,
}

impl<C: PolkadotApi, R: TableRouter> bft::Proposer for Proposer<C, R> {
type CreateProposal = Result<SubstrateBlock, bft::Error>;

fn propose(&self) -> Self::CreateProposal {
unimplemented!()
}

fn evaluate(&self, proposal: &SubstrateBlock) -> bool {
unimplemented!()
}
}
6 changes: 6 additions & 0 deletions substrate/bft/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ error_chain! {
description("Unable to dispatch agreement future"),
display("Unable to dispatch agreement future: {:?}", e),
}

/// Some other error.
Other(e: Box<::std::error::Error + Send>) {
description("Other error")
display("Other error: {}", e.description())
}
}
}

Expand Down
75 changes: 48 additions & 27 deletions substrate/bft/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,22 +90,28 @@ pub type Committed = generic::Committed<Block, HeaderHash, LocalizedSignature>;
/// Communication between BFT participants.
pub type Communication = generic::Communication<Block, HeaderHash, AuthorityId, LocalizedSignature>;

/// Proposer factory. Can be used to create a proposer instance.
pub trait ProposerFactory {
type Proposer: Proposer;
type Error: From<Error>;

/// Initialize the proposal logic on top of a specific header.
// TODO: provide state context explicitly?
fn init(&self, parent_header: &Header, authorities: &[AuthorityId], sign_with: Arc<ed25519::Pair>) -> Result<Self::Proposer, Self::Error>;
}

/// Logic for a proposer.
///
/// This will encapsulate creation and evaluation of proposals at a specific
/// block.
pub trait Proposer: Sized {
type CreateProposal: IntoFuture<Item=Block,Error=Error>;
pub trait Proposer {
type CreateProposal: IntoFuture<Item=Block,Error=Error>;

/// Initialize the proposal logic on top of a specific header.
// TODO: provide state context explicitly?
fn init(parent_header: &Header, sign_with: Arc<ed25519::Pair>) -> Self;

/// Create a proposal.
fn propose(&self) -> Self::CreateProposal;
/// Evaluate proposal. True means valid.
/// Create a proposal.
fn propose(&self) -> Self::CreateProposal;
/// Evaluate proposal. True means valid.
// TODO: change this to a future.
fn evaluate(&self, proposal: &Block) -> bool;
fn evaluate(&self, proposal: &Block) -> bool;
}

/// Block import trait.
Expand Down Expand Up @@ -272,30 +278,39 @@ pub struct BftService<P, E, I> {
timer: Timer,
round_timeout_multiplier: u64,
key: Arc<ed25519::Pair>, // TODO: key changing over time.
_marker: ::std::marker::PhantomData<P>,
factory: P,
}

impl<P, E, I> BftService<P, E, I>
where
P: Proposer,
E: Executor<BftFuture<P, I>>,
P: ProposerFactory,
E: Executor<BftFuture<P::Proposer, I>>,
I: BlockImport + Authorities,
P::Error: From<Error>,
{
/// Signal that a valid block with the given header has been imported.
///
/// This will begin the consensus process to build a block on top of it.
/// If the executor fails to run the future, an error will be returned.
pub fn build_upon(&self, header: &Header) -> Result<(), Error> {
/// If the local signing key is an authority, this will begin the consensus process to build a
/// block on top of it. If the executor fails to run the future, an error will be returned.
pub fn build_upon(&self, header: &Header) -> Result<(), P::Error> {
let hash = header.hash();
let mut _preempted_consensus = None;
let mut _preempted_consensus = None; // defers drop of live to the end.

let proposer = P::init(header, self.key.clone());
let authorities = self.client.authorities(&BlockId::Hash(hash))?;

// TODO: check key is one of the authorities.
let authorities = self.client.authorities(&BlockId::Hash(hash))?;
let n = authorities.len();
let max_faulty = max_faulty_of(n);

let local_id = self.key.public().0;

if !authorities.contains(&local_id) {
self.live_agreements.lock().remove(&header.parent_hash);
return Ok(())
}

let proposer = self.factory.init(header, &authorities, self.key.clone())?;

let bft_instance = BftInstance {
proposer,
parent_hash: hash,
Expand All @@ -321,7 +336,7 @@ impl<P, E, I> BftService<P, E, I>
cancel: cancel.clone(),
send_task: Some(tx),
import: self.client.clone(),
}).map_err(|e| e.kind()).map_err(ErrorKind::Executor)?;
}).map_err(|e| e.kind()).map_err(ErrorKind::Executor).map_err(Error::from)?;

{
let mut live = self.live_agreements.lock();
Expand Down Expand Up @@ -445,16 +460,22 @@ mod tests {
}
}

struct DummyFactory;
struct DummyProposer(block::Number);

impl Proposer for DummyProposer {
type CreateProposal = Result<Block, Error>;
impl ProposerFactory for DummyFactory {
type Proposer = DummyProposer;
type Error = Error;

fn init(parent_header: &Header, _sign_with: Arc<ed25519::Pair>) -> Self {
DummyProposer(parent_header.number + 1)
fn init(&self, parent_header: &Header, _authorities: &[AuthorityId], _sign_with: Arc<ed25519::Pair>) -> Result<DummyProposer, Error> {
Ok(DummyProposer(parent_header.number + 1))
}
}

impl Proposer for DummyProposer {
type CreateProposal = Result<Block, Error>;

fn propose(&self) -> Result<Block, Error> {
fn propose(&self) -> Result<Block, Error> {
Ok(Block {
header: Header::from_block_number(self.0),
transactions: Default::default()
Expand All @@ -467,7 +488,7 @@ mod tests {
}

fn make_service(client: FakeClient, handle: Handle)
-> BftService<DummyProposer, Handle, FakeClient>
-> BftService<DummyFactory, Handle, FakeClient>
{
BftService {
client: Arc::new(client),
Expand All @@ -476,7 +497,7 @@ mod tests {
timer: Timer::default(),
round_timeout_multiplier: 4,
key: Arc::new(Keyring::One.into()),
_marker: Default::default(),
factory: DummyFactory
}
}

Expand Down