Skip to content

Commit dd7d751

Browse files
feat: allow host to be implemented on custom context (#2112)
* allow host to be implemented on custom context * fix warning * moved Host default implementation into ContextTr * add comment in context * cleanup for inspector Host bound * remove redundant set_error in contexctTr
1 parent 5886b9e commit dd7d751

File tree

7 files changed

+194
-188
lines changed

7 files changed

+194
-188
lines changed

crates/context/interface/src/context.rs

Lines changed: 188 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
use crate::{Block, Cfg, Database, Journal, Transaction};
1+
pub use crate::journaled_state::StateLoad;
2+
use crate::{journaled_state::AccountLoad, Block, Cfg, Database, Journal, Transaction};
23
use auto_impl::auto_impl;
4+
use primitives::{Address, Bytes, Log, B256, BLOCK_HASH_HISTORY, U256};
35

46
#[auto_impl(&mut, Box)]
57
pub trait ContextTr {
@@ -20,4 +22,189 @@ pub trait ContextTr {
2022
fn chain(&mut self) -> &mut Self::Chain;
2123
fn error(&mut self) -> &mut Result<(), <Self::Db as Database>::Error>;
2224
fn tx_journal(&mut self) -> (&mut Self::Tx, &mut Self::Journal);
25+
// default implementationHost calls interface
26+
27+
/// Gets the block hash of the given block `number`.
28+
fn block_hash(&mut self, requested_number: u64) -> Option<B256> {
29+
let block_number = self.block().number();
30+
31+
let Some(diff) = block_number.checked_sub(requested_number) else {
32+
return Some(B256::ZERO);
33+
};
34+
35+
// blockhash should push zero if number is same as current block number.
36+
if diff == 0 {
37+
return Some(B256::ZERO);
38+
}
39+
40+
if diff <= BLOCK_HASH_HISTORY {
41+
return self
42+
.journal()
43+
.db()
44+
.block_hash(requested_number)
45+
.map_err(|e| {
46+
*self.error() = Err(e);
47+
})
48+
.ok();
49+
}
50+
51+
Some(B256::ZERO)
52+
}
53+
54+
fn load_account_delegated(&mut self, address: Address) -> Option<StateLoad<AccountLoad>> {
55+
self.journal()
56+
.load_account_delegated(address)
57+
.map_err(|e| {
58+
*self.error() = Err(e);
59+
})
60+
.ok()
61+
}
62+
63+
/// Gets balance of `address` and if the account is cold.
64+
fn balance(&mut self, address: Address) -> Option<StateLoad<U256>> {
65+
self.journal()
66+
.load_account(address)
67+
.map(|acc| acc.map(|a| a.info.balance))
68+
.map_err(|e| {
69+
*self.error() = Err(e);
70+
})
71+
.ok()
72+
}
73+
74+
/// Gets code of `address` and if the account is cold.
75+
fn code(&mut self, address: Address) -> Option<StateLoad<Bytes>> {
76+
self.journal()
77+
.code(address)
78+
.map_err(|e| {
79+
*self.error() = Err(e);
80+
})
81+
.ok()
82+
}
83+
84+
/// Gets code hash of `address` and if the account is cold.
85+
fn code_hash(&mut self, address: Address) -> Option<StateLoad<B256>> {
86+
self.journal()
87+
.code_hash(address)
88+
.map_err(|e| {
89+
*self.error() = Err(e);
90+
})
91+
.ok()
92+
}
93+
94+
/// Gets storage value of `address` at `index` and if the account is cold.
95+
fn sload(&mut self, address: Address, index: U256) -> Option<StateLoad<U256>> {
96+
self.journal()
97+
.sload(address, index)
98+
.map_err(|e| {
99+
*self.error() = Err(e);
100+
})
101+
.ok()
102+
}
103+
104+
/// Sets storage value of account address at index.
105+
///
106+
/// Returns [`StateLoad`] with [`SStoreResult`] that contains original/new/old storage value.
107+
fn sstore(
108+
&mut self,
109+
address: Address,
110+
index: U256,
111+
value: U256,
112+
) -> Option<StateLoad<SStoreResult>> {
113+
self.journal()
114+
.sstore(address, index, value)
115+
.map_err(|e| {
116+
*self.error() = Err(e);
117+
})
118+
.ok()
119+
}
120+
121+
/// Gets the transient storage value of `address` at `index`.
122+
fn tload(&mut self, address: Address, index: U256) -> U256 {
123+
self.journal().tload(address, index)
124+
}
125+
126+
/// Sets the transient storage value of `address` at `index`.
127+
fn tstore(&mut self, address: Address, index: U256, value: U256) {
128+
self.journal().tstore(address, index, value)
129+
}
130+
131+
/// Emits a log owned by `address` with given `LogData`.
132+
fn log(&mut self, log: Log) {
133+
self.journal().log(log);
134+
}
135+
136+
/// Marks `address` to be deleted, with funds transferred to `target`.
137+
fn selfdestruct(
138+
&mut self,
139+
address: Address,
140+
target: Address,
141+
) -> Option<StateLoad<SelfDestructResult>> {
142+
self.journal()
143+
.selfdestruct(address, target)
144+
.map_err(|e| {
145+
*self.error() = Err(e);
146+
})
147+
.ok()
148+
}
149+
}
150+
151+
/// Represents the result of an `sstore` operation.
152+
#[derive(Clone, Debug, Default, PartialEq, Eq)]
153+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
154+
pub struct SStoreResult {
155+
/// Value of the storage when it is first read
156+
pub original_value: U256,
157+
/// Current value of the storage
158+
pub present_value: U256,
159+
/// New value that is set
160+
pub new_value: U256,
161+
}
162+
163+
impl SStoreResult {
164+
/// Returns `true` if the new value is equal to the present value.
165+
#[inline]
166+
pub fn is_new_eq_present(&self) -> bool {
167+
self.new_value == self.present_value
168+
}
169+
170+
/// Returns `true` if the original value is equal to the present value.
171+
#[inline]
172+
pub fn is_original_eq_present(&self) -> bool {
173+
self.original_value == self.present_value
174+
}
175+
176+
/// Returns `true` if the original value is equal to the new value.
177+
#[inline]
178+
pub fn is_original_eq_new(&self) -> bool {
179+
self.original_value == self.new_value
180+
}
181+
182+
/// Returns `true` if the original value is zero.
183+
#[inline]
184+
pub fn is_original_zero(&self) -> bool {
185+
self.original_value.is_zero()
186+
}
187+
188+
/// Returns `true` if the present value is zero.
189+
#[inline]
190+
pub fn is_present_zero(&self) -> bool {
191+
self.present_value.is_zero()
192+
}
193+
194+
/// Returns `true` if the new value is zero.
195+
#[inline]
196+
pub fn is_new_zero(&self) -> bool {
197+
self.new_value.is_zero()
198+
}
199+
}
200+
201+
/// Result of a selfdestruct action
202+
///
203+
/// Value returned are needed to calculate the gas spent.
204+
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
205+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
206+
pub struct SelfDestructResult {
207+
pub had_value: bool,
208+
pub target_exists: bool,
209+
pub previously_destroyed: bool,
23210
}

crates/context/interface/src/host.rs

Lines changed: 0 additions & 182 deletions
This file was deleted.

crates/context/interface/src/journaled_state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::host::{SStoreResult, SelfDestructResult};
1+
use crate::context::{SStoreResult, SelfDestructResult};
22
use core::ops::{Deref, DerefMut};
33
use database_interface::Database;
44
use primitives::{Address, Bytes, HashSet, Log, B256, U256};

crates/context/interface/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ extern crate alloc as std;
88
pub mod block;
99
pub mod cfg;
1010
pub mod context;
11-
pub mod host;
1211
pub mod journaled_state;
1312
pub mod result;
1413
pub mod transaction;

0 commit comments

Comments
 (0)