Break circular dependency between Client and Engine (part 1) (#10833)
* First draft: pass the parent block header to on_close_block * typos and cleanup * whitespace * Store parent in ClosedBlock as well so it can be reopen()'d * Don't pass parent when reopening a block * Remove the unused ancestry param
This commit is contained in:
parent
09edb94d53
commit
582a4ea339
@ -22,13 +22,13 @@
|
|||||||
//! and can be appended to with transactions and uncles.
|
//! and can be appended to with transactions and uncles.
|
||||||
//!
|
//!
|
||||||
//! When ready, `OpenBlock` can be closed and turned into a `ClosedBlock`. A `ClosedBlock` can
|
//! When ready, `OpenBlock` can be closed and turned into a `ClosedBlock`. A `ClosedBlock` can
|
||||||
//! be reopend again by a miner under certain circumstances. On block close, state commit is
|
//! be re-opend again by a miner under certain circumstances. On block close, state commit is
|
||||||
//! performed.
|
//! performed.
|
||||||
//!
|
//!
|
||||||
//! `LockedBlock` is a version of a `ClosedBlock` that cannot be reopened. It can be sealed
|
//! `LockedBlock` is a version of a `ClosedBlock` that cannot be reopened. It can be sealed
|
||||||
//! using an engine.
|
//! using an engine.
|
||||||
//!
|
//!
|
||||||
//! `ExecutedBlock` is an underlaying data structure used by all structs above to store block
|
//! `ExecutedBlock` is an underlying data structure used by all structs above to store block
|
||||||
//! related info.
|
//! related info.
|
||||||
|
|
||||||
use std::{cmp, ops};
|
use std::{cmp, ops};
|
||||||
@ -52,7 +52,7 @@ 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::header::{Header, ExtendedHeader};
|
use types::header::Header;
|
||||||
use types::receipt::{Receipt, TransactionOutcome};
|
use types::receipt::{Receipt, TransactionOutcome};
|
||||||
|
|
||||||
/// Block that is ready for transactions to be added.
|
/// Block that is ready for transactions to be added.
|
||||||
@ -62,6 +62,7 @@ use types::receipt::{Receipt, TransactionOutcome};
|
|||||||
pub struct OpenBlock<'x> {
|
pub struct OpenBlock<'x> {
|
||||||
block: ExecutedBlock,
|
block: ExecutedBlock,
|
||||||
engine: &'x dyn Engine,
|
engine: &'x dyn Engine,
|
||||||
|
parent: Header,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Just like `OpenBlock`, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
|
/// Just like `OpenBlock`, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
|
||||||
@ -72,6 +73,7 @@ pub struct OpenBlock<'x> {
|
|||||||
pub struct ClosedBlock {
|
pub struct ClosedBlock {
|
||||||
block: ExecutedBlock,
|
block: ExecutedBlock,
|
||||||
unclosed_state: State<StateDB>,
|
unclosed_state: State<StateDB>,
|
||||||
|
parent: Header,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Just like `ClosedBlock` except that we can't reopen it and it's faster.
|
/// Just like `ClosedBlock` except that we can't reopen it and it's faster.
|
||||||
@ -102,7 +104,7 @@ pub struct ExecutedBlock {
|
|||||||
pub receipts: Vec<Receipt>,
|
pub receipts: Vec<Receipt>,
|
||||||
/// Hashes of already executed transactions.
|
/// Hashes of already executed transactions.
|
||||||
pub transactions_set: HashSet<H256>,
|
pub transactions_set: HashSet<H256>,
|
||||||
/// Underlaying state.
|
/// Underlying state.
|
||||||
pub state: State<StateDB>,
|
pub state: State<StateDB>,
|
||||||
/// Transaction traces.
|
/// Transaction traces.
|
||||||
pub traces: Tracing,
|
pub traces: Tracing,
|
||||||
@ -119,13 +121,13 @@ impl ExecutedBlock {
|
|||||||
uncles: Default::default(),
|
uncles: Default::default(),
|
||||||
receipts: Default::default(),
|
receipts: Default::default(),
|
||||||
transactions_set: Default::default(),
|
transactions_set: Default::default(),
|
||||||
state: state,
|
state,
|
||||||
traces: if tracing {
|
traces: if tracing {
|
||||||
Tracing::enabled()
|
Tracing::enabled()
|
||||||
} else {
|
} else {
|
||||||
Tracing::Disabled
|
Tracing::Disabled
|
||||||
},
|
},
|
||||||
last_hashes: last_hashes,
|
last_hashes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +164,7 @@ pub trait Drain {
|
|||||||
|
|
||||||
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, I: IntoIterator<Item = ExtendedHeader>>(
|
pub fn new<'a>(
|
||||||
engine: &'x dyn Engine,
|
engine: &'x dyn Engine,
|
||||||
factories: Factories,
|
factories: Factories,
|
||||||
tracing: bool,
|
tracing: bool,
|
||||||
@ -173,14 +175,11 @@ impl<'x> OpenBlock<'x> {
|
|||||||
gas_range_target: (U256, U256),
|
gas_range_target: (U256, U256),
|
||||||
extra_data: Bytes,
|
extra_data: Bytes,
|
||||||
is_epoch_begin: bool,
|
is_epoch_begin: bool,
|
||||||
ancestry: I,
|
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let number = parent.number() + 1;
|
let number = parent.number() + 1;
|
||||||
let state = State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce(number), factories)?;
|
let state = State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce(number), factories)?;
|
||||||
let mut r = OpenBlock {
|
|
||||||
block: ExecutedBlock::new(state, last_hashes, tracing),
|
let mut r = OpenBlock { block: ExecutedBlock::new(state, last_hashes, tracing), engine, parent: parent.clone() };
|
||||||
engine: engine,
|
|
||||||
};
|
|
||||||
|
|
||||||
r.block.header.set_parent_hash(parent.hash());
|
r.block.header.set_parent_hash(parent.hash());
|
||||||
r.block.header.set_number(number);
|
r.block.header.set_number(number);
|
||||||
@ -195,7 +194,7 @@ impl<'x> OpenBlock<'x> {
|
|||||||
engine.populate_from_parent(&mut r.block.header, parent);
|
engine.populate_from_parent(&mut r.block.header, parent);
|
||||||
|
|
||||||
engine.machine().on_new_block(&mut r.block)?;
|
engine.machine().on_new_block(&mut r.block)?;
|
||||||
engine.on_new_block(&mut r.block, is_epoch_begin, &mut ancestry.into_iter())?;
|
engine.on_new_block(&mut r.block, is_epoch_begin)?;
|
||||||
|
|
||||||
Ok(r)
|
Ok(r)
|
||||||
}
|
}
|
||||||
@ -297,19 +296,20 @@ impl<'x> OpenBlock<'x> {
|
|||||||
/// Turn this into a `ClosedBlock`.
|
/// Turn this into a `ClosedBlock`.
|
||||||
pub fn close(self) -> Result<ClosedBlock, Error> {
|
pub fn close(self) -> Result<ClosedBlock, Error> {
|
||||||
let unclosed_state = self.block.state.clone();
|
let unclosed_state = self.block.state.clone();
|
||||||
|
let parent = self.parent.clone();
|
||||||
let locked = self.close_and_lock()?;
|
let locked = self.close_and_lock()?;
|
||||||
|
|
||||||
Ok(ClosedBlock {
|
Ok(ClosedBlock {
|
||||||
block: locked.block,
|
block: locked.block,
|
||||||
unclosed_state,
|
unclosed_state,
|
||||||
|
parent,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn this into a `LockedBlock`.
|
/// Turn this into a `LockedBlock`.
|
||||||
pub fn close_and_lock(self) -> Result<LockedBlock, Error> {
|
pub fn close_and_lock(self) -> Result<LockedBlock, Error> {
|
||||||
let mut s = self;
|
let mut s = self;
|
||||||
|
s.engine.on_close_block(&mut s.block, &s.parent)?;
|
||||||
s.engine.on_close_block(&mut s.block)?;
|
|
||||||
s.block.state.commit()?;
|
s.block.state.commit()?;
|
||||||
|
|
||||||
s.block.header.set_transactions_root(ordered_trie_root(s.block.transactions.iter().map(|e| e.rlp_bytes())));
|
s.block.header.set_transactions_root(ordered_trie_root(s.block.transactions.iter().map(|e| e.rlp_bytes())));
|
||||||
@ -378,10 +378,8 @@ impl ClosedBlock {
|
|||||||
// revert rewards (i.e. set state back at last transaction's state).
|
// revert rewards (i.e. set state back at last transaction's state).
|
||||||
let mut block = self.block;
|
let mut block = self.block;
|
||||||
block.state = self.unclosed_state;
|
block.state = self.unclosed_state;
|
||||||
OpenBlock {
|
let parent = self.parent;
|
||||||
block: block,
|
OpenBlock { block, engine, parent }
|
||||||
engine: engine,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,7 +477,6 @@ pub(crate) fn enact(
|
|||||||
last_hashes: Arc<LastHashes>,
|
last_hashes: Arc<LastHashes>,
|
||||||
factories: Factories,
|
factories: Factories,
|
||||||
is_epoch_begin: bool,
|
is_epoch_begin: bool,
|
||||||
ancestry: &mut dyn Iterator<Item=ExtendedHeader>,
|
|
||||||
) -> Result<LockedBlock, Error> {
|
) -> Result<LockedBlock, Error> {
|
||||||
// For trace log
|
// For trace log
|
||||||
let trace_state = if log_enabled!(target: "enact", ::log::Level::Trace) {
|
let trace_state = if log_enabled!(target: "enact", ::log::Level::Trace) {
|
||||||
@ -501,7 +498,6 @@ pub(crate) fn enact(
|
|||||||
(3141562.into(), 31415620.into()),
|
(3141562.into(), 31415620.into()),
|
||||||
vec![],
|
vec![],
|
||||||
is_epoch_begin,
|
is_epoch_begin,
|
||||||
ancestry,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if let Some(ref s) = trace_state {
|
if let Some(ref s) = trace_state {
|
||||||
@ -522,7 +518,7 @@ pub(crate) fn enact(
|
|||||||
b.close_and_lock()
|
b.close_and_lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with the given `parent` block header
|
||||||
pub fn enact_verified(
|
pub fn enact_verified(
|
||||||
block: PreverifiedBlock,
|
block: PreverifiedBlock,
|
||||||
engine: &dyn Engine,
|
engine: &dyn Engine,
|
||||||
@ -532,7 +528,6 @@ pub fn enact_verified(
|
|||||||
last_hashes: Arc<LastHashes>,
|
last_hashes: Arc<LastHashes>,
|
||||||
factories: Factories,
|
factories: Factories,
|
||||||
is_epoch_begin: bool,
|
is_epoch_begin: bool,
|
||||||
ancestry: &mut dyn Iterator<Item=ExtendedHeader>,
|
|
||||||
) -> Result<LockedBlock, Error> {
|
) -> Result<LockedBlock, Error> {
|
||||||
|
|
||||||
enact(
|
enact(
|
||||||
@ -546,7 +541,6 @@ pub fn enact_verified(
|
|||||||
last_hashes,
|
last_hashes,
|
||||||
factories,
|
factories,
|
||||||
is_epoch_begin,
|
is_epoch_begin,
|
||||||
ancestry,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,7 +602,6 @@ mod tests {
|
|||||||
(3141562.into(), 31415620.into()),
|
(3141562.into(), 31415620.into()),
|
||||||
vec![],
|
vec![],
|
||||||
false,
|
false,
|
||||||
None,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
b.populate_from(&header);
|
b.populate_from(&header);
|
||||||
@ -643,7 +636,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap();
|
let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let b = b.close_and_lock().unwrap();
|
let b = b.close_and_lock().unwrap();
|
||||||
let _ = b.seal(&*spec.engine, vec![]);
|
let _ = b.seal(&*spec.engine, vec![]);
|
||||||
}
|
}
|
||||||
@ -657,7 +650,7 @@ mod tests {
|
|||||||
|
|
||||||
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||||
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.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap()
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap()
|
||||||
.close_and_lock().unwrap().seal(engine, vec![]).unwrap();
|
.close_and_lock().unwrap().seal(engine, vec![]).unwrap();
|
||||||
let orig_bytes = b.rlp_bytes();
|
let orig_bytes = b.rlp_bytes();
|
||||||
let orig_db = b.drain().state.drop().1;
|
let orig_db = b.drain().state.drop().1;
|
||||||
@ -682,7 +675,7 @@ mod tests {
|
|||||||
|
|
||||||
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap();
|
let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let mut uncle1_header = Header::new();
|
let mut uncle1_header = Header::new();
|
||||||
uncle1_header.set_extra_data(b"uncle1".to_vec());
|
uncle1_header.set_extra_data(b"uncle1".to_vec());
|
||||||
let mut uncle2_header = Header::new();
|
let mut uncle2_header = Header::new();
|
||||||
|
@ -407,7 +407,6 @@ impl Importer {
|
|||||||
last_hashes,
|
last_hashes,
|
||||||
client.factories.clone(),
|
client.factories.clone(),
|
||||||
is_epoch_begin,
|
is_epoch_begin,
|
||||||
&mut chain.ancestry_with_metadata_iter(*header.parent_hash()),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut locked_block = match enact_result {
|
let mut locked_block = match enact_result {
|
||||||
@ -2361,7 +2360,6 @@ impl PrepareOpenBlock for Client {
|
|||||||
gas_range_target,
|
gas_range_target,
|
||||||
extra_data,
|
extra_data,
|
||||||
is_epoch_begin,
|
is_epoch_begin,
|
||||||
chain.ancestry_with_metadata_iter(best_header.hash()),
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Add uncles
|
// Add uncles
|
||||||
|
@ -417,7 +417,6 @@ impl PrepareOpenBlock for TestBlockChainClient {
|
|||||||
gas_range_target,
|
gas_range_target,
|
||||||
extra_data,
|
extra_data,
|
||||||
false,
|
false,
|
||||||
None,
|
|
||||||
)?;
|
)?;
|
||||||
// TODO [todr] Override timestamp for predictability
|
// TODO [todr] Override timestamp for predictability
|
||||||
open_block.set_timestamp(*self.latest_block_timestamp.read());
|
open_block.set_timestamp(*self.latest_block_timestamp.read());
|
||||||
|
@ -1211,7 +1211,6 @@ impl Engine for AuthorityRound {
|
|||||||
&self,
|
&self,
|
||||||
block: &mut ExecutedBlock,
|
block: &mut ExecutedBlock,
|
||||||
epoch_begin: bool,
|
epoch_begin: bool,
|
||||||
_ancestry: &mut dyn Iterator<Item=ExtendedHeader>,
|
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// with immediate transitions, we don't use the epoch mechanism anyway.
|
// with immediate transitions, we don't use the epoch mechanism anyway.
|
||||||
// the genesis is always considered an epoch, but we ignore it intentionally.
|
// the genesis is always considered an epoch, but we ignore it intentionally.
|
||||||
@ -1236,26 +1235,18 @@ impl Engine 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,
|
||||||
|
parent: &Header,
|
||||||
|
) -> 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 parent_step = header_step(parent, self.empty_steps_transition)?;
|
||||||
Some(client) => client,
|
|
||||||
None => {
|
|
||||||
debug!(target: "engine", "Unable to close block: missing client ref.");
|
|
||||||
return Err(EngineError::RequiresClient.into())
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let parent = client.block_header(::client::BlockId::Hash(*block.header.parent_hash()))
|
|
||||||
.expect("hash is from parent; parent header must exist; qed")
|
|
||||||
.decode()?;
|
|
||||||
|
|
||||||
let parent_step = header_step(&parent, self.empty_steps_transition)?;
|
|
||||||
let current_step = self.step.inner.load();
|
let current_step = self.step.inner.load();
|
||||||
self.empty_steps(parent_step.into(), current_step.into(), parent.hash())
|
self.empty_steps(parent_step, current_step, 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)?
|
||||||
@ -1707,9 +1698,9 @@ mod tests {
|
|||||||
let db1 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
let db1 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||||
let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap();
|
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let b1 = b1.close_and_lock().unwrap();
|
let b1 = b1.close_and_lock().unwrap();
|
||||||
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, None).unwrap();
|
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
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())));
|
||||||
@ -1741,9 +1732,9 @@ mod tests {
|
|||||||
let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
|
|
||||||
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap();
|
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let b1 = b1.close_and_lock().unwrap();
|
let b1 = b1.close_and_lock().unwrap();
|
||||||
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, None).unwrap();
|
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
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())));
|
||||||
@ -1991,7 +1982,7 @@ mod tests {
|
|||||||
|
|
||||||
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
|
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
|
||||||
|
|
||||||
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap();
|
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
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
|
||||||
@ -2029,7 +2020,7 @@ mod tests {
|
|||||||
engine.register_client(Arc::downgrade(&client) as _);
|
engine.register_client(Arc::downgrade(&client) as _);
|
||||||
|
|
||||||
// step 2
|
// step 2
|
||||||
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap();
|
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let b1 = b1.close_and_lock().unwrap();
|
let b1 = b1.close_and_lock().unwrap();
|
||||||
|
|
||||||
// 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
|
||||||
@ -2038,7 +2029,7 @@ mod tests {
|
|||||||
engine.step();
|
engine.step();
|
||||||
|
|
||||||
// step 3
|
// step 3
|
||||||
let mut b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, None).unwrap();
|
let mut b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
b2.push_transaction(Transaction {
|
b2.push_transaction(Transaction {
|
||||||
action: Action::Create,
|
action: Action::Create,
|
||||||
nonce: U256::from(0),
|
nonce: U256::from(0),
|
||||||
@ -2082,7 +2073,7 @@ mod tests {
|
|||||||
engine.register_client(Arc::downgrade(&client) as _);
|
engine.register_client(Arc::downgrade(&client) as _);
|
||||||
|
|
||||||
// step 2
|
// step 2
|
||||||
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap();
|
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let b1 = b1.close_and_lock().unwrap();
|
let b1 = b1.close_and_lock().unwrap();
|
||||||
|
|
||||||
// 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
|
||||||
@ -2091,7 +2082,7 @@ mod tests {
|
|||||||
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, None).unwrap();
|
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false).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, &genesis_header), Seal::None);
|
assert_eq!(engine.generate_seal(&b2, &genesis_header), Seal::None);
|
||||||
@ -2099,7 +2090,7 @@ mod tests {
|
|||||||
|
|
||||||
// step 4
|
// step 4
|
||||||
// the spec sets the maximum_empty_steps to 2 so we will now seal an empty block and include the empty step messages
|
// the spec sets the maximum_empty_steps to 2 so we will now seal an empty block and include the empty step messages
|
||||||
let b3 = OpenBlock::new(engine, Default::default(), false, db3, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap();
|
let b3 = OpenBlock::new(engine, Default::default(), false, db3, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
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())));
|
||||||
@ -2132,7 +2123,7 @@ mod tests {
|
|||||||
engine.register_client(Arc::downgrade(&client) as _);
|
engine.register_client(Arc::downgrade(&client) as _);
|
||||||
|
|
||||||
// step 2
|
// step 2
|
||||||
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap();
|
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let b1 = b1.close_and_lock().unwrap();
|
let b1 = b1.close_and_lock().unwrap();
|
||||||
|
|
||||||
// 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
|
||||||
@ -2142,7 +2133,7 @@ mod tests {
|
|||||||
|
|
||||||
// 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, None).unwrap();
|
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let addr1_balance = b2.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
|
||||||
@ -2242,7 +2233,6 @@ mod tests {
|
|||||||
(3141562.into(), 31415620.into()),
|
(3141562.into(), 31415620.into()),
|
||||||
vec![],
|
vec![],
|
||||||
false,
|
false,
|
||||||
None,
|
|
||||||
).unwrap();
|
).unwrap();
|
||||||
let b1 = b1.close_and_lock().unwrap();
|
let b1 = b1.close_and_lock().unwrap();
|
||||||
|
|
||||||
@ -2264,7 +2254,6 @@ mod tests {
|
|||||||
(3141562.into(), 31415620.into()),
|
(3141562.into(), 31415620.into()),
|
||||||
vec![],
|
vec![],
|
||||||
false,
|
false,
|
||||||
None,
|
|
||||||
).unwrap();
|
).unwrap();
|
||||||
let addr1_balance = b2.state.balance(&addr1).unwrap();
|
let addr1_balance = b2.state.balance(&addr1).unwrap();
|
||||||
|
|
||||||
|
@ -268,7 +268,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||||
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, None).unwrap();
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let b = b.close_and_lock().unwrap();
|
let b = b.close_and_lock().unwrap();
|
||||||
if let Seal::Regular(seal) = engine.generate_seal(&b, &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());
|
||||||
|
@ -368,13 +368,16 @@ impl Engine for Clique {
|
|||||||
&self,
|
&self,
|
||||||
_block: &mut ExecutedBlock,
|
_block: &mut ExecutedBlock,
|
||||||
_epoch_begin: bool,
|
_epoch_begin: bool,
|
||||||
_ancestry: &mut dyn Iterator<Item=ExtendedHeader>,
|
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clique has no block reward.
|
// Clique has no block reward.
|
||||||
fn on_close_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> {
|
fn on_close_block(
|
||||||
|
&self,
|
||||||
|
_block: &mut ExecutedBlock,
|
||||||
|
_parent_header: &Header
|
||||||
|
) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ impl CliqueTester {
|
|||||||
|
|
||||||
/// Get signers after a certain state
|
/// Get signers after a certain state
|
||||||
// This is generally used to fetch the state after a test has been executed and checked against
|
// This is generally used to fetch the state after a test has been executed and checked against
|
||||||
// the intial list of signers provided in the test
|
// the initial list of signers provided in the test
|
||||||
pub fn clique_signers(&self, hash: &H256) -> impl Iterator<Item = Address> {
|
pub fn clique_signers(&self, hash: &H256) -> impl Iterator<Item = Address> {
|
||||||
self.get_state_at_block(hash).signers().clone().into_iter()
|
self.get_state_at_block(hash).signers().clone().into_iter()
|
||||||
}
|
}
|
||||||
@ -171,7 +171,6 @@ impl CliqueTester {
|
|||||||
(3141562.into(), 31415620.into()),
|
(3141562.into(), 31415620.into()),
|
||||||
extra_data,
|
extra_data,
|
||||||
false,
|
false,
|
||||||
None,
|
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -110,7 +110,7 @@ mod tests {
|
|||||||
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
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, None).unwrap();
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let b = b.close_and_lock().unwrap();
|
let b = b.close_and_lock().unwrap();
|
||||||
if let Seal::Regular(seal) = engine.generate_seal(&b, &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());
|
||||||
|
@ -304,13 +304,16 @@ pub trait Engine: Sync + Send {
|
|||||||
&self,
|
&self,
|
||||||
_block: &mut ExecutedBlock,
|
_block: &mut ExecutedBlock,
|
||||||
_epoch_begin: bool,
|
_epoch_begin: bool,
|
||||||
_ancestry: &mut dyn Iterator<Item = ExtendedHeader>,
|
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Block transformation functions, after the transactions.
|
/// Block transformation functions, after the transactions.
|
||||||
fn on_close_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> {
|
fn on_close_block(
|
||||||
|
&self,
|
||||||
|
_block: &mut ExecutedBlock,
|
||||||
|
_parent_header: &Header,
|
||||||
|
) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,11 @@ impl Engine for NullEngine {
|
|||||||
|
|
||||||
fn machine(&self) -> &Machine { &self.machine }
|
fn machine(&self) -> &Machine { &self.machine }
|
||||||
|
|
||||||
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
|
fn on_close_block(
|
||||||
|
&self,
|
||||||
|
block: &mut ExecutedBlock,
|
||||||
|
_parent_header: &Header
|
||||||
|
) -> Result<(), Error> {
|
||||||
use std::ops::Shr;
|
use std::ops::Shr;
|
||||||
|
|
||||||
let author = *block.header.author();
|
let author = *block.header.author();
|
||||||
|
@ -239,7 +239,7 @@ impl Engine for Arc<Ethash> {
|
|||||||
|
|
||||||
/// Apply the block reward on finalisation of the block.
|
/// Apply the block reward on finalisation of the block.
|
||||||
/// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current).
|
/// 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) -> Result<(), Error> {
|
fn on_close_block(&self, block: &mut ExecutedBlock, _parent_header: &Header) -> Result<(), Error> {
|
||||||
use std::ops::Shr;
|
use std::ops::Shr;
|
||||||
|
|
||||||
let author = *block.header.author();
|
let author = *block.header.author();
|
||||||
@ -540,7 +540,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||||
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, None).unwrap();
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).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());
|
||||||
}
|
}
|
||||||
@ -589,7 +589,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap();
|
let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let mut uncle = Header::new();
|
let mut uncle = Header::new();
|
||||||
let uncle_author = Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap();
|
let uncle_author = Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap();
|
||||||
uncle.set_author(uncle_author);
|
uncle.set_author(uncle_author);
|
||||||
@ -607,7 +607,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||||
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, None).unwrap();
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let b = b.close().unwrap();
|
let b = b.close().unwrap();
|
||||||
|
|
||||||
let ubi_contract = Address::from_str("00efdd5883ec628983e9063c7d969fe268bbf310").unwrap();
|
let ubi_contract = Address::from_str("00efdd5883ec628983e9063c7d969fe268bbf310").unwrap();
|
||||||
|
@ -548,7 +548,7 @@ impl Miner {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Invalid nonce error can happen only if previous transaction is skipped because of gas limit.
|
// Invalid nonce error can happen only if previous transaction is skipped because of gas limit.
|
||||||
// If there is errornous state of transaction queue it will be fixed when next block is imported.
|
// If there is erroneous state of transaction queue it will be fixed when next block is imported.
|
||||||
Err(Error::Execution(ExecutionError::InvalidNonce { expected, got })) => {
|
Err(Error::Execution(ExecutionError::InvalidNonce { expected, got })) => {
|
||||||
debug!(target: "miner", "Skipping adding transaction to block because of invalid nonce: {:?} (expected: {:?}, got: {:?})", hash, expected, got);
|
debug!(target: "miner", "Skipping adding transaction to block because of invalid nonce: {:?} (expected: {:?}, got: {:?})", hash, expected, got);
|
||||||
},
|
},
|
||||||
|
@ -155,7 +155,6 @@ pub fn generate_dummy_client_with_spec_and_data<F>(test_spec: F, block_number: u
|
|||||||
(3141562.into(), 31415620.into()),
|
(3141562.into(), 31415620.into()),
|
||||||
vec![],
|
vec![],
|
||||||
false,
|
false,
|
||||||
None,
|
|
||||||
).unwrap();
|
).unwrap();
|
||||||
rolling_timestamp += 10;
|
rolling_timestamp += 10;
|
||||||
b.set_timestamp(rolling_timestamp);
|
b.set_timestamp(rolling_timestamp);
|
||||||
|
@ -87,7 +87,6 @@ fn can_trace_block_and_uncle_reward() {
|
|||||||
(3141562.into(), 31415620.into()),
|
(3141562.into(), 31415620.into()),
|
||||||
vec![],
|
vec![],
|
||||||
false,
|
false,
|
||||||
None,
|
|
||||||
).unwrap();
|
).unwrap();
|
||||||
rolling_timestamp += 10;
|
rolling_timestamp += 10;
|
||||||
root_block.set_timestamp(rolling_timestamp);
|
root_block.set_timestamp(rolling_timestamp);
|
||||||
@ -116,7 +115,6 @@ fn can_trace_block_and_uncle_reward() {
|
|||||||
(3141562.into(), 31415620.into()),
|
(3141562.into(), 31415620.into()),
|
||||||
vec![],
|
vec![],
|
||||||
false,
|
false,
|
||||||
None,
|
|
||||||
).unwrap();
|
).unwrap();
|
||||||
rolling_timestamp += 10;
|
rolling_timestamp += 10;
|
||||||
parent_block.set_timestamp(rolling_timestamp);
|
parent_block.set_timestamp(rolling_timestamp);
|
||||||
@ -144,7 +142,6 @@ fn can_trace_block_and_uncle_reward() {
|
|||||||
(3141562.into(), 31415620.into()),
|
(3141562.into(), 31415620.into()),
|
||||||
vec![],
|
vec![],
|
||||||
false,
|
false,
|
||||||
None,
|
|
||||||
).unwrap();
|
).unwrap();
|
||||||
rolling_timestamp += 10;
|
rolling_timestamp += 10;
|
||||||
block.set_timestamp(rolling_timestamp);
|
block.set_timestamp(rolling_timestamp);
|
||||||
|
Loading…
Reference in New Issue
Block a user