Skip to content

Commit 03e2232

Browse files
committed
Merge branch 'main' into edr/change-edr-npm-org
2 parents 51b8cb8 + 5ffb64b commit 03e2232

File tree

26 files changed

+333
-333
lines changed

26 files changed

+333
-333
lines changed

.changeset/cold-cobras-carry.md

-5
This file was deleted.

.changeset/proud-peas-sort.md

-5
This file was deleted.

.github/workflows/hardhat-core-ci.yml

+7
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,13 @@ jobs:
197197

198198
- uses: Swatinem/rust-cache@v2
199199

200+
- name: Cache EDR RPC cache
201+
uses: actions/cache@v2
202+
with:
203+
path: |
204+
**/edr-cache
205+
key: edr-rs-rpc-cache-v1
206+
200207
- name: Run cargo test
201208
uses: actions-rs/cargo@v1
202209
env:

Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/edr_eth/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ url = "2.4.1"
3333
[dev-dependencies]
3434
anyhow = "1.0.75"
3535
assert-json-diff = "2.0.2"
36+
edr_defaults = { version = "0.2.0-dev", path = "../edr_defaults" }
3637
lazy_static = "1.4.0"
3738
mockito = { version = "1.0.2", default-features = false }
3839
paste = { version = "1.0.14", default-features = false }

crates/edr_eth/tests/receipt.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
#[cfg(feature = "test-remote")]
22
mod remote {
3-
use lazy_static::lazy_static;
43
use serial_test::serial;
5-
use tempfile::TempDir;
6-
7-
lazy_static! {
8-
// Use same cache dir for all tests
9-
static ref CACHE_DIR: TempDir = TempDir::new().unwrap();
10-
}
114

125
macro_rules! impl_test_remote_block_receipt_root {
136
($(
@@ -21,7 +14,7 @@ mod remote {
2114
use edr_eth::{remote::{RpcClient, PreEip1898BlockSpec}, trie::ordered_trie_root};
2215
use edr_test_utils::env::get_alchemy_url;
2316

24-
let client = RpcClient::new(&get_alchemy_url(), CACHE_DIR.path().into(), None).expect("url ok");
17+
let client = RpcClient::new(&get_alchemy_url(), edr_defaults::CACHE_DIR.into(), None).expect("url ok");
2518

2619
let block = client
2720
.get_block_by_number_with_transaction_data(PreEip1898BlockSpec::Number($block_number))

crates/edr_evm/src/blockchain.rs

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ pub enum BlockchainError {
3434
/// Forked blockchain error
3535
#[error(transparent)]
3636
Forked(#[from] ForkedBlockchainError),
37+
/// An error that occurs when trying to insert a block into storage.
38+
#[error(transparent)]
39+
Insert(#[from] storage::InsertError),
3740
/// Invalid block number
3841
#[error("Invalid block number: {actual}. Expected: {expected}.")]
3942
InvalidBlockNumber {

crates/edr_evm/src/blockchain/forked.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ use revm::{
1616
use tokio::runtime;
1717

1818
use super::{
19-
compute_state_at_block, remote::RemoteBlockchain, storage::ReservableSparseBlockchainStorage,
20-
validate_next_block, Blockchain, BlockchainError, BlockchainMut,
19+
compute_state_at_block, remote::RemoteBlockchain, storage,
20+
storage::ReservableSparseBlockchainStorage, validate_next_block, Blockchain, BlockchainError,
21+
BlockchainMut,
2122
};
2223
use crate::{
2324
state::{ForkState, StateDiff, StateError, StateOverride, SyncState},
@@ -60,6 +61,9 @@ pub enum ForkedBlockchainError {
6061
/// Remote blocks cannot be deleted
6162
#[error("Cannot delete remote block.")]
6263
CannotDeleteRemote,
64+
/// An error that occurs when trying to insert a block into storage.
65+
#[error(transparent)]
66+
Insert(#[from] storage::InsertError),
6367
/// Rpc client error
6468
#[error(transparent)]
6569
RpcClient(#[from] RpcClientError),
@@ -194,7 +198,7 @@ impl BlockHashRef for ForkedBlockchain {
194198
.map(|block| Ok(*block.hash()))?
195199
} else {
196200
self.local_storage
197-
.block_by_number(number)
201+
.block_by_number(number)?
198202
.map(|block| *block.hash())
199203
.ok_or(BlockchainError::UnknownBlockNumber)
200204
}
@@ -235,7 +239,7 @@ impl Blockchain for ForkedBlockchain {
235239
})
236240
.map(|block| Ok(Some(block)))?
237241
} else {
238-
Ok(self.local_storage.block_by_number(number))
242+
Ok(self.local_storage.block_by_number(number)?)
239243
}
240244
}
241245

@@ -271,7 +275,7 @@ impl Blockchain for ForkedBlockchain {
271275
if self.fork_block_number < last_block_number {
272276
Ok(self
273277
.local_storage
274-
.block_by_number(last_block_number)
278+
.block_by_number(last_block_number)?
275279
.expect("Block must exist since block number is less than the last block number"))
276280
} else {
277281
Ok(tokio::task::block_in_place(move || {
@@ -467,12 +471,9 @@ impl BlockchainMut for ForkedBlockchain {
467471

468472
let total_difficulty = previous_total_difficulty + block.header().difficulty;
469473

470-
// SAFETY: The block number is guaranteed to be unique, so the block hash must
471-
// be too.
472-
let block = unsafe {
473-
self.local_storage
474-
.insert_block_unchecked(block, state_diff, total_difficulty)
475-
};
474+
let block = self
475+
.local_storage
476+
.insert_block(block, state_diff, total_difficulty)?;
476477

477478
Ok(BlockAndTotalDifficulty {
478479
block: block.clone(),

crates/edr_evm/src/blockchain/local.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ impl Blockchain for LocalBlockchain {
222222
number: u64,
223223
) -> Result<Option<Arc<dyn SyncBlock<Error = Self::BlockchainError>>>, Self::BlockchainError>
224224
{
225-
Ok(self.storage.block_by_number(number))
225+
Ok(self.storage.block_by_number(number)?)
226226
}
227227

228228
#[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
@@ -245,7 +245,7 @@ impl Blockchain for LocalBlockchain {
245245
) -> Result<Arc<dyn SyncBlock<Error = Self::BlockchainError>>, Self::BlockchainError> {
246246
Ok(self
247247
.storage
248-
.block_by_number(self.storage.last_block_number())
248+
.block_by_number(self.storage.last_block_number())?
249249
.expect("Block must exist"))
250250
}
251251

@@ -331,12 +331,9 @@ impl BlockchainMut for LocalBlockchain {
331331

332332
let total_difficulty = previous_total_difficulty + block.header().difficulty;
333333

334-
// SAFETY: The block number is guaranteed to be unique, so the block hash must
335-
// be too.
336-
let block = unsafe {
337-
self.storage
338-
.insert_block_unchecked(block, state_diff, total_difficulty)
339-
};
334+
let block = self
335+
.storage
336+
.insert_block(block, state_diff, total_difficulty)?;
340337

341338
Ok(BlockAndTotalDifficulty {
342339
block: block.clone(),
@@ -390,7 +387,7 @@ impl BlockHashRef for LocalBlockchain {
390387
u64::try_from(number).map_err(|_error| BlockchainError::BlockNumberTooLarge)?;
391388

392389
self.storage
393-
.block_by_number(number)
390+
.block_by_number(number)?
394391
.map(|block| *block.hash())
395392
.ok_or(BlockchainError::UnknownBlockNumber)
396393
}

crates/edr_evm/src/blockchain/remote.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,7 @@ impl<BlockT: Block + Clone + From<RemoteBlock>, const FORCE_CACHING: bool>
171171
{
172172
Ok(Some({
173173
let mut cache = RwLockUpgradableReadGuard::upgrade(cache).await;
174-
// SAFETY: the receipt with this hash didn't exist yet, so it must be unique
175-
unsafe { cache.insert_receipt_unchecked(receipt) }.clone()
174+
cache.insert_receipt(receipt)?.clone()
176175
}))
177176
} else {
178177
Ok(None)
@@ -235,8 +234,7 @@ impl<BlockT: Block + Clone + From<RemoteBlock>, const FORCE_CACHING: bool>
235234
if is_cacheable {
236235
let mut remote_cache = RwLockUpgradableReadGuard::upgrade(cache).await;
237236

238-
// SAFETY: the block with this number didn't exist yet, so it must be unique
239-
Ok(unsafe { remote_cache.insert_block_unchecked(block, total_difficulty) }.clone())
237+
Ok(remote_cache.insert_block(block, total_difficulty)?.clone())
240238
} else {
241239
Ok(block)
242240
}

crates/edr_evm/src/blockchain/storage.rs

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ pub enum InsertError {
1616
/// The block's number
1717
block_number: u64,
1818
},
19+
/// Receipt already exists
20+
#[error("A receipt with transaction hash {transaction_hash} already exists.")]
21+
DuplicateReceipt {
22+
/// Transaction hash of duplicated receipt
23+
transaction_hash: B256,
24+
},
1925
/// Transaction already exists
2026
#[error("A transaction with hash {hash} already exists.")]
2127
DuplicateTransaction {

crates/edr_evm/src/blockchain/storage/reservable.rs

+18-28
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use edr_eth::{
66
use parking_lot::{RwLock, RwLockUpgradableReadGuard, RwLockWriteGuard};
77
use revm::primitives::{HashMap, HashSet};
88

9-
use super::{sparse, SparseBlockchainStorage};
9+
use super::{sparse, InsertError, SparseBlockchainStorage};
1010
use crate::{state::StateDiff, Block, LocalBlock};
1111

1212
/// A reservation for a sequence of blocks that have not yet been inserted into
@@ -225,24 +225,21 @@ impl<BlockT: Block + Clone> ReservableSparseBlockchainStorage<BlockT> {
225225
impl<BlockT: Block + Clone + From<LocalBlock>> ReservableSparseBlockchainStorage<BlockT> {
226226
/// Retrieves the block by number, if it exists.
227227
#[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
228-
pub fn block_by_number(&self, number: u64) -> Option<BlockT> {
229-
self.try_fulfilling_reservation(number)
230-
.or_else(|| self.storage.read().block_by_number(number).cloned())
228+
pub fn block_by_number(&self, number: u64) -> Result<Option<BlockT>, InsertError> {
229+
Ok(self
230+
.try_fulfilling_reservation(number)?
231+
.or_else(|| self.storage.read().block_by_number(number).cloned()))
231232
}
232233

233-
/// Inserts a block without checking its validity.
234-
///
235-
/// # Safety
236-
///
237-
/// Ensure that the instance does not contain a block with the same hash or
238-
/// number, nor any transactions with the same hash.
234+
/// Insert a block into the storage. Errors if a block with the same hash or
235+
/// number already exists.
239236
#[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
240-
pub unsafe fn insert_block_unchecked(
237+
pub fn insert_block(
241238
&mut self,
242239
block: LocalBlock,
243240
state_diff: StateDiff,
244241
total_difficulty: U256,
245-
) -> &BlockT {
242+
) -> Result<&BlockT, InsertError> {
246243
self.last_block_number = block.header().number;
247244
self.number_to_diff_index
248245
.insert(self.last_block_number, self.state_diffs.len());
@@ -252,17 +249,13 @@ impl<BlockT: Block + Clone + From<LocalBlock>> ReservableSparseBlockchainStorage
252249
let receipts: Vec<_> = block.transaction_receipts().to_vec();
253250
let block = BlockT::from(block);
254251

255-
self.storage
256-
.get_mut()
257-
.insert_receipts_unchecked(receipts, block.clone());
252+
self.storage.get_mut().insert_receipts(receipts)?;
258253

259-
self.storage
260-
.get_mut()
261-
.insert_block_unchecked(block, total_difficulty)
254+
self.storage.get_mut().insert_block(block, total_difficulty)
262255
}
263256

264257
#[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
265-
fn try_fulfilling_reservation(&self, block_number: u64) -> Option<BlockT> {
258+
fn try_fulfilling_reservation(&self, block_number: u64) -> Result<Option<BlockT>, InsertError> {
266259
let reservations = self.reservations.upgradable_read();
267260

268261
reservations
@@ -321,17 +314,14 @@ impl<BlockT: Block + Clone + From<LocalBlock>> ReservableSparseBlockchainStorage
321314
},
322315
);
323316

324-
let mut storage = RwLockUpgradableReadGuard::upgrade(storage);
325-
326-
// SAFETY: Reservations are guaranteed to not overlap with other reservations or
327-
// blocks, so the generated block must have a unique block
328-
// number and thus hash.
329-
unsafe {
330-
storage
331-
.insert_block_unchecked(block.into(), reservation.previous_total_difficulty)
317+
{
318+
let mut storage = RwLockUpgradableReadGuard::upgrade(storage);
319+
Ok(storage
320+
.insert_block(block.into(), reservation.previous_total_difficulty)?
321+
.clone())
332322
}
333-
.clone()
334323
})
324+
.transpose()
335325
}
336326
}
337327

0 commit comments

Comments
 (0)