Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Integrate op-node with op-signer for block payload signing #59

Merged
merged 6 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ This repository is an extension of the [Optimism monorepo](https://github.com/et

## Components
- op-conductor-mon: Monitors multiple op-conductor instances and provides a unified interface for reporting metrics.
- op-signer: Thin gateway that supports `eth_signTransaction` RPC endpoint to sign ethereum tx payloads using private key stored in KMS
- op-signer: Thin gateway that supports various RPC endpoints to sign payloads from op-stack components using private key stored in KMS.
- op-ufm: User facing monitoring creates transactions at regular intervals and observe transaction propagation across different RPC providers.
4 changes: 2 additions & 2 deletions op-signer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
FROM golang:1.21.3-alpine3.18 as builder
FROM golang:1.22.7-alpine3.20 as builder

COPY ./op-signer /app

WORKDIR /app
RUN apk --no-cache add make jq bash git alpine-sdk
RUN make build

FROM alpine:3.18
FROM alpine:3.20
RUN apk --no-cache add ca-certificates

RUN addgroup -S app && adduser -S app -G app
Expand Down
17 changes: 16 additions & 1 deletion op-signer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,26 @@ Signer service and client library

## Setup

Install go1.18
Install go1.21

```bash
make build

source .env.example # (or copy to .envrc if using direnv)
./bin/signer
```

## Configuring Cloud KMS
Modify the `config.yaml` file to connect op-signer with your cloud KMS.
- `name`: DNS name of the client connecting to op-signer. Must match the DNS name in the TLS certificate.
- `key`: key resource name of the Cloud KMS.

You can add a list of `name`/`key` to use different keys for each client connecting with op-signer.

## Testing with local tls
Running op-signer requires mTLS connection between the op-signer and the requesting server.

To test services in your local environment
1. run `./gen-local-tls.sh`
2. Check that `/tls` folder has been created with certificates and keys
2. Set the appropriate flags (`tls.cert`, `tls.key`, `tls.ca`) to the corresponding files under `/tls`
93 changes: 65 additions & 28 deletions op-signer/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/urfave/cli/v2"

"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/log"
Expand Down Expand Up @@ -197,43 +198,79 @@ func MainAppAction(version string) cliapp.LifecycleAction {
}
}

func ClientSign(version string) func(cliCtx *cli.Context) error {
type SignActionType string

const (
SignTransaction SignActionType = "transaction"
SignBlockPayload SignActionType = "block_payload"
)

func ClientSign(version string, action SignActionType) func(cliCtx *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(os.Stdout, cfg.LogConfig)
log.Root().SetHandler(l.GetHandler())

txarg := cliCtx.Args().First()
if txarg == "" {
return errors.New("no transaction argument was provided")
}
txraw, err := hexutil.Decode(txarg)
if err != nil {
return errors.New("failed to decode transaction argument")
}

client, err := client.NewSignerClient(l, cfg.ClientEndpoint, cfg.TLSConfig)
if err != nil {
return err
}

tx := &types.Transaction{}
if err := tx.UnmarshalBinary(txraw); err != nil {
return fmt.Errorf("failed to unmarshal transaction argument: %w", err)
oplog.SetGlobalLogHandler(l.Handler())

switch action {
case SignTransaction:
txarg := cliCtx.Args().Get(0)
if txarg == "" {
return errors.New("no transaction argument was provided")
}
txraw, err := hexutil.Decode(txarg)
if err != nil {
return errors.New("failed to decode transaction argument")
}

client, err := client.NewSignerClient(l, cfg.ClientEndpoint, cfg.TLSConfig)
if err != nil {
return err
}

tx := &types.Transaction{}
if err := tx.UnmarshalBinary(txraw); err != nil {
return fmt.Errorf("failed to unmarshal transaction argument: %w", err)
}

tx, err = client.SignTransaction(context.Background(), tx)
if err != nil {
return err
}

result, _ := tx.MarshalJSON()
fmt.Println(string(result))

case SignBlockPayload:
blockPayloadHash := cliCtx.Args().Get(0)
if blockPayloadHash == "" {
return errors.New("no block payload argument was provided")
}

client, err := client.NewSignerClient(l, cfg.ClientEndpoint, cfg.TLSConfig)
if err != nil {
return err
}

signingHash := common.Hash{}
if err := signingHash.UnmarshalText([]byte(blockPayloadHash)); err != nil {
return fmt.Errorf("failed to unmarshal block payload argument: %w", err)
}

signature, err := client.SignBlockPayload(context.Background(), signingHash)
if err != nil {
return err
}

fmt.Println(string(signature[:]))

case "":
return errors.New("no action was provided")
}

tx, err = client.SignTransaction(context.Background(), tx)
if err != nil {
return err
}

result, _ := tx.MarshalJSON()
fmt.Println(string(result))

return nil
}
}
14 changes: 14 additions & 0 deletions op-signer/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"os"

"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/log"
Expand Down Expand Up @@ -89,3 +90,16 @@ func (s *SignerClient) SignTransaction(

return signed, nil
}

func (s *SignerClient) SignBlockPayload(
ctx context.Context,
signingHash common.Hash,
) ([]byte, error) {
var result []byte

if err := s.client.Call(&result, "eth_signBlockPayload", signingHash); err != nil {
return []byte{}, fmt.Errorf("eth_signTransaction failed: %w", err)
}

return result, nil
}
10 changes: 8 additions & 2 deletions op-signer/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,15 @@ func main() {
Usage: "test client for signer service",
Subcommands: []*cli.Command{
{
Name: "sign",
Name: string(signer.SignTransaction),
Usage: "sign a transaction",
Action: signer.ClientSign(Version),
Action: signer.ClientSign(Version, signer.SignTransaction),
Flags: cliapp.ProtectFlags(signer.ClientSignCLIFlags("SIGNER")),
},
{
Name: string(signer.SignBlockPayload),
Usage: "sign a block payload",
Action: signer.ClientSign(Version, signer.SignBlockPayload),
Flags: cliapp.ProtectFlags(signer.ClientSignCLIFlags("SIGNER")),
},
},
Expand Down
126 changes: 65 additions & 61 deletions op-signer/go.mod
Original file line number Diff line number Diff line change
@@ -1,115 +1,119 @@
module github.com/ethereum-optimism/infra/op-signer

go 1.21
go 1.22

toolchain go1.22.0

replace github.com/ethereum-optimism/optimism v1.4.3-0.20240125020216-6a3b1ec12399 => github.com/testinprod-io/optimism v0.0.0-20241018221952-12c4820e35fb
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be reverted once the monorepo pr gets merged


require (
cloud.google.com/go/kms v1.10.1
cloud.google.com/go/kms v1.12.1
github.com/ethereum-optimism/optimism v1.4.3-0.20240125020216-6a3b1ec12399
github.com/ethereum/go-ethereum v1.13.5
github.com/ethereum/go-ethereum v1.14.11
github.com/golang/mock v1.6.0
github.com/googleapis/gax-go v1.0.3
github.com/googleapis/gax-go/v2 v2.11.0
github.com/holiman/uint256 v1.2.3
github.com/prometheus/client_golang v1.18.0
github.com/stretchr/testify v1.8.4
github.com/urfave/cli/v2 v2.27.1
google.golang.org/protobuf v1.33.0
github.com/holiman/uint256 v1.3.1
github.com/prometheus/client_golang v1.20.4
github.com/stretchr/testify v1.9.0
github.com/urfave/cli/v2 v2.27.4
google.golang.org/protobuf v1.34.2
gopkg.in/yaml.v3 v3.0.1
)

require (
cloud.google.com/go/compute v1.20.1 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v0.13.0 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/DataDog/zstd v1.5.2 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/VictoriaMetrics/fastcache v1.12.1 // indirect
cloud.google.com/go/compute/metadata v0.3.0 // indirect
cloud.google.com/go/iam v1.1.1 // indirect
github.com/BurntSushi/toml v1.4.0 // indirect
github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.7.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cockroachdb/errors v1.11.1 // indirect
github.com/bits-and-blooms/bitset v1.13.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cockroachdb/errors v1.11.3 // indirect
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/pebble v0.0.0-20231018212520-f6cde3fc2fa4 // indirect
github.com/cockroachdb/pebble v1.1.2 // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/consensys/bavard v0.1.13 // indirect
github.com/consensys/gnark-crypto v0.12.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deckarep/golang-set/v2 v2.1.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240123193359-a5fc767e225a // indirect
github.com/ethereum/c-kzg-4844 v0.4.0 // indirect
github.com/fjl/memsize v0.0.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect
github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240910145426-b3905c89e8ac // indirect
github.com/ethereum/c-kzg-4844 v1.0.0 // indirect
github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/getsentry/sentry-go v0.18.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/getsentry/sentry-go v0.27.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/s2a-go v0.1.4 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/hashicorp/go-bexpr v0.1.11 // indirect
github.com/huin/goupnp v1.3.0 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/klauspost/compress v1.17.2 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/pointerstructure v1.2.1 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/rs/cors v1.9.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/rs/cors v1.11.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/supranational/blst v0.3.11 // indirect
github.com/supranational/blst v0.3.13 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/oauth2 v0.12.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/term v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.16.1 // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/term v0.24.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.24.0 // indirect
google.golang.org/api v0.126.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
google.golang.org/grpc v1.55.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect
google.golang.org/grpc v1.57.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
honnef.co/go/tools v0.0.1-2020.1.4 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
)

replace github.com/ethereum/go-ethereum v1.13.5 => github.com/ethereum-optimism/op-geth v1.101305.3-rc.1.0.20240124221225-5c6f10d449ab
replace github.com/ethereum/go-ethereum v1.14.11 => github.com/ethereum-optimism/op-geth v1.101408.1-0.20241002211323-d5a96613c22b
Loading