[beta] Engine backports (#4806)

* calibrate before rejection

* change flag name

* add eip155

* make network_id default
This commit is contained in:
keorn 2017-03-08 15:26:26 +01:00 committed by Arkadiy Paronyan
parent b643f4011d
commit 2a36a89c36
2 changed files with 27 additions and 6 deletions

View File

@ -83,6 +83,8 @@ pub struct AuthorityRound {
client: RwLock<Option<Weak<EngineClient>>>,
signer: EngineSigner,
validators: Box<ValidatorSet + Send + Sync>,
/// Is this Engine just for testing (prevents step calibration).
calibrate_step: bool,
}
fn header_step(header: &Header) -> Result<usize, ::rlp::DecoderError> {
@ -122,6 +124,7 @@ impl AuthorityRound {
client: RwLock::new(None),
signer: Default::default(),
validators: new_validator_set(our_params.validators),
calibrate_step: our_params.start_step.is_none(),
});
// Do not initialize timeouts for tests.
if should_timeout {
@ -131,6 +134,12 @@ impl AuthorityRound {
Ok(engine)
}
fn calibrate_step(&self) {
if self.calibrate_step {
self.step.store((unix_now().as_secs() / self.step_duration.as_secs()) as usize, AtomicOrdering::SeqCst);
}
}
fn remaining_step_duration(&self) -> Duration {
let now = unix_now();
let step_end = self.step_duration * (self.step.load(AtomicOrdering::SeqCst) as u32 + 1);
@ -148,6 +157,16 @@ impl AuthorityRound {
fn is_step_proposer(&self, step: usize, address: &Address) -> bool {
self.step_proposer(step) == *address
}
fn is_future_step(&self, step: usize) -> bool {
if step > self.step.load(AtomicOrdering::SeqCst) + 1 {
// Make absolutely sure that the step is correct.
self.calibrate_step();
step > self.step.load(AtomicOrdering::SeqCst) + 1
} else {
false
}
}
}
fn unix_now() -> Duration {
@ -285,7 +304,11 @@ impl Engine for AuthorityRound {
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
let header_step = header_step(header)?;
// Give one step slack if step is lagging, double vote is still not possible.
if header_step <= self.step.load(AtomicOrdering::SeqCst) + 1 {
if self.is_future_step(header_step) {
trace!(target: "engine", "verify_block_unordered: block from the future");
self.validators.report_benign(header.author());
Err(BlockError::InvalidSeal)?
} else {
let proposer_signature = header_signature(header)?;
let correct_proposer = self.step_proposer(header_step);
if verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())? {
@ -294,10 +317,6 @@ impl Engine for AuthorityRound {
trace!(target: "engine", "verify_block_unordered: bad proposer for step: {}", header_step);
Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))?
}
} else {
trace!(target: "engine", "verify_block_unordered: block from the future");
self.validators.report_benign(header.author());
Err(BlockError::InvalidSeal)?
}
}

View File

@ -166,7 +166,9 @@ pub trait Engine : Sync + Send {
}
/// The network ID that transactions should be signed with.
fn signing_network_id(&self, _env_info: &EnvInfo) -> Option<u64> { None }
fn signing_network_id(&self, _env_info: &EnvInfo) -> Option<u64> {
Some(self.params().chain_id)
}
/// Verify the seal of a block. This is an auxilliary method that actually just calls other `verify_` methods
/// to get the job done. By default it must pass `verify_basic` and `verify_block_unordered`. If more or fewer