Skip to content

Commit ecb327f

Browse files
committed
Merge remote-tracking branch 'origin/main' into refactor_fatal_error
2 parents 6daa311 + 5736d1f commit ecb327f

File tree

10 files changed

+67
-52
lines changed

10 files changed

+67
-52
lines changed

crates/interpreter/src/host.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,7 @@ pub trait Host {
3737
/// Set storage value of account address at index.
3838
///
3939
/// Returns (original, present, new, is_cold).
40-
fn sstore(
41-
&mut self,
42-
address: Address,
43-
index: U256,
44-
value: U256,
45-
) -> Option<(U256, U256, U256, bool)>;
40+
fn sstore(&mut self, address: Address, index: U256, value: U256) -> Option<SStoreResult>;
4641

4742
/// Get the transient storage value of `address` at `index`.
4843
fn tload(&mut self, address: Address, index: U256) -> U256;
@@ -56,3 +51,17 @@ pub trait Host {
5651
/// Mark `address` to be deleted, with funds transferred to `target`.
5752
fn selfdestruct(&mut self, address: Address, target: Address) -> Option<SelfDestructResult>;
5853
}
54+
55+
/// Represents the result of an `sstore` operation.
56+
#[derive(Debug, Clone, PartialEq, Eq)]
57+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
58+
pub struct SStoreResult {
59+
/// Value of the storage when it is first read
60+
pub original_value: U256,
61+
/// Current value of the storage
62+
pub present_value: U256,
63+
/// New value that is set
64+
pub new_value: U256,
65+
/// Is storage slot loaded from database
66+
pub is_cold: bool,
67+
}

crates/interpreter/src/host/dummy.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::primitives::{hash_map::Entry, Bytecode, HashMap, U256};
22
use crate::{
33
primitives::{Address, Env, Log, B256, KECCAK_EMPTY},
4-
Host, SelfDestructResult,
4+
Host, SStoreResult, SelfDestructResult,
55
};
66
use std::vec::Vec;
77

@@ -80,12 +80,7 @@ impl Host for DummyHost {
8080
}
8181

8282
#[inline]
83-
fn sstore(
84-
&mut self,
85-
_address: Address,
86-
index: U256,
87-
value: U256,
88-
) -> Option<(U256, U256, U256, bool)> {
83+
fn sstore(&mut self, _address: Address, index: U256, value: U256) -> Option<SStoreResult> {
8984
let (present, is_cold) = match self.storage.entry(index) {
9085
Entry::Occupied(mut entry) => (entry.insert(value), false),
9186
Entry::Vacant(entry) => {
@@ -94,7 +89,12 @@ impl Host for DummyHost {
9489
}
9590
};
9691

97-
Some((U256::ZERO, present, value, is_cold))
92+
Some(SStoreResult {
93+
original_value: U256::ZERO,
94+
present_value: present,
95+
new_value: value,
96+
is_cold,
97+
})
9898
}
9999

100100
#[inline]

crates/interpreter/src/instructions/host.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
interpreter::{Interpreter, InterpreterAction},
88
primitives::{Address, Bytes, Log, LogData, Spec, SpecId::*, B256, U256},
99
CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, Host, InstructionResult,
10-
Transfer, MAX_INITCODE_SIZE,
10+
SStoreResult, Transfer, MAX_INITCODE_SIZE,
1111
};
1212
use core::cmp::min;
1313
use revm_primitives::BLOCK_HASH_HISTORY;
@@ -154,8 +154,12 @@ pub fn sstore<H: Host, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H)
154154
check_staticcall!(interpreter);
155155

156156
pop!(interpreter, index, value);
157-
let Some((original, old, new, is_cold)) =
158-
host.sstore(interpreter.contract.address, index, value)
157+
let Some(SStoreResult {
158+
original_value: original,
159+
present_value: old,
160+
new_value: new,
161+
is_cold,
162+
}) = host.sstore(interpreter.contract.address, index, value)
159163
else {
160164
interpreter.instruction_result = InstructionResult::FatalExternalError;
161165
return;

crates/interpreter/src/interpreter.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,9 @@ impl Interpreter {
156156
/// - Updates gas costs and records refunds in the interpreter's `gas` field.
157157
/// - May alter `instruction_result` in case of external errors.
158158
pub fn insert_create_outcome(&mut self, create_outcome: CreateOutcome) {
159-
let instruction_result = create_outcome.instruction_result();
159+
self.instruction_result = InstructionResult::Continue;
160160

161+
let instruction_result = create_outcome.instruction_result();
161162
self.return_data_buffer = if instruction_result.is_revert() {
162163
// Save data to return data buffer if the create reverted
163164
create_outcome.output().to_owned()
@@ -213,6 +214,7 @@ impl Interpreter {
213214
shared_memory: &mut SharedMemory,
214215
call_outcome: CallOutcome,
215216
) {
217+
self.instruction_result = InstructionResult::Continue;
216218
let out_offset = call_outcome.memory_start();
217219
let out_len = call_outcome.memory_length();
218220

@@ -314,7 +316,6 @@ impl Interpreter {
314316
FN: Fn(&mut Interpreter, &mut H),
315317
{
316318
self.next_action = InterpreterAction::None;
317-
self.instruction_result = InstructionResult::Continue;
318319
self.shared_memory = shared_memory;
319320
// main loop
320321
while self.instruction_result == InstructionResult::Continue {

crates/interpreter/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ mod interpreter;
2525
pub use call_outcome::CallOutcome;
2626
pub use create_outcome::CreateOutcome;
2727
pub use gas::Gas;
28-
pub use host::{DummyHost, Host};
28+
pub use host::{DummyHost, Host, SStoreResult};
2929
pub use inner_models::*;
3030
pub use instruction_result::*;
3131
pub use instructions::{opcode, Instruction, OpCode, OPCODE_JUMPMAP};

crates/revm/src/context.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::{
1212
},
1313
FrameOrResult, JournalCheckpoint, CALL_STACK_LIMIT,
1414
};
15+
use revm_interpreter::SStoreResult;
1516
use std::boxed::Box;
1617

1718
/// Main Context structure that contains both EvmContext and External context.
@@ -245,7 +246,7 @@ impl<DB: Database> EvmContext<DB> {
245246
address: Address,
246247
index: U256,
247248
value: U256,
248-
) -> Result<(U256, U256, U256, bool), EVMError<DB::Error>> {
249+
) -> Result<SStoreResult, EVMError<DB::Error>> {
249250
self.journaled_state
250251
.sstore(address, index, value, &mut self.db)
251252
}

crates/revm/src/db/ethersdb.rs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,47 +3,39 @@ use crate::{Database, DatabaseRef};
33
use ethers_core::types::{BlockId, H160 as eH160, H256, U64 as eU64};
44
use ethers_providers::Middleware;
55
use std::sync::Arc;
6-
use tokio::runtime::{Handle, Runtime};
76

87
#[derive(Debug)]
98
pub struct EthersDB<M: Middleware> {
109
client: Arc<M>,
11-
runtime: Option<Runtime>,
1210
block_number: Option<BlockId>,
1311
}
1412

1513
impl<M: Middleware> EthersDB<M> {
1614
/// create ethers db connector inputs are url and block on what we are basing our database (None for latest)
1715
pub fn new(client: Arc<M>, block_number: Option<BlockId>) -> Option<Self> {
18-
let runtime = Handle::try_current()
19-
.is_err()
20-
.then(|| Runtime::new().unwrap());
21-
2216
let client = client;
2317

2418
let mut out = Self {
2519
client,
26-
runtime,
2720
block_number: None,
2821
};
2922

30-
out.block_number = if block_number.is_some() {
31-
block_number
23+
out.block_number = if let Some(bn) = block_number {
24+
Some(bn)
3225
} else {
33-
Some(BlockId::from(
34-
out.block_on(out.client.get_block_number()).ok()?,
35-
))
26+
let current_block_number = tokio::runtime::Handle::current()
27+
.block_on(out.client.get_block_number())
28+
.ok()?;
29+
30+
Some(BlockId::from(current_block_number))
3631
};
3732

3833
Some(out)
3934
}
4035

4136
/// internal utility function to call tokio feature and wait for output
4237
fn block_on<F: core::future::Future>(&self, f: F) -> F::Output {
43-
match &self.runtime {
44-
Some(runtime) => runtime.block_on(f),
45-
None => futures::executor::block_on(f),
46-
}
38+
tokio::runtime::Handle::current().block_on(f)
4739
}
4840
}
4941

crates/revm/src/db/in_memory_db.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub type InMemoryDB = CacheDB<EmptyDB>;
1919
/// The [DbAccount] holds the code hash of the contract, which is used to look up the contract in the `contracts` map.
2020
#[derive(Debug, Clone)]
2121
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22-
pub struct CacheDB<ExtDB: DatabaseRef> {
22+
pub struct CacheDB<ExtDB> {
2323
/// Account info where None means it is not existing. Not existing state is needed for Pre TANGERINE forks.
2424
/// `code` is always `None`, and bytecode can be found in `contracts`.
2525
pub accounts: HashMap<Address, DbAccount>,
@@ -35,13 +35,13 @@ pub struct CacheDB<ExtDB: DatabaseRef> {
3535
pub db: ExtDB,
3636
}
3737

38-
impl<ExtDB: DatabaseRef + Default> Default for CacheDB<ExtDB> {
38+
impl<ExtDB: Default> Default for CacheDB<ExtDB> {
3939
fn default() -> Self {
4040
Self::new(ExtDB::default())
4141
}
4242
}
4343

44-
impl<ExtDB: DatabaseRef> CacheDB<ExtDB> {
44+
impl<ExtDB> CacheDB<ExtDB> {
4545
pub fn new(db: ExtDB) -> Self {
4646
let mut contracts = HashMap::new();
4747
contracts.insert(KECCAK_EMPTY, Bytecode::new());
@@ -81,7 +81,9 @@ impl<ExtDB: DatabaseRef> CacheDB<ExtDB> {
8181
self.insert_contract(&mut info);
8282
self.accounts.entry(address).or_default().info = info;
8383
}
84+
}
8485

86+
impl<ExtDB: DatabaseRef> CacheDB<ExtDB> {
8587
/// Returns the account for the given address.
8688
///
8789
/// If the account was not found in the cache, it will be loaded from the underlying database.
@@ -125,7 +127,7 @@ impl<ExtDB: DatabaseRef> CacheDB<ExtDB> {
125127
}
126128
}
127129

128-
impl<ExtDB: DatabaseRef> DatabaseCommit for CacheDB<ExtDB> {
130+
impl<ExtDB> DatabaseCommit for CacheDB<ExtDB> {
129131
fn commit(&mut self, changes: HashMap<Address, Account>) {
130132
for (address, mut account) in changes {
131133
if !account.is_touched() {

crates/revm/src/evm.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use crate::{
33
db::{Database, DatabaseCommit, EmptyDB},
44
handler::Handler,
55
interpreter::{
6-
opcode::InstructionTables, Host, Interpreter, InterpreterAction, SelfDestructResult,
7-
SharedMemory,
6+
opcode::InstructionTables, Host, Interpreter, InterpreterAction, SStoreResult,
7+
SelfDestructResult, SharedMemory,
88
},
99
primitives::{
1010
specification::SpecId, Address, BlockEnv, Bytecode, CfgEnv, EVMError, EVMResult, Env,
@@ -425,12 +425,7 @@ impl<EXT, DB: Database> Host for Evm<'_, EXT, DB> {
425425
.ok()
426426
}
427427

428-
fn sstore(
429-
&mut self,
430-
address: Address,
431-
index: U256,
432-
value: U256,
433-
) -> Option<(U256, U256, U256, bool)> {
428+
fn sstore(&mut self, address: Address, index: U256, value: U256) -> Option<SStoreResult> {
434429
self.context
435430
.evm
436431
.sstore(address, index, value)

crates/revm/src/journaled_state.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::primitives::{
55
};
66
use core::mem;
77
use revm_interpreter::primitives::SpecId;
8+
use revm_interpreter::SStoreResult;
89
use std::vec::Vec;
910

1011
/// JournalState is internal EVM state that is used to contain state and track changes to that state.
@@ -655,7 +656,7 @@ impl JournaledState {
655656
key: U256,
656657
new: U256,
657658
db: &mut DB,
658-
) -> Result<(U256, U256, U256, bool), EVMError<DB::Error>> {
659+
) -> Result<SStoreResult, EVMError<DB::Error>> {
659660
// assume that acc exists and load the slot.
660661
let (present, is_cold) = self.sload(address, key, db)?;
661662
let acc = self.state.get_mut(&address).unwrap();
@@ -665,7 +666,12 @@ impl JournaledState {
665666

666667
// new value is same as present, we don't need to do anything
667668
if present == new {
668-
return Ok((slot.previous_or_original_value, present, new, is_cold));
669+
return Ok(SStoreResult {
670+
original_value: slot.previous_or_original_value,
671+
present_value: present,
672+
new_value: new,
673+
is_cold,
674+
});
669675
}
670676

671677
self.journal
@@ -678,7 +684,12 @@ impl JournaledState {
678684
});
679685
// insert value into present state.
680686
slot.present_value = new;
681-
Ok((slot.previous_or_original_value, present, new, is_cold))
687+
Ok(SStoreResult {
688+
original_value: slot.previous_or_original_value,
689+
present_value: present,
690+
new_value: new,
691+
is_cold,
692+
})
682693
}
683694

684695
/// Read transient storage tied to the account.

0 commit comments

Comments
 (0)