Skip to content

Commit

Permalink
Merge pull request #238 from OffchainLabs/execution-split
Browse files Browse the repository at this point in the history
Execution split support
  • Loading branch information
PlasmaPower authored Oct 4, 2023
2 parents abfeebc + b422163 commit 8919ab3
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 38 deletions.
88 changes: 53 additions & 35 deletions arbitrum/apibackend.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,21 +86,28 @@ 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
}
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 {
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)

Expand Down Expand Up @@ -137,7 +144,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()
}

Expand All @@ -146,19 +153,24 @@ func (a *APIBackend) GetArbitrumNode() interface{} {
}

func (a *APIBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {
if body := a.blockChain().GetBody(hash); body != nil {
if body := a.BlockChain().GetBody(hash); body != nil {
return body, nil
}
return nil, errors.New("block body not found")
}

// 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 len(progress) == 0 {
return ethereum.SyncProgress{}
Expand All @@ -184,7 +196,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 := a.b.config.FeeHistoryMaxBlockCount
if blocks > maxFeeHistory {
Expand Down Expand Up @@ -260,7 +272,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
Expand Down Expand Up @@ -329,17 +341,23 @@ 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 {
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 {
Expand All @@ -350,13 +368,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(), nil
return a.BlockChain().CurrentBlock(), 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) {
Expand All @@ -366,7 +384,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")
}
Expand All @@ -376,17 +394,17 @@ 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.Header {
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 {
currentHeader := a.blockChain().CurrentBlock()
currentBlock := a.blockChain().GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64())
currentHeader := a.BlockChain().CurrentBlock()
currentBlock := a.BlockChain().GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64())
if currentBlock == nil {
return nil, errors.New("can't find block for current header")
}
Expand All @@ -396,11 +414,11 @@ func (a *APIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber)
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) {
Expand All @@ -422,10 +440,10 @@ func (a *APIBackend) stateAndHeaderFromHeader(ctx context.Context, header *types
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
}
bc := a.blockChain()
bc := a.BlockChain()
stateFor := func(header *types.Header) (*state.StateDB, error) {
return bc.StateAt(header.Root)
}
Expand Down Expand Up @@ -454,51 +472,51 @@ 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, release tracers.StateReleaseFunc, err error) {
if !a.blockChain().Config().IsArbitrumNitro(block.Number()) {
if !a.BlockChain().Config().IsArbitrumNitro(block.Number()) {
return nil, 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(ctx, 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, tracers.StateReleaseFunc, error) {
if !a.blockChain().Config().IsArbitrumNitro(block.Number()) {
if !a.BlockChain().Config().IsArbitrumNitro(block.Number()) {
return nil, vm.BlockContext{}, nil, 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(ctx, 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
}

func (a *APIBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) (*vm.EVM, func() error) {
vmError := func() error { return nil }
if vmConfig == nil {
vmConfig = a.blockChain().GetVMConfig()
vmConfig = a.BlockChain().GetVMConfig()
}
txContext := core.NewEVMTxContext(msg)
return vm.NewEVM(*blockCtx, txContext, state, a.blockChain().Config(), *vmConfig), vmError
return vm.NewEVM(*blockCtx, txContext, state, a.BlockChain().Config(), *vmConfig), vmError
}

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
Expand Down Expand Up @@ -526,7 +544,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
}
Expand Down Expand Up @@ -566,7 +584,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 {
Expand All @@ -575,15 +593,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) {
Expand Down
4 changes: 2 additions & 2 deletions arbitrum/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,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,
Expand All @@ -52,7 +52,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
}
Expand Down
6 changes: 5 additions & 1 deletion core/blockchain_arbitrum.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package core

import (
"errors"
"time"

"github.com/ethereum/go-ethereum/core/state"
Expand All @@ -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() {
Expand Down

0 comments on commit 8919ab3

Please sign in to comment.