simplify block module and usage (#10479)

* removed trait IsBlock and simplify block usage

* removed redundant ClosedBlock::hash function
This commit is contained in:
Marek Kotewicz 2019-03-15 13:22:47 +01:00 committed by Andrew Jones
parent d83143d0ba
commit a574df3132
10 changed files with 125 additions and 152 deletions

View File

@ -31,7 +31,7 @@
//! `ExecutedBlock` is an underlaying data structure used by all structs above to store block //! `ExecutedBlock` is an underlaying data structure used by all structs above to store block
//! related info. //! related info.
use std::cmp; use std::{cmp, ops};
use std::collections::HashSet; use std::collections::HashSet;
use std::sync::Arc; use std::sync::Arc;
@ -52,7 +52,6 @@ use vm::{EnvInfo, LastHashes};
use hash::keccak; use hash::keccak;
use rlp::{RlpStream, Encodable, encode_list}; use rlp::{RlpStream, Encodable, encode_list};
use types::transaction::{SignedTransaction, Error as TransactionError}; use types::transaction::{SignedTransaction, Error as TransactionError};
use types::block::Block;
use types::header::{Header, ExtendedHeader}; use types::header::{Header, ExtendedHeader};
use types::receipt::{Receipt, TransactionOutcome}; use types::receipt::{Receipt, TransactionOutcome};
@ -155,46 +154,12 @@ impl ExecutedBlock {
} }
} }
/// Trait for a object that is a `ExecutedBlock`.
pub trait IsBlock {
/// Get the `ExecutedBlock` associated with this object.
fn block(&self) -> &ExecutedBlock;
/// Get the base `Block` object associated with this.
fn to_base(&self) -> Block {
Block {
header: self.header().clone(),
transactions: self.transactions().iter().cloned().map(Into::into).collect(),
uncles: self.uncles().to_vec(),
}
}
/// Get the header associated with this object's block.
fn header(&self) -> &Header { &self.block().header }
/// Get the final state associated with this object's block.
fn state(&self) -> &State<StateDB> { &self.block().state }
/// Get all information on transactions in this block.
fn transactions(&self) -> &[SignedTransaction] { &self.block().transactions }
/// Get all information on receipts in this block.
fn receipts(&self) -> &[Receipt] { &self.block().receipts }
/// Get all uncles in this block.
fn uncles(&self) -> &[Header] { &self.block().uncles }
}
/// Trait for an object that owns an `ExecutedBlock` /// Trait for an object that owns an `ExecutedBlock`
pub trait Drain { pub trait Drain {
/// Returns `ExecutedBlock` /// Returns `ExecutedBlock`
fn drain(self) -> ExecutedBlock; fn drain(self) -> ExecutedBlock;
} }
impl IsBlock for ExecutedBlock {
fn block(&self) -> &ExecutedBlock { self }
}
impl<'x> OpenBlock<'x> { impl<'x> OpenBlock<'x> {
/// Create a new `OpenBlock` ready for transaction pushing. /// Create a new `OpenBlock` ready for transaction pushing.
pub fn new<'a>( pub fn new<'a>(
@ -250,7 +215,7 @@ impl<'x> OpenBlock<'x> {
/// NOTE Will check chain constraints and the uncle number but will NOT check /// NOTE Will check chain constraints and the uncle number but will NOT check
/// that the header itself is actually valid. /// that the header itself is actually valid.
pub fn push_uncle(&mut self, valid_uncle_header: Header) -> Result<(), BlockError> { pub fn push_uncle(&mut self, valid_uncle_header: Header) -> Result<(), BlockError> {
let max_uncles = self.engine.maximum_uncle_count(self.block.header().number()); let max_uncles = self.engine.maximum_uncle_count(self.block.header.number());
if self.block.uncles.len() + 1 > max_uncles { if self.block.uncles.len() + 1 > max_uncles {
return Err(BlockError::TooManyUncles(OutOfBounds{ return Err(BlockError::TooManyUncles(OutOfBounds{
min: None, min: None,
@ -264,11 +229,6 @@ impl<'x> OpenBlock<'x> {
Ok(()) Ok(())
} }
/// Get the environment info concerning this block.
pub fn env_info(&self) -> EnvInfo {
self.block.env_info()
}
/// Push a transaction into the block. /// Push a transaction into the block.
/// ///
/// If valid, it will be executed, and archived together with the receipt. /// If valid, it will be executed, and archived together with the receipt.
@ -277,7 +237,7 @@ impl<'x> OpenBlock<'x> {
return Err(TransactionError::AlreadyImported.into()); return Err(TransactionError::AlreadyImported.into());
} }
let env_info = self.env_info(); let env_info = self.block.env_info();
let outcome = self.block.state.apply(&env_info, self.engine.machine(), &t, self.block.traces.is_enabled())?; let outcome = self.block.state.apply(&env_info, self.engine.machine(), &t, self.block.traces.is_enabled())?;
self.block.transactions_set.insert(h.unwrap_or_else(||t.hash())); self.block.transactions_set.insert(h.unwrap_or_else(||t.hash()));
@ -374,22 +334,39 @@ impl<'x> OpenBlock<'x> {
pub fn block_mut(&mut self) -> &mut ExecutedBlock { &mut self.block } pub fn block_mut(&mut self) -> &mut ExecutedBlock { &mut self.block }
} }
impl<'x> IsBlock for OpenBlock<'x> { impl<'a> ops::Deref for OpenBlock<'a> {
fn block(&self) -> &ExecutedBlock { &self.block } type Target = ExecutedBlock;
fn deref(&self) -> &Self::Target {
&self.block
}
} }
impl IsBlock for ClosedBlock { impl ops::Deref for ClosedBlock {
fn block(&self) -> &ExecutedBlock { &self.block } type Target = ExecutedBlock;
fn deref(&self) -> &Self::Target {
&self.block
}
} }
impl IsBlock for LockedBlock { impl ops::Deref for LockedBlock {
fn block(&self) -> &ExecutedBlock { &self.block } type Target = ExecutedBlock;
fn deref(&self) -> &Self::Target {
&self.block
}
}
impl ops::Deref for SealedBlock {
type Target = ExecutedBlock;
fn deref(&self) -> &Self::Target {
&self.block
}
} }
impl ClosedBlock { impl ClosedBlock {
/// Get the hash of the header without seal arguments.
pub fn hash(&self) -> H256 { self.header().bare_hash() }
/// Turn this into a `LockedBlock`, unable to be reopened again. /// Turn this into a `LockedBlock`, unable to be reopened again.
pub fn lock(self) -> LockedBlock { pub fn lock(self) -> LockedBlock {
LockedBlock { LockedBlock {
@ -423,18 +400,13 @@ impl LockedBlock {
self.block.header.set_receipts_root( self.block.header.set_receipts_root(
ordered_trie_root(self.block.receipts.iter().map(|r| r.rlp_bytes())) ordered_trie_root(self.block.receipts.iter().map(|r| r.rlp_bytes()))
); );
// compute hash and cache it.
self.block.header.compute_hash();
} }
/// Get the hash of the header without seal arguments.
pub fn hash(&self) -> H256 { self.header().bare_hash() }
/// Provide a valid seal in order to turn this into a `SealedBlock`. /// Provide a valid seal in order to turn this into a `SealedBlock`.
/// ///
/// NOTE: This does not check the validity of `seal` with the engine. /// NOTE: This does not check the validity of `seal` with the engine.
pub fn seal(self, engine: &EthEngine, seal: Vec<Bytes>) -> Result<SealedBlock, BlockError> { pub fn seal(self, engine: &EthEngine, seal: Vec<Bytes>) -> Result<SealedBlock, BlockError> {
let expected_seal_fields = engine.seal_fields(self.header()); let expected_seal_fields = engine.seal_fields(&self.block.header);
let mut s = self; let mut s = self;
if seal.len() != expected_seal_fields { if seal.len() != expected_seal_fields {
return Err(BlockError::InvalidSealArity( return Err(BlockError::InvalidSealArity(
@ -490,10 +462,6 @@ impl Drain for SealedBlock {
} }
} }
impl IsBlock for SealedBlock {
fn block(&self) -> &ExecutedBlock { &self.block }
}
/// Enact the block given by block header, transactions and uncles /// Enact the block given by block header, transactions and uncles
fn enact( fn enact(
header: Header, header: Header,

View File

@ -45,7 +45,7 @@ use types::receipt::{Receipt, LocalizedReceipt};
use types::{BlockNumber, header::{Header, ExtendedHeader}}; use types::{BlockNumber, header::{Header, ExtendedHeader}};
use vm::{EnvInfo, LastHashes}; use vm::{EnvInfo, LastHashes};
use block::{IsBlock, LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock}; use block::{LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock};
use client::ancient_import::AncientVerifier; use client::ancient_import::AncientVerifier;
use client::{ use client::{
Nonce, Balance, ChainInfo, BlockInfo, TransactionInfo, Nonce, Balance, ChainInfo, BlockInfo, TransactionInfo,
@ -299,7 +299,7 @@ impl Importer {
match self.check_and_lock_block(&bytes, block, client) { match self.check_and_lock_block(&bytes, block, client) {
Ok((closed_block, pending)) => { Ok((closed_block, pending)) => {
imported_blocks.push(hash); imported_blocks.push(hash);
let transactions_len = closed_block.transactions().len(); let transactions_len = closed_block.transactions.len();
let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), pending, client); let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), pending, client);
import_results.push(route); import_results.push(route);
client.report.write().accrue_block(&header, transactions_len); client.report.write().accrue_block(&header, transactions_len);
@ -423,13 +423,13 @@ impl Importer {
// if the expected receipts root header does not match. // if the expected receipts root header does not match.
// (i.e. allow inconsistency in receipts outcome before the transition block) // (i.e. allow inconsistency in receipts outcome before the transition block)
if header.number() < engine.params().validate_receipts_transition if header.number() < engine.params().validate_receipts_transition
&& header.receipts_root() != locked_block.block().header().receipts_root() && header.receipts_root() != locked_block.header.receipts_root()
{ {
locked_block.strip_receipts_outcomes(); locked_block.strip_receipts_outcomes();
} }
// Final Verification // Final Verification
if let Err(e) = self.verifier.verify_block_final(&header, locked_block.block().header()) { if let Err(e) = self.verifier.verify_block_final(&header, &locked_block.header) {
warn!(target: "client", "Stage 5 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); warn!(target: "client", "Stage 5 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
bail!(e); bail!(e);
} }
@ -437,8 +437,8 @@ impl Importer {
let pending = self.check_epoch_end_signal( let pending = self.check_epoch_end_signal(
&header, &header,
bytes, bytes,
locked_block.receipts(), &locked_block.receipts,
locked_block.state().db(), locked_block.state.db(),
client client
)?; )?;
@ -2276,8 +2276,8 @@ impl ReopenBlock for Client {
fn reopen_block(&self, block: ClosedBlock) -> OpenBlock { fn reopen_block(&self, block: ClosedBlock) -> OpenBlock {
let engine = &*self.engine; let engine = &*self.engine;
let mut block = block.reopen(engine); let mut block = block.reopen(engine);
let max_uncles = engine.maximum_uncle_count(block.header().number()); let max_uncles = engine.maximum_uncle_count(block.header.number());
if block.uncles().len() < max_uncles { if block.uncles.len() < max_uncles {
let chain = self.chain.read(); let chain = self.chain.read();
let h = chain.best_block_hash(); let h = chain.best_block_hash();
// Add new uncles // Add new uncles
@ -2286,14 +2286,14 @@ impl ReopenBlock for Client {
.unwrap_or_else(Vec::new); .unwrap_or_else(Vec::new);
for h in uncles { for h in uncles {
if !block.uncles().iter().any(|header| header.hash() == h) { if !block.uncles.iter().any(|header| header.hash() == h) {
let uncle = chain.block_header_data(&h).expect("find_uncle_hashes only returns hashes for existing headers; qed"); let uncle = chain.block_header_data(&h).expect("find_uncle_hashes only returns hashes for existing headers; qed");
let uncle = uncle.decode().expect("decoding failure"); let uncle = uncle.decode().expect("decoding failure");
block.push_uncle(uncle).expect("pushing up to maximum_uncle_count; block.push_uncle(uncle).expect("pushing up to maximum_uncle_count;
push_uncle is not ok only if more than maximum_uncle_count is pushed; push_uncle is not ok only if more than maximum_uncle_count is pushed;
so all push_uncle are Ok; so all push_uncle are Ok;
qed"); qed");
if block.uncles().len() >= max_uncles { break } if block.uncles.len() >= max_uncles { break }
} }
} }
@ -2329,7 +2329,7 @@ impl PrepareOpenBlock for Client {
.find_uncle_headers(&h, MAX_UNCLE_AGE) .find_uncle_headers(&h, MAX_UNCLE_AGE)
.unwrap_or_else(Vec::new) .unwrap_or_else(Vec::new)
.into_iter() .into_iter()
.take(engine.maximum_uncle_count(open_block.header().number())) .take(engine.maximum_uncle_count(open_block.header.number()))
.foreach(|h| { .foreach(|h| {
open_block.push_uncle(h.decode().expect("decoding failure")).expect("pushing maximum_uncle_count; open_block.push_uncle(h.decode().expect("decoding failure")).expect("pushing maximum_uncle_count;
open_block was just created; open_block was just created;
@ -2354,7 +2354,7 @@ impl ImportSealedBlock for Client {
fn import_sealed_block(&self, block: SealedBlock) -> EthcoreResult<H256> { fn import_sealed_block(&self, block: SealedBlock) -> EthcoreResult<H256> {
let start = Instant::now(); let start = Instant::now();
let raw = block.rlp_bytes(); let raw = block.rlp_bytes();
let header = block.header().clone(); let header = block.header.clone();
let hash = header.hash(); let hash = header.hash();
self.notify(|n| n.block_pre_import(&raw, &hash, header.difficulty())); self.notify(|n| n.block_pre_import(&raw, &hash, header.difficulty()));
@ -2377,8 +2377,8 @@ impl ImportSealedBlock for Client {
let pending = self.importer.check_epoch_end_signal( let pending = self.importer.check_epoch_end_signal(
&header, &header,
&block_data, &block_data,
block.receipts(), &block.receipts,
block.state().db(), block.state.db(),
self self
)?; )?;
let route = self.importer.commit_block( let route = self.importer.commit_block(

View File

@ -1030,7 +1030,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
return Seal::None; return Seal::None;
} }
let header = block.header(); let header = &block.header;
let parent_step = header_step(parent, self.empty_steps_transition) let parent_step = header_step(parent, self.empty_steps_transition)
.expect("Header has been verified; qed"); .expect("Header has been verified; qed");
@ -1076,7 +1076,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
// `EmptyStep(step, parent_hash)` message. If we exceed the maximum amount of `empty_step` rounds we proceed // `EmptyStep(step, parent_hash)` message. If we exceed the maximum amount of `empty_step` rounds we proceed
// with the seal. // with the seal.
if header.number() >= self.empty_steps_transition && if header.number() >= self.empty_steps_transition &&
block.transactions().is_empty() && block.transactions.is_empty() &&
empty_steps.len() < self.maximum_empty_steps { empty_steps.len() < self.maximum_empty_steps {
if self.step.can_propose.compare_and_swap(true, false, AtomicOrdering::SeqCst) { if self.step.can_propose.compare_and_swap(true, false, AtomicOrdering::SeqCst) {
@ -1146,7 +1146,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
if self.immediate_transitions || !epoch_begin { return Ok(()) } if self.immediate_transitions || !epoch_begin { return Ok(()) }
// genesis is never a new block, but might as well check. // genesis is never a new block, but might as well check.
let header = block.header().clone(); let header = block.header.clone();
let first = header.number() == 0; let first = header.number() == 0;
let mut call = |to, data| { let mut call = |to, data| {
@ -1166,8 +1166,8 @@ impl Engine<EthereumMachine> for AuthorityRound {
/// Apply the block reward on finalisation of the block. /// Apply the block reward on finalisation of the block.
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
let mut beneficiaries = Vec::new(); let mut beneficiaries = Vec::new();
if block.header().number() >= self.empty_steps_transition { if block.header.number() >= self.empty_steps_transition {
let empty_steps = if block.header().seal().is_empty() { let empty_steps = if block.header.seal().is_empty() {
// this is a new block, calculate rewards based on the empty steps messages we have accumulated // this is a new block, calculate rewards based on the empty steps messages we have accumulated
let client = match self.client.read().as_ref().and_then(|weak| weak.upgrade()) { let client = match self.client.read().as_ref().and_then(|weak| weak.upgrade()) {
Some(client) => client, Some(client) => client,
@ -1177,7 +1177,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
}, },
}; };
let parent = client.block_header(::client::BlockId::Hash(*block.header().parent_hash())) let parent = client.block_header(::client::BlockId::Hash(*block.header.parent_hash()))
.expect("hash is from parent; parent header must exist; qed") .expect("hash is from parent; parent header must exist; qed")
.decode()?; .decode()?;
@ -1186,7 +1186,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
self.empty_steps(parent_step.into(), current_step.into(), parent.hash()) self.empty_steps(parent_step.into(), current_step.into(), parent.hash())
} else { } else {
// we're verifying a block, extract empty steps from the seal // we're verifying a block, extract empty steps from the seal
header_empty_steps(block.header())? header_empty_steps(&block.header)?
}; };
for empty_step in empty_steps { for empty_step in empty_steps {
@ -1195,11 +1195,11 @@ impl Engine<EthereumMachine> for AuthorityRound {
} }
} }
let author = *block.header().author(); let author = *block.header.author();
beneficiaries.push((author, RewardKind::Author)); beneficiaries.push((author, RewardKind::Author));
let rewards: Vec<_> = match self.block_reward_contract { let rewards: Vec<_> = match self.block_reward_contract {
Some(ref c) if block.header().number() >= self.block_reward_contract_transition => { Some(ref c) if block.header.number() >= self.block_reward_contract_transition => {
let mut call = super::default_system_or_code_call(&self.machine, block); let mut call = super::default_system_or_code_call(&self.machine, block);
let rewards = c.reward(&beneficiaries, &mut call)?; let rewards = c.reward(&beneficiaries, &mut call)?;
@ -1634,17 +1634,17 @@ mod tests {
let b2 = b2.close_and_lock().unwrap(); let b2 = b2.close_and_lock().unwrap();
engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
if let Seal::Regular(seal) = engine.generate_seal(b1.block(), &genesis_header) { if let Seal::Regular(seal) = engine.generate_seal(&b1, &genesis_header) {
assert!(b1.clone().try_seal(engine, seal).is_ok()); assert!(b1.clone().try_seal(engine, seal).is_ok());
// Second proposal is forbidden. // Second proposal is forbidden.
assert!(engine.generate_seal(b1.block(), &genesis_header) == Seal::None); assert!(engine.generate_seal(&b1, &genesis_header) == Seal::None);
} }
engine.set_signer(Box::new((tap, addr2, "2".into()))); engine.set_signer(Box::new((tap, addr2, "2".into())));
if let Seal::Regular(seal) = engine.generate_seal(b2.block(), &genesis_header) { if let Seal::Regular(seal) = engine.generate_seal(&b2, &genesis_header) {
assert!(b2.clone().try_seal(engine, seal).is_ok()); assert!(b2.clone().try_seal(engine, seal).is_ok());
// Second proposal is forbidden. // Second proposal is forbidden.
assert!(engine.generate_seal(b2.block(), &genesis_header) == Seal::None); assert!(engine.generate_seal(&b2, &genesis_header) == Seal::None);
} }
} }
@ -1668,13 +1668,13 @@ mod tests {
let b2 = b2.close_and_lock().unwrap(); let b2 = b2.close_and_lock().unwrap();
engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
match engine.generate_seal(b1.block(), &genesis_header) { match engine.generate_seal(&b1, &genesis_header) {
Seal::None | Seal::Proposal(_) => panic!("wrong seal"), Seal::None | Seal::Proposal(_) => panic!("wrong seal"),
Seal::Regular(_) => { Seal::Regular(_) => {
engine.step(); engine.step();
engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
match engine.generate_seal(b2.block(), &genesis_header) { match engine.generate_seal(&b2, &genesis_header) {
Seal::Regular(_) | Seal::Proposal(_) => panic!("sealed despite wrong difficulty"), Seal::Regular(_) | Seal::Proposal(_) => panic!("sealed despite wrong difficulty"),
Seal::None => {} Seal::None => {}
} }
@ -1902,7 +1902,7 @@ mod tests {
let b1 = b1.close_and_lock().unwrap(); let b1 = b1.close_and_lock().unwrap();
// the block is empty so we don't seal and instead broadcast an empty step message // the block is empty so we don't seal and instead broadcast an empty step message
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None);
// spec starts with step 2 // spec starts with step 2
let empty_step_rlp = encode(&empty_step(engine, 2, &genesis_header.hash())); let empty_step_rlp = encode(&empty_step(engine, 2, &genesis_header.hash()));
@ -1912,7 +1912,7 @@ mod tests {
let len = notify.messages.read().len(); let len = notify.messages.read().len();
// make sure that we don't generate empty step for the second time // make sure that we don't generate empty step for the second time
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None);
assert_eq!(len, notify.messages.read().len()); assert_eq!(len, notify.messages.read().len());
} }
@ -1941,7 +1941,7 @@ mod tests {
// since the block is empty it isn't sealed and we generate empty steps // since the block is empty it isn't sealed and we generate empty steps
engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None);
engine.step(); engine.step();
// step 3 // step 3
@ -1958,7 +1958,7 @@ mod tests {
// we will now seal a block with 1tx and include the accumulated empty step message // we will now seal a block with 1tx and include the accumulated empty step message
engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
if let Seal::Regular(seal) = engine.generate_seal(b2.block(), &genesis_header) { if let Seal::Regular(seal) = engine.generate_seal(&b2, &genesis_header) {
engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
let empty_step2 = sealed_empty_step(engine, 2, &genesis_header.hash()); let empty_step2 = sealed_empty_step(engine, 2, &genesis_header.hash());
let empty_steps = ::rlp::encode_list(&vec![empty_step2]); let empty_steps = ::rlp::encode_list(&vec![empty_step2]);
@ -1994,14 +1994,14 @@ mod tests {
// since the block is empty it isn't sealed and we generate empty steps // since the block is empty it isn't sealed and we generate empty steps
engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None);
engine.step(); engine.step();
// step 3 // step 3
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b2 = b2.close_and_lock().unwrap(); let b2 = b2.close_and_lock().unwrap();
engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
assert_eq!(engine.generate_seal(b2.block(), &genesis_header), Seal::None); assert_eq!(engine.generate_seal(&b2, &genesis_header), Seal::None);
engine.step(); engine.step();
// step 4 // step 4
@ -2010,7 +2010,7 @@ mod tests {
let b3 = b3.close_and_lock().unwrap(); let b3 = b3.close_and_lock().unwrap();
engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
if let Seal::Regular(seal) = engine.generate_seal(b3.block(), &genesis_header) { if let Seal::Regular(seal) = engine.generate_seal(&b3, &genesis_header) {
let empty_step2 = sealed_empty_step(engine, 2, &genesis_header.hash()); let empty_step2 = sealed_empty_step(engine, 2, &genesis_header.hash());
engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
let empty_step3 = sealed_empty_step(engine, 3, &genesis_header.hash()); let empty_step3 = sealed_empty_step(engine, 3, &genesis_header.hash());
@ -2044,19 +2044,19 @@ mod tests {
// since the block is empty it isn't sealed and we generate empty steps // since the block is empty it isn't sealed and we generate empty steps
engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None);
engine.step(); engine.step();
// step 3 // step 3
// the signer of the accumulated empty step message should be rewarded // the signer of the accumulated empty step message should be rewarded
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let addr1_balance = b2.block().state().balance(&addr1).unwrap(); let addr1_balance = b2.state.balance(&addr1).unwrap();
// after closing the block `addr1` should be reward twice, one for the included empty step message and another for block creation // after closing the block `addr1` should be reward twice, one for the included empty step message and another for block creation
let b2 = b2.close_and_lock().unwrap(); let b2 = b2.close_and_lock().unwrap();
// the spec sets the block reward to 10 // the spec sets the block reward to 10
assert_eq!(b2.block().state().balance(&addr1).unwrap(), addr1_balance + (10 * 2)) assert_eq!(b2.state.balance(&addr1).unwrap(), addr1_balance + (10 * 2))
} }
#[test] #[test]
@ -2155,7 +2155,7 @@ mod tests {
// since the block is empty it isn't sealed and we generate empty steps // since the block is empty it isn't sealed and we generate empty steps
engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None);
engine.step(); engine.step();
// step 3 // step 3
@ -2173,7 +2173,7 @@ mod tests {
false, false,
&mut Vec::new().into_iter(), &mut Vec::new().into_iter(),
).unwrap(); ).unwrap();
let addr1_balance = b2.block().state().balance(&addr1).unwrap(); let addr1_balance = b2.state.balance(&addr1).unwrap();
// after closing the block `addr1` should be reward twice, one for the included empty step // after closing the block `addr1` should be reward twice, one for the included empty step
// message and another for block creation // message and another for block creation
@ -2181,7 +2181,7 @@ mod tests {
// the contract rewards (1000 + kind) for each benefactor/reward kind // the contract rewards (1000 + kind) for each benefactor/reward kind
assert_eq!( assert_eq!(
b2.block().state().balance(&addr1).unwrap(), b2.state.balance(&addr1).unwrap(),
addr1_balance + (1000 + 0) + (1000 + 2), addr1_balance + (1000 + 0) + (1000 + 2),
) )
} }

View File

@ -104,7 +104,7 @@ impl Engine<EthereumMachine> for BasicAuthority {
/// Attempt to seal the block internally. /// Attempt to seal the block internally.
fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal { fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal {
let header = block.header(); let header = &block.header;
let author = header.author(); let author = header.author();
if self.validators.contains(header.parent_hash(), author) { if self.validators.contains(header.parent_hash(), author) {
// account should be pernamently unlocked, otherwise sealing will fail // account should be pernamently unlocked, otherwise sealing will fail
@ -266,7 +266,7 @@ mod tests {
let last_hashes = Arc::new(vec![genesis_header.hash()]); let last_hashes = Arc::new(vec![genesis_header.hash()]);
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b = b.close_and_lock().unwrap(); let b = b.close_and_lock().unwrap();
if let Seal::Regular(seal) = engine.generate_seal(b.block(), &genesis_header) { if let Seal::Regular(seal) = engine.generate_seal(&b, &genesis_header) {
assert!(b.try_seal(engine, seal).is_ok()); assert!(b.try_seal(engine, seal).is_ok());
} }
} }

View File

@ -110,7 +110,7 @@ mod tests {
let last_hashes = Arc::new(vec![genesis_header.hash()]); let last_hashes = Arc::new(vec![genesis_header.hash()]);
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b = b.close_and_lock().unwrap(); let b = b.close_and_lock().unwrap();
if let Seal::Regular(seal) = engine.generate_seal(b.block(), &genesis_header) { if let Seal::Regular(seal) = engine.generate_seal(&b, &genesis_header) {
assert!(b.try_seal(engine, seal).is_ok()); assert!(b.try_seal(engine, seal).is_ok());
} }
} }

View File

@ -542,7 +542,7 @@ mod tests {
let last_hashes = Arc::new(vec![genesis_header.hash()]); let last_hashes = Arc::new(vec![genesis_header.hash()]);
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b = b.close().unwrap(); let b = b.close().unwrap();
assert_eq!(b.state().balance(&Address::zero()).unwrap(), U256::from_str("4563918244f40000").unwrap()); assert_eq!(b.state.balance(&Address::zero()).unwrap(), U256::from_str("4563918244f40000").unwrap());
} }
#[test] #[test]
@ -596,8 +596,8 @@ mod tests {
b.push_uncle(uncle).unwrap(); b.push_uncle(uncle).unwrap();
let b = b.close().unwrap(); let b = b.close().unwrap();
assert_eq!(b.state().balance(&Address::zero()).unwrap(), "478eae0e571ba000".into()); assert_eq!(b.state.balance(&Address::zero()).unwrap(), "478eae0e571ba000".into());
assert_eq!(b.state().balance(&uncle_author).unwrap(), "3cb71f51fc558000".into()); assert_eq!(b.state.balance(&uncle_author).unwrap(), "3cb71f51fc558000".into());
} }
#[test] #[test]
@ -612,9 +612,9 @@ mod tests {
let ubi_contract: Address = "00efdd5883ec628983e9063c7d969fe268bbf310".into(); let ubi_contract: Address = "00efdd5883ec628983e9063c7d969fe268bbf310".into();
let dev_contract: Address = "00756cf8159095948496617f5fb17ed95059f536".into(); let dev_contract: Address = "00756cf8159095948496617f5fb17ed95059f536".into();
assert_eq!(b.state().balance(&Address::zero()).unwrap(), U256::from_str("d8d726b7177a80000").unwrap()); assert_eq!(b.state.balance(&Address::zero()).unwrap(), U256::from_str("d8d726b7177a80000").unwrap());
assert_eq!(b.state().balance(&ubi_contract).unwrap(), U256::from_str("2b5e3af16b1880000").unwrap()); assert_eq!(b.state.balance(&ubi_contract).unwrap(), U256::from_str("2b5e3af16b1880000").unwrap());
assert_eq!(b.state().balance(&dev_contract).unwrap(), U256::from_str("c249fdd327780000").unwrap()); assert_eq!(b.state.balance(&dev_contract).unwrap(), U256::from_str("c249fdd327780000").unwrap());
} }
#[test] #[test]

View File

@ -28,7 +28,7 @@ use types::header::Header;
use vm::{CallType, ActionParams, ActionValue, ParamsType}; use vm::{CallType, ActionParams, ActionValue, ParamsType};
use vm::{EnvInfo, Schedule, CreateContractAddress}; use vm::{EnvInfo, Schedule, CreateContractAddress};
use block::{ExecutedBlock, IsBlock}; use block::ExecutedBlock;
use builtin::Builtin; use builtin::Builtin;
use call_contract::CallContract; use call_contract::CallContract;
use client::BlockInfo; use client::BlockInfo;
@ -126,7 +126,7 @@ impl EthereumMachine {
data: Option<Vec<u8>>, data: Option<Vec<u8>>,
) -> Result<Vec<u8>, Error> { ) -> Result<Vec<u8>, Error> {
let (code, code_hash) = { let (code, code_hash) = {
let state = block.state(); let state = &block.state;
(state.code(&contract_address)?, (state.code(&contract_address)?,
state.code_hash(&contract_address)?) state.code_hash(&contract_address)?)
@ -193,12 +193,12 @@ impl EthereumMachine {
/// Push last known block hash to the state. /// Push last known block hash to the state.
fn push_last_hash(&self, block: &mut ExecutedBlock) -> Result<(), Error> { fn push_last_hash(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
let params = self.params(); let params = self.params();
if block.header().number() == params.eip210_transition { if block.header.number() == params.eip210_transition {
let state = block.state_mut(); let state = block.state_mut();
state.init_code(&params.eip210_contract_address, params.eip210_contract_code.clone())?; state.init_code(&params.eip210_contract_address, params.eip210_contract_code.clone())?;
} }
if block.header().number() >= params.eip210_transition { if block.header.number() >= params.eip210_transition {
let parent_hash = block.header().parent_hash().clone(); let parent_hash = *block.header.parent_hash();
let _ = self.execute_as_system( let _ = self.execute_as_system(
block, block,
params.eip210_contract_address, params.eip210_contract_address,
@ -215,7 +215,7 @@ impl EthereumMachine {
self.push_last_hash(block)?; self.push_last_hash(block)?;
if let Some(ref ethash_params) = self.ethash_extensions { if let Some(ref ethash_params) = self.ethash_extensions {
if block.header().number() == ethash_params.dao_hardfork_transition { if block.header.number() == ethash_params.dao_hardfork_transition {
let state = block.state_mut(); let state = block.state_mut();
for child in &ethash_params.dao_hardfork_accounts { for child in &ethash_params.dao_hardfork_accounts {
let beneficiary = &ethash_params.dao_hardfork_beneficiary; let beneficiary = &ethash_params.dao_hardfork_beneficiary;
@ -434,7 +434,7 @@ impl super::Machine for EthereumMachine {
type Error = Error; type Error = Error;
fn balance(&self, live: &ExecutedBlock, address: &Address) -> Result<U256, Error> { fn balance(&self, live: &ExecutedBlock, address: &Address) -> Result<U256, Error> {
live.state().balance(address).map_err(Into::into) live.state.balance(address).map_err(Into::into)
} }
fn add_balance(&self, live: &mut ExecutedBlock, address: &Address, amount: &U256) -> Result<(), Error> { fn add_balance(&self, live: &mut ExecutedBlock, address: &Address, amount: &U256) -> Result<(), Error> {

View File

@ -46,7 +46,7 @@ use types::header::Header;
use types::receipt::RichReceipt; use types::receipt::RichReceipt;
use using_queue::{UsingQueue, GetAction}; use using_queue::{UsingQueue, GetAction};
use block::{ClosedBlock, IsBlock, SealedBlock}; use block::{ClosedBlock, SealedBlock};
use client::{ use client::{
BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId
}; };
@ -362,7 +362,7 @@ impl Miner {
.and_then(|b| { .and_then(|b| {
// to prevent a data race between block import and updating pending block // to prevent a data race between block import and updating pending block
// we allow the number to be equal. // we allow the number to be equal.
if b.block().header().number() >= latest_block_number { if b.header.number() >= latest_block_number {
Some(f(b)) Some(f(b))
} else { } else {
None None
@ -392,7 +392,7 @@ impl Miner {
// Open block // Open block
let (mut open_block, original_work_hash) = { let (mut open_block, original_work_hash) = {
let mut sealing = self.sealing.lock(); let mut sealing = self.sealing.lock();
let last_work_hash = sealing.queue.peek_last_ref().map(|pb| pb.block().header().hash()); let last_work_hash = sealing.queue.peek_last_ref().map(|pb| pb.header.hash());
let best_hash = chain_info.best_block_hash; let best_hash = chain_info.best_block_hash;
// check to see if last ClosedBlock in would_seals is actually same parent block. // check to see if last ClosedBlock in would_seals is actually same parent block.
@ -401,7 +401,7 @@ impl Miner {
// if at least one was pushed successfully, close and enqueue new ClosedBlock; // if at least one was pushed successfully, close and enqueue new ClosedBlock;
// otherwise, leave everything alone. // otherwise, leave everything alone.
// otherwise, author a fresh block. // otherwise, author a fresh block.
let mut open_block = match sealing.queue.get_pending_if(|b| b.block().header().parent_hash() == &best_hash) { let mut open_block = match sealing.queue.get_pending_if(|b| b.header.parent_hash() == &best_hash) {
Some(old_block) => { Some(old_block) => {
trace!(target: "miner", "prepare_block: Already have previous work; updating and returning"); trace!(target: "miner", "prepare_block: Already have previous work; updating and returning");
// add transactions to old_block // add transactions to old_block
@ -436,7 +436,7 @@ impl Miner {
let mut invalid_transactions = HashSet::new(); let mut invalid_transactions = HashSet::new();
let mut not_allowed_transactions = HashSet::new(); let mut not_allowed_transactions = HashSet::new();
let mut senders_to_penalize = HashSet::new(); let mut senders_to_penalize = HashSet::new();
let block_number = open_block.block().header().number(); let block_number = open_block.header.number();
let mut tx_count = 0usize; let mut tx_count = 0usize;
let mut skipped_transactions = 0usize; let mut skipped_transactions = 0usize;
@ -453,7 +453,7 @@ impl Miner {
let max_transactions = if min_tx_gas.is_zero() { let max_transactions = if min_tx_gas.is_zero() {
usize::max_value() usize::max_value()
} else { } else {
MAX_SKIPPED_TRANSACTIONS.saturating_add(cmp::min(*open_block.block().header().gas_limit() / min_tx_gas, u64::max_value().into()).as_u64() as usize) MAX_SKIPPED_TRANSACTIONS.saturating_add(cmp::min(*open_block.header.gas_limit() / min_tx_gas, u64::max_value().into()).as_u64() as usize)
}; };
let pending: Vec<Arc<_>> = self.transaction_queue.pending( let pending: Vec<Arc<_>> = self.transaction_queue.pending(
@ -636,7 +636,7 @@ impl Miner {
{ {
{ {
let sealing = self.sealing.lock(); let sealing = self.sealing.lock();
if block.transactions().is_empty() if block.transactions.is_empty()
&& !self.forced_sealing() && !self.forced_sealing()
&& Instant::now() <= sealing.next_mandatory_reseal && Instant::now() <= sealing.next_mandatory_reseal
{ {
@ -646,7 +646,7 @@ impl Miner {
trace!(target: "miner", "seal_block_internally: attempting internal seal."); trace!(target: "miner", "seal_block_internally: attempting internal seal.");
let parent_header = match chain.block_header(BlockId::Hash(*block.header().parent_hash())) { let parent_header = match chain.block_header(BlockId::Hash(*block.header.parent_hash())) {
Some(h) => { Some(h) => {
match h.decode() { match h.decode() {
Ok(decoded_hdr) => decoded_hdr, Ok(decoded_hdr) => decoded_hdr,
@ -656,7 +656,7 @@ impl Miner {
None => return false, None => return false,
}; };
match self.engine.generate_seal(block.block(), &parent_header) { match self.engine.generate_seal(&block, &parent_header) {
// Save proposal for later seal submission and broadcast it. // Save proposal for later seal submission and broadcast it.
Seal::Proposal(seal) => { Seal::Proposal(seal) => {
trace!(target: "miner", "Received a Proposal seal."); trace!(target: "miner", "Received a Proposal seal.");
@ -705,11 +705,11 @@ impl Miner {
/// Prepares work which has to be done to seal. /// Prepares work which has to be done to seal.
fn prepare_work(&self, block: ClosedBlock, original_work_hash: Option<H256>) { fn prepare_work(&self, block: ClosedBlock, original_work_hash: Option<H256>) {
let (work, is_new) = { let (work, is_new) = {
let block_header = block.block().header().clone(); let block_header = block.header.clone();
let block_hash = block_header.hash(); let block_hash = block_header.hash();
let mut sealing = self.sealing.lock(); let mut sealing = self.sealing.lock();
let last_work_hash = sealing.queue.peek_last_ref().map(|pb| pb.block().header().hash()); let last_work_hash = sealing.queue.peek_last_ref().map(|pb| pb.header.hash());
trace!( trace!(
target: "miner", target: "miner",
@ -742,7 +742,7 @@ impl Miner {
trace!( trace!(
target: "miner", target: "miner",
"prepare_work: leaving (last={:?})", "prepare_work: leaving (last={:?})",
sealing.queue.peek_last_ref().map(|b| b.block().header().hash()) sealing.queue.peek_last_ref().map(|b| b.header.hash())
); );
(work, is_new) (work, is_new)
}; };
@ -994,7 +994,7 @@ impl miner::MinerService for Miner {
let from_pending = || { let from_pending = || {
self.map_existing_pending_block(|sealing| { self.map_existing_pending_block(|sealing| {
sealing.transactions() sealing.transactions
.iter() .iter()
.map(|signed| signed.hash()) .map(|signed| signed.hash())
.collect() .collect()
@ -1041,7 +1041,7 @@ impl miner::MinerService for Miner {
let from_pending = || { let from_pending = || {
self.map_existing_pending_block(|sealing| { self.map_existing_pending_block(|sealing| {
sealing.transactions() sealing.transactions
.iter() .iter()
.map(|signed| pool::VerifiedTransaction::from_pending_block_transaction(signed.clone())) .map(|signed| pool::VerifiedTransaction::from_pending_block_transaction(signed.clone()))
.map(Arc::new) .map(Arc::new)
@ -1086,9 +1086,9 @@ impl miner::MinerService for Miner {
fn pending_receipts(&self, best_block: BlockNumber) -> Option<Vec<RichReceipt>> { fn pending_receipts(&self, best_block: BlockNumber) -> Option<Vec<RichReceipt>> {
self.map_existing_pending_block(|pending| { self.map_existing_pending_block(|pending| {
let receipts = pending.receipts(); let receipts = &pending.receipts;
pending.transactions() pending.transactions
.into_iter() .iter()
.enumerate() .enumerate()
.map(|(index, tx)| { .map(|(index, tx)| {
let prev_gas = if index == 0 { Default::default() } else { receipts[index - 1].gas_used }; let prev_gas = if index == 0 { Default::default() } else { receipts[index - 1].gas_used };
@ -1102,7 +1102,7 @@ impl miner::MinerService for Miner {
Action::Call(_) => None, Action::Call(_) => None,
Action::Create => { Action::Create => {
let sender = tx.sender(); let sender = tx.sender();
Some(contract_address(self.engine.create_address_scheme(pending.header().number()), &sender, &tx.nonce, &tx.data).0) Some(contract_address(self.engine.create_address_scheme(pending.header.number()), &sender, &tx.nonce, &tx.data).0)
} }
}, },
logs: receipt.logs.clone(), logs: receipt.logs.clone(),
@ -1139,7 +1139,7 @@ impl miner::MinerService for Miner {
// refuse to seal the first block of the chain if it contains hard forks // refuse to seal the first block of the chain if it contains hard forks
// which should be on by default. // which should be on by default.
if block.block().header().number() == 1 { if block.header.number() == 1 {
if let Some(name) = self.engine.params().nonzero_bugfix_hard_fork() { if let Some(name) = self.engine.params().nonzero_bugfix_hard_fork() {
warn!("Your chain specification contains one or more hard forks which are required to be \ warn!("Your chain specification contains one or more hard forks which are required to be \
on by default. Please remove these forks and start your chain again: {}.", name); on by default. Please remove these forks and start your chain again: {}.", name);
@ -1180,7 +1180,7 @@ impl miner::MinerService for Miner {
self.prepare_pending_block(chain); self.prepare_pending_block(chain);
self.sealing.lock().queue.use_last_ref().map(|b| { self.sealing.lock().queue.use_last_ref().map(|b| {
let header = b.header(); let header = &b.header;
(header.hash(), header.number(), header.timestamp(), *header.difficulty()) (header.hash(), header.number(), header.timestamp(), *header.difficulty())
}) })
} }
@ -1194,9 +1194,9 @@ impl miner::MinerService for Miner {
} else { } else {
GetAction::Take GetAction::Take
}, },
|b| &b.hash() == &block_hash |b| &b.header.bare_hash() == &block_hash
) { ) {
trace!(target: "miner", "Submitted block {}={}={} with seal {:?}", block_hash, b.hash(), b.header().bare_hash(), seal); trace!(target: "miner", "Submitted block {}={} with seal {:?}", block_hash, b.header.bare_hash(), seal);
b.lock().try_seal(&*self.engine, seal).or_else(|e| { b.lock().try_seal(&*self.engine, seal).or_else(|e| {
warn!(target: "miner", "Mined solution rejected: {}", e); warn!(target: "miner", "Mined solution rejected: {}", e);
Err(ErrorKind::PowInvalid.into()) Err(ErrorKind::PowInvalid.into())
@ -1207,8 +1207,8 @@ impl miner::MinerService for Miner {
}; };
result.and_then(|sealed| { result.and_then(|sealed| {
let n = sealed.header().number(); let n = sealed.header.number();
let h = sealed.header().hash(); let h = sealed.header.hash();
info!(target: "miner", "Submitted block imported OK. #{}: {}", Colour::White.bold().paint(format!("{}", n)), Colour::White.bold().paint(format!("{:x}", h))); info!(target: "miner", "Submitted block imported OK. #{}: {}", Colour::White.bold().paint(format!("{}", n)), Colour::White.bold().paint(format!("{:x}", h)));
Ok(sealed) Ok(sealed)
}) })
@ -1304,19 +1304,25 @@ impl miner::MinerService for Miner {
} }
fn pending_state(&self, latest_block_number: BlockNumber) -> Option<Self::State> { fn pending_state(&self, latest_block_number: BlockNumber) -> Option<Self::State> {
self.map_existing_pending_block(|b| b.state().clone(), latest_block_number) self.map_existing_pending_block(|b| b.state.clone(), latest_block_number)
} }
fn pending_block_header(&self, latest_block_number: BlockNumber) -> Option<Header> { fn pending_block_header(&self, latest_block_number: BlockNumber) -> Option<Header> {
self.map_existing_pending_block(|b| b.header().clone(), latest_block_number) self.map_existing_pending_block(|b| b.header.clone(), latest_block_number)
} }
fn pending_block(&self, latest_block_number: BlockNumber) -> Option<Block> { fn pending_block(&self, latest_block_number: BlockNumber) -> Option<Block> {
self.map_existing_pending_block(|b| b.to_base(), latest_block_number) self.map_existing_pending_block(|b| {
Block {
header: b.header.clone(),
transactions: b.transactions.iter().cloned().map(Into::into).collect(),
uncles: b.uncles.to_vec(),
}
}, latest_block_number)
} }
fn pending_transactions(&self, latest_block_number: BlockNumber) -> Option<Vec<SignedTransaction>> { fn pending_transactions(&self, latest_block_number: BlockNumber) -> Option<Vec<SignedTransaction>> {
self.map_existing_pending_block(|b| b.transactions().into_iter().cloned().collect(), latest_block_number) self.map_existing_pending_block(|b| b.transactions.iter().cloned().collect(), latest_block_number)
} }
} }

View File

@ -27,7 +27,6 @@ use types::filter::Filter;
use types::view; use types::view;
use types::views::BlockView; use types::views::BlockView;
use block::IsBlock;
use client::{BlockChainClient, Client, ClientConfig, BlockId, ChainInfo, BlockInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock}; use client::{BlockChainClient, Client, ClientConfig, BlockId, ChainInfo, BlockInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock};
use ethereum; use ethereum;
use executive::{Executive, TransactOptions}; use executive::{Executive, TransactOptions};
@ -254,7 +253,7 @@ fn can_mine() {
let b = client.prepare_open_block(Address::default(), (3141562.into(), 31415620.into()), vec![]).unwrap().close().unwrap(); let b = client.prepare_open_block(Address::default(), (3141562.into(), 31415620.into()), vec![]).unwrap().close().unwrap();
assert_eq!(*b.block().header().parent_hash(), view!(BlockView, &dummy_blocks[0]).header_view().hash()); assert_eq!(*b.header.parent_hash(), view!(BlockView, &dummy_blocks[0]).header_view().hash());
} }
#[test] #[test]

View File

@ -20,7 +20,7 @@ use std::sync::Arc;
use std::collections::{BTreeMap, BTreeSet, HashMap}; use std::collections::{BTreeMap, BTreeSet, HashMap};
use bytes::Bytes; use bytes::Bytes;
use ethcore::block::{SealedBlock, IsBlock}; use ethcore::block::SealedBlock;
use ethcore::client::{Nonce, PrepareOpenBlock, StateClient, EngineInfo}; use ethcore::client::{Nonce, PrepareOpenBlock, StateClient, EngineInfo};
use ethcore::engines::{EthEngine, signer::EngineSigner}; use ethcore::engines::{EthEngine, signer::EngineSigner};
use ethcore::error::Error; use ethcore::error::Error;
@ -193,7 +193,7 @@ impl MinerService for TestMinerService {
let params = self.authoring_params(); let params = self.authoring_params();
let open_block = chain.prepare_open_block(params.author, params.gas_range_target, params.extra_data).unwrap(); let open_block = chain.prepare_open_block(params.author, params.gas_range_target, params.extra_data).unwrap();
let closed = open_block.close().unwrap(); let closed = open_block.close().unwrap();
let header = closed.header(); let header = &closed.header;
Some((header.hash(), header.number(), header.timestamp(), *header.difficulty())) Some((header.hash(), header.number(), header.timestamp(), *header.difficulty()))
} }