diff --git a/polkadot/api/src/lib.rs b/polkadot/api/src/lib.rs index fcd52e7f38..5089155e81 100644 --- a/polkadot/api/src/lib.rs +++ b/polkadot/api/src/lib.rs @@ -192,7 +192,16 @@ impl PolkadotApi for Client> } fn duty_roster(&self, at: &CheckedId) -> Result { - with_runtime!(self, at, ::runtime::Parachains::calculate_duty_roster) + // duty roster can only be queried at the start of a block, + // so we create a dummy. + let id = at.block_id(); + let parent_hash = self.block_hash_from_id(id)?.ok_or(ErrorKind::UnknownBlock(*id))?; + let number = self.block_number_from_id(id)?.ok_or(ErrorKind::UnknownBlock(*id))? + 1; + + with_runtime!(self, at, || { + ::runtime::System::initialise(&number, &parent_hash, &Default::default()); + ::runtime::Parachains::calculate_duty_roster() + }) } fn timestamp(&self, at: &CheckedId) -> Result { @@ -203,7 +212,7 @@ impl PolkadotApi for Client> with_runtime!(self, at, || ::runtime::Executive::execute_block(block)) } - fn index(&self, at: &Self::CheckedBlockId, account: AccountId) -> Result { + fn index(&self, at: &CheckedId, account: AccountId) -> Result { with_runtime!(self, at, || ::runtime::System::account_index(account)) } @@ -381,10 +390,6 @@ mod tests { || { let mut storage = genesis_config.build_externalities(); let block = ::client::genesis::construct_genesis_block(&storage); - with_externalities(&mut storage, || - // TODO: use api.rs to dispatch instead - runtime::System::initialise_genesis_state(&block.header) - ); (substrate_primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) } ).unwrap() diff --git a/polkadot/consensus/src/error.rs b/polkadot/consensus/src/error.rs index 38ba4ab607..312c88f13e 100644 --- a/polkadot/consensus/src/error.rs +++ b/polkadot/consensus/src/error.rs @@ -16,8 +16,7 @@ //! Errors that can occur during the consensus process. -use primitives::block::HeaderHash; - +use primitives::block::{HeaderHash, Number}; error_chain! { links { PolkadotApi(::polkadot_api::Error, ::polkadot_api::ErrorKind); @@ -41,6 +40,10 @@ error_chain! { description("Proposal had wrong parent hash."), display("Proposal had wrong parent hash. Expected {:?}, got {:?}", expected, got), } + WrongNumber(expected: Number, got: Number) { + description("Proposal had wrong number."), + display("Proposal had wrong number. Expected {:?}, got {:?}", expected, got), + } ProposalTooLarge(size: usize) { description("Proposal exceeded the maximum size."), display( diff --git a/polkadot/consensus/src/lib.rs b/polkadot/consensus/src/lib.rs index 53cf39b6c8..978181be1e 100644 --- a/polkadot/consensus/src/lib.rs +++ b/polkadot/consensus/src/lib.rs @@ -575,7 +575,7 @@ impl bft::Proposer for Proposer { let substrate_block = Slicable::decode(&mut polkadot_block.encode().as_slice()) .expect("polkadot blocks defined to serialize to substrate blocks correctly; qed"); - assert!(evaluate_proposal(&substrate_block, &*self.client, current_timestamp(), &self.parent_hash, &self.parent_id).is_ok()); + assert!(evaluate_proposal(&substrate_block, &*self.client, current_timestamp(), &self.parent_hash, self.parent_number, &self.parent_id).is_ok()); Ok(substrate_block) } @@ -583,7 +583,7 @@ impl bft::Proposer for Proposer { // TODO: certain kinds of errors here should lead to a misbehavior report. fn evaluate(&self, proposal: &SubstrateBlock) -> Result { debug!(target: "bft", "evaluating block on top of parent ({}, {:?})", self.parent_number, self.parent_hash); - match evaluate_proposal(proposal, &*self.client, current_timestamp(), &self.parent_hash, &self.parent_id) { + match evaluate_proposal(proposal, &*self.client, current_timestamp(), &self.parent_hash, self.parent_number, &self.parent_id) { Ok(x) => Ok(x), Err(e) => match *e.kind() { ErrorKind::PolkadotApi(polkadot_api::ErrorKind::Executor(_)) => Ok(false), @@ -656,6 +656,7 @@ fn evaluate_proposal( client: &C, now: Timestamp, parent_hash: &HeaderHash, + parent_number: BlockNumber, parent_id: &C::CheckedBlockId, ) -> Result { const MAX_TIMESTAMP_DRIFT: Timestamp = 4; @@ -677,9 +678,9 @@ fn evaluate_proposal( 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)` + if proposal.header.number != parent_number + 1 { + bail!(ErrorKind::WrongNumber(parent_number + 1, proposal.header.number)) + } let block_timestamp = proposal.timestamp(); diff --git a/polkadot/consensus/src/service.rs b/polkadot/consensus/src/service.rs index 3671edfb90..ce4d9e56b1 100644 --- a/polkadot/consensus/src/service.rs +++ b/polkadot/consensus/src/service.rs @@ -249,12 +249,13 @@ fn start_bft( return; } }; + let input = messages.select(hash, network.bft_messages(), authorities).map_err(|e| e.into()); let output = BftSink { network: network, parent_hash: hash.clone(), _e: Default::default() }; match bft_service.build_upon(&header, input, output) { Ok(Some(bft)) => handle.spawn(bft), Ok(None) => {}, - Err(e) => debug!("BFT agreement error: {:?}", e), + Err(e) => debug!(target: "bft","BFT agreement error: {:?}", e), } } diff --git a/polkadot/runtime/wasm/genesis.wasm b/polkadot/runtime/wasm/genesis.wasm index 13aa514936..bc0861d31f 100644 Binary files a/polkadot/runtime/wasm/genesis.wasm and b/polkadot/runtime/wasm/genesis.wasm differ diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index 13aa514936..bc0861d31f 100644 Binary files a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm and b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm differ diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm index 3c4a32a5a9..98f0bf055e 100755 Binary files a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm and b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm differ diff --git a/polkadot/service/src/lib.rs b/polkadot/service/src/lib.rs index 4c2c27ddf7..8e92435c01 100644 --- a/polkadot/service/src/lib.rs +++ b/polkadot/service/src/lib.rs @@ -258,11 +258,6 @@ impl Service { let prepare_genesis = || { storage = genesis_config.build_externalities(); let block = genesis::construct_genesis_block(&storage); - with_externalities(&mut storage, || { - // TODO: use api.rs to dispatch instead - polkadot_runtime::System::initialise_genesis_state(&block.header); - info!("Genesis header hash: {}", polkadot_runtime::System::block_hash(0)); - }); (primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) };