Skip to content

Commit 3a4acd4

Browse files
authored
feat: Introduce Auth and AccessList traits (#2079)
* feat: Introduce Auth and AccessList traits * add recovery to context interface
1 parent a82801b commit 3a4acd4

File tree

16 files changed

+134
-189
lines changed

16 files changed

+134
-189
lines changed

Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/context/interface/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ primitives.workspace = true
2727
database-interface.workspace = true
2828
state.workspace = true
2929
specification.workspace = true
30+
alloy-eip7702 = { workspace = true, features = ["k256"] }
31+
alloy-eip2930.workspace = true
3032

3133
# mics
3234
auto_impl.workspace = true
@@ -45,4 +47,3 @@ default = ["std"]
4547
std = ["serde?/std"]
4648
serde = ["dep:serde", "primitives/serde", "specification/serde", "state/serde"]
4749
serde-json = ["serde"]
48-

crates/context/interface/src/transaction.rs

+14-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
mod alloy_types;
2+
pub mod eip2930;
3+
pub mod eip7702;
14
pub mod transaction_type;
25

6+
pub use eip2930::AccessListTrait;
7+
pub use eip7702::AuthorizationTrait;
38
use specification::eip4844::GAS_PER_BLOB;
49
pub use transaction_type::TransactionType;
510

@@ -11,9 +16,6 @@ use primitives::{Address, Bytes, TxKind, B256, U256};
1116
/// Transaction validity error types.
1217
pub trait TransactionError: Debug + core::error::Error {}
1318

14-
/// (Optional signer, chain id, nonce, address)
15-
pub type AuthorizationItem = (Option<Address>, U256, u64, Address);
16-
1719
/// Main Transaction trait that abstracts and specifies all transaction currently supported by Ethereum
1820
///
1921
/// Access to any associated type is gaited behind [`tx_type`][Transaction::tx_type] function.
@@ -22,6 +24,9 @@ pub type AuthorizationItem = (Option<Address>, U256, u64, Address);
2224
/// deprecated by not returning tx_type.
2325
#[auto_impl(&, Box, Arc, Rc)]
2426
pub trait Transaction {
27+
type AccessList: AccessListTrait;
28+
type Authorization: AuthorizationTrait;
29+
2530
/// Returns the transaction type.
2631
///
2732
/// Depending on this field other functions should be called.
@@ -68,20 +73,11 @@ pub trait Transaction {
6873
/// For Eip1559 it is max_fee_per_gas.
6974
fn gas_price(&self) -> u128;
7075

71-
fn access_list(&self) -> Option<impl Iterator<Item = (&Address, &[B256])>>;
72-
73-
fn access_list_nums(&self) -> Option<(usize, usize)> {
74-
self.access_list().map(|al| {
75-
let mut accounts_num = 0;
76-
let mut storage_num = 0;
77-
for (_, storage) in al {
78-
accounts_num += 1;
79-
storage_num += storage.len();
80-
}
76+
/// Access list for the transaction.
77+
///
78+
/// Introduced in EIP-2930.
79+
fn access_list(&self) -> Option<&Self::AccessList>;
8180

82-
(accounts_num, storage_num)
83-
})
84-
}
8581
/// Returns vector of fixed size hash(32 bytes)
8682
///
8783
/// Note : EIP-4844 transaction field.
@@ -114,6 +110,7 @@ pub trait Transaction {
114110
/// Returns length of the authorization list.
115111
///
116112
/// # Note
113+
///
117114
/// Transaction is considered invalid if list is empty.
118115
fn authorization_list_len(&self) -> usize;
119116

@@ -123,7 +120,7 @@ pub trait Transaction {
123120
/// Set EOA account code for one transaction
124121
///
125122
/// [EIP-Set EOA account code for one transaction](https://eips.ethereum.org/EIPS/eip-7702)
126-
fn authorization_list(&self) -> impl Iterator<Item = AuthorizationItem>;
123+
fn authorization_list(&self) -> impl Iterator<Item = &Self::Authorization>;
127124

128125
/// Returns maximum fee that can be paid for the transaction.
129126
fn max_fee_per_gas(&self) -> u128 {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use super::{AccessListTrait, AuthorizationTrait};
2+
use primitives::{Address, B256, U256};
3+
4+
use alloy_eip2930::AccessList;
5+
use alloy_eip7702::{RecoveredAuthorization, SignedAuthorization};
6+
7+
impl AccessListTrait for AccessList {
8+
fn access_list(&self) -> impl Iterator<Item = (Address, impl Iterator<Item = B256>)> {
9+
self.0
10+
.iter()
11+
.map(|item| (item.address, item.storage_keys.iter().cloned()))
12+
}
13+
}
14+
15+
impl AuthorizationTrait for SignedAuthorization {
16+
fn authority(&self) -> Option<Address> {
17+
self.recover_authority().ok()
18+
}
19+
20+
fn chain_id(&self) -> U256 {
21+
self.chain_id
22+
}
23+
24+
fn nonce(&self) -> u64 {
25+
self.nonce
26+
}
27+
28+
fn address(&self) -> Address {
29+
self.address
30+
}
31+
}
32+
33+
impl AuthorizationTrait for RecoveredAuthorization {
34+
fn authority(&self) -> Option<Address> {
35+
self.authority()
36+
}
37+
38+
fn chain_id(&self) -> U256 {
39+
self.chain_id
40+
}
41+
42+
fn nonce(&self) -> u64 {
43+
self.nonce
44+
}
45+
46+
fn address(&self) -> Address {
47+
self.address
48+
}
49+
}

crates/context/interface/src/transaction/common.rs

-23
This file was deleted.

crates/context/interface/src/transaction/eip1559.rs

-24
This file was deleted.

crates/context/interface/src/transaction/access_list.rs crates/context/interface/src/transaction/eip2930.rs

-12
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,3 @@ pub trait AccessListTrait {
2121
(account_num, storage_num)
2222
}
2323
}
24-
25-
// TODO : Move to default context
26-
use specification::eip2930::AccessList;
27-
28-
impl AccessListTrait for AccessList {
29-
fn access_list(&self) -> impl Iterator<Item = (Address, impl Iterator<Item = B256>)> {
30-
self.0.iter().map(|item| {
31-
let slots = item.storage_keys.iter().copied();
32-
(item.address, slots)
33-
})
34-
}
35-
}

crates/context/interface/src/transaction/eip4844.rs

-35
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1-
use super::Eip1559Tx;
21
use auto_impl::auto_impl;
32
use primitives::{Address, U256};
3+
4+
/// Authorization trait.
5+
#[auto_impl(&, Box, Arc, Rc)]
6+
pub trait AuthorizationTrait {
7+
/// Authority address.
8+
///
9+
/// # Note
10+
///
11+
/// Authority signature can be invalid, so this method returns None if the authority
12+
/// could not be recovered.
13+
///
14+
/// Valid signature Parity should be 0 or 1 and
15+
/// signature s-value should be less than SECP256K1N_HALF.
16+
fn authority(&self) -> Option<Address>;
17+
18+
/// Returns authorization the chain id.
19+
fn chain_id(&self) -> U256;
20+
21+
/// Returns the nonce.
22+
///
23+
/// # Note
24+
///
25+
/// If nonce is not same as the nonce of the signer account,
26+
/// the authorization is skipped.
27+
fn nonce(&self) -> u64;
28+
29+
/// Returns the address that this account is delegated to.
30+
fn address(&self) -> Address;
31+
}

crates/context/interface/src/transaction/legacy.rs

-18
This file was deleted.

crates/context/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ pub use cfg::{Cfg, CfgEnv};
1818
pub use context::*;
1919
pub use journal_init::JournalInit;
2020
pub use journaled_state::*;
21-
pub use tx::TxEnv;
21+
pub use tx::{AccessList, SignedAuthorization, TxEnv};
2222
pub mod setters;
2323
pub use evm::{Evm, EvmData};

crates/context/src/tx.rs

+9-19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
use alloy_eip2930::AccessList;
2-
use alloy_eip7702::SignedAuthorization;
3-
use context_interface::transaction::AuthorizationItem;
1+
pub use alloy_eip2930::AccessList;
2+
pub use alloy_eip7702::SignedAuthorization;
43
use context_interface::Transaction;
54
use core::fmt::Debug;
65
use primitives::{Address, Bytes, TxKind, B256, U256};
@@ -99,6 +98,9 @@ impl Default for TxEnv {
9998
}
10099

101100
impl Transaction for TxEnv {
101+
type AccessList = AccessList;
102+
type Authorization = SignedAuthorization;
103+
102104
fn tx_type(&self) -> u8 {
103105
self.tx_type
104106
}
@@ -131,13 +133,8 @@ impl Transaction for TxEnv {
131133
self.chain_id
132134
}
133135

134-
fn access_list(&self) -> Option<impl Iterator<Item = (&Address, &[B256])>> {
135-
Some(
136-
self.access_list
137-
.0
138-
.iter()
139-
.map(|item| (&item.address, item.storage_keys.as_slice())),
140-
)
136+
fn access_list(&self) -> Option<&Self::AccessList> {
137+
Some(&self.access_list)
141138
}
142139

143140
fn max_fee_per_gas(&self) -> u128 {
@@ -152,15 +149,8 @@ impl Transaction for TxEnv {
152149
self.authorization_list.len()
153150
}
154151

155-
fn authorization_list(&self) -> impl Iterator<Item = AuthorizationItem> {
156-
self.authorization_list.iter().map(|item| {
157-
(
158-
item.recover_authority().ok(),
159-
item.chain_id,
160-
item.nonce,
161-
item.address,
162-
)
163-
})
152+
fn authorization_list(&self) -> impl Iterator<Item = &Self::Authorization> {
153+
self.authorization_list.iter()
164154
}
165155

166156
fn input(&self) -> &Bytes {

0 commit comments

Comments
 (0)