Bulid on any block

This commit is contained in:
Gav
2018-02-13 10:18:28 +01:00
parent ec4be3d260
commit ef2b32b9ed
2 changed files with 32 additions and 7 deletions
@@ -42,24 +42,29 @@ impl<B, E> BlockBuilder<B, E> where
E: CodeExecutor + Clone,
error::Error: From<<<B as backend::Backend>::State as state_machine::backend::Backend>::Error>,
{
/// Create a new instance of builder from the given client.
/// Create a new instance of builder from the given client, building on the latest block.
pub fn new(client: &Client<B, E>) -> error::Result<Self> {
let best = (client.info().map(|i| i.chain.best_number)?..1)
.find(|&n| if let Ok(BlockStatus::InChain) = client.block_status(&BlockId::Number(n))
{ true } else { false })
.unwrap_or(0);
Self::at_block(&BlockId::Number(best), client)
}
/// Create a new instance of builder from the given client using a particular block's ID to
/// build upon.
pub fn at_block(block_id: &BlockId, client: &Client<B, E>) -> error::Result<Self> {
Ok(BlockBuilder {
header: Header {
number: best + 1,
parent_hash: client.block_hash(best)?.expect("We already ascertained this is InChain before; qed"),
number: client.block_number_from_id(block_id)?.ok_or(error::ErrorKind::UnknownBlock(*block_id))? + 1,
parent_hash: client.block_hash_from_id(block_id)?.ok_or(error::ErrorKind::UnknownBlock(*block_id))?,
state_root: Default::default(),
transaction_root: Default::default(),
digest: Default::default(),
},
transactions: Default::default(),
executor: client.clone_executor(),
state: client.state_at(&BlockId::Number(best))?,
state: client.state_at(block_id)?,
changes: Default::default(),
})
}
+23 -3
View File
@@ -43,7 +43,6 @@ pub mod block_builder;
pub use blockchain::Info as ChainInfo;
pub use blockchain::BlockId;
pub use block_builder::BlockBuilder;
use primitives::{block, AuthorityId};
use primitives::storage::{StorageKey, StorageData};
@@ -202,8 +201,13 @@ impl<B, E> Client<B, E> where
}
/// Create a new block, built on the head of the chain.
pub fn new_block(&self) -> error::Result<BlockBuilder<B, E>> where E: Clone {
BlockBuilder::new(self)
pub fn new_block(&self) -> error::Result<block_builder::BlockBuilder<B, E>> where E: Clone {
block_builder::BlockBuilder::new(self)
}
/// Create a new block, built on top of `parent`.
pub fn new_block_at(&self, parent: &BlockId) -> error::Result<block_builder::BlockBuilder<B, E>> where E: Clone {
block_builder::BlockBuilder::at_block(parent, &self)
}
/// Queue a block for import.
@@ -249,6 +253,22 @@ impl<B, E> Client<B, E> where
self.backend.blockchain().hash(block_number)
}
/// Convert an arbitrary block ID into a block hash.
pub fn block_hash_from_id(&self, id: &BlockId) -> error::Result<Option<block::HeaderHash>> {
match *id {
BlockId::Hash(h) => Ok(Some(h)),
BlockId::Number(n) => self.block_hash(n),
}
}
/// Convert an arbitrary block ID into a block hash.
pub fn block_number_from_id(&self, id: &BlockId) -> error::Result<Option<block::Number>> {
match *id {
BlockId::Hash(_) => Ok(self.header(id)?.map(|h| h.number)),
BlockId::Number(n) => Ok(Some(n)),
}
}
/// Get block header by id.
pub fn header(&self, id: &BlockId) -> error::Result<Option<block::Header>> {
self.backend.blockchain().header(*id)