adding access list to rpc type crate (#4992)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
DoTheBestToGetTheBest
2023-10-18 12:42:59 -07:00
committed by GitHub
parent 3adc627a35
commit ce73d933c9
6 changed files with 117 additions and 8 deletions

View File

@ -1,6 +1,7 @@
//! Compatibility functions for rpc `Log` type. //! Compatibility functions for rpc `Log` type.
/// Creates a new rpc Log from a primitive log type from DB /// Creates a new rpc Log from a primitive log type from DB
#[inline]
pub fn from_primitive_log(log: reth_primitives::Log) -> reth_rpc_types::Log { pub fn from_primitive_log(log: reth_primitives::Log) -> reth_rpc_types::Log {
reth_rpc_types::Log { reth_rpc_types::Log {
address: log.address, address: log.address,
@ -14,3 +15,18 @@ pub fn from_primitive_log(log: reth_primitives::Log) -> reth_rpc_types::Log {
removed: false, removed: false,
} }
} }
/// Converts a primitive `AccessList` structure from the `reth_primitives` module into the
/// corresponding RPC type.
#[inline]
pub fn from_primitive_access_list(list: reth_primitives::AccessList) -> reth_rpc_types::AccessList {
let converted_list: Vec<reth_rpc_types::AccessListItem> = list
.0
.into_iter()
.map(|item| reth_rpc_types::AccessListItem {
address: item.address,
storage_keys: item.storage_keys,
})
.collect();
reth_rpc_types::AccessList(converted_list)
}

View File

@ -1,11 +1,10 @@
//! Compatibility functions for rpc `Transaction` type. //! Compatibility functions for rpc `Transaction` type.
mod signature; mod signature;
use reth_primitives::{ use reth_primitives::{
AccessListItem, BlockNumber, Transaction as PrimitiveTransaction, BlockNumber, Transaction as PrimitiveTransaction, TransactionKind as PrimitiveTransactionKind,
TransactionKind as PrimitiveTransactionKind, TransactionSignedEcRecovered, TxType, B256, U128, TransactionSignedEcRecovered, TxType, B256, U128, U256, U64,
U256, U64,
}; };
use reth_rpc_types::{CallInput, CallRequest, Transaction}; use reth_rpc_types::{AccessListItem, CallInput, CallRequest, Transaction};
use signature::from_primitive_signature; use signature::from_primitive_signature;
/// Create a new rpc transaction result for a mined transaction, using the given block hash, /// Create a new rpc transaction result for a mined transaction, using the given block hash,
/// number, and tx index fields to populate the corresponding fields in the rpc result. /// number, and tx index fields to populate the corresponding fields in the rpc result.

View File

@ -14,18 +14,21 @@ Reth RPC types
# reth # reth
reth-primitives.workspace = true reth-primitives.workspace = true
# # ethereum
alloy-rlp = { workspace = true, features = ["arrayvec"] }
# misc # misc
alloy-rlp.workspace = true
thiserror.workspace = true thiserror.workspace = true
itertools.workspace = true itertools.workspace = true
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true serde_json.workspace = true
jsonrpsee-types = { workspace = true, optional = true } jsonrpsee-types = { workspace = true, optional = true }
[features] [features]
default = ["jsonrpsee-types"] default = ["jsonrpsee-types"]
[dev-dependencies] [dev-dependencies]
# misc # misc
rand.workspace = true rand.workspace = true
similar-asserts = "1.4" similar-asserts = "1.4"

View File

@ -1,7 +1,7 @@
//use crate::access_list::AccessList;
use crate::BlockOverrides; use crate::BlockOverrides;
use reth_primitives::{AccessList, Address, BlockId, Bytes, B256, U256, U64, U8}; use reth_primitives::{AccessList, Address, BlockId, Bytes, B256, U256, U64, U8};
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
/// Bundle of transactions /// Bundle of transactions
#[derive(Debug, Clone, Default, Eq, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, Default, Eq, PartialEq, Serialize, Deserialize)]
#[serde(default, rename_all = "camelCase")] #[serde(default, rename_all = "camelCase")]

View File

@ -0,0 +1,89 @@
use reth_primitives::{Address, B256, U256};
use serde::{Deserialize, Serialize};
/// A list of addresses and storage keys that the transaction plans to access.
/// Accesses outside the list are possible, but become more expensive.
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, Hash, Default)]
#[serde(rename_all = "camelCase")]
pub struct AccessListItem {
/// Account addresses that would be loaded at the start of execution
pub address: Address,
/// Keys of storage that would be loaded at the start of execution
pub storage_keys: Vec<B256>,
}
/// AccessList as defined in EIP-2930
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, Hash, Default)]
pub struct AccessList(pub Vec<AccessListItem>);
impl AccessList {
/// Converts the list into a vec, expected by revm
pub fn flattened(&self) -> Vec<(Address, Vec<U256>)> {
self.flatten().collect()
}
/// Consumes the type and converts the list into a vec, expected by revm
pub fn into_flattened(self) -> Vec<(Address, Vec<U256>)> {
self.into_flatten().collect()
}
/// Consumes the type and returns an iterator over the list's addresses and storage keys.
pub fn into_flatten(self) -> impl Iterator<Item = (Address, Vec<U256>)> {
self.0.into_iter().map(|item| {
(
item.address,
item.storage_keys.into_iter().map(|slot| U256::from_be_bytes(slot.0)).collect(),
)
})
}
/// Returns an iterator over the list's addresses and storage keys.
pub fn flatten(&self) -> impl Iterator<Item = (Address, Vec<U256>)> + '_ {
self.0.iter().map(|item| {
(
item.address,
item.storage_keys.iter().map(|slot| U256::from_be_bytes(slot.0)).collect(),
)
})
}
}
/// Access list with gas used appended.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
#[serde(rename_all = "camelCase")]
pub struct AccessListWithGasUsed {
/// List with accounts accessed during transaction.
pub access_list: AccessList,
/// Estimated gas used with access list.
pub gas_used: U256,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn access_list_serde() {
let list = AccessList(vec![
AccessListItem { address: Address::ZERO, storage_keys: vec![B256::ZERO] },
AccessListItem { address: Address::ZERO, storage_keys: vec![B256::ZERO] },
]);
let json = serde_json::to_string(&list).unwrap();
let list2 = serde_json::from_str::<AccessList>(&json).unwrap();
assert_eq!(list, list2);
}
#[test]
fn access_list_with_gas_used() {
let list = AccessListWithGasUsed {
access_list: AccessList(vec![
AccessListItem { address: Address::ZERO, storage_keys: vec![B256::ZERO] },
AccessListItem { address: Address::ZERO, storage_keys: vec![B256::ZERO] },
]),
gas_used: U256::from(100),
};
let json = serde_json::to_string(&list).unwrap();
let list2 = serde_json::from_str::<AccessListWithGasUsed>(&json).unwrap();
assert_eq!(list, list2);
}
}

View File

@ -1,11 +1,13 @@
pub use access_list::{AccessList, AccessListItem, AccessListWithGasUsed};
pub use common::TransactionInfo; pub use common::TransactionInfo;
pub use receipt::TransactionReceipt; pub use receipt::TransactionReceipt;
pub use request::TransactionRequest; pub use request::TransactionRequest;
use reth_primitives::{AccessListItem, Address, Bytes, B256, U128, U256, U64}; use reth_primitives::{Address, Bytes, B256, U128, U256, U64};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub use signature::{Parity, Signature}; pub use signature::{Parity, Signature};
pub use typed::*; pub use typed::*;
mod access_list;
mod common; mod common;
mod receipt; mod receipt;
mod request; mod request;