New mining framework.

Fixes #756.
This commit is contained in:
Gav Wood
2016-03-24 23:03:22 +01:00
parent 3be2763929
commit 830ef7ddfc
10 changed files with 105 additions and 148 deletions

View File

@@ -101,6 +101,22 @@ pub struct BlockRefMut<'a> {
pub traces: &'a Option<Vec<Trace>>,
}
/// A set of immutable references to `ExecutedBlock` fields that are publicly accessible.
pub struct BlockRef<'a> {
/// Block header.
pub header: &'a Header,
/// Block transactions.
pub transactions: &'a Vec<SignedTransaction>,
/// Block uncles.
pub uncles: &'a Vec<Header>,
/// Transaction receipts.
pub receipts: &'a Vec<Receipt>,
/// State.
pub state: &'a State,
/// Traces.
pub traces: &'a Option<Vec<Trace>>,
}
impl ExecutedBlock {
/// Create a new block from the given `state`.
fn new(state: State, tracing: bool) -> ExecutedBlock {
@@ -114,7 +130,7 @@ impl ExecutedBlock {
}
/// Get a structure containing individual references to all public fields.
pub fn fields(&mut self) -> BlockRefMut {
pub fn fields_mut(&mut self) -> BlockRefMut {
BlockRefMut {
header: &self.base.header,
transactions: &self.base.transactions,
@@ -124,6 +140,18 @@ impl ExecutedBlock {
traces: &self.traces,
}
}
/// Get a structure containing individual references to all public fields.
pub fn fields(&self) -> BlockRef {
BlockRef {
header: &self.base.header,
transactions: &self.base.transactions,
uncles: &self.base.uncles,
state: &self.state,
receipts: &self.receipts,
traces: &self.traces,
}
}
}
/// Trait for a object that is_a `ExecutedBlock`.
@@ -261,8 +289,8 @@ impl<'x> OpenBlock<'x> {
///
/// If valid, it will be executed, and archived together with the receipt.
pub fn push_transaction(&mut self, t: SignedTransaction, h: Option<H256>) -> Result<&Receipt, Error> {
if self.block.transactions_set.contains(t.hash()) {
return Err(From::from(ExecutionError::AlreadyImported));
if self.block.transactions_set.contains(&t.hash()) {
return Err(From::from(TransactionError::AlreadyImported));
}
let env_info = self.env_info();

View File

@@ -426,9 +426,8 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
block.try_seal(self.engine.deref().deref(), seal)
}
// TODO: either work out a better API than this or refactor prepare_sealing and try_seal in terms of this.
fn with_engine<F, T>(&self, f: F) -> T where F: FnOnce(&Engine) -> T {
f(self.engine.deref().deref())
fn engine(&self) -> &Engine {
self.engine.deref().deref()
}
// TODO [todr] Should be moved to miner crate eventually.

View File

@@ -40,6 +40,7 @@ use log_entry::LocalizedLogEntry;
use filter::Filter;
use error::{ImportResult, Error};
use receipt::LocalizedReceipt;
use engine::{Engine};
/// Blockchain database client. Owns and manages a blockchain and a block queue.
pub trait BlockChainClient : Sync + Send {
@@ -130,6 +131,6 @@ pub trait BlockChainClient : Sync + Send {
fn call(&self, t: &SignedTransaction) -> Result<Executed, Error>;
/// Executes a function providing it with a reference to an engine.
fn with_engine<F>(&self, _f: F) where F: FnOnce(&Engine) {}
fn engine(&self) -> &Engine;
}

View File

@@ -31,6 +31,7 @@ use block_queue::BlockQueueInfo;
use block::{SealedBlock, ClosedBlock};
use executive::Executed;
use error::Error;
use engine::Engine;
/// Test client.
pub struct TestBlockChainClient {
@@ -249,7 +250,7 @@ impl BlockChainClient for TestBlockChainClient {
}
fn prepare_sealing(&self, _author: Address, _gas_floor_target: U256, _extra_data: Bytes, _transactions: Vec<SignedTransaction>) -> (Option<ClosedBlock>, HashSet<H256>) {
(None, vec![])
(None, HashSet::new())
}
fn try_seal(&self, block: ClosedBlock, _seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
@@ -404,4 +405,8 @@ impl BlockChainClient for TestBlockChainClient {
best_block_number: self.blocks.read().unwrap().len() as BlockNumber - 1,
}
}
fn engine(&self) -> &Engine {
unimplemented!();
}
}

View File

@@ -101,7 +101,7 @@ impl Engine for Ethash {
/// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current).
fn on_close_block(&self, block: &mut ExecutedBlock) {
let reward = self.spec().engine_params.get("blockReward").map_or(U256::from(0u64), |a| decode(&a));
let fields = block.fields();
let fields = block.fields_mut();
// Bestow block reward
fields.state.add_balance(&fields.header.author, &(reward + reward / U256::from(32) * U256::from(fields.uncles.len())));