Skip to content

Commit

Permalink
Merge branch 'master' into mem-limit-count-active-pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Tristan-Wilson authored Sep 27, 2023
2 parents a683c2c + efba003 commit 777bd01
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 122 deletions.
53 changes: 29 additions & 24 deletions arbnode/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"math/big"
"strings"
"time"

flag "github.com/spf13/pflag"
Expand Down Expand Up @@ -43,6 +44,7 @@ import (
"github.com/offchainlabs/nitro/solgen/go/precompilesgen"
"github.com/offchainlabs/nitro/solgen/go/rollupgen"
"github.com/offchainlabs/nitro/staker"
"github.com/offchainlabs/nitro/staker/validatorwallet"
"github.com/offchainlabs/nitro/util/contracts"
"github.com/offchainlabs/nitro/util/headerreader"
"github.com/offchainlabs/nitro/util/redisutil"
Expand Down Expand Up @@ -816,28 +818,32 @@ func createNodeImpl(
return nil, err
}
getExtraGas := func() uint64 { return configFetcher.Get().Staker.ExtraGas }
var wallet staker.ValidatorWalletInterface
if config.Staker.UseSmartContractWallet || txOptsValidator == nil {
var existingWalletAddress *common.Address
if len(config.Staker.ContractWalletAddress) > 0 {
if !common.IsHexAddress(config.Staker.ContractWalletAddress) {
log.Error("invalid validator smart contract wallet", "addr", config.Staker.ContractWalletAddress)
return nil, errors.New("invalid validator smart contract wallet address")
// TODO: factor this out into separate helper, and split rest of node
// creation into multiple helpers.
var wallet staker.ValidatorWalletInterface = validatorwallet.NewNoOp(l1client)
if !strings.EqualFold(config.Staker.Strategy, "watchtower") {
if config.Staker.UseSmartContractWallet || txOptsValidator == nil {
var existingWalletAddress *common.Address
if len(config.Staker.ContractWalletAddress) > 0 {
if !common.IsHexAddress(config.Staker.ContractWalletAddress) {
log.Error("invalid validator smart contract wallet", "addr", config.Staker.ContractWalletAddress)
return nil, errors.New("invalid validator smart contract wallet address")
}
tmpAddress := common.HexToAddress(config.Staker.ContractWalletAddress)
existingWalletAddress = &tmpAddress
}
wallet, err = validatorwallet.NewContract(dp, existingWalletAddress, deployInfo.ValidatorWalletCreator, deployInfo.Rollup, l1Reader, txOptsValidator, int64(deployInfo.DeployedAt), func(common.Address) {}, getExtraGas)
if err != nil {
return nil, err
}
} else {
if len(config.Staker.ContractWalletAddress) > 0 {
return nil, errors.New("validator contract wallet specified but flag to use a smart contract wallet was not specified")
}
wallet, err = validatorwallet.NewEOA(dp, deployInfo.Rollup, l1client, txOptsValidator, getExtraGas)
if err != nil {
return nil, err
}
tmpAddress := common.HexToAddress(config.Staker.ContractWalletAddress)
existingWalletAddress = &tmpAddress
}
wallet, err = staker.NewContractValidatorWallet(dp, existingWalletAddress, deployInfo.ValidatorWalletCreator, deployInfo.Rollup, l1Reader, txOptsValidator, int64(deployInfo.DeployedAt), func(common.Address) {}, getExtraGas)
if err != nil {
return nil, err
}
} else {
if len(config.Staker.ContractWalletAddress) > 0 {
return nil, errors.New("validator contract wallet specified but flag to use a smart contract wallet was not specified")
}
wallet, err = staker.NewEoaValidatorWallet(dp, deployInfo.Rollup, l1client, txOptsValidator, getExtraGas)
if err != nil {
return nil, err
}
}

Expand All @@ -851,9 +857,8 @@ func createNodeImpl(
if err != nil {
return nil, err
}
if stakerObj.Strategy() != staker.WatchtowerStrategy {
err := wallet.Initialize(ctx)
if err != nil {
if stakerObj.Strategy() == staker.WatchtowerStrategy {
if err := wallet.Initialize(ctx); err != nil {
return nil, err
}
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/nitro/nitro.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import (
_ "github.com/offchainlabs/nitro/nodeInterface"
"github.com/offchainlabs/nitro/solgen/go/precompilesgen"
"github.com/offchainlabs/nitro/staker"
"github.com/offchainlabs/nitro/staker/validatorwallet"
"github.com/offchainlabs/nitro/util/colors"
"github.com/offchainlabs/nitro/util/headerreader"
"github.com/offchainlabs/nitro/util/rpcclient"
Expand Down Expand Up @@ -367,7 +368,7 @@ func mainImpl() int {
if err != nil {
log.Crit("error getting rollup addresses config", "err", err)
}
addr, err := staker.GetValidatorWalletContract(ctx, deployInfo.ValidatorWalletCreator, int64(deployInfo.DeployedAt), l1TransactionOptsValidator, l1Reader, true)
addr, err := validatorwallet.GetValidatorWalletContract(ctx, deployInfo.ValidatorWalletCreator, int64(deployInfo.DeployedAt), l1TransactionOptsValidator, l1Reader, true)
if err != nil {
log.Crit("error creating validator wallet contract", "error", err, "address", l1TransactionOptsValidator.From.Hex())
}
Expand Down
5 changes: 3 additions & 2 deletions staker/l1_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"github.com/offchainlabs/nitro/arbstate"
"github.com/offchainlabs/nitro/staker/txbuilder"
"github.com/offchainlabs/nitro/util/arbmath"
"github.com/offchainlabs/nitro/validator"

Expand Down Expand Up @@ -45,7 +46,7 @@ type L1Validator struct {
rollupAddress common.Address
validatorUtils *rollupgen.ValidatorUtils
client arbutil.L1Interface
builder *ValidatorTxBuilder
builder *txbuilder.Builder
wallet ValidatorWalletInterface
callOpts bind.CallOpts

Expand All @@ -66,7 +67,7 @@ func NewL1Validator(
txStreamer TransactionStreamerInterface,
blockValidator *BlockValidator,
) (*L1Validator, error) {
builder, err := NewValidatorTxBuilder(wallet)
builder, err := txbuilder.NewBuilder(wallet)
if err != nil {
return nil, err
}
Expand Down
26 changes: 24 additions & 2 deletions staker/staker.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/offchainlabs/nitro/arbnode/redislock"
"github.com/offchainlabs/nitro/arbutil"
"github.com/offchainlabs/nitro/cmd/genericconf"
"github.com/offchainlabs/nitro/staker/txbuilder"
"github.com/offchainlabs/nitro/util/arbmath"
"github.com/offchainlabs/nitro/util/stopwaiter"
"github.com/offchainlabs/nitro/validator"
Expand Down Expand Up @@ -254,6 +255,27 @@ type Staker struct {
fatalErr chan<- error
}

type ValidatorWalletInterface interface {
Initialize(context.Context) error
// Address must be able to be called concurrently with other functions
Address() *common.Address
// Address must be able to be called concurrently with other functions
AddressOrZero() common.Address
TxSenderAddress() *common.Address
RollupAddress() common.Address
ChallengeManagerAddress() common.Address
L1Client() arbutil.L1Interface
TestTransactions(context.Context, []*types.Transaction) error
ExecuteTransactions(context.Context, *txbuilder.Builder, common.Address) (*types.Transaction, error)
TimeoutChallenges(context.Context, []uint64) (*types.Transaction, error)
CanBatchTxs() bool
AuthIfEoa() *bind.TransactOpts
Start(context.Context)
StopAndWait()
// May be nil
DataPoster() *dataposter.DataPoster
}

func NewStaker(
l1Reader L1ReaderInterface,
wallet ValidatorWalletInterface,
Expand Down Expand Up @@ -777,8 +799,8 @@ func (s *Staker) handleConflict(ctx context.Context, info *StakerInfo) error {
newChallengeManager, err := NewChallengeManager(
ctx,
s.builder,
s.builder.builderAuth,
*s.builder.wallet.Address(),
s.builder.BuilderAuth(),
*s.builder.WalletAddress(),
s.wallet.ChallengeManagerAddress(),
*info.CurrentChallenge,
s.statelessBlockValidator,
Expand Down
45 changes: 34 additions & 11 deletions staker/builder_backend.go → staker/txbuilder/builder.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/nitro/blob/master/LICENSE

package staker
package txbuilder

import (
"context"
Expand All @@ -15,20 +15,29 @@ import (
"github.com/offchainlabs/nitro/arbutil"
)

// ValidatorTxBuilder combines any transactions sent to it via SendTransaction into one batch,
type ValidatorWalletInterface interface {
// Address must be able to be called concurrently with other functions
Address() *common.Address
L1Client() arbutil.L1Interface
TestTransactions(context.Context, []*types.Transaction) error
ExecuteTransactions(context.Context, *Builder, common.Address) (*types.Transaction, error)
AuthIfEoa() *bind.TransactOpts
}

// Builder combines any transactions sent to it via SendTransaction into one batch,
// which is then sent to the validator wallet.
// This lets the validator make multiple atomic transactions.
// This inherits from an eth client so it can be used as an L1Interface,
// where it transparently intercepts calls to SendTransaction and queues them for the next batch.
type ValidatorTxBuilder struct {
type Builder struct {
arbutil.L1Interface
transactions []*types.Transaction
builderAuth *bind.TransactOpts
isAuthFake bool
wallet ValidatorWalletInterface
}

func NewValidatorTxBuilder(wallet ValidatorWalletInterface) (*ValidatorTxBuilder, error) {
func NewBuilder(wallet ValidatorWalletInterface) (*Builder, error) {
randKey, err := crypto.GenerateKey()
if err != nil {
return nil, err
Expand All @@ -43,30 +52,30 @@ func NewValidatorTxBuilder(wallet ValidatorWalletInterface) (*ValidatorTxBuilder
}
isAuthFake = true
}
return &ValidatorTxBuilder{
return &Builder{
builderAuth: builderAuth,
wallet: wallet,
L1Interface: wallet.L1Client(),
isAuthFake: isAuthFake,
}, nil
}

func (b *ValidatorTxBuilder) BuildingTransactionCount() int {
func (b *Builder) BuildingTransactionCount() int {
return len(b.transactions)
}

func (b *ValidatorTxBuilder) ClearTransactions() {
func (b *Builder) ClearTransactions() {
b.transactions = nil
}

func (b *ValidatorTxBuilder) EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error) {
func (b *Builder) EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error) {
if len(b.transactions) == 0 && !b.isAuthFake {
return b.L1Interface.EstimateGas(ctx, call)
}
return 0, nil
}

func (b *ValidatorTxBuilder) SendTransaction(ctx context.Context, tx *types.Transaction) error {
func (b *Builder) SendTransaction(ctx context.Context, tx *types.Transaction) error {
b.transactions = append(b.transactions, tx)
err := b.wallet.TestTransactions(ctx, b.transactions)
if err != nil {
Expand All @@ -80,7 +89,7 @@ func (b *ValidatorTxBuilder) SendTransaction(ctx context.Context, tx *types.Tran
// While this is not currently required, it's recommended not to reuse the returned auth for multiple transactions,
// as for an EOA this has the nonce in it. However, the EOA wwallet currently will only publish the first created tx,
// which is why that doesn't really matter.
func (b *ValidatorTxBuilder) AuthWithAmount(ctx context.Context, amount *big.Int) (*bind.TransactOpts, error) {
func (b *Builder) AuthWithAmount(ctx context.Context, amount *big.Int) (*bind.TransactOpts, error) {
nonce, err := b.NonceAt(ctx, b.builderAuth.From, nil)
if err != nil {
return nil, err
Expand All @@ -98,6 +107,20 @@ func (b *ValidatorTxBuilder) AuthWithAmount(ctx context.Context, amount *big.Int

// Auth is the same as AuthWithAmount with a 0 amount specified.
// See AuthWithAmount docs for important details.
func (b *ValidatorTxBuilder) Auth(ctx context.Context) (*bind.TransactOpts, error) {
func (b *Builder) Auth(ctx context.Context) (*bind.TransactOpts, error) {
return b.AuthWithAmount(ctx, common.Big0)
}

func (b *Builder) Transactions() []*types.Transaction {
return b.transactions
}

// Auth is the same as AuthWithAmount with a 0 amount specified.
// See AuthWithAmount docs for important details.
func (b *Builder) BuilderAuth() *bind.TransactOpts {
return b.builderAuth
}

func (b *Builder) WalletAddress() *common.Address {
return b.wallet.Address()
}
Loading

0 comments on commit 777bd01

Please sign in to comment.