Skip to content

Commit 78c81ea

Browse files
authored
Merge branch 'merge-v1.14.4' into merge-v1.14.5
2 parents 91e9de8 + da10033 commit 78c81ea

15 files changed

+181
-92
lines changed

arbitrum/recordingdb.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,19 @@ type RecordingKV struct {
3232
inner *triedb.Database
3333
diskDb ethdb.KeyValueStore
3434
readDbEntries map[common.Hash][]byte
35+
mutex sync.Mutex
3536
enableBypass bool
3637
}
3738

3839
func newRecordingKV(inner *triedb.Database, diskDb ethdb.KeyValueStore) *RecordingKV {
39-
return &RecordingKV{inner, diskDb, make(map[common.Hash][]byte), false}
40+
return &RecordingKV{inner, diskDb, make(map[common.Hash][]byte), sync.Mutex{}, false}
4041
}
4142

4243
func (db *RecordingKV) Has(key []byte) (bool, error) {
4344
return false, errors.New("recording KV doesn't support Has")
4445
}
4546

47+
// Get may be called concurrently with other Get calls
4648
func (db *RecordingKV) Get(key []byte) ([]byte, error) {
4749
var hash common.Hash
4850
var res []byte
@@ -66,6 +68,8 @@ func (db *RecordingKV) Get(key []byte) ([]byte, error) {
6668
if crypto.Keccak256Hash(res) != hash {
6769
return nil, fmt.Errorf("recording KV attempted to access non-hash key %v", hash)
6870
}
71+
db.mutex.Lock()
72+
defer db.mutex.Unlock()
6973
db.readDbEntries[hash] = res
7074
return res, nil
7175
}

common/lru/blob_lru.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,21 @@ func (c *SizeConstrainedCache[K, V]) Get(key K) (V, bool) {
8282

8383
return c.lru.Get(key)
8484
}
85+
86+
func (c *SizeConstrainedCache[K, V]) Remove(key K) {
87+
c.lock.Lock()
88+
defer c.lock.Unlock()
89+
90+
if v, ok := c.lru.Peek(key); ok {
91+
c.size -= uint64(len(v))
92+
c.lru.Remove(key)
93+
}
94+
}
95+
96+
func (c *SizeConstrainedCache[K, V]) Clear() {
97+
c.lock.Lock()
98+
defer c.lock.Unlock()
99+
100+
c.lru.Purge()
101+
c.size = 0
102+
}

core/state/statedb.go

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package state
1919

2020
import (
21-
"bytes"
2221
"errors"
2322
"fmt"
2423
"maps"
@@ -208,6 +207,18 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)
208207
return sdb, nil
209208
}
210209

210+
func (s *StateDB) FilterTx() {
211+
s.arbExtraData.arbTxFilter = true
212+
}
213+
214+
func (s *StateDB) ClearTxFilter() {
215+
s.arbExtraData.arbTxFilter = false
216+
}
217+
218+
func (s *StateDB) IsTxFiltered() bool {
219+
return s.arbExtraData.arbTxFilter
220+
}
221+
211222
// SetLogger sets the logger for account update hooks.
212223
func (s *StateDB) SetLogger(l *tracing.Hooks) {
213224
s.logger = l
@@ -718,6 +729,7 @@ func (s *StateDB) Copy() *StateDB {
718729
recentWasms: s.arbExtraData.recentWasms.Copy(),
719730
openWasmPages: s.arbExtraData.openWasmPages,
720731
everWasmPages: s.arbExtraData.everWasmPages,
732+
arbTxFilter: s.arbExtraData.arbTxFilter,
721733
},
722734

723735
db: s.db,
@@ -898,32 +910,15 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
898910
// later time.
899911
workers.SetLimit(1)
900912
}
901-
if s.deterministic {
902-
addressesToUpdate := make([]common.Address, 0, len(s.mutations))
903-
for addr := range s.mutations {
904-
addressesToUpdate = append(addressesToUpdate, addr)
905-
}
906-
sort.Slice(addressesToUpdate, func(i, j int) bool { return bytes.Compare(addressesToUpdate[i][:], addressesToUpdate[j][:]) < 0 })
907-
for _, addr := range addressesToUpdate {
908-
if obj := s.mutations[addr]; !obj.applied && !obj.isDelete() {
909-
obj := s.stateObjects[addr] // closure for the task runner below
910-
workers.Go(func() error {
911-
obj.updateRoot()
912-
return nil
913-
})
914-
}
915-
}
916-
} else {
917-
for addr, op := range s.mutations {
918-
if op.applied || op.isDelete() {
919-
continue
920-
}
921-
obj := s.stateObjects[addr] // closure for the task runner below
922-
workers.Go(func() error {
923-
obj.updateRoot()
924-
return nil
925-
})
913+
for addr, op := range s.mutations {
914+
if op.applied || op.isDelete() {
915+
continue
926916
}
917+
obj := s.stateObjects[addr] // closure for the task runner below
918+
workers.Go(func() error {
919+
obj.updateRoot()
920+
return nil
921+
})
927922
}
928923
workers.Wait()
929924
s.StorageUpdates += time.Since(start)
@@ -968,6 +963,9 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
968963
}
969964
usedAddrs = append(usedAddrs, common.CopyBytes(addr[:])) // Copy needed for closure
970965
}
966+
if s.deterministic {
967+
sort.Slice(deletedAddrs, func(i, j int) bool { return deletedAddrs[i].Cmp(deletedAddrs[j]) < 0 })
968+
}
971969
for _, deletedAddr := range deletedAddrs {
972970
s.deleteStateObject(deletedAddr)
973971
s.AccountDeleted += 1
@@ -1182,6 +1180,9 @@ func (s *StateDB) GetTrie() Trie {
11821180
// commit gathers the state mutations accumulated along with the associated
11831181
// trie changes, resetting all internal flags with the new state as the base.
11841182
func (s *StateDB) commit(deleteEmptyObjects bool) (*stateUpdate, error) {
1183+
if s.arbExtraData.arbTxFilter {
1184+
return nil, ErrArbTxFilter
1185+
}
11851186
// Short circuit in case any database failure occurred earlier.
11861187
if s.dbErr != nil {
11871188
return nil, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr)
@@ -1326,7 +1327,7 @@ func (s *StateDB) commit(deleteEmptyObjects bool) (*stateUpdate, error) {
13261327

13271328
origin := s.originalRoot
13281329
s.originalRoot = root
1329-
return newStateUpdate(origin, root, deletes, updates, nodes), nil
1330+
return newStateUpdate(origin, root, deletes, updates, nodes, s.arbExtraData.activatedWasms), nil
13301331
}
13311332

13321333
// commitAndFlush is a wrapper of commit which also commits the state mutations
@@ -1347,10 +1348,10 @@ func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool) (*stateU
13471348
}
13481349
}
13491350

1350-
if db := s.db.WasmStore(); db != nil && len(s.arbExtraData.activatedWasms) > 0 {
1351+
if db := s.db.WasmStore(); db != nil && len(ret.activatedWasms) > 0 {
13511352
batch := db.NewBatch()
13521353
// Arbitrum: write Stylus programs to disk
1353-
for moduleHash, asmMap := range s.arbExtraData.activatedWasms {
1354+
for moduleHash, asmMap := range ret.activatedWasms {
13541355
rawdb.WriteActivation(batch, moduleHash, asmMap)
13551356
}
13561357
s.arbExtraData.activatedWasms = make(map[common.Hash]ActivatedWasm)

core/state/statedb_arbitrum.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,16 @@ func (s *StateDB) Deterministic() bool {
164164
return s.deterministic
165165
}
166166

167+
var ErrArbTxFilter error = errors.New("internal error")
168+
167169
type ArbitrumExtraData struct {
168170
unexpectedBalanceDelta *big.Int // total balance change across all accounts
169171
userWasms UserWasms // user wasms encountered during execution
170172
openWasmPages uint16 // number of pages currently open
171173
everWasmPages uint16 // largest number of pages ever allocated during this tx's execution
172174
activatedWasms map[common.Hash]ActivatedWasm // newly activated WASMs
173175
recentWasms RecentWasms
176+
arbTxFilter bool
174177
}
175178

176179
func (s *StateDB) SetArbFinalizer(f func(*ArbitrumExtraData)) {

core/state/stateupdate.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type stateUpdate struct {
5757
storages map[common.Hash]map[common.Hash][]byte // storages stores mutated slots in 'prefix-zero-trimmed' RLP format
5858
storagesOrigin map[common.Address]map[common.Hash][]byte // storagesOrigin stores the original values of mutated slots in 'prefix-zero-trimmed' RLP format
5959
codes map[common.Address]contractCode // codes contains the set of dirty codes
60+
activatedWasms map[common.Hash]ActivatedWasm // newly activated WASMs
6061
nodes *trienode.MergedNodeSet // Aggregated dirty nodes caused by state changes
6162
}
6263

@@ -68,7 +69,7 @@ func (sc *stateUpdate) empty() bool {
6869
// newStateUpdate constructs a state update object, representing the differences
6970
// between two states by performing state execution. It aggregates the given
7071
// account deletions and account updates to form a comprehensive state update.
71-
func newStateUpdate(originRoot common.Hash, root common.Hash, deletes map[common.Hash]*accountDelete, updates map[common.Hash]*accountUpdate, nodes *trienode.MergedNodeSet) *stateUpdate {
72+
func newStateUpdate(originRoot common.Hash, root common.Hash, deletes map[common.Hash]*accountDelete, updates map[common.Hash]*accountUpdate, nodes *trienode.MergedNodeSet, activatedWasms map[common.Hash]ActivatedWasm) *stateUpdate {
7273
var (
7374
destructs = make(map[common.Hash]struct{})
7475
accounts = make(map[common.Hash][]byte)
@@ -128,6 +129,7 @@ func newStateUpdate(originRoot common.Hash, root common.Hash, deletes map[common
128129
storages: storages,
129130
storagesOrigin: storagesOrigin,
130131
codes: codes,
132+
activatedWasms: activatedWasms,
131133
nodes: nodes,
132134
}
133135
}

core/state_transition.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
530530
} else {
531531
fee := new(uint256.Int).SetUint64(st.gasUsed())
532532
fee.Mul(fee, effectiveTipU256)
533-
st.state.AddBalance(st.evm.Context.Coinbase, fee, tracing.BalanceIncreaseRewardTransactionFee)
533+
st.state.AddBalance(tipReceipient, fee, tracing.BalanceIncreaseRewardTransactionFee)
534534
tipAmount = fee.ToBig()
535535
// add the coinbase to the witness iff the fee is greater than 0
536536
if rules.IsEIP4762 && fee.Sign() != 0 {

core/types/transaction.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,54 @@ type Transaction struct {
6464
inner TxData // Consensus contents of a transaction
6565
time time.Time // Time first seen locally (spam avoidance)
6666

67-
// Arbitrum cache: must be atomically accessed
68-
CalldataUnits uint64
67+
// Arbitrum cache of the calldata units at a brotli compression level.
68+
// The top 8 bits are the brotli compression level last used to compute this,
69+
// and the remaining 56 bits are the calldata units at that compression level.
70+
calldataUnitsForBrotliCompressionLevel atomic.Uint64
6971

7072
// caches
7173
hash atomic.Pointer[common.Hash]
7274
size atomic.Uint64
7375
from atomic.Pointer[sigCache]
7476
}
7577

78+
// GetRawCachedCalldataUnits returns the cached brotli compression level and corresponding calldata units,
79+
// or (0, 0) if the cache is empty.
80+
func (tx *Transaction) GetRawCachedCalldataUnits() (uint64, uint64) {
81+
repr := tx.calldataUnitsForBrotliCompressionLevel.Load()
82+
cachedCompressionLevel := repr >> 56
83+
calldataUnits := repr & ((1 << 56) - 1)
84+
return cachedCompressionLevel, calldataUnits
85+
}
86+
87+
// GetCachedCalldataUnits returns the cached calldata units for a given brotli compression level,
88+
// returning nil if no cache is present or the cache is for a different compression level.
89+
func (tx *Transaction) GetCachedCalldataUnits(requestedCompressionLevel uint64) *uint64 {
90+
cachedCompressionLevel, cachedUnits := tx.GetRawCachedCalldataUnits()
91+
if cachedUnits == 0 {
92+
// empty cache
93+
return nil
94+
}
95+
if cachedCompressionLevel != requestedCompressionLevel {
96+
// wrong compression level
97+
return nil
98+
}
99+
return &cachedUnits
100+
}
101+
102+
// SetCachedCalldataUnits sets the cached brotli compression level and corresponding calldata units,
103+
// or clears the cache if the values are too large to fit (at least 2**8 and 2**56 respectively).
104+
// Note that a zero calldataUnits is also treated as an empty cache.
105+
func (tx *Transaction) SetCachedCalldataUnits(compressionLevel uint64, calldataUnits uint64) {
106+
var repr uint64
107+
// Ensure the compressionLevel and calldataUnits will fit.
108+
// Otherwise, just clear the cache.
109+
if compressionLevel < 1<<8 && calldataUnits < 1<<56 {
110+
repr = compressionLevel<<56 | calldataUnits
111+
}
112+
tx.calldataUnitsForBrotliCompressionLevel.Store(repr)
113+
}
114+
76115
// NewTx creates a new transaction.
77116
func NewTx(inner TxData) *Transaction {
78117
tx := new(Transaction)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2014 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package types
18+
19+
import "testing"
20+
21+
func TestTxCalldataUnitsCache(t *testing.T) {
22+
tx := &Transaction{}
23+
units := tx.GetCachedCalldataUnits(0)
24+
if units != nil {
25+
t.Errorf("unexpected initial cache present %v for compression 0", units)
26+
}
27+
units = tx.GetCachedCalldataUnits(1)
28+
if units != nil {
29+
t.Errorf("unexpected initial cache present %v for compression 1", units)
30+
}
31+
tx.SetCachedCalldataUnits(200, 1000)
32+
units = tx.GetCachedCalldataUnits(100)
33+
if units != nil {
34+
t.Errorf("unexpected cached units %v present for incorrect compression 100", units)
35+
}
36+
units = tx.GetCachedCalldataUnits(0)
37+
if units != nil {
38+
t.Errorf("unexpected cached units %v present for incorrect compression 0", units)
39+
}
40+
units = tx.GetCachedCalldataUnits(200)
41+
if units == nil || *units != 1000 {
42+
t.Errorf("unexpected cached units %v for correct compression 200", units)
43+
}
44+
tx.SetCachedCalldataUnits(1, 1<<60)
45+
units = tx.GetCachedCalldataUnits(1)
46+
if units != nil {
47+
t.Errorf("unexpected cache value %v present after reset", units)
48+
}
49+
}

core/vm/instructions_arbitrum.go

Lines changed: 0 additions & 50 deletions
This file was deleted.

core/vm/interface.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ type StateDB interface {
4949
// Arbitrum: preserve old empty account behavior
5050
CreateZombieIfDeleted(common.Address)
5151

52+
// Arbitrum
53+
FilterTx()
54+
ClearTxFilter()
55+
IsTxFiltered() bool
56+
5257
Deterministic() bool
5358
Database() state.Database
5459

ethdb/pebble/extraoptions.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package pebble
33
import "time"
44

55
type ExtraOptions struct {
6+
SyncMode bool
67
BytesPerSync int
78
L0CompactionFileThreshold int
89
L0CompactionThreshold int

0 commit comments

Comments
 (0)