diff --git a/core/rawdb/accessors_snapshot.go b/core/rawdb/accessors_snapshot.go
index 3c82b3f731..8c72c28482 100644
--- a/core/rawdb/accessors_snapshot.go
+++ b/core/rawdb/accessors_snapshot.go
@@ -73,9 +73,8 @@ func DeleteSnapshotRoot(db ethdb.KeyValueWriter) {
}
// ReadAccountSnapshot retrieves the snapshot entry of an account trie leaf.
-func ReadAccountSnapshot(db ethdb.KeyValueReader, hash common.Hash) []byte {
- data, _ := db.Get(accountSnapshotKey(hash))
- return data
+func ReadAccountSnapshot(db ethdb.KeyValueReader, hash common.Hash) ([]byte, error) {
+ return ignoreNotFound(db.Get(accountSnapshotKey(hash)))
}
// WriteAccountSnapshot stores the snapshot entry of an account trie leaf.
@@ -93,9 +92,8 @@ func DeleteAccountSnapshot(db ethdb.KeyValueWriter, hash common.Hash) {
}
// ReadStorageSnapshot retrieves the snapshot entry of an storage trie leaf.
-func ReadStorageSnapshot(db ethdb.KeyValueReader, accountHash, storageHash common.Hash) []byte {
- data, _ := db.Get(storageSnapshotKey(accountHash, storageHash))
- return data
+func ReadStorageSnapshot(db ethdb.KeyValueReader, accountHash, storageHash common.Hash) ([]byte, error) {
+ return ignoreNotFound(db.Get(storageSnapshotKey(accountHash, storageHash)))
}
// WriteStorageSnapshot stores the snapshot entry of an storage trie leaf.
diff --git a/core/rawdb/arbitrum_not_found.go b/core/rawdb/arbitrum_not_found.go
new file mode 100644
index 0000000000..2c335a4e34
--- /dev/null
+++ b/core/rawdb/arbitrum_not_found.go
@@ -0,0 +1,26 @@
+// Copyright 2024 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package rawdb
+
+// Arbitrum specific code to handle database errors
+
+func ignoreNotFound(blob []byte, err error) ([]byte, error) {
+ if isDbErrNotFound(err) {
+ return nil, nil
+ }
+ return blob, err
+}
diff --git a/core/rawdb/arbitrum_not_found_native.go b/core/rawdb/arbitrum_not_found_native.go
new file mode 100644
index 0000000000..3543aedc8d
--- /dev/null
+++ b/core/rawdb/arbitrum_not_found_native.go
@@ -0,0 +1,32 @@
+// Copyright 2024 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+//go:build !wasm
+// +build !wasm
+
+package rawdb
+
+import (
+ "errors"
+
+ "github.com/cockroachdb/pebble"
+ "github.com/ethereum/go-ethereum/ethdb/memorydb"
+ "github.com/syndtr/goleveldb/leveldb"
+)
+
+func isDbErrNotFound(err error) bool {
+ return errors.Is(err, leveldb.ErrNotFound) || errors.Is(err, pebble.ErrNotFound) || errors.Is(err, memorydb.ErrMemorydbNotFound)
+}
diff --git a/core/rawdb/arbitrum_not_found_wasm.go b/core/rawdb/arbitrum_not_found_wasm.go
new file mode 100644
index 0000000000..d49c96848e
--- /dev/null
+++ b/core/rawdb/arbitrum_not_found_wasm.go
@@ -0,0 +1,30 @@
+// Copyright 2024 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+//go:build wasm
+// +build wasm
+
+package rawdb
+
+import (
+ "errors"
+
+ "github.com/ethereum/go-ethereum/ethdb/memorydb"
+)
+
+func isDbErrNotFound(err error) bool {
+ return errors.Is(err, memorydb.ErrMemorydbNotFound)
+}
diff --git a/core/state/snapshot/disklayer.go b/core/state/snapshot/disklayer.go
index f5518a204c..29a590d24f 100644
--- a/core/state/snapshot/disklayer.go
+++ b/core/state/snapshot/disklayer.go
@@ -117,7 +117,10 @@ func (dl *diskLayer) AccountRLP(hash common.Hash) ([]byte, error) {
return blob, nil
}
// Cache doesn't contain account, pull from disk and cache for later
- blob := rawdb.ReadAccountSnapshot(dl.diskdb, hash)
+ blob, err := rawdb.ReadAccountSnapshot(dl.diskdb, hash)
+ if err != nil {
+ return nil, err
+ }
dl.cache.Set(hash[:], blob)
snapshotCleanAccountMissMeter.Mark(1)
@@ -157,7 +160,10 @@ func (dl *diskLayer) Storage(accountHash, storageHash common.Hash) ([]byte, erro
return blob, nil
}
// Cache doesn't contain storage slot, pull from disk and cache for later
- blob := rawdb.ReadStorageSnapshot(dl.diskdb, accountHash, storageHash)
+ blob, err := rawdb.ReadStorageSnapshot(dl.diskdb, accountHash, storageHash)
+ if err != nil {
+ return nil, err
+ }
dl.cache.Set(key, blob)
snapshotCleanStorageMissMeter.Mark(1)
diff --git a/core/state/snapshot/disklayer_test.go b/core/state/snapshot/disklayer_test.go
index 168458c405..5854e8fcd3 100644
--- a/core/state/snapshot/disklayer_test.go
+++ b/core/state/snapshot/disklayer_test.go
@@ -183,7 +183,7 @@ func TestDiskMerge(t *testing.T) {
// assertDatabaseAccount ensures that an account from the database matches the given blob.
assertDatabaseAccount := func(account common.Hash, data []byte) {
t.Helper()
- if blob := rawdb.ReadAccountSnapshot(db, account); !bytes.Equal(blob, data) {
+ if blob, _ := rawdb.ReadAccountSnapshot(db, account); !bytes.Equal(blob, data) {
t.Errorf("account database access (%x) mismatch: have %x, want %x", account, blob, data)
}
}
@@ -197,7 +197,7 @@ func TestDiskMerge(t *testing.T) {
// assertDatabaseStorage ensures that a storage slot from the database matches the given blob.
assertDatabaseStorage := func(account common.Hash, slot common.Hash, data []byte) {
t.Helper()
- if blob := rawdb.ReadStorageSnapshot(db, account, slot); !bytes.Equal(blob, data) {
+ if blob, _ := rawdb.ReadStorageSnapshot(db, account, slot); !bytes.Equal(blob, data) {
t.Errorf("storage database access (%x:%x) mismatch: have %x, want %x", account, slot, blob, data)
}
}
@@ -387,7 +387,7 @@ func TestDiskPartialMerge(t *testing.T) {
// exist otherwise.
assertDatabaseAccount := func(account common.Hash, data []byte) {
t.Helper()
- blob := rawdb.ReadAccountSnapshot(db, account)
+ blob, _ := rawdb.ReadAccountSnapshot(db, account)
if bytes.Compare(account[:], genMarker) > 0 && blob != nil {
t.Fatalf("test %d: post-marker (%x) account database access (%x) succeeded: %x", i, genMarker, account, blob)
}
@@ -407,7 +407,7 @@ func TestDiskPartialMerge(t *testing.T) {
// and does not exist otherwise.
assertDatabaseStorage := func(account common.Hash, slot common.Hash, data []byte) {
t.Helper()
- blob := rawdb.ReadStorageSnapshot(db, account, slot)
+ blob, _ := rawdb.ReadStorageSnapshot(db, account, slot)
if bytes.Compare(append(account[:], slot[:]...), genMarker) > 0 && blob != nil {
t.Fatalf("test %d: post-marker (%x) storage database access (%x:%x) succeeded: %x", i, genMarker, account, slot, blob)
}
diff --git a/core/state/snapshot/generate_test.go b/core/state/snapshot/generate_test.go
index da93ebc875..f1be172fd4 100644
--- a/core/state/snapshot/generate_test.go
+++ b/core/state/snapshot/generate_test.go
@@ -578,7 +578,7 @@ func testGenerateWithExtraAccounts(t *testing.T, scheme string) {
root := helper.Commit()
// To verify the test: If we now inspect the snap db, there should exist extraneous storage items
- if data := rawdb.ReadStorageSnapshot(helper.diskdb, hashData([]byte("acc-2")), hashData([]byte("b-key-1"))); data == nil {
+ if data, _ := rawdb.ReadStorageSnapshot(helper.diskdb, hashData([]byte("acc-2")), hashData([]byte("b-key-1"))); data == nil {
t.Fatalf("expected snap storage to exist")
}
snap := generateSnapshot(helper.diskdb, helper.triedb, 16, root)
@@ -596,7 +596,7 @@ func testGenerateWithExtraAccounts(t *testing.T, scheme string) {
snap.genAbort <- stop
<-stop
// If we now inspect the snap db, there should exist no extraneous storage items
- if data := rawdb.ReadStorageSnapshot(helper.diskdb, hashData([]byte("acc-2")), hashData([]byte("b-key-1"))); data != nil {
+ if data, _ := rawdb.ReadStorageSnapshot(helper.diskdb, hashData([]byte("acc-2")), hashData([]byte("b-key-1"))); data != nil {
t.Fatalf("expected slot to be removed, got %v", string(data))
}
}
@@ -746,7 +746,7 @@ func testGenerateWithMalformedSnapdata(t *testing.T, scheme string) {
snap.genAbort <- stop
<-stop
// If we now inspect the snap db, there should exist no extraneous storage items
- if data := rawdb.ReadStorageSnapshot(helper.diskdb, hashData([]byte("acc-2")), hashData([]byte("b-key-1"))); data != nil {
+ if data, _ := rawdb.ReadStorageSnapshot(helper.diskdb, hashData([]byte("acc-2")), hashData([]byte("b-key-1"))); data != nil {
t.Fatalf("expected slot to be removed, got %v", string(data))
}
}
diff --git a/core/state/snapshot/utils.go b/core/state/snapshot/utils.go
index 62f073d2e1..ba94804743 100644
--- a/core/state/snapshot/utils.go
+++ b/core/state/snapshot/utils.go
@@ -61,7 +61,7 @@ func checkDanglingDiskStorage(chaindb ethdb.KeyValueStore) error {
log.Info("Iterating snap storage", "at", fmt.Sprintf("%#x", accKey), "elapsed", common.PrettyDuration(time.Since(start)))
lastReport = time.Now()
}
- if data := rawdb.ReadAccountSnapshot(chaindb, common.BytesToHash(accKey)); len(data) == 0 {
+ if data, _ := rawdb.ReadAccountSnapshot(chaindb, common.BytesToHash(accKey)); len(data) == 0 {
log.Warn("Dangling storage - missing account", "account", fmt.Sprintf("%#x", accKey), "storagekey", fmt.Sprintf("%#x", k))
return fmt.Errorf("dangling snapshot storage account %#x", accKey)
}
@@ -97,7 +97,7 @@ func CheckJournalAccount(db ethdb.KeyValueStore, hash common.Hash) error {
// Look up the disk layer first
baseRoot := rawdb.ReadSnapshotRoot(db)
fmt.Printf("Disklayer: Root: %x\n", baseRoot)
- if data := rawdb.ReadAccountSnapshot(db, hash); data != nil {
+ if data, _ := rawdb.ReadAccountSnapshot(db, hash); data != nil {
account, err := types.FullAccount(data)
if err != nil {
panic(err)