Skip to content

Commit 42be4fe

Browse files
Backport test Genesis assertion on nitro init to 3.7.x (#3596)
* Test Genesis assertion on nitro init * revert go.mod changes
1 parent 361de54 commit 42be4fe

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

cmd/conf/init.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type InitConfig struct {
4141
ReorgToBatch int64 `koanf:"reorg-to-batch"`
4242
ReorgToMessageBatch int64 `koanf:"reorg-to-message-batch"`
4343
ReorgToBlockBatch int64 `koanf:"reorg-to-block-batch"`
44+
ValidateGenesisAssertion bool `koanf:"validate-genesis-assertion"`
4445
}
4546

4647
var InitConfigDefault = InitConfig{
@@ -71,6 +72,7 @@ var InitConfigDefault = InitConfig{
7172
ReorgToBatch: -1,
7273
ReorgToMessageBatch: -1,
7374
ReorgToBlockBatch: -1,
75+
ValidateGenesisAssertion: true,
7476
}
7577

7678
func InitConfigAddOptions(prefix string, f *pflag.FlagSet) {
@@ -105,6 +107,7 @@ func InitConfigAddOptions(prefix string, f *pflag.FlagSet) {
105107
"\"force\"- force rebuilding which would commence rebuilding despite the status of previous attempts,\n"+
106108
"\"false\"- do not rebuild on startup",
107109
)
110+
f.Bool(prefix+".validate-genesis-assertion", InitConfigDefault.ValidateGenesisAssertion, "tests genesis assertion posted on parent chain against the genesis block created on init")
108111
}
109112

110113
func (c *InitConfig) Validate() error {

cmd/nitro/init.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

5358
var 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+
919973
func testTxIndexUpdated(chainDb ethdb.Database, lastBlock uint64) bool {
920974
var transactions types.Transactions
921975
blockHash := rawdb.ReadCanonicalHash(chainDb, lastBlock)

cmd/nitro/init_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ func TestOpenInitializeChainDbIncompatibleStateScheme(t *testing.T) {
429429
nodeConfig.Node = *arbnode.ConfigDefaultL2Test()
430430
nodeConfig.Init.DevInit = true
431431
nodeConfig.Init.DevInitAddress = "0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E"
432+
nodeConfig.Init.ValidateGenesisAssertion = false
432433

433434
l1Client := ethclient.NewClient(stack.Attach())
434435

@@ -696,6 +697,7 @@ func TestOpenInitializeChainDbEmptyInit(t *testing.T) {
696697
nodeConfig.Chain.ID = 42161
697698
nodeConfig.Node = *arbnode.ConfigDefaultL2Test()
698699
nodeConfig.Init.Empty = true
700+
nodeConfig.Init.ValidateGenesisAssertion = false
699701

700702
l1Client := ethclient.NewClient(stack.Attach())
701703

0 commit comments

Comments
 (0)