diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 2ee5fa0681..e8a38fd233 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -69,11 +69,12 @@ pub use revm_primitives::JumpMap; pub use serde_helper::JsonU256; pub use storage::StorageEntry; pub use transaction::{ - util::secp256k1::sign_message, AccessList, AccessListItem, AccessListWithGasUsed, - FromRecoveredTransaction, IntoRecoveredTransaction, InvalidTransactionError, Signature, - Transaction, TransactionKind, TransactionMeta, TransactionSigned, TransactionSignedEcRecovered, - TransactionSignedNoHash, TxEip1559, TxEip2930, TxLegacy, TxType, EIP1559_TX_TYPE_ID, - EIP2930_TX_TYPE_ID, LEGACY_TX_TYPE_ID, + util::secp256k1::{recover_signer, sign_message}, + AccessList, AccessListItem, AccessListWithGasUsed, FromRecoveredTransaction, + IntoRecoveredTransaction, InvalidTransactionError, Signature, Transaction, TransactionKind, + TransactionMeta, TransactionSigned, TransactionSignedEcRecovered, TransactionSignedNoHash, + TxEip1559, TxEip2930, TxLegacy, TxType, EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, + LEGACY_TX_TYPE_ID, }; pub use withdrawal::Withdrawal; diff --git a/crates/primitives/src/transaction/signature.rs b/crates/primitives/src/transaction/signature.rs index 04ab978a81..aef723cd84 100644 --- a/crates/primitives/src/transaction/signature.rs +++ b/crates/primitives/src/transaction/signature.rs @@ -123,7 +123,7 @@ impl Signature { // NOTE: we are removing error from underlying crypto library as it will restrain primitive // errors and we care only if recovery is passing or not. - secp256k1::recover(&sig, hash.as_fixed_bytes()).ok() + secp256k1::recover_signer(&sig, hash.as_fixed_bytes()).ok() } /// Turn this signature into its byte diff --git a/crates/primitives/src/transaction/util.rs b/crates/primitives/src/transaction/util.rs index f2d471c304..5a221bfe12 100644 --- a/crates/primitives/src/transaction/util.rs +++ b/crates/primitives/src/transaction/util.rs @@ -13,7 +13,7 @@ pub(crate) mod secp256k1 { pub(crate) use ::secp256k1::Error; /// secp256k1 signer recovery - pub(crate) fn recover(sig: &[u8; 65], msg: &[u8; 32]) -> Result
{ + pub fn recover_signer(sig: &[u8; 65], msg: &[u8; 32]) -> Result { let sig = RecoverableSignature::from_compact(&sig[0..64], RecoveryId::from_i32(sig[64] as i32)?)?; @@ -49,6 +49,6 @@ mod tests { let hash = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad"); let out: Address = hex!("c08b5542d177ac6686946920409741463a15dddb").into(); - assert_eq!(secp256k1::recover(&sig, &hash), Ok(out)); + assert_eq!(secp256k1::recover_signer(&sig, &hash), Ok(out)); } } diff --git a/crates/revm/revm-primitives/src/env.rs b/crates/revm/revm-primitives/src/env.rs index 1f81ec4c78..588586acf3 100644 --- a/crates/revm/revm-primitives/src/env.rs +++ b/crates/revm/revm-primitives/src/env.rs @@ -1,7 +1,7 @@ use crate::config::revm_spec; use reth_primitives::{ - Address, ChainSpec, Head, Header, Transaction, TransactionKind, TransactionSignedEcRecovered, - TxEip1559, TxEip2930, TxLegacy, U256, + recover_signer, Address, Bytes, Chain, ChainSpec, Head, Header, Transaction, TransactionKind, + TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxLegacy, U256, }; use revm::primitives::{AnalysisKind, BlockEnv, CfgEnv, SpecId, TransactTo, TxEnv}; @@ -15,7 +15,7 @@ pub fn fill_cfg_and_block_env( ) { fill_cfg_env(cfg, chain_spec, header, total_difficulty); let after_merge = cfg.spec_id >= SpecId::MERGE; - fill_block_env(block_env, header, after_merge); + fill_block_env(block_env, chain_spec, header, after_merge); } /// Fill [CfgEnv] fields according to the chain spec and given header @@ -42,9 +42,14 @@ pub fn fill_cfg_env( cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse; } /// Fill block environment from Block. -pub fn fill_block_env(block_env: &mut BlockEnv, header: &Header, after_merge: bool) { +pub fn fill_block_env( + block_env: &mut BlockEnv, + chain_spec: &ChainSpec, + header: &Header, + after_merge: bool, +) { block_env.number = U256::from(header.number); - block_env.coinbase = header.beneficiary; + block_env.coinbase = block_coinbase(chain_spec, header, after_merge); block_env.timestamp = U256::from(header.timestamp); if after_merge { block_env.prevrandao = Some(header.mix_hash); @@ -57,6 +62,31 @@ pub fn fill_block_env(block_env: &mut BlockEnv, header: &Header, after_merge: bo block_env.gas_limit = U256::from(header.gas_limit); } +/// Return the coinbase address for the given header and chain spec. +pub fn block_coinbase(chain_spec: &ChainSpec, header: &Header, after_merge: bool) -> Address { + if chain_spec.chain == Chain::goerli() && !after_merge { + recover_header_signer(header).expect("failed to recover signer") + } else { + header.beneficiary + } +} + +/// Recover the account from signed header per clique consensus rules. +pub fn recover_header_signer(header: &Header) -> Option { + let extra_data_len = header.extra_data.len(); + // Fixed number of extra-data suffix bytes reserved for signer signature. + // 65 bytes fixed as signatures are based on the standard secp256k1 curve. + // Filled with zeros on genesis block. + let signature_start_byte = extra_data_len - 65; + let signature: [u8; 65] = header.extra_data[signature_start_byte..].try_into().ok()?; + let seal_hash = { + let mut header_to_seal = header.clone(); + header_to_seal.extra_data = Bytes::from(&header.extra_data[..signature_start_byte]); + header_to_seal.hash_slow() + }; + recover_signer(&signature, seal_hash.as_fixed_bytes()).ok() +} + /// Returns a new [TxEnv] filled with the transaction's data. pub fn tx_env_with_recovered(transaction: &TransactionSignedEcRecovered) -> TxEnv { let mut tx_env = TxEnv::default(); diff --git a/crates/storage/provider/src/providers/database.rs b/crates/storage/provider/src/providers/database.rs index e5e0797324..04ff715060 100644 --- a/crates/storage/provider/src/providers/database.rs +++ b/crates/storage/provider/src/providers/database.rs @@ -422,7 +422,7 @@ impl