@@ -25,6 +25,7 @@ import (
2525 "github.com/cavaliergopher/grab/v3"
2626 "github.com/codeclysm/extract/v3"
2727
28+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
2829 "github.com/ethereum/go-ethereum/common"
2930 "github.com/ethereum/go-ethereum/core"
3031 "github.com/ethereum/go-ethereum/core/rawdb"
@@ -36,6 +37,7 @@ import (
3637 "github.com/ethereum/go-ethereum/node"
3738 "github.com/ethereum/go-ethereum/params"
3839
40+ protocol "github.com/offchainlabs/bold/chain-abstraction"
3941 "github.com/offchainlabs/nitro/arbnode"
4042 "github.com/offchainlabs/nitro/arbos/arbosState"
4143 "github.com/offchainlabs/nitro/arbos/arbostypes"
@@ -44,10 +46,13 @@ import (
4446 "github.com/offchainlabs/nitro/cmd/pruning"
4547 "github.com/offchainlabs/nitro/cmd/staterecovery"
4648 "github.com/offchainlabs/nitro/execution/gethexec"
49+ "github.com/offchainlabs/nitro/solgen/go/rollupgen"
50+ "github.com/offchainlabs/nitro/staker/bold"
4751 "github.com/offchainlabs/nitro/statetransfer"
4852 "github.com/offchainlabs/nitro/util"
4953 "github.com/offchainlabs/nitro/util/arbmath"
5054 "github.com/offchainlabs/nitro/util/dbutil"
55+ "github.com/offchainlabs/nitro/util/headerreader"
5156)
5257
5358var notFoundError = errors .New ("file not found" )
@@ -806,6 +811,14 @@ func openInitializeChainDb(ctx context.Context, stack *node.Node, config *NodeCo
806811 }
807812 testUpdateTxIndex (chainDb , chainConfig , & txIndexWg )
808813 } else {
814+ var initDataReaderHasAccounts bool
815+ if config .Init .ValidateGenesisAssertion {
816+ accountsReader , err := initDataReader .GetAccountDataReader ()
817+ if err != nil {
818+ return chainDb , nil , err
819+ }
820+ initDataReaderHasAccounts = accountsReader .More ()
821+ }
809822 genesisBlockNr , err := initDataReader .GetNextBlockNumber ()
810823 if err != nil {
811824 return chainDb , nil , err
@@ -895,6 +908,14 @@ func openInitializeChainDb(ctx context.Context, stack *node.Node, config *NodeCo
895908 if err != nil {
896909 return chainDb , nil , err
897910 }
911+ if config .Init .ValidateGenesisAssertion {
912+ if err := validateGenesisAssertion (ctx , rollupAddrs .Rollup , l1Client , l2BlockChain .Genesis ().Hash (), initDataReaderHasAccounts ); err != nil {
913+ if ! config .Init .Force {
914+ return chainDb , nil , fmt .Errorf ("error testing genesis assertion: %w" , err )
915+ }
916+ log .Error ("Error testing genesis assertions" , "err" , err )
917+ }
918+ }
898919 }
899920
900921 txIndexWg .Wait ()
@@ -916,6 +937,39 @@ func openInitializeChainDb(ctx context.Context, stack *node.Node, config *NodeCo
916937 return rebuildLocalWasm (ctx , & config .Execution , l2BlockChain , chainDb , wasmDb , config .Init .RebuildLocalWasm )
917938}
918939
940+ func validateGenesisAssertion (ctx context.Context , rollupAddress common.Address , l1Client * ethclient.Client , genesisBlockHash common.Hash , initDataReaderHasAccounts bool ) error {
941+ userLogic , err := rollupgen .NewRollupUserLogic (rollupAddress , l1Client )
942+ if err != nil {
943+ return err
944+ }
945+ _ , err = userLogic .ChallengeGracePeriodBlocks (& bind.CallOpts {Context : ctx })
946+ if err != nil {
947+ if ! headerreader .IsExecutionReverted (err ) {
948+ return err
949+ }
950+ log .Warn ("Genesis Assertion is not tested" ) // not a bold chain
951+ return nil
952+ }
953+ genesisAssertionHash , err := userLogic .GenesisAssertionHash (& bind.CallOpts {Context : context .Background ()})
954+ if err != nil {
955+ return err
956+ }
957+ genesisAssertionCreationInfo , err := bold .ReadBoldAssertionCreationInfo (ctx , userLogic , l1Client , rollupAddress , genesisAssertionHash )
958+ if err != nil {
959+ return err
960+ }
961+ beforeGlobalState := protocol .GoGlobalStateFromSolidity (genesisAssertionCreationInfo .BeforeState .GlobalState )
962+ afterGlobalState := protocol .GoGlobalStateFromSolidity (genesisAssertionCreationInfo .AfterState .GlobalState )
963+ isNullAssertion := beforeGlobalState .Batch == afterGlobalState .Batch && beforeGlobalState .PosInBatch == afterGlobalState .PosInBatch
964+ if isNullAssertion && initDataReaderHasAccounts {
965+ return errors .New ("genesis assertion is null but there are accounts in the init data" )
966+ }
967+ if ! isNullAssertion && afterGlobalState .BlockHash != genesisBlockHash {
968+ return errors .New ("genesis assertion is non null and its afterGlobalState.BlockHash doesn't match the genesis blockHash" )
969+ }
970+ return nil
971+ }
972+
919973func testTxIndexUpdated (chainDb ethdb.Database , lastBlock uint64 ) bool {
920974 var transactions types.Transactions
921975 blockHash := rawdb .ReadCanonicalHash (chainDb , lastBlock )
0 commit comments