Skip to content

Commit

Permalink
Merge pull request #1836 from OffchainLabs/staker_bold
Browse files Browse the repository at this point in the history
Add option to switch to new bold protocol staker during the contract upgrade
  • Loading branch information
amsanghi authored Nov 28, 2023
2 parents b16afd7 + 8b68e35 commit 9f46865
Show file tree
Hide file tree
Showing 5 changed files with 313 additions and 31 deletions.
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

0 comments on commit 9f46865

Please sign in to comment.