diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index 78a82ccca..01ea9956a 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -24,7 +24,8 @@ "0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de" ] }, - "validateScoreTransition": 1000000 + "validateScoreTransition": 1000000, + "eip155Transition": 1000000 } } }, diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index aeef176a9..e6cbdb531 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -27,12 +27,13 @@ use block::*; use spec::CommonParams; use engines::{Engine, Seal, EngineError}; use header::Header; -use error::{Error, BlockError}; +use error::{Error, TransactionError, BlockError}; use evm::Schedule; use ethjson; use io::{IoContext, IoHandler, TimerToken, IoService}; use env_info::EnvInfo; use builtin::Builtin; +use transaction::UnverifiedTransaction; use client::{Client, EngineClient}; use state::CleanupMode; use super::signer::EngineSigner; @@ -55,6 +56,8 @@ pub struct AuthorityRoundParams { pub validators: ethjson::spec::ValidatorSet, /// Chain score validation transition block. pub validate_score_transition: u64, + /// Number of first block where EIP-155 rules are validated. + pub eip155_transition: u64, } impl From for AuthorityRoundParams { @@ -67,6 +70,7 @@ impl From for AuthorityRoundParams { registrar: p.registrar.map_or_else(Address::new, Into::into), start_step: p.start_step.map(Into::into), validate_score_transition: p.validate_score_transition.map_or(0, Into::into), + eip155_transition: p.eip155_transition.map_or(0, Into::into), } } } @@ -89,6 +93,7 @@ pub struct AuthorityRound { /// Is this Engine just for testing (prevents step calibration). calibrate_step: bool, validate_score_transition: u64, + eip155_transition: u64, } fn header_step(header: &Header) -> Result { @@ -130,6 +135,7 @@ impl AuthorityRound { validators: new_validator_set(our_params.validators), calibrate_step: our_params.start_step.is_none(), validate_score_transition: our_params.validate_score_transition, + eip155_transition: our_params.eip155_transition, }); // Do not initialize timeouts for tests. if should_timeout { @@ -352,6 +358,18 @@ impl Engine for AuthorityRound { Ok(()) } + fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> { + t.check_low_s()?; + + if let Some(n) = t.network_id() { + if header.number() >= self.eip155_transition && n != self.params().chain_id { + return Err(TransactionError::InvalidNetworkId.into()); + } + } + + Ok(()) + } + fn register_client(&self, client: Weak) { *self.client.write() = Some(client.clone()); self.validators.register_contract(client); diff --git a/json/src/spec/authority_round.rs b/json/src/spec/authority_round.rs index 1c01d81fe..b4c009051 100644 --- a/json/src/spec/authority_round.rs +++ b/json/src/spec/authority_round.rs @@ -43,6 +43,9 @@ pub struct AuthorityRoundParams { /// Block at which score validation should start. #[serde(rename="validateScoreTransition")] pub validate_score_transition: Option, + /// See main AuthorityRoundParams docs. + #[serde(rename="eip155Transition")] + pub eip155_transition: Option, } /// Authority engine deserialization. @@ -67,7 +70,8 @@ mod tests { "list" : ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] }, "blockReward": "0x50", - "startStep" : 24 + "startStep" : 24, + "eip155Transition": "0x42" } }"#;