Skip to content

Commit 9d8d2e9

Browse files
authored
fix(evm): account history fallback (#975)
* add fallback for historical account lookup * use fallback
1 parent 696e842 commit 9d8d2e9

3 files changed

Lines changed: 64 additions & 29 deletions

File tree

packages/evm/bindings/src/lib.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,20 @@ impl EvmInner {
143143
) -> std::result::Result<Bytes, EVMError<String>> {
144144
let account = match block_number {
145145
None => self.persistent_db.basic(address),
146-
Some(block_number) => self
147-
.persistent_db
148-
.get_historical_account_info(block_number, address),
146+
Some(block_number) => {
147+
let result = self
148+
.persistent_db
149+
.get_historical_account_info(block_number, address);
150+
151+
match result {
152+
Ok((historical, _)) if historical.is_some() => Ok(historical),
153+
Ok((_, missing_fallback)) if missing_fallback => {
154+
self.persistent_db.basic(address)
155+
} // fallback
156+
Ok(_) => Ok(None),
157+
Err(err) => Err(err),
158+
}
159+
}
149160
}
150161
.map_err(|err| EVMError::Database(format!("account lookup failed: {}", err).into()))?;
151162

@@ -362,9 +373,20 @@ impl EvmInner {
362373
) -> std::result::Result<AccountInfo, EVMError<String>> {
363374
let result = match block_number {
364375
None => self.persistent_db.basic(address),
365-
Some(block_number) => self
366-
.persistent_db
367-
.get_historical_account_info(block_number, address),
376+
Some(block_number) => {
377+
let result = self
378+
.persistent_db
379+
.get_historical_account_info(block_number, address);
380+
381+
match result {
382+
Ok((historical, _)) if historical.is_some() => Ok(historical),
383+
Ok((_, missing_fallback)) if missing_fallback => {
384+
self.persistent_db.basic(address)
385+
} // fallback
386+
Ok(_) => Ok(None),
387+
Err(err) => Err(err),
388+
}
389+
}
368390
};
369391

370392
match result {

packages/evm/core/src/db.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -553,34 +553,37 @@ impl PersistentDB {
553553
&mut self,
554554
block_number: u64,
555555
address: Address,
556-
) -> Result<Option<AccountInfo>, Error> {
556+
) -> Result<(Option<AccountInfo>, bool), Error> {
557557
match self.inner.borrow().accounts_history {
558558
Some(db) => {
559559
let tx_env = self.env.read_txn()?;
560560

561561
match self.accounts_history.as_ref() {
562562
Some(accounts_history) => {
563-
let data = accounts_history.get_by_block_and_address(
563+
let (data, missing_fallback) = accounts_history.get_by_block_and_address(
564564
&tx_env,
565565
&db,
566566
block_number,
567567
&address,
568568
)?;
569569

570570
match data {
571-
Some(data) => Ok(Some(AccountInfo {
572-
balance: data.balance,
573-
nonce: data.nonce,
574-
code_hash: data.code_hash,
575-
..Default::default()
576-
})),
577-
None => Ok(None),
571+
Some(data) => Ok((
572+
Some(AccountInfo {
573+
balance: data.balance,
574+
nonce: data.nonce,
575+
code_hash: data.code_hash,
576+
..Default::default()
577+
}),
578+
missing_fallback,
579+
)),
580+
None => Ok((None, missing_fallback)),
578581
}
579582
}
580-
None => Ok(None),
583+
None => Ok((None, false)),
581584
}
582585
}
583-
None => Ok(None),
586+
None => Ok((None, false)),
584587
}
585588
}
586589

packages/evm/core/src/historical.rs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,20 @@ impl AccountHistory {
7272
>,
7373
block_number: u64,
7474
address: &Address,
75-
) -> Result<Option<HistoricalAccountData>, Error> {
75+
) -> Result<(Option<HistoricalAccountData>, bool), Error> {
7676
let mut iter = database.rev_range(txn, &..=block_number)?;
7777

78+
let mut missing_fallback = false;
79+
7880
while let Some((_, history)) = iter.next().transpose()? {
7981
if let Some(data) = history.get(address) {
80-
return Ok(Some(data.clone()));
82+
return Ok((Some(data.clone()), false));
8183
}
84+
85+
missing_fallback = true;
8286
}
8387

84-
Ok(None)
88+
Ok((None, missing_fallback))
8589
}
8690
}
8791

@@ -229,12 +233,13 @@ fn test_account_history() {
229233
.get_by_block_and_address(&mut txn, history_db, block_number, &address)
230234
.unwrap();
231235

232-
assert!(account.is_some_and(|a| a
236+
assert!(account.0.is_some_and(|a| a
233237
== HistoricalAccountData {
234238
balance: balance,
235239
nonce: nonce,
236240
code_hash: revm::primitives::KECCAK_EMPTY,
237241
}));
242+
assert_eq!(account.1, false);
238243
}
239244

240245
// Assert Account 2 at respective block_numbers (1 - 5)
@@ -279,12 +284,13 @@ fn test_account_history() {
279284
.get_by_block_and_address(&mut txn, history_db, block_number, &address)
280285
.unwrap();
281286

282-
assert!(account.is_some_and(|a| a
287+
assert!(account.0.is_some_and(|a| a
283288
== HistoricalAccountData {
284289
balance: balance,
285290
nonce: nonce,
286291
code_hash: revm::primitives::KECCAK_EMPTY,
287292
}));
293+
assert_eq!(account.1, false);
288294
}
289295

290296
// Assert Account 3 at respective block_numbers (1 - 5)
@@ -298,7 +304,7 @@ fn test_account_history() {
298304
let account = history
299305
.get_by_block_and_address(&mut txn, history_db, block_number, &address)
300306
.unwrap();
301-
assert!(account.is_none());
307+
assert_eq!(account, (None, true));
302308
}
303309

304310
for (block_number, address, balance, nonce) in vec![
@@ -335,12 +341,13 @@ fn test_account_history() {
335341
.get_by_block_and_address(&mut txn, history_db, block_number, &address)
336342
.unwrap();
337343

338-
assert!(account.is_some_and(|a| a
344+
assert!(account.0.is_some_and(|a| a
339345
== HistoricalAccountData {
340346
balance: balance,
341347
nonce: nonce,
342348
code_hash: revm::primitives::KECCAK_EMPTY,
343349
}));
350+
assert_eq!(account.1, false);
344351
}
345352

346353
// Assert Account 4 at respective block_numbers (1 - 5)
@@ -366,7 +373,8 @@ fn test_account_history() {
366373
let account = history
367374
.get_by_block_and_address(&mut txn, history_db, block_number, &address)
368375
.unwrap();
369-
assert!(account.is_none());
376+
assert!(account.0.is_none());
377+
assert_eq!(account.1, true);
370378
}
371379

372380
for (block_number, address, balance, nonce) in vec![
@@ -382,12 +390,13 @@ fn test_account_history() {
382390
.get_by_block_and_address(&mut txn, history_db, block_number, &address)
383391
.unwrap();
384392

385-
assert!(account.is_some_and(|a| a
393+
assert!(account.0.is_some_and(|a| a
386394
== HistoricalAccountData {
387395
balance: balance,
388396
nonce: nonce,
389397
code_hash: revm::primitives::KECCAK_EMPTY,
390398
}));
399+
assert_eq!(account.1, false);
391400
}
392401
}
393402

@@ -454,7 +463,7 @@ fn test_accounts_history_capacity() {
454463
let account = history
455464
.get_by_block_and_address(&mut txn, history_db, block_number, &address)
456465
.unwrap();
457-
assert!(account.is_none());
466+
assert_eq!(account, (None, false));
458467
}
459468

460469
// Assert accounts found at respective block_numbers (2+)
@@ -503,12 +512,13 @@ fn test_accounts_history_capacity() {
503512
.get_by_block_and_address(&mut txn, history_db, block_number, &address)
504513
.unwrap();
505514

506-
assert!(account.is_some_and(|a| a
515+
assert!(account.0.is_some_and(|a| a
507516
== HistoricalAccountData {
508517
balance: balance,
509518
nonce: nonce,
510519
code_hash: revm::primitives::KECCAK_EMPTY,
511520
}));
521+
assert!(account.1 == false);
512522
}
513523

514524
// Write empty blocks until everything is evicted
@@ -528,7 +538,7 @@ fn test_accounts_history_capacity() {
528538
let account = history
529539
.get_by_block_and_address(&mut txn, history_db, i, &address)
530540
.unwrap();
531-
assert!(account.is_none());
541+
assert_eq!(account, (None, i >= 10 - history.capacity));
532542
}
533543
}
534544
}

0 commit comments

Comments
 (0)