From 301bd9bbdd2d267ae7ed19d3735f6eee44e7f052 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 15 Mar 2023 10:59:42 +0200 Subject: [PATCH 1/5] make Blockchain public func of APIBackend --- arbitrum/apibackend.go | 66 +++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/arbitrum/apibackend.go b/arbitrum/apibackend.go index 6cd971009b..562499663d 100644 --- a/arbitrum/apibackend.go +++ b/arbitrum/apibackend.go @@ -129,7 +129,7 @@ func (a *APIBackend) GetAPIs(filterSystem *filters.FilterSystem) []rpc.API { return apis } -func (a *APIBackend) blockChain() *core.BlockChain { +func (a *APIBackend) BlockChain() *core.BlockChain { return a.b.arb.BlockChain() } @@ -170,7 +170,7 @@ func (a *APIBackend) FeeHistory( } nitroGenesis := rpc.BlockNumber(a.ChainConfig().ArbitrumChainParams.GenesisBlockNum) - newestBlock, latestBlock := a.blockChain().ClipToPostNitroGenesis(newestBlock) + newestBlock, latestBlock := a.BlockChain().ClipToPostNitroGenesis(newestBlock) maxFeeHistory := int(a.b.config.FeeHistoryMaxBlockCount) if blocks > maxFeeHistory { @@ -246,7 +246,7 @@ func (a *APIBackend) FeeHistory( currentTimestampGasUsed = 0 } - receipts := a.blockChain().GetReceiptsByHash(header.ReceiptHash) + receipts := a.BlockChain().GetReceiptsByHash(header.ReceiptHash) for _, receipt := range receipts { if receipt.GasUsed > receipt.GasUsedForL1 { currentTimestampGasUsed += receipt.GasUsed - receipt.GasUsedForL1 @@ -316,12 +316,12 @@ func (a *APIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) } func (a *APIBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { - return a.blockChain().GetHeaderByHash(hash), nil + return a.BlockChain().GetHeaderByHash(hash), nil } func (a *APIBackend) blockNumberToUint(ctx context.Context, number rpc.BlockNumber) (uint64, error) { if number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber { - return a.blockChain().CurrentBlock().Number().Uint64(), nil + return a.BlockChain().CurrentBlock().Number().Uint64(), nil } if number == rpc.SafeBlockNumber { return a.sync.SafeBlockNumber(ctx) @@ -337,13 +337,13 @@ func (a *APIBackend) blockNumberToUint(ctx context.Context, number rpc.BlockNumb func (a *APIBackend) headerByNumberImpl(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { if number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber { - return a.blockChain().CurrentBlock().Header(), nil + return a.BlockChain().CurrentBlock().Header(), nil } numUint, err := a.blockNumberToUint(ctx, number) if err != nil { return nil, err } - return a.blockChain().GetHeaderByNumber(numUint), nil + return a.BlockChain().GetHeaderByNumber(numUint), nil } func (a *APIBackend) headerByNumberOrHashImpl(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) { @@ -353,7 +353,7 @@ func (a *APIBackend) headerByNumberOrHashImpl(ctx context.Context, blockNrOrHash } hash, ishash := blockNrOrHash.Hash() if ishash { - return a.blockChain().GetHeaderByHash(hash), nil + return a.BlockChain().GetHeaderByHash(hash), nil } return nil, errors.New("invalid arguments; neither block nor hash specified") } @@ -363,26 +363,26 @@ func (a *APIBackend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc } func (a *APIBackend) CurrentHeader() *types.Header { - return a.blockChain().CurrentHeader() + return a.BlockChain().CurrentHeader() } func (a *APIBackend) CurrentBlock() *types.Block { - return a.blockChain().CurrentBlock() + return a.BlockChain().CurrentBlock() } func (a *APIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { if number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber { - return a.blockChain().CurrentBlock(), nil + return a.BlockChain().CurrentBlock(), nil } numUint, err := a.blockNumberToUint(ctx, number) if err != nil { return nil, err } - return a.blockChain().GetBlockByNumber(numUint), nil + return a.BlockChain().GetBlockByNumber(numUint), nil } func (a *APIBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { - return a.blockChain().GetBlockByHash(hash), nil + return a.BlockChain().GetBlockByHash(hash), nil } func (a *APIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) { @@ -404,10 +404,10 @@ func (a *APIBackend) stateAndHeaderFromHeader(header *types.Header, err error) ( if header == nil { return nil, nil, errors.New("header not found") } - if !a.blockChain().Config().IsArbitrumNitro(header.Number) { + if !a.BlockChain().Config().IsArbitrumNitro(header.Number) { return nil, header, types.ErrUseFallback } - state, err := a.blockChain().StateAt(header.Root) + state, err := a.BlockChain().StateAt(header.Root) return state, header, err } @@ -420,28 +420,28 @@ func (a *APIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOr } func (a *APIBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, checkLive bool, preferDisk bool) (statedb *state.StateDB, err error) { - if !a.blockChain().Config().IsArbitrumNitro(block.Number()) { + if !a.BlockChain().Config().IsArbitrumNitro(block.Number()) { return nil, types.ErrUseFallback } // DEV: This assumes that `StateAtBlock` only accesses the blockchain and chainDb fields - return eth.NewArbEthereum(a.b.arb.BlockChain(), a.ChainDb()).StateAtBlock(block, reexec, base, checkLive, preferDisk) + return eth.NewArbEthereum(a.BlockChain(), a.ChainDb()).StateAtBlock(block, reexec, base, checkLive, preferDisk) } func (a *APIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, error) { - if !a.blockChain().Config().IsArbitrumNitro(block.Number()) { + if !a.BlockChain().Config().IsArbitrumNitro(block.Number()) { return nil, vm.BlockContext{}, nil, types.ErrUseFallback } // DEV: This assumes that `StateAtTransaction` only accesses the blockchain and chainDb fields - return eth.NewArbEthereum(a.b.arb.BlockChain(), a.ChainDb()).StateAtTransaction(block, txIndex, reexec) + return eth.NewArbEthereum(a.BlockChain(), a.ChainDb()).StateAtTransaction(block, txIndex, reexec) } func (a *APIBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { - return a.blockChain().GetReceiptsByHash(hash), nil + return a.BlockChain().GetReceiptsByHash(hash), nil } func (a *APIBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int { - if header := a.blockChain().GetHeaderByHash(hash); header != nil { - return a.blockChain().GetTd(hash, header.Number.Uint64()) + if header := a.BlockChain().GetHeaderByHash(hash); header != nil { + return a.BlockChain().GetTd(hash, header.Number.Uint64()) } return nil } @@ -449,23 +449,23 @@ func (a *APIBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int { func (a *APIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error) { vmError := func() error { return nil } if vmConfig == nil { - vmConfig = a.blockChain().GetVMConfig() + vmConfig = a.BlockChain().GetVMConfig() } txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(header, a.blockChain(), nil) - return vm.NewEVM(context, txContext, state, a.blockChain().Config(), *vmConfig), vmError, nil + context := core.NewEVMBlockContext(header, a.BlockChain(), nil) + return vm.NewEVM(context, txContext, state, a.BlockChain().Config(), *vmConfig), vmError, nil } func (a *APIBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { - return a.blockChain().SubscribeChainEvent(ch) + return a.BlockChain().SubscribeChainEvent(ch) } func (a *APIBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription { - return a.blockChain().SubscribeChainHeadEvent(ch) + return a.BlockChain().SubscribeChainHeadEvent(ch) } func (a *APIBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription { - return a.blockChain().SubscribeChainSideEvent(ch) + return a.BlockChain().SubscribeChainSideEvent(ch) } // Transaction pool API @@ -489,7 +489,7 @@ func (a *APIBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction { } func (a *APIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) { - stateDB, err := a.blockChain().State() + stateDB, err := a.BlockChain().State() if err != nil { return 0, err } @@ -529,7 +529,7 @@ func (a *APIBackend) ServiceFilter(ctx context.Context, session *bloombits.Match } func (a *APIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { - return a.blockChain().SubscribeLogsEvent(ch) + return a.BlockChain().SubscribeLogsEvent(ch) } func (a *APIBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription { @@ -538,15 +538,15 @@ func (a *APIBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Sub } func (a *APIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { - return a.blockChain().SubscribeRemovedLogsEvent(ch) + return a.BlockChain().SubscribeRemovedLogsEvent(ch) } func (a *APIBackend) ChainConfig() *params.ChainConfig { - return a.blockChain().Config() + return a.BlockChain().Config() } func (a *APIBackend) Engine() consensus.Engine { - return a.blockChain().Engine() + return a.BlockChain().Engine() } func (b *APIBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) { From 49495e4020536a6acb8e1c065d725742b3493932 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 15 Mar 2023 14:27:42 +0200 Subject: [PATCH 2/5] arbitrum backend: set sync object after creation --- arbitrum/apibackend.go | 24 +++++++++++++++++++++--- arbitrum/backend.go | 4 ++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/arbitrum/apibackend.go b/arbitrum/apibackend.go index 562499663d..eac54d39cd 100644 --- a/arbitrum/apibackend.go +++ b/arbitrum/apibackend.go @@ -85,7 +85,7 @@ type SyncProgressBackend interface { FinalizedBlockNumber(ctx context.Context) (uint64, error) } -func createRegisterAPIBackend(backend *Backend, sync SyncProgressBackend, filterConfig filters.Config, fallbackClientUrl string, fallbackClientTimeout time.Duration) (*filters.FilterSystem, error) { +func createRegisterAPIBackend(backend *Backend, filterConfig filters.Config, fallbackClientUrl string, fallbackClientTimeout time.Duration) (*filters.FilterSystem, error) { fallbackClient, err := CreateFallbackClient(fallbackClientUrl, fallbackClientTimeout) if err != nil { return nil, err @@ -93,13 +93,20 @@ func createRegisterAPIBackend(backend *Backend, sync SyncProgressBackend, filter backend.apiBackend = &APIBackend{ b: backend, fallbackClient: fallbackClient, - sync: sync, } filterSystem := filters.NewFilterSystem(backend.apiBackend, filterConfig) backend.stack.RegisterAPIs(backend.apiBackend.GetAPIs(filterSystem)) return filterSystem, nil } +func (a *APIBackend) SetSyncBackend(sync SyncProgressBackend) error { + if a.sync != nil && sync != nil { + return errors.New("sync progress monitor already set") + } + a.sync = sync + return nil +} + func (a *APIBackend) GetAPIs(filterSystem *filters.FilterSystem) []rpc.API { apis := ethapi.GetAPIs(a) @@ -139,11 +146,16 @@ func (a *APIBackend) GetArbitrumNode() interface{} { // General Ethereum API func (a *APIBackend) SyncProgressMap() map[string]interface{} { + if a.sync == nil { + res := make(map[string]interface{}) + res["error"] = "sync object not set in apibackend" + return res + } return a.sync.SyncProgressMap() } func (a *APIBackend) SyncProgress() ethereum.SyncProgress { - progress := a.sync.SyncProgressMap() + progress := a.SyncProgressMap() if progress == nil || len(progress) == 0 { return ethereum.SyncProgress{} @@ -324,9 +336,15 @@ func (a *APIBackend) blockNumberToUint(ctx context.Context, number rpc.BlockNumb return a.BlockChain().CurrentBlock().Number().Uint64(), nil } if number == rpc.SafeBlockNumber { + if a.sync == nil { + return 0, errors.New("block number not supported: object not set") + } return a.sync.SafeBlockNumber(ctx) } if number == rpc.FinalizedBlockNumber { + if a.sync == nil { + return 0, errors.New("block number not supported: object not set") + } return a.sync.FinalizedBlockNumber(ctx) } if number < 0 { diff --git a/arbitrum/backend.go b/arbitrum/backend.go index c8ede8960f..3f376326a5 100644 --- a/arbitrum/backend.go +++ b/arbitrum/backend.go @@ -33,7 +33,7 @@ type Backend struct { chanNewBlock chan struct{} //create new L2 block unless empty } -func NewBackend(stack *node.Node, config *Config, chainDb ethdb.Database, publisher ArbInterface, sync SyncProgressBackend, filterConfig filters.Config) (*Backend, *filters.FilterSystem, error) { +func NewBackend(stack *node.Node, config *Config, chainDb ethdb.Database, publisher ArbInterface, filterConfig filters.Config) (*Backend, *filters.FilterSystem, error) { backend := &Backend{ arb: publisher, stack: stack, @@ -51,7 +51,7 @@ func NewBackend(stack *node.Node, config *Config, chainDb ethdb.Database, publis } backend.bloomIndexer.Start(backend.arb.BlockChain()) - filterSystem, err := createRegisterAPIBackend(backend, sync, filterConfig, config.ClassicRedirect, config.ClassicRedirectTimeout) + filterSystem, err := createRegisterAPIBackend(backend, filterConfig, config.ClassicRedirect, config.ClassicRedirectTimeout) if err != nil { return nil, nil, err } From ce5c50156406f408cc6fc80575c99db1d4d9b2f0 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 15 Mar 2023 18:49:38 +0200 Subject: [PATCH 3/5] error instead of panic in ReorgToOldBlock --- core/blockchain_arbitrum.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/blockchain_arbitrum.go b/core/blockchain_arbitrum.go index 7e8a852389..fb0a69a5b7 100644 --- a/core/blockchain_arbitrum.go +++ b/core/blockchain_arbitrum.go @@ -18,6 +18,7 @@ package core import ( + "errors" "time" "github.com/ethereum/go-ethereum/core/state" @@ -39,7 +40,10 @@ func (bc *BlockChain) WriteBlockAndSetHeadWithTime(block *types.Block, receipts func (bc *BlockChain) ReorgToOldBlock(newHead *types.Block) error { bc.wg.Add(1) defer bc.wg.Done() - bc.chainmu.MustLock() + locked := bc.chainmu.TryLock() + if !locked { + return errors.New("couldn't catch lock to reorg") + } defer bc.chainmu.Unlock() oldHead := bc.CurrentBlock() if oldHead.Hash() == newHead.Hash() { From 7ea707239f34fc2fa56be4b1b97a470f00cab600 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 14 Jun 2023 18:44:18 -0600 Subject: [PATCH 4/5] fix merge --- arbitrum/apibackend.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum/apibackend.go b/arbitrum/apibackend.go index f132b3c0ec..e0ed791e2c 100644 --- a/arbitrum/apibackend.go +++ b/arbitrum/apibackend.go @@ -406,7 +406,7 @@ func (a *APIBackend) CurrentBlock() *types.Header { func (a *APIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { if number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber { currentHeader := a.BlockChain().CurrentBlock() - currentBlock := a.blockChain().GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64()) + currentBlock := a.BlockChain().GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64()) if currentBlock == nil { return nil, errors.New("can't find block for current header") } From b4221631e1e5eac86f01582bd74234e3c0f7f5c7 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 4 Oct 2023 10:55:06 -0600 Subject: [PATCH 5/5] apibakcend: cannot unset syncbackend --- arbitrum/apibackend.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum/apibackend.go b/arbitrum/apibackend.go index 3b95af0cf4..4d5c308dc8 100644 --- a/arbitrum/apibackend.go +++ b/arbitrum/apibackend.go @@ -101,7 +101,7 @@ func createRegisterAPIBackend(backend *Backend, filterConfig filters.Config, fal } func (a *APIBackend) SetSyncBackend(sync SyncProgressBackend) error { - if a.sync != nil && sync != nil { + if a.sync != nil { return errors.New("sync progress monitor already set") } a.sync = sync