fix(evm): goerli coinbase (#2377)

This commit is contained in:
Roman Krasiuk
2023-04-25 13:32:51 +03:00
committed by GitHub
parent dc8308f820
commit eebcb03fea
5 changed files with 45 additions and 14 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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<Address, Error> {
pub fn recover_signer(sig: &[u8; 65], msg: &[u8; 32]) -> Result<Address, Error> {
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));
}
}

View File

@@ -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<Address> {
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();

View File

@@ -422,7 +422,7 @@ impl<DB: Database> EvmEnvProvider for ShareableDatabase<DB> {
},
);
let after_merge = spec_id >= SpecId::MERGE;
fill_block_env(block_env, header, after_merge);
fill_block_env(block_env, &self.chain_spec, header, after_merge);
Ok(())
}