Skip to content

Commit a551686

Browse files
authored
Merge branch 'master' into merge-v1.14.5
2 parents 78c81ea + 0ec8e93 commit a551686

17 files changed

+194
-20
lines changed

arbitrum/apibackend.go

Lines changed: 32 additions & 0 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,
@@ -96,6 +123,7 @@ type SyncProgressBackend interface {
96123
SyncProgressMap() map[string]interface{}
97124
SafeBlockNumber(ctx context.Context) (uint64, error)
98125
FinalizedBlockNumber(ctx context.Context) (uint64, error)
126+
BlockMetadataByNumber(blockNum uint64) (common.BlockMetadata, error)
99127
}
100128

101129
func createRegisterAPIBackend(backend *Backend, filterConfig filters.Config, fallbackClientUrl string, fallbackClientTimeout time.Duration) (*filters.FilterSystem, error) {
@@ -460,6 +488,10 @@ func (a *APIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.
460488
return nil, errors.New("invalid arguments; neither block nor hash specified")
461489
}
462490

491+
func (a *APIBackend) BlockMetadataByNumber(blockNum uint64) (common.BlockMetadata, error) {
492+
return a.sync.BlockMetadataByNumber(blockNum)
493+
}
494+
463495
func StateAndHeaderFromHeader(ctx context.Context, chainDb ethdb.Database, bc *core.BlockChain, maxRecreateStateDepth int64, header *types.Header, err error) (*state.StateDB, *types.Header, error) {
464496
if err != nil {
465497
return nil, header, err

arbitrum/recordingdb.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ func (r *RecordingDatabase) StateFor(header *types.Header) (*state.StateDB, erro
194194
r.mutex.Lock()
195195
defer r.mutex.Unlock()
196196

197-
sdb, err := state.NewDeterministic(header.Root, r.db)
197+
sdb, err := state.NewRecording(header.Root, r.db)
198198
if err == nil {
199199
r.referenceRootLockHeld(header.Root)
200200
}
@@ -267,7 +267,7 @@ func (r *RecordingDatabase) PrepareRecording(ctx context.Context, lastBlockHeade
267267
if lastBlockHeader != nil {
268268
prevRoot = lastBlockHeader.Root
269269
}
270-
recordingStateDb, err := state.NewDeterministic(prevRoot, recordingStateDatabase)
270+
recordingStateDb, err := state.NewRecording(prevRoot, recordingStateDatabase)
271271
if err != nil {
272272
return nil, nil, nil, fmt.Errorf("failed to create recordingStateDb: %w", err)
273273
}

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
@@ -78,6 +78,9 @@ var (
7878

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

81+
triedbSizeGauge = metrics.NewRegisteredGauge("chain/triedb/size", nil)
82+
triedbGCProcGauge = metrics.NewRegisteredGauge("chain/triedb/gcproc", nil)
83+
8184
blockInsertTimer = metrics.NewRegisteredResettingTimer("chain/inserts", nil)
8285
blockValidationTimer = metrics.NewRegisteredResettingTimer("chain/validation", nil)
8386
blockExecutionTimer = metrics.NewRegisteredResettingTimer("chain/execution", nil)
@@ -1654,6 +1657,11 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
16541657
bc.triedb.Dereference(prevEntry.Root)
16551658
}
16561659
}
1660+
1661+
_, dirtyNodesBufferedSize, _ := bc.triedb.Size()
1662+
triedbSizeGauge.Update(int64(dirtyNodesBufferedSize))
1663+
triedbGCProcGauge.Update(int64(bc.gcproc))
1664+
16571665
return nil
16581666
}
16591667

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() {

core/state/snapshot/disklayer.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,30 +76,28 @@ func (dl *diskLayer) Stale() bool {
7676

7777
// Account directly retrieves the account associated with a particular hash in
7878
// the snapshot slim data format.
79-
func (dl *diskLayer) Account(hash common.Hash) (*types.SlimAccount, error) {
80-
data, err := dl.AccountRLP(hash)
79+
func (dl *diskLayer) account(hash common.Hash, evenIfStale bool) (*types.SlimAccount, error) {
80+
data, err := dl.accountRLP(hash, evenIfStale)
8181
if err != nil {
8282
return nil, err
8383
}
8484
if len(data) == 0 { // can be both nil and []byte{}
8585
return nil, nil
8686
}
8787
account := new(types.SlimAccount)
88-
if err := rlp.DecodeBytes(data, account); err != nil {
89-
panic(err)
90-
}
91-
return account, nil
88+
err = rlp.DecodeBytes(data, account)
89+
return account, err
9290
}
9391

9492
// AccountRLP directly retrieves the account RLP associated with a particular
9593
// hash in the snapshot slim data format.
96-
func (dl *diskLayer) AccountRLP(hash common.Hash) ([]byte, error) {
94+
func (dl *diskLayer) accountRLP(hash common.Hash, evenIfStale bool) ([]byte, error) {
9795
dl.lock.RLock()
9896
defer dl.lock.RUnlock()
9997

10098
// If the layer was flattened into, consider it invalid (any live reference to
10199
// the original should be marked as unusable).
102-
if dl.stale {
100+
if dl.stale && !evenIfStale {
103101
return nil, ErrSnapshotStale
104102
}
105103
// If the layer is being generated, ensure the requested hash has already been
@@ -121,7 +119,9 @@ func (dl *diskLayer) AccountRLP(hash common.Hash) ([]byte, error) {
121119
if err != nil {
122120
return nil, err
123121
}
124-
dl.cache.Set(hash[:], blob)
122+
if !dl.stale {
123+
dl.cache.Set(hash[:], blob)
124+
}
125125

126126
snapshotCleanAccountMissMeter.Mark(1)
127127
if n := len(blob); n > 0 {
@@ -132,6 +132,14 @@ func (dl *diskLayer) AccountRLP(hash common.Hash) ([]byte, error) {
132132
return blob, nil
133133
}
134134

135+
func (dl *diskLayer) Account(hash common.Hash) (*types.SlimAccount, error) {
136+
return dl.account(hash, false)
137+
}
138+
139+
func (dl *diskLayer) AccountRLP(hash common.Hash) ([]byte, error) {
140+
return dl.accountRLP(hash, false)
141+
}
142+
135143
// Storage directly retrieves the storage data associated with a particular hash,
136144
// within a particular account.
137145
func (dl *diskLayer) Storage(accountHash, storageHash common.Hash) ([]byte, error) {

core/state/snapshot/snapshot.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,10 +564,23 @@ func diffToDisk(bottom *diffLayer) *diskLayer {
564564
if base.genMarker != nil && bytes.Compare(hash[:], base.genMarker) > 0 {
565565
continue
566566
}
567-
// Remove all storage slots
567+
568+
oldAccount, err := base.account(hash, true)
569+
570+
// Delete the account snapshot
568571
rawdb.DeleteAccountSnapshot(batch, hash)
569572
base.cache.Set(hash[:], nil)
570573

574+
// Try to check if there's any associated storage to delete from the snapshot
575+
if err != nil {
576+
log.Warn("Failed to get destructed account from snapshot", "err", err)
577+
// Fall through to deleting storage in case this account has any
578+
} else if oldAccount == nil || oldAccount.Root == nil {
579+
// There's no storage associated with this account to delete
580+
continue
581+
}
582+
583+
// Remove all storage slots
571584
it := rawdb.IterateStorageSnapshots(base.diskdb, hash)
572585
for it.Next() {
573586
key := it.Key()

core/state/statedb.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ type StateDB struct {
170170
StorageDeleted atomic.Int64
171171

172172
deterministic bool
173+
recording bool
173174
}
174175

175176
// New creates a new state from a given trie.
@@ -949,6 +950,21 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
949950
usedAddrs [][]byte
950951
deletedAddrs []common.Address
951952
)
953+
// When recording, it's important to handle deletions before other mutations
954+
// to ensure that access the most state possible in the database. If, instead,
955+
// the updates were applied before the deletions, it might be possible to
956+
// record an update for an address that would then be subsequently deleted.
957+
if s.recording {
958+
for addr, op := range s.mutations {
959+
if op.applied {
960+
continue
961+
}
962+
if op.isDelete() {
963+
op.applied = true
964+
s.deleteStateObject(addr)
965+
}
966+
}
967+
}
952968
for addr, op := range s.mutations {
953969
if op.applied {
954970
continue

core/state/statedb_arbitrum.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,16 @@ func NewDeterministic(root common.Hash, db Database) (*StateDB, error) {
160160
return sdb, nil
161161
}
162162

163+
func NewRecording(root common.Hash, db Database) (*StateDB, error) {
164+
sdb, err := New(root, db, nil)
165+
if err != nil {
166+
return nil, err
167+
}
168+
sdb.deterministic = true
169+
sdb.recording = true
170+
return sdb, nil
171+
}
172+
163173
func (s *StateDB) Deterministic() bool {
164174
return s.deterministic
165175
}

eth/api_backend.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r
182182
return nil, errors.New("invalid arguments; neither block nor hash specified")
183183
}
184184

185+
func (b *EthAPIBackend) BlockMetadataByNumber(blockNum uint64) (common.BlockMetadata, error) {
186+
return nil, nil
187+
}
188+
185189
func (b *EthAPIBackend) Pending() (*types.Block, types.Receipts, *state.StateDB) {
186190
return b.eth.miner.Pending()
187191
}

eth/tracers/native/call_flat.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ func (t *flatCallTracer) OnExit(depth int, output []byte, gasUsed uint64, err er
195195
if t.config.IncludePrecompiles {
196196
return
197197
}
198+
if len(t.tracer.callstack[len(t.tracer.callstack)-1].Calls) == 0 {
199+
return
200+
}
198201
var (
199202
// call has been nested in parent
200203
parent = t.tracer.callstack[len(t.tracer.callstack)-1]

internal/ethapi/api.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1308,7 +1308,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr
13081308
call := args.ToMessage(header.BaseFee, gasCap, header, state, core.MessageGasEstimationMode)
13091309

13101310
// Arbitrum: raise the gas cap to ignore L1 costs so that it's compute-only
1311-
{
1311+
if gasCap > 0 {
13121312
postingGas, err := core.RPCPostingGasHook(call, header, state)
13131313
if err != nil {
13141314
return 0, err
@@ -1988,6 +1988,17 @@ func marshalReceipt(ctx context.Context, receipt *types.Receipt, blockHash commo
19881988
fields["l1BlockNumber"] = hexutil.Uint64(arbTx.L1BlockNumber)
19891989
}
19901990
}
1991+
1992+
blockMetadata, err := backend.BlockMetadataByNumber(blockNumber)
1993+
if err != nil {
1994+
return nil, err
1995+
}
1996+
if blockMetadata != nil {
1997+
fields["timeboosted"], err = blockMetadata.IsTxTimeboosted(txIndex)
1998+
if err != nil {
1999+
log.Error("Error checking if a tx was timeboosted", "txIndex", txIndex, "txHash", tx.Hash(), "err", err)
2000+
}
2001+
}
19912002
}
19922003
return fields, nil
19932004
}

internal/ethapi/api_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,9 @@ func (b testBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.
527527
}
528528
panic("unknown type rpc.BlockNumberOrHash")
529529
}
530+
func (b testBackend) BlockMetadataByNumber(blockNum uint64) (common.BlockMetadata, error) {
531+
return nil, nil
532+
}
530533
func (b testBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {
531534
return b.chain.GetBlock(hash, uint64(number.Int64())).Body(), nil
532535
}

internal/ethapi/backend.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ type Backend interface {
6767
BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
6868
BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
6969
BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error)
70+
BlockMetadataByNumber(blockNum uint64) (common.BlockMetadata, error)
7071
StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error)
7172
StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error)
7273
Pending() (*types.Block, types.Receipts, *state.StateDB)

0 commit comments

Comments
 (0)