Commit 4de5c8c2 authored by Minhyuk Kim's avatar Minhyuk Kim Committed by GitHub

op-signer, op-node: Integrate op-node with op-signer for block payload signing (#12325)

* Initial implementation of integrating op-node with op-signer for remote signer configuration for block payload signing

* op-service: remove the requirement for signer.address to be set when using op-service

* op-service: add blockpayload_args to send to rpc opsigner_signBlockPayload

* Implement mock rpc in gossip_test and apply review

* Clean up tests
parent 72ec8d3f
......@@ -7,6 +7,7 @@ import (
"github.com/urfave/cli/v2"
"github.com/ethereum-optimism/optimism/op-node/p2p"
opsigner "github.com/ethereum-optimism/optimism/op-service/signer"
)
func p2pEnv(envprefix, v string) []string {
......@@ -87,7 +88,7 @@ func deprecatedP2PFlags(envPrefix string) []cli.Flag {
// None of these flags are strictly required.
// Some are hidden if they are too technical, or not recommended.
func P2PFlags(envPrefix string) []cli.Flag {
return []cli.Flag{
return append([]cli.Flag{
&cli.BoolFlag{
Name: DisableP2PName,
Usage: "Completely disable the P2P stack",
......@@ -410,5 +411,5 @@ func P2PFlags(envPrefix string) []cli.Flag {
Required: false,
EnvVars: p2pEnv(envPrefix, "PING"),
},
}
}, opsigner.CLIFlags(envPrefix, P2PCategory)...)
}
......@@ -5,18 +5,18 @@ import (
"strings"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/urfave/cli/v2"
"github.com/ethereum-optimism/optimism/op-node/flags"
"github.com/ethereum-optimism/optimism/op-node/p2p"
opsigner "github.com/ethereum-optimism/optimism/op-service/signer"
)
// TODO: implement remote signer setup (config to authenticated endpoint)
// and remote signer itself (e.g. a open http client to make signing requests)
// LoadSignerSetup loads a configuration for a Signer to be set up later
func LoadSignerSetup(ctx *cli.Context) (p2p.SignerSetup, error) {
func LoadSignerSetup(ctx *cli.Context, logger log.Logger) (p2p.SignerSetup, error) {
key := ctx.String(flags.SequencerP2PKeyName)
signerCfg := opsigner.ReadCLIConfig(ctx)
if key != "" {
// Mnemonics are bad because they leak *all* keys when they leak.
// Unencrypted keys from file are bad because they are easy to leak (and we are not checking file permissions).
......@@ -26,9 +26,13 @@ func LoadSignerSetup(ctx *cli.Context) (p2p.SignerSetup, error) {
}
return &p2p.PreparedSigner{Signer: p2p.NewLocalSigner(priv)}, nil
} else if signerCfg.Enabled() {
remoteSigner, err := p2p.NewRemoteSigner(logger, signerCfg)
if err != nil {
return nil, err
}
return &p2p.PreparedSigner{Signer: remoteSigner}, nil
}
// TODO: create remote signer
return nil, nil
}
......@@ -3,31 +3,33 @@ package p2p
import (
"bytes"
"context"
"crypto/ecdsa"
"fmt"
"io"
"math/big"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/golang/snappy"
// "github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-service/eth"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
opsigner "github.com/ethereum-optimism/optimism/op-service/signer"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum-optimism/optimism/op-service/testutils"
"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/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
pubsub "github.com/libp2p/go-libp2p-pubsub"
pubsub_pb "github.com/libp2p/go-libp2p-pubsub/pb"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-service/testlog"
)
func TestGuardGossipValidator(t *testing.T) {
......@@ -62,30 +64,122 @@ func TestVerifyBlockSignature(t *testing.T) {
L2ChainID: big.NewInt(100),
}
peerId := peer.ID("foo")
secrets, err := e2eutils.DefaultMnemonicConfig.Secrets()
secrets, err := crypto.GenerateKey()
require.NoError(t, err)
msg := []byte("any msg")
t.Run("Valid", func(t *testing.T) {
runCfg := &testutils.MockRuntimeConfig{P2PSeqAddress: crypto.PubkeyToAddress(secrets.PublicKey)}
signer := &PreparedSigner{Signer: NewLocalSigner(secrets)}
sig, err := signer.Sign(context.Background(), SigningDomainBlocksV1, cfg.L2ChainID, msg)
require.NoError(t, err)
result := verifyBlockSignature(logger, cfg, runCfg, peerId, sig[:], msg)
require.Equal(t, pubsub.ValidationAccept, result)
})
t.Run("WrongSigner", func(t *testing.T) {
runCfg := &testutils.MockRuntimeConfig{P2PSeqAddress: common.HexToAddress("0x1234")}
signer := &PreparedSigner{Signer: NewLocalSigner(secrets)}
sig, err := signer.Sign(context.Background(), SigningDomainBlocksV1, cfg.L2ChainID, msg)
require.NoError(t, err)
result := verifyBlockSignature(logger, cfg, runCfg, peerId, sig[:], msg)
require.Equal(t, pubsub.ValidationReject, result)
})
t.Run("InvalidSignature", func(t *testing.T) {
runCfg := &testutils.MockRuntimeConfig{P2PSeqAddress: crypto.PubkeyToAddress(secrets.PublicKey)}
sig := make([]byte, 65)
result := verifyBlockSignature(logger, cfg, runCfg, peerId, sig, msg)
require.Equal(t, pubsub.ValidationReject, result)
})
t.Run("NoSequencer", func(t *testing.T) {
runCfg := &testutils.MockRuntimeConfig{}
signer := &PreparedSigner{Signer: NewLocalSigner(secrets)}
sig, err := signer.Sign(context.Background(), SigningDomainBlocksV1, cfg.L2ChainID, msg)
require.NoError(t, err)
result := verifyBlockSignature(logger, cfg, runCfg, peerId, sig[:], msg)
require.Equal(t, pubsub.ValidationIgnore, result)
})
}
type mockRemoteSigner struct {
priv *ecdsa.PrivateKey
}
func (t *mockRemoteSigner) SignBlockPayload(args opsigner.BlockPayloadArgs) (hexutil.Bytes, error) {
signingHash, err := args.ToSigningHash()
if err != nil {
return nil, err
}
signature, err := crypto.Sign(signingHash[:], t.priv)
if err != nil {
return nil, err
}
return signature, nil
}
func TestVerifyBlockSignatureWithRemoteSigner(t *testing.T) {
secrets, err := crypto.GenerateKey()
require.NoError(t, err)
remoteSigner := &mockRemoteSigner{secrets}
server := oprpc.NewServer(
"127.0.0.1",
0,
"test",
oprpc.WithAPIs([]rpc.API{
{
Namespace: "opsigner",
Service: remoteSigner,
},
}),
)
require.NoError(t, server.Start())
defer func() {
_ = server.Stop()
}()
logger := testlog.Logger(t, log.LevelCrit)
cfg := &rollup.Config{
L2ChainID: big.NewInt(100),
}
peerId := peer.ID("foo")
msg := []byte("any msg")
signerCfg := opsigner.NewCLIConfig()
signerCfg.Endpoint = fmt.Sprintf("http://%s", server.Endpoint())
signerCfg.TLSConfig.TLSKey = ""
signerCfg.TLSConfig.TLSCert = ""
signerCfg.TLSConfig.TLSCaCert = ""
signerCfg.TLSConfig.Enabled = false
t.Run("Valid", func(t *testing.T) {
runCfg := &testutils.MockRuntimeConfig{P2PSeqAddress: crypto.PubkeyToAddress(secrets.SequencerP2P.PublicKey)}
signer := &PreparedSigner{Signer: NewLocalSigner(secrets.SequencerP2P)}
runCfg := &testutils.MockRuntimeConfig{P2PSeqAddress: crypto.PubkeyToAddress(secrets.PublicKey)}
remoteSigner, err := NewRemoteSigner(logger, signerCfg)
require.NoError(t, err)
signer := &PreparedSigner{Signer: remoteSigner}
sig, err := signer.Sign(context.Background(), SigningDomainBlocksV1, cfg.L2ChainID, msg)
require.NoError(t, err)
result := verifyBlockSignature(logger, cfg, runCfg, peerId, sig[:65], msg)
result := verifyBlockSignature(logger, cfg, runCfg, peerId, sig[:], msg)
require.Equal(t, pubsub.ValidationAccept, result)
})
t.Run("WrongSigner", func(t *testing.T) {
runCfg := &testutils.MockRuntimeConfig{P2PSeqAddress: common.HexToAddress("0x1234")}
signer := &PreparedSigner{Signer: NewLocalSigner(secrets.SequencerP2P)}
remoteSigner, err := NewRemoteSigner(logger, signerCfg)
require.NoError(t, err)
signer := &PreparedSigner{Signer: remoteSigner}
sig, err := signer.Sign(context.Background(), SigningDomainBlocksV1, cfg.L2ChainID, msg)
require.NoError(t, err)
result := verifyBlockSignature(logger, cfg, runCfg, peerId, sig[:65], msg)
result := verifyBlockSignature(logger, cfg, runCfg, peerId, sig[:], msg)
require.Equal(t, pubsub.ValidationReject, result)
})
t.Run("InvalidSignature", func(t *testing.T) {
runCfg := &testutils.MockRuntimeConfig{P2PSeqAddress: crypto.PubkeyToAddress(secrets.SequencerP2P.PublicKey)}
runCfg := &testutils.MockRuntimeConfig{P2PSeqAddress: crypto.PubkeyToAddress(secrets.PublicKey)}
sig := make([]byte, 65)
result := verifyBlockSignature(logger, cfg, runCfg, peerId, sig, msg)
require.Equal(t, pubsub.ValidationReject, result)
......@@ -93,12 +187,36 @@ func TestVerifyBlockSignature(t *testing.T) {
t.Run("NoSequencer", func(t *testing.T) {
runCfg := &testutils.MockRuntimeConfig{}
signer := &PreparedSigner{Signer: NewLocalSigner(secrets.SequencerP2P)}
remoteSigner, err := NewRemoteSigner(logger, signerCfg)
require.NoError(t, err)
signer := &PreparedSigner{Signer: remoteSigner}
sig, err := signer.Sign(context.Background(), SigningDomainBlocksV1, cfg.L2ChainID, msg)
require.NoError(t, err)
result := verifyBlockSignature(logger, cfg, runCfg, peerId, sig[:65], msg)
result := verifyBlockSignature(logger, cfg, runCfg, peerId, sig[:], msg)
require.Equal(t, pubsub.ValidationIgnore, result)
})
t.Run("RemoteSignerNoTLS", func(t *testing.T) {
signerCfg := opsigner.NewCLIConfig()
signerCfg.Endpoint = fmt.Sprintf("http://%s", server.Endpoint())
signerCfg.TLSConfig.TLSKey = "invalid"
signerCfg.TLSConfig.TLSCert = "invalid"
signerCfg.TLSConfig.TLSCaCert = "invalid"
signerCfg.TLSConfig.Enabled = true
_, err := NewRemoteSigner(logger, signerCfg)
require.Error(t, err)
})
t.Run("RemoteSignerInvalidEndpoint", func(t *testing.T) {
signerCfg := opsigner.NewCLIConfig()
signerCfg.Endpoint = "Invalid"
signerCfg.TLSConfig.TLSKey = ""
signerCfg.TLSConfig.TLSCert = ""
signerCfg.TLSConfig.TLSCaCert = ""
_, err := NewRemoteSigner(logger, signerCfg)
require.Error(t, err)
})
}
type MarshalSSZ interface {
......@@ -146,10 +264,10 @@ func TestBlockValidator(t *testing.T) {
cfg := &rollup.Config{
L2ChainID: big.NewInt(100),
}
secrets, err := e2eutils.DefaultMnemonicConfig.Secrets()
secrets, err := crypto.GenerateKey()
require.NoError(t, err)
runCfg := &testutils.MockRuntimeConfig{P2PSeqAddress: crypto.PubkeyToAddress(secrets.SequencerP2P.PublicKey)}
signer := &PreparedSigner{Signer: NewLocalSigner(secrets.SequencerP2P)}
runCfg := &testutils.MockRuntimeConfig{P2PSeqAddress: crypto.PubkeyToAddress(secrets.PublicKey)}
signer := &PreparedSigner{Signer: NewLocalSigner(secrets)}
// Params Set 2: Call the validation function
peerID := peer.ID("foo")
......
......@@ -9,8 +9,10 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-node/rollup"
opsigner "github.com/ethereum-optimism/optimism/op-service/signer"
)
var SigningDomainBlocksV1 = [32]byte{}
......@@ -20,40 +22,27 @@ type Signer interface {
io.Closer
}
func SigningHash(domain [32]byte, chainID *big.Int, payloadBytes []byte) (common.Hash, error) {
var msgInput [32 + 32 + 32]byte
// domain: first 32 bytes
copy(msgInput[:32], domain[:])
// chain_id: second 32 bytes
if chainID.BitLen() > 256 {
return common.Hash{}, errors.New("chain_id is too large")
}
chainID.FillBytes(msgInput[32:64])
// payload_hash: third 32 bytes, hash of encoded payload
copy(msgInput[64:], crypto.Keccak256(payloadBytes))
return crypto.Keccak256Hash(msgInput[:]), nil
}
func BlockSigningHash(cfg *rollup.Config, payloadBytes []byte) (common.Hash, error) {
return SigningHash(SigningDomainBlocksV1, cfg.L2ChainID, payloadBytes)
return opsigner.NewBlockPayloadArgs(SigningDomainBlocksV1, cfg.L2ChainID, payloadBytes, nil).ToSigningHash()
}
// LocalSigner is suitable for testing
type LocalSigner struct {
priv *ecdsa.PrivateKey
hasher func(domain [32]byte, chainID *big.Int, payloadBytes []byte) (common.Hash, error)
priv *ecdsa.PrivateKey
}
func NewLocalSigner(priv *ecdsa.PrivateKey) *LocalSigner {
return &LocalSigner{priv: priv, hasher: SigningHash}
return &LocalSigner{priv: priv}
}
func (s *LocalSigner) Sign(ctx context.Context, domain [32]byte, chainID *big.Int, encodedMsg []byte) (sig *[65]byte, err error) {
if s.priv == nil {
return nil, errors.New("signer is closed")
}
signingHash, err := s.hasher(domain, chainID, encodedMsg)
blockPayloadArgs := opsigner.NewBlockPayloadArgs(domain, chainID, encodedMsg, nil)
signingHash, err := blockPayloadArgs.ToSigningHash()
if err != nil {
return nil, err
}
......@@ -69,6 +58,39 @@ func (s *LocalSigner) Close() error {
return nil
}
type RemoteSigner struct {
client *opsigner.SignerClient
sender *common.Address
}
func NewRemoteSigner(logger log.Logger, config opsigner.CLIConfig) (*RemoteSigner, error) {
signerClient, err := opsigner.NewSignerClientFromConfig(logger, config)
if err != nil {
return nil, err
}
senderAddress := common.HexToAddress(config.Address)
return &RemoteSigner{signerClient, &senderAddress}, nil
}
func (s *RemoteSigner) Sign(ctx context.Context, domain [32]byte, chainID *big.Int, encodedMsg []byte) (sig *[65]byte, err error) {
if s.client == nil {
return nil, errors.New("signer is closed")
}
blockPayloadArgs := opsigner.NewBlockPayloadArgs(domain, chainID, encodedMsg, s.sender)
signature, err := s.client.SignBlockPayload(ctx, blockPayloadArgs)
if err != nil {
return nil, err
}
return &signature, nil
}
func (s *RemoteSigner) Close() error {
s.client = nil
return nil
}
type PreparedSigner struct {
Signer
}
......
......@@ -5,6 +5,7 @@ import (
"testing"
"github.com/ethereum-optimism/optimism/op-node/rollup"
opsigner "github.com/ethereum-optimism/optimism/op-service/signer"
"github.com/stretchr/testify/require"
)
......@@ -14,10 +15,10 @@ func TestSigningHash_DifferentDomain(t *testing.T) {
}
payloadBytes := []byte("arbitraryData")
hash, err := SigningHash(SigningDomainBlocksV1, cfg.L2ChainID, payloadBytes)
hash, err := opsigner.NewBlockPayloadArgs(SigningDomainBlocksV1, cfg.L2ChainID, payloadBytes, nil).ToSigningHash()
require.NoError(t, err, "creating first signing hash")
hash2, err := SigningHash([32]byte{3}, cfg.L2ChainID, payloadBytes)
hash2, err := opsigner.NewBlockPayloadArgs([32]byte{3}, cfg.L2ChainID, payloadBytes, nil).ToSigningHash()
require.NoError(t, err, "creating second signing hash")
require.NotEqual(t, hash, hash2, "signing hash should be different when domain is different")
......@@ -32,10 +33,10 @@ func TestSigningHash_DifferentChainID(t *testing.T) {
}
payloadBytes := []byte("arbitraryData")
hash, err := SigningHash(SigningDomainBlocksV1, cfg1.L2ChainID, payloadBytes)
hash, err := opsigner.NewBlockPayloadArgs(SigningDomainBlocksV1, cfg1.L2ChainID, payloadBytes, nil).ToSigningHash()
require.NoError(t, err, "creating first signing hash")
hash2, err := SigningHash(SigningDomainBlocksV1, cfg2.L2ChainID, payloadBytes)
hash2, err := opsigner.NewBlockPayloadArgs(SigningDomainBlocksV1, cfg2.L2ChainID, payloadBytes, nil).ToSigningHash()
require.NoError(t, err, "creating second signing hash")
require.NotEqual(t, hash, hash2, "signing hash should be different when chain ID is different")
......@@ -46,10 +47,10 @@ func TestSigningHash_DifferentMessage(t *testing.T) {
L2ChainID: big.NewInt(100),
}
hash, err := SigningHash(SigningDomainBlocksV1, cfg.L2ChainID, []byte("msg1"))
hash, err := opsigner.NewBlockPayloadArgs(SigningDomainBlocksV1, cfg.L2ChainID, []byte("msg1"), nil).ToSigningHash()
require.NoError(t, err, "creating first signing hash")
hash2, err := SigningHash(SigningDomainBlocksV1, cfg.L2ChainID, []byte("msg2"))
hash2, err := opsigner.NewBlockPayloadArgs(SigningDomainBlocksV1, cfg.L2ChainID, []byte("msg2"), nil).ToSigningHash()
require.NoError(t, err, "creating second signing hash")
require.NotEqual(t, hash, hash2, "signing hash should be different when message is different")
......@@ -62,6 +63,6 @@ func TestSigningHash_LimitChainID(t *testing.T) {
cfg := &rollup.Config{
L2ChainID: chainID,
}
_, err := SigningHash(SigningDomainBlocksV1, cfg.L2ChainID, []byte("arbitraryData"))
_, err := opsigner.NewBlockPayloadArgs(SigningDomainBlocksV1, cfg.L2ChainID, []byte("arbitraryData"), nil).ToSigningHash()
require.ErrorContains(t, err, "chain_id is too large")
}
......@@ -49,7 +49,7 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) {
driverConfig := NewDriverConfig(ctx)
p2pSignerSetup, err := p2pcli.LoadSignerSetup(ctx)
p2pSignerSetup, err := p2pcli.LoadSignerSetup(ctx, log)
if err != nil {
return nil, fmt.Errorf("failed to load p2p signer: %w", err)
}
......
package signer
import (
"errors"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
// BlockPayloadArgs represents the arguments to sign a new block payload from the sequencer.
type BlockPayloadArgs struct {
Domain [32]byte `json:"domain"`
ChainID *big.Int `json:"chainId"`
PayloadHash []byte `json:"payloadHash"`
PayloadBytes []byte
SenderAddress *common.Address `json:"senderAddress"`
}
// NewBlockPayloadArgs creates a BlockPayloadArgs struct
func NewBlockPayloadArgs(domain [32]byte, chainId *big.Int, payloadBytes []byte, senderAddress *common.Address) *BlockPayloadArgs {
payloadHash := crypto.Keccak256(payloadBytes)
args := &BlockPayloadArgs{
Domain: domain,
ChainID: chainId,
PayloadHash: payloadHash,
PayloadBytes: payloadBytes,
SenderAddress: senderAddress,
}
return args
}
func (args *BlockPayloadArgs) Check() error {
if args.ChainID == nil {
return errors.New("chainId not specified")
}
if len(args.PayloadHash) == 0 {
return errors.New("payloadHash not specified")
}
return nil
}
// ToSigningHash creates a signingHash from the block payload args.
// Uses the hashing scheme from https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/rollup-node-p2p.md#block-signatures
func (args *BlockPayloadArgs) ToSigningHash() (common.Hash, error) {
if err := args.Check(); err != nil {
return common.Hash{}, err
}
var msgInput [32 + 32 + 32]byte
// domain: first 32 bytes
copy(msgInput[:32], args.Domain[:])
// chain_id: second 32 bytes
if args.ChainID.BitLen() > 256 {
return common.Hash{}, errors.New("chain_id is too large")
}
args.ChainID.FillBytes(msgInput[32:64])
// payload_hash: third 32 bytes, hash of encoded payload
copy(msgInput[64:], args.PayloadHash[:])
return crypto.Keccak256Hash(msgInput[:]), nil
}
......@@ -17,18 +17,20 @@ const (
HeadersFlagName = "signer.header"
)
func CLIFlags(envPrefix string) []cli.Flag {
func CLIFlags(envPrefix string, category string) []cli.Flag {
envPrefix += "_SIGNER"
flags := []cli.Flag{
&cli.StringFlag{
Name: EndpointFlagName,
Usage: "Signer endpoint the client will connect to",
EnvVars: opservice.PrefixEnvVar(envPrefix, "ENDPOINT"),
Name: EndpointFlagName,
Usage: "Signer endpoint the client will connect to",
EnvVars: opservice.PrefixEnvVar(envPrefix, "ENDPOINT"),
Category: category,
},
&cli.StringFlag{
Name: AddressFlagName,
Usage: "Address the signer is signing transactions for",
EnvVars: opservice.PrefixEnvVar(envPrefix, "ADDRESS"),
Name: AddressFlagName,
Usage: "Address the signer is signing requests for",
EnvVars: opservice.PrefixEnvVar(envPrefix, "ADDRESS"),
Category: category,
},
&cli.StringSliceFlag{
Name: HeadersFlagName,
......@@ -36,7 +38,7 @@ func CLIFlags(envPrefix string) []cli.Flag {
EnvVars: opservice.PrefixEnvVar(envPrefix, "HEADER"),
},
}
flags = append(flags, optls.CLIFlagsWithFlagPrefix(envPrefix, "signer")...)
flags = append(flags, optls.CLIFlagsWithFlagPrefix(envPrefix, "signer", category)...)
return flags
}
......@@ -65,10 +67,7 @@ func (c CLIConfig) Check() error {
}
func (c CLIConfig) Enabled() bool {
if c.Endpoint != "" && c.Address != "" {
return true
}
return false
return c.Endpoint != "" && c.Address != ""
}
func ReadCLIConfig(ctx *cli.Context) CLIConfig {
......
......@@ -93,7 +93,7 @@ func TestInvalidConfig(t *testing.T) {
func configForArgs(args ...string) CLIConfig {
app := cli.NewApp()
app.Flags = CLIFlags("TEST_")
app.Flags = CLIFlags("TEST_", "")
app.Name = "test"
var config CLIConfig
app.Action = func(ctx *cli.Context) error {
......
......@@ -113,3 +113,19 @@ func (s *SignerClient) SignTransaction(ctx context.Context, chainId *big.Int, fr
return &signed, nil
}
func (s *SignerClient) SignBlockPayload(ctx context.Context, args *BlockPayloadArgs) ([65]byte, error) {
var result hexutil.Bytes
if err := s.client.CallContext(ctx, &result, "opsigner_signBlockPayload", args); err != nil {
return [65]byte{}, fmt.Errorf("opsigner_signBlockPayload failed: %w", err)
}
if len(result) != 65 {
return [65]byte{}, fmt.Errorf("invalid signature: %s", result.String())
}
signature := [65]byte(result)
return signature, nil
}
......@@ -21,7 +21,7 @@ const (
// CLIFlags returns flags with env var envPrefix
// This should be used for server TLS configs, or when client and server tls configs are the same
func CLIFlags(envPrefix string) []cli.Flag {
return CLIFlagsWithFlagPrefix(envPrefix, "")
return CLIFlagsWithFlagPrefix(envPrefix, "", "")
}
var (
......@@ -33,7 +33,7 @@ var (
// CLIFlagsWithFlagPrefix returns flags with env var and cli flag prefixes
// Should be used for client TLS configs when different from server on the same process
func CLIFlagsWithFlagPrefix(envPrefix string, flagPrefix string) []cli.Flag {
func CLIFlagsWithFlagPrefix(envPrefix string, flagPrefix string, category string) []cli.Flag {
prefixFunc := func(flagName string) string {
return strings.Trim(fmt.Sprintf("%s.%s", flagPrefix, flagName), ".")
}
......@@ -48,22 +48,25 @@ func CLIFlagsWithFlagPrefix(envPrefix string, flagPrefix string) []cli.Flag {
EnvVars: prefixEnvVars("TLS_ENABLED"),
},
&cli.StringFlag{
Name: prefixFunc(TLSCaCertFlagName),
Usage: "tls ca cert path",
Value: defaultTLSCaCert,
EnvVars: prefixEnvVars("TLS_CA"),
Name: prefixFunc(TLSCaCertFlagName),
Usage: "tls ca cert path",
Value: defaultTLSCaCert,
EnvVars: prefixEnvVars("TLS_CA"),
Category: category,
},
&cli.StringFlag{
Name: prefixFunc(TLSCertFlagName),
Usage: "tls cert path",
Value: defaultTLSCert,
EnvVars: prefixEnvVars("TLS_CERT"),
Name: prefixFunc(TLSCertFlagName),
Usage: "tls cert path",
Value: defaultTLSCert,
EnvVars: prefixEnvVars("TLS_CERT"),
Category: category,
},
&cli.StringFlag{
Name: prefixFunc(TLSKeyFlagName),
Usage: "tls key",
Value: defaultTLSKey,
EnvVars: prefixEnvVars("TLS_KEY"),
Name: prefixFunc(TLSKeyFlagName),
Usage: "tls key",
Value: defaultTLSKey,
EnvVars: prefixEnvVars("TLS_KEY"),
Category: category,
},
}
}
......
......@@ -53,7 +53,7 @@ func TestInvalidConfig(t *testing.T) {
func configForArgs(args ...string) CLIConfig {
app := cli.NewApp()
app.Flags = CLIFlagsWithFlagPrefix("TEST_", "test")
app.Flags = CLIFlagsWithFlagPrefix("TEST_", "test", "")
app.Name = "test"
var config CLIConfig
app.Action = func(ctx *cli.Context) error {
......
......@@ -191,7 +191,7 @@ func CLIFlagsWithDefaults(envPrefix string, defaults DefaultFlagValues) []cli.Fl
Value: defaults.ReceiptQueryInterval,
EnvVars: prefixEnvVars("TXMGR_RECEIPT_QUERY_INTERVAL"),
},
}, opsigner.CLIFlags(envPrefix)...)
}, opsigner.CLIFlags(envPrefix, "")...)
}
type CLIConfig struct {
......
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