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
add inherent transaction functionality to block body
  • Loading branch information
rphmeier committed Feb 20, 2018
commit 2abbe6c20798430c0be1e2ded6943ac77f89866c
18 changes: 16 additions & 2 deletions polkadot/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ 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::{AccountId, SessionKey, Timestamp};
use primitives::block::{Id as BlockId, Block};
use primitives::parachain::DutyRoster;

error_chain! {
Expand Down Expand Up @@ -72,6 +72,12 @@ pub trait PolkadotApi {

/// Get the authority duty roster at a block.
fn duty_roster(&self, at: &BlockId) -> Result<DutyRoster>;

/// Get the timestamp registered at a block.
fn timestamp(&self, at: &BlockId) -> Result<Timestamp>;

/// Evaluate a block and see if it gives an error.
fn evaluate_block(&self, at: &BlockId, block: Block) -> Result<()>;
}

fn convert_client_error(e: client::error::Error) -> Error {
Expand Down Expand Up @@ -115,4 +121,12 @@ impl<B: Backend> PolkadotApi for Client<B, NativeExecutor<LocalDispatch>>
fn duty_roster(&self, at: &BlockId) -> Result<DutyRoster> {
with_runtime!(self, at, ::runtime::parachains::calculate_duty_roster)
}

fn timestamp(&self, at: &BlockId) -> Result<Timestamp> {
with_runtime!(self, at, ::runtime::timestamp::get)
}

fn evaluate_block(&self, at: &BlockId, block: Block) -> Result<()> {
with_runtime!(self, at, || ::runtime::system::internal::execute_block(block))
}
}
11 changes: 11 additions & 0 deletions polkadot/consensus/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

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

use polkadot_primitives::Timestamp;
use primitives::block::{Number as BlockNumber, HeaderHash};

error_chain! {
links {
PolkadotApi(::polkadot_api::Error, ::polkadot_api::ErrorKind);
Expand All @@ -31,6 +34,14 @@ error_chain! {
description("Proposal provided not a Polkadot block."),
display("Proposal provided not a Polkadot block."),
}
TimestampInFuture {
description("Proposal had timestamp too far in the future."),
display("Proposal had timestamp too far in the future."),
}
WrongParentHash(expected: HeaderHash, got: HeaderHash) {
description("Proposal had wrong parent hash."),
display("Proposal had wrong parent hash. Expected {:?}, got {:?}", expected, got),
}
}
}

Expand Down
82 changes: 72 additions & 10 deletions polkadot/consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ use polkadot_api::PolkadotApi;
use polkadot_primitives::Hash;
use polkadot_primitives::block::Block as PolkadotBlock;
use polkadot_primitives::parachain::{Id as ParaId, DutyRoster, BlockData, Extrinsic, CandidateReceipt};
use primitives::block::{Block as SubstrateBlock, Header, HeaderHash, Id as BlockId};
use primitives::block::{Block as SubstrateBlock, Header as SubstrateHeader, HeaderHash, Id as BlockId};
use primitives::AuthorityId;

use futures::prelude::*;
Expand Down Expand Up @@ -463,7 +463,7 @@ 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> {
fn init(&self, parent_header: &SubstrateHeader, 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))?;

Expand All @@ -474,19 +474,29 @@ impl<C: PolkadotApi, N: Network> bft::ProposerFactory for ProposerFactory<C, N>
// TODO [PoC-2]: kick off collation process.
Ok(Proposer {
parent_hash,
table: table,
router,
parent_header: parent_header.clone(),
_table: table,
_router: router,
client: self.client.clone(),
})
}
}

fn current_timestamp() -> ::polkadot_primitives::Timestamp {
use std::time;

time::SystemTime::now().duration_since(time::UNIX_EPOCH)
.expect("now always later than unix epoch; qed")
.as_secs()
}

/// The Polkadot proposer logic.
pub struct Proposer<C, R> {
parent_hash: HeaderHash,
parent_header: SubstrateHeader,
client: Arc<C>,
table: Arc<SharedTable>,
router: R,
_table: Arc<SharedTable>,
_router: R,
}

impl<C: PolkadotApi, R: TableRouter> bft::Proposer for Proposer<C, R> {
Expand All @@ -495,14 +505,66 @@ impl<C: PolkadotApi, R: TableRouter> bft::Proposer for Proposer<C, R> {
type Evaluate = Result<bool, Error>;

fn propose(&self) -> Result<SubstrateBlock, Error> {
use polkadot_primitives::{Header as PolkadotHeader, Body as PolkadotBody};

let header = PolkadotHeader {
parent_hash: self.parent_hash,
number: self.parent_header.number + 1,
state_root: Default::default(),
transaction_root: Default::default(),
digest: Default::default(),
};

let body = PolkadotBody {
// TODO: compare against parent block's and schedule proposal for then.
timestamp: current_timestamp(),
transactions: Vec::new(),
};

for tx in body.inherent_transactions() {
// import these TXs first.
}

// get transactions out of the queue.

// finalise block and get new header.
unimplemented!()
}

// TODO: certain kinds of errors here should lead to a misbehavior report.
fn evaluate(&self, proposal: &SubstrateBlock) -> Result<bool, Error> {
let encoded = Slicable::encode(proposal);
let _polkadot_encoded = PolkadotBlock::decode(&mut &encoded[..])
.ok_or_else(|| ErrorKind::ProposalNotForPolkadot)?;
evaluate_proposal(proposal, &*self.client, current_timestamp(), &self.parent_hash)
}
}

fn evaluate_proposal<C: PolkadotApi>(
proposal: &SubstrateBlock,
client: &C,
now: ::polkadot_primitives::Timestamp,
parent_hash: &HeaderHash,
) -> Result<bool, Error> {
const MAX_TIMESTAMP_DRIFT: ::polkadot_primitives::Timestamp = 4;

Ok(true)
let encoded = Slicable::encode(proposal);
let proposal = PolkadotBlock::decode(&mut &encoded[..])
.ok_or_else(|| ErrorKind::ProposalNotForPolkadot)?;

if proposal.header.parent_hash != *parent_hash {
bail!(ErrorKind::WrongParentHash(*parent_hash, proposal.header.parent_hash));
}

// no need to check number because
// a) we assume the parent is valid.
// b) the runtime checks that `proposal.parent_hash` == `block_hash(proposal.number - 1)`

let block_timestamp = proposal.body.timestamp;

// TODO: just defer using `tokio_timer` to delay prepare vote.
if block_timestamp > now + MAX_TIMESTAMP_DRIFT {
bail!(ErrorKind::TimestampInFuture)
}

// execute the block.
client.evaluate_block(&BlockId::Hash(*parent_hash), proposal)?;
Ok(true)
}
61 changes: 37 additions & 24 deletions polkadot/primitives/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,6 @@ impl Slicable for Digest {
}
}

/// The block body. Contains timestamp and transactions.
// TODO: add candidates update as well.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct Body {
/// The timestamp of the block.
pub timestamp: u64,
/// The transactions in the block.
pub transactions: Vec<UncheckedTransaction>,
}

/// Iterator over all inherent transactions.
pub struct InherentTransactions<'a> {
number: u64,
Expand All @@ -107,6 +94,41 @@ impl<'a> Iterator for InherentTransactions<'a> {
}
}

/// Type alias for an iterator over all transactions in a block.
pub type AllTransactions<'a> = ::rstd::iter::Chain<
InherentTransactions<'a>,
::rstd::iter::Cloned<::rstd::slice::Iter<'a, UncheckedTransaction>>,
>;

/// The block body. Contains timestamp and transactions.
// TODO: add candidates update as well.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct Body {
/// The timestamp of the block.
pub timestamp: u64,
/// The transactions in the block.
pub transactions: Vec<UncheckedTransaction>,
}

impl Body {
/// Get an iterator over all inherent transactions of the body.
pub fn inherent_transactions(&self) -> InherentTransactions {
InherentTransactions {
number: 0,
body: self,
}
}

/// Get an iterator over all transactions in a block.
pub fn all_transactions(&self) -> AllTransactions {
self.inherent_transactions().chain(self.transactions.iter().cloned())
}
}


/// A Polkadot relay chain block.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
Expand All @@ -117,24 +139,15 @@ pub struct Block {
pub body: Body,
}

/// Type alias for an iterator over all transactions in a block.
pub type AllTransactions<'a> = ::rstd::iter::Chain<
InherentTransactions<'a>,
::rstd::iter::Cloned<::rstd::slice::Iter<'a, UncheckedTransaction>>,
>;

impl Block {
/// Get an iterator over all inherent transactions of the body.
pub fn inherent_transactions(&self) -> InherentTransactions {
InherentTransactions {
number: 0,
body: &self.body,
}
self.body.inherent_transactions()
}

/// Get an iterator over all transactions in a block.
pub fn all_transactions(&self) -> AllTransactions {
self.inherent_transactions().chain(self.body.transactions.iter().cloned())
self.body.all_transactions()
}
}

Expand Down
3 changes: 3 additions & 0 deletions polkadot/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,6 @@ pub type Hash = primitives::H256;

/// Alias to 512-bit hash when used in the context of a signature on the relay chain.
pub type Signature = primitives::hash::H512;

/// A timestamp: seconds since the unix epoch.
pub type Timestamp = u64;
5 changes: 3 additions & 2 deletions polkadot/runtime/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

use runtime::{system, parachains, consensus, session};
use runtime::{system, parachains, consensus, session, timestamp};

impl_stubs!(
execute_block => |block| system::internal::execute_block(block),
Expand All @@ -23,5 +23,6 @@ impl_stubs!(
validator_count => |()| session::validator_count(),
validators => |()| session::validators(),
authorities => |()| consensus::authorities(),
duty_roster => |()| parachains::calculate_duty_roster()
duty_roster => |()| parachains::calculate_duty_roster(),
get_timestamp => |()| timestamp::get()
);
7 changes: 5 additions & 2 deletions polkadot/runtime/src/runtime/timestamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
//! Timestamp manager: just handles the current timestamp.

use runtime_support::storage;

pub type Timestamp = u64;
use polkadot_primitives::Timestamp;

const CURRENT_TIMESTAMP: &[u8] = b"tim:val";

Expand All @@ -32,6 +31,10 @@ pub mod public {

/// Set the current time.
pub fn set(now: Timestamp) {
if super::get() > now {
panic!("last timestamp less than now");
}

storage::put(CURRENT_TIMESTAMP, &now);
}
}
Expand Down