From d8757174b3f07aac93d0b04f9c2cc5271ff969cf Mon Sep 17 00:00:00 2001 From: Darioush Jalali Date: Tue, 24 Sep 2024 10:58:55 -0700 Subject: [PATCH] add prestate panic prevention (NativeAssetCall) --- eth/tracers/native/prestate.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index d7e10173cf27..0421a45e3533 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -290,6 +290,16 @@ func (t *prestateTracer) lookupAccount(addr common.Address) { // it to the prestate of the given contract. It assumes `lookupAccount` // has been performed on the contract before. func (t *prestateTracer) lookupStorage(addr common.Address, key common.Hash) { + // TODO: Refactor coreth test outside of eth/tracers/internal + // See https://github.com/ava-labs/coreth/pull/286 for context. + // lookupStorage assumes that lookupAccount has already been called. + // This assumption is violated for some historical blocks by the NativeAssetCall + // precompile. To fix this, we perform an extra call to lookupAccount here to ensure + // that the pre-state account is populated before attempting to read from the Storage + // map. When the invariant is maintained properly (since de-activation of the precompile), + // lookupAccount is a no-op. When the invariant is broken by the precompile, this avoids + // the panic and correctly captures the account prestate before the next opcode is executed. + t.lookupAccount(addr) if _, ok := t.pre[addr].Storage[key]; ok { return }