From 12de883500915a08923f0cc47fcb68cc06d53629 Mon Sep 17 00:00:00 2001 From: amsanghi Date: Thu, 24 Aug 2023 20:15:10 +0530 Subject: [PATCH 01/11] Add option to switch to new bold protocol staker during the contract upgrade --- arbnode/node.go | 2 +- staker/staker.go | 57 +++++++++++++++++++++++++++++++++++++ system_tests/staker_test.go | 3 ++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/arbnode/node.go b/arbnode/node.go index a4025429c6..40aa58c342 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -843,7 +843,7 @@ func createNodeImpl( confirmedNotifiers = append(confirmedNotifiers, messagePruner) } - stakerObj, err = staker.NewStaker(l1Reader, wallet, bind.CallOpts{}, config.Staker, blockValidator, statelessBlockValidator, nil, confirmedNotifiers, deployInfo.ValidatorUtils, fatalErrChan) + stakerObj, err = staker.NewStaker(l1Reader, wallet, bind.CallOpts{}, config.Staker, blockValidator, statelessBlockValidator, nil, confirmedNotifiers, deployInfo.ValidatorUtils, deployInfo.Rollup, fatalErrChan) if err != nil { return nil, err } diff --git a/staker/staker.go b/staker/staker.go index a35f5088c1..9d9d3c1816 100644 --- a/staker/staker.go +++ b/staker/staker.go @@ -22,6 +22,8 @@ import ( "github.com/offchainlabs/nitro/arbutil" "github.com/offchainlabs/nitro/cmd/genericconf" + "github.com/offchainlabs/nitro/solgen/go/bridgegen" + "github.com/offchainlabs/nitro/solgen/go/rollupgen" "github.com/offchainlabs/nitro/util/arbmath" "github.com/offchainlabs/nitro/util/stopwaiter" "github.com/offchainlabs/nitro/validator" @@ -70,6 +72,7 @@ func L1PostingStrategyAddOptions(prefix string, f *flag.FlagSet) { type L1ValidatorConfig struct { Enable bool `koanf:"enable"` + EnableBold bool `koanf:"enable-bold"` Strategy string `koanf:"strategy"` StakerInterval time.Duration `koanf:"staker-interval"` MakeAssertionInterval time.Duration `koanf:"make-assertion-interval"` @@ -133,6 +136,7 @@ func (c *L1ValidatorConfig) Validate() error { var DefaultL1ValidatorConfig = L1ValidatorConfig{ Enable: true, + EnableBold: false, Strategy: "Watchtower", StakerInterval: time.Minute, MakeAssertionInterval: time.Hour, @@ -158,6 +162,7 @@ var DefaultValidatorL1WalletConfig = genericconf.WalletConfig{ func L1ValidatorConfigAddOptions(prefix string, f *flag.FlagSet) { f.Bool(prefix+".enable", DefaultL1ValidatorConfig.Enable, "enable validator") + f.Bool(prefix+".enable-bold", DefaultL1ValidatorConfig.EnableBold, "enable switch check to bold validator") f.String(prefix+".strategy", DefaultL1ValidatorConfig.Strategy, "L1 validator strategy, either watchtower, defensive, stakeLatest, or makeNodes") f.Duration(prefix+".staker-interval", DefaultL1ValidatorConfig.StakerInterval, "how often the L1 validator should check the status of the L1 rollup and maybe take action with its stake") f.Duration(prefix+".make-assertion-interval", DefaultL1ValidatorConfig.MakeAssertionInterval, "if configured with the makeNodes strategy, how often to create new assertions (bypassed in case of a dispute)") @@ -216,6 +221,7 @@ type Staker struct { bringActiveUntilNode uint64 inboxReader InboxReaderInterface statelessBlockValidator *StatelessBlockValidator + bridge *bridgegen.IBridge fatalErr chan<- error } @@ -229,6 +235,7 @@ func NewStaker( stakedNotifiers []LatestStakedNotifier, confirmedNotifiers []LatestConfirmedNotifier, validatorUtilsAddress common.Address, + bridgeAddress common.Address, fatalErr chan<- error, ) (*Staker, error) { @@ -245,6 +252,13 @@ func NewStaker( if config.StartValidationFromStaked && blockValidator != nil { stakedNotifiers = append(stakedNotifiers, blockValidator) } + var bridge *bridgegen.IBridge + if config.EnableBold { + bridge, err = bridgegen.NewIBridge(bridgeAddress, client) + if err != nil { + return nil, err + } + } return &Staker{ L1Validator: val, l1Reader: l1Reader, @@ -256,6 +270,7 @@ func NewStaker( lastActCalledBlock: nil, inboxReader: statelessBlockValidator.inboxReader, statelessBlockValidator: statelessBlockValidator, + bridge: bridge, fatalErr: fatalErr, }, nil } @@ -424,6 +439,48 @@ func (s *Staker) Start(ctxIn context.Context) { } return s.config.StakerInterval }) + s.CallIteratively(func(ctx context.Context) time.Duration { + // Using ctxIn instead of ctx since, ctxIn will be passed on to bold staker + // and ctx will be cancelled after the switch to bold staker. + switchedToBoldProtocol, err := s.checkAndSwitchToBoldStaker(ctxIn) + if err != nil { + log.Error("staker: error in checking switch to bold staker", "err", err) + } + if switchedToBoldProtocol { + s.StopAndWait() + } + return s.config.StakerInterval + }) +} + +func (s *Staker) checkAndSwitchToBoldStaker(ctx context.Context) (bool, error) { + switchedToBoldProtocol := false + if s.config.EnableBold { + callOpts := s.getCallOpts(ctx) + rollupAddress, err := s.bridge.Rollup(callOpts) + if err != nil { + return false, err + } + userLogic, err := rollupgen.NewRollupUserLogic(rollupAddress, s.client) + if err != nil { + return false, err + } + _, err = userLogic.ExtraChallengeTimeBlocks(callOpts) + if err != nil { + // Switch to Bold protocol since ExtraChallengeTimeBlocks does not exist in bold protocol . + auth, err := s.builder.Auth(ctx) + if err != nil { + return false, err + } + boldManager, err := NewManager(ctx, rollupAddress, auth, *callOpts, s.client, s.statelessBlockValidator, "") + if err != nil { + return false, err + } + boldManager.Start(ctx) + switchedToBoldProtocol = true + } + } + return switchedToBoldProtocol, nil } func (s *Staker) IsWhitelisted(ctx context.Context) (bool, error) { diff --git a/system_tests/staker_test.go b/system_tests/staker_test.go index 468463d58f..f126a10a6a 100644 --- a/system_tests/staker_test.go +++ b/system_tests/staker_test.go @@ -168,6 +168,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) nil, nil, l2nodeA.DeployInfo.ValidatorUtils, + l2nodeA.DeployInfo.Rollup, nil, ) Require(t, err) @@ -208,6 +209,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) nil, nil, l2nodeB.DeployInfo.ValidatorUtils, + l2nodeB.DeployInfo.Rollup, nil, ) Require(t, err) @@ -234,6 +236,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) nil, nil, l2nodeA.DeployInfo.ValidatorUtils, + l2nodeA.DeployInfo.Rollup, nil, ) Require(t, err) From 7f011e7aafbf8e8147db2c18959cbc7b7c98a582 Mon Sep 17 00:00:00 2001 From: amsanghi Date: Thu, 31 Aug 2023 18:45:12 +0530 Subject: [PATCH 02/11] call checkAndSwitchToBoldStaker before act as well --- staker/staker.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/staker/staker.go b/staker/staker.go index 9d9d3c1816..94556f2064 100644 --- a/staker/staker.go +++ b/staker/staker.go @@ -381,6 +381,13 @@ func (s *Staker) Start(ctxIn context.Context) { if err != nil { log.Warn("error updating latest wasm module root", "err", err) } + switchedToBoldProtocol, err := s.checkAndSwitchToBoldStaker(ctxIn) + if err != nil { + log.Error("staker: error in checking switch to bold staker", "err", err) + } + if switchedToBoldProtocol { + s.StopAndWait() + } arbTx, err := s.Act(ctx) if err == nil && arbTx != nil { _, err = s.l1Reader.WaitForTxApproval(ctx, arbTx) From 612949a9260a5528bd01147d4bceb34aa7fdb514 Mon Sep 17 00:00:00 2001 From: amsanghi Date: Fri, 1 Sep 2023 15:27:00 +0530 Subject: [PATCH 03/11] Add TestStakerSwitchDuringRollupUpgrade --- arbnode/node.go | 2 +- contracts | 2 +- system_tests/staker_test.go | 194 +++++++++++++++++++++++++++++++++++- 3 files changed, 193 insertions(+), 5 deletions(-) diff --git a/arbnode/node.go b/arbnode/node.go index 40aa58c342..4efcf1b7f7 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -843,7 +843,7 @@ func createNodeImpl( confirmedNotifiers = append(confirmedNotifiers, messagePruner) } - stakerObj, err = staker.NewStaker(l1Reader, wallet, bind.CallOpts{}, config.Staker, blockValidator, statelessBlockValidator, nil, confirmedNotifiers, deployInfo.ValidatorUtils, deployInfo.Rollup, fatalErrChan) + stakerObj, err = staker.NewStaker(l1Reader, wallet, bind.CallOpts{}, config.Staker, blockValidator, statelessBlockValidator, nil, confirmedNotifiers, deployInfo.ValidatorUtils, deployInfo.Bridge, fatalErrChan) if err != nil { return nil, err } diff --git a/contracts b/contracts index 97cfbe00ff..8324fc06de 160000 --- a/contracts +++ b/contracts @@ -1 +1 @@ -Subproject commit 97cfbe00ff0eea4d7f5f5f3afb01598c19ddabc4 +Subproject commit 8324fc06de2718d9d3a4ba927ac0fd8b5c427ef8 diff --git a/system_tests/staker_test.go b/system_tests/staker_test.go index f126a10a6a..bb4f0dffe3 100644 --- a/system_tests/staker_test.go +++ b/system_tests/staker_test.go @@ -9,6 +9,7 @@ package arbtest import ( "context" + "encoding/json" "errors" "fmt" "math/big" @@ -21,19 +22,27 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" + mocksgen_bold "github.com/OffchainLabs/bold/solgen/go/mocksgen" + challenge_testing "github.com/OffchainLabs/bold/testing" + "github.com/OffchainLabs/bold/testing/setup" + "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/arbnode/dataposter/storage" "github.com/offchainlabs/nitro/arbos/l2pricing" "github.com/offchainlabs/nitro/arbutil" + "github.com/offchainlabs/nitro/cmd/chaininfo" + "github.com/offchainlabs/nitro/solgen/go/bridgegen" "github.com/offchainlabs/nitro/solgen/go/mocksgen" "github.com/offchainlabs/nitro/solgen/go/rollupgen" "github.com/offchainlabs/nitro/staker" "github.com/offchainlabs/nitro/util" "github.com/offchainlabs/nitro/util/arbmath" "github.com/offchainlabs/nitro/util/colors" + "github.com/offchainlabs/nitro/validator/server_common" "github.com/offchainlabs/nitro/validator/valnode" ) @@ -168,7 +177,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) nil, nil, l2nodeA.DeployInfo.ValidatorUtils, - l2nodeA.DeployInfo.Rollup, + l2nodeA.DeployInfo.Bridge, nil, ) Require(t, err) @@ -209,7 +218,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) nil, nil, l2nodeB.DeployInfo.ValidatorUtils, - l2nodeB.DeployInfo.Rollup, + l2nodeB.DeployInfo.Bridge, nil, ) Require(t, err) @@ -236,7 +245,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) nil, nil, l2nodeA.DeployInfo.ValidatorUtils, - l2nodeA.DeployInfo.Rollup, + l2nodeA.DeployInfo.Bridge, nil, ) Require(t, err) @@ -413,3 +422,182 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) func TestStakersCooperative(t *testing.T) { stakerTestImpl(t, false, false) } + +func TestStakerSwitchDuringRollupUpgrade(t *testing.T) { + ctx, cancelCtx := context.WithCancel(context.Background()) + defer cancelCtx() + stakerImpl, l1info, l1client, l2chainConfig, l2node, deployAuth := setupNonBoldStaker(t, ctx) + defer l2node.StopAndWait() + + err := stakerImpl.Initialize(ctx) + Require(t, err) + stakerImpl.Start(ctx) + if stakerImpl.Stopped() { + t.Fatal("Old protocol staker not started") + } + + rollupAddresses := deployBoldContracts(t, ctx, l1info, l1client, l2chainConfig.ChainID, deployAuth) + + bridge, err := bridgegen.NewBridge(l2node.DeployInfo.Bridge, l1client) + Require(t, err) + tx, err := bridge.UpdateRollupAddress(&deployAuth, rollupAddresses.Rollup) + Require(t, err) + _, err = EnsureTxSucceeded(ctx, l1client, tx) + Require(t, err) + + time.Sleep(time.Second) + + if !stakerImpl.Stopped() { + t.Fatal("Old protocol staker not stopped after rollup upgrade") + } +} + +func setupNonBoldStaker(t *testing.T, ctx context.Context) (*staker.Staker, info, *ethclient.Client, *params.ChainConfig, *arbnode.Node, bind.TransactOpts) { + var transferGas = util.NormalizeL2GasForL1GasInitial(800_000, params.GWei) // include room for aggregator L1 costs + l2chainConfig := params.ArbitrumDevTestChainConfig() + l2info := NewBlockChainTestInfo( + t, + types.NewArbitrumSigner(types.NewLondonSigner(l2chainConfig.ChainID)), big.NewInt(l2pricing.InitialBaseFeeWei*2), + transferGas, + ) + _, l2node, l2client, _, l1info, _, l1client, _ := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, l2chainConfig, nil, nil, l2info) + + config := arbnode.ConfigDefaultL1Test() + config.Sequencer.Enable = false + config.DelayedSequencer.Enable = false + config.BatchPoster.Enable = false + + BridgeBalance(t, "Faucet", big.NewInt(1).Mul(big.NewInt(params.Ether), big.NewInt(10000)), l1info, l2info, l1client, l2client, ctx) + + deployAuth := l1info.GetDefaultTransactOpts("RollupOwner", ctx) + + balance := big.NewInt(params.Ether) + balance.Mul(balance, big.NewInt(100)) + l1info.GenerateAccount("Validator") + TransferBalance(t, "Faucet", "Validator", balance, l1info, l1client, ctx) + l1auth := l1info.GetDefaultTransactOpts("Validator", ctx) + + rollup, err := rollupgen.NewRollupAdminLogic(l2node.DeployInfo.Rollup, l1client) + Require(t, err) + + tx, err := rollup.SetMinimumAssertionPeriod(&deployAuth, big.NewInt(1)) + Require(t, err) + _, err = EnsureTxSucceeded(ctx, l1client, tx) + Require(t, err) + valConfig := staker.DefaultL1ValidatorConfig + valConfig.Strategy = "WatchTower" + valConfig.EnableBold = true + valConfig.StakerInterval = 100 * time.Millisecond + + dp, err := arbnode.ValidatorDataposter(rawdb.NewTable(l2node.ArbDB, storage.BlockValidatorPrefix), l2node.L1Reader, &l1auth, NewFetcherFromConfig(arbnode.ConfigDefaultL1NonSequencerTest()), nil) + if err != nil { + t.Fatalf("Error creating validator dataposter: %v", err) + } + valWallet, err := staker.NewContractValidatorWallet(dp, nil, l2node.DeployInfo.ValidatorWalletCreator, l2node.DeployInfo.Rollup, l2node.L1Reader, &l1auth, 0, func(common.Address) {}, 10000) + Require(t, err) + _, valStack := createTestValidationNode(t, ctx, &valnode.TestValidationConfig) + blockValidatorConfig := staker.TestBlockValidatorConfig + + stateless, err := staker.NewStatelessBlockValidator( + l2node.InboxReader, + l2node.InboxTracker, + l2node.TxStreamer, + l2node.Execution.Recorder, + l2node.ArbDB, + nil, + StaticFetcherFrom(t, &blockValidatorConfig), + valStack, + ) + Require(t, err) + err = stateless.Start(ctx) + Require(t, err) + stakerImpl, err := staker.NewStaker( + l2node.L1Reader, + valWallet, + bind.CallOpts{}, + valConfig, + nil, + stateless, + nil, + nil, + l2node.DeployInfo.ValidatorUtils, + l2node.DeployInfo.Bridge, + nil, + ) + Require(t, err) + return stakerImpl, l1info, l1client, l2chainConfig, l2node, deployAuth +} + +func deployBoldContracts( + t *testing.T, + ctx context.Context, + l1info info, + backend *ethclient.Client, + chainId *big.Int, + deployAuth bind.TransactOpts, +) *chaininfo.RollupAddresses { + stakeToken, tx, tokenBindings, err := mocksgen_bold.DeployTestWETH9( + &deployAuth, + backend, + "Weth", + "WETH", + ) + Require(t, err) + _, err = EnsureTxSucceeded(ctx, backend, tx) + Require(t, err) + value, _ := new(big.Int).SetString("1000000", 10) + deployAuth.Value = value + tx, err = tokenBindings.Deposit(&deployAuth) + Require(t, err) + _, err = EnsureTxSucceeded(ctx, backend, tx) + Require(t, err) + deployAuth.Value = nil + Require(t, err) + _, err = EnsureTxSucceeded(ctx, backend, tx) + Require(t, err) + + initialBalance := new(big.Int).Lsh(big.NewInt(1), 200) + l1info.GenerateGenesisAccount("deployer", initialBalance) + l1info.GenerateGenesisAccount("asserter", initialBalance) + l1info.GenerateGenesisAccount("sequencer", initialBalance) + SendWaitTestTransactions(t, ctx, backend, []*types.Transaction{ + l1info.PrepareTx("Faucet", "RollupOwner", 30000, initialBalance, nil)}) + l1TransactionOpts := l1info.GetDefaultTransactOpts("RollupOwner", ctx) + locator, err := server_common.NewMachineLocator("") + Require(t, err) + + cfg := challenge_testing.GenerateRollupConfig( + false, + locator.LatestWasmModuleRoot(), + l1TransactionOpts.From, + chainId, + common.Address{}, + big.NewInt(1), + stakeToken, + ) + config, err := json.Marshal(params.ArbitrumDevTestChainConfig()) + if err != nil { + return nil + } + cfg.ChainConfig = string(config) + + addresses, err := setup.DeployFullRollupStack( + ctx, + backend, + &l1TransactionOpts, + l1info.GetAddress("sequencer"), + cfg, + false, + ) + Require(t, err) + + return &chaininfo.RollupAddresses{ + Bridge: addresses.Bridge, + Inbox: addresses.Inbox, + SequencerInbox: addresses.SequencerInbox, + Rollup: addresses.Rollup, + ValidatorUtils: addresses.ValidatorUtils, + ValidatorWalletCreator: addresses.ValidatorWalletCreator, + DeployedAt: addresses.DeployedAt, + } +} From 8c0df58c9bb326ced9ad4d283ee48879335ed1b5 Mon Sep 17 00:00:00 2001 From: amsanghi Date: Tue, 19 Sep 2023 16:39:36 +0530 Subject: [PATCH 04/11] minor fix --- bold | 2 +- go-ethereum | 2 +- nitro-testnode | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bold b/bold index e517fa7c4b..98bda6d104 160000 --- a/bold +++ b/bold @@ -1 +1 @@ -Subproject commit e517fa7c4b69052616b56f8d96e35c2f5207a382 +Subproject commit 98bda6d1047d3c7273f324866b3909c27410e88a diff --git a/go-ethereum b/go-ethereum index d312afd03b..b4bd0da114 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit d312afd03bba77aa2b4ea36e80b7308cd6528e80 +Subproject commit b4bd0da1142fe6bb81cac7e0794ebb4746b9885a diff --git a/nitro-testnode b/nitro-testnode index 14f24a1bad..7ad12c0f1b 160000 --- a/nitro-testnode +++ b/nitro-testnode @@ -1 +1 @@ -Subproject commit 14f24a1bad2625412602d06156156c380bd589d2 +Subproject commit 7ad12c0f1be75a72c7360d5258e0090f8225594e From 52934a83f07fbbbbcba460bf972288cc72c3f761 Mon Sep 17 00:00:00 2001 From: amsanghi Date: Tue, 19 Sep 2023 16:48:18 +0530 Subject: [PATCH 05/11] minor fix --- system_tests/staker_test.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/system_tests/staker_test.go b/system_tests/staker_test.go index edab59b8d5..4d979471fa 100644 --- a/system_tests/staker_test.go +++ b/system_tests/staker_test.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/params" mocksgen_bold "github.com/OffchainLabs/bold/solgen/go/mocksgen" + rollupgen_bold "github.com/OffchainLabs/bold/solgen/go/rollupgen" challenge_testing "github.com/OffchainLabs/bold/testing" "github.com/OffchainLabs/bold/testing/setup" @@ -489,11 +490,11 @@ func setupNonBoldStaker(t *testing.T, ctx context.Context) (*staker.Staker, info valConfig.EnableBold = true valConfig.StakerInterval = 100 * time.Millisecond - dp, err := arbnode.ValidatorDataposter(rawdb.NewTable(l2node.ArbDB, storage.BlockValidatorPrefix), l2node.L1Reader, &l1auth, NewFetcherFromConfig(arbnode.ConfigDefaultL1NonSequencerTest()), nil) + dp, err := arbnode.StakerDataposter(rawdb.NewTable(l2node.ArbDB, storage.StakerPrefix), l2node.L1Reader, &l1auth, NewFetcherFromConfig(arbnode.ConfigDefaultL1NonSequencerTest()), nil) if err != nil { t.Fatalf("Error creating validator dataposter: %v", err) } - valWallet, err := staker.NewContractValidatorWallet(dp, nil, l2node.DeployInfo.ValidatorWalletCreator, l2node.DeployInfo.Rollup, l2node.L1Reader, &l1auth, 0, func(common.Address) {}, 10000) + valWallet, err := staker.NewContractValidatorWallet(dp, nil, l2node.DeployInfo.ValidatorWalletCreator, l2node.DeployInfo.Rollup, l2node.L1Reader, &l1auth, 0, func(common.Address) {}, func() uint64 { return valConfig.ExtraGas }) Require(t, err) _, valStack := createTestValidationNode(t, ctx, &valnode.TestValidationConfig) blockValidatorConfig := staker.TestBlockValidatorConfig @@ -574,6 +575,12 @@ func deployBoldContracts( common.Address{}, big.NewInt(1), stakeToken, + rollupgen_bold.ExecutionState{ + GlobalState: rollupgen_bold.GlobalState{}, + MachineStatus: 1, + }, + big.NewInt(0), + common.Address{}, ) config, err := json.Marshal(params.ArbitrumDevTestChainConfig()) if err != nil { From 94594587c908a305de1385a29a1e24f4e9a4c66e Mon Sep 17 00:00:00 2001 From: amsanghi Date: Thu, 5 Oct 2023 19:34:31 +0530 Subject: [PATCH 06/11] Empty-Commit From 372a166e92e120d1aedc703d2994ce473033fb94 Mon Sep 17 00:00:00 2001 From: amsanghi Date: Thu, 5 Oct 2023 19:37:11 +0530 Subject: [PATCH 07/11] Empty-Commit From f3cd9fd82c1e041d9b6356e5c55a9aff38b68fdb Mon Sep 17 00:00:00 2001 From: amsanghi Date: Thu, 5 Oct 2023 19:44:30 +0530 Subject: [PATCH 08/11] update --- staker/manager.go | 6 +++--- system_tests/manager_test.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/staker/manager.go b/staker/manager.go index 8790a14374..f69136bca7 100644 --- a/staker/manager.go +++ b/staker/manager.go @@ -56,9 +56,9 @@ func NewManager( if err != nil { return nil, err } - challengeLeafHeights := make([]l2stateprovider.Height, numBigStepLevel.Uint64()+2) - for i := uint64(0); i <= numBigStepLevel.Uint64()+1; i++ { - leafHeight, err := managerBinding.GetLayerZeroEndHeight(&callOpts, uint8(i)) + challengeLeafHeights := make([]l2stateprovider.Height, numBigStepLevel+2) + for i := uint8(0); i <= numBigStepLevel+1; i++ { + leafHeight, err := managerBinding.GetLayerZeroEndHeight(&callOpts, i) if err != nil { return nil, err } diff --git a/system_tests/manager_test.go b/system_tests/manager_test.go index 5b8759cc64..5703fba7cc 100644 --- a/system_tests/manager_test.go +++ b/system_tests/manager_test.go @@ -69,7 +69,7 @@ func setupManger(t *testing.T, ctx context.Context) (*arbnode.Node, *node.Node, types.NewArbitrumSigner(types.NewLondonSigner(l2chainConfig.ChainID)), big.NewInt(l2pricing.InitialBaseFeeWei*2), transferGas, ) - _, l2node, l2client, _, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, l2chainConfig, nil, nil, l2info) + _, l2node, l2client, _, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, nil, l2chainConfig, nil, l2info) BridgeBalance(t, "Faucet", big.NewInt(1).Mul(big.NewInt(params.Ether), big.NewInt(10000)), l1info, l2info, l1client, l2client, ctx) l2info.GenerateAccount("BackgroundUser") balance := big.NewInt(params.Ether) @@ -95,7 +95,7 @@ func setupManger(t *testing.T, ctx context.Context) (*arbnode.Node, *node.Node, l2node.InboxReader, l2node.InboxTracker, l2node.TxStreamer, - l2node.Execution.Recorder, + l2node.Execution, l2node.ArbDB, nil, StaticFetcherFrom(t, &blockValidatorConfig), From 8b72013cd53fc41489e06ab7fd54e0cffe3b03e7 Mon Sep 17 00:00:00 2001 From: amsanghi Date: Wed, 15 Nov 2023 19:17:48 +0530 Subject: [PATCH 09/11] minor fix --- system_tests/manager_test.go | 115 ----------------------------------- 1 file changed, 115 deletions(-) delete mode 100644 system_tests/manager_test.go diff --git a/system_tests/manager_test.go b/system_tests/manager_test.go deleted file mode 100644 index 5703fba7cc..0000000000 --- a/system_tests/manager_test.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2023, Offchain Labs, Inc. -// For license information, see https://github.com/offchainlabs/bold/blob/main/LICENSE -package arbtest - -import ( - "context" - "math/big" - "reflect" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/params" - - "github.com/offchainlabs/nitro/arbnode" - "github.com/offchainlabs/nitro/arbos/l2pricing" - "github.com/offchainlabs/nitro/staker" - "github.com/offchainlabs/nitro/util" - "github.com/offchainlabs/nitro/util/testhelpers" - "github.com/offchainlabs/nitro/validator/valnode" - - protocol "github.com/OffchainLabs/bold/chain-abstraction" -) - -func TestExecutionStateMsgCount(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - l2node, l1stack, manager := setupManger(t, ctx) - defer requireClose(t, l1stack) - defer l2node.StopAndWait() - res, err := l2node.TxStreamer.ResultAtCount(1) - Require(t, err) - msgCount, err := manager.ExecutionStateMsgCount(ctx, &protocol.ExecutionState{GlobalState: protocol.GoGlobalState{Batch: 1, BlockHash: res.BlockHash}}) - Require(t, err) - if msgCount != 1 { - Fail(t, "Unexpected msg batch", msgCount, "(expected 1)") - } -} - -func TestExecutionStateAtMessageNumber(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - l2node, l1stack, manager := setupManger(t, ctx) - defer requireClose(t, l1stack) - defer l2node.StopAndWait() - res, err := l2node.TxStreamer.ResultAtCount(1) - Require(t, err) - expectedState := &protocol.ExecutionState{ - GlobalState: protocol.GoGlobalState{ - Batch: 1, - BlockHash: res.BlockHash, - }, - MachineStatus: protocol.MachineStatusFinished, - } - executionState, err := manager.ExecutionStateAtMessageNumber(ctx, 1) - Require(t, err) - if !reflect.DeepEqual(executionState, expectedState) { - Fail(t, "Unexpected executionState", executionState, "(expected ", expectedState, ")") - } - Require(t, err) -} - -func setupManger(t *testing.T, ctx context.Context) (*arbnode.Node, *node.Node, *staker.StateManager) { - var transferGas = util.NormalizeL2GasForL1GasInitial(800_000, params.GWei) // include room for aggregator L1 costs - l2chainConfig := params.ArbitrumDevTestChainConfig() - l2info := NewBlockChainTestInfo( - t, - types.NewArbitrumSigner(types.NewLondonSigner(l2chainConfig.ChainID)), big.NewInt(l2pricing.InitialBaseFeeWei*2), - transferGas, - ) - _, l2node, l2client, _, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, nil, l2chainConfig, nil, l2info) - BridgeBalance(t, "Faucet", big.NewInt(1).Mul(big.NewInt(params.Ether), big.NewInt(10000)), l1info, l2info, l1client, l2client, ctx) - l2info.GenerateAccount("BackgroundUser") - balance := big.NewInt(params.Ether) - balance.Mul(balance, big.NewInt(100)) - tx := l2info.PrepareTx("Faucet", "BackgroundUser", l2info.TransferGas, balance, nil) - err := l2client.SendTransaction(ctx, tx) - Require(t, err) - _, err = EnsureTxSucceeded(ctx, l2client, tx) - Require(t, err) - - for i := uint64(0); i < 10; i++ { - l2info.Accounts["BackgroundUser"].Nonce = i - tx = l2info.PrepareTx("BackgroundUser", "BackgroundUser", l2info.TransferGas, common.Big0, nil) - err = l2client.SendTransaction(ctx, tx) - Require(t, err) - _, err = EnsureTxSucceeded(ctx, l2client, tx) - Require(t, err) - } - - _, valStack := createTestValidationNode(t, ctx, &valnode.TestValidationConfig) - blockValidatorConfig := staker.TestBlockValidatorConfig - stateless, err := staker.NewStatelessBlockValidator( - l2node.InboxReader, - l2node.InboxTracker, - l2node.TxStreamer, - l2node.Execution, - l2node.ArbDB, - nil, - StaticFetcherFrom(t, &blockValidatorConfig), - valStack, - ) - Require(t, err) - err = stateless.Start(ctx) - Require(t, err) - manager, err := staker.NewStateManager(stateless, t.TempDir(), nil) - Require(t, err) - return l2node, l1stack, manager -} - -func Fail(t *testing.T, printables ...interface{}) { - t.Helper() - testhelpers.FailImpl(t, printables...) -} From fad6d7fd7bcfc9066ec36cbcef839d0d0acfd7bf Mon Sep 17 00:00:00 2001 From: amsanghi Date: Wed, 15 Nov 2023 19:19:41 +0530 Subject: [PATCH 10/11] Minor fix --- staker/staker.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/staker/staker.go b/staker/staker.go index 522b08088a..e050ed3c8a 100644 --- a/staker/staker.go +++ b/staker/staker.go @@ -535,12 +535,12 @@ func (s *Staker) checkAndSwitchToBoldStaker(ctx context.Context) (bool, error) { } _, err = userLogic.ExtraChallengeTimeBlocks(callOpts) if err != nil { - // Switch to Bold protocol since ExtraChallengeTimeBlocks does not exist in bold protocol . + // Switch to Bold protocol since ExtraChallengeTimeBlocks does not exist in bold protocol. auth, err := s.builder.Auth(ctx) if err != nil { return false, err } - boldManager, err := NewManager(ctx, rollupAddress, auth, *callOpts, s.client, s.statelessBlockValidator, "") + boldManager, err := NewManager(ctx, rollupAddress, auth, *callOpts, s.client, s.statelessBlockValidator, "", "") if err != nil { return false, err } From a237cf284e54ea460c8f554c31dea10724d09cf3 Mon Sep 17 00:00:00 2001 From: amsanghi Date: Wed, 15 Nov 2023 20:03:53 +0530 Subject: [PATCH 11/11] Use config --- staker/manager.go | 16 ++++++---- staker/staker.go | 12 +++---- staker/state_provider.go | 63 +++++++++++++++++++++++-------------- system_tests/staker_test.go | 2 +- 4 files changed, 56 insertions(+), 37 deletions(-) diff --git a/staker/manager.go b/staker/manager.go index 72731261d8..bef8a62882 100644 --- a/staker/manager.go +++ b/staker/manager.go @@ -7,7 +7,6 @@ import ( solimpl "github.com/OffchainLabs/bold/chain-abstraction/sol-implementation" challengemanager "github.com/OffchainLabs/bold/challenge-manager" - "github.com/OffchainLabs/bold/challenge-manager/types" l2stateprovider "github.com/OffchainLabs/bold/layer2-state-provider" "github.com/OffchainLabs/bold/solgen/go/challengeV2gen" "github.com/OffchainLabs/bold/solgen/go/rollupgen" @@ -25,8 +24,7 @@ func NewManager( callOpts bind.CallOpts, client arbutil.L1Interface, statelessBlockValidator *StatelessBlockValidator, - historyCacheBaseDir, - validatorName string, + config *BoldConfig, ) (*challengemanager.Manager, error) { chain, err := solimpl.NewAssertionChain( ctx, @@ -68,9 +66,9 @@ func NewManager( stateManager, err := NewStateManager( statelessBlockValidator, - historyCacheBaseDir, + config.MachineLeavesCachePath, challengeLeafHeights, - validatorName, + config.ValidatorName, ) if err != nil { return nil, err @@ -88,7 +86,13 @@ func NewManager( client, provider, rollupAddress, - challengemanager.WithMode(types.MakeMode), + challengemanager.WithName(config.ValidatorName), + challengemanager.WithMode(BoldModes[config.Mode]), + challengemanager.WithAssertionPostingInterval(config.AssertionPostingInterval), + challengemanager.WithAssertionScanningInterval(config.AssertionScanningInterval), + challengemanager.WithAssertionConfirmingInterval(config.AssertionConfirmingInterval), + challengemanager.WithEdgeTrackerWakeInterval(config.EdgeTrackerWakeInterval), + challengemanager.WithAddress(txOpts.From), ) if err != nil { return nil, err diff --git a/staker/staker.go b/staker/staker.go index e050ed3c8a..2d831f0186 100644 --- a/staker/staker.go +++ b/staker/staker.go @@ -75,7 +75,7 @@ func L1PostingStrategyAddOptions(prefix string, f *flag.FlagSet) { type L1ValidatorConfig struct { Enable bool `koanf:"enable"` - EnableBold bool `koanf:"enable-bold"` + Bold BoldConfig `koanf:"bold"` Strategy string `koanf:"strategy"` StakerInterval time.Duration `koanf:"staker-interval"` MakeAssertionInterval time.Duration `koanf:"make-assertion-interval"` @@ -143,7 +143,7 @@ func (c *L1ValidatorConfig) Validate() error { var DefaultL1ValidatorConfig = L1ValidatorConfig{ Enable: true, - EnableBold: false, + Bold: DefaultBoldConfig, Strategy: "Watchtower", StakerInterval: time.Minute, MakeAssertionInterval: time.Hour, @@ -194,7 +194,7 @@ var DefaultValidatorL1WalletConfig = genericconf.WalletConfig{ func L1ValidatorConfigAddOptions(prefix string, f *flag.FlagSet) { f.Bool(prefix+".enable", DefaultL1ValidatorConfig.Enable, "enable validator") - f.Bool(prefix+".enable-bold", DefaultL1ValidatorConfig.EnableBold, "enable switch check to bold validator") + BoldConfigAddOptions(prefix+".bold", f) f.String(prefix+".strategy", DefaultL1ValidatorConfig.Strategy, "L1 validator strategy, either watchtower, defensive, stakeLatest, or makeNodes") f.Duration(prefix+".staker-interval", DefaultL1ValidatorConfig.StakerInterval, "how often the L1 validator should check the status of the L1 rollup and maybe take action with its stake") f.Duration(prefix+".make-assertion-interval", DefaultL1ValidatorConfig.MakeAssertionInterval, "if configured with the makeNodes strategy, how often to create new assertions (bypassed in case of a dispute)") @@ -310,7 +310,7 @@ func NewStaker( stakedNotifiers = append(stakedNotifiers, blockValidator) } var bridge *bridgegen.IBridge - if config.EnableBold { + if config.Bold.Enable { bridge, err = bridgegen.NewIBridge(bridgeAddress, client) if err != nil { return nil, err @@ -523,7 +523,7 @@ func (s *Staker) Start(ctxIn context.Context) { func (s *Staker) checkAndSwitchToBoldStaker(ctx context.Context) (bool, error) { switchedToBoldProtocol := false - if s.config.EnableBold { + if s.config.Bold.Enable { callOpts := s.getCallOpts(ctx) rollupAddress, err := s.bridge.Rollup(callOpts) if err != nil { @@ -540,7 +540,7 @@ func (s *Staker) checkAndSwitchToBoldStaker(ctx context.Context) (bool, error) { if err != nil { return false, err } - boldManager, err := NewManager(ctx, rollupAddress, auth, *callOpts, s.client, s.statelessBlockValidator, "", "") + boldManager, err := NewManager(ctx, rollupAddress, auth, *callOpts, s.client, s.statelessBlockValidator, &s.config.Bold) if err != nil { return false, err } diff --git a/staker/state_provider.go b/staker/state_provider.go index 48c78c6c7e..c4fe00feb1 100644 --- a/staker/state_provider.go +++ b/staker/state_provider.go @@ -8,13 +8,18 @@ import ( "fmt" "strings" "sync" + "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + flag "github.com/spf13/pflag" + protocol "github.com/OffchainLabs/bold/chain-abstraction" + "github.com/OffchainLabs/bold/challenge-manager/types" "github.com/OffchainLabs/bold/containers/option" l2stateprovider "github.com/OffchainLabs/bold/layer2-state-provider" + "github.com/offchainlabs/nitro/arbutil" challengecache "github.com/offchainlabs/nitro/staker/challenge-cache" "github.com/offchainlabs/nitro/validator" @@ -32,33 +37,43 @@ var ( ) type BoldConfig struct { - Enable bool `koanf:"enable"` - Mode string `koanf:"mode"` - BlockChallengeLeafHeight uint64 `koanf:"block-challenge-leaf-height"` - BigStepLeafHeight uint64 `koanf:"big-step-leaf-height"` - SmallStepLeafHeight uint64 `koanf:"small-step-leaf-height"` - NumBigSteps uint64 `koanf:"num-big-steps"` - ValidatorName string `koanf:"validator-name"` - MachineLeavesCachePath string `koanf:"machine-leaves-cache-path"` - AssertionPostingIntervalSeconds uint64 `koanf:"assertion-posting-interval-seconds"` - AssertionScanningIntervalSeconds uint64 `koanf:"assertion-scanning-interval-seconds"` - AssertionConfirmingIntervalSeconds uint64 `koanf:"assertion-confirming-interval-seconds"` - EdgeTrackerWakeIntervalSeconds uint64 `koanf:"edge-tracker-wake-interval-seconds"` + Enable bool `koanf:"enable"` + Mode string `koanf:"mode"` + ValidatorName string `koanf:"validator-name"` + MachineLeavesCachePath string `koanf:"machine-leaves-cache-path"` + AssertionPostingInterval time.Duration `koanf:"assertion-posting-interval"` + AssertionScanningInterval time.Duration `koanf:"assertion-scanning-interval"` + AssertionConfirmingInterval time.Duration `koanf:"assertion-confirming-interval"` + EdgeTrackerWakeInterval time.Duration `koanf:"edge-tracker-wake-interval"` } var DefaultBoldConfig = BoldConfig{ - Enable: false, - Mode: "make-mode", - BlockChallengeLeafHeight: 1 << 5, - BigStepLeafHeight: 1 << 5, - SmallStepLeafHeight: 1 << 7, - NumBigSteps: 5, - ValidatorName: "default-validator", - MachineLeavesCachePath: "/tmp/machine-leaves-cache", - AssertionPostingIntervalSeconds: 30, - AssertionScanningIntervalSeconds: 30, - AssertionConfirmingIntervalSeconds: 60, - EdgeTrackerWakeIntervalSeconds: 1, + Enable: false, + Mode: "make-mode", + ValidatorName: "default-validator", + MachineLeavesCachePath: "/tmp/machine-leaves-cache", + AssertionPostingInterval: 30 * time.Second, + AssertionScanningInterval: 30 * time.Second, + AssertionConfirmingInterval: 60 * time.Second, + EdgeTrackerWakeInterval: 1 * time.Second, +} + +var BoldModes = map[string]types.Mode{ + "watch-tower-mode": types.WatchTowerMode, + "resolve-mode": types.ResolveMode, + "defensive-mode": types.DefensiveMode, + "make-mode": types.MakeMode, +} + +func BoldConfigAddOptions(prefix string, f *flag.FlagSet) { + f.Bool(prefix+".enable", DefaultBoldConfig.Enable, "enable bold protocol") + f.String(prefix+".mode", DefaultBoldConfig.Mode, "mode for bold protocol") + f.String(prefix+".validator-name", DefaultBoldConfig.ValidatorName, "name of validator") + f.String(prefix+".machine-leaves-cache-path", DefaultBoldConfig.MachineLeavesCachePath, "path to machine leaves cache") + f.Duration(prefix+".assertion-posting-interval", DefaultBoldConfig.AssertionPostingInterval, "interval for posting assertions") + f.Duration(prefix+".assertion-scanning-interval", DefaultBoldConfig.AssertionScanningInterval, "interval for scanning assertions") + f.Duration(prefix+".assertion-confirming-interval", DefaultBoldConfig.AssertionConfirmingInterval, "interval for confirming assertions") + f.Duration(prefix+".edge-tracker-wake-interval", DefaultBoldConfig.EdgeTrackerWakeInterval, "interval for waking edge tracker") } type StateManager struct { diff --git a/system_tests/staker_test.go b/system_tests/staker_test.go index b30d804411..9d56eac356 100644 --- a/system_tests/staker_test.go +++ b/system_tests/staker_test.go @@ -506,7 +506,7 @@ func setupNonBoldStaker(t *testing.T, ctx context.Context) (*staker.Staker, info Require(t, err) valConfig := staker.DefaultL1ValidatorConfig valConfig.Strategy = "WatchTower" - valConfig.EnableBold = true + valConfig.Bold = staker.DefaultBoldConfig valConfig.StakerInterval = 100 * time.Millisecond dp, err := arbnode.StakerDataposter(ctx, rawdb.NewTable(l2node.ArbDB, storage.StakerPrefix), l2node.L1Reader, &l1auth, NewFetcherFromConfig(arbnode.ConfigDefaultL1NonSequencerTest()), nil)