Skip to content

Commit

Permalink
Factor out validator wallets and transaction builder into separate pa…
Browse files Browse the repository at this point in the history
…ckages
  • Loading branch information
anodar committed Sep 18, 2023
1 parent 8b7db54 commit fa69b19
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 47 deletions.
5 changes: 3 additions & 2 deletions arbnode/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,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 @@ -826,15 +827,15 @@ func createNodeImpl(
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)
wallet, err = validatorwallet.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)
wallet, err = validatorwallet.NewEoaValidatorWallet(dp, deployInfo.Rollup, l1client, txOptsValidator, getExtraGas)
if 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.ValidatorTxBuilder
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.NewValidatorTxBuilder(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.ValidatorTxBuilder, 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
25 changes: 24 additions & 1 deletion 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,6 +15,15 @@ import (
"github.com/offchainlabs/nitro/arbutil"
)

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, *ValidatorTxBuilder, common.Address) (*types.Transaction, error)
AuthIfEoa() *bind.TransactOpts
}

// ValidatorTxBuilder 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.
Expand Down Expand Up @@ -101,3 +110,17 @@ func (b *ValidatorTxBuilder) AuthWithAmount(ctx context.Context, amount *big.Int
func (b *ValidatorTxBuilder) Auth(ctx context.Context) (*bind.TransactOpts, error) {
return b.AuthWithAmount(ctx, common.Big0)
}

func (b *ValidatorTxBuilder) 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 *ValidatorTxBuilder) BuilderAuth() *bind.TransactOpts {
return b.builderAuth
}

func (b *ValidatorTxBuilder) WalletAddress() *common.Address {
return b.wallet.Address()
}
41 changes: 13 additions & 28 deletions staker/validator_wallet.go → staker/validatorwallet/contract.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 validatorwallet

import (
"context"
Expand All @@ -22,6 +22,7 @@ import (
"github.com/offchainlabs/nitro/arbnode/dataposter"
"github.com/offchainlabs/nitro/arbutil"
"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 All @@ -43,27 +44,6 @@ func init() {
walletCreatedID = parsedValidatorWalletCreator.Events["WalletCreated"].ID
}

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, *ValidatorTxBuilder, 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
}

type ContractValidatorWallet struct {
con *rollupgen.ValidatorWallet
address atomic.Pointer[common.Address]
Expand All @@ -79,8 +59,6 @@ type ContractValidatorWallet struct {
getExtraGas func() uint64
}

var _ ValidatorWalletInterface = (*ContractValidatorWallet)(nil)

func NewContractValidatorWallet(dp *dataposter.DataPoster, address *common.Address, walletFactoryAddr, rollupAddress common.Address, l1Reader *headerreader.HeaderReader, auth *bind.TransactOpts, rollupFromBlock int64, onWalletCreated func(common.Address),
getExtraGas func() uint64) (*ContractValidatorWallet, error) {
var con *rollupgen.ValidatorWallet
Expand Down Expand Up @@ -257,8 +235,8 @@ func combineTxes(txes []*types.Transaction) ([][]byte, []common.Address, []*big.
}

// Not thread safe! Don't call this from multiple threads at the same time.
func (v *ContractValidatorWallet) ExecuteTransactions(ctx context.Context, builder *ValidatorTxBuilder, gasRefunder common.Address) (*types.Transaction, error) {
txes := builder.transactions
func (v *ContractValidatorWallet) ExecuteTransactions(ctx context.Context, builder *txbuilder.ValidatorTxBuilder, gasRefunder common.Address) (*types.Transaction, error) {
txes := builder.Transactions()
if len(txes) == 0 {
return nil, nil
}
Expand All @@ -273,7 +251,7 @@ func (v *ContractValidatorWallet) ExecuteTransactions(ctx context.Context, build
if err != nil {
return nil, err
}
builder.transactions = nil
builder.ClearTransactions()
return arbTx, nil
}

Expand Down Expand Up @@ -314,7 +292,7 @@ func (v *ContractValidatorWallet) ExecuteTransactions(ctx context.Context, build
if err != nil {
return nil, err
}
builder.transactions = nil
builder.ClearTransactions()
return arbTx, nil
}

Expand Down Expand Up @@ -422,6 +400,13 @@ func (b *ContractValidatorWallet) DataPoster() *dataposter.DataPoster {
return b.dataPoster
}

type L1ReaderInterface interface {
Client() arbutil.L1Interface
Subscribe(bool) (<-chan *types.Header, func())
WaitForTxApproval(ctx context.Context, tx *types.Transaction) (*types.Receipt, error)
UseFinalityData() bool
}

func GetValidatorWalletContract(
ctx context.Context,
validatorWalletFactoryAddr common.Address,
Expand Down
11 changes: 5 additions & 6 deletions staker/eoa_validator_wallet.go → staker/validatorwallet/eoa.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 validatorwallet

import (
"context"
Expand All @@ -15,6 +15,7 @@ import (
"github.com/offchainlabs/nitro/arbutil"
"github.com/offchainlabs/nitro/solgen/go/challengegen"
"github.com/offchainlabs/nitro/solgen/go/rollupgen"
"github.com/offchainlabs/nitro/staker/txbuilder"
)

type EoaValidatorWallet struct {
Expand All @@ -27,8 +28,6 @@ type EoaValidatorWallet struct {
getExtraGas func() uint64
}

var _ ValidatorWalletInterface = (*EoaValidatorWallet)(nil)

func NewEoaValidatorWallet(dataPoster *dataposter.DataPoster, rollupAddress common.Address, l1Client arbutil.L1Interface, auth *bind.TransactOpts, getExtraGas func() uint64) (*EoaValidatorWallet, error) {
return &EoaValidatorWallet{
auth: auth,
Expand Down Expand Up @@ -82,11 +81,11 @@ func (w *EoaValidatorWallet) TestTransactions(context.Context, []*types.Transact
return nil
}

func (w *EoaValidatorWallet) ExecuteTransactions(ctx context.Context, builder *ValidatorTxBuilder, _ common.Address) (*types.Transaction, error) {
if len(builder.transactions) == 0 {
func (w *EoaValidatorWallet) ExecuteTransactions(ctx context.Context, builder *txbuilder.ValidatorTxBuilder, _ common.Address) (*types.Transaction, error) {
if len(builder.Transactions()) == 0 {
return nil, nil
}
tx := builder.transactions[0] // we ignore future txs and only execute the first
tx := builder.Transactions()[0] // we ignore future txs and only execute the first
return w.postTransaction(ctx, tx)
}

Expand Down
11 changes: 6 additions & 5 deletions system_tests/staker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/offchainlabs/nitro/solgen/go/mocksgen"
"github.com/offchainlabs/nitro/solgen/go/rollupgen"
"github.com/offchainlabs/nitro/staker"
"github.com/offchainlabs/nitro/staker/validatorwallet"
"github.com/offchainlabs/nitro/util"
"github.com/offchainlabs/nitro/util/arbmath"
"github.com/offchainlabs/nitro/util/colors"
Expand Down Expand Up @@ -104,10 +105,10 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool)
TransferBalance(t, "Faucet", "ValidatorB", balance, l1info, l1client, ctx)
l1authB := l1info.GetDefaultTransactOpts("ValidatorB", ctx)

valWalletAddrAPtr, err := staker.GetValidatorWalletContract(ctx, l2nodeA.DeployInfo.ValidatorWalletCreator, 0, &l1authA, l2nodeA.L1Reader, true)
valWalletAddrAPtr, err := validatorwallet.GetValidatorWalletContract(ctx, l2nodeA.DeployInfo.ValidatorWalletCreator, 0, &l1authA, l2nodeA.L1Reader, true)
Require(t, err)
valWalletAddrA := *valWalletAddrAPtr
valWalletAddrCheck, err := staker.GetValidatorWalletContract(ctx, l2nodeA.DeployInfo.ValidatorWalletCreator, 0, &l1authA, l2nodeA.L1Reader, true)
valWalletAddrCheck, err := validatorwallet.GetValidatorWalletContract(ctx, l2nodeA.DeployInfo.ValidatorWalletCreator, 0, &l1authA, l2nodeA.L1Reader, true)
Require(t, err)
if valWalletAddrA == *valWalletAddrCheck {
Require(t, err, "didn't cache validator wallet address", valWalletAddrA.String(), "vs", valWalletAddrCheck.String())
Expand All @@ -134,7 +135,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool)
if err != nil {
t.Fatalf("Error creating validator dataposter: %v", err)
}
valWalletA, err := staker.NewContractValidatorWallet(dpA, nil, l2nodeA.DeployInfo.ValidatorWalletCreator, l2nodeA.DeployInfo.Rollup, l2nodeA.L1Reader, &l1authA, 0, func(common.Address) {}, func() uint64 { return valConfig.ExtraGas })
valWalletA, err := validatorwallet.NewContractValidatorWallet(dpA, nil, l2nodeA.DeployInfo.ValidatorWalletCreator, l2nodeA.DeployInfo.Rollup, l2nodeA.L1Reader, &l1authA, 0, func(common.Address) {}, func() uint64 { return valConfig.ExtraGas })
Require(t, err)
if honestStakerInactive {
valConfig.Strategy = "Defensive"
Expand Down Expand Up @@ -182,7 +183,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool)
if err != nil {
t.Fatalf("Error creating validator dataposter: %v", err)
}
valWalletB, err := staker.NewEoaValidatorWallet(dpB, l2nodeB.DeployInfo.Rollup, l2nodeB.L1Reader.Client(), &l1authB, func() uint64 { return 0 })
valWalletB, err := validatorwallet.NewEoaValidatorWallet(dpB, l2nodeB.DeployInfo.Rollup, l2nodeB.L1Reader.Client(), &l1authB, func() uint64 { return 0 })
Require(t, err)
valConfig.Strategy = "MakeNodes"
statelessB, err := staker.NewStatelessBlockValidator(
Expand Down Expand Up @@ -221,7 +222,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool)
if err != nil {
t.Fatalf("Error creating validator dataposter: %v", err)
}
valWalletC, err := staker.NewContractValidatorWallet(dpC, nil, l2nodeA.DeployInfo.ValidatorWalletCreator, l2nodeA.DeployInfo.Rollup, l2nodeA.L1Reader, nil, 0, func(common.Address) {}, func() uint64 { return 10000 })
valWalletC, err := validatorwallet.NewContractValidatorWallet(dpC, nil, l2nodeA.DeployInfo.ValidatorWalletCreator, l2nodeA.DeployInfo.Rollup, l2nodeA.L1Reader, nil, 0, func(common.Address) {}, func() uint64 { return 10000 })
Require(t, err)
valConfig.Strategy = "Watchtower"
stakerC, err := staker.NewStaker(
Expand Down

0 comments on commit fa69b19

Please sign in to comment.