From ff9a16e5f0b00d9292e103ff13028f8425d0197b Mon Sep 17 00:00:00 2001
From: Kolby Moroz Liebl <31669092+KolbyML@users.noreply.github.com>
Date: Wed, 19 Nov 2025 11:39:03 -0700
Subject: [PATCH 1/2] Fix RecentWasms cache bug by using pointers in methods
---
core/state/statedb_arbitrum.go | 6 +--
core/state/statedb_arbitrum_test.go | 67 +++++++++++++++++++++++++++++
core/state/statedb_hooked.go | 2 +-
core/vm/interface.go | 2 +-
4 files changed, 72 insertions(+), 5 deletions(-)
create mode 100644 core/state/statedb_arbitrum_test.go
diff --git a/core/state/statedb_arbitrum.go b/core/state/statedb_arbitrum.go
index bd8da24355..dba4c30f5a 100644
--- a/core/state/statedb_arbitrum.go
+++ b/core/state/statedb_arbitrum.go
@@ -330,8 +330,8 @@ func (s *StateDB) RecordEvictWasm(wasm EvictWasm) {
s.journal.entries = append(s.journal.entries, wasm)
}
-func (s *StateDB) GetRecentWasms() RecentWasms {
- return s.arbExtraData.recentWasms
+func (s *StateDB) GetRecentWasms() *RecentWasms {
+ return &s.arbExtraData.recentWasms
}
// Type for managing recent program access.
@@ -346,7 +346,7 @@ func NewRecentWasms() RecentWasms {
}
// Inserts a new item, returning true if already present.
-func (p RecentWasms) Insert(item common.Hash, retain uint16) bool {
+func (p *RecentWasms) Insert(item common.Hash, retain uint16) bool {
if p.cache == nil {
cache := lru.NewBasicLRU[common.Hash, struct{}](int(retain))
p.cache = &cache
diff --git a/core/state/statedb_arbitrum_test.go b/core/state/statedb_arbitrum_test.go
new file mode 100644
index 0000000000..027e5a4edd
--- /dev/null
+++ b/core/state/statedb_arbitrum_test.go
@@ -0,0 +1,67 @@
+// Copyright 2016 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 state
+
+import (
+ "testing"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+)
+
+func TestRecentWasmsInsertAndCopy(t *testing.T) {
+ db := NewDatabaseForTesting()
+ state, err := New(types.EmptyRootHash, db)
+ if err != nil {
+ t.Fatalf("failed to create state: %v", err)
+ }
+
+ const retain = uint16(8)
+
+ hash1 := common.HexToHash("0x01")
+ hash2 := common.HexToHash("0x02")
+ hash3 := common.HexToHash("0x03")
+
+ if hit := state.GetRecentWasms().Insert(hash1, retain); hit {
+ t.Fatalf("first insert of hash1 should be a miss")
+ }
+
+ if hit := state.GetRecentWasms().Insert(hash1, retain); !hit {
+ t.Fatalf("second insert of hash1 should be a hit (cache not persisting)")
+ }
+
+ if hit := state.GetRecentWasms().Insert(hash2, retain); hit {
+ t.Fatalf("first insert of hash2 should be a miss")
+ }
+
+ copy := state.Copy()
+
+ if hit := copy.GetRecentWasms().Insert(hash1, retain); !hit {
+ t.Fatalf("copy: expected hit for hash1 present before copy")
+ }
+ if hit := copy.GetRecentWasms().Insert(hash2, retain); !hit {
+ t.Fatalf("copy: expected hit for hash2 present before copy")
+ }
+
+ if hit := copy.GetRecentWasms().Insert(hash3, retain); hit {
+ t.Fatalf("copy: first insert of hash3 should be a miss")
+ }
+
+ if hit := state.GetRecentWasms().Insert(hash3, retain); hit {
+ t.Fatalf("original: first insert of hash3 should be a miss (must be independent of copy)")
+ }
+}
diff --git a/core/state/statedb_hooked.go b/core/state/statedb_hooked.go
index 673a9dc74d..c718d508fc 100644
--- a/core/state/statedb_hooked.go
+++ b/core/state/statedb_hooked.go
@@ -321,7 +321,7 @@ func (s *hookedStateDB) RecordEvictWasm(wasm EvictWasm) {
s.inner.RecordEvictWasm(wasm)
}
-func (s *hookedStateDB) GetRecentWasms() RecentWasms {
+func (s *hookedStateDB) GetRecentWasms() *RecentWasms {
return s.inner.GetRecentWasms()
}
diff --git a/core/vm/interface.go b/core/vm/interface.go
index ce92dcb53b..48dda58233 100644
--- a/core/vm/interface.go
+++ b/core/vm/interface.go
@@ -38,7 +38,7 @@ type StateDB interface {
ActivatedAsmMap(targets []rawdb.WasmTarget, moduleHash common.Hash) (asmMap map[rawdb.WasmTarget][]byte, missingTargets []rawdb.WasmTarget, err error)
RecordCacheWasm(wasm state.CacheWasm)
RecordEvictWasm(wasm state.EvictWasm)
- GetRecentWasms() state.RecentWasms
+ GetRecentWasms() *state.RecentWasms
// Arbitrum: track stylus's memory footprint
GetStylusPages() (uint16, uint16)
From dfd63684af55b6d4b96dd68c0f284ca34cbbe8bb Mon Sep 17 00:00:00 2001
From: Kolby Moroz Liebl <31669092+KolbyML@users.noreply.github.com>
Date: Fri, 21 Nov 2025 09:37:24 -0700
Subject: [PATCH 2/2] Resolve PR concern
---
core/state/statedb_arbitrum_test.go | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/core/state/statedb_arbitrum_test.go b/core/state/statedb_arbitrum_test.go
index 027e5a4edd..87f2b65b2e 100644
--- a/core/state/statedb_arbitrum_test.go
+++ b/core/state/statedb_arbitrum_test.go
@@ -1,19 +1,3 @@
-// Copyright 2016 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 state
import (