Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.

Commit 1c1cd7e

Browse files
committed
tload in busmapping with test case
1 parent d98385c commit 1c1cd7e

File tree

6 files changed

+84
-46
lines changed

6 files changed

+84
-46
lines changed

bus-mapping/src/evm/opcodes.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ mod precompiles;
6666
#[cfg(test)]
6767
mod memory_expansion_test;
6868

69-
use self::{invalid_tx::InvalidTx, sha3::Sha3};
7069
use address::Address;
7170
use balance::Balance;
7271
use begin_end_tx::BeginEndTx;
@@ -97,6 +96,7 @@ use extcodecopy::Extcodecopy;
9796
use extcodehash::Extcodehash;
9897
use extcodesize::Extcodesize;
9998
use gasprice::GasPrice;
99+
use invalid_tx::InvalidTx;
100100
use logs::Log;
101101
use mload::Mload;
102102
use mstore::Mstore;
@@ -105,11 +105,13 @@ use return_revert::ReturnRevert;
105105
use returndatacopy::Returndatacopy;
106106
use returndatasize::Returndatasize;
107107
use selfbalance::Selfbalance;
108+
use sha3::Sha3;
108109
use sload::Sload;
109110
use sstore::Sstore;
110111
use stackonlyop::StackOnlyOpcode;
111112
use stop::Stop;
112113
use swap::Swap;
114+
use tload::Tload;
113115

114116
#[cfg(any(feature = "test", test))]
115117
pub use crate::precompile::PrecompileCallArgs;
@@ -225,6 +227,7 @@ fn fn_gen_associated_ops(opcode_id: &OpcodeId) -> FnGenAssociatedOps {
225227
OpcodeId::MSIZE => StackOnlyOpcode::<0, 1>::gen_associated_ops,
226228
OpcodeId::GAS => StackOnlyOpcode::<0, 1>::gen_associated_ops,
227229
OpcodeId::JUMPDEST => Dummy::gen_associated_ops,
230+
OpcodeId::TLOAD => Tload::gen_associated_ops,
228231
OpcodeId::DUP1 => Dup::<1>::gen_associated_ops,
229232
OpcodeId::DUP2 => Dup::<2>::gen_associated_ops,
230233
OpcodeId::DUP3 => Dup::<3>::gen_associated_ops,

bus-mapping/src/evm/opcodes/tload.rs

Lines changed: 9 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::Opcode;
22
use crate::{
33
circuit_input_builder::{CircuitInputStateRef, ExecStep},
4-
operation::{CallContextField, StorageOp, TxAccessListAccountStorageOp, RW},
4+
operation::{CallContextField, TransientStorageOp, RW},
55
Error,
66
};
77
use eth_types::{GethExecStep, ToWord, Word};
@@ -18,6 +18,7 @@ impl Opcode for Tload {
1818
geth_steps: &[GethExecStep],
1919
) -> Result<Vec<ExecStep>, Error> {
2020
let geth_step = &geth_steps[0];
21+
let next_geth_step = &geth_steps[1];
2122
let mut exec_step = state.new_step(geth_step)?;
2223

2324
let call_id = state.call()?.call_id;
@@ -59,50 +60,19 @@ impl Opcode for Tload {
5960
state.stack_read(&mut exec_step, stack_position, key)?;
6061

6162
// Storage read
62-
let value = geth_step.storage.get_or_err(&key)?;
63+
let value = next_geth_step
64+
.stack
65+
.last()
66+
.expect("No value in stack in TLOAD next step");
6367

64-
let is_warm = state
65-
.sdb
66-
.check_account_storage_in_access_list(&(contract_addr, key));
67-
68-
let (_, committed_value) = state.sdb.get_committed_storage(&contract_addr, &key);
69-
let committed_value = *committed_value;
7068
state.push_op(
7169
&mut exec_step,
7270
RW::READ,
73-
StorageOp::new(
74-
contract_addr,
75-
key,
76-
value,
77-
value,
78-
state.tx_ctx.id(),
79-
committed_value,
80-
),
71+
TransientStorageOp::new(contract_addr, key, value, value, state.tx_ctx.id()),
8172
)?;
8273

8374
// First stack write
8475
state.stack_write(&mut exec_step, stack_position, value)?;
85-
state.push_op(
86-
&mut exec_step,
87-
RW::READ,
88-
TxAccessListAccountStorageOp {
89-
tx_id: state.tx_ctx.id(),
90-
address: contract_addr,
91-
key,
92-
is_warm,
93-
is_warm_prev: is_warm,
94-
},
95-
)?;
96-
state.push_op_reversible(
97-
&mut exec_step,
98-
TxAccessListAccountStorageOp {
99-
tx_id: state.tx_ctx.id(),
100-
address: contract_addr,
101-
key,
102-
is_warm: true,
103-
is_warm_prev: is_warm,
104-
},
105-
)?;
10676

10777
Ok(vec![exec_step])
10878
}
@@ -128,7 +98,8 @@ mod tload_tests {
12898
};
12999
use pretty_assertions::assert_eq;
130100

131-
fn test_ok() {
101+
#[test]
102+
fn tload_opcode() {
132103
let code = bytecode! {
133104
// Load transient storage slot 0
134105
PUSH1(0x00u64)
@@ -152,7 +123,6 @@ mod tload_tests {
152123
.handle_block(&block.eth_block, &block.geth_traces)
153124
.unwrap();
154125

155-
println!("{:#?}", builder.block.txs()[0].steps());
156126
let step = builder.block.txs()[0]
157127
.steps()
158128
.iter()
@@ -191,9 +161,4 @@ mod tload_tests {
191161
)
192162
);
193163
}
194-
195-
#[test]
196-
fn tload_opcode_impl_warm() {
197-
test_ok()
198-
}
199164
}

eth-types/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ pub enum Error {
2828
InvalidMemoryPointer,
2929
/// Error while trying to access an invalid/empty Storage key.
3030
InvalidStorageKey,
31+
/// Error while trying to access an invalid/empty Transient Storage key.
32+
InvalidTransientStorageKey,
3133
/// Error when an EvmWord is too big to be converted into a
3234
/// `MemoryAddress`.
3335
WordToMemAddr,

eth-types/src/evm_types.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ pub mod memory;
88
pub mod opcode_ids;
99
pub mod stack;
1010
pub mod storage;
11+
pub mod transient_storage;
1112

1213
pub use memory::{Memory, MemoryAddress};
1314
pub use opcode_ids::OpcodeId;
1415
pub use stack::{Stack, StackAddress};
1516
pub use storage::Storage;
17+
pub use transient_storage::TransientStorage;
1618

1719
/// According to EIP-3541, disallow new code starting with 0xEF to be deployed.
1820
pub const INVALID_INIT_CODE_FIRST_BYTE: u8 = 0xef;

eth-types/src/evm_types/opcode_ids.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,6 @@ impl OpcodeId {
918918

919919
impl From<u8> for OpcodeId {
920920
fn from(value: u8) -> Self {
921-
println!("from u8: {}", value);
922921
match value {
923922
0x00u8 => OpcodeId::STOP,
924923
0x01u8 => OpcodeId::ADD,
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//! Doc this
2+
use crate::{DebugWord, Error, ToBigEndian, Word};
3+
use serde::{ser::SerializeMap, Serialize, Serializer};
4+
use std::{collections::HashMap, fmt};
5+
6+
/// Represents a snapshot of the EVM stack state at a certain
7+
/// execution step height.
8+
#[derive(Clone, Eq, PartialEq)]
9+
pub struct TransientStorage(pub HashMap<Word, Word>);
10+
11+
impl<T: Into<HashMap<Word, Word>>> From<T> for TransientStorage {
12+
fn from(map: T) -> Self {
13+
Self(map.into())
14+
}
15+
}
16+
17+
impl fmt::Debug for TransientStorage {
18+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19+
f.debug_map()
20+
.entries(self.0.iter().map(|(k, v)| (DebugWord(k), DebugWord(v))))
21+
.finish()
22+
}
23+
}
24+
25+
impl Serialize for TransientStorage {
26+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
27+
where
28+
S: Serializer,
29+
{
30+
let mut ser = serializer.serialize_map(Some(self.0.len()))?;
31+
for (k, v) in self.0.iter() {
32+
ser.serialize_entry(&hex::encode(k.to_be_bytes()), &hex::encode(v.to_be_bytes()))?;
33+
}
34+
ser.end()
35+
}
36+
}
37+
38+
impl Default for TransientStorage {
39+
fn default() -> Self {
40+
Self::empty()
41+
}
42+
}
43+
44+
impl TransientStorage {
45+
/// Generate an empty instance of EVM TransientStorage.
46+
pub fn empty() -> Self {
47+
TransientStorage(HashMap::new())
48+
}
49+
50+
/// Generate an new instance of EVM transient storage given a `HashMap<Word, Word>`.
51+
pub fn new(map: HashMap<Word, Word>) -> Self {
52+
Self::from(map)
53+
}
54+
55+
/// Get the word for a given key in the EVM transient storage
56+
pub fn get(&self, key: &Word) -> Option<&Word> {
57+
self.0.get(key)
58+
}
59+
60+
/// Get the word for a given key in the EVM transient storage. Returns error if key
61+
/// is not found.
62+
pub fn get_or_err(&self, key: &Word) -> Result<Word, Error> {
63+
self.get(key)
64+
.cloned()
65+
.ok_or(Error::InvalidTransientStorageKey)
66+
}
67+
}

0 commit comments

Comments
 (0)