Commit c84493ce authored by Joshua Gutow's avatar Joshua Gutow

op-proposer: Move to shared signer setup & simplified init

This removes the NewL2OutputSubmitterWithSigner function and places
the old NewL2OutputSubmitter code inside the main function.
parent 5af21847
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -34,7 +34,7 @@ type L2Proposer struct { ...@@ -34,7 +34,7 @@ type L2Proposer struct {
} }
func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Client, rollupCl *sources.RollupClient) *L2Proposer { func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Client, rollupCl *sources.RollupClient) *L2Proposer {
signer := func(chainID *big.Int) proposer.SignerFn { signer := func(chainID *big.Int) opcrypto.SignerFn {
s := opcrypto.PrivateKeySignerFn(cfg.ProposerKey, chainID) s := opcrypto.PrivateKeySignerFn(cfg.ProposerKey, chainID)
return func(_ context.Context, addr common.Address, tx *types.Transaction) (*types.Transaction, error) { return func(_ context.Context, addr common.Address, tx *types.Transaction) (*types.Transaction, error) {
return s(addr, tx) return s(addr, tx)
...@@ -60,7 +60,7 @@ func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Cl ...@@ -60,7 +60,7 @@ func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Cl
SignerFnFactory: signer, SignerFnFactory: signer,
} }
dr, err := proposer.NewL2OutputSubmitterWithSigner(proposerCfg, log) dr, err := proposer.NewL2OutputSubmitter(proposerCfg, log)
require.NoError(t, err) require.NoError(t, err)
return &L2Proposer{ return &L2Proposer{
......
...@@ -342,7 +342,7 @@ func TestMigration(t *testing.T) { ...@@ -342,7 +342,7 @@ func TestMigration(t *testing.T) {
batcher.Stop() batcher.Stop()
}) })
proposer, err := l2os.NewL2OutputSubmitter(l2os.CLIConfig{ proposer, err := l2os.NewL2OutputSubmitterFromCLIConfig(l2os.CLIConfig{
L1EthRpc: forkedL1URL, L1EthRpc: forkedL1URL,
RollupRpc: rollupNode.HTTPEndpoint(), RollupRpc: rollupNode.HTTPEndpoint(),
L2OOAddress: l2OS.Address.String(), L2OOAddress: l2OS.Address.String(),
......
...@@ -498,7 +498,7 @@ func (cfg SystemConfig) Start() (*System, error) { ...@@ -498,7 +498,7 @@ func (cfg SystemConfig) Start() (*System, error) {
} }
// L2Output Submitter // L2Output Submitter
sys.L2OutputSubmitter, err = l2os.NewL2OutputSubmitter(l2os.CLIConfig{ sys.L2OutputSubmitter, err = l2os.NewL2OutputSubmitterFromCLIConfig(l2os.CLIConfig{
L1EthRpc: sys.Nodes["l1"].WSEndpoint(), L1EthRpc: sys.Nodes["l1"].WSEndpoint(),
RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(), RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(),
L2OOAddress: predeploys.DevL2OutputOracleAddr.String(), L2OOAddress: predeploys.DevL2OutputOracleAddr.String(),
......
...@@ -28,9 +28,17 @@ func main() { ...@@ -28,9 +28,17 @@ func main() {
app.Usage = "L2Output Submitter" app.Usage = "L2Output Submitter"
app.Description = "Service for generating and submitting L2 Output checkpoints to the L2OutputOracle contract" app.Description = "Service for generating and submitting L2 Output checkpoints to the L2OutputOracle contract"
app.Action = proposer.Main(Version) app.Action = curryMain(Version)
err := app.Run(os.Args) err := app.Run(os.Args)
if err != nil { if err != nil {
log.Crit("Application failed", "message", err) log.Crit("Application failed", "message", err)
} }
} }
// curryMain transforms the proposer.Main function into an app.Action
// This is done to capture the Version of the proposer.
func curryMain(version string) func(ctx *cli.Context) error {
return func(ctx *cli.Context) error {
return proposer.Main(version, ctx)
}
}
...@@ -3,7 +3,6 @@ module github.com/ethereum-optimism/optimism/op-proposer ...@@ -3,7 +3,6 @@ module github.com/ethereum-optimism/optimism/op-proposer
go 1.18 go 1.18
require ( require (
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3
github.com/ethereum-optimism/optimism/op-bindings v0.10.11 github.com/ethereum-optimism/optimism/op-bindings v0.10.11
github.com/ethereum-optimism/optimism/op-node v0.10.11 github.com/ethereum-optimism/optimism/op-node v0.10.11
github.com/ethereum-optimism/optimism/op-service v0.10.11 github.com/ethereum-optimism/optimism/op-service v0.10.11
...@@ -16,10 +15,7 @@ require ( ...@@ -16,10 +15,7 @@ require (
github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/VictoriaMetrics/fastcache v1.10.0 // indirect
github.com/benbjohnson/clock v1.3.0 // indirect github.com/benbjohnson/clock v1.3.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/btcsuite/btcd v0.23.3 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/btcutil v1.1.0 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect github.com/deckarep/golang-set v1.8.0 // indirect
...@@ -84,7 +80,6 @@ require ( ...@@ -84,7 +80,6 @@ require (
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
github.com/tklauser/go-sysconf v0.3.10 // indirect github.com/tklauser/go-sysconf v0.3.10 // indirect
github.com/tklauser/numcpus v0.5.0 // indirect github.com/tklauser/numcpus v0.5.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect
......
This diff is collapsed.
...@@ -9,6 +9,8 @@ import ( ...@@ -9,6 +9,8 @@ import (
"github.com/ethereum-optimism/optimism/op-node/sources" "github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-proposer/flags" "github.com/ethereum-optimism/optimism/op-proposer/flags"
opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto"
oplog "github.com/ethereum-optimism/optimism/op-service/log" oplog "github.com/ethereum-optimism/optimism/op-service/log"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
...@@ -27,7 +29,7 @@ type Config struct { ...@@ -27,7 +29,7 @@ type Config struct {
RollupClient *sources.RollupClient RollupClient *sources.RollupClient
AllowNonFinalized bool AllowNonFinalized bool
From common.Address From common.Address
SignerFnFactory SignerFactory SignerFnFactory opcrypto.SignerFactory
} }
// CLIConfig is a well typed config that is parsed from the CLI params. // CLIConfig is a well typed config that is parsed from the CLI params.
......
...@@ -2,7 +2,6 @@ package proposer ...@@ -2,7 +2,6 @@ package proposer
import ( import (
"context" "context"
"crypto/ecdsa"
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
...@@ -14,18 +13,14 @@ import ( ...@@ -14,18 +13,14 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/urfave/cli" "github.com/urfave/cli"
hdwallet "github.com/ethereum-optimism/go-ethereum-hdwallet"
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-node/eth" "github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/sources" "github.com/ethereum-optimism/optimism/op-node/sources"
...@@ -35,7 +30,6 @@ import ( ...@@ -35,7 +30,6 @@ import (
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
opsigner "github.com/ethereum-optimism/optimism/op-signer/client"
) )
const ( const (
...@@ -46,83 +40,75 @@ const ( ...@@ -46,83 +40,75 @@ const (
var supportedL2OutputVersion = eth.Bytes32{} var supportedL2OutputVersion = eth.Bytes32{}
type SignerFn func(context.Context, common.Address, *types.Transaction) (*types.Transaction, error) // Main is the entrypoint into the L2 Output Submitter. This method executes the
// service and blocks until the service exits.
type SignerFactory func(chainID *big.Int) SignerFn func Main(version string, cliCtx *cli.Context) error {
cfg := NewConfig(cliCtx)
// Main is the entrypoint into the L2 Output Submitter. This method returns a if err := cfg.Check(); err != nil {
// closure that executes the service and blocks until the service exits. The use return fmt.Errorf("invalid CLI flags: %w", err)
// of a closure allows the parameters bound to the top-level main package, e.g. }
// GitVersion, to be captured and used once the function is executed.
func Main(version string) func(ctx *cli.Context) error {
return func(cliCtx *cli.Context) error {
cfg := NewConfig(cliCtx)
if err := cfg.Check(); err != nil {
return fmt.Errorf("invalid CLI flags: %w", err)
}
l := oplog.NewLogger(cfg.LogConfig)
l.Info("Initializing L2 Output Submitter")
l2OutputSubmitter, err := NewL2OutputSubmitter(cfg, l) l := oplog.NewLogger(cfg.LogConfig)
if err != nil { l.Info("Initializing L2 Output Submitter")
l.Error("Unable to create L2 Output Submitter", "error", err)
return err
}
l.Info("Starting L2 Output Submitter") l2OutputSubmitter, err := NewL2OutputSubmitterFromCLIConfig(cfg, l)
ctx, cancel := context.WithCancel(context.Background()) if err != nil {
l.Error("Unable to create the L2 Output Submitter", "error", err)
return err
}
if err := l2OutputSubmitter.Start(); err != nil { l.Info("Starting L2 Output Submitter")
cancel() ctx, cancel := context.WithCancel(context.Background())
l.Error("Unable to start L2 Output Submitter", "error", err)
return err
}
defer l2OutputSubmitter.Stop()
l.Info("L2 Output Submitter started")
pprofConfig := cfg.PprofConfig
if pprofConfig.Enabled {
l.Info("starting pprof", "addr", pprofConfig.ListenAddr, "port", pprofConfig.ListenPort)
go func() {
if err := oppprof.ListenAndServe(ctx, pprofConfig.ListenAddr, pprofConfig.ListenPort); err != nil {
l.Error("error starting pprof", "err", err)
}
}()
}
registry := opmetrics.NewRegistry() if err := l2OutputSubmitter.Start(); err != nil {
metricsCfg := cfg.MetricsConfig cancel()
if metricsCfg.Enabled { l.Error("Unable to start L2 Output Submitter", "error", err)
l.Info("starting metrics server", "addr", metricsCfg.ListenAddr, "port", metricsCfg.ListenPort) return err
go func() { }
if err := opmetrics.ListenAndServe(ctx, registry, metricsCfg.ListenAddr, metricsCfg.ListenPort); err != nil { defer l2OutputSubmitter.Stop()
l.Error("error starting metrics server", err)
} l.Info("L2 Output Submitter started")
}() pprofConfig := cfg.PprofConfig
addr := l2OutputSubmitter.from if pprofConfig.Enabled {
opmetrics.LaunchBalanceMetrics(ctx, l, registry, "", l2OutputSubmitter.l1Client, addr) l.Info("starting pprof", "addr", pprofConfig.ListenAddr, "port", pprofConfig.ListenPort)
} go func() {
if err := oppprof.ListenAndServe(ctx, pprofConfig.ListenAddr, pprofConfig.ListenPort); err != nil {
l.Error("error starting pprof", "err", err)
}
}()
}
rpcCfg := cfg.RPCConfig registry := opmetrics.NewRegistry()
server := oprpc.NewServer(rpcCfg.ListenAddr, rpcCfg.ListenPort, version) metricsCfg := cfg.MetricsConfig
if err := server.Start(); err != nil { if metricsCfg.Enabled {
cancel() l.Info("starting metrics server", "addr", metricsCfg.ListenAddr, "port", metricsCfg.ListenPort)
return fmt.Errorf("error starting RPC server: %w", err) go func() {
} if err := opmetrics.ListenAndServe(ctx, registry, metricsCfg.ListenAddr, metricsCfg.ListenPort); err != nil {
l.Error("error starting metrics server", err)
}
}()
addr := l2OutputSubmitter.from
opmetrics.LaunchBalanceMetrics(ctx, l, registry, "", l2OutputSubmitter.l1Client, addr)
}
interruptChannel := make(chan os.Signal, 1) rpcCfg := cfg.RPCConfig
signal.Notify(interruptChannel, []os.Signal{ server := oprpc.NewServer(rpcCfg.ListenAddr, rpcCfg.ListenPort, version)
os.Interrupt, if err := server.Start(); err != nil {
os.Kill,
syscall.SIGTERM,
syscall.SIGQUIT,
}...)
<-interruptChannel
cancel() cancel()
return fmt.Errorf("error starting RPC server: %w", err)
return nil
} }
interruptChannel := make(chan os.Signal, 1)
signal.Notify(interruptChannel, []os.Signal{
os.Interrupt,
os.Kill,
syscall.SIGTERM,
syscall.SIGQUIT,
}...)
<-interruptChannel
cancel()
return nil
} }
// L2OutputSubmitter is responsible for proposing outputs // L2OutputSubmitter is responsible for proposing outputs
...@@ -151,66 +137,16 @@ type L2OutputSubmitter struct { ...@@ -151,66 +137,16 @@ type L2OutputSubmitter struct {
// From is the address to send transactions from // From is the address to send transactions from
from common.Address from common.Address
// SignerFn is the function used to sign transactions // SignerFn is the function used to sign transactions
signerFn SignerFn signerFn opcrypto.SignerFn
// How frequently to poll L2 for new finalized outputs // How frequently to poll L2 for new finalized outputs
pollInterval time.Duration pollInterval time.Duration
} }
// NewL2OutputSubmitter initializes the L2OutputSubmitter, gathering any resources // NewL2OutputSubmitterFromCLIConfig creates a new L2 Output Submitter given the CLI Config
// that will be needed during operation. func NewL2OutputSubmitterFromCLIConfig(cfg CLIConfig, l log.Logger) (*L2OutputSubmitter, error) {
func NewL2OutputSubmitter(cfg CLIConfig, l log.Logger) (*L2OutputSubmitter, error) { signer, fromAddress, err := opcrypto.SignerFactoryFromConfig(l, cfg.PrivateKey, cfg.Mnemonic, cfg.L2OutputHDPath, cfg.SignerConfig)
var l2OutputPrivKey *ecdsa.PrivateKey if err != nil {
var err error return nil, err
var signer SignerFactory
var fromAddress common.Address
if cfg.SignerConfig.Enabled() {
signerClient, err := opsigner.NewSignerClientFromConfig(l, cfg.SignerConfig)
if err != nil {
l.Error("Unable to create Signer Client", "error", err)
return nil, err
}
fromAddress = common.BytesToAddress(hexutil.MustDecode(cfg.SignerConfig.Address))
signer = func(chainID *big.Int) SignerFn {
return func(ctx context.Context, address common.Address, tx *types.Transaction) (*types.Transaction, error) {
if address.String() != cfg.SignerConfig.Address {
return nil, fmt.Errorf("attempting to sign for %s, expected %s: ", address, cfg.SignerConfig.Address)
}
return signerClient.SignTransaction(ctx, chainID, tx)
}
}
} else {
if cfg.PrivateKey != "" && cfg.Mnemonic != "" {
return nil, errors.New("cannot specify both a private key and a mnemonic")
}
if cfg.PrivateKey == "" {
// Parse l2output wallet private key and L2OO contract address.
wallet, err := hdwallet.NewFromMnemonic(cfg.Mnemonic)
if err != nil {
return nil, err
}
l2OutputPrivKey, err = wallet.PrivateKey(accounts.Account{
URL: accounts.URL{
Path: cfg.L2OutputHDPath,
},
})
if err != nil {
return nil, err
}
} else {
l2OutputPrivKey, err = crypto.HexToECDSA(strings.TrimPrefix(cfg.PrivateKey, "0x"))
if err != nil {
return nil, err
}
}
fromAddress = crypto.PubkeyToAddress(l2OutputPrivKey.PublicKey)
signer = func(chainID *big.Int) SignerFn {
s := opcrypto.PrivateKeySignerFn(l2OutputPrivKey, chainID)
return func(_ context.Context, addr common.Address, tx *types.Transaction) (*types.Transaction, error) {
return s(addr, tx)
}
}
} }
l2ooAddress, err := parseAddress(cfg.L2OOAddress) l2ooAddress, err := parseAddress(cfg.L2OOAddress)
...@@ -218,8 +154,7 @@ func NewL2OutputSubmitter(cfg CLIConfig, l log.Logger) (*L2OutputSubmitter, erro ...@@ -218,8 +154,7 @@ func NewL2OutputSubmitter(cfg CLIConfig, l log.Logger) (*L2OutputSubmitter, erro
return nil, err return nil, err
} }
// Connect to L1 and L2 providers. Perform these last since they are the // Connect to L1 and L2 providers. Perform these last since they are the most expensive.
// most expensive.
ctx := context.Background() ctx := context.Background()
l1Client, err := dialEthClientWithTimeout(ctx, cfg.L1EthRpc) l1Client, err := dialEthClientWithTimeout(ctx, cfg.L1EthRpc)
if err != nil { if err != nil {
...@@ -251,11 +186,11 @@ func NewL2OutputSubmitter(cfg CLIConfig, l log.Logger) (*L2OutputSubmitter, erro ...@@ -251,11 +186,11 @@ func NewL2OutputSubmitter(cfg CLIConfig, l log.Logger) (*L2OutputSubmitter, erro
SignerFnFactory: signer, SignerFnFactory: signer,
} }
return NewL2OutputSubmitterWithSigner(proposerCfg, l) return NewL2OutputSubmitter(proposerCfg, l)
} }
// NewL2OutputSubmitterWithSigner creates a new L2 Output Submitter // NewL2OutputSubmitter creates a new L2 Output Submitter
func NewL2OutputSubmitterWithSigner(cfg Config, l log.Logger) (*L2OutputSubmitter, error) { func NewL2OutputSubmitter(cfg Config, l log.Logger) (*L2OutputSubmitter, error) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
cCtx, cCancel := context.WithTimeout(ctx, defaultDialTimeout) cCtx, cCancel := context.WithTimeout(ctx, defaultDialTimeout)
......
package crypto package crypto
import ( import (
"context"
"crypto/ecdsa" "crypto/ecdsa"
"errors"
"fmt"
"math/big" "math/big"
"strings"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
hdwallet "github.com/ethereum-optimism/go-ethereum-hdwallet"
opsigner "github.com/ethereum-optimism/optimism/op-signer/client"
) )
func PrivateKeySignerFn(key *ecdsa.PrivateKey, chainID *big.Int) bind.SignerFn { func PrivateKeySignerFn(key *ecdsa.PrivateKey, chainID *big.Int) bind.SignerFn {
...@@ -24,3 +33,71 @@ func PrivateKeySignerFn(key *ecdsa.PrivateKey, chainID *big.Int) bind.SignerFn { ...@@ -24,3 +33,71 @@ func PrivateKeySignerFn(key *ecdsa.PrivateKey, chainID *big.Int) bind.SignerFn {
return tx.WithSignature(signer, signature) return tx.WithSignature(signer, signature)
} }
} }
// SignerFn is a generic transaction signing function. It may be a remote signer so it takes a context.
// It also takes the address that should be used to sign the transaction with.
type SignerFn func(context.Context, common.Address, *types.Transaction) (*types.Transaction, error)
// SignerFactory creates a SignerFn that is bound to a specific ChainID
type SignerFactory func(chainID *big.Int) SignerFn
// SignerFactoryFromConfig considers three ways that signers are created & then creates single factory from those config options.
// It can either take a remote signer (via opsigner.CLIConfig) or it can be provided either a mnemonic + derivation path or a private key.
// It prefers the remote signer, then the mnemonic or private key (only one of which can be provided).
func SignerFactoryFromConfig(l log.Logger, privateKey, mnemonic, hdPath string, signerConfig opsigner.CLIConfig) (SignerFactory, common.Address, error) {
var signer SignerFactory
var fromAddress common.Address
if signerConfig.Enabled() {
signerClient, err := opsigner.NewSignerClientFromConfig(l, signerConfig)
if err != nil {
l.Error("Unable to create Signer Client", "error", err)
return nil, common.Address{}, fmt.Errorf("failed to create the signer client: %w", err)
}
fromAddress = common.HexToAddress(signerConfig.Address)
signer = func(chainID *big.Int) SignerFn {
return func(ctx context.Context, address common.Address, tx *types.Transaction) (*types.Transaction, error) {
if address.String() != signerConfig.Address {
return nil, fmt.Errorf("attempting to sign for %s, expected %s: ", address, signerConfig.Address)
}
return signerClient.SignTransaction(ctx, chainID, tx)
}
}
} else {
var privKey *ecdsa.PrivateKey
var err error
if privateKey != "" && mnemonic != "" {
return nil, common.Address{}, errors.New("cannot specify both a private key and a mnemonic")
}
if privateKey == "" {
// Parse l2output wallet private key and L2OO contract address.
wallet, err := hdwallet.NewFromMnemonic(mnemonic)
if err != nil {
return nil, common.Address{}, fmt.Errorf("failed to parse mnemonic: %w", err)
}
privKey, err = wallet.PrivateKey(accounts.Account{
URL: accounts.URL{
Path: hdPath,
},
})
if err != nil {
return nil, common.Address{}, fmt.Errorf("failed to create a wallet: %w", err)
}
} else {
privKey, err = crypto.HexToECDSA(strings.TrimPrefix(privateKey, "0x"))
if err != nil {
return nil, common.Address{}, fmt.Errorf("failed to parse the private key: %w", err)
}
}
fromAddress = crypto.PubkeyToAddress(privKey.PublicKey)
signer = func(chainID *big.Int) SignerFn {
s := PrivateKeySignerFn(privKey, chainID)
return func(_ context.Context, addr common.Address, tx *types.Transaction) (*types.Transaction, error) {
return s(addr, tx)
}
}
}
return signer, fromAddress, nil
}
...@@ -3,6 +3,8 @@ module github.com/ethereum-optimism/optimism/op-service ...@@ -3,6 +3,8 @@ module github.com/ethereum-optimism/optimism/op-service
go 1.18 go 1.18
require ( require (
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3
github.com/ethereum-optimism/optimism/op-signer v0.1.0
github.com/ethereum/go-ethereum v1.10.26 github.com/ethereum/go-ethereum v1.10.26
github.com/prometheus/client_golang v1.13.0 github.com/prometheus/client_golang v1.13.0
github.com/stretchr/testify v1.8.1 github.com/stretchr/testify v1.8.1
...@@ -13,20 +15,27 @@ require ( ...@@ -13,20 +15,27 @@ require (
require ( require (
github.com/VictoriaMetrics/fastcache v1.9.0 // indirect github.com/VictoriaMetrics/fastcache v1.9.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/btcsuite/btcd v0.23.3 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/btcutil v1.1.0 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect github.com/deckarep/golang-set v1.8.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/dyson/certman v0.3.0 // indirect
github.com/edsrzf/mmap-go v1.1.0 // indirect
github.com/fjl/memsize v0.0.1 // indirect github.com/fjl/memsize v0.0.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
github.com/go-kit/kit v0.10.0 // indirect github.com/go-kit/kit v0.10.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-stack/stack v1.8.1 // indirect github.com/go-stack/stack v1.8.1 // indirect
github.com/golang-jwt/jwt/v4 v4.3.0 // indirect github.com/golang-jwt/jwt/v4 v4.3.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.2.0 // indirect github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/go-bexpr v0.1.11 // indirect github.com/hashicorp/go-bexpr v0.1.11 // indirect
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
...@@ -49,21 +58,24 @@ require ( ...@@ -49,21 +58,24 @@ require (
github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect
github.com/prometheus/tsdb v0.10.0 // indirect github.com/prometheus/tsdb v0.10.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect github.com/rivo/uniseg v0.2.1-0.20211004051800-57c86be7915a // indirect
github.com/rjeczalik/notify v0.9.1 // indirect github.com/rjeczalik/notify v0.9.2 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/rs/cors v1.8.2 // indirect github.com/rs/cors v1.8.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/status-im/keycard-go v0.0.0-20211109104530-b0e0482ba91d // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
github.com/tklauser/go-sysconf v0.3.10 // indirect github.com/tklauser/go-sysconf v0.3.10 // indirect
github.com/tklauser/numcpus v0.4.0 // indirect github.com/tklauser/numcpus v0.4.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43 // indirect golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43 // indirect
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
......
This diff is collapsed.
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