diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index c6c41c5f8..84c1df8fc 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -168,7 +168,10 @@ fn verify_external(header: &Header, validators: &ValidatorSet, step: &Step) -> R } else { let proposer_signature = header_signature(header)?; let correct_proposer = validators.get(header.parent_hash(), header_step); - if !verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())? { + let is_invalid_proposer = *header.author() != correct_proposer || + !verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())?; + + if is_invalid_proposer { trace!(target: "engine", "verify_block_unordered: bad proposer for step: {}", header_step); Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))? } else { diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 008a63424..75a4806b8 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -69,6 +69,10 @@ fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Err let sig = UntrustedRlp::new(&header.seal()[0]).as_val::()?; let signer = public_to_address(&recover(&sig.into(), &header.bare_hash())?); + if *header.author() != signer { + return Err(EngineError::NotAuthorized(*header.author()).into()) + } + match validators.contains(header.parent_hash(), &signer) { false => Err(BlockError::InvalidSeal.into()), true => Ok(()) diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index e0000f4cc..7d3963eac 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -60,7 +60,7 @@ pub const DEFAULT_BLOCKHASH_CONTRACT: &'static str = "73ffffffffffffffffffffffff /// Voting errors. #[derive(Debug)] pub enum EngineError { - /// Signature does not belong to an authority. + /// Signature or author field does not belong to an authority. NotAuthorized(Address), /// The same author issued different votes at the same step. DoubleVote(Address),