diff --git a/bins/revme/src/cmd/statetest/models/mod.rs b/bins/revme/src/cmd/statetest/models/mod.rs
index 0a38b514b2..6bb58e5bd8 100644
--- a/bins/revme/src/cmd/statetest/models/mod.rs
+++ b/bins/revme/src/cmd/statetest/models/mod.rs
@@ -6,7 +6,9 @@ use deserializer::*;
pub use eip7702::TxEip7702;
pub use spec::SpecName;
-use revm::primitives::{AccessList, Address, AuthorizationList, Bytes, HashMap, B256, U256};
+use revm::primitives::{
+ alloy_primitives::Parity, AccessList, Address, AuthorizationList, Bytes, HashMap, B256, U256,
+};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
@@ -60,6 +62,11 @@ impl Test {
if txbytes.first() == Some(&0x04) {
let mut txbytes = &txbytes[1..];
let tx = TxEip7702::decode(&mut txbytes)?;
+ if let Parity::Eip155(parity) = tx.signature.v() {
+ if parity < u8::MAX as u64 {
+ return Err(alloy_rlp::Error::Custom("Invalid parity value"));
+ }
+ }
return Ok(Some(
AuthorizationList::Signed(tx.authorization_list).into_recovered(),
));
diff --git a/crates/primitives/src/eip7702.rs b/crates/primitives/src/eip7702.rs
index f63600b904..c75a0b977d 100644
--- a/crates/primitives/src/eip7702.rs
+++ b/crates/primitives/src/eip7702.rs
@@ -11,7 +11,7 @@ pub use bytecode::{
};
// Base cost of updating authorized account.
-pub const PER_AUTH_BASE_COST: u64 = 2500;
+pub const PER_AUTH_BASE_COST: u64 = 12500;
/// Cost of creating authorized account that was previously empty.
pub const PER_EMPTY_ACCOUNT_COST: u64 = 25000;
@@ -20,7 +20,7 @@ pub const PER_EMPTY_ACCOUNT_COST: u64 = 25000;
/// to EIP-2 should have an S value less than or equal to this.
///
/// `57896044618658097711785492504343953926418782139537452191302581570759080747168`
-const SECP256K1N_HALF: U256 = U256::from_be_bytes([
+pub const SECP256K1N_HALF: U256 = U256::from_be_bytes([
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x5D, 0x57, 0x6E, 0x73, 0x57, 0xA4, 0x50, 0x1D, 0xDF, 0xE9, 0x2F, 0x46, 0x68, 0x1B, 0x20, 0xA0,
]);
diff --git a/crates/primitives/src/eip7702/authorization_list.rs b/crates/primitives/src/eip7702/authorization_list.rs
index 4b1a872f7b..f4f7680c5e 100644
--- a/crates/primitives/src/eip7702/authorization_list.rs
+++ b/crates/primitives/src/eip7702/authorization_list.rs
@@ -1,11 +1,12 @@
pub use alloy_eip7702::{Authorization, SignedAuthorization};
pub use alloy_primitives::{Parity, Signature};
-use super::SECP256K1N_HALF;
use crate::Address;
use core::{fmt, ops::Deref};
use std::{boxed::Box, vec::Vec};
+use super::SECP256K1N_HALF;
+
/// Authorization list for EIP-7702 transaction type.
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@@ -35,40 +36,6 @@ impl AuthorizationList {
}
}
- /// Returns true if the authorization list is valid.
- pub fn is_valid(&self, _chain_id: u64) -> Result<(), InvalidAuthorization> {
- let validate = |auth: &SignedAuthorization| -> Result<(), InvalidAuthorization> {
- // TODO Eip7702. Check chain_id
- // Pending: https://github.com/ethereum/EIPs/pull/8833/files
- // let auth_chain_id: u64 = auth.chain_id().try_into().unwrap_or(u64::MAX);
- // if auth_chain_id != 0 && auth_chain_id != chain_id {
- // return Err(InvalidAuthorization::InvalidChainId);
- // }
-
- // Check y_parity, Parity::Parity means that it was 0 or 1.
- if !matches!(auth.signature().v(), Parity::Parity(_)) {
- return Err(InvalidAuthorization::InvalidYParity);
- }
-
- // Check s-value
- if auth.signature().s() > SECP256K1N_HALF {
- return Err(InvalidAuthorization::Eip2InvalidSValue);
- }
-
- Ok(())
- };
-
- match self {
- Self::Signed(signed) => signed.iter().try_for_each(validate)?,
- Self::Recovered(recovered) => recovered
- .iter()
- .map(|recovered| &recovered.inner)
- .try_for_each(validate)?,
- };
-
- Ok(())
- }
-
/// Return empty authorization list.
pub fn empty() -> Self {
Self::Recovered(Vec::new())
@@ -114,7 +81,18 @@ impl RecoveredAuthorization {
/// Get the `authority` for the authorization.
///
/// If this is `None`, then the authority could not be recovered.
- pub const fn authority(&self) -> Option
{
+ pub fn authority(&self) -> Option {
+ let signature = self.inner.signature();
+
+ // Check s-value
+ if signature.s() > SECP256K1N_HALF {
+ return None;
+ }
+
+ // Check y_parity, Parity::Parity means that it was 0 or 1.
+ if !matches!(signature.v(), Parity::Parity(_)) {
+ return None;
+ }
self.authority
}
diff --git a/crates/primitives/src/env.rs b/crates/primitives/src/env.rs
index ed6bc1b141..e0d856df98 100644
--- a/crates/primitives/src/env.rs
+++ b/crates/primitives/src/env.rs
@@ -202,9 +202,6 @@ impl Env {
return Err(InvalidTransaction::EmptyAuthorizationList);
}
- // Check validity of authorization_list
- auth_list.is_valid(self.cfg.chain_id)?;
-
// Check if other fields are unset.
if self.tx.max_fee_per_blob_gas.is_some() || !self.tx.blob_hashes.is_empty() {
return Err(InvalidTransaction::AuthorizationListInvalidFields);
diff --git a/crates/revm/benches/bench.rs b/crates/revm/benches/bench.rs
index 59cc261c9f..a2f98cff98 100644
--- a/crates/revm/benches/bench.rs
+++ b/crates/revm/benches/bench.rs
@@ -82,7 +82,7 @@ fn transfer(c: &mut Criterion) {
}
fn bench_transact(g: &mut BenchmarkGroup<'_, WallTime>, evm: &mut Evm<'_, EXT, BenchmarkDB>) {
- let state = match evm.context.evm.db.0 {
+ let state = match evm.context.evm.db.bytecode {
Bytecode::LegacyRaw(_) => "raw",
Bytecode::LegacyAnalyzed(_) => "analysed",
Bytecode::Eof(_) => "eof",
@@ -96,7 +96,7 @@ fn bench_eval(g: &mut BenchmarkGroup<'_, WallTime>, evm: &mut Evm<'static, (), B
g.bench_function("eval", |b| {
let contract = Contract {
input: evm.context.evm.env.tx.data.clone(),
- bytecode: to_analysed(evm.context.evm.db.0.clone()),
+ bytecode: to_analysed(evm.context.evm.db.bytecode.clone()),
..Default::default()
};
let mut shared_memory = SharedMemory::new();
diff --git a/crates/revm/src/db/in_memory_db.rs b/crates/revm/src/db/in_memory_db.rs
index 5cc6987f55..c5b6593a41 100644
--- a/crates/revm/src/db/in_memory_db.rs
+++ b/crates/revm/src/db/in_memory_db.rs
@@ -360,12 +360,33 @@ impl AccountState {
///
/// Any other address will return an empty account.
#[derive(Debug, Default, Clone)]
-pub struct BenchmarkDB(pub Bytecode, B256);
+pub struct BenchmarkDB {
+ pub bytecode: Bytecode,
+ pub hash: B256,
+ pub target: Address,
+ pub caller: Address,
+}
impl BenchmarkDB {
+ /// Create a new benchmark database with the given bytecode.
pub fn new_bytecode(bytecode: Bytecode) -> Self {
let hash = bytecode.hash_slow();
- Self(bytecode, hash)
+ Self {
+ bytecode,
+ hash,
+ target: Address::ZERO,
+ caller: Address::with_last_byte(1),
+ }
+ }
+
+ /// Change the caller address for the benchmark.
+ pub fn with_caller(self, caller: Address) -> Self {
+ Self { caller, ..self }
+ }
+
+ /// Change the target address for the benchmark.
+ pub fn with_target(self, target: Address) -> Self {
+ Self { target, ..self }
}
}
@@ -373,15 +394,15 @@ impl Database for BenchmarkDB {
type Error = Infallible;
/// Get basic account information.
fn basic(&mut self, address: Address) -> Result