Skip to content

Commit 8fa6e26

Browse files
authored
Merge branch 'ethereum:master' into gethintegration
2 parents 3969e18 + f750117 commit 8fa6e26

File tree

12 files changed

+116
-30
lines changed

12 files changed

+116
-30
lines changed

beacon/params/networks.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ var (
4141
AddFork("ALTAIR", 74240, []byte{1, 0, 0, 0}).
4242
AddFork("BELLATRIX", 144896, []byte{2, 0, 0, 0}).
4343
AddFork("CAPELLA", 194048, []byte{3, 0, 0, 0}).
44-
AddFork("DENEB", 269568, []byte{4, 0, 0, 0})
44+
AddFork("DENEB", 269568, []byte{4, 0, 0, 0}).
45+
AddFork("ELECTRA", 364032, []byte{5, 0, 0, 0})
4546

4647
SepoliaLightConfig = (&ChainConfig{
4748
GenesisValidatorsRoot: common.HexToHash("0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"),

core/blockchain_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4099,7 +4099,7 @@ func TestEIP7702(t *testing.T) {
40994099
// The way the auths are combined, it becomes
41004100
// 1. tx -> addr1 which is delegated to 0xaaaa
41014101
// 2. addr1:0xaaaa calls into addr2:0xbbbb
4102-
// 3. addr2:0xbbbb writes to storage
4102+
// 3. addr2:0xbbbb writes to storage
41034103
auth1, _ := types.SignSetCode(key1, types.SetCodeAuthorization{
41044104
ChainID: *uint256.MustFromBig(gspec.Config.ChainID),
41054105
Address: aa,

core/filtermaps/filtermaps.go

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,17 @@ type FilterMaps struct {
8585
// fields written by the indexer and read by matcher backend. Indexer can
8686
// read them without a lock and write them under indexLock write lock.
8787
// Matcher backend can read them under indexLock read lock.
88-
indexLock sync.RWMutex
89-
indexedRange filterMapsRange
90-
cleanedEpochsBefore uint32 // all unindexed data cleaned before this point
91-
indexedView *ChainView // always consistent with the log index
92-
hasTempRange bool
88+
indexLock sync.RWMutex
89+
indexedRange filterMapsRange
90+
indexedView *ChainView // always consistent with the log index
91+
hasTempRange bool
92+
93+
// cleanedEpochsBefore indicates that all unindexed data before this point
94+
// has been cleaned.
95+
//
96+
// This field is only accessed and modified within tryUnindexTail, so no
97+
// explicit locking is required.
98+
cleanedEpochsBefore uint32
9399

94100
// also accessed by indexer and matcher backend but no locking needed.
95101
filterMapCache *lru.Cache[uint32, filterMap]
@@ -248,15 +254,16 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f
248254
},
249255
// deleting last unindexed epoch might have been interrupted by shutdown
250256
cleanedEpochsBefore: max(rs.MapsFirst>>params.logMapsPerEpoch, 1) - 1,
251-
historyCutoff: historyCutoff,
252-
finalBlock: finalBlock,
253-
matcherSyncCh: make(chan *FilterMapsMatcherBackend),
254-
matchers: make(map[*FilterMapsMatcherBackend]struct{}),
255-
filterMapCache: lru.NewCache[uint32, filterMap](cachedFilterMaps),
256-
lastBlockCache: lru.NewCache[uint32, lastBlockOfMap](cachedLastBlocks),
257-
lvPointerCache: lru.NewCache[uint64, uint64](cachedLvPointers),
258-
baseRowsCache: lru.NewCache[uint64, [][]uint32](cachedBaseRows),
259-
renderSnapshots: lru.NewCache[uint64, *renderedMap](cachedRenderSnapshots),
257+
258+
historyCutoff: historyCutoff,
259+
finalBlock: finalBlock,
260+
matcherSyncCh: make(chan *FilterMapsMatcherBackend),
261+
matchers: make(map[*FilterMapsMatcherBackend]struct{}),
262+
filterMapCache: lru.NewCache[uint32, filterMap](cachedFilterMaps),
263+
lastBlockCache: lru.NewCache[uint32, lastBlockOfMap](cachedLastBlocks),
264+
lvPointerCache: lru.NewCache[uint64, uint64](cachedLvPointers),
265+
baseRowsCache: lru.NewCache[uint64, [][]uint32](cachedBaseRows),
266+
renderSnapshots: lru.NewCache[uint64, *renderedMap](cachedRenderSnapshots),
260267
}
261268

262269
// Set initial indexer target.
@@ -444,6 +451,7 @@ func (f *FilterMaps) safeDeleteWithLogs(deleteFn func(db ethdb.KeyValueStore, ha
444451

445452
// setRange updates the indexed chain view and covered range and also adds the
446453
// changes to the given batch.
454+
//
447455
// Note that this function assumes that the index write lock is being held.
448456
func (f *FilterMaps) setRange(batch ethdb.KeyValueWriter, newView *ChainView, newRange filterMapsRange, isTempRange bool) {
449457
f.indexedView = newView
@@ -477,6 +485,7 @@ func (f *FilterMaps) setRange(batch ethdb.KeyValueWriter, newView *ChainView, ne
477485
// Note that this function assumes that the log index structure is consistent
478486
// with the canonical chain at the point where the given log value index points.
479487
// If this is not the case then an invalid result or an error may be returned.
488+
//
480489
// Note that this function assumes that the indexer read lock is being held when
481490
// called from outside the indexerLoop goroutine.
482491
func (f *FilterMaps) getLogByLvIndex(lvIndex uint64) (*types.Log, error) {
@@ -655,6 +664,7 @@ func (f *FilterMaps) mapRowIndex(mapIndex, rowIndex uint32) uint64 {
655664
// getBlockLvPointer returns the starting log value index where the log values
656665
// generated by the given block are located. If blockNumber is beyond the current
657666
// head then the first unoccupied log value index is returned.
667+
//
658668
// Note that this function assumes that the indexer read lock is being held when
659669
// called from outside the indexerLoop goroutine.
660670
func (f *FilterMaps) getBlockLvPointer(blockNumber uint64) (uint64, error) {
@@ -762,7 +772,7 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) {
762772
return false, errors.New("invalid tail epoch number")
763773
}
764774
// remove index data
765-
if err := f.safeDeleteWithLogs(func(db ethdb.KeyValueStore, hashScheme bool, stopCb func(bool) bool) error {
775+
deleteFn := func(db ethdb.KeyValueStore, hashScheme bool, stopCb func(bool) bool) error {
766776
first := f.mapRowIndex(firstMap, 0)
767777
count := f.mapRowIndex(firstMap+f.mapsPerEpoch, 0) - first
768778
if err := rawdb.DeleteFilterMapRows(f.db, common.NewRange(first, count), hashScheme, stopCb); err != nil {
@@ -786,10 +796,13 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) {
786796
f.lvPointerCache.Remove(blockNumber)
787797
}
788798
return nil
789-
}, fmt.Sprintf("Deleting tail epoch #%d", epoch), func() bool {
799+
}
800+
action := fmt.Sprintf("Deleting tail epoch #%d", epoch)
801+
stopFn := func() bool {
790802
f.processEvents()
791803
return f.stop || !f.targetHeadIndexed()
792-
}); err == nil {
804+
}
805+
if err := f.safeDeleteWithLogs(deleteFn, action, stopFn); err == nil {
793806
// everything removed; mark as cleaned and report success
794807
if f.cleanedEpochsBefore == epoch {
795808
f.cleanedEpochsBefore = epoch + 1
@@ -808,6 +821,9 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) {
808821
}
809822

810823
// exportCheckpoints exports epoch checkpoints in the format used by checkpoints.go.
824+
//
825+
// Note: acquiring the indexLock read lock is unnecessary here, as this function
826+
// is always called within the indexLoop.
811827
func (f *FilterMaps) exportCheckpoints() {
812828
finalLvPtr, err := f.getBlockLvPointer(f.finalBlock + 1)
813829
if err != nil {

core/filtermaps/indexer.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ func (f *FilterMaps) indexerLoop() {
4343
log.Info("Started log indexer")
4444

4545
for !f.stop {
46+
// Note: acquiring the indexLock read lock is unnecessary here,
47+
// as the `indexedRange` is accessed within the indexerLoop.
4648
if !f.indexedRange.initialized {
4749
if f.targetView.HeadNumber() == 0 {
4850
// initialize when chain head is available
@@ -105,7 +107,7 @@ type targetUpdate struct {
105107
historyCutoff, finalBlock uint64
106108
}
107109

108-
// SetTargetView sets a new target chain view for the indexer to render.
110+
// SetTarget sets a new target chain view for the indexer to render.
109111
// Note that SetTargetView never blocks.
110112
func (f *FilterMaps) SetTarget(targetView *ChainView, historyCutoff, finalBlock uint64) {
111113
if targetView == nil {
@@ -178,6 +180,8 @@ func (f *FilterMaps) processSingleEvent(blocking bool) bool {
178180
if f.stop {
179181
return false
180182
}
183+
// Note: acquiring the indexLock read lock is unnecessary here,
184+
// as this function is always called within the indexLoop.
181185
if !f.hasTempRange {
182186
for _, mb := range f.matcherSyncRequests {
183187
mb.synced()

core/filtermaps/matcher_backend.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,17 @@ func (fm *FilterMapsMatcherBackend) GetLogByLvIndex(ctx context.Context, lvIndex
111111
// synced signals to the matcher that has triggered a synchronisation that it
112112
// has been finished and the log index is consistent with the chain head passed
113113
// as a parameter.
114+
//
114115
// Note that if the log index head was far behind the chain head then it might not
115116
// be synced up to the given head in a single step. Still, the latest chain head
116117
// should be passed as a parameter and the existing log index should be consistent
117118
// with that chain.
119+
//
120+
// Note: acquiring the indexLock read lock is unnecessary here, as this function
121+
// is always called within the indexLoop.
118122
func (fm *FilterMapsMatcherBackend) synced() {
119-
fm.f.indexLock.RLock()
120123
fm.f.matchersLock.Lock()
121-
defer func() {
122-
fm.f.matchersLock.Unlock()
123-
fm.f.indexLock.RUnlock()
124-
}()
124+
defer fm.f.matchersLock.Unlock()
125125

126126
indexedBlocks := fm.f.indexedRange.blocks
127127
if !fm.f.indexedRange.headIndexed && !indexedBlocks.IsEmpty() {
@@ -154,6 +154,8 @@ func (fm *FilterMapsMatcherBackend) SyncLogIndex(ctx context.Context) (SyncRange
154154
case <-ctx.Done():
155155
return SyncRange{}, ctx.Err()
156156
case <-fm.f.disabledCh:
157+
// Note: acquiring the indexLock read lock is unnecessary here,
158+
// as the indexer has already been terminated.
157159
return SyncRange{IndexedView: fm.f.indexedView}, nil
158160
}
159161
select {
@@ -162,6 +164,8 @@ func (fm *FilterMapsMatcherBackend) SyncLogIndex(ctx context.Context) (SyncRange
162164
case <-ctx.Done():
163165
return SyncRange{}, ctx.Err()
164166
case <-fm.f.disabledCh:
167+
// Note: acquiring the indexLock read lock is unnecessary here,
168+
// as the indexer has already been terminated.
165169
return SyncRange{IndexedView: fm.f.indexedView}, nil
166170
}
167171
}
@@ -170,7 +174,9 @@ func (fm *FilterMapsMatcherBackend) SyncLogIndex(ctx context.Context) (SyncRange
170174
// valid range with the current indexed range. This function should be called
171175
// whenever a part of the log index has been removed, before adding new blocks
172176
// to it.
173-
// Note that this function assumes that the index read lock is being held.
177+
//
178+
// Note: acquiring the indexLock read lock is unnecessary here, as this function
179+
// is always called within the indexLoop.
174180
func (f *FilterMaps) updateMatchersValidRange() {
175181
f.matchersLock.Lock()
176182
defer f.matchersLock.Unlock()

core/state_processor_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,8 @@ func TestStateProcessorErrors(t *testing.T) {
255255
},
256256
want: "could not apply tx 0 [0xc18d10f4c809dbdfa1a074c3300de9bc4b7f16a20f0ec667f6f67312b71b956a]: EIP-7702 transaction with empty auth list (sender 0x71562b71999873DB5b286dF957af199Ec94617F7)",
257257
},
258-
// ErrSetCodeTxCreate cannot be tested: it is impossible to create a SetCode-tx with nil `to`.
258+
// ErrSetCodeTxCreate cannot be tested here: it is impossible to create a SetCode-tx with nil `to`.
259+
// The EstimateGas API tests test this case.
259260
} {
260261
block := GenerateBadBlock(gspec.ToBlock(), beacon.New(ethash.NewFaker()), tt.txs, gspec.Config, false)
261262
_, err := blockchain.InsertChain(types.Blocks{block})

ethclient/ethclient.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,9 @@ func toCallArg(msg ethereum.CallMsg) interface{} {
754754
if msg.BlobHashes != nil {
755755
arg["blobVersionedHashes"] = msg.BlobHashes
756756
}
757+
if msg.AuthorizationList != nil {
758+
arg["authorizationList"] = msg.AuthorizationList
759+
}
757760
return arg
758761
}
759762

ethclient/gethclient/gethclient.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@ func toCallArg(msg ethereum.CallMsg) interface{} {
251251
if msg.BlobHashes != nil {
252252
arg["blobVersionedHashes"] = msg.BlobHashes
253253
}
254+
if msg.AuthorizationList != nil {
255+
arg["authorizationList"] = msg.AuthorizationList
256+
}
254257
return arg
255258
}
256259

interfaces.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ type CallMsg struct {
156156
// For BlobTxType
157157
BlobGasFeeCap *big.Int
158158
BlobHashes []common.Hash
159+
160+
// For SetCodeTxType
161+
AuthorizationList []types.SetCodeAuthorization
159162
}
160163

161164
// A ContractCaller provides contract calls, essentially transactions that are executed by

internal/ethapi/api_test.go

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,11 @@ func TestEstimateGas(t *testing.T) {
668668
b.SetPoS()
669669
}))
670670

671+
setCodeAuthorization, _ := types.SignSetCode(accounts[0].key, types.SetCodeAuthorization{
672+
Address: accounts[0].addr,
673+
Nonce: uint64(genBlocks + 1),
674+
})
675+
671676
var testSuite = []struct {
672677
blockNumber rpc.BlockNumber
673678
call TransactionArgs
@@ -846,6 +851,50 @@ func TestEstimateGas(t *testing.T) {
846851
},
847852
want: 21000,
848853
},
854+
// Should be able to estimate SetCodeTx.
855+
{
856+
blockNumber: rpc.LatestBlockNumber,
857+
call: TransactionArgs{
858+
From: &accounts[0].addr,
859+
To: &accounts[1].addr,
860+
Value: (*hexutil.Big)(big.NewInt(0)),
861+
AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization},
862+
},
863+
want: 46000,
864+
},
865+
// Should retrieve the code of 0xef0001 || accounts[0].addr and return an invalid opcode error.
866+
{
867+
blockNumber: rpc.LatestBlockNumber,
868+
call: TransactionArgs{
869+
From: &accounts[0].addr,
870+
To: &accounts[0].addr,
871+
Value: (*hexutil.Big)(big.NewInt(0)),
872+
AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization},
873+
},
874+
expectErr: errors.New("invalid opcode: opcode 0xef not defined"),
875+
},
876+
// SetCodeTx with empty authorization list should fail.
877+
{
878+
blockNumber: rpc.LatestBlockNumber,
879+
call: TransactionArgs{
880+
From: &accounts[0].addr,
881+
To: &common.Address{},
882+
Value: (*hexutil.Big)(big.NewInt(0)),
883+
AuthorizationList: []types.SetCodeAuthorization{},
884+
},
885+
expectErr: core.ErrEmptyAuthList,
886+
},
887+
// SetCodeTx with nil `to` should fail.
888+
{
889+
blockNumber: rpc.LatestBlockNumber,
890+
call: TransactionArgs{
891+
From: &accounts[0].addr,
892+
To: nil,
893+
Value: (*hexutil.Big)(big.NewInt(0)),
894+
AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization},
895+
},
896+
expectErr: core.ErrSetCodeTxCreate,
897+
},
849898
}
850899
for i, tc := range testSuite {
851900
result, err := api.EstimateGas(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides, &tc.blockOverrides)
@@ -855,7 +904,7 @@ func TestEstimateGas(t *testing.T) {
855904
continue
856905
}
857906
if !errors.Is(err, tc.expectErr) {
858-
if !reflect.DeepEqual(err, tc.expectErr) {
907+
if err.Error() != tc.expectErr.Error() {
859908
t.Errorf("test %d: error mismatch, want %v, have %v", i, tc.expectErr, err)
860909
}
861910
}

0 commit comments

Comments
 (0)