Skip to content

Commit

Permalink
feat: Sync and relay L1 messages (ethereum#350)
Browse files Browse the repository at this point in the history
* add l1 config in genesis config (ethereum#249)

* add l1 config in genesis config

* fix lint

* Update params/config.go

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>

---------

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>

* extend node configuration (ethereum#251)

* extend node configuration

* use block number instead of hash

* accept safe, finalized and numbers for L1Confirmations

* fix typos

---------

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>

* Fix/improve node config parsing (ethereum#260)

* raise error on failed parsing

* default value

* add l1-message-type, transaction methods (ethereum#252)

* add l1-message-type, transaction methods

* goimports

* Update core/types/transaction.go

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>

* txpool l1 check, pointer change, marhsal test

* draft: start implementing l1message gas behavior

* draft: start implementing l1message gas behavior

* change to gas usage

* error comment typo

Co-authored-by: Haichen Shen <shenhaichen@gmail.com>

* goimports

* update nonce, add hash test (fails), marshal test

* goimports

* target addr cant be nil

* change call msg

* comment out test

* lint

---------

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>

* Add L1 message database (ethereum#255)

* add l1-message-type, transaction methods

* goimports

* Update core/types/transaction.go

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>

* add L1 message store to rawdb

* remove comments

* rename to l1_message

* rename variables and add comments

* write l1 msgs in a batch

* add more comments

* update tests

* allow batched and non-batched writes

* rename to accessors_l1_message

* handle error

* add range check

* fix tests

* update comments

* nit

* support blocks with 0 l1 messages

---------

Co-authored-by: Max Wolff <maxcwolff@gmail.com>
Co-authored-by: Max Wolff <max@scroll.io>

* Fix L1Message Deep Copy, Complete Bridge Tx Hash test (ethereum#269)

* deep copy value field, add tx hash test

comment

* typo

* Rename nonce to queueindex, increment sender nonce on L1 message execution (ethereum#271)

* change nonce to queueindex, increment nonce on L1 message

* fix db acccessors

* Update core/types/transaction_marshalling.go

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>

---------

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>

* Fix db inspect command (ethereum#276)

fix db inspect command

* Add l1 sync service (ethereum#256)

* extend node configuration

* add l1-message-type, transaction methods

* goimports

* Update core/types/transaction.go

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>

* use block number instead of hash

* accept safe, finalized and numbers for L1Confirmations

* add L1 message store to rawdb

* remove comments

* fix typos

* add L1 message sync service

* use l1 contract address and chain ID

* use L1DeploymentBlock

* add confirmation config

* move bridge client to separate file

* use uint64 block number

* fix bigint comparison

* rename constants

* add more logs

* rename to l1_message

* rename variables and add comments

* write l1 msgs in a batch

* add more comments

* update tests

* allow batched and non-batched writes

* rename to accessors_l1_message

* handle error

* check if config is provided

* improve sync service DB batched writes

* add range check

* fix tests

* update comments

* nit

* fix flush range and improve comments

* solve circular dependency

* update stress tests

* initialize l1 client for geth

* start sync service

* add more comments

* check nil correctly

* address comments

* fix merge

* fix genesis l1config deserialization

* add sync progress logs

* initial sync

* handle leveldb not found error

* use errors.Is

* address comments

* update DefaultPollInterval

---------

Co-authored-by: Nazarii Denha <dengaaa2002@gmail.com>
Co-authored-by: Max Wolff <maxcwolff@gmail.com>
Co-authored-by: Max Wolff <max@scroll.io>

* Add L1 message validation (ethereum#272)

* add L1 message validation

* add comments and better error handling

* handle leveldb not found error

* update incorrect condition for genesis block

* typo

* change inclusion index logic

* disable L1 message check for legacy tests

* set NumL1MessagesPerBlock to 0 in tests

* update default genesis config

* Add L1 msg validation tests (ethereum#303)

add L1 msg validation tests

* Update miner include l1 messages (ethereum#265)

* add l1-message-type, transaction methods

* goimports

* Update core/types/transaction.go

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>

* add L1 message store to rawdb

* add L1 message sync service

* remove comments

* use l1 contract address and chain ID

* extend node configuration

* use block number instead of hash

* accept safe, finalized and numbers for L1Confirmations

* fix typos

* use L1DeploymentBlock

* add confirmation config

* move bridge client to separate file

* use uint64 block number

* fix bigint comparison

* rename constants

* add more logs

* Fix/improve node config parsing (ethereum#260)

* raise error on failed parsing

* default value

* rename to l1_message

* rename variables and add comments

* write l1 msgs in a batch

* add more comments

* update tests

* allow batched and non-batched writes

* rename to accessors_l1_message

* handle error

* check if config is provided

* improve sync service DB batched writes

* include l1 messages in blocks: part 1

* add l1-message-type, transaction methods (ethereum#252)

* add l1-message-type, transaction methods

* goimports

* Update core/types/transaction.go

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>

* txpool l1 check, pointer change, marhsal test

* draft: start implementing l1message gas behavior

* draft: start implementing l1message gas behavior

* change to gas usage

* error comment typo

Co-authored-by: Haichen Shen <shenhaichen@gmail.com>

* goimports

* update nonce, add hash test (fails), marshal test

* goimports

* target addr cant be nil

* change call msg

* comment out test

* lint

---------

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>

* Add L1 message database (ethereum#255)

* add l1-message-type, transaction methods

* goimports

* Update core/types/transaction.go

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>

* add L1 message store to rawdb

* remove comments

* rename to l1_message

* rename variables and add comments

* write l1 msgs in a batch

* add more comments

* update tests

* allow batched and non-batched writes

* rename to accessors_l1_message

* handle error

* add range check

* fix tests

* update comments

* nit

* support blocks with 0 l1 messages

---------

Co-authored-by: Max Wolff <maxcwolff@gmail.com>
Co-authored-by: Max Wolff <max@scroll.io>

* build(docker): auto docker push when pushing git tags (ethereum#258)

* build(docker): update docker trigger tag prefix (ethereum#259)

* Fix L1Message Deep Copy, Complete Bridge Tx Hash test (ethereum#269)

* deep copy value field, add tx hash test

comment

* typo

* commitl1messages

* lint

* Revert "add L1 message sync service"

This reverts commit 5305e8a.

* Revert "move bridge client to separate file"

This reverts commit 0b220be.

* update branch

* use commitMessages for l1Txs

* little fix

* fix config

* fix test

* comment fixes

* fix

* fix config check

---------

Co-authored-by: Max Wolff <maxcwolff@gmail.com>
Co-authored-by: Max Wolff <max@scroll.io>
Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>

* Add ErrUnknownAncestor tests (ethereum#305)

add ErrUnknownAncestor tests

* worker test include l1 msgs (ethereum#306)

* worker test include l1 msgs

* move L1 message index update next to block insertion

---------

Co-authored-by: Péter Garamvölgyi <peter@scroll.io>

* exclude l1 messages from transaction count limit in block (ethereum#307)

* exclude l1 messages from transaction count limit in block

* fix comments

* trigger ci

* nit

---------

Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>

* Expose queueIndex on Transaction (ethereum#316)

expose queueIndex on Transaction

* test that l1msg doesn't count in maxTxPerBlock limit (ethereum#312)

* test that l1msg doesn't count in maxTxPerBlock limit

* fix, comment

* retrigger ci

* change order inside test

---------

Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Co-authored-by: Péter Garamvölgyi <th307q@gmail.com>

* reuse trace nonce field for queueIndex

* expose scroll APIs on the geth console

* add L1 message query APIs

* Trigger new block on new l1 messages (ethereum#343)

* trigger new block on new l1 messages

* typo

* initialize l1MsgCh

* fix worker l1msg tests (ethereum#345)

---------

Co-authored-by: Nazarii Denha <dengaaa2002@gmail.com>

* test(worker): ensure that l1 messages are included in the correct order (ethereum#346)

test that l1msgs added in correct order

* rename enqueueIndex --> queueIndex

* move QueueIndex into transaction

* improve l1 db interface

* formatting

* bump version

* print l1config

* add API to query latest included message queue index

* clean up tx limit logic

* add clarifying comments and todos to ValidateL1Messages

* improve db comments and logs

* clean up L1MessageTx type handling

* format

* format

* improve L1 message block check

* fix missing L1 event handling

* fix TestL1MessageValidationFailure

* simplify sync height resume logic

* make l1Config.l1MessageQueueAddress non-pointer

* improve command line flags

* remove todo

* use abigen tools for log filtering

* cache block L1 message count

* nit: fix variable name case

* improve logs

* flush pending writes to DB before shutdown

---------

Co-authored-by: Nazarii Denha <dengaaa2002@gmail.com>
Co-authored-by: Max Wolff <max@scroll.io>
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
Co-authored-by: Max Wolff <maxcwolff@gmail.com>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Co-authored-by: HAOYUatHZ <haoyu@protonmail.com>
  • Loading branch information
7 people authored Jun 7, 2023
1 parent 4867699 commit 983d630
Show file tree
Hide file tree
Showing 50 changed files with 1,988 additions and 99 deletions.
1 change: 1 addition & 0 deletions accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,7 @@ func (m callMsg) Gas() uint64 { return m.CallMsg.Gas }
func (m callMsg) Value() *big.Int { return m.CallMsg.Value }
func (m callMsg) Data() []byte { return m.CallMsg.Data }
func (m callMsg) AccessList() types.AccessList { return m.CallMsg.AccessList }
func (m callMsg) IsL1MessageTx() bool { return false }

// filterBackend implements filters.Backend to support filtering for logs without
// taking bloom-bits acceleration structures into account.
Expand Down
2 changes: 1 addition & 1 deletion cmd/devp2p/internal/ethtest/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func setupGeth(stack *node.Node) error {
TrieDirtyCache: 16,
TrieTimeout: 60 * time.Minute,
SnapshotCache: 10,
})
}, nil)
if err != nil {
return err
}
Expand Down
3 changes: 3 additions & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ var (
utils.MinerNotifyFullFlag,
configFileFlag,
utils.CatalystFlag,
utils.L1EndpointFlag,
utils.L1ConfirmationsFlag,
utils.L1DeploymentBlockFlag,
}

rpcFlags = []cli.Flag{
Expand Down
73 changes: 72 additions & 1 deletion cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package utils

import (
"crypto/ecdsa"
"errors"
"fmt"
"io"
"io/ioutil"
Expand All @@ -41,6 +42,7 @@ import (
"github.com/scroll-tech/go-ethereum/accounts/keystore"
"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/common/fdlimit"
"github.com/scroll-tech/go-ethereum/common/hexutil"
"github.com/scroll-tech/go-ethereum/consensus"
"github.com/scroll-tech/go-ethereum/consensus/clique"
"github.com/scroll-tech/go-ethereum/consensus/ethash"
Expand All @@ -53,6 +55,7 @@ import (
"github.com/scroll-tech/go-ethereum/eth/ethconfig"
"github.com/scroll-tech/go-ethereum/eth/gasprice"
"github.com/scroll-tech/go-ethereum/eth/tracers"
"github.com/scroll-tech/go-ethereum/ethclient"
"github.com/scroll-tech/go-ethereum/ethdb"
"github.com/scroll-tech/go-ethereum/ethstats"
"github.com/scroll-tech/go-ethereum/graphql"
Expand All @@ -70,6 +73,7 @@ import (
"github.com/scroll-tech/go-ethereum/p2p/nat"
"github.com/scroll-tech/go-ethereum/p2p/netutil"
"github.com/scroll-tech/go-ethereum/params"
"github.com/scroll-tech/go-ethereum/rpc"
)

func init() {
Expand Down Expand Up @@ -794,6 +798,20 @@ var (
Name: "catalyst",
Usage: "Catalyst mode (eth2 integration testing)",
}

// L1Settings
L1EndpointFlag = cli.StringFlag{
Name: "l1.endpoint",
Usage: "Endpoint of L1 HTTP-RPC server",
}
L1ConfirmationsFlag = cli.StringFlag{
Name: "l1.confirmations",
Usage: "Number of confirmations on L1 needed for finalization, or \"safe\" or \"finalized\"",
}
L1DeploymentBlockFlag = cli.Int64Flag{
Name: "l1.sync.startblock",
Usage: "L1 block height to start syncing from. Should be set to the L1 message queue deployment block number.",
}
)

// MakeDataDir retrieves the currently requested data directory, terminating
Expand Down Expand Up @@ -1226,6 +1244,7 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
setNodeUserIdent(ctx, cfg)
setDataDir(ctx, cfg)
setSmartCard(ctx, cfg)
setL1(ctx, cfg)

if ctx.GlobalIsSet(ExternalSignerFlag.Name) {
cfg.ExternalSigner = ctx.GlobalString(ExternalSignerFlag.Name)
Expand All @@ -1251,6 +1270,42 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
}
}

func unmarshalBlockNumber(input string) (rpc.BlockNumber, error) {
switch input {
case "finalized":
return rpc.FinalizedBlockNumber, nil
case "safe":
return rpc.SafeBlockNumber, nil
}
blockNum, err := hexutil.DecodeUint64(input)
if err == nil && blockNum <= math.MaxInt64 {
return rpc.BlockNumber(blockNum), nil
}
blockNum, err = strconv.ParseUint(input, 10, 64)
if err == nil && blockNum <= math.MaxInt64 {
return rpc.BlockNumber(blockNum), nil
}
return 0, errors.New("incorrect value")
}

func setL1(ctx *cli.Context, cfg *node.Config) {
var err error
if ctx.GlobalIsSet(L1EndpointFlag.Name) {
cfg.L1Endpoint = ctx.GlobalString(L1EndpointFlag.Name)
}
if ctx.GlobalIsSet(L1ConfirmationsFlag.Name) {
cfg.L1Confirmations, err = unmarshalBlockNumber(ctx.GlobalString(L1ConfirmationsFlag.Name))
if err != nil {
panic(fmt.Sprintf("invalid value for flag %s: %s", L1ConfirmationsFlag.Name, ctx.GlobalString(L1ConfirmationsFlag.Name)))
}
} else {
cfg.L1Confirmations = rpc.FinalizedBlockNumber
}
if ctx.GlobalIsSet(L1DeploymentBlockFlag.Name) {
cfg.L1DeploymentBlock = ctx.GlobalUint64(L1DeploymentBlockFlag.Name)
}
}

func setSmartCard(ctx *cli.Context, cfg *node.Config) {
// Skip enabling smartcards if no path is set
path := ctx.GlobalString(SmartCardDaemonPathFlag.Name)
Expand Down Expand Up @@ -1732,7 +1787,23 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend
stack.RegisterAPIs(tracers.APIs(backend.ApiBackend))
return backend.ApiBackend, nil
}
backend, err := eth.New(stack, cfg)

// initialize L1 client for sync service
// note: we need to do this here to avoid circular dependency
l1EndpointUrl := stack.Config().L1Endpoint
var l1Client *ethclient.Client

if l1EndpointUrl != "" {
var err error
l1Client, err = ethclient.Dial(l1EndpointUrl)
if err != nil {
Fatalf("Unable to connect to L1 endpoint at %v: %v", l1EndpointUrl, err)
}

log.Info("Initialized L1 client", "endpoint", l1EndpointUrl)
}

backend, err := eth.New(stack, cfg, l1Client)
if err != nil {
Fatalf("Failed to register the Ethereum service: %v", err)
}
Expand Down
15 changes: 15 additions & 0 deletions consensus/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,19 @@ var (

// ErrInvalidTxCount is returned if a block contains too many transactions.
ErrInvalidTxCount = errors.New("invalid transaction count")

// ErrMissingL1MessageData is returned if a block contains L1 messages that the
// node has not synced yet. In this case we insert the block into the future
// queue and process it again later.
ErrMissingL1MessageData = errors.New("unknown L1 message data")

// ErrInvalidL1MessageOrder is returned if a block contains L1 messages in the wrong
// order. Possible scenarios are: (1) L1 messages do not follow their QueueIndex order,
// (2) the block skipped one or more L1 messages, (3) L1 messages are not included in
// a contiguous block at the front of the block.
ErrInvalidL1MessageOrder = errors.New("invalid L1 message order")

// ErrUnknownL1Message is returned if a block contains an L1 message that does not
// match the corresponding message in the node's local database.
ErrUnknownL1Message = errors.New("unknown L1 message")
)
2 changes: 1 addition & 1 deletion console/console_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func newTester(t *testing.T, confOverride func(*ethconfig.Config)) *tester {
if confOverride != nil {
confOverride(ethConf)
}
ethBackend, err := eth.New(stack, ethConf)
ethBackend, err := eth.New(stack, ethConf, nil)
if err != nil {
t.Fatalf("failed to register Ethereum protocol: %v", err)
}
Expand Down
70 changes: 69 additions & 1 deletion core/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"

"github.com/scroll-tech/go-ethereum/consensus"
"github.com/scroll-tech/go-ethereum/core/rawdb"
"github.com/scroll-tech/go-ethereum/core/state"
"github.com/scroll-tech/go-ethereum/core/types"
"github.com/scroll-tech/go-ethereum/params"
Expand Down Expand Up @@ -54,7 +55,7 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
if v.bc.HasBlockAndState(block.Hash(), block.NumberU64()) {
return ErrKnownBlock
}
if !v.config.Scroll.IsValidTxCount(len(block.Transactions())) {
if !v.config.Scroll.IsValidL2TxCount(block.CountL2Tx()) {
return consensus.ErrInvalidTxCount
}
// Check if block payload size is smaller than the max size
Expand All @@ -78,6 +79,73 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
}
return consensus.ErrPrunedAncestor
}
return v.ValidateL1Messages(block)
}

// ValidateL1Messages validates L1 messages contained in a block.
// We check the following conditions:
// - L1 messages are in a contiguous section at the front of the block.
// - The first L1 message's QueueIndex is right after the last L1 message included in the chain.
// - L1 messages follow the QueueIndex order. No L1 message is skipped.
// - The L1 messages included in the block match the node's view of the L1 ledger.
func (v *BlockValidator) ValidateL1Messages(block *types.Block) error {
// no further processing if the block contains no L1 messages
if block.L1MessageCount() == 0 {
return nil
}

if v.config.Scroll.L1Config == nil {
// TODO: should we allow follower nodes to skip L1 message verification?
panic("Running on L1Message-enabled network but no l1Config was provided")
}

nextQueueIndex := rawdb.ReadFirstQueueIndexNotInL2Block(v.bc.db, block.ParentHash())
if nextQueueIndex == nil {
// we'll reprocess this block at a later time
return consensus.ErrMissingL1MessageData
}
queueIndex := *nextQueueIndex

L1SectionOver := false
it := rawdb.IterateL1MessagesFrom(v.bc.db, queueIndex)

for _, tx := range block.Transactions() {
if !tx.IsL1MessageTx() {
L1SectionOver = true
continue // we do not verify L2 transactions here
}

// check that L1 messages are before L2 transactions
if L1SectionOver {
return consensus.ErrInvalidL1MessageOrder
}

// check queue index
// TODO: account for skipped messages here
if tx.AsL1MessageTx().QueueIndex != queueIndex {
return consensus.ErrInvalidL1MessageOrder
}

queueIndex += 1

if exists := it.Next(); !exists {
// we'll reprocess this block at a later time
return consensus.ErrMissingL1MessageData
}

// check that the L1 message in the block is the same that we collected from L1
msg := it.L1Message()
expectedHash := types.NewTx(&msg).Hash()

if tx.Hash() != expectedHash {
return consensus.ErrUnknownL1Message
}
}

// TODO: consider adding a rule to enforce L1Config.NumL1MessagesPerBlock.
// If there are L1 messages available, sequencer nodes should include them.
// However, this is hard to enforce as different nodes might have different views of L1.

return nil
}

Expand Down
26 changes: 24 additions & 2 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,9 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
return nil, ErrNoGenesis
}

// initialize L1 message index for genesis block
rawdb.WriteFirstQueueIndexNotInL2Block(db, bc.genesisBlock.Hash(), 0)

var nilBlock *types.Block
bc.currentBlock.Store(nilBlock)
bc.currentFastBlock.Store(nilBlock)
Expand Down Expand Up @@ -695,6 +698,7 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
batch := bc.db.NewBatch()
rawdb.WriteTd(batch, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty())
rawdb.WriteBlock(batch, genesis)
rawdb.WriteFirstQueueIndexNotInL2Block(batch, genesis.Hash(), 0)
if err := batch.Write(); err != nil {
log.Crit("Failed to write genesis block", "err", err)
}
Expand Down Expand Up @@ -1176,6 +1180,14 @@ func (bc *BlockChain) writeBlockWithoutState(block *types.Block, td *big.Int) (e
batch := bc.db.NewBatch()
rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), td)
rawdb.WriteBlock(batch, block)

queueIndex := rawdb.ReadFirstQueueIndexNotInL2Block(bc.db, block.ParentHash())
if queueIndex != nil {
// note: we can insert blocks with header-only ancestors here,
// so queueIndex might not yet be available in DB.
rawdb.WriteFirstQueueIndexNotInL2Block(batch, block.Hash(), *queueIndex+uint64(block.L1MessageCount()))
}

if err := batch.Write(); err != nil {
log.Crit("Failed to write block into disk", "err", err)
}
Expand Down Expand Up @@ -1230,6 +1242,15 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
rawdb.WriteBlock(blockBatch, block)
rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts)
rawdb.WritePreimages(blockBatch, state.Preimages())

queueIndex := rawdb.ReadFirstQueueIndexNotInL2Block(bc.db, block.ParentHash())
if queueIndex == nil {
// We expect that we only insert contiguous chain segments,
// so the parent will always be inserted first.
log.Crit("Queue index in DB is nil", "parent", block.ParentHash(), "hash", block.Hash())
}
rawdb.WriteFirstQueueIndexNotInL2Block(blockBatch, block.Hash(), *queueIndex+uint64(block.L1MessageCount()))

if err := blockBatch.Write(); err != nil {
log.Crit("Failed to write block into disk", "err", err)
}
Expand Down Expand Up @@ -1500,7 +1521,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er
return bc.insertSideChain(block, it)

// First block is future, shove it (and all children) to the future queue (unknown ancestor)
case errors.Is(err, consensus.ErrFutureBlock) || (errors.Is(err, consensus.ErrUnknownAncestor) && bc.futureBlocks.Contains(it.first().ParentHash())):
case errors.Is(err, consensus.ErrFutureBlock) || errors.Is(err, consensus.ErrMissingL1MessageData) || (errors.Is(err, consensus.ErrUnknownAncestor) && bc.futureBlocks.Contains(it.first().ParentHash())):
for block != nil && (it.index == 0 || errors.Is(err, consensus.ErrUnknownAncestor)) {
log.Debug("Future block, postponing import", "number", block.Number(), "hash", block.Hash())
if err := bc.addFutureBlock(block); err != nil {
Expand Down Expand Up @@ -2175,11 +2196,12 @@ Chain config: %v
Number: %v
Hash: 0x%x
ParentHash: 0x%x
%v
Error: %v
##############################
`, bc.chainConfig, block.Number(), block.Hash(), receiptString, err))
`, bc.chainConfig, block.Number(), block.Hash(), block.ParentHash(), receiptString, err))
}

// InsertHeaderChain attempts to insert the given header chain in to the local
Expand Down
Loading

0 comments on commit 983d630

Please sign in to comment.