Skip to content

Commit 784a065

Browse files
refactor: replace U256 with u64 in BLOCKHASH (bluealloy#1505)
* replace U256 -> u64 * cargo fmt * refactor type cast to prevent panic
1 parent 99367b1 commit 784a065

File tree

12 files changed

+37
-43
lines changed

12 files changed

+37
-43
lines changed

Diff for: crates/interpreter/src/host.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub trait Host {
1717
fn load_account(&mut self, address: Address) -> Option<LoadAccountResult>;
1818

1919
/// Get the block hash of the given block `number`.
20-
fn block_hash(&mut self, number: U256) -> Option<B256>;
20+
fn block_hash(&mut self, number: u64) -> Option<B256>;
2121

2222
/// Get balance of `address` and if the account is cold.
2323
fn balance(&mut self, address: Address) -> Option<(U256, bool)>;

Diff for: crates/interpreter/src/host/dummy.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ impl Host for DummyHost {
5050
}
5151

5252
#[inline]
53-
fn block_hash(&mut self, _number: U256) -> Option<B256> {
53+
fn block_hash(&mut self, _number: u64) -> Option<B256> {
5454
Some(B256::ZERO)
5555
}
5656

Diff for: crates/interpreter/src/instructions/host.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ pub fn blockhash<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, ho
106106
gas!(interpreter, gas::BLOCKHASH);
107107
pop_top!(interpreter, number);
108108

109-
let Some(hash) = host.block_hash(*number) else {
109+
let number_u64 = as_u64_saturated!(number);
110+
let Some(hash) = host.block_hash(number_u64) else {
110111
interpreter.instruction_result = InstructionResult::FatalExternalError;
111112
return;
112113
};

Diff for: crates/primitives/src/db.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub trait Database {
2222
fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error>;
2323

2424
/// Get block hash by block number.
25-
fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error>;
25+
fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error>;
2626
}
2727

2828
/// EVM database commit interface.
@@ -53,7 +53,7 @@ pub trait DatabaseRef {
5353
fn storage_ref(&self, address: Address, index: U256) -> Result<U256, Self::Error>;
5454

5555
/// Get block hash by block number.
56-
fn block_hash_ref(&self, number: U256) -> Result<B256, Self::Error>;
56+
fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error>;
5757
}
5858

5959
/// Wraps a [`DatabaseRef`] to provide a [`Database`] implementation.
@@ -86,7 +86,7 @@ impl<T: DatabaseRef> Database for WrapDatabaseRef<T> {
8686
}
8787

8888
#[inline]
89-
fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
89+
fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
9090
self.0.block_hash_ref(number)
9191
}
9292
}

Diff for: crates/primitives/src/db/components.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl<S: State, BH: BlockHash> Database for DatabaseComponents<S, BH> {
4343
.map_err(Self::Error::State)
4444
}
4545

46-
fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
46+
fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
4747
self.block_hash
4848
.block_hash(number)
4949
.map_err(Self::Error::BlockHash)
@@ -69,7 +69,7 @@ impl<S: StateRef, BH: BlockHashRef> DatabaseRef for DatabaseComponents<S, BH> {
6969
.map_err(Self::Error::State)
7070
}
7171

72-
fn block_hash_ref(&self, number: U256) -> Result<B256, Self::Error> {
72+
fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error> {
7373
self.block_hash
7474
.block_hash(number)
7575
.map_err(Self::Error::BlockHash)

Diff for: crates/primitives/src/db/components/block_hash.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! BlockHash database component from [`crate::db::Database`]
22
//! it is used inside [`crate::db::DatabaseComponents`]
33
4-
use crate::{B256, U256};
4+
use crate::B256;
55
use auto_impl::auto_impl;
66
use core::ops::Deref;
77
use std::sync::Arc;
@@ -11,15 +11,15 @@ pub trait BlockHash {
1111
type Error;
1212

1313
/// Get block hash by block number
14-
fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error>;
14+
fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error>;
1515
}
1616

1717
#[auto_impl(&, &mut, Box, Rc, Arc)]
1818
pub trait BlockHashRef {
1919
type Error;
2020

2121
/// Get block hash by block number
22-
fn block_hash(&self, number: U256) -> Result<B256, Self::Error>;
22+
fn block_hash(&self, number: u64) -> Result<B256, Self::Error>;
2323
}
2424

2525
impl<T> BlockHash for &T
@@ -28,7 +28,7 @@ where
2828
{
2929
type Error = <T as BlockHashRef>::Error;
3030

31-
fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
31+
fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
3232
BlockHashRef::block_hash(*self, number)
3333
}
3434
}
@@ -39,7 +39,7 @@ where
3939
{
4040
type Error = <T as BlockHashRef>::Error;
4141

42-
fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
42+
fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
4343
self.deref().block_hash(number)
4444
}
4545
}

Diff for: crates/revm/src/context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,9 @@ impl<EXT, DB: Database> Host for Context<EXT, DB> {
108108
&mut self.evm.env
109109
}
110110

111-
fn block_hash(&mut self, number: U256) -> Option<B256> {
111+
fn block_hash(&mut self, number: u64) -> Option<B256> {
112112
let block_number = as_usize_saturated!(self.env().block.number);
113-
let requested_number = as_usize_saturated!(number);
113+
let requested_number = usize::try_from(number).unwrap_or(usize::MAX);
114114

115115
let Some(diff) = block_number.checked_sub(requested_number) else {
116116
return Some(B256::ZERO);

Diff for: crates/revm/src/context/inner_evm_context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl<DB: Database> InnerEvmContext<DB> {
122122

123123
/// Fetch block hash from database.
124124
#[inline]
125-
pub fn block_hash(&mut self, number: U256) -> Result<B256, EVMError<DB::Error>> {
125+
pub fn block_hash(&mut self, number: u64) -> Result<B256, EVMError<DB::Error>> {
126126
self.db.block_hash(number).map_err(EVMError::Database)
127127
}
128128

Diff for: crates/revm/src/db/emptydb.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl<E> Database for EmptyDBTyped<E> {
7272
}
7373

7474
#[inline]
75-
fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
75+
fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
7676
<Self as DatabaseRef>::block_hash_ref(self, number)
7777
}
7878
}
@@ -96,7 +96,7 @@ impl<E> DatabaseRef for EmptyDBTyped<E> {
9696
}
9797

9898
#[inline]
99-
fn block_hash_ref(&self, number: U256) -> Result<B256, Self::Error> {
99+
fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error> {
100100
Ok(keccak256(number.to_string().as_bytes()))
101101
}
102102
}
@@ -110,21 +110,21 @@ mod tests {
110110
fn conform_block_hash_calculation() {
111111
let db = EmptyDB::new();
112112
assert_eq!(
113-
db.block_hash_ref(U256::from(0)),
113+
db.block_hash_ref(0u64),
114114
Ok(b256!(
115115
"044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d"
116116
))
117117
);
118118

119119
assert_eq!(
120-
db.block_hash_ref(U256::from(1)),
120+
db.block_hash_ref(1u64),
121121
Ok(b256!(
122122
"c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6"
123123
))
124124
);
125125

126126
assert_eq!(
127-
db.block_hash_ref(U256::from(100)),
127+
db.block_hash_ref(100u64),
128128
Ok(b256!(
129129
"8c18210df0d9514f2d2e5d8ca7c100978219ee80d3968ad850ab5ead208287b3"
130130
))

Diff for: crates/revm/src/db/ethersdb.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use ethers_core::types::{Block, BlockId, TxHash, H160 as eH160, H256, U64 as eU6
44
use ethers_providers::Middleware;
55
use tokio::runtime::{Builder, Handle, RuntimeFlavor};
66

7-
use crate::primitives::{AccountInfo, Address, Bytecode, B256, KECCAK_EMPTY, U256};
7+
use crate::primitives::{AccountInfo, Address, Bytecode, B256, U256};
88
use crate::{Database, DatabaseRef};
99

1010
#[derive(Debug, Clone)]
@@ -103,13 +103,8 @@ impl<M: Middleware> DatabaseRef for EthersDB<M> {
103103
Ok(U256::from_be_bytes(slot_value.to_fixed_bytes()))
104104
}
105105

106-
fn block_hash_ref(&self, number: U256) -> Result<B256, Self::Error> {
107-
// saturate usize
108-
if number > U256::from(u64::MAX) {
109-
return Ok(KECCAK_EMPTY);
110-
}
111-
// We know number <= u64::MAX so unwrap is safe
112-
let number = eU64::from(u64::try_from(number).unwrap());
106+
fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error> {
107+
let number = eU64::from(number);
113108
let block: Option<Block<TxHash>> =
114109
Self::block_on(self.client.get_block(BlockId::from(number)))?;
115110
// If number is given, the block is supposed to be finalized so unwrap is safe too.
@@ -136,7 +131,7 @@ impl<M: Middleware> Database for EthersDB<M> {
136131
}
137132

138133
#[inline]
139-
fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
134+
fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
140135
<Self as DatabaseRef>::block_hash_ref(self, number)
141136
}
142137
}

Diff for: crates/revm/src/db/in_memory_db.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,8 @@ impl<ExtDB: DatabaseRef> Database for CacheDB<ExtDB> {
234234
}
235235
}
236236

237-
fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
238-
match self.block_hashes.entry(number) {
237+
fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
238+
match self.block_hashes.entry(U256::from(number)) {
239239
Entry::Occupied(entry) => Ok(*entry.get()),
240240
Entry::Vacant(entry) => {
241241
let hash = self.db.block_hash_ref(number)?;
@@ -282,8 +282,8 @@ impl<ExtDB: DatabaseRef> DatabaseRef for CacheDB<ExtDB> {
282282
}
283283
}
284284

285-
fn block_hash_ref(&self, number: U256) -> Result<B256, Self::Error> {
286-
match self.block_hashes.get(&number) {
285+
fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error> {
286+
match self.block_hashes.get(&U256::from(number)) {
287287
Some(entry) => Ok(*entry),
288288
None => self.db.block_hash_ref(number),
289289
}
@@ -403,7 +403,7 @@ impl Database for BenchmarkDB {
403403
}
404404

405405
// History related
406-
fn block_hash(&mut self, _number: U256) -> Result<B256, Self::Error> {
406+
fn block_hash(&mut self, _number: u64) -> Result<B256, Self::Error> {
407407
Ok(B256::default())
408408
}
409409
}

Diff for: crates/revm/src/db/states/state.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -268,16 +268,14 @@ impl<DB: Database> Database for State<DB> {
268268
}
269269
}
270270

271-
fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
272-
// block number is never bigger then u64::MAX.
273-
let u64num: u64 = number.to();
274-
match self.block_hashes.entry(u64num) {
271+
fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
272+
match self.block_hashes.entry(number) {
275273
btree_map::Entry::Occupied(entry) => Ok(*entry.get()),
276274
btree_map::Entry::Vacant(entry) => {
277275
let ret = *entry.insert(self.database.block_hash(number)?);
278276

279277
// prune all hashes that are older then BLOCK_HASH_HISTORY
280-
let last_block = u64num.saturating_sub(BLOCK_HASH_HISTORY as u64);
278+
let last_block = number.saturating_sub(BLOCK_HASH_HISTORY as u64);
281279
while let Some(entry) = self.block_hashes.first_entry() {
282280
if *entry.key() < last_block {
283281
entry.remove();
@@ -311,8 +309,8 @@ mod tests {
311309
#[test]
312310
fn block_hash_cache() {
313311
let mut state = State::builder().build();
314-
state.block_hash(U256::from(1)).unwrap();
315-
state.block_hash(U256::from(2)).unwrap();
312+
state.block_hash(1u64).unwrap();
313+
state.block_hash(2u64).unwrap();
316314

317315
let test_number = BLOCK_HASH_HISTORY as u64 + 2;
318316

@@ -325,7 +323,7 @@ mod tests {
325323
BTreeMap::from([(1, block1_hash), (2, block2_hash)])
326324
);
327325

328-
state.block_hash(U256::from(test_number)).unwrap();
326+
state.block_hash(test_number).unwrap();
329327
assert_eq!(
330328
state.block_hashes,
331329
BTreeMap::from([(test_number, block_test_hash), (2, block2_hash)])

0 commit comments

Comments
 (0)