Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to switch to new bold protocol staker during the contract upgrade #1836

Merged
merged 17 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion arbnode/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,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.Bridge, fatalErrChan)
if err != nil {
return nil, err
}
Expand Down
16 changes: 10 additions & 6 deletions staker/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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,
Expand Down Expand Up @@ -68,9 +66,9 @@ func NewManager(

stateManager, err := NewStateManager(
statelessBlockValidator,
historyCacheBaseDir,
config.MachineLeavesCachePath,
challengeLeafHeights,
validatorName,
config.ValidatorName,
)
if err != nil {
return nil, err
Expand All @@ -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
Expand Down
64 changes: 64 additions & 0 deletions staker/staker.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
"github.com/offchainlabs/nitro/arbnode/redislock"
"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/staker/txbuilder"
"github.com/offchainlabs/nitro/util/arbmath"
"github.com/offchainlabs/nitro/util/headerreader"
Expand Down Expand Up @@ -74,6 +76,7 @@ func L1PostingStrategyAddOptions(prefix string, f *flag.FlagSet) {

type L1ValidatorConfig struct {
Enable bool `koanf:"enable"`
Bold BoldConfig `koanf:"bold"`
Strategy string `koanf:"strategy"`
StakerInterval time.Duration `koanf:"staker-interval"`
MakeAssertionInterval time.Duration `koanf:"make-assertion-interval"`
Expand Down Expand Up @@ -141,6 +144,7 @@ func (c *L1ValidatorConfig) Validate() error {

var DefaultL1ValidatorConfig = L1ValidatorConfig{
Enable: true,
Bold: DefaultBoldConfig,
Strategy: "Watchtower",
StakerInterval: time.Minute,
MakeAssertionInterval: time.Hour,
Expand Down Expand Up @@ -191,6 +195,7 @@ var DefaultValidatorL1WalletConfig = genericconf.WalletConfig{

func L1ValidatorConfigAddOptions(prefix string, f *flag.FlagSet) {
f.Bool(prefix+".enable", DefaultL1ValidatorConfig.Enable, "enable 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)")
Expand Down Expand Up @@ -253,6 +258,7 @@ type Staker struct {
bringActiveUntilNode uint64
inboxReader InboxReaderInterface
statelessBlockValidator *StatelessBlockValidator
bridge *bridgegen.IBridge
fatalErr chan<- error
}

Expand Down Expand Up @@ -287,6 +293,7 @@ func NewStaker(
stakedNotifiers []LatestStakedNotifier,
confirmedNotifiers []LatestConfirmedNotifier,
validatorUtilsAddress common.Address,
bridgeAddress common.Address,
fatalErr chan<- error,
) (*Staker, error) {

Expand All @@ -303,6 +310,13 @@ func NewStaker(
if config.StartValidationFromStaked && blockValidator != nil {
stakedNotifiers = append(stakedNotifiers, blockValidator)
}
var bridge *bridgegen.IBridge
if config.Bold.Enable {
bridge, err = bridgegen.NewIBridge(bridgeAddress, client)
if err != nil {
return nil, err
}
}
return &Staker{
L1Validator: val,
l1Reader: l1Reader,
Expand All @@ -314,6 +328,7 @@ func NewStaker(
lastActCalledBlock: nil,
inboxReader: statelessBlockValidator.inboxReader,
statelessBlockValidator: statelessBlockValidator,
bridge: bridge,
fatalErr: fatalErr,
}, nil
}
Expand Down Expand Up @@ -428,6 +443,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)
Expand Down Expand Up @@ -486,6 +508,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.Bold.Enable {
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, &s.config.Bold)
if err != nil {
return false, err
}
boldManager.Start(ctx)
switchedToBoldProtocol = true
}
}
return switchedToBoldProtocol, nil
}

func (s *Staker) IsWhitelisted(ctx context.Context) (bool, error) {
Expand Down
63 changes: 39 additions & 24 deletions staker/state_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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 {
Expand Down
Loading
Loading