Commit 357c7707 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

op-proposer, op-batcher: Support private keys in addition to mnemonics (#3155)

parent 20a9fe43
...@@ -3,6 +3,8 @@ package op_batcher ...@@ -3,6 +3,8 @@ package op_batcher
import ( import (
"bytes" "bytes"
"context" "context"
"crypto/ecdsa"
"errors"
"fmt" "fmt"
"io" "io"
"math/big" "math/big"
...@@ -11,6 +13,7 @@ import ( ...@@ -11,6 +13,7 @@ import (
_ "net/http/pprof" _ "net/http/pprof"
"os" "os"
"os/signal" "os/signal"
"strings"
"sync" "sync"
"syscall" "syscall"
"time" "time"
...@@ -135,26 +138,43 @@ type BatchSubmitter struct { ...@@ -135,26 +138,43 @@ type BatchSubmitter struct {
func NewBatchSubmitter(cfg Config, l log.Logger) (*BatchSubmitter, error) { func NewBatchSubmitter(cfg Config, l log.Logger) (*BatchSubmitter, error) {
ctx := context.Background() ctx := context.Background()
// Parse wallet private key that will be used to submit L2 txs to the batch var err error
// inbox address. var sequencerPrivKey *ecdsa.PrivateKey
wallet, err := hdwallet.NewFromMnemonic(cfg.Mnemonic) var addr common.Address
if err != nil {
return nil, err
}
acc := accounts.Account{ if cfg.PrivateKey != "" && cfg.Mnemonic != "" {
URL: accounts.URL{ return nil, errors.New("cannot specify both a private key and a mnemonic")
Path: cfg.SequencerHDPath,
},
}
addr, err := wallet.Address(acc)
if err != nil {
return nil, err
} }
sequencerPrivKey, err := wallet.PrivateKey(acc) if cfg.PrivateKey == "" {
if err != nil { // Parse wallet private key that will be used to submit L2 txs to the batch
return nil, err // inbox address.
wallet, err := hdwallet.NewFromMnemonic(cfg.Mnemonic)
if err != nil {
return nil, err
}
acc := accounts.Account{
URL: accounts.URL{
Path: cfg.SequencerHDPath,
},
}
addr, err = wallet.Address(acc)
if err != nil {
return nil, err
}
sequencerPrivKey, err = wallet.PrivateKey(acc)
if err != nil {
return nil, err
}
} else {
sequencerPrivKey, err = crypto.HexToECDSA(strings.TrimPrefix(cfg.PrivateKey, "0x"))
if err != nil {
return nil, err
}
addr = crypto.PubkeyToAddress(sequencerPrivKey.PublicKey)
} }
batchInboxAddress, err := parseAddress(cfg.SequencerBatchInboxAddress) batchInboxAddress, err := parseAddress(cfg.SequencerBatchInboxAddress)
......
...@@ -56,6 +56,9 @@ type Config struct { ...@@ -56,6 +56,9 @@ type Config struct {
// batched submission of sequencer transactions. // batched submission of sequencer transactions.
SequencerHDPath string SequencerHDPath string
// PrivateKey is the private key used to submit sequencer transactions.
PrivateKey string
// SequencerBatchInboxAddress is the address in which to send batch // SequencerBatchInboxAddress is the address in which to send batch
// transactions. // transactions.
SequencerBatchInboxAddress string SequencerBatchInboxAddress string
...@@ -91,6 +94,7 @@ func NewConfig(ctx *cli.Context) Config { ...@@ -91,6 +94,7 @@ func NewConfig(ctx *cli.Context) Config {
ResubmissionTimeout: ctx.GlobalDuration(flags.ResubmissionTimeoutFlag.Name), ResubmissionTimeout: ctx.GlobalDuration(flags.ResubmissionTimeoutFlag.Name),
Mnemonic: ctx.GlobalString(flags.MnemonicFlag.Name), Mnemonic: ctx.GlobalString(flags.MnemonicFlag.Name),
SequencerHDPath: ctx.GlobalString(flags.SequencerHDPathFlag.Name), SequencerHDPath: ctx.GlobalString(flags.SequencerHDPathFlag.Name),
PrivateKey: ctx.GlobalString(flags.PrivateKeyFlag.Name),
SequencerBatchInboxAddress: ctx.GlobalString(flags.SequencerBatchInboxAddressFlag.Name), SequencerBatchInboxAddress: ctx.GlobalString(flags.SequencerBatchInboxAddressFlag.Name),
/* Optional Flags */ /* Optional Flags */
LogLevel: ctx.GlobalString(flags.LogLevelFlag.Name), LogLevel: ctx.GlobalString(flags.LogLevelFlag.Name),
......
...@@ -82,15 +82,18 @@ var ( ...@@ -82,15 +82,18 @@ var (
Name: "mnemonic", Name: "mnemonic",
Usage: "The mnemonic used to derive the wallets for either the " + Usage: "The mnemonic used to derive the wallets for either the " +
"sequencer or the l2output", "sequencer or the l2output",
Required: true, EnvVar: prefixEnvVar("MNEMONIC"),
EnvVar: prefixEnvVar("MNEMONIC"),
} }
SequencerHDPathFlag = cli.StringFlag{ SequencerHDPathFlag = cli.StringFlag{
Name: "sequencer-hd-path", Name: "sequencer-hd-path",
Usage: "The HD path used to derive the sequencer wallet from the " + Usage: "The HD path used to derive the sequencer wallet from the " +
"mnemonic. The mnemonic flag must also be set.", "mnemonic. The mnemonic flag must also be set.",
Required: true, EnvVar: prefixEnvVar("SEQUENCER_HD_PATH"),
EnvVar: prefixEnvVar("SEQUENCER_HD_PATH"), }
PrivateKeyFlag = cli.StringFlag{
Name: "private-key",
Usage: "The private key to use with the l2output wallet. Must not be used with mnemonic.",
EnvVar: prefixEnvVar("PRIVATE_KEY"),
} }
SequencerBatchInboxAddressFlag = cli.StringFlag{ SequencerBatchInboxAddressFlag = cli.StringFlag{
Name: "sequencer-batch-inbox-address", Name: "sequencer-batch-inbox-address",
...@@ -143,12 +146,13 @@ var requiredFlags = []cli.Flag{ ...@@ -143,12 +146,13 @@ var requiredFlags = []cli.Flag{
NumConfirmationsFlag, NumConfirmationsFlag,
SafeAbortNonceTooLowCountFlag, SafeAbortNonceTooLowCountFlag,
ResubmissionTimeoutFlag, ResubmissionTimeoutFlag,
MnemonicFlag,
SequencerHDPathFlag,
SequencerBatchInboxAddressFlag, SequencerBatchInboxAddressFlag,
} }
var optionalFlags = []cli.Flag{ var optionalFlags = []cli.Flag{
MnemonicFlag,
SequencerHDPathFlag,
PrivateKeyFlag,
LogLevelFlag, LogLevelFlag,
LogTerminalFlag, LogTerminalFlag,
PprofEnabledFlag, PprofEnabledFlag,
......
...@@ -49,6 +49,9 @@ type Config struct { ...@@ -49,6 +49,9 @@ type Config struct {
// the l2output transactions. // the l2output transactions.
L2OutputHDPath string L2OutputHDPath string
// PrivateKey is the private key used for l2output transactions.
PrivateKey string
/* Optional Params */ /* Optional Params */
// LogLevel is the lowest log level that will be output. // LogLevel is the lowest log level that will be output.
...@@ -78,6 +81,7 @@ func NewConfig(ctx *cli.Context) Config { ...@@ -78,6 +81,7 @@ func NewConfig(ctx *cli.Context) Config {
ResubmissionTimeout: ctx.GlobalDuration(flags.ResubmissionTimeoutFlag.Name), ResubmissionTimeout: ctx.GlobalDuration(flags.ResubmissionTimeoutFlag.Name),
Mnemonic: ctx.GlobalString(flags.MnemonicFlag.Name), Mnemonic: ctx.GlobalString(flags.MnemonicFlag.Name),
L2OutputHDPath: ctx.GlobalString(flags.L2OutputHDPathFlag.Name), L2OutputHDPath: ctx.GlobalString(flags.L2OutputHDPathFlag.Name),
PrivateKey: ctx.GlobalString(flags.PrivateKeyFlag.Name),
/* Optional Flags */ /* Optional Flags */
LogLevel: ctx.GlobalString(flags.LogLevelFlag.Name), LogLevel: ctx.GlobalString(flags.LogLevelFlag.Name),
LogTerminal: ctx.GlobalBool(flags.LogTerminalFlag.Name), LogTerminal: ctx.GlobalBool(flags.LogTerminalFlag.Name),
......
...@@ -70,15 +70,18 @@ var ( ...@@ -70,15 +70,18 @@ var (
Name: "mnemonic", Name: "mnemonic",
Usage: "The mnemonic used to derive the wallets for either the " + Usage: "The mnemonic used to derive the wallets for either the " +
"sequencer or the l2output", "sequencer or the l2output",
Required: true, EnvVar: prefixEnvVar("MNEMONIC"),
EnvVar: prefixEnvVar("MNEMONIC"),
} }
L2OutputHDPathFlag = cli.StringFlag{ L2OutputHDPathFlag = cli.StringFlag{
Name: "l2-output-hd-path", Name: "l2-output-hd-path",
Usage: "The HD path used to derive the l2output wallet from the " + Usage: "The HD path used to derive the l2output wallet from the " +
"mnemonic. The mnemonic flag must also be set.", "mnemonic. The mnemonic flag must also be set.",
Required: true, EnvVar: prefixEnvVar("L2_OUTPUT_HD_PATH"),
EnvVar: prefixEnvVar("L2_OUTPUT_HD_PATH"), }
PrivateKeyFlag = cli.StringFlag{
Name: "private-key",
Usage: "The private key to use with the l2output wallet. Must not be used with mnemonic.",
EnvVar: prefixEnvVar("PRIVATE_KEY"),
} }
/* Optional Flags */ /* Optional Flags */
...@@ -123,11 +126,12 @@ var requiredFlags = []cli.Flag{ ...@@ -123,11 +126,12 @@ var requiredFlags = []cli.Flag{
NumConfirmationsFlag, NumConfirmationsFlag,
SafeAbortNonceTooLowCountFlag, SafeAbortNonceTooLowCountFlag,
ResubmissionTimeoutFlag, ResubmissionTimeoutFlag,
MnemonicFlag,
L2OutputHDPathFlag,
} }
var optionalFlags = []cli.Flag{ var optionalFlags = []cli.Flag{
MnemonicFlag,
L2OutputHDPathFlag,
PrivateKeyFlag,
LogLevelFlag, LogLevelFlag,
LogTerminalFlag, LogTerminalFlag,
PprofEnabledFlag, PprofEnabledFlag,
......
...@@ -2,15 +2,20 @@ package op_proposer ...@@ -2,15 +2,20 @@ package op_proposer
import ( import (
"context" "context"
"crypto/ecdsa"
"errors"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
_ "net/http/pprof" _ "net/http/pprof"
"os" "os"
"os/signal" "os/signal"
"strings"
"syscall" "syscall"
"time" "time"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum-optimism/optimism/op-proposer/drivers/l2output" "github.com/ethereum-optimism/optimism/op-proposer/drivers/l2output"
"github.com/ethereum-optimism/optimism/op-proposer/rollupclient" "github.com/ethereum-optimism/optimism/op-proposer/rollupclient"
"github.com/ethereum-optimism/optimism/op-proposer/txmgr" "github.com/ethereum-optimism/optimism/op-proposer/txmgr"
...@@ -121,20 +126,33 @@ func NewL2OutputSubmitter( ...@@ -121,20 +126,33 @@ func NewL2OutputSubmitter(
) (*L2OutputSubmitter, error) { ) (*L2OutputSubmitter, error) {
ctx := context.Background() ctx := context.Background()
var l2OutputPrivKey *ecdsa.PrivateKey
var err error
// Parse l2output wallet private key and L2OO contract address. if cfg.PrivateKey != "" && cfg.Mnemonic != "" {
wallet, err := hdwallet.NewFromMnemonic(cfg.Mnemonic) return nil, errors.New("cannot specify both a private key and a mnemonic")
if err != nil {
return nil, err
} }
l2OutputPrivKey, err := wallet.PrivateKey(accounts.Account{ if cfg.PrivateKey == "" {
URL: accounts.URL{ // Parse l2output wallet private key and L2OO contract address.
Path: cfg.L2OutputHDPath, wallet, err := hdwallet.NewFromMnemonic(cfg.Mnemonic)
}, if err != nil {
}) return nil, err
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
}
} }
l2ooAddress, err := parseAddress(cfg.L2OOAddress) l2ooAddress, err := parseAddress(cfg.L2OOAddress)
......
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