Skip to content

Commit bae0024

Browse files
authored
Merge branch 'master' into merge-v1.14.7
2 parents 7455a86 + 9f3ca3f commit bae0024

31 files changed

+447
-132
lines changed

arbitrum/apibackend.go

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"math/big"
8+
"net/url"
89
"strconv"
910
"strings"
1011
"time"
@@ -51,6 +52,22 @@ type APIBackend struct {
5152
sync SyncProgressBackend
5253
}
5354

55+
type errorFilteredFallbackClient struct {
56+
impl types.FallbackClient
57+
url string
58+
}
59+
60+
func (c *errorFilteredFallbackClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
61+
err := c.impl.CallContext(ctx, result, method, args...)
62+
if err != nil && strings.Contains(err.Error(), c.url) {
63+
// avoids leaking the URL in the error message.
64+
// URL can contain sensitive information such as API keys.
65+
log.Warn("fallback client error", "error", err)
66+
return errors.New("Failed to call fallback API")
67+
}
68+
return err
69+
}
70+
5471
type timeoutFallbackClient struct {
5572
impl types.FallbackClient
5673
timeout time.Duration
@@ -77,12 +94,22 @@ func CreateFallbackClient(fallbackClientUrl string, fallbackClientTimeout time.D
7794
types.SetFallbackError(strings.Join(fields, ":"), int(errNumber))
7895
return nil, nil
7996
}
97+
8098
var fallbackClient types.FallbackClient
8199
var err error
82100
fallbackClient, err = rpc.Dial(fallbackClientUrl)
83101
if err != nil {
84102
return nil, fmt.Errorf("failed creating fallback connection: %w", err)
85103
}
104+
url, err := url.Parse(fallbackClientUrl)
105+
if err != nil {
106+
return nil, fmt.Errorf("failed parsing fallback URL: %w", err)
107+
}
108+
fallbackClient = &errorFilteredFallbackClient{
109+
impl: fallbackClient,
110+
url: url.String(),
111+
}
112+
86113
if fallbackClientTimeout != 0 {
87114
fallbackClient = &timeoutFallbackClient{
88115
impl: fallbackClient,
@@ -94,8 +121,7 @@ func CreateFallbackClient(fallbackClientUrl string, fallbackClientTimeout time.D
94121

95122
type SyncProgressBackend interface {
96123
SyncProgressMap() map[string]interface{}
97-
SafeBlockNumber(ctx context.Context) (uint64, error)
98-
FinalizedBlockNumber(ctx context.Context) (uint64, error)
124+
BlockMetadataByNumber(blockNum uint64) (common.BlockMetadata, error)
99125
}
100126

101127
func createRegisterAPIBackend(backend *Backend, filterConfig filters.Config, fallbackClientUrl string, fallbackClientTimeout time.Duration) (*filters.FilterSystem, error) {
@@ -379,13 +405,23 @@ func (a *APIBackend) blockNumberToUint(ctx context.Context, number rpc.BlockNumb
379405
if a.sync == nil {
380406
return 0, errors.New("block number not supported: object not set")
381407
}
382-
return a.sync.SafeBlockNumber(ctx)
408+
409+
currentSafeBlock := a.BlockChain().CurrentSafeBlock()
410+
if currentSafeBlock == nil {
411+
return 0, errors.New("safe block not found")
412+
}
413+
return currentSafeBlock.Number.Uint64(), nil
383414
}
384415
if number == rpc.FinalizedBlockNumber {
385416
if a.sync == nil {
386417
return 0, errors.New("block number not supported: object not set")
387418
}
388-
return a.sync.FinalizedBlockNumber(ctx)
419+
420+
currentFinalizedBlock := a.BlockChain().CurrentFinalBlock()
421+
if currentFinalizedBlock == nil {
422+
return 0, errors.New("finalized block not found")
423+
}
424+
return currentFinalizedBlock.Number.Uint64(), nil
389425
}
390426
if number < 0 {
391427
return 0, errors.New("block number not supported")
@@ -460,6 +496,10 @@ func (a *APIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.
460496
return nil, errors.New("invalid arguments; neither block nor hash specified")
461497
}
462498

499+
func (a *APIBackend) BlockMetadataByNumber(blockNum uint64) (common.BlockMetadata, error) {
500+
return a.sync.BlockMetadataByNumber(blockNum)
501+
}
502+
463503
func StateAndHeaderFromHeader(ctx context.Context, chainDb ethdb.Database, bc *core.BlockChain, maxRecreateStateDepth int64, header *types.Header, err error) (*state.StateDB, *types.Header, error) {
464504
if err != nil {
465505
return nil, header, err

arbitrum/recordingdb.go

Lines changed: 7 additions & 3 deletions
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
}
@@ -190,7 +194,7 @@ func (r *RecordingDatabase) StateFor(header *types.Header) (*state.StateDB, erro
190194
r.mutex.Lock()
191195
defer r.mutex.Unlock()
192196

193-
sdb, err := state.NewDeterministic(header.Root, r.db)
197+
sdb, err := state.NewRecording(header.Root, r.db)
194198
if err == nil {
195199
r.referenceRootLockHeld(header.Root)
196200
}
@@ -263,7 +267,7 @@ func (r *RecordingDatabase) PrepareRecording(ctx context.Context, lastBlockHeade
263267
if lastBlockHeader != nil {
264268
prevRoot = lastBlockHeader.Root
265269
}
266-
recordingStateDb, err := state.NewDeterministic(prevRoot, recordingStateDatabase)
270+
recordingStateDb, err := state.NewRecording(prevRoot, recordingStateDatabase)
267271
if err != nil {
268272
return nil, nil, nil, fmt.Errorf("failed to create recordingStateDb: %w", err)
269273
}

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+
}

common/types.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,3 +486,24 @@ func (b PrettyBytes) TerminalString() string {
486486
}
487487
return fmt.Sprintf("%#x...%x (%dB)", b[:3], b[len(b)-3:], len(b))
488488
}
489+
490+
type BlockMetadata []byte
491+
492+
// IsTxTimeboosted given a tx's index in the block returns whether the tx was timeboosted
493+
// or not. The first byte of blockMetadata byte array is reserved to indicate the version,
494+
// starting from the second byte, (N)th bit would represent if (N)th tx is timeboosted or not, 1 means yes and 0 means no
495+
// blockMetadata[index / 8 + 1] & (1 << (index % 8)) != 0; where index = (N - 1), implies whether (N)th tx in a block is timeboosted
496+
// note that number of txs in a block will always lag behind (len(blockMetadata) - 1) * 8 but it wont lag more than a value of 7
497+
func (b BlockMetadata) IsTxTimeboosted(txIndex int) (bool, error) {
498+
if len(b) == 0 {
499+
return false, errors.New("blockMetadata is not set")
500+
}
501+
if txIndex < 0 {
502+
return false, fmt.Errorf("invalid transaction index- %d, should be positive", txIndex)
503+
}
504+
maxTxCount := (len(b) - 1) * 8
505+
if txIndex >= maxTxCount {
506+
return false, nil
507+
}
508+
return b[1+(txIndex/8)]&(1<<(txIndex%8)) != 0, nil
509+
}

core/blockchain.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ var (
7979

8080
triedbCommitTimer = metrics.NewRegisteredResettingTimer("chain/triedb/commits", nil)
8181

82+
triedbSizeGauge = metrics.NewRegisteredGauge("chain/triedb/size", nil)
83+
triedbGCProcGauge = metrics.NewRegisteredGauge("chain/triedb/gcproc", nil)
84+
8285
blockInsertTimer = metrics.NewRegisteredResettingTimer("chain/inserts", nil)
8386
blockValidationTimer = metrics.NewRegisteredResettingTimer("chain/validation", nil)
8487
blockExecutionTimer = metrics.NewRegisteredResettingTimer("chain/execution", nil)
@@ -1656,6 +1659,11 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
16561659
bc.triedb.Dereference(prevEntry.Root)
16571660
}
16581661
}
1662+
1663+
_, dirtyNodesBufferedSize, _ := bc.triedb.Size()
1664+
triedbSizeGauge.Update(int64(dirtyNodesBufferedSize))
1665+
triedbGCProcGauge.Update(int64(bc.gcproc))
1666+
16591667
return nil
16601668
}
16611669

core/blockchain_arbitrum.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,50 @@ import (
2121
"fmt"
2222
"time"
2323

24+
"github.com/ethereum/go-ethereum/common"
25+
"github.com/ethereum/go-ethereum/core/rawdb"
2426
"github.com/ethereum/go-ethereum/core/state"
2527
"github.com/ethereum/go-ethereum/core/types"
2628
"github.com/ethereum/go-ethereum/log"
2729
"github.com/ethereum/go-ethereum/rpc"
2830
)
2931

32+
func (bc *BlockChain) FlushTrieDB(capLimit common.StorageSize) error {
33+
if bc.triedb.Scheme() == rawdb.PathScheme {
34+
return nil
35+
}
36+
37+
if !bc.chainmu.TryLock() {
38+
return errChainStopped
39+
}
40+
defer bc.chainmu.Unlock()
41+
42+
if !bc.triegc.Empty() {
43+
_, triegcBlockNumber := bc.triegc.Peek()
44+
blockNumber := uint64(-triegcBlockNumber)
45+
46+
header := bc.GetHeaderByNumber(blockNumber)
47+
if header == nil {
48+
log.Warn("Reorg in progress, trie commit postponed")
49+
} else {
50+
err := bc.triedb.Commit(header.Root, true)
51+
if err != nil {
52+
return err
53+
}
54+
55+
bc.gcproc = 0
56+
bc.lastWrite = blockNumber
57+
}
58+
}
59+
60+
err := bc.triedb.Cap(capLimit)
61+
if err != nil {
62+
return err
63+
}
64+
65+
return nil
66+
}
67+
3068
// WriteBlockAndSetHeadWithTime also counts processTime, which will cause intermittent TrieDirty cache writes
3169
func (bc *BlockChain) WriteBlockAndSetHeadWithTime(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool, processTime time.Duration) (status WriteStatus, err error) {
3270
if !bc.chainmu.TryLock() {

0 commit comments

Comments
 (0)