Include the seal when populating the header for a new block (#11475)
* debug signer * Don't panic if empty_steps_transition already happened Before this the `header_empty_steps_raw` would panic if the chain has already progressed beyond the block number set in `emptyStepsTransition`. As this is a user accessible configuration option I don't think we should panic. * Cleanup some code in Aura Nothing really interesting here, renames or removes some methods. Adds some docs and extends a test a bit to clarify the behaviour of the code. * Include the seal when populating the header for a new block (fixes #11445) * cleanup * cleanup2 * Review grumbles * Update ethcore/engines/authority-round/src/lib.rs Co-Authored-By: André Silva <andre.beat@gmail.com> * Update ethcore/engines/authority-round/src/lib.rs Co-Authored-By: André Silva <andre.beat@gmail.com> * Update ethcore/src/block.rs Co-Authored-By: André Silva <andre.beat@gmail.com> Co-authored-by: André Silva <andre.beat@gmail.com>
This commit is contained in:
parent
ea9322f9c1
commit
856a075588
@ -720,17 +720,22 @@ fn header_signature(header: &Header, empty_steps_transition: u64) -> Result<Sign
|
|||||||
.as_val::<H520>().map(Into::into)
|
.as_val::<H520>().map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
// extracts the raw empty steps vec from the header seal. should only be called when there are 3 fields in the seal
|
// Extracts the RLP bytes of the empty steps from the header seal. Returns data only when there are
|
||||||
// (i.e. header.number() >= self.empty_steps_transition)
|
// 3 fields in the seal. (i.e. header.number() >= self.empty_steps_transition).
|
||||||
fn header_empty_steps_raw(header: &Header) -> &[u8] {
|
fn header_empty_steps_raw(header: &Header) -> Option<&[u8]> {
|
||||||
header.seal().get(2).expect("was checked with verify_block_basic; has 3 fields; qed")
|
header.seal().get(2).map(Vec::as_slice)
|
||||||
}
|
}
|
||||||
|
|
||||||
// extracts the empty steps from the header seal. should only be called when there are 3 fields in the seal
|
// Extracts the empty steps from the header seal. Returns data only when there are 3 fields in the seal
|
||||||
// (i.e. header.number() >= self.empty_steps_transition).
|
// (i.e. header.number() >= self.empty_steps_transition).
|
||||||
fn header_empty_steps(header: &Header) -> Result<Vec<EmptyStep>, ::rlp::DecoderError> {
|
fn header_empty_steps(header: &Header) -> Result<Vec<EmptyStep>, ::rlp::DecoderError> {
|
||||||
let empty_steps = Rlp::new(header_empty_steps_raw(header)).as_list::<SealedEmptyStep>()?;
|
header_empty_steps_raw(header).map_or(Ok(vec![]), |raw| {
|
||||||
Ok(empty_steps.into_iter().map(|s| EmptyStep::from_sealed(s, header.parent_hash())).collect())
|
let empty_steps = Rlp::new(raw).as_list::<SealedEmptyStep>()?;
|
||||||
|
Ok(empty_steps
|
||||||
|
.into_iter()
|
||||||
|
.map(|s| EmptyStep::from_sealed(s, header.parent_hash()))
|
||||||
|
.collect())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// gets the signers of empty step messages for the given header, does not include repeated signers
|
// gets the signers of empty step messages for the given header, does not include repeated signers
|
||||||
@ -788,7 +793,7 @@ fn verify_external(header: &Header, validators: &dyn ValidatorSet, empty_steps_t
|
|||||||
let correct_proposer = validators.get(header.parent_hash(), header_step as usize);
|
let correct_proposer = validators.get(header.parent_hash(), header_step as usize);
|
||||||
let is_invalid_proposer = *header.author() != correct_proposer || {
|
let is_invalid_proposer = *header.author() != correct_proposer || {
|
||||||
let empty_steps_rlp = if header.number() >= empty_steps_transition {
|
let empty_steps_rlp = if header.number() >= empty_steps_transition {
|
||||||
Some(header_empty_steps_raw(header))
|
header_empty_steps_raw(header)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@ -970,11 +975,15 @@ impl AuthorityRound {
|
|||||||
/// Drops all `EmptySteps` less than or equal to the passed `step`, irregardless of the parent hash.
|
/// Drops all `EmptySteps` less than or equal to the passed `step`, irregardless of the parent hash.
|
||||||
fn clear_empty_steps(&self, step: u64) {
|
fn clear_empty_steps(&self, step: u64) {
|
||||||
let mut empty_steps = self.empty_steps.lock();
|
let mut empty_steps = self.empty_steps.lock();
|
||||||
*empty_steps = empty_steps.split_off(&EmptyStep {
|
if empty_steps.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let next_empty_steps = empty_steps.split_off(&EmptyStep {
|
||||||
step: step + 1,
|
step: step + 1,
|
||||||
parent_hash: Default::default(),
|
parent_hash: Default::default(),
|
||||||
signature: Default::default(),
|
signature: Default::default(),
|
||||||
});
|
});
|
||||||
|
*empty_steps = next_empty_steps
|
||||||
}
|
}
|
||||||
|
|
||||||
fn store_empty_step(&self, empty_step: EmptyStep) {
|
fn store_empty_step(&self, empty_step: EmptyStep) {
|
||||||
@ -3013,7 +3022,8 @@ mod tests {
|
|||||||
let params = AuthorityRoundParams::from(deserialized.params);
|
let params = AuthorityRoundParams::from(deserialized.params);
|
||||||
for ((block_num1, address1), (block_num2, address2)) in
|
for ((block_num1, address1), (block_num2, address2)) in
|
||||||
params.block_reward_contract_transitions.iter().zip(
|
params.block_reward_contract_transitions.iter().zip(
|
||||||
[(0u64, BlockRewardContract::new_from_address(Address::from_str("2000000000000000000000000000000000000002").unwrap())),
|
[
|
||||||
|
(0u64, BlockRewardContract::new_from_address(Address::from_str("2000000000000000000000000000000000000002").unwrap())),
|
||||||
(7u64, BlockRewardContract::new_from_address(Address::from_str("3000000000000000000000000000000000000003").unwrap())),
|
(7u64, BlockRewardContract::new_from_address(Address::from_str("3000000000000000000000000000000000000003").unwrap())),
|
||||||
(42u64, BlockRewardContract::new_from_address(Address::from_str("4000000000000000000000000000000000000004").unwrap())),
|
(42u64, BlockRewardContract::new_from_address(Address::from_str("4000000000000000000000000000000000000004").unwrap())),
|
||||||
].iter())
|
].iter())
|
||||||
|
@ -222,6 +222,10 @@ impl<'x> OpenBlock<'x> {
|
|||||||
self.block.header.set_timestamp(header.timestamp());
|
self.block.header.set_timestamp(header.timestamp());
|
||||||
self.block.header.set_uncles_hash(*header.uncles_hash());
|
self.block.header.set_uncles_hash(*header.uncles_hash());
|
||||||
self.block.header.set_transactions_root(*header.transactions_root());
|
self.block.header.set_transactions_root(*header.transactions_root());
|
||||||
|
// For Aura-based chains, the seal may contain EmptySteps which are used to bestow rewards;
|
||||||
|
// such rewards affect the state and the state root (see
|
||||||
|
// https://github.com/paritytech/parity-ethereum/pull/11475).
|
||||||
|
self.block.header.set_seal(header.seal().to_vec());
|
||||||
// TODO: that's horrible. set only for backwards compatibility
|
// TODO: that's horrible. set only for backwards compatibility
|
||||||
if header.extra_data().len() > self.engine.maximum_extra_data_size() {
|
if header.extra_data().len() > self.engine.maximum_extra_data_size() {
|
||||||
warn!("Couldn't set extradata. Ignoring.");
|
warn!("Couldn't set extradata. Ignoring.");
|
||||||
@ -554,7 +558,7 @@ mod tests {
|
|||||||
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. Seal the block aferwards
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block afterwards
|
||||||
fn enact_and_seal(
|
fn enact_and_seal(
|
||||||
block_bytes: Vec<u8>,
|
block_bytes: Vec<u8>,
|
||||||
engine: &dyn Engine,
|
engine: &dyn Engine,
|
||||||
|
@ -492,6 +492,7 @@ fn execute_impl<Cr, Rr>(
|
|||||||
let fetch = fetch::Client::new(FETCH_FULL_NUM_DNS_THREADS).map_err(|e| format!("Error starting fetch client: {:?}", e))?;
|
let fetch = fetch::Client::new(FETCH_FULL_NUM_DNS_THREADS).map_err(|e| format!("Error starting fetch client: {:?}", e))?;
|
||||||
|
|
||||||
let txpool_size = cmd.miner_options.pool_limits.max_count;
|
let txpool_size = cmd.miner_options.pool_limits.max_count;
|
||||||
|
|
||||||
// create miner
|
// create miner
|
||||||
let miner = Arc::new(Miner::new(
|
let miner = Arc::new(Miner::new(
|
||||||
cmd.miner_options,
|
cmd.miner_options,
|
||||||
@ -502,6 +503,7 @@ fn execute_impl<Cr, Rr>(
|
|||||||
account_utils::miner_local_accounts(account_provider.clone()),
|
account_utils::miner_local_accounts(account_provider.clone()),
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
miner.set_author(miner::Author::External(cmd.miner_extras.author));
|
miner.set_author(miner::Author::External(cmd.miner_extras.author));
|
||||||
miner.set_gas_range_target(cmd.miner_extras.gas_range_target);
|
miner.set_gas_range_target(cmd.miner_extras.gas_range_target);
|
||||||
miner.set_extra_data(cmd.miner_extras.extra_data);
|
miner.set_extra_data(cmd.miner_extras.extra_data);
|
||||||
|
Loading…
Reference in New Issue
Block a user