simplify block module and usage (#10479)
* removed trait IsBlock and simplify block usage * removed redundant ClosedBlock::hash function
This commit is contained in:
parent
d83143d0ba
commit
a574df3132
@ -31,7 +31,7 @@
|
||||
//! `ExecutedBlock` is an underlaying data structure used by all structs above to store block
|
||||
//! related info.
|
||||
|
||||
use std::cmp;
|
||||
use std::{cmp, ops};
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -52,7 +52,6 @@ use vm::{EnvInfo, LastHashes};
|
||||
use hash::keccak;
|
||||
use rlp::{RlpStream, Encodable, encode_list};
|
||||
use types::transaction::{SignedTransaction, Error as TransactionError};
|
||||
use types::block::Block;
|
||||
use types::header::{Header, ExtendedHeader};
|
||||
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`
|
||||
pub trait Drain {
|
||||
/// Returns `ExecutedBlock`
|
||||
fn drain(self) -> ExecutedBlock;
|
||||
}
|
||||
|
||||
impl IsBlock for ExecutedBlock {
|
||||
fn block(&self) -> &ExecutedBlock { self }
|
||||
}
|
||||
|
||||
impl<'x> OpenBlock<'x> {
|
||||
/// Create a new `OpenBlock` ready for transaction pushing.
|
||||
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
|
||||
/// that the header itself is actually valid.
|
||||
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 {
|
||||
return Err(BlockError::TooManyUncles(OutOfBounds{
|
||||
min: None,
|
||||
@ -264,11 +229,6 @@ impl<'x> OpenBlock<'x> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the environment info concerning this block.
|
||||
pub fn env_info(&self) -> EnvInfo {
|
||||
self.block.env_info()
|
||||
}
|
||||
|
||||
/// Push a transaction into the block.
|
||||
///
|
||||
/// 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());
|
||||
}
|
||||
|
||||
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())?;
|
||||
|
||||
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 }
|
||||
}
|
||||
|
||||
impl<'x> IsBlock for OpenBlock<'x> {
|
||||
fn block(&self) -> &ExecutedBlock { &self.block }
|
||||
impl<'a> ops::Deref for OpenBlock<'a> {
|
||||
type Target = ExecutedBlock;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.block
|
||||
}
|
||||
}
|
||||
|
||||
impl IsBlock for ClosedBlock {
|
||||
fn block(&self) -> &ExecutedBlock { &self.block }
|
||||
impl ops::Deref for ClosedBlock {
|
||||
type Target = ExecutedBlock;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.block
|
||||
}
|
||||
}
|
||||
|
||||
impl IsBlock for LockedBlock {
|
||||
fn block(&self) -> &ExecutedBlock { &self.block }
|
||||
impl ops::Deref for LockedBlock {
|
||||
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 {
|
||||
/// 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.
|
||||
pub fn lock(self) -> LockedBlock {
|
||||
LockedBlock {
|
||||
@ -423,18 +400,13 @@ impl LockedBlock {
|
||||
self.block.header.set_receipts_root(
|
||||
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`.
|
||||
///
|
||||
/// NOTE: This does not check the validity of `seal` with the engine.
|
||||
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;
|
||||
if seal.len() != expected_seal_fields {
|
||||
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
|
||||
fn enact(
|
||||
header: Header,
|
||||
|
@ -45,7 +45,7 @@ use types::receipt::{Receipt, LocalizedReceipt};
|
||||
use types::{BlockNumber, header::{Header, ExtendedHeader}};
|
||||
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::{
|
||||
Nonce, Balance, ChainInfo, BlockInfo, TransactionInfo,
|
||||
@ -299,7 +299,7 @@ impl Importer {
|
||||
match self.check_and_lock_block(&bytes, block, client) {
|
||||
Ok((closed_block, pending)) => {
|
||||
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);
|
||||
import_results.push(route);
|
||||
client.report.write().accrue_block(&header, transactions_len);
|
||||
@ -423,13 +423,13 @@ impl Importer {
|
||||
// if the expected receipts root header does not match.
|
||||
// (i.e. allow inconsistency in receipts outcome before the transition block)
|
||||
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();
|
||||
}
|
||||
|
||||
// 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);
|
||||
bail!(e);
|
||||
}
|
||||
@ -437,8 +437,8 @@ impl Importer {
|
||||
let pending = self.check_epoch_end_signal(
|
||||
&header,
|
||||
bytes,
|
||||
locked_block.receipts(),
|
||||
locked_block.state().db(),
|
||||
&locked_block.receipts,
|
||||
locked_block.state.db(),
|
||||
client
|
||||
)?;
|
||||
|
||||
@ -2276,8 +2276,8 @@ impl ReopenBlock for Client {
|
||||
fn reopen_block(&self, block: ClosedBlock) -> OpenBlock {
|
||||
let engine = &*self.engine;
|
||||
let mut block = block.reopen(engine);
|
||||
let max_uncles = engine.maximum_uncle_count(block.header().number());
|
||||
if block.uncles().len() < max_uncles {
|
||||
let max_uncles = engine.maximum_uncle_count(block.header.number());
|
||||
if block.uncles.len() < max_uncles {
|
||||
let chain = self.chain.read();
|
||||
let h = chain.best_block_hash();
|
||||
// Add new uncles
|
||||
@ -2286,14 +2286,14 @@ impl ReopenBlock for Client {
|
||||
.unwrap_or_else(Vec::new);
|
||||
|
||||
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 = uncle.decode().expect("decoding failure");
|
||||
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;
|
||||
so all push_uncle are Ok;
|
||||
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)
|
||||
.unwrap_or_else(Vec::new)
|
||||
.into_iter()
|
||||
.take(engine.maximum_uncle_count(open_block.header().number()))
|
||||
.take(engine.maximum_uncle_count(open_block.header.number()))
|
||||
.foreach(|h| {
|
||||
open_block.push_uncle(h.decode().expect("decoding failure")).expect("pushing maximum_uncle_count;
|
||||
open_block was just created;
|
||||
@ -2354,7 +2354,7 @@ impl ImportSealedBlock for Client {
|
||||
fn import_sealed_block(&self, block: SealedBlock) -> EthcoreResult<H256> {
|
||||
let start = Instant::now();
|
||||
let raw = block.rlp_bytes();
|
||||
let header = block.header().clone();
|
||||
let header = block.header.clone();
|
||||
let hash = header.hash();
|
||||
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(
|
||||
&header,
|
||||
&block_data,
|
||||
block.receipts(),
|
||||
block.state().db(),
|
||||
&block.receipts,
|
||||
block.state.db(),
|
||||
self
|
||||
)?;
|
||||
let route = self.importer.commit_block(
|
||||
|
@ -1030,7 +1030,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
return Seal::None;
|
||||
}
|
||||
|
||||
let header = block.header();
|
||||
let header = &block.header;
|
||||
let parent_step = header_step(parent, self.empty_steps_transition)
|
||||
.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
|
||||
// with the seal.
|
||||
if header.number() >= self.empty_steps_transition &&
|
||||
block.transactions().is_empty() &&
|
||||
block.transactions.is_empty() &&
|
||||
empty_steps.len() < self.maximum_empty_steps {
|
||||
|
||||
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(()) }
|
||||
|
||||
// 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 mut call = |to, data| {
|
||||
@ -1166,8 +1166,8 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
/// Apply the block reward on finalisation of the block.
|
||||
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
|
||||
let mut beneficiaries = Vec::new();
|
||||
if block.header().number() >= self.empty_steps_transition {
|
||||
let empty_steps = if block.header().seal().is_empty() {
|
||||
if block.header.number() >= self.empty_steps_transition {
|
||||
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
|
||||
let client = match self.client.read().as_ref().and_then(|weak| weak.upgrade()) {
|
||||
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")
|
||||
.decode()?;
|
||||
|
||||
@ -1186,7 +1186,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
self.empty_steps(parent_step.into(), current_step.into(), parent.hash())
|
||||
} else {
|
||||
// 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 {
|
||||
@ -1195,11 +1195,11 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
}
|
||||
}
|
||||
|
||||
let author = *block.header().author();
|
||||
let author = *block.header.author();
|
||||
beneficiaries.push((author, RewardKind::Author));
|
||||
|
||||
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 rewards = c.reward(&beneficiaries, &mut call)?;
|
||||
@ -1634,17 +1634,17 @@ mod tests {
|
||||
let b2 = b2.close_and_lock().unwrap();
|
||||
|
||||
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());
|
||||
// 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())));
|
||||
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());
|
||||
// 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();
|
||||
|
||||
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::Regular(_) => {
|
||||
engine.step();
|
||||
|
||||
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::None => {}
|
||||
}
|
||||
@ -1902,7 +1902,7 @@ mod tests {
|
||||
let b1 = b1.close_and_lock().unwrap();
|
||||
|
||||
// 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
|
||||
let empty_step_rlp = encode(&empty_step(engine, 2, &genesis_header.hash()));
|
||||
@ -1912,7 +1912,7 @@ mod tests {
|
||||
let len = notify.messages.read().len();
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
@ -1941,7 +1941,7 @@ mod tests {
|
||||
|
||||
// since the block is empty it isn't sealed and we generate empty steps
|
||||
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();
|
||||
|
||||
// step 3
|
||||
@ -1958,7 +1958,7 @@ mod tests {
|
||||
|
||||
// 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())));
|
||||
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())));
|
||||
let empty_step2 = sealed_empty_step(engine, 2, &genesis_header.hash());
|
||||
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
|
||||
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();
|
||||
|
||||
// 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 = b2.close_and_lock().unwrap();
|
||||
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();
|
||||
|
||||
// step 4
|
||||
@ -2010,7 +2010,7 @@ mod tests {
|
||||
let b3 = b3.close_and_lock().unwrap();
|
||||
|
||||
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());
|
||||
engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
|
||||
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
|
||||
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();
|
||||
|
||||
// step 3
|
||||
// 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 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
|
||||
let b2 = b2.close_and_lock().unwrap();
|
||||
|
||||
// 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]
|
||||
@ -2155,7 +2155,7 @@ mod tests {
|
||||
|
||||
// since the block is empty it isn't sealed and we generate empty steps
|
||||
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();
|
||||
|
||||
// step 3
|
||||
@ -2173,7 +2173,7 @@ mod tests {
|
||||
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
|
||||
@ -2181,7 +2181,7 @@ mod tests {
|
||||
|
||||
// the contract rewards (1000 + kind) for each benefactor/reward kind
|
||||
assert_eq!(
|
||||
b2.block().state().balance(&addr1).unwrap(),
|
||||
b2.state.balance(&addr1).unwrap(),
|
||||
addr1_balance + (1000 + 0) + (1000 + 2),
|
||||
)
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ impl Engine<EthereumMachine> for BasicAuthority {
|
||||
|
||||
/// Attempt to seal the block internally.
|
||||
fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal {
|
||||
let header = block.header();
|
||||
let header = &block.header;
|
||||
let author = header.author();
|
||||
if self.validators.contains(header.parent_hash(), author) {
|
||||
// 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 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();
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ mod tests {
|
||||
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 = 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());
|
||||
}
|
||||
}
|
||||
|
@ -542,7 +542,7 @@ mod tests {
|
||||
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 = 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]
|
||||
@ -596,8 +596,8 @@ mod tests {
|
||||
b.push_uncle(uncle).unwrap();
|
||||
|
||||
let b = b.close().unwrap();
|
||||
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(&Address::zero()).unwrap(), "478eae0e571ba000".into());
|
||||
assert_eq!(b.state.balance(&uncle_author).unwrap(), "3cb71f51fc558000".into());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -612,9 +612,9 @@ mod tests {
|
||||
|
||||
let ubi_contract: Address = "00efdd5883ec628983e9063c7d969fe268bbf310".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(&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(&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(&dev_contract).unwrap(), U256::from_str("c249fdd327780000").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -28,7 +28,7 @@ use types::header::Header;
|
||||
use vm::{CallType, ActionParams, ActionValue, ParamsType};
|
||||
use vm::{EnvInfo, Schedule, CreateContractAddress};
|
||||
|
||||
use block::{ExecutedBlock, IsBlock};
|
||||
use block::ExecutedBlock;
|
||||
use builtin::Builtin;
|
||||
use call_contract::CallContract;
|
||||
use client::BlockInfo;
|
||||
@ -126,7 +126,7 @@ impl EthereumMachine {
|
||||
data: Option<Vec<u8>>,
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
let (code, code_hash) = {
|
||||
let state = block.state();
|
||||
let state = &block.state;
|
||||
|
||||
(state.code(&contract_address)?,
|
||||
state.code_hash(&contract_address)?)
|
||||
@ -193,12 +193,12 @@ impl EthereumMachine {
|
||||
/// Push last known block hash to the state.
|
||||
fn push_last_hash(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
|
||||
let params = self.params();
|
||||
if block.header().number() == params.eip210_transition {
|
||||
if block.header.number() == params.eip210_transition {
|
||||
let state = block.state_mut();
|
||||
state.init_code(¶ms.eip210_contract_address, params.eip210_contract_code.clone())?;
|
||||
}
|
||||
if block.header().number() >= params.eip210_transition {
|
||||
let parent_hash = block.header().parent_hash().clone();
|
||||
if block.header.number() >= params.eip210_transition {
|
||||
let parent_hash = *block.header.parent_hash();
|
||||
let _ = self.execute_as_system(
|
||||
block,
|
||||
params.eip210_contract_address,
|
||||
@ -215,7 +215,7 @@ impl EthereumMachine {
|
||||
self.push_last_hash(block)?;
|
||||
|
||||
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();
|
||||
for child in ðash_params.dao_hardfork_accounts {
|
||||
let beneficiary = ðash_params.dao_hardfork_beneficiary;
|
||||
@ -434,7 +434,7 @@ impl super::Machine for EthereumMachine {
|
||||
type Error = 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> {
|
||||
|
@ -46,7 +46,7 @@ use types::header::Header;
|
||||
use types::receipt::RichReceipt;
|
||||
use using_queue::{UsingQueue, GetAction};
|
||||
|
||||
use block::{ClosedBlock, IsBlock, SealedBlock};
|
||||
use block::{ClosedBlock, SealedBlock};
|
||||
use client::{
|
||||
BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId
|
||||
};
|
||||
@ -362,7 +362,7 @@ impl Miner {
|
||||
.and_then(|b| {
|
||||
// to prevent a data race between block import and updating pending block
|
||||
// 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))
|
||||
} else {
|
||||
None
|
||||
@ -392,7 +392,7 @@ impl Miner {
|
||||
// Open block
|
||||
let (mut open_block, original_work_hash) = {
|
||||
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;
|
||||
|
||||
// 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;
|
||||
// otherwise, leave everything alone.
|
||||
// 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) => {
|
||||
trace!(target: "miner", "prepare_block: Already have previous work; updating and returning");
|
||||
// add transactions to old_block
|
||||
@ -436,7 +436,7 @@ impl Miner {
|
||||
let mut invalid_transactions = HashSet::new();
|
||||
let mut not_allowed_transactions = 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 skipped_transactions = 0usize;
|
||||
@ -453,7 +453,7 @@ impl Miner {
|
||||
let max_transactions = if min_tx_gas.is_zero() {
|
||||
usize::max_value()
|
||||
} 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(
|
||||
@ -636,7 +636,7 @@ impl Miner {
|
||||
{
|
||||
{
|
||||
let sealing = self.sealing.lock();
|
||||
if block.transactions().is_empty()
|
||||
if block.transactions.is_empty()
|
||||
&& !self.forced_sealing()
|
||||
&& Instant::now() <= sealing.next_mandatory_reseal
|
||||
{
|
||||
@ -646,7 +646,7 @@ impl Miner {
|
||||
|
||||
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) => {
|
||||
match h.decode() {
|
||||
Ok(decoded_hdr) => decoded_hdr,
|
||||
@ -656,7 +656,7 @@ impl Miner {
|
||||
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.
|
||||
Seal::Proposal(seal) => {
|
||||
trace!(target: "miner", "Received a Proposal seal.");
|
||||
@ -705,11 +705,11 @@ impl Miner {
|
||||
/// Prepares work which has to be done to seal.
|
||||
fn prepare_work(&self, block: ClosedBlock, original_work_hash: Option<H256>) {
|
||||
let (work, is_new) = {
|
||||
let block_header = block.block().header().clone();
|
||||
let block_header = block.header.clone();
|
||||
let block_hash = block_header.hash();
|
||||
|
||||
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!(
|
||||
target: "miner",
|
||||
@ -742,7 +742,7 @@ impl Miner {
|
||||
trace!(
|
||||
target: "miner",
|
||||
"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)
|
||||
};
|
||||
@ -994,7 +994,7 @@ impl miner::MinerService for Miner {
|
||||
|
||||
let from_pending = || {
|
||||
self.map_existing_pending_block(|sealing| {
|
||||
sealing.transactions()
|
||||
sealing.transactions
|
||||
.iter()
|
||||
.map(|signed| signed.hash())
|
||||
.collect()
|
||||
@ -1041,7 +1041,7 @@ impl miner::MinerService for Miner {
|
||||
|
||||
let from_pending = || {
|
||||
self.map_existing_pending_block(|sealing| {
|
||||
sealing.transactions()
|
||||
sealing.transactions
|
||||
.iter()
|
||||
.map(|signed| pool::VerifiedTransaction::from_pending_block_transaction(signed.clone()))
|
||||
.map(Arc::new)
|
||||
@ -1086,9 +1086,9 @@ impl miner::MinerService for Miner {
|
||||
|
||||
fn pending_receipts(&self, best_block: BlockNumber) -> Option<Vec<RichReceipt>> {
|
||||
self.map_existing_pending_block(|pending| {
|
||||
let receipts = pending.receipts();
|
||||
pending.transactions()
|
||||
.into_iter()
|
||||
let receipts = &pending.receipts;
|
||||
pending.transactions
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, tx)| {
|
||||
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::Create => {
|
||||
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(),
|
||||
@ -1139,7 +1139,7 @@ impl miner::MinerService for Miner {
|
||||
|
||||
// refuse to seal the first block of the chain if it contains hard forks
|
||||
// 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() {
|
||||
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);
|
||||
@ -1180,7 +1180,7 @@ impl miner::MinerService for Miner {
|
||||
self.prepare_pending_block(chain);
|
||||
|
||||
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())
|
||||
})
|
||||
}
|
||||
@ -1194,9 +1194,9 @@ impl miner::MinerService for Miner {
|
||||
} else {
|
||||
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| {
|
||||
warn!(target: "miner", "Mined solution rejected: {}", e);
|
||||
Err(ErrorKind::PowInvalid.into())
|
||||
@ -1207,8 +1207,8 @@ impl miner::MinerService for Miner {
|
||||
};
|
||||
|
||||
result.and_then(|sealed| {
|
||||
let n = sealed.header().number();
|
||||
let h = sealed.header().hash();
|
||||
let n = sealed.header.number();
|
||||
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)));
|
||||
Ok(sealed)
|
||||
})
|
||||
@ -1304,19 +1304,25 @@ impl miner::MinerService for Miner {
|
||||
}
|
||||
|
||||
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> {
|
||||
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> {
|
||||
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>> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@ use types::filter::Filter;
|
||||
use types::view;
|
||||
use types::views::BlockView;
|
||||
|
||||
use block::IsBlock;
|
||||
use client::{BlockChainClient, Client, ClientConfig, BlockId, ChainInfo, BlockInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock};
|
||||
use ethereum;
|
||||
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();
|
||||
|
||||
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]
|
||||
|
@ -20,7 +20,7 @@ use std::sync::Arc;
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap};
|
||||
|
||||
use bytes::Bytes;
|
||||
use ethcore::block::{SealedBlock, IsBlock};
|
||||
use ethcore::block::SealedBlock;
|
||||
use ethcore::client::{Nonce, PrepareOpenBlock, StateClient, EngineInfo};
|
||||
use ethcore::engines::{EthEngine, signer::EngineSigner};
|
||||
use ethcore::error::Error;
|
||||
@ -193,7 +193,7 @@ impl MinerService for TestMinerService {
|
||||
let params = self.authoring_params();
|
||||
let open_block = chain.prepare_open_block(params.author, params.gas_range_target, params.extra_data).unwrap();
|
||||
let closed = open_block.close().unwrap();
|
||||
let header = closed.header();
|
||||
let header = &closed.header;
|
||||
|
||||
Some((header.hash(), header.number(), header.timestamp(), *header.difficulty()))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user