revm_statetest_types/
test.rs1use revm::{
2 context::tx::TxEnv,
3 primitives::{Address, Bytes, HashMap, TxKind, B256},
4};
5use serde::Deserialize;
6
7use crate::{
8 error::TestError, transaction::TxPartIndices, utils::recover_address, AccountInfo, TestUnit,
9};
10
11#[derive(Debug, PartialEq, Eq, Deserialize)]
13#[serde(rename_all = "camelCase", deny_unknown_fields)]
14pub struct Test {
15 pub expect_exception: Option<String>,
21
22 pub indexes: TxPartIndices,
24 pub hash: B256,
26 #[serde(default)]
28 pub post_state: HashMap<Address, AccountInfo>,
29
30 pub logs: B256,
32
33 #[serde(default)]
37 state: HashMap<Address, AccountInfo>,
38
39 pub txbytes: Option<Bytes>,
41}
42
43impl Test {
44 pub fn tx_env(&self, unit: &TestUnit) -> Result<TxEnv, TestError> {
64 let caller = if let Some(address) = unit.transaction.sender {
66 address
67 } else {
68 recover_address(unit.transaction.secret_key.as_slice())
69 .ok_or(TestError::UnknownPrivateKey(unit.transaction.secret_key))?
70 };
71
72 let tx_type = unit.transaction.tx_type(self.indexes.data).ok_or_else(|| {
74 if self.expect_exception.is_some() {
75 TestError::UnexpectedException {
76 expected_exception: self.expect_exception.clone(),
77 got_exception: Some("Invalid transaction type".to_string()),
78 }
79 } else {
80 TestError::InvalidTransactionType
81 }
82 })?;
83
84 let tx = TxEnv {
85 caller,
86 gas_price: unit
87 .transaction
88 .gas_price
89 .or(unit.transaction.max_fee_per_gas)
90 .unwrap_or_default()
91 .try_into()
92 .unwrap_or(u128::MAX),
93 gas_priority_fee: unit
94 .transaction
95 .max_priority_fee_per_gas
96 .map(|b| u128::try_from(b).expect("max priority fee less than u128::MAX")),
97 blob_hashes: unit.transaction.blob_versioned_hashes.clone(),
98 max_fee_per_blob_gas: unit
99 .transaction
100 .max_fee_per_blob_gas
101 .map(|b| u128::try_from(b).expect("max fee less than u128::MAX"))
102 .unwrap_or(u128::MAX),
103 tx_type: tx_type as u8,
104 gas_limit: unit.transaction.gas_limit[self.indexes.gas].saturating_to(),
105 data: unit.transaction.data[self.indexes.data].clone(),
106 nonce: u64::try_from(unit.transaction.nonce).unwrap(),
107 value: unit.transaction.value[self.indexes.value],
108 access_list: unit
109 .transaction
110 .access_lists
111 .get(self.indexes.data)
112 .cloned()
113 .flatten()
114 .unwrap_or_default(),
115 authorization_list: unit
116 .transaction
117 .authorization_list
118 .clone()
119 .map(|auth_list| {
120 auth_list
121 .into_iter()
122 .map(|i| revm::context::either::Either::Left(i.into()))
123 .collect::<Vec<_>>()
124 })
125 .unwrap_or_default(),
126 kind: match unit.transaction.to {
127 Some(add) => TxKind::Call(add),
128 None => TxKind::Create,
129 },
130 ..TxEnv::default()
131 };
132
133 Ok(tx)
134 }
135}