Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
[stable] Engine backports (#4807)
Browse files Browse the repository at this point in the history
* calibrate before rejection

* change flag name

* add eip155

* fix build

* make network_id default
  • Loading branch information
keorn authored and gavofyork committed Mar 8, 2017
1 parent d0b6f26 commit 7f5795d
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
27 changes: 23 additions & 4 deletions ethcore/src/engines/authority_round.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ pub struct AuthorityRound {
account_provider: Mutex<Arc<AccountProvider>>,
password: RwLock<Option<String>>,
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> {
Expand Down Expand Up @@ -126,6 +128,7 @@ impl AuthorityRound {
account_provider: Mutex::new(Arc::new(AccountProvider::transient_provider())),
password: RwLock::new(None),
validators: new_validator_set(our_params.validators),
calibrate_step: our_params.start_step.is_none(),
});
// Do not initialize timeouts for tests.
if should_timeout {
Expand All @@ -135,6 +138,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);
Expand All @@ -152,6 +161,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 {
Expand Down Expand Up @@ -286,7 +305,10 @@ 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");
Err(BlockError::InvalidSeal)?
} else {
let proposer_signature = header_signature(header)?;
let ok_sig = verify_address(&self.step_proposer(header_step), &proposer_signature, &header.bare_hash())?;
if ok_sig {
Expand All @@ -295,9 +317,6 @@ impl Engine for AuthorityRound {
trace!(target: "poa", "verify_block_unordered: invalid seal signature");
Err(BlockError::InvalidSeal)?
}
} else {
trace!(target: "poa", "verify_block_unordered: block from the future");
Err(BlockError::InvalidSeal)?
}
}

Expand Down
4 changes: 3 additions & 1 deletion ethcore/src/engines/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ pub trait Engine : Sync + Send {
fn verify_transaction(&self, _t: &SignedTransaction, _header: &Header) -> Result<(), Error> { Ok(()) }

/// 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
Expand Down

0 comments on commit 7f5795d

Please sign in to comment.