Commit 1084fbec authored by Michael de Hoog's avatar Michael de Hoog Committed by GitHub

[Bedrock] op-batcher / op-proposer: allow customization of signer function (#4431)

* Allow customization of signer function

* Switch to using function from op-service

* Small cleanup

* Support passing SignerFn to BatchSubmitter contructor

* Switch to signer factory methods

* Update op-service dep in op-e2e too

* go mod tidy

* go mod tidy

* Cleanup confusing duplicate variable naming
parent 690af45c
......@@ -17,6 +17,7 @@ import (
"github.com/ethereum-optimism/optimism/op-proposer/txmgr"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
)
......@@ -43,8 +44,6 @@ type BatchSubmitter struct {
// NewBatchSubmitter initializes the BatchSubmitter, gathering any resources
// that will be needed during operation.
func NewBatchSubmitter(cfg Config, l log.Logger) (*BatchSubmitter, error) {
ctx := context.Background()
var err error
var sequencerPrivKey *ecdsa.PrivateKey
var addr common.Address
......@@ -84,6 +83,21 @@ func NewBatchSubmitter(cfg Config, l log.Logger) (*BatchSubmitter, error) {
addr = crypto.PubkeyToAddress(sequencerPrivKey.PublicKey)
}
signer := func(chainID *big.Int) SignerFn {
s := types.LatestSignerForChainID(chainID)
return func(rawTx types.TxData) (*types.Transaction, error) {
return types.SignNewTx(sequencerPrivKey, s, rawTx)
}
}
return NewBatchSubmitterWithSigner(cfg, addr, signer, l)
}
type SignerFactory func(chainID *big.Int) SignerFn
func NewBatchSubmitterWithSigner(cfg Config, addr common.Address, signer SignerFactory, l log.Logger) (*BatchSubmitter, error) {
ctx := context.Background()
batchInboxAddress, err := parseAddress(cfg.SequencerBatchInboxAddress)
if err != nil {
return nil, err
......@@ -138,7 +152,6 @@ func NewBatchSubmitter(cfg Config, l log.Logger) (*BatchSubmitter, error) {
BatchInboxAddress: batchInboxAddress,
ChannelTimeout: cfg.ChannelTimeout,
ChainID: chainID,
PrivKey: sequencerPrivKey,
PollInterval: cfg.PollInterval,
}
......@@ -147,7 +160,7 @@ func NewBatchSubmitter(cfg Config, l log.Logger) (*BatchSubmitter, error) {
return &BatchSubmitter{
cfg: batcherCfg,
addr: addr,
txMgr: NewTransactionManager(l, txManagerConfig, batchInboxAddress, chainID, sequencerPrivKey, l1Client),
txMgr: NewTransactionManager(l, txManagerConfig, batchInboxAddress, chainID, addr, l1Client, signer(chainID)),
done: make(chan struct{}),
log: l,
state: NewChannelManager(l, cfg.ChannelTimeout),
......
package sequencer
import (
"crypto/ecdsa"
"math/big"
"time"
......@@ -39,8 +38,5 @@ type Config struct {
// Chain ID of the L1 chain to submit txs to.
ChainID *big.Int
// Private key to sign batch txs with
PrivKey *ecdsa.PrivateKey
PollInterval time.Duration
}
......@@ -2,7 +2,6 @@ package op_batcher
import (
"context"
"crypto/ecdsa"
"fmt"
"math/big"
"time"
......@@ -11,13 +10,14 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"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"
)
const networkTimeout = 2 * time.Second // How long a single network request can take. TODO: put in a config somewhere
type SignerFn func(rawTx types.TxData) (*types.Transaction, error)
// TransactionManager wraps the simple txmgr package to make it easy to send & wait for transactions
type TransactionManager struct {
// Config
......@@ -27,18 +27,14 @@ type TransactionManager struct {
// Outside world
txMgr txmgr.TxManager
l1Client *ethclient.Client
signerFn func(types.TxData) (*types.Transaction, error)
signerFn SignerFn
log log.Logger
}
func NewTransactionManager(log log.Logger, txMgrConfg txmgr.Config, batchInboxAddress common.Address, chainID *big.Int, privKey *ecdsa.PrivateKey, l1Client *ethclient.Client) *TransactionManager {
signerFn := func(rawTx types.TxData) (*types.Transaction, error) {
return types.SignNewTx(privKey, types.LatestSignerForChainID(chainID), rawTx)
}
func NewTransactionManager(log log.Logger, txMgrConfg txmgr.Config, batchInboxAddress common.Address, chainID *big.Int, senderAddress common.Address, l1Client *ethclient.Client, signerFn SignerFn) *TransactionManager {
t := &TransactionManager{
batchInboxAddress: batchInboxAddress,
senderAddress: crypto.PubkeyToAddress(privKey.PublicKey),
senderAddress: senderAddress,
chainID: chainID,
txMgr: txmgr.NewSimpleTxManager("batcher", txMgrConfg, l1Client),
l1Client: l1Client,
......
......@@ -12,6 +12,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-proposer/drivers/l2output"
opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto"
)
type ProposerCfg struct {
......@@ -38,8 +39,8 @@ func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Cl
RollupClient: rollupCl,
AllowNonFinalized: cfg.AllowNonFinalized,
L2OOAddr: cfg.OutputOracleAddr,
ChainID: chainID,
PrivKey: cfg.ProposerKey,
From: crypto.PubkeyToAddress(cfg.ProposerKey.PublicKey),
SignerFn: opcrypto.PrivateKeySignerFn(cfg.ProposerKey, chainID),
})
require.NoError(t, err)
return &L2Proposer{
......
......@@ -2,7 +2,6 @@ package l2output
import (
"context"
"crypto/ecdsa"
"fmt"
"math/big"
"strings"
......@@ -13,7 +12,6 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"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"
......@@ -42,11 +40,11 @@ type Config struct {
// L2OOAddr is the L1 contract address of the L2 Output Oracle.
L2OOAddr common.Address
// ChainID is the L1 chain ID used for proposal transaction signing
ChainID *big.Int
// From is the address to send transactions from
From common.Address
// Privkey used for proposal transaction signing
PrivKey *ecdsa.PrivateKey
// SignerFn is the function used to sign transactions
SignerFn bind.SignerFn
}
type Driver struct {
......@@ -74,14 +72,13 @@ func NewDriver(cfg Config) (*Driver, error) {
cfg.L2OOAddr, parsed, cfg.L1Client, cfg.L1Client, cfg.L1Client,
)
walletAddr := crypto.PubkeyToAddress(cfg.PrivKey.PublicKey)
cfg.Log.Info("Configured driver", "wallet", walletAddr, "l2-output-contract", cfg.L2OOAddr)
cfg.Log.Info("Configured driver", "wallet", cfg.From, "l2-output-contract", cfg.L2OOAddr)
return &Driver{
cfg: cfg,
l2ooContract: l2ooContract,
rawL2ooContract: rawL2ooContract,
walletAddr: walletAddr,
walletAddr: cfg.From,
l: cfg.Log,
}, nil
}
......@@ -184,13 +181,13 @@ func (d *Driver) CraftTx(ctx context.Context, start, end, nonce *big.Int) (*type
return nil, fmt.Errorf("output for L2 block %s is still unsafe", output.BlockRef)
}
opts, err := bind.NewKeyedTransactorWithChainID(d.cfg.PrivKey, d.cfg.ChainID)
if err != nil {
return nil, err
opts := &bind.TransactOpts{
From: d.cfg.From,
Signer: d.cfg.SignerFn,
Context: ctx,
Nonce: nonce,
NoSend: true,
}
opts.Context = ctx
opts.Nonce = nonce
opts.NoSend = true
// Note: the CurrentL1 is up to (and incl.) what the safe chain and finalized chain have been derived from,
// and should be a quite recent L1 block (depends on L1 conf distance applied to rollup node).
......@@ -227,16 +224,13 @@ func (d *Driver) CraftTx(ctx context.Context, start, end, nonce *big.Int) (*type
//
// NOTE: This method SHOULD NOT publish the resulting transaction.
func (d *Driver) UpdateGasPrice(ctx context.Context, tx *types.Transaction) (*types.Transaction, error) {
opts, err := bind.NewKeyedTransactorWithChainID(
d.cfg.PrivKey, d.cfg.ChainID,
)
if err != nil {
return nil, err
opts := &bind.TransactOpts{
From: d.cfg.From,
Signer: d.cfg.SignerFn,
Context: ctx,
Nonce: new(big.Int).SetUint64(tx.Nonce()),
NoSend: true,
}
opts.Context = ctx
opts.Nonce = new(big.Int).SetUint64(tx.Nonce())
opts.NoSend = true
return d.rawL2ooContract.RawTransact(opts, tx.Data())
}
......
......@@ -5,6 +5,7 @@ import (
"crypto/ecdsa"
"errors"
"fmt"
"math/big"
_ "net/http/pprof"
"os"
"os/signal"
......@@ -14,6 +15,7 @@ import (
hdwallet "github.com/ethereum-optimism/go-ethereum-hdwallet"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
......@@ -25,6 +27,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-proposer/drivers/l2output"
"github.com/ethereum-optimism/optimism/op-proposer/txmgr"
opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
......@@ -130,8 +133,6 @@ func NewL2OutputSubmitter(
gitVersion string,
l log.Logger,
) (*L2OutputSubmitter, error) {
ctx := context.Background()
var l2OutputPrivKey *ecdsa.PrivateKey
var err error
......@@ -161,6 +162,23 @@ func NewL2OutputSubmitter(
}
}
signer := func(chainID *big.Int) bind.SignerFn {
return opcrypto.PrivateKeySignerFn(l2OutputPrivKey, chainID)
}
return NewL2OutputSubmitterWithSigner(cfg, crypto.PubkeyToAddress(l2OutputPrivKey.PublicKey), signer, gitVersion, l)
}
type SignerFactory func(chainID *big.Int) bind.SignerFn
func NewL2OutputSubmitterWithSigner(
cfg Config,
from common.Address,
signer SignerFactory,
gitVersion string,
l log.Logger,
) (*L2OutputSubmitter, error) {
ctx := context.Background()
l2ooAddress, err := parseAddress(cfg.L2OOAddress)
if err != nil {
return nil, err
......@@ -199,8 +217,8 @@ func NewL2OutputSubmitter(
RollupClient: rollupClient,
AllowNonFinalized: cfg.AllowNonFinalized,
L2OOAddr: l2ooAddress,
ChainID: chainID,
PrivKey: l2OutputPrivKey,
From: from,
SignerFn: signer(chainID),
})
if err != nil {
return nil, err
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment