diff --git a/cmd/start.go b/cmd/start.go index 4557ebc..9979990 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -8,12 +8,14 @@ import ( "github.com/spf13/cobra" "github.com/strangelove-ventures/horcrux-proxy/privval" + "github.com/strangelove-ventures/horcrux-proxy/signer" ) const ( - flagLogLevel = "log-level" - flagListen = "listen" - flagAll = "all" + flagLogLevel = "log-level" + flagListen = "listen" + flagAll = "all" + flagGRPCAddress = "grpc" ) func startCmd() *cobra.Command { @@ -42,15 +44,28 @@ func startCmd() *cobra.Command { listeners[i] = privval.NewSignerListener(logger, addr) } - loadBalancer := privval.NewRemoteSignerLoadBalancer(logger, listeners) - if err = loadBalancer.Start(); err != nil { - return fmt.Errorf("failed to start listener(s): %w", err) + var hc signer.HorcruxConnection + + grpcAddr, _ := cmd.Flags().GetString(flagGRPCAddress) + + if grpcAddr != "" { + hc, err = signer.NewHorcruxGRPCClient(logger, grpcAddr) + if err != nil { + return fmt.Errorf("failed to create grpc connection: %w", err) + } + } else { + loadBalancer := privval.NewRemoteSignerLoadBalancer(logger, listeners) + if err = loadBalancer.Start(); err != nil { + return fmt.Errorf("failed to start listener(s): %w", err) + } + defer logIfErr(logger, loadBalancer.Stop) + + hc = loadBalancer } - defer logIfErr(logger, loadBalancer.Stop) ctx := cmd.Context() - watcher, err := NewSentryWatcher(ctx, logger, all, loadBalancer) + watcher, err := NewSentryWatcher(ctx, logger, all, hc) if err != nil { return err } @@ -64,6 +79,7 @@ func startCmd() *cobra.Command { } cmd.Flags().StringArrayP(flagListen, "l", []string{"tcp://0.0.0.0:1234"}, "Privval listen addresses for the proxy") + cmd.Flags().StringP(flagGRPCAddress, "g", "", "GRPC address for the proxy") cmd.Flags().BoolP(flagAll, "a", false, "Connect to sentries on all nodes") cmd.Flags().String(flagLogLevel, "info", "Set log level (debug, info, error, none)") diff --git a/cmd/watcher.go b/cmd/watcher.go index 46b53f4..754c634 100644 --- a/cmd/watcher.go +++ b/cmd/watcher.go @@ -9,7 +9,6 @@ import ( "time" cometlog "github.com/cometbft/cometbft/libs/log" - "github.com/strangelove-ventures/horcrux-proxy/privval" "github.com/strangelove-ventures/horcrux-proxy/signer" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -26,7 +25,7 @@ const ( type SentryWatcher struct { all bool client *kubernetes.Clientset - lb *privval.RemoteSignerLoadBalancer + hc signer.HorcruxConnection log cometlog.Logger node string sentries map[string]*signer.ReconnRemoteSigner @@ -39,7 +38,7 @@ func NewSentryWatcher( ctx context.Context, logger cometlog.Logger, all bool, // should we connect to sentries on all nodes, or just this node? - lb *privval.RemoteSignerLoadBalancer, + hc signer.HorcruxConnection, ) (*SentryWatcher, error) { config, err := rest.InClusterConfig() if err != nil { @@ -73,7 +72,7 @@ func NewSentryWatcher( all: all, client: clientset, done: make(chan struct{}), - lb: lb, + hc: hc, log: logger, node: thisNode, sentries: make(map[string]*signer.ReconnRemoteSigner), @@ -194,7 +193,7 @@ func (w *SentryWatcher) reconcileSentries( for _, newSentry := range newSentries { dialer := net.Dialer{Timeout: 2 * time.Second} - s := signer.NewReconnRemoteSigner(newSentry, w.log, w.lb, dialer) + s := signer.NewReconnRemoteSigner(newSentry, w.log, w.hc, dialer) if err := s.Start(); err != nil { return fmt.Errorf("failed to start new remote signer(s): %w", err) diff --git a/go.mod b/go.mod index 2f248b5..b537981 100644 --- a/go.mod +++ b/go.mod @@ -4,18 +4,20 @@ go 1.20 require ( github.com/cometbft/cometbft v0.37.2 - github.com/cosmos/gogoproto v1.4.1 + github.com/cosmos/gogoproto v1.4.10 github.com/spf13/cobra v1.6.1 + github.com/strangelove-ventures/horcrux v0.1.5-0.20231108005242-84006451edad github.com/stretchr/testify v1.8.2 - golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde + golang.org/x/sync v0.1.0 + google.golang.org/grpc v1.55.0 k8s.io/apimachinery v0.28.1 k8s.io/client-go v0.28.1 ) require ( - github.com/btcsuite/btcd/btcec/v2 v2.2.1 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect @@ -39,12 +41,13 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect + github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/crypto v0.11.0 // indirect + golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect golang.org/x/net v0.13.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/sys v0.10.0 // indirect @@ -52,6 +55,7 @@ require ( golang.org/x/text v0.11.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 46357f5..02f8923 100644 --- a/go.sum +++ b/go.sum @@ -1,22 +1,21 @@ github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= -github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh2R/Yv3E= -github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= -github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU= -github.com/cosmos/gogoproto v1.4.1 h1:WoyH+0/jbCTzpKNvyav5FL1ZTWsp1im1MxEpJEzKUB8= -github.com/cosmos/gogoproto v1.4.1/go.mod h1:Ac9lzL4vFpBMcptJROQ6dQ4M3pOEK5Z/l0Q9p+LoCr4= +github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= +github.com/cosmos/gogoproto v1.4.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoKuI= +github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= @@ -85,8 +84,9 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= -github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= +github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -99,6 +99,8 @@ github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/strangelove-ventures/horcrux v0.1.5-0.20231108005242-84006451edad h1:fe8iWUpTOIxXFwoUr/Yccjp4OQwETIAvF0wWBLpYJ70= +github.com/strangelove-ventures/horcrux v0.1.5-0.20231108005242-84006451edad/go.mod h1:SHegQxcwdJUSAY5o1Q14MGqTFV8pQvEZjhMfBFB5oUY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -115,6 +117,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -129,8 +133,8 @@ golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde h1:ejfdSekXMDxDLbRrJMwUk6KnSLZ2McaUCVcIKM+N6jc= -golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -156,6 +160,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= diff --git a/signer/grpc_client.go b/signer/grpc_client.go new file mode 100644 index 0000000..749f6b6 --- /dev/null +++ b/signer/grpc_client.go @@ -0,0 +1,112 @@ +package signer + +import ( + "context" + "fmt" + + cometlog "github.com/cometbft/cometbft/libs/log" + cometprotoprivval "github.com/cometbft/cometbft/proto/tendermint/privval" + "github.com/strangelove-ventures/horcrux/signer/proto" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +var _ HorcruxConnection = (*HorcruxGRPCClient)(nil) + +type HorcruxGRPCClient struct { + grpcClient proto.RemoteSignerClient + logger cometlog.Logger +} + +func NewHorcruxGRPCClient( + logger cometlog.Logger, + address string, +) (*HorcruxGRPCClient, error) { + conn, err := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + return nil, err + } + return &HorcruxGRPCClient{ + logger: logger, + grpcClient: proto.NewRemoteSignerClient(conn), + }, nil +} + +func (c *HorcruxGRPCClient) SendRequest(req cometprotoprivval.Message) (*cometprotoprivval.Message, error) { + switch typedReq := req.Sum.(type) { + case *cometprotoprivval.Message_SignVoteRequest: + return c.handleSignVoteRequest(req) + case *cometprotoprivval.Message_SignProposalRequest: + return c.handleSignProposalRequest(req) + case *cometprotoprivval.Message_PubKeyRequest: + return c.handlePubKeyRequest(req) + case *cometprotoprivval.Message_PingRequest: + return c.handlePingRequest() + default: + c.logger.Error("Unknown request", "err", fmt.Errorf("%v", typedReq)) + return &cometprotoprivval.Message{}, nil + } +} + +func (c *HorcruxGRPCClient) handleSignVoteRequest(req cometprotoprivval.Message) (*cometprotoprivval.Message, error) { + res, err := c.grpcClient.SignVote(context.TODO(), req.GetSignVoteRequest()) + if err == nil { + return &cometprotoprivval.Message{ + Sum: &cometprotoprivval.Message_SignedVoteResponse{SignedVoteResponse: res}, + }, nil + } + + return &cometprotoprivval.Message{ + Sum: &cometprotoprivval.Message_SignedVoteResponse{SignedVoteResponse: &cometprotoprivval.SignedVoteResponse{ + Error: getRemoteSignerError(err), + }}, + }, nil +} + +func (c *HorcruxGRPCClient) handleSignProposalRequest(req cometprotoprivval.Message) (*cometprotoprivval.Message, error) { + res, err := c.grpcClient.SignProposal(context.TODO(), req.GetSignProposalRequest()) + if err == nil { + return &cometprotoprivval.Message{ + Sum: &cometprotoprivval.Message_SignedProposalResponse{SignedProposalResponse: res}, + }, nil + } + + return &cometprotoprivval.Message{ + Sum: &cometprotoprivval.Message_SignedProposalResponse{SignedProposalResponse: &cometprotoprivval.SignedProposalResponse{ + Error: getRemoteSignerError(err), + }}, + }, nil +} + +func (c *HorcruxGRPCClient) handlePubKeyRequest(req cometprotoprivval.Message) (*cometprotoprivval.Message, error) { + res, err := c.grpcClient.PubKey(context.TODO(), req.GetPubKeyRequest()) + if err == nil { + return &cometprotoprivval.Message{ + Sum: &cometprotoprivval.Message_PubKeyResponse{PubKeyResponse: res}, + }, nil + } + + return &cometprotoprivval.Message{ + Sum: &cometprotoprivval.Message_PubKeyResponse{PubKeyResponse: &cometprotoprivval.PubKeyResponse{ + Error: getRemoteSignerError(err), + }}, + }, nil +} + +func (c *HorcruxGRPCClient) handlePingRequest() (*cometprotoprivval.Message, error) { + return &cometprotoprivval.Message{ + Sum: &cometprotoprivval.Message_PingResponse{ + PingResponse: &cometprotoprivval.PingResponse{}, + }, + }, nil +} + +func getRemoteSignerError(err error) *cometprotoprivval.RemoteSignerError { + if err == nil { + return nil + } + return &cometprotoprivval.RemoteSignerError{ + Code: 0, + Description: err.Error(), + } +} diff --git a/signer/remote_signer.go b/signer/remote_signer.go index 569fbf0..c11e2dc 100644 --- a/signer/remote_signer.go +++ b/signer/remote_signer.go @@ -1,7 +1,6 @@ package signer import ( - "fmt" "io" "net" "time" @@ -12,12 +11,13 @@ import ( "github.com/cometbft/cometbft/libs/protoio" cometservice "github.com/cometbft/cometbft/libs/service" cometp2pconn "github.com/cometbft/cometbft/p2p/conn" - cometprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" cometprotoprivval "github.com/cometbft/cometbft/proto/tendermint/privval" - cometproto "github.com/cometbft/cometbft/proto/tendermint/types" - "github.com/strangelove-ventures/horcrux-proxy/privval" ) +type HorcruxConnection interface { + SendRequest(request cometprotoprivval.Message) (*cometprotoprivval.Message, error) +} + // ReconnRemoteSigner dials using its dialer and responds to any // signature requests using its privVal. type ReconnRemoteSigner struct { @@ -26,7 +26,7 @@ type ReconnRemoteSigner struct { address string privKey cometcryptoed25519.PrivKey - loadBalancer *privval.RemoteSignerLoadBalancer + horcruxConnection HorcruxConnection dialer net.Dialer } @@ -39,14 +39,14 @@ type ReconnRemoteSigner struct { func NewReconnRemoteSigner( address string, logger cometlog.Logger, - loadBalancer *privval.RemoteSignerLoadBalancer, + horcruxConnection HorcruxConnection, dialer net.Dialer, ) *ReconnRemoteSigner { rs := &ReconnRemoteSigner{ - address: address, - dialer: dialer, - loadBalancer: loadBalancer, - privKey: cometcryptoed25519.GenPrivKey(), + address: address, + dialer: dialer, + horcruxConnection: horcruxConnection, + privKey: cometcryptoed25519.GenPrivKey(), } rs.BaseService = *cometservice.NewBaseService(logger, "RemoteSigner", rs) @@ -120,91 +120,27 @@ func (rs *ReconnRemoteSigner) loop() { } // handleRequest handles request errors. We always send back a response - res := rs.handleRequest(req) - - err = WriteMsg(conn, res) + res, err := rs.horcruxConnection.SendRequest(req) if err != nil { - rs.Logger.Error("writeMsg", "err", err) + rs.Logger.Error("handleRequest", "err", err) conn.Close() conn = nil + continue } - } -} - -func (rs *ReconnRemoteSigner) handleRequest(req cometprotoprivval.Message) cometprotoprivval.Message { - switch typedReq := req.Sum.(type) { - case *cometprotoprivval.Message_SignVoteRequest: - return rs.handleSignVoteRequest(req) - case *cometprotoprivval.Message_SignProposalRequest: - return rs.handleSignProposalRequest(req) - case *cometprotoprivval.Message_PubKeyRequest: - return rs.handlePubKeyRequest(req) - case *cometprotoprivval.Message_PingRequest: - return rs.handlePingRequest() - default: - rs.Logger.Error("Unknown request", "err", fmt.Errorf("%v", typedReq)) - return cometprotoprivval.Message{} - } -} -func (rs *ReconnRemoteSigner) handleSignVoteRequest(req cometprotoprivval.Message) cometprotoprivval.Message { - res, err := rs.loadBalancer.SendRequest(req) - if err == nil { - return *res - } - - return cometprotoprivval.Message{ - Sum: &cometprotoprivval.Message_SignedVoteResponse{SignedVoteResponse: &cometprotoprivval.SignedVoteResponse{ - Vote: cometproto.Vote{}, - Error: getRemoteSignerError(err), - }}, - } -} - -func (rs *ReconnRemoteSigner) handleSignProposalRequest(req cometprotoprivval.Message) cometprotoprivval.Message { - res, err := rs.loadBalancer.SendRequest(req) - if err == nil { - return *res - } - - return cometprotoprivval.Message{ - Sum: &cometprotoprivval.Message_SignedProposalResponse{ - SignedProposalResponse: &cometprotoprivval.SignedProposalResponse{ - Proposal: cometproto.Proposal{}, - Error: getRemoteSignerError(err), - }}, - } -} - -func (rs *ReconnRemoteSigner) handlePubKeyRequest(req cometprotoprivval.Message) cometprotoprivval.Message { - res, err := rs.loadBalancer.SendRequest(req) - if err == nil { - return *res - } - - return cometprotoprivval.Message{ - Sum: &cometprotoprivval.Message_PubKeyResponse{PubKeyResponse: &cometprotoprivval.PubKeyResponse{ - PubKey: cometprotocrypto.PublicKey{}, - Error: getRemoteSignerError(err), - }}, - } -} - -func (rs *ReconnRemoteSigner) handlePingRequest() cometprotoprivval.Message { - return cometprotoprivval.Message{ - Sum: &cometprotoprivval.Message_PingResponse{ - PingResponse: &cometprotoprivval.PingResponse{}, - }, - } -} + if res == nil { + rs.Logger.Error("handleRequest", "err", "nil response") + conn.Close() + conn = nil + continue + } -func getRemoteSignerError(err error) *cometprotoprivval.RemoteSignerError { - if err == nil { - return nil - } - return &cometprotoprivval.RemoteSignerError{ - Code: 0, - Description: err.Error(), + err = WriteMsg(conn, *res) + if err != nil { + rs.Logger.Error("writeMsg", "err", err) + conn.Close() + conn = nil + } } }